diff --git a/src/main/java/com/minelittlepony/unicopia/entity/MotionChecker.java b/src/main/java/com/minelittlepony/unicopia/entity/MotionChecker.java new file mode 100644 index 00000000..5fe8b97d --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/entity/MotionChecker.java @@ -0,0 +1,5 @@ +package com.minelittlepony.unicopia.entity; + +public interface MotionChecker { + void setPreventMotionChecks(boolean enabled); +} diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinLivingEntity.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinLivingEntity.java index afe833fa..858bd485 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinLivingEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinLivingEntity.java @@ -20,9 +20,9 @@ import com.minelittlepony.unicopia.entity.PonyContainer; import com.minelittlepony.unicopia.entity.behaviour.Disguise; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.entity.Equine; +import com.minelittlepony.unicopia.entity.ItemWielder; import com.minelittlepony.unicopia.entity.Jumper; import com.minelittlepony.unicopia.entity.Leaner; -import com.minelittlepony.unicopia.entity.ItemWielder; import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinServerPlayNetworkHandler.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinServerPlayNetworkHandler.java new file mode 100644 index 00000000..749ce16c --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinServerPlayNetworkHandler.java @@ -0,0 +1,53 @@ +package com.minelittlepony.unicopia.mixin; + +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.callback.CallbackInfo; + +import com.minelittlepony.unicopia.entity.MotionChecker; +import com.minelittlepony.unicopia.entity.player.Pony; + +import net.minecraft.network.NetworkThreadUtils; +import net.minecraft.network.listener.ServerPlayPacketListener; +import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket; +import net.minecraft.server.network.ServerPlayNetworkHandler; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.server.world.EntityTrackingListener; + +@Mixin(ServerPlayNetworkHandler.class) +abstract class MixinServerPlayNetworkHandler implements EntityTrackingListener, ServerPlayPacketListener { + @Shadow private boolean floating; + @Shadow private int floatingTicks; + + private boolean flyingSurvival; + private boolean prevMotionChecks; + + @Inject(method = "onPlayerMove(Lnet/minecraft/network/packet/c2s/play/PlayerMoveC2SPacket;)V", at = @At("HEAD")) + private void beforePlayerMove(PlayerMoveC2SPacket packet, CallbackInfo info) { + ServerPlayerEntity player = ((ServerPlayNetworkHandler)(Object)this).player; + NetworkThreadUtils.forceMainThread(packet, this, player.getServerWorld()); + flyingSurvival = Pony.of(player).getPhysics().isFlyingSurvival; + + if (flyingSurvival) { + setPreventMotionChecks(true); + } + } + + @Inject(method = "onPlayerMove(Lnet/minecraft/network/packet/c2s/play/PlayerMoveC2SPacket;)V", at = @At("RETURN")) + private void afterPlayerMove(PlayerMoveC2SPacket packet, CallbackInfo info) { + if (flyingSurvival) { + setPreventMotionChecks(prevMotionChecks); + } + } + + private void setPreventMotionChecks(boolean motionChecks) { + ServerPlayerEntity player = ((ServerPlayNetworkHandler)(Object)this).player; + prevMotionChecks = player.isInTeleportationState(); + ((MotionChecker)player).setPreventMotionChecks(motionChecks); + player.fallDistance = 0; + floating = false; + floatingTicks = 0; + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinServerPlayerEntity.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinServerPlayerEntity.java index cd2f7091..873ddd72 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinServerPlayerEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinServerPlayerEntity.java @@ -1,11 +1,13 @@ package com.minelittlepony.unicopia.mixin; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import com.minelittlepony.unicopia.entity.PonyContainer; +import com.minelittlepony.unicopia.entity.MotionChecker; import com.minelittlepony.unicopia.entity.player.Pony; import net.minecraft.entity.player.PlayerEntity; @@ -13,12 +15,17 @@ import net.minecraft.screen.ScreenHandlerListener; import net.minecraft.server.network.ServerPlayerEntity; @Mixin(ServerPlayerEntity.class) -abstract class MixinServerPlayerEntity extends PlayerEntity implements ScreenHandlerListener, PonyContainer { +abstract class MixinServerPlayerEntity extends PlayerEntity implements ScreenHandlerListener, PonyContainer, MotionChecker { MixinServerPlayerEntity() {super(null, null, 0, null);} + @Override + @Accessor("inTeleportationState") + public abstract void setPreventMotionChecks(boolean enabled); + @SuppressWarnings("unchecked") @Inject(method = "copyFrom(Lnet/minecraft/server/network/ServerPlayerEntity;Z)V", at = @At("HEAD")) private void onCopyFrom(ServerPlayerEntity oldPlayer, boolean alive, CallbackInfo info) { get().copyFrom(((PonyContainer)oldPlayer).get()); } + } diff --git a/src/main/resources/unicopia.mixin.json b/src/main/resources/unicopia.mixin.json index 12f060bd..74a9f47b 100644 --- a/src/main/resources/unicopia.mixin.json +++ b/src/main/resources/unicopia.mixin.json @@ -23,6 +23,7 @@ "MixinPlayerEntity", "MixinProjectileEntity", "MixinServerPlayerEntity", + "MixinServerPlayNetworkHandler", "MixinServerWorld", "MixinSheepEntity", "MixinShulkerEntity",