diff --git a/API/API.iml b/API/API.iml index fa63d4b..61e4724 100644 --- a/API/API.iml +++ b/API/API.iml @@ -1,12 +1,16 @@ - - - - - - SPIGOT - - - + + + + + + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 182f8fe..b491b18 100644 --- a/pom.xml +++ b/pom.xml @@ -101,7 +101,7 @@ com.h2database h2 - 1.4.199 + 2.1.214 provided diff --git a/src/main/java/dev/brighten/ac/Anticheat.java b/src/main/java/dev/brighten/ac/Anticheat.java index 5749a2b..d4bd0e0 100644 --- a/src/main/java/dev/brighten/ac/Anticheat.java +++ b/src/main/java/dev/brighten/ac/Anticheat.java @@ -49,7 +49,7 @@ import java.util.concurrent.atomic.AtomicLong; @Init @MavenLibrary(groupId = "co.aikar", artifactId = "acf-bukkit", version = "0.5.0", 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 = "com.h2database", artifactId = "h2", version = "1.4.199", repo = @Repository(url = "https://repo1.maven.org/maven2")) +@MavenLibrary(groupId = "com.h2database", artifactId = "h2", version = "2.1.214", 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")) diff --git a/src/main/java/dev/brighten/ac/check/Check.java b/src/main/java/dev/brighten/ac/check/Check.java index b59ccb2..c766024 100644 --- a/src/main/java/dev/brighten/ac/check/Check.java +++ b/src/main/java/dev/brighten/ac/check/Check.java @@ -149,7 +149,9 @@ public class Check implements ECheck { if(currentResult.isCancelled()) return; - Anticheat.INSTANCE.getLogManager().insertLog(player, checkData, vl, System.currentTimeMillis(), info); + Anticheat.INSTANCE.getScheduler() + .execute(() -> Anticheat.INSTANCE.getLogManager() + .insertLog(player, checkData, vl, System.currentTimeMillis(), info)); boolean dev = Anticheat.INSTANCE.getTps() < 18; //if(vl > 0) Anticheat.INSTANCE.loggerManager.addLog(player, this, info); diff --git a/src/main/java/dev/brighten/ac/check/impl/movement/velocity/VelocityB.java b/src/main/java/dev/brighten/ac/check/impl/movement/velocity/VelocityB.java index c013ae1..dc399c4 100644 --- a/src/main/java/dev/brighten/ac/check/impl/movement/velocity/VelocityB.java +++ b/src/main/java/dev/brighten/ac/check/impl/movement/velocity/VelocityB.java @@ -1,34 +1,37 @@ package dev.brighten.ac.check.impl.movement.velocity; +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.impl.movement.speed.Horizontal; import dev.brighten.ac.data.APlayer; +import dev.brighten.ac.packet.ProtocolVersion; import dev.brighten.ac.packet.wrapper.in.WPacketPlayInFlying; -import dev.brighten.ac.packet.wrapper.in.WPacketPlayInUseEntity; -import dev.brighten.ac.utils.Tuple; +import dev.brighten.ac.utils.BlockUtils; +import dev.brighten.ac.utils.KLocation; +import dev.brighten.ac.utils.MathHelper; +import dev.brighten.ac.utils.math.IntVector; import dev.brighten.ac.utils.timer.Timer; import dev.brighten.ac.utils.timer.impl.TickTimer; +import org.bukkit.Material; +import org.bukkit.block.Block; import org.bukkit.craftbukkit.v1_8_R3.util.CraftMagicNumbers; -import org.bukkit.enchantments.Enchantment; import org.bukkit.potion.PotionEffectType; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Optional; +import java.util.Deque; -//@CheckData(name = "Velocity (B)", type = CheckType.MOVEMENT) +@CheckData(name = "Velocity (B)", checkId = "velocityb", type = CheckType.MOVEMENT) public class VelocityB extends Check { private Timer lastVelocity = new TickTimer(); + public VelocityB(APlayer player) { super(player); player.onVelocity(velocity -> { - if(lastVelocity.isPassed(10)) { //Temp fix for combo mode + if (lastVelocity.isPassed(10)) { //Temp fix for combo mode pvX = velocity.getX(); pvZ = velocity.getZ(); - ticks = 0; + ticks = 1; debug("did velocity: %.3f, %.3f", pvX, pvZ); } @@ -38,168 +41,274 @@ public class VelocityB extends Check { private double pvX, pvZ; private boolean useEntity, sprint; - private double buffer; - private float fromFriction; private int ticks; - private static final double[] moveValues = new double[] {-0.98, 0, 0.98}; + private double buffer; + private float friction; + private KLocation previousFrom; + private static final boolean[] TRUE_FALSE = new boolean[]{true, false}; - WAction usePacket = packet -> { - if(!useEntity - && packet.getAction().equals(WPacketPlayInUseEntity.EnumEntityUseAction.ATTACK)) { - useEntity = true; - } - }; + public double strafe, forward; WAction flying = packet -> { - check: { - if((pvX != 0 || pvZ != 0) && (player.getMovement().getDeltaX() != 0 - || player.getMovement().getDeltaY() != 0 - || player.getMovement().getDeltaZ() != 0)) { - boolean found = false; - double drag = 0.91; + check: + { + Block underBlock = BlockUtils.getBlock((previousFrom != null ? player.getMovement().getFrom().getLoc() : player.getMovement().getTo().getLoc()) + .toLocation(player.getBukkitPlayer().getWorld()) + .subtract(0, 1, 0)), + lastUnderBlock = BlockUtils.getBlock((previousFrom != null ? previousFrom : player.getMovement().getFrom().getLoc()) + .toLocation(player.getBukkitPlayer().getWorld()) + .subtract(0, 1, 0)); + if (underBlock == null || lastUnderBlock == null) + break check; - if(player.getBlockInfo().blocksNear - || player.getBlockInfo().blocksAbove - || player.getBlockInfo().inLiquid - || player.getLagInfo().getLastPacketDrop().isNotPassed(2) - || player.getLagInfo().getLastPingDrop().isNotPassed(4)) { - pvX = pvZ = 0; - buffer-= buffer > 0 ? 1 : 0; - break check; - } + Deque frictionList = player.getBlockUpdateHandler() + .getPossibleMaterials(new IntVector(underBlock.getX(), underBlock.getY(), underBlock.getZ())), + lfrictionList = player.getBlockUpdateHandler() + .getPossibleMaterials(new IntVector(lastUnderBlock.getX(), lastUnderBlock.getY(), lastUnderBlock.getZ())); - if(player.getMovement().getFrom().isOnGround()) { - drag*= fromFriction; - } + if (ticks == 0) break check; - if(useEntity && (sprint || (player.getBukkitPlayer().getItemInHand() != null - && player.getBukkitPlayer().getItemInHand().containsEnchantment(Enchantment.KNOCKBACK)))) { - pvX*= 0.6; - pvZ*= 0.6; - } - - double f = 0.16277136 / (drag * drag * drag); - double f5; - - if (player.getMovement().getFrom().isOnGround()) { - double aiMoveSpeed = (double) player.getBukkitPlayer().getWalkSpeed() / 2f; - - if(player.getInfo().isSprinting()) aiMoveSpeed += aiMoveSpeed * 0.30000001192092896D; - - aiMoveSpeed += (player.getPotionHandler() - .getEffectByType(PotionEffectType.SPEED) - .map(p -> p.getAmplifier() + 1).orElse(0)) - * 0.20000000298023224D * aiMoveSpeed; - aiMoveSpeed += (player.getPotionHandler() - .getEffectByType(PotionEffectType.SLOW) - .map(p -> p.getAmplifier() + 1).orElse(0)) - * -0.15000000596046448D * aiMoveSpeed; - - f5 = aiMoveSpeed * f; - } else { - f5 = sprint ? 0.026f : 0.02f; - } - - double vX = pvX; - double vZ = pvZ; - - List> predictions = new ArrayList<>(); - - double moveStrafe = 0, moveForward = 0; - for (double forward : moveValues) { - for(double strafe : moveValues) { - moveFlying(strafe, forward, f5); - - predictions.add(new Tuple<>(new Double[]{forward, strafe}, new Double[]{pvX, pvZ})); - - pvX = vX; - pvZ = vZ; - } - } - - Optional> velocity = predictions.stream() - .filter(tuple -> { - double deltaX = Math.abs(tuple.two[0] - player.getMovement().getDeltaX()); - double deltaZ = Math.abs(tuple.two[1] - player.getMovement().getDeltaZ()); - - return (deltaX * deltaX + deltaZ * deltaZ) < 0.005; - }) - .min(Comparator.comparing(tuple -> { - double deltaX = Math.abs(tuple.two[0] - player.getMovement().getDeltaX()); - double deltaZ = Math.abs(tuple.two[1] - player.getMovement().getDeltaZ()); - - return (deltaX * deltaX + deltaZ * deltaZ); - })); - - found = true; - if(!velocity.isPresent()) { - Horizontal speedCheck = (Horizontal) player.getCheckHandler().findCheck(Horizontal.class); - double s2 = speedCheck.strafe; - double f2 = speedCheck.forward; - - moveStrafe = s2; - moveForward = f2; - - moveFlying(s2, f2, f5); - } else { - Tuple tuple = velocity.get(); - - moveForward = tuple.one[0]; - moveStrafe = tuple.one[1]; - pvX = tuple.two[0]; - pvZ = tuple.two[1]; - } - - double pvXZ = Math.hypot(pvX, pvZ); - - if(pvXZ < 0.2) break check; - double ratio = player.getMovement().getDeltaXZ() / pvXZ; - - if((ratio < 0.996) && pvX != 0 - && pvZ != 0 - && player.getCreation().isPassed(3000L) - && player.getMovement().getLastTeleport().isPassed(1) - && !player.getBlockInfo().blocksNear) { - if(player.getInfo().lastUseItem.isPassed(2) && ++buffer > 11) { - flag("pct=%.2f buffer=%.1f forward=%.2f strafe=%.2f", - ratio * 100, buffer, moveStrafe, moveForward); - buffer = 11; - } - } else if(buffer > 0) buffer-= 0.5; - - debug("ratio=%.3f dxz=%.4f vxz=%.4f vxz=%.4g,%.4f buffer=%.1f ticks=%s strafe=%.2f forward=%.2f " + - "found=%s lastV=%s", ratio, player.getMovement().getDeltaXZ(), pvXZ, pvX, pvZ, - buffer, ticks, moveStrafe, moveForward, - found, player.getInfo().getVelocity().getPassed()); - - pvX = 0; - pvZ = 0; + if (player.getMovement().getMoveTicks() == 0 + || player.getInfo().isGeneralCancel() + || player.getBlockInfo().onClimbable + || player.getInfo().lastLiquid.isNotPassed(2) + || player.getBlockInfo().collidesHorizontally) { + ticks = 0; + break check; } + double smallestDelta = Double.MAX_VALUE; + + double pmotionx = 0, pmotionz = 0; + boolean onGround = player.getMovement().getFrom().isOnGround(); + + loop: + { + for (int f = -1; f < 2; f++) { + for (Material underMaterial : frictionList) { + for (int s = -1; s < 2; s++) { + for (boolean sprinting : TRUE_FALSE) { + for (int fastMath = 0; fastMath <= 2; fastMath++) { + for (boolean attack : TRUE_FALSE) { + for (boolean using : TRUE_FALSE) { + for (boolean sneaking : TRUE_FALSE) { + for (boolean jumped : TRUE_FALSE) { + + float forward = f, strafe = s; + + if (sprinting && forward <= 0) { + continue; + } + + if (sneaking) { + forward *= 0.3; + strafe *= 0.3; + } + + float friction = CraftMagicNumbers.getBlock(underMaterial).frictionFactor; + + if (using) { + forward *= 0.2; + strafe *= 0.2; + } + + //Multiplying by 0.98 like in client + forward *= 0.9800000190734863F; + strafe *= 0.9800000190734863F; + + double aiMoveSpeed = player.getBukkitPlayer().getWalkSpeed() / 2; + + float drag = 0.91f; + double lmotionX = pvX, + lmotionZ = pvZ; + + //lmotionX *= (lastLastClientGround ? lfriction : 1) * 0.9100000262260437D; + //lmotionZ *= (lastLastClientGround ? lfriction : 1) * 0.9100000262260437D; + + //Running multiplication done after previous prediction + if (player.getPlayerVersion().isOrAbove(ProtocolVersion.V1_9)) { + if (Math.abs(lmotionX) < 0.003) + lmotionX = 0; + if (Math.abs(lmotionZ) < 0.003) + lmotionZ = 0; + } else { + if (Math.abs(lmotionX) < 0.005) + lmotionX = 0; + if (Math.abs(lmotionZ) < 0.005) + lmotionZ = 0; + } + + //Less than 0.05 + if (((lmotionX * lmotionX) + (lmotionZ * lmotionZ)) < 0.0025 && player.getMovement().getDeltaXZ() < 0.2) { + break check; + } + // Attack slowdown + if (attack) { + lmotionX *= 0.6; + lmotionZ *= 0.6; + } + + if (sprinting) + aiMoveSpeed += aiMoveSpeed * 0.30000001192092896D; + + if (player.getPotionHandler().hasPotionEffect(PotionEffectType.SPEED)) + aiMoveSpeed += (player.getPotionHandler().getEffectByType(PotionEffectType.SPEED) + .get() + .getAmplifier() + 1) * (double) 0.20000000298023224D * aiMoveSpeed; + if (player.getPotionHandler().hasPotionEffect(PotionEffectType.SLOW)) + aiMoveSpeed += (player.getPotionHandler().getEffectByType(PotionEffectType.SLOW) + .get() + .getAmplifier() + 1) * (double) -0.15000000596046448D * aiMoveSpeed; + + float f5; + if (onGround) { + drag *= friction; + + f5 = (float) (aiMoveSpeed * (0.16277136F / (drag * drag * drag))); + + if (sprinting && jumped) { + float rot = player.getMovement().getTo().getLoc().yaw * 0.017453292F; + lmotionX -= sin(fastMath, rot) * 0.2F; + lmotionZ += cos(fastMath, rot) * 0.2F; + } + + } else f5 = sprinting ? 0.025999999F : 0.02f; + + if (player.getPlayerVersion().isOrAbove(ProtocolVersion.V1_9)) { + double keyedMotion = forward * forward + strafe * strafe; + + if (keyedMotion >= 1.0E-4F) { + keyedMotion = f5 / Math.max(1.0, Math.sqrt(keyedMotion)); + forward *= keyedMotion; + strafe *= keyedMotion; + + final float yawSin = sin(fastMath, + player.getMovement().getTo().getLoc().yaw * (float) Math.PI / 180.F), + yawCos = cos(fastMath, + player.getMovement().getTo().getLoc().yaw * (float) Math.PI / 180.F); + + lmotionX += (strafe * yawCos - forward * yawSin); + lmotionZ += (forward * yawCos + strafe * yawSin); + } + } else { + float keyedMotion = forward * forward + strafe * strafe; + + if (keyedMotion >= 1.0E-4F) { + keyedMotion = f5 / Math.max(1.0f, MathHelper.sqrt_float(keyedMotion)); + forward *= keyedMotion; + strafe *= keyedMotion; + + final float yawSin = sin(fastMath, + player.getMovement().getTo().getLoc().yaw * (float) Math.PI / 180.F), + yawCos = cos(fastMath, + player.getMovement().getTo().getLoc().yaw * (float) Math.PI / 180.F); + + lmotionX += (strafe * yawCos - forward * yawSin); + lmotionZ += (forward * yawCos + strafe * yawSin); + } + } + double diffX = player.getMovement().getDeltaX() - lmotionX, + diffZ = player.getMovement().getDeltaZ() - lmotionZ; + double delta = (diffX * diffX) + (diffZ * diffZ); + + if (delta < smallestDelta) { + smallestDelta = delta; + pmotionx = lmotionX; + pmotionz = lmotionZ; + this.friction = friction; + + if (delta < 4E-17) { + this.strafe = s * 0.98f; + this.forward = f * 0.98f; + + break loop; + } + } + } + } + } + } + } + } + } + } + } + } + + if (++ticks > 6) { + ticks = 0; + } + + double pmotion = Math.hypot(pmotionx, pmotionz); + + double ratio = Math.abs(player.getMovement().getDeltaXZ() / pmotion); + + if (ratio < 0.992) { + if (++buffer > 10) { + flag("p=%.1f%%", ratio); + } + } else if (buffer > 0) buffer-= 0.2; + + debug("r=%.4f smallest=%s f=%s lf=%s pm=%.5f dxz=%.5f b=%.1f f/s=%.2f,%.2f soulsand=%s ", ratio, smallestDelta, frictionList, lfrictionList, pmotion, + player.getMovement().getDeltaXZ(), buffer, forward, strafe, + player.getBlockInfo().onSoulSand); + + pvX = pmotionx * (0.9100000262260437 * (player.getMovement().getFrom().isOnGround() ? friction : 1)); + pvZ = pmotionz * (0.9100000262260437 * (player.getMovement().getFrom().isOnGround() ? friction : 1)); } - sprint = player.getInfo().isSprinting(); - useEntity = false; - fromFriction = player.getInfo().getBlockBelow() - .map(b -> CraftMagicNumbers.getBlock(b.getType()).frictionFactor).orElse(0.6f); + previousFrom = player.getMovement().getFrom().getLoc().clone(); }; - private void moveFlying(double strafe, double forward, double friction) { - double f = strafe * strafe + forward * forward; + private static final float[] SIN_TABLE_FAST = new float[4096], SIN_TABLE_FAST_NEW = new float[4096]; + private static final float[] SIN_TABLE = new float[65536]; + private static final float radToIndex = roundToFloat(651.8986469044033D); - if (f >= 1.0E-4F) { - f = Math.sqrt(f); - - if (f < 1.0F) { - f = 1.0F; + public static float sin(int type, float value) { + switch (type) { + case 0: + default: { + return SIN_TABLE[(int) (value * 10430.378F) & 65535]; + } + case 1: { + return SIN_TABLE_FAST[(int) (value * 651.8986F) & 4095]; + } + case 2: { + return SIN_TABLE_FAST_NEW[(int) (value * radToIndex) & 4095]; } - - f = friction / f; - strafe = strafe * f; - forward = forward * f; - double f1 = Math.sin(player.getMovement().getTo().getLoc().yaw * Math.PI / 180.0F); - double f2 = Math.cos(player.getMovement().getTo().getLoc().yaw * Math.PI / 180.0F); - pvX += (strafe * f2 - forward * f1); - pvZ += (forward * f2 + strafe * f1); } } + + public static float cos(int type, float value) { + switch (type) { + case 0: + default: + return SIN_TABLE[(int) (value * 10430.378F + 16384.0F) & 65535]; + case 1: + return SIN_TABLE_FAST[(int) ((value + ((float) Math.PI / 2F)) * 651.8986F) & 4095]; + case 2: + return SIN_TABLE_FAST_NEW[(int) (value * radToIndex + 1024.0F) & 4095]; + } + } + + static { + for (int i = 0; i < 65536; ++i) { + SIN_TABLE[i] = (float) Math.sin((double) i * Math.PI * 2.0D / 65536.0D); + } + + for (int j = 0; j < 4096; ++j) { + SIN_TABLE_FAST[j] = (float) Math.sin((double) (((float) j + 0.5F) / 4096.0F * ((float) Math.PI * 2F))); + } + + for (int l = 0; l < 360; l += 90) { + SIN_TABLE_FAST[(int) ((float) l * 11.377778F) & 4095] = (float) Math.sin((double) ((float) l * 0.017453292F)); + } + + for (int j = 0; j < SIN_TABLE_FAST_NEW.length; ++j) { + SIN_TABLE_FAST_NEW[j] = roundToFloat(Math.sin((double) j * Math.PI * 2.0D / 4096.0D)); + } + } + + private static float roundToFloat(double d) { + return (float) ((double) Math.round(d * 1.0E8D) / 1.0E8D); + } } diff --git a/src/main/java/dev/brighten/ac/command/AnticheatCommand.java b/src/main/java/dev/brighten/ac/command/AnticheatCommand.java index 44ea6cb..197e694 100644 --- a/src/main/java/dev/brighten/ac/command/AnticheatCommand.java +++ b/src/main/java/dev/brighten/ac/command/AnticheatCommand.java @@ -5,8 +5,10 @@ import co.aikar.commands.annotation.*; import co.aikar.commands.bukkit.contexts.OnlinePlayer; import dev.brighten.ac.Anticheat; import dev.brighten.ac.check.Check; +import dev.brighten.ac.check.CheckData; import dev.brighten.ac.data.APlayer; import dev.brighten.ac.logging.Log; +import dev.brighten.ac.logging.sql.Query; import dev.brighten.ac.messages.Messages; import dev.brighten.ac.packet.handler.HandlerAbstract; import dev.brighten.ac.utils.*; @@ -23,6 +25,7 @@ import org.bukkit.craftbukkit.v1_8_R3.util.CraftChatMessage; import org.bukkit.entity.Player; import java.io.UnsupportedEncodingException; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Comparator; import java.util.List; @@ -42,6 +45,10 @@ public class AnticheatCommand extends BaseCommand { .stream() .sorted(Comparator.naturalOrder()) .map(name -> name.replace(" ", "_")).collect(Collectors.toList())); + cc.registerCompletion("checkIds", (c) -> Anticheat.INSTANCE.getCheckManager().getCheckClasses().values() + .stream().map(s -> s.getCheckClass().getAnnotation(CheckData.class).checkId()) + .sorted(Comparator.naturalOrder()).collect(Collectors.toList())); + BukkitCommandContexts contexts = (BukkitCommandContexts) Anticheat.INSTANCE.getCommandManager() .getCommandContexts(); @@ -112,38 +119,64 @@ public class AnticheatCommand extends BaseCommand { } @Subcommand("logs") - @Syntax("[player]") - @CommandCompletion("@players") + @Syntax("[player] [check]") + @CommandCompletion("@players @checkIds") @CommandPermission("anticheat.command.logs") @Description("Get player logs") - public void onLogs(CommandSender sender, @Single String playername) { + public void onLogs(CommandSender sender, @Single String playername, @Single @Optional @Default("none") String check) { UUID uuid = Bukkit.getOfflinePlayer(playername).getUniqueId(); sender.sendMessage(Color.Red + "Getting logs for " + playername + "..."); Anticheat.INSTANCE.getScheduler().execute(() -> { List logs = new ArrayList<>(); - System.out.println("shit 1"); - Anticheat.INSTANCE.getLogManager().runQuery("select * from logs where uuid=" + uuid.hashCode(), rs -> { - Log log = Log.builder() - .uuid(UUID.fromString(rs.getString("uuid"))) - .checkId(rs.getString("check")) - .data(rs.getString("data")) - .vl(rs.getFloat("vl")) - .time(rs.getLong("time")) - .build(); - System.out.println("Shit"); + if(check.equals("none")) { + Query.prepare("select * from `logs` where `uuid` = ? limit 500").append(uuid.hashCode()).execute(rs -> { + dev.brighten.ac.logging.Log log = Log.builder() + .uuid(uuid) + .checkId(rs.getString("check")) + .data(rs.getString("data")) + .vl(rs.getFloat("vl")) + .time(rs.getTimestamp("time").getTime()) + .build(); - logs.add("Flagged " + Anticheat.INSTANCE.getCheckManager().getIdToName().get(log.getCheckId()) + " data: " + log.getData() + " VL: " + log.getVl() + " at " + log.getTime()); - }); - String url = null; - try { - url = Pastebin.makePaste(String.join("\n", logs), playername + "'s Logs", Pastebin.Privacy.UNLISTED); + logs.add("[" + rs.getTimestamp("time").toLocalDateTime() + .format(DateTimeFormatter.ISO_DATE_TIME) + "] funkemunky failed " + + Anticheat.INSTANCE.getCheckManager().getIdToName().get(log.getCheckId()) + "(VL: " + log.getVl() + ") {" + log.getData() + "}"); + }); + } else { + Query.prepare("select * from `logs` where `uuid` = ? and `check` = ? limit 500") + .append(uuid.hashCode()).append(check).execute(rs -> { + dev.brighten.ac.logging.Log log = Log.builder() + .uuid(uuid) + .checkId(rs.getString("check")) + .data(rs.getString("data")) + .vl(rs.getFloat("vl")) + .time(rs.getTimestamp("time").getTime()) + .build(); - sender.sendMessage(Color.Green + "Logs for " + playername + ": " + Color.White + url); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException(e); + logs.add("[" + rs.getTimestamp("time").toLocalDateTime() + .format(DateTimeFormatter.ISO_DATE_TIME) + "] funkemunky failed " + + Anticheat.INSTANCE.getCheckManager().getIdToName().get(log.getCheckId()) + "(VL: " + log.getVl() + ") {" + log.getData() + "}"); + }); + } + + if(logs.size() == 0) { + if(check.equals("none")) { + sender.sendMessage(Color.Gray + "There are no logs for player \"" + playername + "\""); + } else { + sender.sendMessage(Color.Gray + " does not have any violations for check \"" + check + "\""); + } + } else { + String url = null; + try { + url = Pastebin.makePaste(String.join("\n", logs), playername + "'s Logs", Pastebin.Privacy.UNLISTED); + + sender.sendMessage(Color.Green + "Logs for " + playername + ": " + Color.White + url); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } } }); } diff --git a/src/main/java/dev/brighten/ac/handler/PacketHandler.java b/src/main/java/dev/brighten/ac/handler/PacketHandler.java index 5f4503a..6aa0614 100644 --- a/src/main/java/dev/brighten/ac/handler/PacketHandler.java +++ b/src/main/java/dev/brighten/ac/handler/PacketHandler.java @@ -162,7 +162,6 @@ public class PacketHandler { player.getVelocityHandler().onPre(packet); } else player.getVelocityHandler().onPost(packet); if(ka.isEnd() && player.getInfo().getVelocityHistory().contains(velocity)) { - player.getOnVelocityTasks().forEach(task -> task.accept(velocity)); player.getInfo().setDoingVelocity(false); player.getInfo().getVelocity().reset(); synchronized (player.getInfo().getVelocityHistory()) { @@ -170,6 +169,10 @@ public class PacketHandler { } } }); + player.runKeepaliveAction(ka -> { + if(player.getInfo().getVelocityHistory().contains(velocity)) + player.getOnVelocityTasks().forEach(task -> task.accept(velocity)); + }, 1); } break; } diff --git a/src/main/java/dev/brighten/ac/logging/LoggerManager.java b/src/main/java/dev/brighten/ac/logging/LoggerManager.java index d4a52f5..debf30f 100644 --- a/src/main/java/dev/brighten/ac/logging/LoggerManager.java +++ b/src/main/java/dev/brighten/ac/logging/LoggerManager.java @@ -38,6 +38,11 @@ public class LoggerManager { "PRIMARY KEY (`id`)" + ");").execute(); + Query.prepare("create index if not exists `uuid_1` on `logs` (`uuid`)") + .execute(); + Query.prepare("create index if not exists `uuid_check_1` on `logs` (`uuid`, `check`)") + .execute(); + Anticheat.INSTANCE.getScheduler().scheduleAtFixedRate(() -> { if(logList.size() > 0) { synchronized (logList) { @@ -66,6 +71,8 @@ public class LoggerManager { statement.execute(); + Anticheat.INSTANCE.getLogger().info("Saved " + amount + " logs!"); + objectsToInsert.clear(); } } diff --git a/src/main/java/dev/brighten/ac/logging/sql/MySQL.java b/src/main/java/dev/brighten/ac/logging/sql/MySQL.java index c3208bd..49c03e9 100644 --- a/src/main/java/dev/brighten/ac/logging/sql/MySQL.java +++ b/src/main/java/dev/brighten/ac/logging/sql/MySQL.java @@ -29,10 +29,10 @@ public class MySQL { try { Class.forName("org.h2.Driver"); WrappedConstructor jdbcConnection = Reflections.getClass("org.h2.jdbc.JdbcConnection") - .getConstructor(String.class, Properties.class); + .getConstructor(String.class, Properties.class, String.class, Object.class, boolean.class); conn = new NonClosableConnection(jdbcConnection.newInstance("jdbc:h2:file:" + dataFolder.getAbsolutePath(), - new Properties())); + new Properties(), "root", "erc5gmv-xvg5CZQ0nzw", false)); conn.setAutoCommit(true); Query.use(conn); Bukkit.getLogger().info("Connection to H2 SQlLite has been established.");