Skip to content

Commit

Permalink
Check for USE_ITEM after stupidity
Browse files Browse the repository at this point in the history
  • Loading branch information
SamB440 committed Jan 16, 2024
1 parent 9660021 commit ac55e2e
Show file tree
Hide file tree
Showing 20 changed files with 277 additions and 23 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package ac.grim.grimac.checks.impl.badpackets;

import ac.grim.grimac.checks.Check;
import ac.grim.grimac.checks.CheckData;
import ac.grim.grimac.checks.type.PacketCheck;
import ac.grim.grimac.player.GrimPlayer;
import ac.grim.grimac.utils.data.packetentity.PacketEntity;
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity;

@CheckData(name = "BadPacketsU")
public class BadPacketsU extends Check implements PacketCheck {

public BadPacketsU(final GrimPlayer player) {
super(player);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import com.github.retrooper.packetevents.wrapper.play.client.*;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerAcknowledgeBlockChanges;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerBlockChange;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSetSlot;
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
import org.bukkit.util.Vector;
Expand All @@ -54,7 +53,7 @@
public class CheckManagerListener extends PacketListenerAbstract {

public CheckManagerListener() {
super(PacketListenerPriority.LOW);
super(PacketListenerPriority.NORMAL);
}

// Copied from MCP...
Expand Down Expand Up @@ -314,33 +313,61 @@ private static void handleBlockPlaceOrUseItem(PacketWrapper packet, GrimPlayer p
}

private boolean isMojangStupid(GrimPlayer player, WrapperPlayClientPlayerFlying flying) {
if (player.packetStateData.lastPacketWasTeleport) {
// Just assume the player could have sent a stupidity packet in a teleport, for enforcement check
player.packetStateData.lastTeleportWasPotentiallyOnePointSeventeenDuplicate = true;
player.packetStateData.lastStupidity = null;
return false;
}

final Location location = flying.getLocation();
double threshold = player.getMovementThreshold();
// Don't check duplicate 1.17 packets (Why would you do this mojang?)
// Don't check rotation since it changes between these packets, with the second being irrelevant.
//
// removed a large rant, but I'm keeping this out of context insult below
// EVEN A BUNCH OF MONKEYS ON A TYPEWRITER COULDNT WRITE WORSE NETCODE THAN MOJANG
if (!player.packetStateData.lastPacketWasTeleport && flying.hasPositionChanged() && flying.hasRotationChanged() &&
final double distance = player.filterMojangStupidityOnMojangStupidity.distanceSquared(location.getPosition());
if (flying.hasPositionChanged() && flying.hasRotationChanged() &&
// Ground status will never change in this stupidity packet
((flying.isOnGround() == player.packetStateData.packetPlayerOnGround
// Mojang added this stupid mechanic in 1.17
&& (player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_17) &&
// Due to 0.03, we can't check exact position, only within 0.03
player.filterMojangStupidityOnMojangStupidity.distanceSquared(flying.getLocation().getPosition()) < threshold * threshold))
distance < threshold * threshold))
// If the player was in a vehicle, has position and look, and wasn't a teleport, then it was this stupid packet
|| player.compensatedEntities.getSelf().inVehicle())) {
// Player can only send this stupidity packet when holding an item
if (player.getInventory().getOffHand().isEmpty() && player.getInventory().getHeldItem().isEmpty()) {
return false;
}

// We detected this as a stupidity packet but due to lack of USE_ITEM after we were wrong
if (player.packetStateData.ignoreDuplicatePacket) {
player.packetStateData.ignoreDuplicatePacket = false;
return false;
}

player.packetStateData.detectedStupidity = true;
player.packetStateData.lastStupidity = location;

// Mark that we want this packet to be cancelled from reaching the server
// Since we delay USE_ITEM until the next valid flying packet, this is not an issue.
// Additionally, only yaw/pitch matters: https://github.com/GrimAnticheat/Grim/issues/1275#issuecomment-1872444018
player.packetStateData.cancelDuplicatePacket = true;

player.packetStateData.lastPacketWasOnePointSeventeenDuplicate = true;

if (player.xRot != flying.getLocation().getYaw() || player.yRot != flying.getLocation().getPitch()) {
if (player.xRot != location.getYaw() || player.yRot != location.getPitch()) {
player.lastXRot = player.xRot;
player.lastYRot = player.yRot;
}

// Take the pitch and yaw, just in case we were wrong about this being a stupidity packet
player.xRot = flying.getLocation().getYaw();
player.yRot = flying.getLocation().getPitch();
player.xRot = location.getYaw();
player.yRot = location.getPitch();

player.packetStateData.lastClaimedPosition = flying.getLocation().getPosition();
player.packetStateData.lastClaimedPosition = location.getPosition();
return true;
}
return false;
Expand Down Expand Up @@ -369,7 +396,7 @@ public void onPacketReceive(PacketReceiveEvent event) {
teleportData = flying.hasPositionChanged() && flying.hasRotationChanged() ? player.getSetbackTeleportUtil().checkTeleportQueue(position.getX(), position.getY(), position.getZ()) : new TeleportAcceptData();
player.packetStateData.lastPacketWasTeleport = teleportData.isTeleport();
// Teleports can't be stupidity packets
player.packetStateData.lastPacketWasOnePointSeventeenDuplicate = !player.packetStateData.lastPacketWasTeleport && isMojangStupid(player, flying);
player.packetStateData.lastPacketWasOnePointSeventeenDuplicate = isMojangStupid(player, flying);
}


Expand All @@ -392,6 +419,7 @@ public void onPacketReceive(PacketReceiveEvent event) {

// The player flagged crasher or timer checks, therefore we must protect predictions against these attacks
if (event.isCancelled() && (WrapperPlayClientPlayerFlying.isFlying(event.getPacketType()) || event.getPacketType() == PacketType.Play.Client.VEHICLE_MOVE)) {
player.packetStateData.cancelDuplicatePacket = false;
return;
}

Expand Down Expand Up @@ -536,6 +564,11 @@ public void onPacketReceive(PacketReceiveEvent event) {
// Such as the NoFall check setting the player to not be on the ground
player.checkManager.onPacketReceive(event);

if (player.packetStateData.cancelDuplicatePacket) {
event.setCancelled(true);
player.packetStateData.cancelDuplicatePacket = false;
}

// Finally, remove the packet state variables on this packet
player.packetStateData.lastPacketWasOnePointSeventeenDuplicate = false;
player.packetStateData.lastPacketWasTeleport = false;
Expand Down Expand Up @@ -667,6 +700,13 @@ private void handleFlying(GrimPlayer player, double x, double y, double z, float
player.packetStateData.packetPlayerOnGround = onGround;
}

if (!player.packetStateData.lastPacketWasOnePointSeventeenDuplicate) {
player.packetStateData.lastMovementWasDefinitelyOnePointSeventeenDuplicate = false;
if (!player.packetStateData.lastPacketWasTeleport) {
player.packetStateData.lastTeleportWasPotentiallyOnePointSeventeenDuplicate = false;
}
}

if (hasLook) {
player.xRot = yaw;
player.yRot = pitch;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
//
public class PacketBlockAction extends PacketListenerAbstract {
public PacketBlockAction() {
super(PacketListenerPriority.HIGH);
super(PacketListenerPriority.HIGHEST);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
public class PacketConfigurationListener extends PacketListenerAbstract {

public PacketConfigurationListener() {
super(PacketListenerPriority.LOW);
super(PacketListenerPriority.NORMAL);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
public class PacketEntityAction extends PacketListenerAbstract {

public PacketEntityAction() {
super(PacketListenerPriority.LOW);
super(PacketListenerPriority.NORMAL);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,9 @@ public class PacketPingListener extends PacketListenerAbstract {

// Must listen on LOWEST (or maybe low) to stop Tuinity packet limiter from kicking players for transaction/pong spam
public PacketPingListener() {
super(PacketListenerPriority.LOWEST);
super(PacketListenerPriority.LOW);
}


@Override
public void onPacketReceive(PacketReceiveEvent event) {
if (event.getPacketType() == PacketType.Play.Client.WINDOW_CONFIRMATION) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
public class PacketPlayerAttack extends PacketListenerAbstract {

public PacketPlayerAttack() {
super(PacketListenerPriority.LOW);
super(PacketListenerPriority.NORMAL);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
public class PacketPlayerCooldown extends PacketListenerAbstract {

public PacketPlayerCooldown() {
super(PacketListenerPriority.HIGH);
super(PacketListenerPriority.HIGHEST);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
public class PacketPlayerDigging extends PacketListenerAbstract {

public PacketPlayerDigging() {
super(PacketListenerPriority.LOW);
super(PacketListenerPriority.NORMAL);
}

public static void handleUseItem(GrimPlayer player, ItemStack item, InteractionHand hand) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
public class PacketPlayerRespawn extends PacketListenerAbstract {

public PacketPlayerRespawn() {
super(PacketListenerPriority.HIGH);
super(PacketListenerPriority.HIGHEST);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
public class PacketPlayerSteer extends PacketListenerAbstract {

public PacketPlayerSteer() {
super(PacketListenerPriority.LOW);
super(PacketListenerPriority.NORMAL);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

public class PacketSelfMetadataListener extends PacketListenerAbstract {
public PacketSelfMetadataListener() {
super(PacketListenerPriority.HIGH);
super(PacketListenerPriority.HIGHEST);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
public class PacketServerTeleport extends PacketListenerAbstract {

public PacketServerTeleport() {
super(PacketListenerPriority.LOW);
super(PacketListenerPriority.NORMAL);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class PacketSetWrapperNull extends PacketListenerAbstract {
// The two packets we change are clientbound entity metadata (to fix a netcode issue)
// and the serverbound player flying packets (to patch NoFall)
public PacketSetWrapperNull() {
super(PacketListenerPriority.HIGHEST);
super(PacketListenerPriority.MONITOR);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package ac.grim.grimac.events.packets.patch;

import ac.grim.grimac.GrimAPI;
import ac.grim.grimac.checks.impl.badpackets.BadPacketsU;
import ac.grim.grimac.player.GrimPlayer;
import com.github.retrooper.packetevents.PacketEvents;
import com.github.retrooper.packetevents.event.PacketListenerAbstract;
import com.github.retrooper.packetevents.event.PacketListenerPriority;
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.protocol.world.BlockFace;
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerBlockPlacement;
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;

// This runs before anything else, so this way we can simulate receiving flying.
public class EnforceUseItemStupidity extends PacketListenerAbstract {

public EnforceUseItemStupidity() {
super(PacketListenerPriority.LOWEST);
}

@Override
public void onPacketReceive(PacketReceiveEvent event) {
GrimPlayer player = GrimAPI.INSTANCE.getPlayerDataManager().getPlayer(event.getUser());
if (player == null) return;

// Stupidity packet only exists on 1.17+
if (player.getClientVersion().isOlderThan(ClientVersion.V_1_17)) return;

final boolean wasPotentiallyOnePointSeventeenDuplicate = player.packetStateData.lastTeleportWasPotentiallyOnePointSeventeenDuplicate;
if (isUseItem(event)) {
player.packetStateData.lastTeleportWasPotentiallyOnePointSeventeenDuplicate = false;
if (!player.packetStateData.detectedStupidity && !wasPotentiallyOnePointSeventeenDuplicate) {
// The player MUST send a stupidity packet before use item
player.checkManager.getPacketCheck(BadPacketsU.class).flagAndAlert("type=skipped_stupid");
return;
}
}

player.packetStateData.lastTeleportWasPotentiallyOnePointSeventeenDuplicate = false;

// If we received a believed stupidity packet, the next packet MUST be USE_ITEM.
// If not, we were wrong or the client is attempting to fake stupidity.
if (player.packetStateData.detectedStupidity || wasPotentiallyOnePointSeventeenDuplicate) {
if (isUseItem(event)) {
// Valid stupidity packet.
player.packetStateData.detectedStupidity = false;

// Possibly delay this USE_ITEM packet.
player.checkManager.getPacketCheck(UseItemDelayer.class).addDelayed(event);

player.packetStateData.lastLastStupidity = player.packetStateData.lastStupidity;
player.packetStateData.lastStupidity = null;
player.packetStateData.lastMovementWasDefinitelyOnePointSeventeenDuplicate = true;
// Bukkit.broadcastMessage("valid stupidity packet");
return;
}

// Reset
player.packetStateData.detectedStupidity = false;
player.packetStateData.lastMovementWasDefinitelyOnePointSeventeenDuplicate = false;

// Let's ignore teleports
if (player.packetStateData.lastStupidity == null || wasPotentiallyOnePointSeventeenDuplicate) return; // Probably a teleport

// We were wrong about it being stupidity, or the client is attempting to fake stupidity, reprocess this packet as non-stupidity
player.packetStateData.ignoreDuplicatePacket = true;

PacketEvents.getAPI().getPlayerManager().receivePacket(player.bukkitPlayer, new WrapperPlayClientPlayerFlying(true, true, player.packetStateData.packetPlayerOnGround, player.packetStateData.lastStupidity));
// Bukkit.broadcastMessage("not stupidity");
}
}

private boolean isUseItem(PacketReceiveEvent event) {
// This is USE_ITEM but translated by via
if (PacketEvents.getAPI().getServerManager().getVersion().isOlderThan(ServerVersion.V_1_9) && event.getPacketType() == PacketType.Play.Client.PLAYER_BLOCK_PLACEMENT) {
return new WrapperPlayClientPlayerBlockPlacement(event).getFace() == BlockFace.OTHER;
}
return event.getPacketType() == PacketType.Play.Client.USE_ITEM;
}
}
Loading

0 comments on commit ac55e2e

Please sign in to comment.