package com.thebrokenrail.gestus.mixin; import com.thebrokenrail.gestus.entity.FakePlayerEntity; import com.thebrokenrail.gestus.util.Util; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.GenericFutureListener; import net.minecraft.entity.Entity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.network.Packet; import net.minecraft.network.packet.s2c.play.EntityEquipmentUpdateS2CPacket; import net.minecraft.network.packet.s2c.play.EntityTrackerUpdateS2CPacket; import net.minecraft.network.packet.s2c.play.MobSpawnS2CPacket; import net.minecraft.server.network.ServerPlayNetworkHandler; import net.minecraft.server.network.ServerPlayerEntity; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.ModifyVariable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(ServerPlayNetworkHandler.class) public class MixinServerPlayNetworkHandler { @Shadow public ServerPlayerEntity player; @Inject(at = @At("HEAD"), method = "sendPacket(Lnet/minecraft/network/Packet;Lio/netty/util/concurrent/GenericFutureListener;)V", cancellable = true) public void sendPacket(Packet packet, GenericFutureListener> listener, CallbackInfo info) { if (packet instanceof MobSpawnS2CPacket) { MobSpawnS2CPacketAccessor packetData = (MobSpawnS2CPacketAccessor) packet; Entity entity = player.getEntityWorld().getEntityById(packetData.getId()); if (entity instanceof FakePlayerEntity && ((FakePlayerEntity) entity).player.getUuid().equals(player.getUuid())) { info.cancel(); } } } @Unique private boolean shouldModify(int id) { return player.getEntityWorld().getEntityById(id) instanceof PlayerEntity && id != player.getEntityId(); } @ModifyVariable(at = @At("HEAD"), method = "sendPacket(Lnet/minecraft/network/Packet;Lio/netty/util/concurrent/GenericFutureListener;)V", argsOnly = true) public Packet modifyPacket(Packet packet) { if (packet instanceof EntityTrackerUpdateS2CPacket && shouldModify(((EntityTrackerUpdateS2CPacketAccessor) packet).getId())) { return Util.modifyTracker(player, (EntityTrackerUpdateS2CPacket) packet); } else if (packet instanceof EntityEquipmentUpdateS2CPacket && shouldModify(((EntityEquipmentUpdateS2CPacketAccessor) packet).getId())) { return Util.modifyEquipment((EntityEquipmentUpdateS2CPacket) packet); } else { return packet; } } }