Fix rapidly breaking/placing instabreak blocks and lighting tnt falses; currently LOSP no longer stops any illegal placements just flags. Will fix later

This commit is contained in:
Axionize committed 2024-11-16 14:41:03 -05:00
1 parent 6a3eec1960
commit 9f09fcd103
3 files changed
+37 -45

No files matched your search

@@ -17,11 +17,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 com.github.retrooper.packetevents.util.Vector3i;
import com.viaversion.viaversion.util.Triple;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@CheckData(name = "LineOfSightPlace")
@@ -37,7 +35,7 @@ public class LineOfSightPlace extends BlockPlaceCheck {
// Since this is used per-player we can avoid calling new[] by allocating it per-player in the check
private final SimpleCollisionBox[] collisionBoxBuffer = new SimpleCollisionBox[15];
public final Set<Triple<Vector3i, WrappedBlockState, Byte>> blocksChangedList = ConcurrentHashMap.newKeySet();
public final ConcurrentHashMap<Vector3i, WrappedBlockState> blocksChangedList = new ConcurrentHashMap<>();
public LineOfSightPlace(GrimPlayer player) {
super(player);
@@ -47,12 +45,16 @@ public class LineOfSightPlace extends BlockPlaceCheck {
public void onBlockPlace(final BlockPlace place) {
if (checkIfShouldSkip(place)) return;
if (flagBuffer > 0 && !didRayTraceHit(place)) {
// if (flagBuffer > 0 && !didRayTraceHit(place)) {
// ignorePost = true;
// // If the player hit and has flagged this check recently
// if (flagAndAlert("pre-flying: " + player.compensatedWorld.getWrappedBlockStateAt(place.getPlacedAgainstBlockLocation()).getType()) && shouldModifyPackets() && shouldCancel()) {
// place.resync(); // Deny the block placement.
// }
// }
// Only flag (which will only happen in post) if we miss pre
if (didRayTraceHit(place)) {
ignorePost = true;
// If the player hit and has flagged this check recently
if (flagAndAlert("pre-flying: " + player.compensatedWorld.getWrappedBlockStateAt(place.getPlacedAgainstBlockLocation()).getType()) && shouldModifyPackets() && shouldCancel()) {
place.resync(); // Deny the block placement.
}
}
}
@@ -71,11 +73,13 @@ public class LineOfSightPlace extends BlockPlaceCheck {
boolean hit = didRayTraceHit(place);
// This can false with rapidly moving yaw in 1.8+ clients
if (!hit) {
flagBuffer = 1;
// flagBuffer = 1;
flagAndAlert("post-flying: " + player.compensatedWorld.getWrappedBlockStateAt(place.getPlacedAgainstBlockLocation()).getType());
} else {
flagBuffer = Math.max(0, flagBuffer - 0.1);
}
// else {
// flagBuffer = Math.max(0, flagBuffer - 0.1);
// }
blocksChangedList.clear();
}
private boolean checkIfShouldSkip(BlockPlace place) {
@@ -93,10 +97,11 @@ public class LineOfSightPlace extends BlockPlaceCheck {
public void handleBlockChange(Vector3i vector3i, WrappedBlockState state) {
if (blocksChangedList.size() >= 60) return; // Don't let players freeze movement packets to grow this
// Only do this for nearby blocks
if (new Vector3d(vector3i.x, vector3i.y, vector3i.z).distanceSquared(new Vector3d(player.x, player.y, player.z)) > 6) return;
if (new Vector3d(vector3i.x, vector3i.y, vector3i.z).distanceSquared(new Vector3d(player.x, player.y, player.z)) > 36) return;
// Only do this if the state really had any world impact
if (state.equals(player.compensatedWorld.getWrappedBlockStateAt(vector3i))) return;
blocksChangedList.add(new Triple<>(vector3i, state, (byte) 2));
// this line always just returns the current world state in compensatedWorld
// if (state.equals(player.compensatedWorld.getWrappedBlockStateAt(vector3i))) return;
blocksChangedList.put(vector3i, state);
}
private boolean didRayTraceHit(BlockPlace place) {
@@ -191,7 +196,10 @@ public class LineOfSightPlace extends BlockPlaceCheck {
}
private boolean didRayTraceHitTargetBlock(double[] eyePos, double[] eyeDir, double maxDistance, int[] targetBlockVec, BlockFace expectedBlockFace) {
HitData hitData = BlockRayTrace.getNearestReachHitResult(player, eyePos, eyeDir, maxDistance, maxDistance, targetBlockVec, expectedBlockFace, collisionBoxBuffer, false);
HitData hitData = BlockRayTrace.getNearestReachHitResult(player, eyePos, eyeDir, maxDistance, maxDistance, targetBlockVec, expectedBlockFace, collisionBoxBuffer, null, false);
if (hitData == null || !hitData.success)
hitData = BlockRayTrace.getNearestReachHitResult(player, eyePos, eyeDir, maxDistance, maxDistance, targetBlockVec,
expectedBlockFace, collisionBoxBuffer, player.checkManager.getBlockPlaceCheck(LineOfSightPlace.class).blocksChangedList, false);
// we check for hitdata != null because of being in expanded hitbox, or there was no result, do we still need this?
return hitData != null && hitData.success;
@@ -1,41 +1,15 @@
package ac.grim.grimac.manager.tick.impl;
import ac.grim.grimac.GrimAPI;
import ac.grim.grimac.checks.impl.scaffolding.LineOfSightPlace;
import ac.grim.grimac.manager.tick.Tickable;
import ac.grim.grimac.player.GrimPlayer;
import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState;
import com.github.retrooper.packetevents.util.Vector3i;
import com.viaversion.viaversion.util.Triple;
import java.util.Iterator;
import java.util.Set;
public class UpdateChangedBlocksList implements Tickable {
@Override
public void tick() {
for (GrimPlayer player : GrimAPI.INSTANCE.getPlayerDataManager().getEntries()) {
Set<Triple<Vector3i, WrappedBlockState, Byte>> blocksChangedList = player.checkManager.getBlockPlaceCheck(LineOfSightPlace.class).blocksChangedList;
// Create an iterator to iterate over the set
Iterator<Triple<Vector3i, WrappedBlockState, Byte>> iterator = blocksChangedList.iterator();
// Iterate over the set
while (iterator.hasNext()) {
Triple<Vector3i, WrappedBlockState, Byte> entry = iterator.next();
// Decrement the byte value
byte newValue = (byte) (entry.third() - 1);
// If the new value is less than or equal to 1, remove the entry
if (newValue == 0) {
iterator.remove();
} else {
// Otherwise, update the entry with the new value
iterator.remove();
blocksChangedList.add(new Triple<>(entry.first(), entry.second(), newValue));
}
}
}
}
}
@@ -1,5 +1,6 @@
package ac.grim.grimac.utils.nmsutil;
import ac.grim.grimac.checks.impl.scaffolding.LineOfSightPlace;
import ac.grim.grimac.player.GrimPlayer;
import ac.grim.grimac.utils.collisions.HitboxData;
import ac.grim.grimac.utils.collisions.RaycastData;
@@ -23,6 +24,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
public class BlockRayTrace {
@@ -175,7 +177,8 @@ public class BlockRayTrace {
}
@Nullable
public static HitData getNearestReachHitResult(GrimPlayer player, double[] startPos, double[] lookVec, double currentDistance, double maxDistance, int[] targetBlockVec, BlockFace expectedBlockFace, SimpleCollisionBox[] boxes, boolean raycastContext) {
public static HitData getNearestReachHitResult(GrimPlayer player, double[] startPos, double[] lookVec, double currentDistance, double maxDistance, int[] targetBlockVec,
BlockFace expectedBlockFace, SimpleCollisionBox[] boxes, Map<Vector3i, WrappedBlockState> blockOverrides, boolean raycastContext) {
double[] endPos = new double[]{
startPos[0] + lookVec[0] * maxDistance,
startPos[1] + lookVec[1] * maxDistance,
@@ -183,6 +186,13 @@ public class BlockRayTrace {
};
return traverseBlocks(player, startPos, endPos, (block, vector3i) -> {
if (blockOverrides != null) {
WrappedBlockState blockState = blockOverrides.get(vector3i);
if (blockState != null) {
System.out.println("Old: " + blockState + "New: " + block);
block = blockState;
}
}
CollisionBox data;
if (!raycastContext) {
data = HitboxData.getBlockHitbox(player, player.getInventory().getHeldItem().getType().getPlacedType(), player.getClientVersion(), block, vector3i.x, vector3i.y, vector3i.z);
@@ -223,8 +233,8 @@ public class BlockRayTrace {
bestHitResult = distSq;
bestHitLoc = hitLoc;
bestFace = intercept.getSecond();
if (isTargetBlock && bestFace == expectedBlockFace) {
return new HitData(vector3i, new Vector(bestHitLoc[0], bestHitLoc[1], bestHitLoc[2]), bestFace, block, true);
if (isTargetBlock && (bestFace == expectedBlockFace || player.checkManager.getBlockPlaceCheck(LineOfSightPlace.class).blocksChangedList.get(vector3i) != null)) {
return new HitData(vector3i, new Vector(bestHitLoc[0], bestHitLoc[1], bestHitLoc[2]), expectedBlockFace, block, true);
}
}
}
@@ -242,7 +252,7 @@ public class BlockRayTrace {
if (bestHitLoc != null) {
HitData hitData = new HitData(vector3i, new Vector(bestHitLoc[0], bestHitLoc[1], bestHitLoc[2]), bestFace, block, isTargetBlock);
if (!raycastContext) {
HitData hitData2 = BlockRayTrace.getNearestReachHitResult(player, startPos, lookVec, maxDistance, maxDistance, targetBlockVec, expectedBlockFace, boxes, true);
HitData hitData2 = BlockRayTrace.getNearestReachHitResult(player, startPos, lookVec, maxDistance, maxDistance, targetBlockVec, expectedBlockFace, boxes, blockOverrides, true);
if (hitData2 != null) {
Vector startVector = new Vector(startPos[0], startPos[1], startPos[2]);
if (hitData2.getBlockHitLocation().subtract(startVector).lengthSquared() <