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:
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() <
|
||||
|
||||
Reference in new issue
Block a user