mirror of
https://github.com/funkemunky/KauriV3.git
synced 2026-07-01 02:08:27 +00:00
New checks and false positive fixes
- Completed Autoclicker (C), Oscillation check. - Added Autoclicker (D). Checks for autoblocks - Added NoFall (C). Fall distance check. - Updated Phase setback to patch bypass. - Added PacketPlayOutMapChunk wrapper. - Tracking MapChunk updates to client, patches false positive from blocks not being updated on anticheat from plugins like FAWE. - Now sniffs packets that aren't wrapped too when packet debugging player. - Updated Fly (A) to now account for vertical collisions on predictions. - Added experimental flag to CheckData. - Removed lastFlagRun alert limiter. - Increased amount of alerts that can be displayed in a second from 40 to 80.
This commit is contained in:
@@ -46,7 +46,7 @@ import java.util.concurrent.atomic.AtomicLong;
|
||||
@Init
|
||||
//@MavenLibrary(groupId = "co.aikar", artifactId = "acf-bukkit", version = "0.5.1", repo = @Repository(url = "https://nexus.funkemunky.cc/content/repositories/releases/"))
|
||||
@MavenLibrary(groupId = "com.google.guava", artifactId = "guava", version = "21.0", repo = @Repository(url = "https://repo1.maven.org/maven2"))
|
||||
@MavenLibrary(groupId = "it.unimi.dsi", artifactId = "fastutil", version = "8.5.6", repo = @Repository(url = "https://repo1.maven.org/maven2"))
|
||||
//@MavenLibrary(groupId = "it.unimi.dsi", artifactId = "fastutil", version = "8.5.6", repo = @Repository(url = "https://repo1.maven.org/maven2"))
|
||||
@MavenLibrary(groupId = "org.ow2.asm", artifactId = "asm", version = "9.2", repo = @Repository(url = "https://repo1.maven.org/maven2"))
|
||||
@MavenLibrary(groupId = "org.ow2.asm", artifactId = "asm-tree", version = "9.2", repo = @Repository(url = "https://repo1.maven.org/maven2"))
|
||||
public class Anticheat extends LoaderPlugin {
|
||||
|
||||
@@ -5,6 +5,7 @@ import dev.brighten.ac.api.AnticheatAPI;
|
||||
import dev.brighten.ac.api.check.CheckType;
|
||||
import dev.brighten.ac.api.check.ECheck;
|
||||
import dev.brighten.ac.api.event.AnticheatEvent;
|
||||
import dev.brighten.ac.api.event.result.CancelResult;
|
||||
import dev.brighten.ac.api.event.result.FlagResult;
|
||||
import dev.brighten.ac.api.event.result.PunishResult;
|
||||
import dev.brighten.ac.data.APlayer;
|
||||
@@ -17,6 +18,7 @@ import lombok.val;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.md_5.bungee.api.chat.*;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
@@ -29,7 +31,6 @@ public class Check implements ECheck {
|
||||
private final CheckData checkData;
|
||||
@Getter
|
||||
public float vl;
|
||||
private long lastFlagRun;
|
||||
@Getter
|
||||
@Setter
|
||||
private boolean enabled, punishable, cancellable;
|
||||
@@ -65,14 +66,6 @@ public class Check implements ECheck {
|
||||
.replace("%info%", info));
|
||||
}
|
||||
|
||||
public void onEnable() {
|
||||
|
||||
}
|
||||
|
||||
public void onDisable() {
|
||||
|
||||
}
|
||||
|
||||
private String addPlaceHolders(String string) {
|
||||
return string.replace("%player%", player.getBukkitPlayer().getName())
|
||||
.replace("%check%", checkData.name())
|
||||
@@ -83,7 +76,6 @@ public class Check implements ECheck {
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
/*
|
||||
CancelResult result = CancelResult.builder().cancelled(false).build();
|
||||
|
||||
for (AnticheatEvent event : AnticheatAPI.INSTANCE.getAllEvents()) {
|
||||
@@ -104,15 +96,15 @@ public class Check implements ECheck {
|
||||
.toLocation(player.getBukkitPlayer().getWorld()), 10);
|
||||
|
||||
player.getBukkitPlayer().teleport(ground);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
public void debug(String information, Object... variables) {
|
||||
if(!Anticheat.allowDebug) return;
|
||||
|
||||
if(debugInstances.containsKey(checkData.name())) {
|
||||
val list = debugInstances.get(checkData.name());
|
||||
val list = debugInstances.get(checkData.name());
|
||||
|
||||
if(list != null) {
|
||||
for (Tuple<UUID, UUID> tuple : list) {
|
||||
UUID toDebug = tuple.one;
|
||||
|
||||
@@ -130,8 +122,14 @@ public class Check implements ECheck {
|
||||
}
|
||||
}
|
||||
|
||||
public <T> Optional<T> find(Class<T> checkClass) {
|
||||
return Optional.ofNullable((T) player.getCheckHandler().findCheck((Class<? extends Check>) checkClass));
|
||||
public <T extends Check> Optional<T> find(Class<T> checkClass) {
|
||||
Check check = player.getCheckHandler().findCheck(checkClass);
|
||||
|
||||
if(check != null) {
|
||||
return Optional.of(checkClass.cast(check));
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
static List<TextComponent> devComponents = new ArrayList<>(), components = new ArrayList<>();
|
||||
@@ -160,8 +158,6 @@ public class Check implements ECheck {
|
||||
|
||||
public void flag(boolean punish, String information, Object... variables) {
|
||||
vl++;
|
||||
if(System.currentTimeMillis() - lastFlagRun < 50L) return;
|
||||
lastFlagRun = System.currentTimeMillis();
|
||||
|
||||
Anticheat.INSTANCE.getScheduler().execute(() -> {
|
||||
if(Anticheat.INSTANCE.getTps() < 18)
|
||||
@@ -186,9 +182,7 @@ public class Check implements ECheck {
|
||||
alertCountReset.reset();
|
||||
}
|
||||
|
||||
if(alertCount.incrementAndGet() < 40) {
|
||||
boolean dev = Anticheat.INSTANCE.getTps() < 18;
|
||||
|
||||
if(alertCount.incrementAndGet() < 80) {
|
||||
//Sending Discord webhook alert
|
||||
|
||||
List<BaseComponent> toSend = new ArrayList<>();
|
||||
@@ -245,11 +239,4 @@ public class Check implements ECheck {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private TextComponent createTxt(String txt) {
|
||||
return createTxt(txt, "");
|
||||
}
|
||||
private TextComponent createTxt(String txt, String info) {
|
||||
return new TextComponent(TextComponent.fromLegacyText(Color.translate(formatAlert(txt, info))));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ public @interface CheckData {
|
||||
boolean enabled() default true;
|
||||
boolean punishable() default true;
|
||||
boolean cancellable() default true;
|
||||
boolean experimental() default false;
|
||||
int punishVl() default 10;
|
||||
|
||||
ProtocolVersion minVersion() default ProtocolVersion.V1_7;
|
||||
|
||||
@@ -15,26 +15,71 @@ public class AutoclickerC extends Check {
|
||||
super(player);
|
||||
}
|
||||
|
||||
private int clicks;
|
||||
private long lastArm, totalTime;
|
||||
private long totalClickTime, lastClickTime;
|
||||
private int clicks, oscillationTime, oscillationLevel, lowest, highest;
|
||||
|
||||
@Async
|
||||
WTimedAction<WPacketPlayInArmAnimation> action = (packet, now) -> {
|
||||
WTimedAction<WPacketPlayInArmAnimation> action = (packet, timeStamp) -> {
|
||||
if(player.getInfo().isBreakingBlock()) return;
|
||||
|
||||
long delta = now - lastArm;
|
||||
clicks++;
|
||||
long diff = timeStamp - lastClickTime;
|
||||
|
||||
totalTime+= delta;
|
||||
if ((totalClickTime += diff) > 990) {
|
||||
|
||||
if(totalTime > 990) {
|
||||
if(clicks >= 3 && delta <= 200) {
|
||||
if (clicks >= 3 && diff <= 200.0f) {
|
||||
int time = oscillationTime + 1;
|
||||
int lowest = this.lowest;
|
||||
int highest = this.highest;
|
||||
|
||||
if (lowest == -1) {
|
||||
lowest = clicks;
|
||||
} else if (clicks < lowest) {
|
||||
lowest = clicks;
|
||||
}
|
||||
if (highest == -1) {
|
||||
highest = clicks;
|
||||
} else if (clicks > highest) {
|
||||
highest = clicks;
|
||||
}
|
||||
|
||||
int oscillation = highest - lowest;
|
||||
int oscLevel = oscillationLevel;
|
||||
if (time >= 9) {
|
||||
if (highest >= 8) {
|
||||
if (highest >= 9 && oscillation <= 5) {
|
||||
oscLevel += 2;
|
||||
}
|
||||
if (oscillation > 3 && oscLevel > 0) {
|
||||
--oscLevel;
|
||||
}
|
||||
} else if (oscLevel > 0) {
|
||||
--oscLevel;
|
||||
}
|
||||
time = 0;
|
||||
highest = -1;
|
||||
lowest = -1;
|
||||
}
|
||||
if (oscillation > 2) {
|
||||
time = 0;
|
||||
oscLevel = 0;
|
||||
highest = -1;
|
||||
lowest = -1;
|
||||
}
|
||||
if (oscLevel >= 10) {
|
||||
vl++;
|
||||
flag("osc=" + oscLevel);
|
||||
}
|
||||
debug("osc=%s level=%s high=%s low=%s", oscillation, oscLevel, highest, lowest);
|
||||
this.lowest = lowest;
|
||||
this.highest = highest;
|
||||
this.oscillationTime = time;
|
||||
this.oscillationLevel = oscLevel;
|
||||
|
||||
}
|
||||
totalClickTime = 0;
|
||||
clicks = 1;
|
||||
totalTime = 0;
|
||||
}
|
||||
|
||||
lastArm = now;
|
||||
lastClickTime = timeStamp;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
package dev.brighten.ac.check.impl.combat.autoclicker;
|
||||
|
||||
import dev.brighten.ac.api.check.CheckType;
|
||||
import dev.brighten.ac.check.Check;
|
||||
import dev.brighten.ac.check.CheckData;
|
||||
import dev.brighten.ac.check.WAction;
|
||||
import dev.brighten.ac.check.WTimedAction;
|
||||
import dev.brighten.ac.data.APlayer;
|
||||
import dev.brighten.ac.packet.ProtocolVersion;
|
||||
import dev.brighten.ac.packet.wrapper.in.WPacketPlayInArmAnimation;
|
||||
import dev.brighten.ac.packet.wrapper.in.WPacketPlayInBlockPlace;
|
||||
import dev.brighten.ac.packet.wrapper.in.WPacketPlayInFlying;
|
||||
import dev.brighten.ac.utils.math.cond.MaxDouble;
|
||||
import org.bukkit.Material;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
|
||||
@CheckData(name = "Autoclicker (D)", checkId = "autoclickerd", type = CheckType.AUTOCLICKER, punishVl = 15,
|
||||
maxVersion = ProtocolVersion.V1_8_9)
|
||||
public class AutoclickerD extends Check {
|
||||
public AutoclickerD(APlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
private static final EnumSet<Material> SWORDS = EnumSet.allOf(Material.class);
|
||||
|
||||
static {
|
||||
Arrays.stream(Material.values()).filter(material -> material.name().contains("SWORD"))
|
||||
.forEach(SWORDS::add);
|
||||
}
|
||||
|
||||
private long lastArm;
|
||||
private double cps;
|
||||
private boolean blocked;
|
||||
private int armTicks;
|
||||
private final MaxDouble verbose = new MaxDouble(40);
|
||||
|
||||
WTimedAction<WPacketPlayInArmAnimation> animation = (packet, timeStamp) -> {
|
||||
if(player.getInfo().isBreakingBlock()) return;
|
||||
|
||||
cps = 1000D / (timeStamp - lastArm);
|
||||
lastArm = timeStamp;
|
||||
armTicks++;
|
||||
};
|
||||
|
||||
WAction<WPacketPlayInFlying> flying = packet -> {
|
||||
if(blocked) {
|
||||
if(armTicks > 0) {
|
||||
if(armTicks == 1 && cps > 3) {
|
||||
if(cps > 7) verbose.add();
|
||||
if(verbose.value() > 15) {
|
||||
flag("arm=%s cps=%.3f lagging=%s", armTicks,
|
||||
cps, player.getLagInfo());
|
||||
}
|
||||
} else verbose.subtract(20);
|
||||
debug("cps=%s arm=%s vb=%s", cps, armTicks, verbose.value());
|
||||
}
|
||||
blocked = false;
|
||||
armTicks = 0;
|
||||
}
|
||||
};
|
||||
|
||||
WAction<WPacketPlayInBlockPlace> place = packet -> {
|
||||
if(packet.getItemStack() == null || !packet.getItemStack().getType().name().contains("SWORD")) return;
|
||||
blocked = true;
|
||||
};
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import dev.brighten.ac.packet.wrapper.in.WPacketPlayInFlying;
|
||||
import dev.brighten.ac.packet.wrapper.out.WPacketPlayOutPosition;
|
||||
import dev.brighten.ac.utils.*;
|
||||
import dev.brighten.ac.utils.world.types.SimpleCollisionBox;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.HashSet;
|
||||
@@ -24,9 +25,8 @@ public class Phase extends Check {
|
||||
}
|
||||
|
||||
private int ticks;
|
||||
private KLocation toSetback = null;
|
||||
|
||||
private Set<Vector> positions = new HashSet<>();
|
||||
private Location teleportLoc = null;
|
||||
|
||||
WAction<WPacketPlayOutPosition> positionOut = packet -> {
|
||||
KLocation loc = new KLocation(packet.getX(), packet.getY(), packet.getZ(),
|
||||
@@ -56,18 +56,6 @@ public class Phase extends Check {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(toSetback != null && packet.isMoved()) {
|
||||
if(player.getMovement().getTo().getLoc().distanceSquared(toSetback) < 1E-8) {
|
||||
toSetback = null;
|
||||
debug("Reached loc");
|
||||
} else {
|
||||
RunUtils.task(() -> player.getBukkitPlayer().teleport(toSetback
|
||||
.toLocation(player.getBukkitPlayer().getWorld())));
|
||||
debug("Hasnt reached location");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!packet.isMoved() || player.getCreation().isNotPassed(800L)
|
||||
|| player.getInfo().lastRespawn.isNotPassed(10)
|
||||
|| player.getInfo().isCreative() || player.getInfo().isCanFly()) {
|
||||
@@ -78,11 +66,13 @@ public class Phase extends Check {
|
||||
.anyMatch(v -> v.distanceSquared(player.getMovement().getTo().getLoc().toVector()) < 0.0001)) {
|
||||
debug("Returned: [%s, %s, %s]", player.getMovement().getTo().getX(),
|
||||
player.getMovement().getTo().getY(), player.getMovement().getTo().getZ());
|
||||
debug("Locs:");
|
||||
positions.stream().forEach(v -> debug("loc: [%s, %s, %s]", v.getX(), v.getY(), v.getZ()));
|
||||
teleportLoc = null;
|
||||
return false;
|
||||
} else if(player.getMovement().getMoveTicks() > 0 && player.getMovement().getTeleportsToConfirm() == 0) {
|
||||
positions.clear();
|
||||
} else if(teleportLoc != null) {
|
||||
RunUtils.task(() -> player.getBukkitPlayer().teleport(teleportLoc));
|
||||
return true;
|
||||
}
|
||||
|
||||
if(player.getMovement().getFrom().getLoc().distanceSquared(player.getMovement().getTo().getLoc()) > 400) {
|
||||
@@ -126,14 +116,12 @@ public class Phase extends Check {
|
||||
|
||||
double totalDelta = dx + dy + dz;
|
||||
|
||||
if(totalDelta > 0.001) {
|
||||
// Fixing calculated teleport location going wonky. If its 0.05 away, just set it to the from lOC.
|
||||
if(calculatedTo.distanceSquared(player.getMovement().getFrom().getLoc()) > 0.0025) {
|
||||
calculatedTo.setLocation(player.getMovement().getFrom().getLoc());
|
||||
}
|
||||
|
||||
RunUtils.task(() -> player.getBukkitPlayer().teleport(calculatedTo
|
||||
.toLocation(player.getBukkitPlayer().getWorld())));
|
||||
if(totalDelta > 0.00001) {
|
||||
RunUtils.task(() -> {
|
||||
teleportLoc = calculatedTo
|
||||
.toLocation(player.getBukkitPlayer().getWorld());
|
||||
player.getBukkitPlayer().teleport(teleportLoc);
|
||||
});
|
||||
flag("x=%.4f, y=%.4f, z=%.4f", dx, dy, dz);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,22 +7,26 @@ import dev.brighten.ac.check.WAction;
|
||||
import dev.brighten.ac.data.APlayer;
|
||||
import dev.brighten.ac.packet.ProtocolVersion;
|
||||
import dev.brighten.ac.packet.wrapper.in.WPacketPlayInFlying;
|
||||
import dev.brighten.ac.utils.Helper;
|
||||
import dev.brighten.ac.utils.MathUtils;
|
||||
import dev.brighten.ac.utils.MovementUtils;
|
||||
import dev.brighten.ac.utils.annotation.Async;
|
||||
import dev.brighten.ac.utils.timer.Timer;
|
||||
import dev.brighten.ac.utils.timer.impl.MillisTimer;
|
||||
import dev.brighten.ac.utils.world.types.SimpleCollisionBox;
|
||||
|
||||
@CheckData(name = "Fly (A)", checkId = "flya", type = CheckType.MOVEMENT)
|
||||
import java.util.List;
|
||||
|
||||
@CheckData(name = "Fly (A)", checkId = "flya", type = CheckType.MOVEMENT, experimental = true, punishVl = 7)
|
||||
public class FlyA extends Check {
|
||||
|
||||
public FlyA(APlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
private Timer lastPos = new MillisTimer();
|
||||
private final Timer lastPos = new MillisTimer();
|
||||
private float buffer;
|
||||
private static double mult = 0.98f, previousPrediction;
|
||||
private static final double mult = 0.98f;
|
||||
private boolean didNextPrediction = false;
|
||||
|
||||
@Async
|
||||
@@ -51,7 +55,6 @@ public class FlyA extends Check {
|
||||
|
||||
if(Math.abs(player.getMovement().getDeltaY() - toCheck)
|
||||
< Math.abs(player.getMovement().getDeltaY() - predicted)) {
|
||||
previousPrediction = predicted;
|
||||
predicted = toCheck;
|
||||
didNextPrediction = true;
|
||||
}
|
||||
@@ -65,11 +68,30 @@ public class FlyA extends Check {
|
||||
debug("Setting y to 0");
|
||||
}
|
||||
|
||||
if(player.getBlockInfo().blocksBelow || player.getInfo().isNearGround()) {
|
||||
List<SimpleCollisionBox> list = Helper.getCollisions(player,
|
||||
player.getMovement().getFrom().getBox().copy().addCoord(player.getMovement().getDeltaX(), predicted,
|
||||
player.getMovement().getDeltaZ()));
|
||||
SimpleCollisionBox axisalignedbb4 = player.getMovement().getFrom().getBox();
|
||||
SimpleCollisionBox axisalignedbb5 = axisalignedbb4.copy().addCoord(player.getMovement().getDeltaX(),
|
||||
0.0D, player.getMovement().getDeltaZ());
|
||||
double d9 = predicted;
|
||||
|
||||
for (SimpleCollisionBox axisalignedbb6 : list) {
|
||||
d9 = axisalignedbb6.calculateYOffset(axisalignedbb5, d9);
|
||||
}
|
||||
|
||||
if(predicted != d9) {
|
||||
debug("Collided!");
|
||||
}
|
||||
|
||||
predicted = d9;
|
||||
}
|
||||
|
||||
double deltaPredict = MathUtils.getDelta(player.getMovement().getDeltaY(), predicted);
|
||||
|
||||
if(!player.getInfo().isGeneralCancel()
|
||||
&& player.getMovement().getTeleportsToConfirm() == 0
|
||||
&& player.getInfo().getBlockAbove().isPassed(1)
|
||||
&& !player.getInfo().isOnLadder()
|
||||
&& player.getInfo().climbTimer.isPassed(2)
|
||||
&& !player.getBlockInfo().inWeb
|
||||
@@ -77,15 +99,13 @@ public class FlyA extends Check {
|
||||
&& !player.getBlockInfo().inScaffolding
|
||||
&& player.getInfo().getLastLiquid().isPassed(2)
|
||||
&& !player.getBlockInfo().fenceBelow
|
||||
&& !packet.isOnGround()
|
||||
&& player.getInfo().worldLoaded
|
||||
&& !player.getInfo().isServerGround()
|
||||
&& !player.getBlockInfo().onHalfBlock
|
||||
&& player.getInfo().getVelocity().isPassed(1)
|
||||
&& !player.getBlockInfo().onSlime
|
||||
&& deltaPredict > (player.getInfo().getClientAirTicks() < 3 ? 0.017 : 0.001)) {
|
||||
if(++buffer > 3) {
|
||||
buffer = 3;
|
||||
if(++buffer > 1) {
|
||||
buffer = 1;
|
||||
flag("dY=%.3f p=%.3f dx=%.3f", player.getMovement().getDeltaY(), predicted,
|
||||
player.getMovement().getDeltaXZ());
|
||||
cancel();
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package dev.brighten.ac.check.impl.movement.nofall;
|
||||
|
||||
import dev.brighten.ac.api.check.CheckType;
|
||||
import dev.brighten.ac.check.Check;
|
||||
import dev.brighten.ac.check.CheckData;
|
||||
import dev.brighten.ac.check.WAction;
|
||||
import dev.brighten.ac.data.APlayer;
|
||||
import dev.brighten.ac.packet.wrapper.in.WPacketPlayInFlying;
|
||||
import dev.brighten.ac.utils.MathUtils;
|
||||
|
||||
@CheckData(name = "NoFall (C)", checkId = "nofallc", type = CheckType.MOVEMENT, punishVl = 5, punishable = false, experimental = true)
|
||||
public class NoFallC extends Check {
|
||||
|
||||
public NoFallC(APlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
private double fallDistance, trueFallDistance;
|
||||
|
||||
WAction<WPacketPlayInFlying> flying = packet -> {
|
||||
if(!packet.isMoved())
|
||||
return;
|
||||
|
||||
if(player.getInfo().isGeneralCancel() || player.getMovement().getLastTeleport().isNotPassed(1)) {
|
||||
fallDistance = trueFallDistance = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if(player.getMovement().getDeltaY() > 0) {
|
||||
fallDistance = 0;
|
||||
trueFallDistance = 0;
|
||||
} else {
|
||||
if(packet.isOnGround()) {
|
||||
fallDistance = 0;
|
||||
} else fallDistance+= player.getMovement().getDeltaY();
|
||||
|
||||
if(player.getInfo().isServerGround()) {
|
||||
trueFallDistance = 0;
|
||||
fallDistance = 0;
|
||||
} else trueFallDistance+= player.getMovement().getDeltaY();
|
||||
|
||||
double delta = MathUtils.getDelta(trueFallDistance, fallDistance);
|
||||
|
||||
if(delta > 0.1) {
|
||||
flag("delta=%.4f;fd=%.4f;tf=%.4f", delta, fallDistance, trueFallDistance);
|
||||
fallDistance = trueFallDistance = 0;
|
||||
cancel();
|
||||
}
|
||||
|
||||
debug("calc=%.3f, true=%.3f", fallDistance, trueFallDistance);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -22,7 +22,7 @@ import org.bukkit.util.Vector;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@CheckData(name = "Horizontal", checkId = "horizontala", type = CheckType.MOVEMENT)
|
||||
@CheckData(name = "Horizontal", checkId = "horizontala", type = CheckType.MOVEMENT, experimental = true)
|
||||
public class Horizontal extends Check {
|
||||
private boolean lastLastClientGround;
|
||||
private float buffer;
|
||||
|
||||
@@ -148,6 +148,12 @@ public class PacketHandler {
|
||||
player.getBlockUpdateHandler().runUpdate(packet);
|
||||
break;
|
||||
}
|
||||
case MAP_CHUNK: {
|
||||
WPacketPlayOutMapChunk packet = (WPacketPlayOutMapChunk) packetObject;
|
||||
|
||||
player.getBlockUpdateHandler().runUpdate(packet);
|
||||
break;
|
||||
}
|
||||
case ENTITY_EFFECT: {
|
||||
WPacketPlayOutEntityEffect packet = (WPacketPlayOutEntityEffect) packetObject;
|
||||
|
||||
@@ -334,9 +340,14 @@ public class PacketHandler {
|
||||
}
|
||||
}
|
||||
|
||||
if(player.sniffing && type != PacketType.UNKNOWN) {
|
||||
player.sniffedPackets.add("[" + Anticheat.INSTANCE.getKeepaliveProcessor().tick + "] " +
|
||||
"" + type.name() + ": " + packetObject.toString());
|
||||
if(player.sniffing) {
|
||||
if(type != PacketType.UNKNOWN) {
|
||||
player.sniffedPackets.add("[" + Anticheat.INSTANCE.getKeepaliveProcessor().tick + "] " +
|
||||
"" + type.name() + ": " + packetObject.toString());
|
||||
} else {
|
||||
player.sniffedPackets.add("[" + Anticheat.INSTANCE.getKeepaliveProcessor().tick + "] (UNKNOWN) " +
|
||||
"" + packetObject.getClass().getSimpleName() + ": " + packetObject);
|
||||
}
|
||||
}
|
||||
|
||||
boolean cancelled = player.getCheckHandler().callSyncPacket(packetObject, timestamp);
|
||||
|
||||
@@ -4,13 +4,14 @@ import dev.brighten.ac.data.APlayer;
|
||||
import dev.brighten.ac.packet.wrapper.in.WPacketPlayInBlockDig;
|
||||
import dev.brighten.ac.packet.wrapper.in.WPacketPlayInBlockPlace;
|
||||
import dev.brighten.ac.packet.wrapper.out.WPacketPlayOutBlockChange;
|
||||
import dev.brighten.ac.packet.wrapper.out.WPacketPlayOutMapChunk;
|
||||
import dev.brighten.ac.packet.wrapper.out.WPacketPlayOutMultiBlockChange;
|
||||
import dev.brighten.ac.utils.BlockUtils;
|
||||
import dev.brighten.ac.utils.Materials;
|
||||
import dev.brighten.ac.utils.XMaterial;
|
||||
import dev.brighten.ac.utils.math.IntVector;
|
||||
import dev.brighten.ac.utils.world.types.RayCollision;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
@@ -21,7 +22,7 @@ import java.util.Optional;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class BlockUpdateHandler {
|
||||
private final Int2ObjectOpenHashMap<WrappedBlock> blockInformation = new Int2ObjectOpenHashMap<>();
|
||||
private final Object2ObjectOpenHashMap<IntVector, WrappedBlock> blockInformation = new Object2ObjectOpenHashMap<>();
|
||||
|
||||
private final APlayer player;
|
||||
|
||||
@@ -62,7 +63,7 @@ public class BlockUpdateHandler {
|
||||
player.getInfo().getLastPlace().reset();
|
||||
|
||||
synchronized (blockInformation) {
|
||||
blockInformation.put(pos.hashCode(), new WrappedBlock(pos.toLocation(player.getBukkitPlayer().getWorld()),
|
||||
blockInformation.put(pos, new WrappedBlock(pos.toLocation(player.getBukkitPlayer().getWorld()),
|
||||
place.getItemStack().getType(), (byte) 0));
|
||||
}
|
||||
}
|
||||
@@ -76,7 +77,7 @@ public class BlockUpdateHandler {
|
||||
player.getInfo().lastBlockUpdate.reset();
|
||||
if (dig.getDigType() == WPacketPlayInBlockDig.EnumPlayerDigType.STOP_DESTROY_BLOCK) {
|
||||
synchronized (blockInformation) {
|
||||
blockInformation.put(dig.getBlockPos().hashCode(),
|
||||
blockInformation.put(dig.getBlockPos(),
|
||||
new WrappedBlock(dig.getBlockPos().toLocation(player.getBukkitPlayer().getWorld()),
|
||||
Material.AIR, (byte) 0));
|
||||
}
|
||||
@@ -90,7 +91,7 @@ public class BlockUpdateHandler {
|
||||
// Updating block information
|
||||
player.runInstantAction(k -> {
|
||||
if (k.isEnd()) {
|
||||
blockInformation.put(packet.getBlockLocation().hashCode(),
|
||||
blockInformation.put(packet.getBlockLocation(),
|
||||
new WrappedBlock(packet.getBlockLocation().toLocation(player.getBukkitPlayer().getWorld()),
|
||||
packet.getMaterial(), packet.getBlockData()));
|
||||
}
|
||||
@@ -104,7 +105,10 @@ public class BlockUpdateHandler {
|
||||
if (k.isEnd()) {
|
||||
synchronized (blockInformation) {
|
||||
for (WPacketPlayOutMultiBlockChange.BlockChange info : packet.getChanges()) {
|
||||
blockInformation.put(info.getLocation().hashCode(),
|
||||
WrappedBlock block = new WrappedBlock(info.getLocation()
|
||||
.toLocation(player.getBukkitPlayer().getWorld()),
|
||||
info.getMaterial(), info.getData());
|
||||
blockInformation.put(info.getLocation(),
|
||||
new WrappedBlock(info.getLocation().toLocation(player.getBukkitPlayer().getWorld()),
|
||||
info.getMaterial(), info.getData()));
|
||||
}
|
||||
@@ -113,11 +117,23 @@ public class BlockUpdateHandler {
|
||||
});
|
||||
}
|
||||
|
||||
public void runUpdate(WPacketPlayOutMapChunk chunkUpdate) {
|
||||
player.runInstantAction(k -> {
|
||||
if(!k.isEnd()) {
|
||||
synchronized (blockInformation) {
|
||||
chunkUpdate.getBlocks().forEach((vec, mblock) -> {
|
||||
WrappedBlock block = new WrappedBlock(vec.toLocation(player.getBukkitPlayer().getWorld()),
|
||||
mblock.material, mblock.data);
|
||||
blockInformation.put(vec, block);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public WrappedBlock getBlock(IntVector loc) {
|
||||
synchronized (blockInformation) {
|
||||
|
||||
final int hashCode = loc.hashCode();
|
||||
WrappedBlock block = blockInformation.get(hashCode);
|
||||
WrappedBlock block = blockInformation.get(loc);
|
||||
|
||||
if (block == null) {
|
||||
Optional<Block> bukkitBlock = BlockUtils.getBlockAsync(
|
||||
@@ -128,7 +144,7 @@ public class BlockUpdateHandler {
|
||||
IntVector intVec = new IntVector(bloc.getBlockX(), bloc.getBlockY(), bloc.getBlockZ());
|
||||
block = new WrappedBlock(intVec.toLocation(player.getBukkitPlayer().getWorld()),
|
||||
bukkitBlock.get().getType(), bukkitBlock.get().getData());
|
||||
blockInformation.put(hashCode, block);
|
||||
blockInformation.put(loc, block);
|
||||
} else
|
||||
block = new WrappedBlock(loc.toLocation(player.getBukkitPlayer().getWorld()), Material.AIR, (byte)0);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.function.Consumer;
|
||||
@@ -22,7 +22,7 @@ import java.util.function.Consumer;
|
||||
|
||||
public class LoggerManager {
|
||||
|
||||
private final Queue<Log> logList = new LinkedBlockingQueue<>();
|
||||
private final Queue<Log> logList = new ConcurrentLinkedQueue<>();
|
||||
private String license;
|
||||
|
||||
/*
|
||||
@@ -53,7 +53,9 @@ public class LoggerManager {
|
||||
|
||||
if(log != null) {
|
||||
oos.writeUTF(log.toJson());
|
||||
} else break;
|
||||
} else if(logList.size() == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("Wrote " + i + " logs;" + logList.size());
|
||||
|
||||
@@ -86,4 +86,6 @@ public interface PacketConverter {
|
||||
WPacketPlayOutTransaction processServerTransaction(Object object);
|
||||
|
||||
Object processServerTransaction(WPacketPlayOutTransaction packet);
|
||||
|
||||
WPacketPlayOutMapChunk processMapChunk(Object object);
|
||||
}
|
||||
|
||||
@@ -148,6 +148,8 @@ public enum PacketType {
|
||||
return convert.processClientTransaction(object);
|
||||
case SERVER_TRANSACTION:
|
||||
return convert.processServerTransaction(object);
|
||||
case MAP_CHUNK:
|
||||
return convert.processMapChunk(object);
|
||||
default:
|
||||
return object;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,10 @@ import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class Processor_18 implements PacketConverter {
|
||||
@@ -743,6 +746,199 @@ public class Processor_18 implements PacketConverter {
|
||||
return new PacketPlayOutTransaction(packet.getId(), packet.getAction(), packet.isAccept());
|
||||
}
|
||||
|
||||
@Override
|
||||
public WPacketPlayOutMapChunk processMapChunk(Object object) {
|
||||
PacketPlayOutMapChunk packet = (PacketPlayOutMapChunk) object;
|
||||
|
||||
PacketDataSerializer serialized = serialize(packet);
|
||||
|
||||
int chunkX = serialized.readInt();
|
||||
int chunkZ = serialized.readInt();
|
||||
boolean groundUp = serialized.readBoolean();
|
||||
int size = serialized.readShort();
|
||||
byte[] locs = serialized.a();
|
||||
|
||||
ChunkSection[] sections = new ChunkSection[16];
|
||||
|
||||
//fillChunk(chunk, locs, size, groundUp);
|
||||
int i = 0;
|
||||
for (int index = 0; index < sections.length; ++index) {
|
||||
if ((size & 1 << index) != 0) {
|
||||
if (sections[index] == null) {
|
||||
sections[index] = new ChunkSection(index << 4, true);
|
||||
}
|
||||
|
||||
char[] achar = sections[index].getIdArray();
|
||||
|
||||
for (int k = 0; k < achar.length; ++k) {
|
||||
achar[k] = (char) ((locs[i + 1] & 255) << 8 | locs[i] & 255);
|
||||
i += 2;
|
||||
}
|
||||
} else if (groundUp && sections[index] != null) {
|
||||
sections[index] = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Map<IntVector, WPacketPlayOutMapChunk.MinBlock> blocks = new HashMap<>();
|
||||
|
||||
int sectionIndex = 0;
|
||||
for (ChunkSection section : sections) {
|
||||
if(section == null) {
|
||||
sectionIndex++;
|
||||
continue;
|
||||
}
|
||||
for (int idIndex = 0; idIndex < section.getIdArray().length; idIndex++) {
|
||||
//int i, int j, int k
|
||||
// x, y, z
|
||||
//j << 8 | k << 4 | i
|
||||
int y = (section.getYPosition() + (idIndex >> 8));
|
||||
int z = (chunkZ * 16 + (idIndex >> 4 & 0xF));
|
||||
int x = (chunkX * 16 + (idIndex & 0xF));
|
||||
|
||||
char id = section.getIdArray()[idIndex];
|
||||
|
||||
IBlockData iblockdata = Block.d.a(id);
|
||||
|
||||
Material material = CraftMagicNumbers.getMaterial(iblockdata.getBlock());
|
||||
|
||||
WPacketPlayOutMapChunk.MinBlock block = new WPacketPlayOutMapChunk
|
||||
.MinBlock(material, (byte)iblockdata.getBlock().toLegacyData(iblockdata));
|
||||
|
||||
blocks.put(new IntVector(x, y, z), block);
|
||||
}
|
||||
sectionIndex++;
|
||||
}
|
||||
|
||||
return WPacketPlayOutMapChunk.builder().blocks(blocks).build();
|
||||
}
|
||||
|
||||
public void fillChunk(Chunk chunk, byte[] p_177439_1_, int p_177439_2_, boolean p_177439_3_) {
|
||||
int i = 0;
|
||||
boolean flag = !chunk.getWorld().worldProvider.o();
|
||||
|
||||
for (int j = 0; j < chunk.getSections().length; ++j) {
|
||||
if ((p_177439_2_ & 1 << j) != 0) {
|
||||
if (chunk.getSections()[j] == null) {
|
||||
chunk.getSections()[j] = new ChunkSection(j << 4, flag);
|
||||
}
|
||||
|
||||
char[] achar = chunk.getSections()[j].getIdArray();
|
||||
|
||||
for (int k = 0; k < achar.length; ++k) {
|
||||
achar[k] = (char) ((p_177439_1_[i + 1] & 255) << 8 | p_177439_1_[i] & 255);
|
||||
i += 2;
|
||||
}
|
||||
} else if (p_177439_3_ && chunk.getSections()[j] != null) {
|
||||
chunk.getSections()[j] = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (p_177439_3_) {
|
||||
System.arraycopy(p_177439_1_, i, chunk.getBiomeIndex(), 0, chunk.getBiomeIndex().length);
|
||||
int k1 = i + chunk.getBiomeIndex().length;
|
||||
}
|
||||
|
||||
for (int j1 = 0; j1 < chunk.getSections().length; ++j1) {
|
||||
if (chunk.getSections()[j1] != null && (p_177439_2_ & 1 << j1) != 0) {
|
||||
chunk.getSections()[j1].recalcBlockCounts();
|
||||
}
|
||||
}
|
||||
|
||||
/*for (TileEntity tileentity : chunk.chunkTileEntityMap.values()) {
|
||||
tileentity.updateContainingBlockInfo();
|
||||
}*/
|
||||
}
|
||||
|
||||
/*
|
||||
public void handleChunkData(S21PacketChunkData packetIn) {
|
||||
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.gameController);
|
||||
|
||||
if (packetIn.func_149274_i()) {
|
||||
if (packetIn.getExtractedSize() == 0) {
|
||||
this.clientWorldController.doPreChunk(packetIn.getChunkX(), packetIn.getChunkZ(), false);
|
||||
return;
|
||||
}
|
||||
|
||||
this.clientWorldController.doPreChunk(packetIn.getChunkX(), packetIn.getChunkZ(), true);
|
||||
}
|
||||
|
||||
this.clientWorldController.invalidateBlockReceiveRegion(packetIn.getChunkX() << 4, 0, packetIn.getChunkZ() << 4, (packetIn.getChunkX() << 4) + 15, 256, (packetIn.getChunkZ() << 4) + 15);
|
||||
Chunk chunk = this.clientWorldController.getChunkFromChunkCoords(packetIn.getChunkX(), packetIn.getChunkZ());
|
||||
chunk.fillChunk(packetIn.func_149272_d(), packetIn.getExtractedSize(), packetIn.func_149274_i());
|
||||
this.clientWorldController.markBlockRangeForRenderUpdate(packetIn.getChunkX() << 4, 0, packetIn.getChunkZ() << 4, (packetIn.getChunkX() << 4) + 15, 256, (packetIn.getChunkZ() << 4) + 15);
|
||||
|
||||
if (!packetIn.func_149274_i() || !(this.clientWorldController.provider instanceof WorldProviderSurface)) {
|
||||
chunk.resetRelightChecks();
|
||||
}
|
||||
}
|
||||
*/
|
||||
/*
|
||||
public void fillChunk(byte[] p_177439_1_, int p_177439_2_, boolean p_177439_3_) {
|
||||
int i = 0;
|
||||
boolean flag = !this.worldObj.provider.getHasNoSky();
|
||||
|
||||
for (int j = 0; j < this.storageArrays.length; ++j) {
|
||||
if ((p_177439_2_ & 1 << j) != 0) {
|
||||
if (this.storageArrays[j] == null) {
|
||||
this.storageArrays[j] = new ExtendedBlockStorage(j << 4, flag);
|
||||
}
|
||||
|
||||
char[] achar = this.storageArrays[j].getData();
|
||||
|
||||
for (int k = 0; k < achar.length; ++k) {
|
||||
achar[k] = (char) ((p_177439_1_[i + 1] & 255) << 8 | p_177439_1_[i] & 255);
|
||||
i += 2;
|
||||
}
|
||||
} else if (p_177439_3_ && this.storageArrays[j] != null) {
|
||||
this.storageArrays[j] = null;
|
||||
}
|
||||
}
|
||||
|
||||
for (int l = 0; l < this.storageArrays.length; ++l) {
|
||||
if ((p_177439_2_ & 1 << l) != 0 && this.storageArrays[l] != null) {
|
||||
NibbleArray nibblearray = this.storageArrays[l].getBlocklightArray();
|
||||
System.arraycopy(p_177439_1_, i, nibblearray.getData(), 0, nibblearray.getData().length);
|
||||
i += nibblearray.getData().length;
|
||||
}
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
for (int i1 = 0; i1 < this.storageArrays.length; ++i1) {
|
||||
if ((p_177439_2_ & 1 << i1) != 0 && this.storageArrays[i1] != null) {
|
||||
NibbleArray nibblearray1 = this.storageArrays[i1].getSkylightArray();
|
||||
System.arraycopy(p_177439_1_, i, nibblearray1.getData(), 0, nibblearray1.getData().length);
|
||||
i += nibblearray1.getData().length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (p_177439_3_) {
|
||||
System.arraycopy(p_177439_1_, i, this.blockBiomeArray, 0, this.blockBiomeArray.length);
|
||||
int k1 = i + this.blockBiomeArray.length;
|
||||
}
|
||||
|
||||
for (int j1 = 0; j1 < this.storageArrays.length; ++j1) {
|
||||
if (this.storageArrays[j1] != null && (p_177439_2_ & 1 << j1) != 0) {
|
||||
this.storageArrays[j1].removeInvalidBlocks();
|
||||
}
|
||||
}
|
||||
|
||||
this.isLightPopulated = true;
|
||||
this.isTerrainPopulated = true;
|
||||
this.generateHeightMap();
|
||||
|
||||
for (TileEntity tileentity : this.chunkTileEntityMap.values()) {
|
||||
tileentity.updateContainingBlockInfo();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
private static int a(byte[] abyte, byte[] abyte1, int i) {
|
||||
System.arraycopy(abyte, 0, abyte1, i, abyte.length);
|
||||
return i + abyte.length;
|
||||
}
|
||||
|
||||
private PacketDataSerializer serialize(Packet<?> packet) {
|
||||
PacketDataSerializer serial = new PacketDataSerializer(Unpooled.buffer());
|
||||
try {
|
||||
|
||||
@@ -1735,7 +1735,6 @@ public enum XMaterial {
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Nonnull
|
||||
@SuppressWarnings("deprecation")
|
||||
public static XMaterial matchXMaterial(@Nonnull ItemStack item) {
|
||||
Objects.requireNonNull(item, "Cannot match null ItemStack");
|
||||
String material = item.getType().name();
|
||||
@@ -2011,7 +2010,6 @@ public enum XMaterial {
|
||||
* @since 3.0.0
|
||||
*/
|
||||
@Nonnull
|
||||
@SuppressWarnings("deprecation")
|
||||
public ItemStack setType(@Nonnull ItemStack item) {
|
||||
Objects.requireNonNull(item, "Cannot set material for null ItemStack");
|
||||
Material material = this.parseMaterial();
|
||||
@@ -2090,7 +2088,6 @@ public enum XMaterial {
|
||||
* @return data of this material, or 0 if none.
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public byte getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user