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.network.Packet; 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.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(); } } } @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 && ((EntityTrackerUpdateS2CPacketAccessor) packet).getId() == player.getEntityId()) { return Util.modifyTracker(player, (EntityTrackerUpdateS2CPacket) packet); } else { return packet; } } }