diff --git a/Plugins/Mineplex.Core/pom.xml b/Plugins/Mineplex.Core/pom.xml
index 81a567966..45dbf6cfb 100644
--- a/Plugins/Mineplex.Core/pom.xml
+++ b/Plugins/Mineplex.Core/pom.xml
@@ -47,7 +47,7 @@
com.mineplex
anticheat
- 1.1
+ 1.2
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHack.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHack.java
index 91a57dd97..650362224 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHack.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHack.java
@@ -62,13 +62,16 @@ import java.util.function.Predicate;
@ReflectivelyCreateMiniPlugin
public class AntiHack extends MiniPlugin
{
- public static final Map CHECKS = ImmutableMap.of(
- "Killaura (Type A)", new CheckThresholds("Kill Aura", 25, 50),
- "Killaura (Type B)", new CheckThresholds("High CPS", 0, Integer.MAX_VALUE),
- "Killaura (Type C)", new CheckThresholds("Reach", Integer.MAX_VALUE, Integer.MAX_VALUE),
- "Killaura (Type D)", new CheckThresholds("Kill Aura", 1000, 1500),
- "BadPackets", new CheckThresholds("Regen", 1000, 2000)
- );
+ public static final Map CHECKS = ImmutableMap.builder()
+ .put("Killaura (Type A)", new CheckThresholds("Kill Aura", 0, 25, 50))
+ .put("Killaura (Type B)", new CheckThresholds("High CPS", 0, 0, Integer.MAX_VALUE))
+ .put("Killaura (Type C)", new CheckThresholds("Reach", 0, Integer.MAX_VALUE, Integer.MAX_VALUE))
+ .put("Killaura (Type D)", new CheckThresholds("Kill Aura", 500, 1000, 1500))
+ .put("BadPackets", new CheckThresholds("Regen", 500, 1000, 2000))
+ .put("Glide", new CheckThresholds("Flying", 50, 100, 200)) // TODO: specific VL levels
+ .put("Speed", new CheckThresholds("Speed", 50, 100, 200)) // TODO: specific VL levels
+ .put("HeadRoll", new CheckThresholds("Illegal Movement", 0, 0, 0))
+ .build();
public static final String NAME = "Chiss";
public static final String USER_HAS_BEEN_BANNED = F.main("GWEN", "%s has been banned. I am always watching");
@@ -176,6 +179,24 @@ public class AntiHack extends MiniPlugin
{
return UtilPlayer.isSpectator(player);
}
+
+ @Override
+ public double getTPS()
+ {
+ return MinecraftServer.getServer().recentTps[0]; // Return the average TPS from the last minute
+ }
+
+ @Override
+ public int getPing(Player player)
+ {
+ return Math.min(((CraftPlayer)player).getHandle().ping, 1000);
+ }
+
+ @Override
+ public boolean isUsingItem(Player player)
+ {
+ return ((CraftPlayer)player).getHandle().bS(); // See Anticheat javadoc
+ }
}, this._plugin, ServicePriority.Normal);
ServerCommandManager.getInstance().registerCommandType(MajorViolationCommand.class, violation ->
@@ -973,7 +994,20 @@ public class AntiHack extends MiniPlugin
{
if (event.shouldTellStaff())
{
- String key = event.getPlayer().getName() + "." + event.getHackType() + "." + CHECKS.get(event.getHackType()).getSeverity(event.getViolations()).toString();
+ CheckThresholds thresholds = CHECKS.get(event.getHackType());
+ if (thresholds == null)
+ {
+ thresholds = new CheckThresholds(event.getHackType(), 0, Integer.MAX_VALUE, Integer.MAX_VALUE);
+ }
+ CheckThresholds.Severity severity = thresholds.getSeverity(event.getViolations());
+
+ if (severity == CheckThresholds.Severity.NONE)
+ {
+ return;
+ }
+
+ String key = event.getPlayer().getName() + "." + event.getHackType() + "." + severity.toString();
+
Integer pastVl = this._cooldown.getIfPresent(key);
if (pastVl != null)
{
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/CheckThresholds.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/CheckThresholds.java
index b00207db6..f64783e55 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/antihack/CheckThresholds.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/CheckThresholds.java
@@ -8,12 +8,14 @@ import net.minecraft.server.v1_8_R3.IChatBaseComponent;
public class CheckThresholds
{
private final String _friendlyName;
+ private final int _low;
private final int _med;
private final int _high;
- public CheckThresholds(String friendlyName, int med, int high)
+ public CheckThresholds(String friendlyName, int low, int med, int high)
{
_friendlyName = friendlyName;
+ _low = low;
_med = med;
_high = high;
}
@@ -39,14 +41,17 @@ public class CheckThresholds
{
return Severity.MEDIUM;
- } else
+ } else if (violationLevel >= _low)
{
return Severity.LOW;
}
+
+ return Severity.NONE;
}
public enum Severity
{
+ NONE(EnumChatFormat.GREEN),
LOW(EnumChatFormat.GREEN),
MEDIUM(EnumChatFormat.GOLD),
HIGH(EnumChatFormat.RED),
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/actions/AntiHackAction.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/actions/AntiHackAction.java
index 689f57f7b..ddcc5e909 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/antihack/actions/AntiHackAction.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/actions/AntiHackAction.java
@@ -2,6 +2,9 @@ package mineplex.core.antihack.actions;
import com.mineplex.anticheat.api.PlayerViolationEvent;
import com.mineplex.anticheat.checks.combat.KillauraTypeA;
+import com.mineplex.anticheat.checks.combat.KillauraTypeD;
+import com.mineplex.anticheat.checks.move.Glide;
+import com.mineplex.anticheat.checks.move.Speed;
import mineplex.core.common.util.UtilServer;
import org.bukkit.event.Listener;
@@ -20,6 +23,9 @@ public abstract class AntiHackAction implements Listener
static
{
ACTIONS.put(KillauraTypeA.class, new ImmediateBanAction(200));
+ ACTIONS.put(KillauraTypeD.class, new BanwaveAction(2000));
+ ACTIONS.put(Glide.class, new ImmediateBanAction(10000));
+ ACTIONS.put(Speed.class, new ImmediateBanAction(10000));
}
private int _vl;
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/actions/BanwaveAction.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/actions/BanwaveAction.java
index 0a28ffdd7..876671029 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/antihack/actions/BanwaveAction.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/actions/BanwaveAction.java
@@ -3,18 +3,17 @@ package mineplex.core.antihack.actions;
import com.mineplex.anticheat.api.PlayerViolationEvent;
import mineplex.core.Managers;
import mineplex.core.antihack.banwave.BanWaveManager;
+import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilServer;
-import java.util.Date;
-
class BanwaveAction extends AntiHackAction
{
- private Date nextBanWave;
+ private static final int BAN_DELAY_AVERAGE = 6 * 60 * 60 * 1000; // 6 hours
+ private static final int BAN_DELAY_VARIANCE_SPAN = 4 * 60 * 60 * 1000; // 4 hours total; 2 on either side
- BanwaveAction(Date nextBanWave, int vl)
+ BanwaveAction(int vl)
{
super(vl);
- this.nextBanWave = nextBanWave;
}
@Override
@@ -22,11 +21,13 @@ class BanwaveAction extends AntiHackAction
{
if (event.getViolations() >= this.getMinVl())
{
+ // Delay bans by 6 hours +/- 2 hours for fuzzing
+ long banTime = System.currentTimeMillis() + BAN_DELAY_AVERAGE + (UtilMath.r(BAN_DELAY_VARIANCE_SPAN) - (BAN_DELAY_VARIANCE_SPAN / 2));
Managers.get(BanWaveManager.class).insertBanWaveInfo(
event.getPlayer(),
- nextBanWave.getTime(),
+ banTime,
event.getCheckClass(),
- event.getMessage(),
+ "[GWEN] Hacking [BanWave]",
event.getViolations(),
UtilServer.getServerName()
);
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/banwave/BanWaveInfo.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/banwave/BanWaveInfo.java
index c73b544a6..2c471cd07 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/antihack/banwave/BanWaveInfo.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/banwave/BanWaveInfo.java
@@ -1,12 +1,9 @@
package mineplex.core.antihack.banwave;
+import java.util.Objects;
+
public class BanWaveInfo
{
- /**
- * The unique id for this BanWaveInfo
- */
- private int _id;
-
/**
* The account id for this BanWaveInfo
*/
@@ -17,11 +14,6 @@ public class BanWaveInfo
*/
private long _timeToBan;
- /**
- * Whether this BanWaveInfo has been executed
- */
- private boolean _banned;
-
/**
* The hack type
*/
@@ -42,16 +34,6 @@ public class BanWaveInfo
*/
private String _server;
- public int getId()
- {
- return _id;
- }
-
- public void setId(int id)
- {
- _id = id;
- }
-
public int getAccountId()
{
return _accountId;
@@ -72,16 +54,6 @@ public class BanWaveInfo
_timeToBan = timeToBan;
}
- public boolean isBanned()
- {
- return _banned;
- }
-
- public void setBanned(boolean banned)
- {
- _banned = banned;
- }
-
public String getHackType()
{
return _hackType;
@@ -130,28 +102,18 @@ public class BanWaveInfo
BanWaveInfo that = (BanWaveInfo) o;
- if (_id != that._id) return false;
- if (_accountId != that._accountId) return false;
- if (_timeToBan != that._timeToBan) return false;
- if (_banned != that._banned) return false;
- if (_vl != that._vl) return false;
- if (_hackType != null ? !_hackType.equals(that._hackType) : that._hackType != null) return false;
- if (_message != null ? !_message.equals(that._message) : that._message != null) return false;
- return _server != null ? _server.equals(that._server) : that._server == null;
+ return Objects.equals(_accountId, that._accountId)
+ && Objects.equals(_timeToBan, that._timeToBan)
+ && Objects.equals(_vl, that._vl)
+ && Objects.equals(_hackType, that._hackType)
+ && Objects.equals(_message, that._message)
+ && Objects.equals(_server, that._server);
}
@Override
public int hashCode()
{
- int result = _id;
- result = 31 * result + _accountId;
- result = 31 * result + (int) (_timeToBan ^ (_timeToBan >>> 32));
- result = 31 * result + (_banned ? 1 : 0);
- result = 31 * result + (_hackType != null ? _hackType.hashCode() : 0);
- result = 31 * result + (_message != null ? _message.hashCode() : 0);
- result = 31 * result + _vl;
- result = 31 * result + (_server != null ? _server.hashCode() : 0);
- return result;
+ return Objects.hash(_accountId, _timeToBan, _hackType, _message, _vl, _server);
}
}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/banwave/BanWaveManager.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/banwave/BanWaveManager.java
index 8b39d9ac0..dd2bebe96 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/antihack/banwave/BanWaveManager.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/banwave/BanWaveManager.java
@@ -9,8 +9,6 @@ import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerJoinEvent;
-import java.util.List;
-
@ReflectivelyCreateMiniPlugin
public class BanWaveManager extends MiniPlugin
{
@@ -28,28 +26,16 @@ public class BanWaveManager extends MiniPlugin
{
CoreClient client = require(CoreClientManager.class).Get(event.getPlayer());
- List infos = _repository.getBanWaveInfo(client.getAccountId());
-
- long now = System.currentTimeMillis();
-
- boolean banned = false;
- for (BanWaveInfo info : infos)
+ _repository.getPendingBanWaveInfo(client.getAccountId(), info ->
{
- if (info.getTimeToBan() < now && !info.isBanned())
+ long now = System.currentTimeMillis();
+
+ if (info.getTimeToBan() < now)
{
- banned = true;
require(AntiHack.class).doBanWave(event.getPlayer(), info.getMessage());
- break;
- }
- }
-
- if (banned)
- {
- for (BanWaveInfo info : infos)
- {
_repository.flagDone(info);
}
- }
+ });
});
}
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/banwave/BanWaveRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/banwave/BanWaveRepository.java
index 7b8650d35..ff41ab647 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/antihack/banwave/BanWaveRepository.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/banwave/BanWaveRepository.java
@@ -1,5 +1,6 @@
package mineplex.core.antihack.banwave;
+import mineplex.core.common.util.Callback;
import mineplex.core.common.util.UtilServer;
import mineplex.core.database.MinecraftRepository;
import mineplex.serverdata.database.DBPool;
@@ -7,27 +8,33 @@ import mineplex.serverdata.database.column.ColumnInt;
import mineplex.serverdata.database.column.ColumnLong;
import mineplex.serverdata.database.column.ColumnVarChar;
-import java.util.ArrayList;
-import java.util.List;
-
public class BanWaveRepository extends MinecraftRepository
{
- private static final String TABLE_NAME = "banwave";
-
- private static final String INITIALIZE_TABLE = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (" +
- "id INT AUTO_INCREMENT, " +
- "accountId INT NOT NULL, " +
+ private static final String INITIALIZE_PENDING_TABLE = "CREATE TABLE IF NOT EXISTS banwavePending (" +
+ "accountId INT(11) NOT NULL, " +
"timeToBan BIGINT UNSIGNED NOT NULL, " +
- "banned TINYINT DEFAULT '0', " +
"hacktype VARCHAR(64), " +
"message VARCHAR(255), " +
"vl INT, " +
"server VARCHAR(32), " +
- "PRIMARY KEY (id), " +
- "INDEX (accountId))";
- private static final String QUERY_BY_ACCOUNT = "SELECT * FROM " + TABLE_NAME + " WHERE accountId = ?";
- private static final String INSERT_INTO_TABLE = "INSERT INTO " + TABLE_NAME + " (accountId, timeToBan, hacktype, message, vl, server) VALUES (?, ?, ?, ?, ?, ?)";
- private static final String FLAG_DONE = "UPDATE " + TABLE_NAME + " SET banned = 1 WHERE id = ?";
+ "PRIMARY KEY (accountId)," +
+ "FOREIGN KEY (accountId) REFERENCES accounts(id))";
+
+ private static final String INITIALIZED_PROCESSED_TABLE = "CREATE TABLE IF NOT EXISTS banwaveProcessed (" +
+ "id INT NOT NULL AUTO_INCREMENT, " +
+ "accountId INT(11) NOT NULL, " +
+ "timeToBan BIGINT UNSIGNED NOT NULL, " +
+ "hacktype VARCHAR(64), " +
+ "message VARCHAR(255), " +
+ "vl INT, " +
+ "server VARCHAR(32), " +
+ "PRIMARY KEY (id)," +
+ "FOREIGN KEY (accountId) REFERENCES accounts(id))";
+ private static final String QUERY_PENDING = "SELECT * FROM banwavePending WHERE accountId = ?";
+ private static final String INSERT_PENDING = "INSERT IGNORE INTO banwavePending (accountId, timeToBan, hacktype, message, vl, server) VALUES (?, ?, ?, ?, ?, ?)";
+
+ private static final String PROCESS_WAVE_FOR_ACCOUNT = "INSERT INTO banwaveProcessed SELECT 0, accountId, timeToBan, hacktype, message, vl, server FROM banwavePending WHERE accountId = ?";
+ private static final String DELETE_PENDING = "DELETE FROM banwavePending WHERE accountId = ?";
BanWaveRepository()
{
@@ -37,7 +44,7 @@ public class BanWaveRepository extends MinecraftRepository
@Override
protected void initialize()
{
- executeUpdate(INITIALIZE_TABLE);
+ //executeUpdate(INITIALIZE_TABLE);
}
@Override
@@ -46,34 +53,28 @@ public class BanWaveRepository extends MinecraftRepository
}
- List getBanWaveInfo(int accountId)
+ void getPendingBanWaveInfo(int accountId, Callback callback)
{
- List banWaveInfo = new ArrayList<>();
-
- executeQuery(QUERY_BY_ACCOUNT, resultSet ->
+ executeQuery(QUERY_PENDING, resultSet ->
{
- while (resultSet.next())
+ if (resultSet.next())
{
BanWaveInfo info = new BanWaveInfo();
- info.setId(resultSet.getInt(1));
- info.setAccountId(resultSet.getInt(2));
- info.setTimeToBan(resultSet.getLong(3));
- info.setBanned(resultSet.getInt(4) == 1);
- info.setHackType(resultSet.getString(5));
- info.setMessage(resultSet.getString(6));
- info.setVl(resultSet.getInt(7));
- info.setServer(resultSet.getString(8));
+ info.setAccountId(resultSet.getInt(1));
+ info.setTimeToBan(resultSet.getLong(2));
+ info.setHackType(resultSet.getString(3));
+ info.setMessage(resultSet.getString(4));
+ info.setVl(resultSet.getInt(5));
+ info.setServer(resultSet.getString(6));
- banWaveInfo.add(info);
+ callback.run(info);
}
}, new ColumnInt("accountId", accountId));
-
- return banWaveInfo;
}
void insertBanWaveInfo(int accountId, long timeToBan, String hackType, String message, int vl, String server)
{
- executeInsert(INSERT_INTO_TABLE, null,
+ executeInsert(INSERT_PENDING, null,
new ColumnInt("accountId", accountId),
new ColumnLong("timeToBan", timeToBan),
new ColumnVarChar("hacktype", 64, hackType),
@@ -85,6 +86,7 @@ public class BanWaveRepository extends MinecraftRepository
void flagDone(BanWaveInfo info)
{
- executeUpdate(FLAG_DONE, new ColumnInt("id", info.getId()));
+ executeUpdate(PROCESS_WAVE_FOR_ACCOUNT, new ColumnInt("id", info.getAccountId()));
+ executeUpdate(DELETE_PENDING, new ColumnInt("id", info.getAccountId()));
}
}