Skip to content

Commit 0e8a872

Browse files
authored
Merge branch 'GrimAnticheat:2.0' into 2.0
2 parents 9b11eb3 + 21c119d commit 0e8a872

File tree

10 files changed

+120
-28
lines changed

10 files changed

+120
-28
lines changed

SECURITY.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
## Supported Versions
44

5-
Vulnerability must be reproducable on the latest grim version on spigotmc or newer.
5+
Vulnerability must be reproducible on the latest grim commit.
66

77
## Reporting a Vulnerability
88

9-
If there's a major bypass that would affect gameplay if reported publicly then join Grim's discord [here](https://discord.com/invite/FNRrcGAybJ) and message DefineOutside.
9+
If there's a major bypass that would affect gameplay if reported publicly then join Grim's discord [here](https://discord.com/invite/kqQAhTmkUF) and reach out to staff.

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ plugins {
1010

1111

1212
group = "ac.grim.grimac"
13-
version = "2.3.64"
13+
version = "2.3.65"
1414
description = "Libre simulation anticheat designed for 1.20 with 1.8-1.20 support, powered by PacketEvents 2.0."
1515
java.sourceCompatibility = JavaVersion.VERSION_1_8
1616
java.targetCompatibility = JavaVersion.VERSION_1_8

src/main/java/ac/grim/grimac/checks/impl/badpackets/BadPacketsZ.java

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ public BadPacketsZ(final GrimPlayer player) {
1919
super(player);
2020
}
2121

22-
private boolean exemptNextFinish = false;
23-
private Vector3i lastBlock, lastLastBlock = null;
22+
private boolean lastBlockWasInstantBreak = false;
23+
private Vector3i lastBlock, lastCancelledBlock, lastLastBlock = null;
2424
private final int exemptedY = player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_8) ? 4095 : 255;
2525

2626
// The client sometimes sends a wierd cancel packet
@@ -47,51 +47,59 @@ private String formatted(Vector3i vec) {
4747

4848
public void handle(PacketReceiveEvent event, WrapperPlayClientPlayerDigging dig) {
4949
if (dig.getAction() == DiggingAction.START_DIGGING) {
50-
lastLastBlock = lastBlock;
51-
lastBlock = dig.getBlockPosition();
50+
final Vector3i pos = dig.getBlockPosition();
5251

53-
exemptNextFinish = player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_14_4) && getBlockDamage(player, lastBlock) >= 1;
54-
return;
52+
lastBlockWasInstantBreak = getBlockDamage(player, pos) >= 1;
53+
lastCancelledBlock = null;
54+
lastLastBlock = lastBlock;
55+
lastBlock = pos;
5556
}
5657

5758
if (dig.getAction() == DiggingAction.CANCELLED_DIGGING) {
58-
if (shouldExempt(dig.getBlockPosition())) {
59+
final Vector3i pos = dig.getBlockPosition();
60+
61+
if (shouldExempt(pos)) {
62+
lastCancelledBlock = null;
5963
lastLastBlock = null;
6064
lastBlock = null;
6165
return;
6266
}
6367

64-
exemptNextFinish = false;
65-
66-
if ((lastBlock == null || !lastBlock.equals(dig.getBlockPosition())) && (lastLastBlock == null || !lastLastBlock.equals(dig.getBlockPosition()))) {
67-
if (flagAndAlert("action=CANCELLED_DIGGING, last=" + formatted(lastBlock) + "/" + formatted(lastLastBlock) + ", pos=" + formatted(dig.getBlockPosition()))) {
68-
if (shouldModifyPackets()) {
69-
event.setCancelled(true);
70-
player.onPacketCancel();
68+
if (!pos.equals(lastBlock)) {
69+
// https://github.com/GrimAnticheat/Grim/issues/1512
70+
if (player.getClientVersion().isOlderThan(ClientVersion.V_1_14_4) || (!lastBlockWasInstantBreak && pos.equals(lastCancelledBlock))) {
71+
if (flagAndAlert("action=CANCELLED_DIGGING" + ", last=" + formatted(lastBlock) + ", pos=" + formatted(pos))) {
72+
if (shouldModifyPackets()) {
73+
event.setCancelled(true);
74+
player.onPacketCancel();
75+
resyncPosition(player, pos);
76+
}
7177
}
7278
}
7379
}
7480

81+
lastCancelledBlock = pos;
7582
lastLastBlock = null;
7683
lastBlock = null;
84+
return;
7785
}
7886

7987
if (dig.getAction() == DiggingAction.FINISHED_DIGGING) {
80-
if (exemptNextFinish) {
81-
exemptNextFinish = false;
82-
return;
83-
}
88+
final Vector3i pos = dig.getBlockPosition();
8489

85-
if ((lastBlock == null || !lastBlock.equals(dig.getBlockPosition())) && (lastLastBlock == null || !lastLastBlock.equals(dig.getBlockPosition()))) {
86-
if (flagAndAlert("action=FINISHED_DIGGING, last=" + formatted(lastBlock) + "/" + formatted(lastLastBlock) + ", pos=" + formatted(dig.getBlockPosition()))) {
90+
// when a player looks away from the mined block, they send a cancel, and if they look at it again, they don't send another start. (thanks mojang!)
91+
if (!pos.equals(lastCancelledBlock) && (!lastBlockWasInstantBreak || player.getClientVersion().isOlderThan(ClientVersion.V_1_14_4)) && !pos.equals(lastBlock)) {
92+
if (flagAndAlert("action=FINISHED_DIGGING" + ", last=" + formatted(lastBlock) + ", pos=" + formatted(pos))) {
8793
if (shouldModifyPackets()) {
8894
event.setCancelled(true);
8995
player.onPacketCancel();
90-
resyncPosition(player, dig.getBlockPosition());
96+
resyncPosition(player, pos);
9197
}
9298
}
9399
}
94100

101+
lastCancelledBlock = null;
102+
95103
// 1.14.4+ clients don't send another start break in protected regions
96104
if (player.getClientVersion().isOlderThan(ClientVersion.V_1_14_4)) {
97105
lastLastBlock = null;

src/main/java/ac/grim/grimac/checks/impl/combat/Reach.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import ac.grim.grimac.player.GrimPlayer;
2222
import ac.grim.grimac.utils.collisions.datatypes.SimpleCollisionBox;
2323
import ac.grim.grimac.utils.data.packetentity.PacketEntity;
24+
import ac.grim.grimac.utils.data.packetentity.dragon.PacketEntityEnderDragonPart;
2425
import ac.grim.grimac.utils.nmsutil.ReachUtils;
2526
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
2627
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
@@ -68,7 +69,8 @@ public void onPacketReceive(final PacketReceiveEvent event) {
6869

6970
PacketEntity entity = player.compensatedEntities.entityMap.get(action.getEntityId());
7071
// Stop people from freezing transactions before an entity spawns to bypass reach
71-
if (entity == null) {
72+
// TODO: implement dragon parts?
73+
if (entity == null || entity instanceof PacketEntityEnderDragonPart) {
7274
// Only cancel if and only if we are tracking this entity
7375
// This is because we don't track paintings.
7476
if (shouldModifyPackets() && player.compensatedEntities.serverPositionsMap.containsKey(action.getEntityId())) {
@@ -140,7 +142,6 @@ private boolean isKnownInvalid(PacketEntity reachEntity) {
140142
private void tickBetterReachCheckWithAngle() {
141143
for (Map.Entry<Integer, Vector3d> attack : playerAttackQueue.entrySet()) {
142144
PacketEntity reachEntity = player.compensatedEntities.entityMap.get(attack.getKey().intValue());
143-
144145
if (reachEntity != null) {
145146
String result = checkReach(reachEntity, attack.getValue(), false);
146147
if (result != null) {

src/main/java/ac/grim/grimac/checks/impl/misc/FastBreak.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828

2929
// Based loosely off of Hawk BlockBreakSpeedSurvival
3030
// Also based loosely off of NoCheatPlus FastBreak
31-
// Also based off minecraft wiki: https://minecraft.fandom.com/wiki/Breaking#Instant_breaking
31+
// Also based off minecraft wiki: https://minecraft.wiki/w/Breaking#Instant_breaking
3232
@CheckData(name = "FastBreak", experimental = false)
3333
public class FastBreak extends Check implements PacketCheck {
3434
public FastBreak(GrimPlayer playerData) {
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package ac.grim.grimac.utils.data.packetentity.dragon;
2+
3+
public enum DragonPart {
4+
HEAD,
5+
NECK,
6+
BODY,
7+
TAIL,
8+
WING
9+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package ac.grim.grimac.utils.data.packetentity.dragon;
2+
3+
import ac.grim.grimac.player.GrimPlayer;
4+
import ac.grim.grimac.utils.data.packetentity.PacketEntity;
5+
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
6+
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
7+
8+
import java.util.ArrayList;
9+
import java.util.List;
10+
11+
public final class PacketEntityEnderDragon extends PacketEntity {
12+
13+
private final List<PacketEntityEnderDragonPart> parts = new ArrayList<>();
14+
15+
public PacketEntityEnderDragon(GrimPlayer player, int entityID, double x, double y, double z) {
16+
super(player, EntityTypes.ENDER_DRAGON, x, y, z);
17+
final Int2ObjectOpenHashMap<PacketEntity> entityMap = player.compensatedEntities.entityMap;
18+
parts.add(new PacketEntityEnderDragonPart(player, DragonPart.HEAD, x, y, z, 1.0F, 1.0F));
19+
parts.add(new PacketEntityEnderDragonPart(player, DragonPart.NECK, x, y, z, 3.0F, 3.0F));
20+
parts.add(new PacketEntityEnderDragonPart(player, DragonPart.BODY, x, y, z, 5.0F, 3.0F));
21+
parts.add(new PacketEntityEnderDragonPart(player, DragonPart.TAIL, x, y, z, 2.0F, 2.0F));
22+
parts.add(new PacketEntityEnderDragonPart(player, DragonPart.TAIL, x, y, z, 2.0F, 2.0F));
23+
parts.add(new PacketEntityEnderDragonPart(player, DragonPart.TAIL, x, y, z, 2.0F, 2.0F));
24+
parts.add(new PacketEntityEnderDragonPart(player, DragonPart.WING, x, y, z, 4.0F, 2.0F));
25+
parts.add(new PacketEntityEnderDragonPart(player, DragonPart.WING, x, y, z, 4.0F, 2.0F));
26+
for (int i = 1; i < parts.size() + 1; i++) {
27+
entityMap.put(entityID + i, parts.get(i - 1));
28+
}
29+
}
30+
31+
public List<PacketEntityEnderDragonPart> getParts() {
32+
return parts;
33+
}
34+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package ac.grim.grimac.utils.data.packetentity.dragon;
2+
3+
import ac.grim.grimac.player.GrimPlayer;
4+
import ac.grim.grimac.utils.data.packetentity.PacketEntity;
5+
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
6+
7+
public final class PacketEntityEnderDragonPart extends PacketEntity {
8+
9+
private final DragonPart part;
10+
private final float width, height;
11+
12+
public PacketEntityEnderDragonPart(GrimPlayer player, DragonPart part, double x, double y, double z, float width, float height) {
13+
super(player, EntityTypes.ENDER_DRAGON, x, y, z);
14+
this.part = part;
15+
this.width = width;
16+
this.height = height;
17+
}
18+
19+
public float getWidth() {
20+
return width;
21+
}
22+
23+
public float getHeight() {
24+
return height;
25+
}
26+
27+
public DragonPart getPart() {
28+
return part;
29+
}
30+
}

src/main/java/ac/grim/grimac/utils/latency/CompensatedEntities.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import ac.grim.grimac.utils.data.ShulkerData;
55
import ac.grim.grimac.utils.data.TrackerData;
66
import ac.grim.grimac.utils.data.packetentity.*;
7+
import ac.grim.grimac.utils.data.packetentity.dragon.PacketEntityEnderDragon;
78
import ac.grim.grimac.utils.math.GrimMath;
89
import ac.grim.grimac.utils.nmsutil.BoundingBoxSize;
910
import ac.grim.grimac.utils.nmsutil.WatchableIndexUtil;
@@ -63,6 +64,13 @@ public void removeEntity(int entityID) {
6364
PacketEntity entity = entityMap.remove(entityID);
6465
if (entity == null) return;
6566

67+
if (entity instanceof PacketEntityEnderDragon) {
68+
PacketEntityEnderDragon dragon = (PacketEntityEnderDragon) entity;
69+
for (int i = 1; i < dragon.getParts().size() + 1; i++) {
70+
entityMap.remove(entityID + i);
71+
}
72+
}
73+
6674
for (PacketEntity passenger : new ArrayList<>(entity.passengers)) {
6775
passenger.eject();
6876
}
@@ -237,6 +245,8 @@ public void addEntity(int entityID, EntityType entityType, Vector3d position, fl
237245
packetEntity = new PacketEntityTrackXRot(player, entityType, position.getX(), position.getY(), position.getZ(), xRot);
238246
} else if (EntityTypes.FISHING_BOBBER.equals(entityType)) {
239247
packetEntity = new PacketEntityHook(player, entityType, position.getX(), position.getY(), position.getZ(), data);
248+
} else if (EntityTypes.ENDER_DRAGON.equals(entityType)) {
249+
packetEntity = new PacketEntityEnderDragon(player, entityID, position.getX(), position.getY(), position.getZ());
240250
} else {
241251
packetEntity = new PacketEntity(player, entityType, position.getX(), position.getY(), position.getZ());
242252
}

src/main/resources/plugin.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: GrimAC
2-
version: 2.3.64
2+
version: 2.3.65
33
main: ac.grim.grimac.GrimAC
44
folia-supported: true
55
description: "Libre simulation anticheat designed for 1.20 with 1.8-1.20 support, powered by PacketEvents 2.0."

0 commit comments

Comments
 (0)