From c6abf493ae0431c8e0e05463d298527eed776b2c Mon Sep 17 00:00:00 2001 From: SamB440 Date: Tue, 18 Jun 2024 20:09:15 +0100 Subject: [PATCH] 1.21 work --- .../events/packets/CheckManagerListener.java | 3 + .../predictionengine/PlayerBaseTick.java | 4 +- .../datatypes/ComplexCollisionBox.java | 1 + .../collisions/datatypes/HexCollisionBox.java | 1 + .../datatypes/SimpleCollisionBox.java | 4 +- .../utils/latency/CompensatedEntities.java | 15 +++- .../grim/grimac/utils/nmsutil/Collisions.java | 76 +++++++++++++++---- 7 files changed, 85 insertions(+), 19 deletions(-) diff --git a/src/main/java/ac/grim/grimac/events/packets/CheckManagerListener.java b/src/main/java/ac/grim/grimac/events/packets/CheckManagerListener.java index 9cf0e65efc..df2640319b 100644 --- a/src/main/java/ac/grim/grimac/events/packets/CheckManagerListener.java +++ b/src/main/java/ac/grim/grimac/events/packets/CheckManagerListener.java @@ -322,6 +322,9 @@ private static void handleBlockPlaceOrUseItem(PacketWrapper packet, GrimPlayer p } private boolean isMojangStupid(GrimPlayer player, WrapperPlayClientPlayerFlying flying) { + // Mojang has become less stupid! + if (player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_21)) return false; + final Location location = flying.getLocation(); final double threshold = player.getMovementThreshold(); diff --git a/src/main/java/ac/grim/grimac/predictionengine/PlayerBaseTick.java b/src/main/java/ac/grim/grimac/predictionengine/PlayerBaseTick.java index 44cda1146e..3264ebc88b 100644 --- a/src/main/java/ac/grim/grimac/predictionengine/PlayerBaseTick.java +++ b/src/main/java/ac/grim/grimac/predictionengine/PlayerBaseTick.java @@ -8,6 +8,8 @@ import ac.grim.grimac.utils.latency.CompensatedEntities; import ac.grim.grimac.utils.math.GrimMath; import ac.grim.grimac.utils.nmsutil.*; +import com.github.retrooper.packetevents.PacketEvents; +import com.github.retrooper.packetevents.manager.server.ServerVersion; import com.github.retrooper.packetevents.protocol.player.ClientVersion; import com.github.retrooper.packetevents.protocol.world.BlockFace; import com.github.retrooper.packetevents.protocol.world.states.type.StateType; @@ -142,7 +144,7 @@ public void updatePowderSnow() { if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_16_4)) return; // The client first desync's this attribute - player.compensatedEntities.getSelf().playerSpeed.getModifiers().removeIf(modifier -> modifier.getUUID().equals(CompensatedEntities.SNOW_MODIFIER_UUID)); + player.compensatedEntities.getSelf().playerSpeed.getModifiers().removeIf(modifier -> modifier.getUUID().equals(CompensatedEntities.SNOW_MODIFIER_UUID) || modifier.getName().getKey().equals("powder_snow")); // And then re-adds it using purely what the server has sent it StateType type = BlockProperties.getOnPos(player, player.mainSupportingBlockData, new Vector3d(player.x, player.y, player.z)); diff --git a/src/main/java/ac/grim/grimac/utils/collisions/datatypes/ComplexCollisionBox.java b/src/main/java/ac/grim/grimac/utils/collisions/datatypes/ComplexCollisionBox.java index 08c2f82f4f..23a0fe0f77 100644 --- a/src/main/java/ac/grim/grimac/utils/collisions/datatypes/ComplexCollisionBox.java +++ b/src/main/java/ac/grim/grimac/utils/collisions/datatypes/ComplexCollisionBox.java @@ -5,6 +5,7 @@ import java.util.List; public class ComplexCollisionBox implements CollisionBox { + private final List boxes = new ArrayList<>(); public ComplexCollisionBox(CollisionBox... boxes) { diff --git a/src/main/java/ac/grim/grimac/utils/collisions/datatypes/HexCollisionBox.java b/src/main/java/ac/grim/grimac/utils/collisions/datatypes/HexCollisionBox.java index 415c1e99e3..5b08696393 100644 --- a/src/main/java/ac/grim/grimac/utils/collisions/datatypes/HexCollisionBox.java +++ b/src/main/java/ac/grim/grimac/utils/collisions/datatypes/HexCollisionBox.java @@ -1,6 +1,7 @@ package ac.grim.grimac.utils.collisions.datatypes; public class HexCollisionBox extends SimpleCollisionBox { + public HexCollisionBox(double minX, double minY, double minZ, double maxX, double maxY, double maxZ) { this.minX = minX / 16d; this.minY = minY / 16d; diff --git a/src/main/java/ac/grim/grimac/utils/collisions/datatypes/SimpleCollisionBox.java b/src/main/java/ac/grim/grimac/utils/collisions/datatypes/SimpleCollisionBox.java index cdbed4ffaa..73395f7b3f 100644 --- a/src/main/java/ac/grim/grimac/utils/collisions/datatypes/SimpleCollisionBox.java +++ b/src/main/java/ac/grim/grimac/utils/collisions/datatypes/SimpleCollisionBox.java @@ -11,9 +11,11 @@ import java.util.List; public class SimpleCollisionBox implements CollisionBox { + public static final double COLLISION_EPSILON = 1.0E-7; + public double minX, minY, minZ, maxX, maxY, maxZ; - boolean isFullBlock = false; + private boolean isFullBlock = false; public SimpleCollisionBox() { this(0, 0, 0, 0, 0, 0, false); diff --git a/src/main/java/ac/grim/grimac/utils/latency/CompensatedEntities.java b/src/main/java/ac/grim/grimac/utils/latency/CompensatedEntities.java index ce2402de63..330c09dd67 100644 --- a/src/main/java/ac/grim/grimac/utils/latency/CompensatedEntities.java +++ b/src/main/java/ac/grim/grimac/utils/latency/CompensatedEntities.java @@ -10,6 +10,7 @@ import ac.grim.grimac.utils.nmsutil.WatchableIndexUtil; import com.github.retrooper.packetevents.PacketEvents; import com.github.retrooper.packetevents.manager.server.ServerVersion; +import com.github.retrooper.packetevents.protocol.attribute.Attributes; import com.github.retrooper.packetevents.protocol.entity.data.EntityData; import com.github.retrooper.packetevents.protocol.entity.type.EntityType; import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes; @@ -17,15 +18,19 @@ import com.github.retrooper.packetevents.protocol.potion.PotionType; import com.github.retrooper.packetevents.protocol.potion.PotionTypes; import com.github.retrooper.packetevents.protocol.world.BlockFace; +import com.github.retrooper.packetevents.resources.ResourceLocation; import com.github.retrooper.packetevents.util.Vector3d; import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerUpdateAttributes; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import org.bukkit.Bukkit; import java.util.*; public class CompensatedEntities { + private static final UUID SPRINTING_MODIFIER_UUID = UUID.fromString("662A6B8D-DA3E-4C1C-8813-96EA6097278D"); public static final UUID SNOW_MODIFIER_UUID = UUID.fromString("1eaf83ff-7207-4596-b37a-d7a07b3ec4ce"); + public final Int2ObjectOpenHashMap entityMap = new Int2ObjectOpenHashMap<>(40, 0.7f); public final Int2ObjectOpenHashMap serverPositionsMap = new Int2ObjectOpenHashMap<>(40, 0.7f); public Integer serverPlayerVehicle = null; @@ -108,12 +113,12 @@ public double getPlayerMovementSpeed() { public void updateAttributes(int entityID, List objects) { if (entityID == player.entityID) { for (WrapperPlayServerUpdateAttributes.Property snapshotWrapper : objects) { - final String key = snapshotWrapper.getKey(); - if (key.toUpperCase().contains("MOVEMENT")) { + if (snapshotWrapper.getAttribute() == Attributes.GENERIC_MOVEMENT_SPEED) { boolean found = false; List modifiers = snapshotWrapper.getModifiers(); for (WrapperPlayServerUpdateAttributes.PropertyModifier modifier : modifiers) { - if (modifier.getUUID().equals(SPRINTING_MODIFIER_UUID)) { + final ResourceLocation name = modifier.getName(); + if (name.getKey().equals(SPRINTING_MODIFIER_UUID.toString()) || name.getKey().equals("sprinting")) { found = true; break; } @@ -125,6 +130,8 @@ public void updateAttributes(int entityID, List modifiers = snapshotWrapper.getModifiers(); - modifiers.removeIf(modifier -> modifier.getUUID().equals(SPRINTING_MODIFIER_UUID)); + modifiers.removeIf(modifier -> modifier.getUUID().equals(SPRINTING_MODIFIER_UUID) || modifier.getName().getKey().equals("sprinting")); for (WrapperPlayServerUpdateAttributes.PropertyModifier attributemodifier : modifiers) { if (attributemodifier.getOperation() == WrapperPlayServerUpdateAttributes.PropertyModifier.Operation.ADDITION) diff --git a/src/main/java/ac/grim/grimac/utils/nmsutil/Collisions.java b/src/main/java/ac/grim/grimac/utils/nmsutil/Collisions.java index 4d0fa2717b..edb6f5842a 100644 --- a/src/main/java/ac/grim/grimac/utils/nmsutil/Collisions.java +++ b/src/main/java/ac/grim/grimac/utils/nmsutil/Collisions.java @@ -20,6 +20,9 @@ import com.github.retrooper.packetevents.protocol.world.states.type.StateType; import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes; import com.github.retrooper.packetevents.util.Vector3d; +import it.unimi.dsi.fastutil.floats.FloatArraySet; +import it.unimi.dsi.fastutil.floats.FloatArrays; +import it.unimi.dsi.fastutil.floats.FloatSet; import org.bukkit.Location; import org.bukkit.util.Vector; @@ -109,27 +112,50 @@ public static Vector collide(GrimPlayer player, double desiredX, double desiredY // While running up stairs and holding space, the player activates the "lastOnGround" part without otherwise being able to step // 0.03 movement must compensate for stepping elsewhere. Too much of a hack to include in this met5hod. - boolean movingIntoGround = (player.lastOnGround || (collisionResult.getY() != desiredY && (desiredY < 0 || clientVelY < 0))) || player.pointThreeEstimator.closeEnoughToGroundToStepWithPointThree(data, clientVelY); + boolean movingIntoGroundReal = player.pointThreeEstimator.closeEnoughToGroundToStepWithPointThree(data, clientVelY) || collisionResult.getY() != desiredY && (desiredY < 0 || clientVelY < 0); + boolean movingIntoGround = player.lastOnGround || movingIntoGroundReal; // If the player has x or z collision, is going in the downwards direction in the last or this tick, and can step up // If not, just return the collisions without stepping up that we calculated earlier if (stepUpHeight > 0.0F && movingIntoGround && (collisionResult.getX() != desiredX || collisionResult.getZ() != desiredZ)) { player.uncertaintyHandler.isStepMovement = true; - Vector regularStepUp = collideBoundingBoxLegacy(new Vector(desiredX, stepUpHeight, desiredZ), player.boundingBox, desiredMovementCollisionBoxes, order); - - // 1.7 clients do not have this stepping bug fix - if (player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_8)) { - Vector stepUpBugFix = collideBoundingBoxLegacy(new Vector(0, stepUpHeight, 0), player.boundingBox.copy().expandToCoordinate(desiredX, 0, desiredZ), desiredMovementCollisionBoxes, order); - if (stepUpBugFix.getY() < stepUpHeight) { - Vector stepUpBugFixResult = collideBoundingBoxLegacy(new Vector(desiredX, 0, desiredZ), player.boundingBox.copy().offset(0, stepUpBugFix.getY(), 0), desiredMovementCollisionBoxes, order).add(stepUpBugFix); - if (getHorizontalDistanceSqr(stepUpBugFixResult) > getHorizontalDistanceSqr(regularStepUp)) { - regularStepUp = stepUpBugFixResult; + // 1.21 significantly refactored this + if (player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_21)) { + SimpleCollisionBox box2 = movingIntoGroundReal ? player.boundingBox.copy().offset(0.0, collisionResult.getY(), 0.0) : player.boundingBox.copy(); + SimpleCollisionBox box3 = box2.expandToCoordinate(desiredX, stepUpHeight, desiredZ); + if (!movingIntoGroundReal) { + box3 = box3.expandToCoordinate(0.0, -1.0E-5F, 0.0); + } + + final List list2 = new ArrayList<>(); + getCollisionBoxes(player, box3, list2, false); + final float[] stepHeights = collectStepHeights(box2, list2, (float) stepUpHeight, (float) collisionResult.getY()); + + for (float g : stepHeights) { + Vector vec3d2 = collideBoundingBoxLegacy(new Vector(desiredX, g, desiredZ), box2, list2, order); + if (getHorizontalDistanceSqr(vec3d2) > getHorizontalDistanceSqr(collisionResult)) { + final double d = player.boundingBox.minY - box2.minY; + collisionResult = vec3d2.add(new Vector(0.0, -d, 0.0)); + break; + } + } + } else { + Vector regularStepUp = collideBoundingBoxLegacy(new Vector(desiredX, stepUpHeight, desiredZ), player.boundingBox, desiredMovementCollisionBoxes, order); + + // 1.7 clients do not have this stepping bug fix + if (player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_8)) { + Vector stepUpBugFix = collideBoundingBoxLegacy(new Vector(0, stepUpHeight, 0), player.boundingBox.copy().expandToCoordinate(desiredX, 0, desiredZ), desiredMovementCollisionBoxes, order); + if (stepUpBugFix.getY() < stepUpHeight) { + Vector stepUpBugFixResult = collideBoundingBoxLegacy(new Vector(desiredX, 0, desiredZ), player.boundingBox.copy().offset(0, stepUpBugFix.getY(), 0), desiredMovementCollisionBoxes, order).add(stepUpBugFix); + if (getHorizontalDistanceSqr(stepUpBugFixResult) > getHorizontalDistanceSqr(regularStepUp)) { + regularStepUp = stepUpBugFixResult; + } } } - } - if (getHorizontalDistanceSqr(regularStepUp) > getHorizontalDistanceSqr(collisionResult)) { - collisionResult = regularStepUp.add(collideBoundingBoxLegacy(new Vector(0, -regularStepUp.getY() + (player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_14) ? desiredY : 0), 0), player.boundingBox.copy().offset(regularStepUp.getX(), regularStepUp.getY(), regularStepUp.getZ()), desiredMovementCollisionBoxes, order)); + if (getHorizontalDistanceSqr(regularStepUp) > getHorizontalDistanceSqr(collisionResult)) { + collisionResult = regularStepUp.add(collideBoundingBoxLegacy(new Vector(0, -regularStepUp.getY() + (player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_14) ? desiredY : 0), 0), player.boundingBox.copy().offset(regularStepUp.getX(), regularStepUp.getY(), regularStepUp.getZ()), desiredMovementCollisionBoxes, order)); + } } } @@ -151,6 +177,30 @@ public static Vector collide(GrimPlayer player, double desiredX, double desiredY return bestOrderResult; } + private static float[] collectStepHeights(SimpleCollisionBox collisionBox, List collisions, float f, float stepHeight) { + FloatSet floatSet = new FloatArraySet(4); + + for (SimpleCollisionBox blockBox : collisions) { + // I DON'T KNOW WHAT THIS DOES, MOJANG!!!!! + // STOP USING ABSTRACTED-TO-HELL CONCEPTS IN IMPORTANT CODE + // I GIVE UP, SOMEONE ELSE IMPLEMENT THIS + for (double d : blockBox.getPointPositions(blockBox, Axis.Y)) { + float g = (float)(d - collisionBox.minY); + if (!(g < 0.0F) && g != stepHeight) { + if (g > f) { + break; + } + + floatSet.add(g); + } + } + } + + float[] fs = floatSet.toFloatArray(); + FloatArrays.unstableSort(fs); + return fs; + } + public static boolean addWorldBorder(GrimPlayer player, SimpleCollisionBox wantedBB, List listOfBlocks, boolean onlyCheckCollide) { // Worldborders were added in 1.8 // Don't add to border unless the player is colliding with it and is near it