Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4933fd9d4f |
No files matched your search
@@ -96,7 +96,7 @@ public class Check extends GrimProcessor implements AbstractCheck {
|
||||
if (event.isCancelled()) return false;
|
||||
|
||||
player.punishmentManager.handleViolation(this);
|
||||
lastViolationTime = System.currentTimeMillis();
|
||||
lastViolationTime = player.now();
|
||||
violations++;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
package ac.grim.grimac.checks.debug;
|
||||
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import com.github.retrooper.packetevents.protocol.player.User;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class DebugGrimPlayer extends GrimPlayer {
|
||||
|
||||
private static final long THRESHOLD_NANO = 200_000_000L; // 200ms
|
||||
private static final long THRESHOLD_MILLIS = 200;
|
||||
|
||||
// Global Offsets: Volatile so all threads see the pause adjustment immediately.
|
||||
// When the Netty thread pauses for 60s, it updates this.
|
||||
// The Scheduler thread sees the update and "stops" the timeout check.
|
||||
private volatile long offsetNano = 0;
|
||||
private volatile long offsetMillis = 0;
|
||||
|
||||
// ThreadLocal: Each thread tracks its OWN execution time.
|
||||
// This prevents the Scheduler Thread (pollData) from resetting the timer
|
||||
// while the Netty Thread is sitting at a breakpoint.
|
||||
private final ThreadLocal<Long> packetStartNano = ThreadLocal.withInitial(System::nanoTime);
|
||||
private final ThreadLocal<Long> packetStartMillis = ThreadLocal.withInitial(System::currentTimeMillis);
|
||||
|
||||
public DebugGrimPlayer(@NotNull User user) {
|
||||
super(user, System.currentTimeMillis(), System.nanoTime());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processingPacket() {
|
||||
// Reset the timer ONLY for the current thread (Netty or Scheduler)
|
||||
this.packetStartNano.set(System.nanoTime());
|
||||
this.packetStartMillis.set(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
@Override
|
||||
public long nano() {
|
||||
// SAFETY CHECK:
|
||||
// If something in the parent constructor calls nano() BEFORE we are fully initialized,
|
||||
// packetStartNano will be null. We must fallback to System time to prevent NPE.
|
||||
if (packetStartNano == null) return System.nanoTime();
|
||||
|
||||
long sysTime = System.nanoTime();
|
||||
|
||||
// 1. Get start time for THIS thread
|
||||
long start = packetStartNano.get();
|
||||
long executionTime = sysTime - start;
|
||||
|
||||
// 2. Check if THIS thread was paused/stuck
|
||||
if (executionTime > THRESHOLD_NANO) {
|
||||
// Update the global offset so ALL threads know to skip this time
|
||||
synchronized (this) {
|
||||
offsetNano += executionTime;
|
||||
}
|
||||
// Reset this thread's timer so we don't loop
|
||||
packetStartNano.set(sysTime);
|
||||
} else if (executionTime < 0) {
|
||||
// Self-healing for rare thread-local init edge cases or system clock jumps
|
||||
packetStartNano.set(sysTime);
|
||||
}
|
||||
|
||||
// 3. Return System Time minus the Global Pause Offset
|
||||
return sysTime - offsetNano;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long now() {
|
||||
if (packetStartMillis == null) return System.currentTimeMillis();
|
||||
|
||||
long sysTime = System.currentTimeMillis();
|
||||
long start = packetStartMillis.get();
|
||||
long executionTime = sysTime - start;
|
||||
|
||||
if (executionTime > THRESHOLD_MILLIS) {
|
||||
synchronized (this) {
|
||||
offsetMillis += executionTime;
|
||||
}
|
||||
packetStartMillis.set(sysTime);
|
||||
}
|
||||
|
||||
return sysTime - offsetMillis;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package ac.grim.grimac.checks.debug;
|
||||
|
||||
import ac.grim.grimac.utils.common.arguments.CommonGrimArguments;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
|
||||
public class GrimDebugSettings {
|
||||
|
||||
public static boolean shouldEnable() {
|
||||
// 1. If the argument is disabled, never enable debug mode.
|
||||
if (!CommonGrimArguments.DEBUG_BREAKPOINT_MODE.value()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 2. Check for Debugger (Startup Agent OR Dynamic Attach)
|
||||
return isDebuggerAttached();
|
||||
}
|
||||
|
||||
private static boolean isDebuggerAttached() {
|
||||
// Fast Path: Check startup arguments for -agentlib:jdwp
|
||||
if (ManagementFactory.getRuntimeMXBean().getInputArguments().toString().contains("jdwp")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Slow Path (Dynamic Attach): Scan threads for JDWP/Signal Dispatcher
|
||||
try {
|
||||
for (Thread t : Thread.getAllStackTraces().keySet()) {
|
||||
String name = t.getName();
|
||||
if (name.contains("JDWP")) return true;
|
||||
}
|
||||
} catch (Throwable ignored) {}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,7 @@ public class BadPacketsR extends Check implements PacketCheck {
|
||||
public void onPacketReceive(final PacketReceiveEvent event) {
|
||||
if (isTransaction(event.getPacketType()) && player.packetStateData.lastTransactionPacketWasValid) {
|
||||
long ms = (player.getPlayerClockAtLeast() - clock) / 1000000L;
|
||||
long diff = (System.currentTimeMillis() - lastTransTime);
|
||||
long diff = (player.now() - lastTransTime);
|
||||
if (diff > 2000 && ms > 2000) {
|
||||
if (positions == 0 && clock != 0 && player.gamemode != GameMode.SPECTATOR && !player.compensatedEntities.self.isDead) {
|
||||
flag("time=" + ms + "ms, " + "lst=" + diff + "ms, positions=" + positions);
|
||||
@@ -34,7 +34,7 @@ public class BadPacketsR extends Check implements PacketCheck {
|
||||
player.compensatedWorld.removeInvalidPistonLikeStuff(oldTransId);
|
||||
positions = 0;
|
||||
clock = player.getPlayerClockAtLeast();
|
||||
lastTransTime = System.currentTimeMillis();
|
||||
lastTransTime = player.now();
|
||||
oldTransId = player.lastTransactionSent.get();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,12 +67,12 @@ public class FastBreak extends Check implements BlockBreakCheck {
|
||||
// * can we translate back "up" to server version and run check against server version to avoid loading older registries?
|
||||
WrappedBlockState block = clientOlderThanServer ? WrappedBlockState.getByGlobalId(player.getClientVersion(), player.getViaTranslatedClientBlockID(blockBreak.block.getGlobalId())) : blockBreak.block;
|
||||
|
||||
startBreak = System.currentTimeMillis() - (targetBlockPosition == null ? 50 : 0); // ???
|
||||
startBreak = player.now() - (targetBlockPosition == null ? 50 : 0); // ???
|
||||
targetBlockPosition = blockBreak.position;
|
||||
|
||||
maximumBlockDamage = BlockBreakSpeed.getBlockDamage(player, block);
|
||||
|
||||
double breakDelay = System.currentTimeMillis() - lastFinishBreak;
|
||||
double breakDelay = player.now() - lastFinishBreak;
|
||||
|
||||
if (breakDelay >= 275) { // Reduce buffer if "close enough"
|
||||
blockDelayBalance *= 0.9;
|
||||
@@ -91,7 +91,7 @@ public class FastBreak extends Check implements BlockBreakCheck {
|
||||
|
||||
if (blockBreak.action == DiggingAction.FINISHED_DIGGING && targetBlockPosition != null) {
|
||||
double predictedTime = Math.ceil(1 / maximumBlockDamage) * 50;
|
||||
double realTime = System.currentTimeMillis() - startBreak;
|
||||
double realTime = player.now() - startBreak;
|
||||
double diff = predictedTime - realTime;
|
||||
|
||||
clampBalance();
|
||||
@@ -109,7 +109,7 @@ public class FastBreak extends Check implements BlockBreakCheck {
|
||||
}
|
||||
|
||||
// also set start time because the breaking netcode is fucked on 1.14.4+
|
||||
lastFinishBreak = startBreak = System.currentTimeMillis();
|
||||
lastFinishBreak = startBreak = player.now();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,18 +12,18 @@ public class NegativeTimer extends Timer implements PostPredictionCheck {
|
||||
|
||||
public NegativeTimer(GrimPlayer player) {
|
||||
super(player);
|
||||
timerBalanceRealTime = System.nanoTime() + clockDrift;
|
||||
timerBalanceRealTime = player.nano() + clockDrift;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPredictionComplete(final PredictionComplete predictionComplete) {
|
||||
// We can't negative timer check a 1.9+ player who is standing still.
|
||||
if (player.uncertaintyHandler.lastPointThree.hasOccurredSince(2) || !predictionComplete.isChecked()) {
|
||||
timerBalanceRealTime = System.nanoTime() + clockDrift;
|
||||
timerBalanceRealTime = player.nano() + clockDrift;
|
||||
}
|
||||
|
||||
if (timerBalanceRealTime < lastMovementPlayerClock - clockDrift) {
|
||||
int lostMS = (int) ((System.nanoTime() - timerBalanceRealTime) / 1e6);
|
||||
int lostMS = (int) ((player.nano() - timerBalanceRealTime) / 1e6);
|
||||
flagAndAlertWithSetback("-" + lostMS);
|
||||
timerBalanceRealTime += 50e6;
|
||||
}
|
||||
|
||||
@@ -14,8 +14,8 @@ public class Timer extends Check implements PacketCheck {
|
||||
protected long timerBalanceRealTime = 0;
|
||||
|
||||
// Default value is real time minus max keep-alive time
|
||||
protected long knownPlayerClockTime = (long) (System.nanoTime() - 6e10);
|
||||
protected long lastMovementPlayerClock = (long) (System.nanoTime() - 6e10);
|
||||
protected long knownPlayerClockTime = (long) (player.nano() - 6e10);
|
||||
protected long lastMovementPlayerClock = (long) (player.nano() - 6e10);
|
||||
|
||||
// How long should the player be able to fall back behind their ping? (nanos)
|
||||
// Default: 120 milliseconds
|
||||
@@ -71,7 +71,7 @@ public class Timer extends Check implements PacketCheck {
|
||||
}
|
||||
|
||||
public void doCheck(final PacketReceiveEvent event) {
|
||||
if (timerBalanceRealTime > System.nanoTime()) {
|
||||
if (timerBalanceRealTime > player.nano()) {
|
||||
if (flagAndAlert()) {
|
||||
// Cancel the packet
|
||||
if (shouldModifyPackets()) {
|
||||
|
||||
@@ -19,7 +19,7 @@ public class TimerLimit extends Timer {
|
||||
@Override
|
||||
public void doCheck(final PacketReceiveEvent event) {
|
||||
// 1:1 with Timer minus cancelling the packet
|
||||
if (timerBalanceRealTime > System.nanoTime()) {
|
||||
if (timerBalanceRealTime > player.nano()) {
|
||||
// If timer check already flagged, don't flag.
|
||||
if (!event.isCancelled()) {
|
||||
if (flagAndAlert() && shouldSetback()) {
|
||||
@@ -38,8 +38,8 @@ public class TimerLimit extends Timer {
|
||||
protected void limitFallBehind() {
|
||||
// Limit using transaction ping if over 1000ms (default)
|
||||
long playerClock = lastMovementPlayerClock;
|
||||
if (limitAbuseOverPing != -1 && System.nanoTime() - playerClock > limitAbuseOverPing) {
|
||||
playerClock = System.nanoTime() - limitAbuseOverPing;
|
||||
if (limitAbuseOverPing != -1 && player.nano() - playerClock > limitAbuseOverPing) {
|
||||
playerClock = player.nano() - limitAbuseOverPing;
|
||||
}
|
||||
timerBalanceRealTime = Math.max(timerBalanceRealTime, playerClock - clockDrift);
|
||||
}
|
||||
|
||||
@@ -495,7 +495,7 @@ public class CheckManagerListener extends PacketListenerAbstract {
|
||||
|
||||
if (event.getPacketType() == PacketType.Play.Client.PLAYER_BLOCK_PLACEMENT) {
|
||||
WrapperPlayClientPlayerBlockPlacement packet = new WrapperPlayClientPlayerBlockPlacement(event);
|
||||
player.lastBlockPlaceUseItem = System.currentTimeMillis();
|
||||
player.lastBlockPlaceUseItem = player.now();
|
||||
|
||||
ItemStack placedWith = player.inventory.getHeldItem();
|
||||
if (packet.getHand() == InteractionHand.OFF_HAND) {
|
||||
@@ -562,7 +562,7 @@ public class CheckManagerListener extends PacketListenerAbstract {
|
||||
if (event.getPacketType() == PacketType.Play.Client.USE_ITEM) {
|
||||
WrapperPlayClientUseItem packet = new WrapperPlayClientUseItem(event);
|
||||
player.placeUseItemPackets.add(new BlockPlaceSnapshot(packet, player.isSneaking));
|
||||
player.lastBlockPlaceUseItem = System.currentTimeMillis();
|
||||
player.lastBlockPlaceUseItem = player.now();
|
||||
}
|
||||
|
||||
// Call the packet checks last as they can modify the contents of the packet
|
||||
@@ -663,7 +663,7 @@ public class CheckManagerListener extends PacketListenerAbstract {
|
||||
}
|
||||
|
||||
private static void handleFlying(GrimPlayer player, double x, double y, double z, float yaw, float pitch, boolean hasPosition, boolean hasLook, boolean onGround, TeleportAcceptData teleportData, PacketReceiveEvent event) {
|
||||
long now = System.currentTimeMillis();
|
||||
long now = player.now();
|
||||
|
||||
if (!hasPosition) {
|
||||
// This may need to be secured later, although nothing that is very important relies on this
|
||||
@@ -759,7 +759,7 @@ public class CheckManagerListener extends PacketListenerAbstract {
|
||||
}
|
||||
|
||||
private static void handleDigging(GrimPlayer player, PacketReceiveEvent event) {
|
||||
player.lastBlockBreak = System.currentTimeMillis();
|
||||
player.lastBlockBreak = player.now();
|
||||
|
||||
final WrapperPlayClientPlayerDigging packet = new WrapperPlayClientPlayerDigging(event);
|
||||
final DiggingAction action = packet.getAction();
|
||||
|
||||
@@ -72,7 +72,7 @@ public class PacketPingListener extends PacketListenerAbstract {
|
||||
if (id <= 0) {
|
||||
if (player.didWeSendThatTrans.remove(id)) {
|
||||
player.packetStateData.lastServerTransWasValid = true;
|
||||
player.transactionsSent.add(new Pair<>(id, System.nanoTime()));
|
||||
player.transactionsSent.add(new Pair<>(id, player.nano()));
|
||||
player.lastTransactionSent.getAndIncrement();
|
||||
}
|
||||
}
|
||||
@@ -91,7 +91,7 @@ public class PacketPingListener extends PacketListenerAbstract {
|
||||
Short shortID = ((short) id);
|
||||
if (player.didWeSendThatTrans.remove(shortID)) {
|
||||
player.packetStateData.lastServerTransWasValid = true;
|
||||
player.transactionsSent.add(new Pair<>(shortID, System.nanoTime()));
|
||||
player.transactionsSent.add(new Pair<>(shortID, player.nano()));
|
||||
player.lastTransactionSent.getAndIncrement();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,7 +228,7 @@ public class PacketPlayerDigging extends PacketListenerAbstract {
|
||||
|
||||
// do we need to do this with block breaks too?
|
||||
// Prevent issues if the player switches slots, while lagging, standing still, and is placing blocks
|
||||
CheckManagerListener.handleQueuedPlaces(player, false, 0, 0, System.currentTimeMillis());
|
||||
CheckManagerListener.handleQueuedPlaces(player, false, 0, 0, player.now());
|
||||
|
||||
if (player.packetStateData.lastSlotSelected != slot) {
|
||||
if (player.isResetItemUsageOnSlotChange() && GrimAPI.INSTANCE.getItemResetHandler().getItemUsageHand(player.platformPlayer) == InteractionHand.MAIN_HAND) {
|
||||
|
||||
@@ -212,7 +212,7 @@ public class PacketPlayerRespawn extends PacketListenerAbstract {
|
||||
player.clientVelocity = new Vector3dm();
|
||||
if (!GrimAPI.INSTANCE.getSpectateManager().isSpectating(player.uuid)) {
|
||||
player.gamemode = respawn.getGameMode();
|
||||
}
|
||||
}
|
||||
if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_17)) {
|
||||
player.compensatedWorld.setDimension(respawn.getDimensionType(), event.getUser());
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ public class PacketWorldBorder extends Check implements PacketCheck {
|
||||
}
|
||||
|
||||
public double getCurrentDiameter() {
|
||||
double d0 = (double) (System.currentTimeMillis() - startTime) / ((double) endTime - startTime);
|
||||
double d0 = (double) (player.now() - startTime) / ((double) endTime - startTime);
|
||||
return d0 < 1.0D ? GrimMath.lerp(d0, oldDiameter, newDiameter) : newDiameter;
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ public class PacketWorldBorder extends Check implements PacketCheck {
|
||||
private void setLerp(double oldDiameter, double newDiameter, long length) {
|
||||
this.oldDiameter = oldDiameter;
|
||||
this.newDiameter = newDiameter;
|
||||
this.startTime = System.currentTimeMillis();
|
||||
this.startTime = player.now();
|
||||
this.endTime = this.startTime + length;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -158,7 +158,7 @@ public class BasePacketWorldReader extends PacketListenerAbstract {
|
||||
Vector3i blockPosition = blockChange.getBlockPosition();
|
||||
// Don't spam transactions (block changes are sent in batches)
|
||||
if (Math.abs(blockPosition.getX() - player.x) < range && Math.abs(blockPosition.getY() - player.y) < range && Math.abs(blockPosition.getZ() - player.z) < range &&
|
||||
player.lastTransSent + 2 < System.currentTimeMillis())
|
||||
player.lastTransSent + 2 < player.now())
|
||||
player.sendTransaction();
|
||||
|
||||
player.latencyUtils.addRealTimeTask(player.lastTransactionSent.get(), () -> player.compensatedWorld.updateBlock(blockPosition.getX(), blockPosition.getY(), blockPosition.getZ(), blockChange.getBlockId()));
|
||||
@@ -172,7 +172,7 @@ public class BasePacketWorldReader extends PacketListenerAbstract {
|
||||
final var blocks = multiBlockChange.getBlocks();
|
||||
for (WrapperPlayServerMultiBlockChange.EncodedBlock blockChange : blocks) {
|
||||
// Don't send a transaction unless it's within 16 blocks of the player
|
||||
if (Math.abs(blockChange.getX() - player.x) < range && Math.abs(blockChange.getY() - player.y) < range && Math.abs(blockChange.getZ() - player.z) < range && player.lastTransSent + 2 < System.currentTimeMillis()) {
|
||||
if (Math.abs(blockChange.getX() - player.x) < range && Math.abs(blockChange.getY() - player.y) < range && Math.abs(blockChange.getZ() - player.z) < range && player.lastTransSent + 2 < player.now()) {
|
||||
player.sendTransaction();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ public class ActionManager extends Check implements PacketCheck {
|
||||
if (action.getAction() == WrapperPlayClientInteractEntity.InteractAction.ATTACK) {
|
||||
player.totalFlyingPacketsSent = 0;
|
||||
attacking = true;
|
||||
lastAttack = System.currentTimeMillis();
|
||||
lastAttack = player.now();
|
||||
}
|
||||
} else if (isTickPacketIncludingNonMovement(event.getPacketType())) {
|
||||
player.totalFlyingPacketsSent++;
|
||||
@@ -33,6 +33,6 @@ public class ActionManager extends Check implements PacketCheck {
|
||||
}
|
||||
|
||||
public boolean hasAttackedSince(long time) {
|
||||
return System.currentTimeMillis() - lastAttack < time;
|
||||
return player.now() - lastAttack < time;
|
||||
}
|
||||
}
|
||||
@@ -75,8 +75,10 @@ public class CheckManager {
|
||||
private final ClassToInstanceMap<BlockPlaceCheck> blockPlaceChecks;
|
||||
private final ClassToInstanceMap<PostPredictionCheck> postPredictionChecks;
|
||||
private PacketEntityReplication packetEntityReplication = null;
|
||||
private final GrimPlayer player;
|
||||
|
||||
public CheckManager(GrimPlayer player) {
|
||||
this.player = player;
|
||||
packetChecks = new ImmutableClassToInstanceMap.Builder<PacketCheck>()
|
||||
.put(PacketOrderProcessor.class, player.packetOrderProcessor)
|
||||
.put(Reach.class, new Reach(player))
|
||||
@@ -294,6 +296,8 @@ public class CheckManager {
|
||||
}
|
||||
|
||||
public void onPacketReceive(final PacketReceiveEvent packet) {
|
||||
player.processingPacket();
|
||||
|
||||
for (PacketCheck check : packetChecks.values()) {
|
||||
check.onPacketReceive(packet);
|
||||
}
|
||||
@@ -309,6 +313,8 @@ public class CheckManager {
|
||||
}
|
||||
|
||||
public void onPacketSend(final PacketSendEvent packet) {
|
||||
player.processingPacket();
|
||||
|
||||
for (PacketCheck check : prePredictionChecks.values()) {
|
||||
check.onPacketSend(packet);
|
||||
}
|
||||
|
||||
@@ -177,7 +177,7 @@ public class PunishmentManager implements ConfigReloadable {
|
||||
public void handleViolation(Check check) {
|
||||
for (PunishGroup group : groups) {
|
||||
if (group.checks.contains(check)) {
|
||||
long currentTime = System.currentTimeMillis();
|
||||
long currentTime = player.now();
|
||||
|
||||
group.violations.put(currentTime, check);
|
||||
// Remove violations older than the defined time in the config
|
||||
|
||||
@@ -161,9 +161,9 @@ public class SetbackTeleportUtil extends Check implements PostPredictionCheck {
|
||||
if (isPendingSetback()) return; // Don't spam setbacks
|
||||
|
||||
// Only let us full resync once every five seconds to prevent unneeded bukkit load
|
||||
if (System.currentTimeMillis() - lastWorldResync > 5 * 1000) {
|
||||
if (player.now() - lastWorldResync > 5 * 1000) {
|
||||
player.resyncPositions(player.boundingBox.copy().expand(1));
|
||||
lastWorldResync = System.currentTimeMillis();
|
||||
lastWorldResync = player.now();
|
||||
}
|
||||
|
||||
Vector3dm clientVel = lastKnownGoodPosition.vector.clone();
|
||||
|
||||
@@ -120,13 +120,13 @@ public class GrimPlayer implements GrimUser {
|
||||
public long lastTransSent = 0;
|
||||
public long lastTransReceived = 0;
|
||||
@Getter
|
||||
private long playerClockAtLeast = System.nanoTime();
|
||||
private long playerClockAtLeast;
|
||||
public double lastWasClimbing = 0;
|
||||
public boolean canSwimHop = false;
|
||||
public int riptideSpinAttackTicks = 0;
|
||||
public int powderSnowFrozenTicks = 0;
|
||||
public boolean hasGravity = true;
|
||||
public final long joinTime = System.currentTimeMillis();
|
||||
public final long joinTime;
|
||||
public boolean playerEntityHasGravity = true;
|
||||
public VectorData predictedVelocity = new VectorData(new Vector3dm(), VectorData.VectorType.Normal);
|
||||
public Vector3dm actualMovement = new Vector3dm();
|
||||
@@ -272,6 +272,12 @@ public class GrimPlayer implements GrimUser {
|
||||
public boolean lastJumping;
|
||||
|
||||
public GrimPlayer(@NotNull User user) {
|
||||
this(user, System.currentTimeMillis(), System.nanoTime());
|
||||
}
|
||||
|
||||
protected GrimPlayer(@NotNull User user, long joinTime, long clockStart) {
|
||||
this.joinTime = joinTime;
|
||||
this.playerClockAtLeast = clockStart;
|
||||
this.user = user;
|
||||
this.uuid = user.getUUID();
|
||||
fireworks = new CompensatedFireworks(this); // Must be before checkmanager
|
||||
@@ -397,7 +403,7 @@ public class GrimPlayer implements GrimUser {
|
||||
// Transactions that we send don't count towards total limit
|
||||
if (viaPacketTracker != null) viaPacketTracker.setIntervalPackets(viaPacketTracker.getIntervalPackets() - 1);
|
||||
|
||||
if (skipped > 0 && System.currentTimeMillis() - joinTime > 5000)
|
||||
if (skipped > 0 && now() - joinTime > 5000)
|
||||
checkManager.getCheck(TransactionOrder.class).flagAndAlert("skipped: " + skipped);
|
||||
|
||||
do {
|
||||
@@ -406,14 +412,14 @@ public class GrimPlayer implements GrimUser {
|
||||
break;
|
||||
|
||||
lastTransactionReceived.incrementAndGet();
|
||||
lastTransReceived = System.currentTimeMillis();
|
||||
transactionPing = (System.nanoTime() - data.second());
|
||||
lastTransReceived = now();
|
||||
transactionPing = (this.nano() - data.second());
|
||||
playerClockAtLeast = data.second();
|
||||
} while (data.first() != id);
|
||||
|
||||
// A transaction means a new tick, so handle any block interactions
|
||||
CheckManagerListener.handleQueuedPlaces(this, false, 0, 0, System.currentTimeMillis());
|
||||
CheckManagerListener.handleQueuedBreaks(this, false, 0, 0, System.currentTimeMillis());
|
||||
CheckManagerListener.handleQueuedPlaces(this, false, 0, 0, now());
|
||||
CheckManagerListener.handleQueuedBreaks(this, false, 0, 0, now());
|
||||
latencyUtils.handleNettySyncTransaction(lastTransactionReceived.get());
|
||||
}
|
||||
|
||||
@@ -461,11 +467,11 @@ public class GrimPlayer implements GrimUser {
|
||||
if (user.getEncoderState() != ConnectionState.PLAY) return;
|
||||
|
||||
// Send a packet once every 15 seconds to avoid any memory leaks
|
||||
if (disableGrim && (System.nanoTime() - getPlayerClockAtLeast()) > 15e9) {
|
||||
if (disableGrim && (this.nano() - getPlayerClockAtLeast()) > 15e9) {
|
||||
return;
|
||||
}
|
||||
|
||||
lastTransSent = System.currentTimeMillis();
|
||||
lastTransSent = now();
|
||||
short transactionID = (short) (-1 * (transactionIDCounter.getAndIncrement() & 0x7FFF));
|
||||
try {
|
||||
|
||||
@@ -524,15 +530,20 @@ public class GrimPlayer implements GrimUser {
|
||||
}
|
||||
|
||||
public void pollData() {
|
||||
// Reset the debug timer for the Scheduler Thread.
|
||||
// In Production: This is a no-op (0 cost).
|
||||
// In Debug: This tells the clock "I am starting a new tick, don't freeze time."
|
||||
this.processingPacket();
|
||||
|
||||
// Send a transaction at least once a tick, for timer and post check purposes
|
||||
// Don't be the first to send the transaction, or we will stack overflow
|
||||
//
|
||||
// This will only really activate if there's no entities around the player being tracked
|
||||
// 80 is a magic value that is roughly every other tick, we don't want to spam too many packets.
|
||||
if (lastTransSent != 0 && lastTransSent + 80 < System.currentTimeMillis()) {
|
||||
if (lastTransSent != 0 && lastTransSent + 80 < now()) {
|
||||
sendTransaction(true); // send on netty thread
|
||||
}
|
||||
if ((System.nanoTime() - getPlayerClockAtLeast()) > maxTransactionTime * 1e9) {
|
||||
if ((this.nano() - getPlayerClockAtLeast()) > maxTransactionTime * 1e9) {
|
||||
timedOut();
|
||||
}
|
||||
|
||||
@@ -988,4 +999,27 @@ public class GrimPlayer implements GrimUser {
|
||||
|
||||
return blockStateId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current high-resolution time in nanoseconds.
|
||||
* In Debug Mode, this will subtract time spent paused at breakpoints.
|
||||
*/
|
||||
public long nano() {
|
||||
return System.nanoTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current wall-clock time in milliseconds.
|
||||
* In Debug Mode, this will subtract time spent paused at breakpoints.
|
||||
*/
|
||||
public long now() {
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called immediately when a packet starts processing.
|
||||
* Used by DebugGrimPlayer to differentiate "Lag" (Pre-Packet) from "Breakpoints" (Intra-Packet).
|
||||
* Optimized away (Dead Code Elimination) in production.
|
||||
*/
|
||||
public void processingPacket() {}
|
||||
}
|
||||
@@ -75,9 +75,9 @@ public class MovementCheckRunner extends Check implements PositionCheck {
|
||||
}
|
||||
}
|
||||
|
||||
long start = System.nanoTime();
|
||||
long start = player.nano();
|
||||
check(data);
|
||||
long length = System.nanoTime() - start;
|
||||
long length = player.nano() - start;
|
||||
|
||||
if (!player.disableGrim) {
|
||||
predictionNanos = (predictionNanos * 499 / 500d) + (length / 500d);
|
||||
@@ -352,7 +352,7 @@ public class MovementCheckRunner extends Check implements PositionCheck {
|
||||
|
||||
boolean clientClaimsRiptide = player.packetStateData.tryingToRiptide;
|
||||
if (player.packetStateData.tryingToRiptide) {
|
||||
long currentTime = System.currentTimeMillis();
|
||||
long currentTime = player.now();
|
||||
boolean isInWater = player.isInWaterOrRain();
|
||||
|
||||
if (currentTime - player.packetStateData.lastRiptide < 450 || !isInWater) {
|
||||
|
||||
@@ -3,6 +3,8 @@ package ac.grim.grimac.utils.anticheat;
|
||||
import ac.grim.grimac.GrimAPI;
|
||||
import ac.grim.grimac.api.event.events.GrimJoinEvent;
|
||||
import ac.grim.grimac.api.event.events.GrimQuitEvent;
|
||||
import ac.grim.grimac.checks.debug.DebugGrimPlayer;
|
||||
import ac.grim.grimac.checks.debug.GrimDebugSettings;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.reflection.GeyserUtil;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
@@ -66,12 +68,21 @@ public class PlayerDataManager {
|
||||
|
||||
public void addUser(final @NotNull User user) {
|
||||
if (shouldCheck(user)) {
|
||||
GrimPlayer player = new GrimPlayer(user);
|
||||
GrimPlayer player = this.createPlayer(user);
|
||||
playerDataMap.put(user, player);
|
||||
GrimAPI.INSTANCE.getEventBus().post(new GrimJoinEvent(player));
|
||||
}
|
||||
}
|
||||
|
||||
public GrimPlayer createPlayer(User user) {
|
||||
// Simple Global Check
|
||||
if (GrimDebugSettings.shouldEnable()) {
|
||||
return new DebugGrimPlayer(user);
|
||||
} else {
|
||||
return new GrimPlayer(user);
|
||||
}
|
||||
}
|
||||
|
||||
public GrimPlayer remove(final @NotNull User user) {
|
||||
return playerDataMap.remove(user);
|
||||
}
|
||||
|
||||
@@ -29,4 +29,10 @@ public class CommonGrimArguments {
|
||||
* This setting is opt-in (default: false) and requires a server restart to change.
|
||||
*/
|
||||
public final static SystemArgument<Boolean> USE_CHAT_FAST_BYPASS = FACTORY.create(string("ChatFastBypass", true));
|
||||
/**
|
||||
* If TRUE, and a Debugger is detected attached to the JVM, Grim will use the
|
||||
* DebugGrimPlayer implementation which absorbs breakpoint pauses > 200ms.
|
||||
* Default: false (Safety).
|
||||
*/
|
||||
public final static SystemArgument<Boolean> DEBUG_BREAKPOINT_MODE = FACTORY.create(string("DebugBreakpointMode", false));
|
||||
}
|
||||
Reference in new issue
Block a user