From f27838323751a077667221b76664e88e18ef6d35 Mon Sep 17 00:00:00 2001 From: "Josiah (Gaming32) Glosson" Date: Fri, 30 Jun 2023 11:20:52 -0500 Subject: [PATCH] Improve portal handling under terrible TPS The portal's "active" state doesn't appear to be synced properly for two ticks after the portal is shot. --- .../portalcubed/items/PortalGun.java | 32 ++++++++++++------- .../packet/PortalCubedServerPackets.java | 13 ++++++++ 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/fusionflux/portalcubed/items/PortalGun.java b/src/main/java/com/fusionflux/portalcubed/items/PortalGun.java index 9f9cda9e..ef7b1e98 100644 --- a/src/main/java/com/fusionflux/portalcubed/items/PortalGun.java +++ b/src/main/java/com/fusionflux/portalcubed/items/PortalGun.java @@ -1,12 +1,12 @@ package com.fusionflux.portalcubed.items; - import com.fusionflux.portalcubed.PortalCubedGameRules; import com.fusionflux.portalcubed.accessor.CalledValues; import com.fusionflux.portalcubed.accessor.LevelExt; import com.fusionflux.portalcubed.blocks.PortalCubedBlocks; import com.fusionflux.portalcubed.entity.Portal; import com.fusionflux.portalcubed.entity.PortalCubedEntities; +import com.fusionflux.portalcubed.packet.PortalCubedServerPackets; import com.fusionflux.portalcubed.sound.PortalCubedSounds; import com.fusionflux.portalcubed.util.ClickHandlingItem; import com.fusionflux.portalcubed.util.IPQuaternion; @@ -15,12 +15,14 @@ import com.google.common.collect.ImmutableMap; import it.unimi.dsi.fastutil.Pair; import it.unimi.dsi.fastutil.doubles.Double2DoubleFunction; +import net.minecraft.Util; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.player.LocalPlayer; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.Vec3i; import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket; import net.minecraft.server.level.ServerLevel; import net.minecraft.sounds.SoundSource; import net.minecraft.world.InteractionHand; @@ -43,11 +45,12 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.quiltmc.loader.api.minecraft.ClientOnly; +import org.quiltmc.qsl.networking.api.PacketByteBufs; +import org.quiltmc.qsl.networking.api.client.ClientPlayNetworking; import java.util.*; import java.util.function.BiFunction; - public class PortalGun extends Item implements ClickHandlingItem, DyeableLeatherItem { private static final Map, List>> FAIL_TRIES; private static final Map FAIL_AXIS_DIRS = new EnumMap<>(Map.of( @@ -304,7 +307,21 @@ protected void shoot(Level world, Player user, InteractionHand hand, boolean lef tag.put(world.dimension().location().toString(), portalsTag); } else { - cancelClientMovement(user); + final LocalPlayer localPlayer = (LocalPlayer)user; + if (localPlayer.input.getMoveVector().lengthSquared() < 0.1 && user.getXRot() >= 88.0) { + user.setDeltaMovement(0, user.getDeltaMovement().y, 0); + } + localPlayer.connection.send(new ServerboundMovePlayerPacket.Pos( + user.getX(), + user.getY(), + user.getZ(), + user.onGround() + )); + // PosRot doesn't apply yHeadRot until the next tick, but we need it applied now + ClientPlayNetworking.send(PortalCubedServerPackets.SYNC_SHOOTER_ROT, Util.make(PacketByteBufs.create(), buf -> { + buf.writeFloat(user.getXRot()); + buf.writeFloat(user.getYHeadRot()); + })); } } @@ -316,15 +333,6 @@ private static boolean vectorsEqual(Vec3 a, Vec3 b) { return a.x() == b.x() && a.y() == b.y() && a.z() == b.z(); } - @ClientOnly - private static void cancelClientMovement(Entity user) { - if (user instanceof LocalPlayer clientPlayer) { - if (clientPlayer.input.getMoveVector().lengthSquared() < 0.1 && user.getXRot() >= 88.0) { - user.setDeltaMovement(0, user.getDeltaMovement().y, 0); - } - } - } - public static Optional getPotentialOpposite(Level world, Vec3 portalPos, @Nullable Portal ignore, int color, boolean includePlayerPortals) { return world.getEntities( PortalCubedEntities.PORTAL, diff --git a/src/main/java/com/fusionflux/portalcubed/packet/PortalCubedServerPackets.java b/src/main/java/com/fusionflux/portalcubed/packet/PortalCubedServerPackets.java index 85525606..52b857b4 100644 --- a/src/main/java/com/fusionflux/portalcubed/packet/PortalCubedServerPackets.java +++ b/src/main/java/com/fusionflux/portalcubed/packet/PortalCubedServerPackets.java @@ -52,6 +52,7 @@ public class PortalCubedServerPackets { public static final ResourceLocation CROWBAR_ATTACK = id("crowbar_attack"); public static final ResourceLocation LEFT_CLICK = id("left_click"); public static final ResourceLocation RIGHT_CLICK = id("right_click"); + public static final ResourceLocation SYNC_SHOOTER_ROT = id("sync_shooter_rot"); public static void onGrabKeyPressed(MinecraftServer server, ServerPlayer player, @SuppressWarnings("unused") ServerGamePacketListenerImpl handler, @SuppressWarnings("unused") FriendlyByteBuf buf, @SuppressWarnings("unused") PacketSender sender) { @@ -190,5 +191,17 @@ public static void registerPackets() { if (chi.onRightClick(player, InteractionHand.MAIN_HAND).shouldSwing()) player.swing(InteractionHand.MAIN_HAND, true); } })); + ServerPlayNetworking.registerGlobalReceiver(SYNC_SHOOTER_ROT, (server, player, handler, buf, responseSender) -> { + final float xRot = buf.readFloat(); + final float yRot = buf.readFloat(); + server.execute(() -> { + player.setXRot(xRot); + player.setYRot(yRot); + player.setYHeadRot(yRot); + // The O's are the ones that are actually used for getViewVector! + player.xRotO = xRot; + player.yHeadRotO = yRot; + }); + }); } }