diff --git a/pom.xml b/pom.xml index 6aa2629..ee50e82 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.mogukun Sentry - 0.2.4 + 0.2.5 jar Sentry diff --git a/src/main/java/com/mogukun/sentry/Sentry.java b/src/main/java/com/mogukun/sentry/Sentry.java index 70e9379..1b86215 100644 --- a/src/main/java/com/mogukun/sentry/Sentry.java +++ b/src/main/java/com/mogukun/sentry/Sentry.java @@ -1,6 +1,8 @@ package com.mogukun.sentry; import com.mogukun.sentry.check.CheckManager; +import com.mogukun.sentry.check.Plan; +import com.mogukun.sentry.listeners.MessageListener; import com.mogukun.sentry.managers.PlayerDataManager; import com.mogukun.sentry.commands.SentryCommand; import com.mogukun.sentry.gui.GUIManager; @@ -29,6 +31,7 @@ public final class Sentry extends JavaPlugin { public HashMap alertStatus = new HashMap<>(); public Configuration config; + public Plan plan = Plan.Free; public GUIManager guiManager; public ConfigurationUtil configurationUtil; @@ -38,7 +41,6 @@ public void onEnable() { long startLoading = System.currentTimeMillis(); System.out.println("[Sentry] Loading Sentry AntiCheat"); - this.instance = this; saveDefaultConfig(); config = getConfig(); @@ -52,6 +54,7 @@ public void onEnable() { getCommand("sentry").setExecutor( new SentryCommand() ); Sentry.instance.checkManager.checkMap.clear(); Sentry.instance.checkManager.vl.clear(); + Bukkit.getMessenger().registerIncomingPluginChannel(this,"mc|brand", new MessageListener()); System.out.println("[Sentry] Loaded Sentry AntiCheat in " + ( System.currentTimeMillis() - startLoading ) + "ms."); } diff --git a/src/main/java/com/mogukun/sentry/check/CheckInfo.java b/src/main/java/com/mogukun/sentry/check/CheckInfo.java index 8f41dd6..eb02bba 100644 --- a/src/main/java/com/mogukun/sentry/check/CheckInfo.java +++ b/src/main/java/com/mogukun/sentry/check/CheckInfo.java @@ -13,5 +13,6 @@ String description(); Category category(); boolean experimental() default false; + Plan plan() default Plan.Free; } diff --git a/src/main/java/com/mogukun/sentry/check/CheckManager.java b/src/main/java/com/mogukun/sentry/check/CheckManager.java index a2de695..8179813 100644 --- a/src/main/java/com/mogukun/sentry/check/CheckManager.java +++ b/src/main/java/com/mogukun/sentry/check/CheckManager.java @@ -6,7 +6,6 @@ import com.mogukun.sentry.check.checks.combats.aura.AuraB; import com.mogukun.sentry.check.checks.combats.aura.AuraC; import com.mogukun.sentry.check.checks.combats.autoclicker.AutoClickerA; -import com.mogukun.sentry.check.checks.combats.autoclicker.AutoClickerB; import com.mogukun.sentry.check.checks.combats.blockhit.BlockHitA; import com.mogukun.sentry.check.checks.combats.reach.ReachA; import com.mogukun.sentry.check.checks.movements.fly.*; @@ -23,6 +22,7 @@ import com.mogukun.sentry.check.checks.players.noslow.NoSlowSword; import com.mogukun.sentry.check.checks.players.pingspoof.PingSpoofA; import com.mogukun.sentry.check.checks.players.timer.TimerA; +import com.mogukun.sentry.check.checks.players.timer.TimerB; import com.mogukun.sentry.models.MovementData; import com.mogukun.sentry.models.ViolationData; import com.mogukun.sentry.utils.PlayerDataUtil; @@ -78,6 +78,7 @@ public CheckManager(){ checks.add( new GroundSpoofC() ); checks.add( new TimerA() ); + checks.add( new TimerB() ); checks.add( new BadPacketA() ); checks.add( new BadPacketB() ); diff --git a/src/main/java/com/mogukun/sentry/check/Plan.java b/src/main/java/com/mogukun/sentry/check/Plan.java new file mode 100644 index 0000000..ddaab73 --- /dev/null +++ b/src/main/java/com/mogukun/sentry/check/Plan.java @@ -0,0 +1,6 @@ +package com.mogukun.sentry.check; + +public enum Plan { + Free, + Dev +} diff --git a/src/main/java/com/mogukun/sentry/check/checks/combats/aura/AuraC.java b/src/main/java/com/mogukun/sentry/check/checks/combats/aura/AuraC.java index bfb507a..0953472 100644 --- a/src/main/java/com/mogukun/sentry/check/checks/combats/aura/AuraC.java +++ b/src/main/java/com/mogukun/sentry/check/checks/combats/aura/AuraC.java @@ -3,6 +3,7 @@ import com.mogukun.sentry.check.Category; import com.mogukun.sentry.check.Check; import com.mogukun.sentry.check.CheckInfo; +import com.mogukun.sentry.models.Counter; import net.minecraft.server.v1_8_R3.Packet; import net.minecraft.server.v1_8_R3.PacketPlayInArmAnimation; import net.minecraft.server.v1_8_R3.PacketPlayInUseEntity; @@ -15,23 +16,24 @@ ) public class AuraC extends Check { - long lastArm = 0; + Counter armCounter = new Counter(); + Counter attackCounter = new Counter(); @Override public void handle(Packet packet) { - long now = System.currentTimeMillis(); if ( packet instanceof PacketPlayInArmAnimation) { - lastArm = now; + if ( getPlayerData().isDigging ) return; + armCounter.count(); } if ( packet instanceof PacketPlayInUseEntity ) { if ( ((PacketPlayInUseEntity) packet).a() != PacketPlayInUseEntity.EnumEntityUseAction.ATTACK ) return; - long diff = now - lastArm; + attackCounter.count(); - if ( diff > 10 ) { - flag("diff=" + diff); - } + int difference = attackCounter.count() - armCounter.getCount(); + + //debug("difference=" + difference); } } diff --git a/src/main/java/com/mogukun/sentry/check/checks/movements/fly/FlyA.java b/src/main/java/com/mogukun/sentry/check/checks/movements/fly/FlyA.java index 118b565..0b3d138 100644 --- a/src/main/java/com/mogukun/sentry/check/checks/movements/fly/FlyA.java +++ b/src/main/java/com/mogukun/sentry/check/checks/movements/fly/FlyA.java @@ -29,7 +29,8 @@ public void handle(MovementData data) data.sinceStandingOnBoatTick <= 10 || data.sinceWebTick <= 10 || data.sinceWaterTick <= 10 || - data.sinceClimbTick <= 10 ) return; + data.sinceClimbTick <= 10 || + data.sinceSlimeTick <= 20) return; if ( data.serverAirTick < 1 ) { buffer = 0; return; diff --git a/src/main/java/com/mogukun/sentry/check/checks/movements/fly/FlyB.java b/src/main/java/com/mogukun/sentry/check/checks/movements/fly/FlyB.java index ed47cc1..e9e675b 100644 --- a/src/main/java/com/mogukun/sentry/check/checks/movements/fly/FlyB.java +++ b/src/main/java/com/mogukun/sentry/check/checks/movements/fly/FlyB.java @@ -33,7 +33,12 @@ public void handle(MovementData data) buffer = 0; return; } - if ( data.sinceVehicleTick <= 10 || data.sinceStandingOnBoatTick <= 10 || data.sinceWebTick <= 10 || data.sinceWaterTick <= 10 || data.sinceClimbTick <= 10 ) return; + if ( data.sinceVehicleTick <= 10 || + data.sinceStandingOnBoatTick <= 10 || + data.sinceWebTick <= 10 || + data.sinceWaterTick <= 10 || + data.sinceClimbTick <= 10 || + data.sinceSlimeTick <= 20) return; if ( data.sinceVelocityTaken < 5 ) return; // Credit: CheatGuard @DerRedstoner diff --git a/src/main/java/com/mogukun/sentry/check/checks/movements/fly/FlyC.java b/src/main/java/com/mogukun/sentry/check/checks/movements/fly/FlyC.java index 9e237f4..7a730cc 100644 --- a/src/main/java/com/mogukun/sentry/check/checks/movements/fly/FlyC.java +++ b/src/main/java/com/mogukun/sentry/check/checks/movements/fly/FlyC.java @@ -13,7 +13,6 @@ category = Category.MOVEMENT ) public class FlyC extends Check { - Counter counter = new Counter(); @Override @@ -25,7 +24,8 @@ public void handle(MovementData data) return; } - if ( data.sinceVehicleTick <= 10 || data.sinceStandingOnBoatTick <= 10 || data.sinceWebTick <= 10 || data.sinceWaterTick <= 10 || data.sinceClimbTick <= 10 ) return; + if ( data.sinceVehicleTick <= 10 || data.sinceStandingOnBoatTick <= 10 + || data.sinceWebTick <= 10 || data.sinceWaterTick <= 10 || data.sinceClimbTick <= 10 || data.sinceSlimeTick <= 10) return; if ( data.currentY < data.lastY && data.currentDeltaY <= data.lastDeltaY ) { if ( counter.count() > config.getDoubleOrDefault("flag_buffer", 5) ) { diff --git a/src/main/java/com/mogukun/sentry/check/checks/movements/fly/FlyD.java b/src/main/java/com/mogukun/sentry/check/checks/movements/fly/FlyD.java index 4c487c6..d2f9f65 100644 --- a/src/main/java/com/mogukun/sentry/check/checks/movements/fly/FlyD.java +++ b/src/main/java/com/mogukun/sentry/check/checks/movements/fly/FlyD.java @@ -72,7 +72,7 @@ public void handle(MovementData data) } else bufferCounter.count(-150); double bufferCount = bufferCounter.getCount(); - if ( bufferCount > 0 ) { + if ( bufferCount > config.getDoubleOrDefault("flag_buffer", 500) ) { flag("buffer1=" + bufferCount + " buffer2=" + totalBuffer + " sampleSize=" + samples.size() ); } } diff --git a/src/main/java/com/mogukun/sentry/check/checks/players/timer/TimerB.java b/src/main/java/com/mogukun/sentry/check/checks/players/timer/TimerB.java new file mode 100644 index 0000000..a360ff9 --- /dev/null +++ b/src/main/java/com/mogukun/sentry/check/checks/players/timer/TimerB.java @@ -0,0 +1,99 @@ +package com.mogukun.sentry.check.checks.players.timer; +import com.mogukun.sentry.check.*; +import com.mogukun.sentry.models.*; +import com.mogukun.sentry.models.Counter; +import net.minecraft.server.v1_8_R3.*; +import org.bukkit.event.Event; +import org.bukkit.event.player.PlayerJoinEvent; +import java.util.*; + +@CheckInfo( + name = "Timer (B)", + path = "player.timer.b", + description = "Designed for Stable Timer Check", + category = Category.PLAYER +) +public class TimerB extends Check { + + long lastPacket = 0; + long startIgnore = 0; + double lastPercentage = 0; + + BetterCounter deltaCounter = new BetterCounter(1000 * 60); + Counter buffer = new Counter(); + + @Override + public void handle(Packet packet) { + if ( packet instanceof PacketPlayInFlying ) + { + long now = System.nanoTime(); + + if ( lastPacket == 0 || + getPlayerData().teleportTick <= 5 || + getPlayerData().respawnTick <= 5 || + System.currentTimeMillis() - startIgnore < 10000 ) { + + lastPacket = now; + return; + } + deltaCounter.count( now - lastPacket ); + + if ( deltaCounter.size() > 60 ) { + long avg = averageWithoutOutliers(deltaCounter.getLongList()); + + // somehow this is weird. this return 50% if player is 50% faster. + double percentage = ((double)avg / 50000000) * 100; + percentage -= 100; // so get difference. + percentage = 100 - percentage; + + if( percentage > 105 || percentage < 95 ) { + int bufferCount = buffer.count(); + if ( bufferCount > 10 ) { + flag("percentage=" + percentage + " buffer=" + bufferCount + " size=" + deltaCounter.size() ); + deltaCounter.clear(); + } + } + + lastPercentage = percentage; + } + + + lastPacket = now; + } + } + + @Override + public void event(Event event) { + if ( event instanceof PlayerJoinEvent) { + startIgnore = System.currentTimeMillis(); + } + } + + + public long averageWithoutOutliers(ArrayList list) { + Collections.sort(list); + int size = list.size(); + long q1 = list.get(size / 4); + long q3 = list.get(3 * size / 4); + double iqr = q3 - q1; + double lowerBound = q1 - 1.5 * iqr; + double upperBound = q3 + 1.5 * iqr; + ArrayList filteredList = new ArrayList<>(); + for (long num : list) { + if (num >= lowerBound && num <= upperBound) { + filteredList.add(num); + } + } + if (filteredList.isEmpty()) { + return 50; + } + + long sum = 0; + for (long num : filteredList) { + sum += num; + } + + return sum / filteredList.size(); + } + +} diff --git a/src/main/java/com/mogukun/sentry/gui/guis/MainMenu.java b/src/main/java/com/mogukun/sentry/gui/guis/MainMenu.java index 00816ba..e4a9b70 100644 --- a/src/main/java/com/mogukun/sentry/gui/guis/MainMenu.java +++ b/src/main/java/com/mogukun/sentry/gui/guis/MainMenu.java @@ -39,10 +39,11 @@ public Inventory createGUI(Player player) { inv.setItem(13, createStack(Material.PAPER, "&6Sentry Information", new ListUtil(). add("&1"). + add("&6Type &f" + Sentry.instance.plan). + add("&6Version &f" + Sentry.instance.getDescription().getVersion()). add("&6Author &f" + (authors.size() > 1 ? String.join(", ", authors) : authors.get(0)) ). add("&6Description"). - add("&f" + Sentry.instance.getDescription().getDescription() ). - add("&6Version &f" + Sentry.instance.getDescription().getVersion()) + add("&f" + Sentry.instance.getDescription().getDescription() ) .getList())); diff --git a/src/main/java/com/mogukun/sentry/listeners/MessageListener.java b/src/main/java/com/mogukun/sentry/listeners/MessageListener.java new file mode 100644 index 0000000..c668b4d --- /dev/null +++ b/src/main/java/com/mogukun/sentry/listeners/MessageListener.java @@ -0,0 +1,19 @@ +package com.mogukun.sentry.listeners; + +import com.mogukun.sentry.Sentry; +import org.bukkit.entity.Player; +import org.bukkit.plugin.messaging.PluginMessageListener; + +import java.io.UnsupportedEncodingException; + +public class MessageListener implements PluginMessageListener { + @Override + public void onPluginMessageReceived(String s, Player player, byte[] bytes) { + String brand = "Unknown"; + try { + brand = new String(bytes, "UTF-8").substring(1); + } catch (UnsupportedEncodingException ignore) {} + Sentry.instance.dataManager.getPlayerData(player).clientBrand = brand; + System.out.println(brand); + } +} diff --git a/src/main/java/com/mogukun/sentry/listeners/PlayerListener.java b/src/main/java/com/mogukun/sentry/listeners/PlayerListener.java index e413107..1d4245f 100644 --- a/src/main/java/com/mogukun/sentry/listeners/PlayerListener.java +++ b/src/main/java/com/mogukun/sentry/listeners/PlayerListener.java @@ -35,6 +35,8 @@ public void onJoin(PlayerJoinEvent event) { new PacketHandler(event.getPlayer())) ); + + call(event.getPlayer(), event); } diff --git a/src/main/java/com/mogukun/sentry/models/BetterCounter.java b/src/main/java/com/mogukun/sentry/models/BetterCounter.java index 2093c1c..063dd9b 100644 --- a/src/main/java/com/mogukun/sentry/models/BetterCounter.java +++ b/src/main/java/com/mogukun/sentry/models/BetterCounter.java @@ -1,25 +1,32 @@ package com.mogukun.sentry.models; +import java.util.ArrayList; import java.util.concurrent.ConcurrentLinkedDeque; public class BetterCounter { ConcurrentLinkedDeque counts = new ConcurrentLinkedDeque<>(); + long interval = 1000000000; + public BetterCounter() {} + public BetterCounter(long interval) { + this.interval = interval * 1000000; + } + public double count(double d) { - long now = System.currentTimeMillis(); + long now = System.nanoTime(); counts.add( new DoubleLong(d,now) ); return getCount(now); } public double getCount() { - return getCount(System.currentTimeMillis()); + return getCount(System.nanoTime()); } private double getCount(long now) { - counts.removeIf(k -> now - k.b > 1000); + counts.removeIf(k -> now - k.b >= interval); double t = 0; for ( DoubleLong l : counts ) t += l.a; return t; @@ -29,4 +36,20 @@ public void clear() { counts.clear(); } + public int size() { + return counts.size(); + } + + public ArrayList getDoubleList() { + ArrayList temp = new ArrayList<>(); + for ( DoubleLong l : counts ) temp.add(l.a); + return temp; + } + + public ArrayList getLongList() { + ArrayList temp = new ArrayList<>(); + for ( DoubleLong l : counts ) temp.add((long)l.a); + return temp; + } + } diff --git a/src/main/java/com/mogukun/sentry/models/PlayerData.java b/src/main/java/com/mogukun/sentry/models/PlayerData.java index aacbedc..6e12a14 100644 --- a/src/main/java/com/mogukun/sentry/models/PlayerData.java +++ b/src/main/java/com/mogukun/sentry/models/PlayerData.java @@ -6,6 +6,7 @@ public class PlayerData { public PlayerData() {} public MovementData data = null; + public String clientBrand = ""; public boolean isDigging = false; public long lastPlace = 0; public boolean runningTransactionPingCheck = false; diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 1243586..7ba5cb4 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1 +1,3 @@ +license: "FREE" +# will auto generated AFTER LOAD THE PLUGIN! checks: \ No newline at end of file