parent
e503654114
commit
fa0e42a918
@ -20,11 +20,6 @@
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.mineplex</groupId>
|
||||
<artifactId>mineplex-serverdata</artifactId>
|
||||
<version>dev-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -4,7 +4,6 @@ import com.google.common.collect.Sets;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
@ -219,7 +218,7 @@ public class PlayerMap<V> implements Map<UUID, V>
|
||||
|
||||
private static class RemovalListener implements Listener
|
||||
{
|
||||
@EventHandler (priority = EventPriority.MONITOR)
|
||||
@EventHandler
|
||||
public void onQuit(PlayerQuitEvent event)
|
||||
{
|
||||
synchronized (LOCK)
|
||||
|
@ -1,10 +1,7 @@
|
||||
package mineplex.core.common.util;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import mineplex.core.common.events.PlayerRecieveBroadcastEvent;
|
||||
import mineplex.serverdata.Region;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.Sound;
|
||||
@ -16,7 +13,6 @@ import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
@ -56,7 +52,7 @@ public class UtilServer
|
||||
{
|
||||
return Bukkit.getServer();
|
||||
}
|
||||
|
||||
|
||||
public static void broadcast(String message)
|
||||
{
|
||||
for (Player cur : getPlayers())
|
||||
@ -65,13 +61,13 @@ public class UtilServer
|
||||
UtilPlayer.message(cur, message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void broadcast(LinkedList<String> messages)
|
||||
{
|
||||
for (Player cur : getPlayers())
|
||||
UtilPlayer.message(cur, messages);
|
||||
}
|
||||
|
||||
|
||||
public static void broadcastSpecial(String event, String message)
|
||||
{
|
||||
for (Player cur : getPlayers())
|
||||
@ -82,32 +78,32 @@ public class UtilServer
|
||||
cur.playSound(cur.getLocation(), Sound.ORB_PICKUP, 2f, 0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void broadcast(String sender, String message)
|
||||
{
|
||||
broadcast("§f§l" + sender + " " + "§b" + message);
|
||||
}
|
||||
|
||||
|
||||
public static void broadcastMagic(String sender, String message)
|
||||
{
|
||||
broadcast("§2§k" + message);
|
||||
}
|
||||
|
||||
public static double getFilledPercent()
|
||||
|
||||
public static double getFilledPercent()
|
||||
{
|
||||
return (double) getPlayers().length / (double) UtilServer.getServer().getMaxPlayers();
|
||||
return (double)getPlayers().length / (double)UtilServer.getServer().getMaxPlayers();
|
||||
}
|
||||
|
||||
|
||||
public static void RegisterEvents(Listener listener)
|
||||
{
|
||||
getPluginManager().registerEvents(listener, getPlugin());
|
||||
}
|
||||
|
||||
|
||||
public static void Unregister(Listener listener)
|
||||
{
|
||||
HandlerList.unregisterAll(listener);
|
||||
}
|
||||
|
||||
|
||||
public static JavaPlugin getPlugin()
|
||||
{
|
||||
return JavaPlugin.getProvidingPlugin(UtilServer.class);
|
||||
@ -139,16 +135,6 @@ public class UtilServer
|
||||
return getPlugin().getConfig().getString("serverstatus.name");
|
||||
}
|
||||
|
||||
public static Region getRegion()
|
||||
{
|
||||
return getPlugin().getConfig().getBoolean("serverstatus.us") ? Region.US : Region.EU;
|
||||
}
|
||||
|
||||
public static String getGroup()
|
||||
{
|
||||
return getPlugin().getConfig().getString("serverstatus.group");
|
||||
}
|
||||
|
||||
public static boolean isTestServer()
|
||||
{
|
||||
return getPlugin().getConfig().getString("serverstatus.group").equalsIgnoreCase("Testing");
|
||||
@ -194,39 +180,4 @@ public class UtilServer
|
||||
throwable.printStackTrace(System.out);
|
||||
}
|
||||
}
|
||||
|
||||
public static BukkitTask runAsync(Runnable runnable)
|
||||
{
|
||||
return getPlugin().getServer().getScheduler().runTaskAsynchronously(getPlugin(), runnable);
|
||||
}
|
||||
|
||||
public static BukkitTask runAsync(Runnable runnable, long time)
|
||||
{
|
||||
return getPlugin().getServer().getScheduler().runTaskLaterAsynchronously(getPlugin(), runnable, time);
|
||||
}
|
||||
|
||||
public static BukkitTask runAsyncTimer(Runnable runnable, long time, long period)
|
||||
{
|
||||
return getPlugin().getServer().getScheduler().runTaskTimerAsynchronously(getPlugin(), runnable, time, period);
|
||||
}
|
||||
|
||||
public static BukkitTask runSync(Runnable runnable)
|
||||
{
|
||||
return getPlugin().getServer().getScheduler().runTask(getPlugin(), runnable);
|
||||
}
|
||||
|
||||
public static BukkitTask runSyncLater(Runnable runnable, long delay)
|
||||
{
|
||||
return getPlugin().getServer().getScheduler().runTaskLater(getPlugin(), runnable, delay);
|
||||
}
|
||||
|
||||
public static BukkitTask runSyncTimer(Runnable runnable, long delay, long period)
|
||||
{
|
||||
return getPlugin().getServer().getScheduler().runTaskTimer(getPlugin(), runnable, delay, period);
|
||||
}
|
||||
|
||||
public static BukkitTask runSyncTimer(BukkitRunnable runnable, long delay, long period)
|
||||
{
|
||||
return runnable.runTaskTimer(getPlugin(), delay, period);
|
||||
}
|
||||
}
|
||||
|
@ -45,11 +45,6 @@
|
||||
<artifactId>anticheat</artifactId>
|
||||
<version>1.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.tukaani</groupId>
|
||||
<artifactId>xz</artifactId>
|
||||
<version>1.5</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
package mineplex.core.antihack.guardians;
|
||||
package mineplex.core.antihack;
|
||||
|
||||
import com.mineplex.spigot.ChunkAddEntityEvent;
|
||||
import mineplex.core.Managers;
|
@ -0,0 +1,71 @@
|
||||
package mineplex.core.antihack;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import mineplex.serverdata.database.DBPool;
|
||||
|
||||
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class AntiHackRepository
|
||||
{
|
||||
private String _serverName;
|
||||
|
||||
//private static String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS AntiHack_Kick_Log (id INT NOT NULL AUTO_INCREMENT, updated LONG, playerName VARCHAR(256), motd VARCHAR(56), gameType VARCHAR(56), map VARCHAR(256), serverName VARCHAR(256), report VARCHAR(256), ping VARCHAR(25), PRIMARY KEY (id));";
|
||||
private static String UPDATE_PLAYER_OFFENSES = "INSERT INTO AntiHack_Kick_Log (updated, playerName, motd, gameType, map, serverName, report, ping) VALUES (now(), ?, ?, ?, ?, ?, ?, ?);";
|
||||
|
||||
public AntiHackRepository(String serverName)
|
||||
{
|
||||
_serverName = serverName;
|
||||
}
|
||||
|
||||
public void initialize()
|
||||
{
|
||||
}
|
||||
|
||||
public void saveOffense(final Player player, final String motd, final String game, final String map, final String report)
|
||||
{
|
||||
new Thread(new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
PreparedStatement preparedStatement = null;
|
||||
|
||||
try (Connection connection = DBPool.getMineplexStats().getConnection())
|
||||
{
|
||||
preparedStatement = connection.prepareStatement(UPDATE_PLAYER_OFFENSES);
|
||||
|
||||
preparedStatement.setString(1, player.getName());
|
||||
preparedStatement.setString(2, motd);
|
||||
preparedStatement.setString(3, game);
|
||||
preparedStatement.setString(4, map);
|
||||
preparedStatement.setString(5, _serverName);
|
||||
preparedStatement.setString(6, report);
|
||||
preparedStatement.setString(7, ((CraftPlayer)player).getHandle().ping + "ms");
|
||||
|
||||
preparedStatement.execute();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
exception.printStackTrace();
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (preparedStatement != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
preparedStatement.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}
|
@ -1,7 +1,5 @@
|
||||
package mineplex.core.antihack;
|
||||
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.md_5.bungee.api.chat.ComponentBuilder;
|
||||
import net.minecraft.server.v1_8_R3.ChatComponentText;
|
||||
import net.minecraft.server.v1_8_R3.ChatModifier;
|
||||
import net.minecraft.server.v1_8_R3.EnumChatFormat;
|
||||
@ -27,9 +25,10 @@ public class CheckThresholds
|
||||
return _friendlyName;
|
||||
}
|
||||
|
||||
public void format(ComponentBuilder builder, int violationLevel)
|
||||
public IChatBaseComponent format(int violationLevel)
|
||||
{
|
||||
builder.append(_friendlyName, ComponentBuilder.FormatRetention.NONE).color(getSeverity(violationLevel)._color);
|
||||
EnumChatFormat color = getSeverity(violationLevel)._color;
|
||||
return new ChatComponentText(_friendlyName).setChatModifier(new ChatModifier().setColor(color));
|
||||
}
|
||||
|
||||
public Severity getSeverity(int violationLevel)
|
||||
@ -52,14 +51,14 @@ public class CheckThresholds
|
||||
|
||||
public enum Severity
|
||||
{
|
||||
NONE(ChatColor.GREEN),
|
||||
LOW(ChatColor.GREEN),
|
||||
MEDIUM(ChatColor.GOLD),
|
||||
HIGH(ChatColor.RED),
|
||||
NONE(EnumChatFormat.GREEN),
|
||||
LOW(EnumChatFormat.GREEN),
|
||||
MEDIUM(EnumChatFormat.GOLD),
|
||||
HIGH(EnumChatFormat.RED),
|
||||
;
|
||||
private final ChatColor _color;
|
||||
private final EnumChatFormat _color;
|
||||
|
||||
Severity(ChatColor color)
|
||||
Severity(EnumChatFormat color)
|
||||
{
|
||||
_color = color;
|
||||
}
|
||||
|
@ -0,0 +1,8 @@
|
||||
package mineplex.core.antihack;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public interface Detector
|
||||
{
|
||||
public void Reset(Player player);
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
package mineplex.core.antihack;
|
||||
|
||||
import net.minecraft.server.v1_8_R3.MinecraftServer;
|
||||
|
||||
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import com.mineplex.anticheat.api.MineplexLink;
|
||||
|
||||
import mineplex.core.Managers;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
import mineplex.core.disguise.DisguiseManager;
|
||||
import mineplex.core.disguise.disguises.DisguiseBase;
|
||||
|
||||
public class MineplexLinkImpl implements MineplexLink
|
||||
{
|
||||
private final DisguiseManager _disguiseManager = Managers.require(DisguiseManager.class);
|
||||
|
||||
@Override
|
||||
public EntityType getActiveDisguise(Player player)
|
||||
{
|
||||
DisguiseBase disguise = _disguiseManager.getActiveDisguise(player);
|
||||
return disguise != null ? disguise.getDisguiseType() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSpectator(Player player)
|
||||
{
|
||||
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
|
||||
}
|
||||
}
|
@ -1,87 +0,0 @@
|
||||
package mineplex.core.antihack;
|
||||
|
||||
import com.mineplex.anticheat.checks.Check;
|
||||
import com.mineplex.anticheat.checks.CheckManager;
|
||||
|
||||
import gnu.trove.map.TObjectIntMap;
|
||||
import gnu.trove.map.hash.TObjectIntHashMap;
|
||||
|
||||
/**
|
||||
* Locally cached information about a user's max violations and total number of alerts for each
|
||||
* check type.
|
||||
* <p>
|
||||
* Instances of this have no concept of identity i.e. account id is not tracked by this.
|
||||
*/
|
||||
public class ViolationLevels
|
||||
{
|
||||
private final TObjectIntMap<Class<? extends Check>> _maxViolations;
|
||||
|
||||
private final TObjectIntMap<Class<? extends Check>> _totalAlerts;
|
||||
|
||||
private final TObjectIntMap<Class<? extends Check>> _lastBan;
|
||||
|
||||
public ViolationLevels()
|
||||
{
|
||||
_maxViolations = new TObjectIntHashMap<>(CheckManager.AVAILABLE_CHECKS.size());
|
||||
_totalAlerts = new TObjectIntHashMap<>(CheckManager.AVAILABLE_CHECKS.size());
|
||||
_lastBan = new TObjectIntHashMap<>(CheckManager.AVAILABLE_CHECKS.size());
|
||||
}
|
||||
|
||||
public void updateMaxViolations(Class<? extends Check> check, int violationLevel)
|
||||
{
|
||||
if (violationLevel > _maxViolations.get(check))
|
||||
{
|
||||
_maxViolations.put(check, violationLevel);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateMaxViolationsSinceLastBan(Class<? extends Check> check, int violationLevel)
|
||||
{
|
||||
if (violationLevel > _lastBan.get(check))
|
||||
{
|
||||
_lastBan.put(check, violationLevel);
|
||||
}
|
||||
}
|
||||
|
||||
public void incrementAlerts(Class<? extends Check> check)
|
||||
{
|
||||
int cur = _totalAlerts.get(check);
|
||||
|
||||
setTotalAlerts(check, cur + 1);
|
||||
}
|
||||
|
||||
public void setTotalAlerts(Class<? extends Check> check, int totalAlerts)
|
||||
{
|
||||
_totalAlerts.put(check, totalAlerts);
|
||||
}
|
||||
|
||||
public int getTotalAlertsForCheck(Class<? extends Check> check)
|
||||
{
|
||||
if (_totalAlerts.containsKey(check))
|
||||
{
|
||||
return _totalAlerts.get(check);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int getMaxViolationsForCheck(Class<? extends Check> check)
|
||||
{
|
||||
if (_maxViolations.containsKey(check))
|
||||
{
|
||||
return _maxViolations.get(check);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int getLastBanViolationsForCheck(Class<? extends Check> check)
|
||||
{
|
||||
if (_lastBan.containsKey(check))
|
||||
{
|
||||
return _lastBan.get(check);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
@ -4,7 +4,6 @@ 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.HeadRoll;
|
||||
import com.mineplex.anticheat.checks.move.Speed;
|
||||
import mineplex.core.common.util.UtilServer;
|
||||
import org.bukkit.event.Listener;
|
||||
@ -14,19 +13,40 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public abstract class AntiHackAction
|
||||
public abstract class AntiHackAction implements Listener
|
||||
{
|
||||
private final int _vl;
|
||||
private static final Map<Class<?>, AntiHackAction> ACTIONS = new HashMap<>();
|
||||
private static final AntiHackAction NOOP_ACTION = new NoopAction();
|
||||
|
||||
private static final Date NEXT_BAN_WAVE = new Date(System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(5));
|
||||
|
||||
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;
|
||||
|
||||
AntiHackAction(int vl)
|
||||
{
|
||||
this._vl = vl;
|
||||
|
||||
UtilServer.RegisterEvents(this);
|
||||
}
|
||||
|
||||
public final int getMinVl()
|
||||
public abstract void handle(PlayerViolationEvent event);
|
||||
|
||||
public int getMinVl()
|
||||
{
|
||||
return this._vl;
|
||||
}
|
||||
|
||||
public abstract void handle(PlayerViolationEvent event);
|
||||
public static AntiHackAction getAction(Class<?> checkClass)
|
||||
{
|
||||
AntiHackAction action = ACTIONS.getOrDefault(checkClass, NOOP_ACTION);
|
||||
return action;
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +1,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;
|
||||
|
||||
public class BanwaveAction extends AntiHackAction
|
||||
class BanwaveAction extends AntiHackAction
|
||||
{
|
||||
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
|
||||
|
||||
public BanwaveAction(int vl)
|
||||
BanwaveAction(int vl)
|
||||
{
|
||||
super(vl);
|
||||
}
|
||||
@ -28,6 +27,7 @@ public class BanwaveAction extends AntiHackAction
|
||||
event.getPlayer(),
|
||||
banTime,
|
||||
event.getCheckClass(),
|
||||
"[GWEN] Hacking [BanWave]",
|
||||
event.getViolations(),
|
||||
UtilServer.getServerName()
|
||||
);
|
||||
|
@ -5,9 +5,9 @@ import mineplex.core.Managers;
|
||||
import mineplex.core.antihack.AntiHack;
|
||||
import mineplex.core.common.util.UtilServer;
|
||||
|
||||
public class ImmediateBanAction extends AntiHackAction
|
||||
class ImmediateBanAction extends AntiHackAction
|
||||
{
|
||||
public ImmediateBanAction(int vl)
|
||||
ImmediateBanAction(int vl)
|
||||
{
|
||||
super(vl);
|
||||
}
|
||||
@ -17,7 +17,12 @@ public class ImmediateBanAction extends AntiHackAction
|
||||
{
|
||||
if (event.getViolations() >= this.getMinVl())
|
||||
{
|
||||
Managers.get(AntiHack.class).doBan(event.getPlayer(), event.getCheckClass());
|
||||
String server = UtilServer.getServerName();
|
||||
if (server.contains("-"))
|
||||
{
|
||||
server = server.substring(0, server.indexOf('-'));
|
||||
}
|
||||
Managers.get(AntiHack.class).doBan(event.getPlayer(), "[GWEN] Hacking [" + server + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,49 @@
|
||||
package mineplex.core.antihack.actions;
|
||||
|
||||
import com.mineplex.anticheat.api.PlayerViolationEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class MixedAction extends AntiHackAction
|
||||
{
|
||||
private List<AntiHackAction> _actions = new ArrayList<>();
|
||||
private Map<UUID, Set<AntiHackAction>> _punished = new HashMap<>();
|
||||
|
||||
public MixedAction(AntiHackAction firstAction, AntiHackAction... actions)
|
||||
{
|
||||
super(firstAction.getMinVl());
|
||||
this._actions.add(firstAction);
|
||||
this._actions.addAll(Arrays.asList(actions));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void handle(PlayerViolationEvent event)
|
||||
{
|
||||
for (int i = this._actions.size() - 1; i >= 0; i--)
|
||||
{
|
||||
AntiHackAction action = this._actions.get(i);
|
||||
if (action.getMinVl() <= event.getViolations())
|
||||
{
|
||||
if (_punished.computeIfAbsent(event.getPlayer().getUniqueId(), key -> new HashSet<>()).add(action))
|
||||
{
|
||||
action.handle(event);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getMinVl()
|
||||
{
|
||||
return this._actions.get(0).getMinVl();
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@ import com.mineplex.anticheat.api.PlayerViolationEvent;
|
||||
|
||||
public class NoopAction extends AntiHackAction
|
||||
{
|
||||
public NoopAction()
|
||||
NoopAction()
|
||||
{
|
||||
super(Integer.MAX_VALUE);
|
||||
}
|
||||
|
@ -1,9 +0,0 @@
|
||||
package mineplex.core.antihack.animations;
|
||||
|
||||
import mineplex.core.antihack.AntiHack;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public interface BanwaveAnimation
|
||||
{
|
||||
void run(Player player, Runnable after);
|
||||
}
|
@ -1,123 +0,0 @@
|
||||
package mineplex.core.antihack.animations;
|
||||
|
||||
import com.google.common.util.concurrent.AtomicDouble;
|
||||
import mineplex.core.antihack.AntiHack;
|
||||
import mineplex.core.antihack.guardians.AntiHackGuardian;
|
||||
import mineplex.core.common.util.UtilEnt;
|
||||
import mineplex.core.common.util.UtilParticle;
|
||||
import mineplex.core.common.util.UtilServer;
|
||||
import net.minecraft.server.v1_8_R3.MathHelper;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class BanwaveAnimationSpin implements BanwaveAnimation
|
||||
{
|
||||
@Override
|
||||
public void run(Player player, Runnable after)
|
||||
{
|
||||
float oldWalkSpeed = player.getWalkSpeed();
|
||||
player.setWalkSpeed(0);
|
||||
player.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, 999999, -10));
|
||||
|
||||
double radius = 4;
|
||||
double heightAdj = 8;
|
||||
|
||||
double baseDeg = 18;
|
||||
|
||||
Location center = player.getLocation().add(0, heightAdj, 0);
|
||||
AntiHackGuardian north = new AntiHackGuardian(center.clone().add(0, 0, -radius), 0, 0, 0, 0, 0, 0, false);
|
||||
AntiHackGuardian east = new AntiHackGuardian(center.clone().add(radius, 0, 0), 0, 0, 0, 0, 0, 0, false);
|
||||
AntiHackGuardian south = new AntiHackGuardian(center.clone().add(0, 0, radius), 0, 0, 0, 0, 0, 0, false);
|
||||
AntiHackGuardian west = new AntiHackGuardian(center.clone().add(-radius, 0, 0), 0, 0, 0, 0, 0, 0, false);
|
||||
|
||||
UtilEnt.CreatureLook(east.getEntity(), player);
|
||||
UtilEnt.CreatureLook(west.getEntity(), player);
|
||||
UtilEnt.CreatureLook(south.getEntity(), player);
|
||||
UtilEnt.CreatureLook(north.getEntity(), player);
|
||||
|
||||
Function<Double, Double> magic = seconds -> Math.pow(2, seconds - 5);
|
||||
|
||||
UtilServer.runSyncLater(() ->
|
||||
{
|
||||
north.shoot(player);
|
||||
east.shoot(player);
|
||||
south.shoot(player);
|
||||
west.shoot(player);
|
||||
|
||||
// We get 5 seconds, or 100 ticks
|
||||
AtomicInteger timer = new AtomicInteger(5);
|
||||
|
||||
AtomicDouble cNorth = new AtomicDouble(270);
|
||||
AtomicDouble cEast = new AtomicDouble(0);
|
||||
AtomicDouble cSouth = new AtomicDouble(90);
|
||||
AtomicDouble cWest = new AtomicDouble(180);
|
||||
|
||||
UtilServer.runSyncTimer(new BukkitRunnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
timer.getAndIncrement();
|
||||
if (timer.get() > 100)
|
||||
{
|
||||
cancel();
|
||||
|
||||
player.removePotionEffect(PotionEffectType.JUMP);
|
||||
player.setWalkSpeed(oldWalkSpeed);
|
||||
Location location = player.getLocation();
|
||||
|
||||
UtilParticle.PlayParticle(UtilParticle.ParticleType.HUGE_EXPLOSION, player.getLocation(), 3f, 3f, 3f, 0, 32, UtilParticle.ViewDist.MAX, UtilServer.getPlayers());
|
||||
|
||||
after.run();
|
||||
|
||||
north.shoot(null);
|
||||
south.shoot(null);
|
||||
east.shoot(null);
|
||||
west.shoot(null);
|
||||
UtilEnt.CreatureLook(north.getEntity(), location);
|
||||
UtilEnt.CreatureLook(south.getEntity(), location);
|
||||
UtilEnt.CreatureLook(east.getEntity(), location);
|
||||
UtilEnt.CreatureLook(west.getEntity(), location);
|
||||
UtilServer.runSyncLater(() ->
|
||||
{
|
||||
north.remove();
|
||||
south.remove();
|
||||
east.remove();
|
||||
west.remove();
|
||||
}, 40L);
|
||||
return;
|
||||
}
|
||||
|
||||
double seconds = timer.get() / 20.0;
|
||||
|
||||
double rate = magic.apply(seconds) * 3 * baseDeg;
|
||||
|
||||
player.getLocation(center);
|
||||
center.add(0, heightAdj, 0);
|
||||
|
||||
{
|
||||
cNorth.addAndGet(rate);
|
||||
north.move(center.getX() + radius * MathHelper.cos((float) Math.toRadians(cNorth.get())), center.getY(), center.getZ() + radius * MathHelper.sin((float) Math.toRadians(cNorth.get())));
|
||||
}
|
||||
{
|
||||
cSouth.addAndGet(rate);
|
||||
south.move(center.getX() + radius * MathHelper.cos((float) Math.toRadians(cSouth.get())), center.getY(), center.getZ() + radius * MathHelper.sin((float) Math.toRadians(cSouth.get())));
|
||||
}
|
||||
{
|
||||
cEast.addAndGet(rate);
|
||||
east.move(center.getX() + radius * MathHelper.cos((float) Math.toRadians(cEast.get())), center.getY(), center.getZ() + radius * MathHelper.sin((float) Math.toRadians(cEast.get())));
|
||||
}
|
||||
{
|
||||
cWest.addAndGet(rate);
|
||||
west.move(center.getX() + radius * MathHelper.cos((float) Math.toRadians(cWest.get())), center.getY(), center.getZ() + radius * MathHelper.sin((float) Math.toRadians(cWest.get())));
|
||||
}
|
||||
}
|
||||
}, 5L, 1L);
|
||||
}, 20);
|
||||
}
|
||||
}
|
@ -34,11 +34,6 @@ public class BanWaveInfo
|
||||
*/
|
||||
private String _server;
|
||||
|
||||
/**
|
||||
* The metadata id
|
||||
*/
|
||||
private String _metadata;
|
||||
|
||||
public int getAccountId()
|
||||
{
|
||||
return _accountId;
|
||||
@ -99,16 +94,6 @@ public class BanWaveInfo
|
||||
_server = server;
|
||||
}
|
||||
|
||||
public String getMetadataId()
|
||||
{
|
||||
return this._metadata;
|
||||
}
|
||||
|
||||
public void setMetadataId(String id)
|
||||
{
|
||||
this._metadata = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
|
@ -5,25 +5,14 @@ import mineplex.core.ReflectivelyCreateMiniPlugin;
|
||||
import mineplex.core.account.CoreClient;
|
||||
import mineplex.core.account.CoreClientManager;
|
||||
import mineplex.core.antihack.AntiHack;
|
||||
import mineplex.core.antihack.logging.AntihackLogger;
|
||||
import mineplex.core.antihack.redisnotifications.GwenBanwaveNotification;
|
||||
import mineplex.core.common.util.UtilServer;
|
||||
import mineplex.serverdata.commands.ServerCommandManager;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.mineplex.anticheat.checks.Check;
|
||||
import com.mineplex.anticheat.checks.CheckManager;
|
||||
|
||||
@ReflectivelyCreateMiniPlugin
|
||||
public class BanWaveManager extends MiniPlugin
|
||||
{
|
||||
private final BanWaveRepository _repository = new BanWaveRepository();
|
||||
private final CoreClientManager _clientManager = require(CoreClientManager.class);
|
||||
|
||||
private BanWaveManager()
|
||||
{
|
||||
@ -43,39 +32,29 @@ public class BanWaveManager extends MiniPlugin
|
||||
|
||||
if (info.getTimeToBan() < now)
|
||||
{
|
||||
require(AntiHack.class).doBanWave(event.getPlayer(), info);
|
||||
require(AntiHack.class).doBanWave(event.getPlayer(), info.getMessage());
|
||||
_repository.flagDone(info);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public void insertBanWaveInfo(Player player, long timeToBan, Class<? extends Check> checkClass, int vl, String server)
|
||||
public void insertBanWaveInfo(Player player, long timeToBan, Class<?> checkClass, String message, int vl, String server)
|
||||
{
|
||||
insertBanWaveInfo(player, timeToBan, checkClass, vl, server, null);
|
||||
insertBanWaveInfo(player, timeToBan, checkClass, message, vl, server, null);
|
||||
}
|
||||
|
||||
public void insertBanWaveInfo(Player player, long timeToBan, Class<? extends Check> checkClass, int vl, String server, Runnable after)
|
||||
public void insertBanWaveInfo(Player player, long timeToBan, Class<?> checkClass, String message, int vl, String server, Runnable after)
|
||||
{
|
||||
runAsync(() ->
|
||||
{
|
||||
String id = AntiHack.generateId();
|
||||
String newMessage = "[GWEN] [BanWave] " + id;
|
||||
CoreClient client = require(CoreClientManager.class).Get(player);
|
||||
|
||||
CoreClient client = _clientManager.Get(player);
|
||||
this._repository.insertBanWaveInfo(client.getAccountId(), timeToBan, checkClass.getName(), message, vl, server);
|
||||
|
||||
if (this._repository.insertBanWaveInfo(client.getAccountId(), timeToBan, CheckManager.getCheckSimpleName(checkClass), newMessage, vl, server, id))
|
||||
if (after != null)
|
||||
{
|
||||
runAsync(() ->
|
||||
{
|
||||
GwenBanwaveNotification notification = new GwenBanwaveNotification(UtilServer.getServerName(), player.getName(), player.getUniqueId().toString(), CheckManager.getCheckSimpleName(checkClass), id, timeToBan);
|
||||
ServerCommandManager.getInstance().publishCommand(notification);
|
||||
});
|
||||
|
||||
JsonObject custom = new JsonObject();
|
||||
custom.addProperty("is-banwave", true);
|
||||
|
||||
require(AntihackLogger.class).saveMetadata(player, id, after, custom);
|
||||
after.run();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -17,7 +17,6 @@ public class BanWaveRepository extends MinecraftRepository
|
||||
"message VARCHAR(255), " +
|
||||
"vl INT, " +
|
||||
"server VARCHAR(32), " +
|
||||
"metadata VARCHAR(10), " +
|
||||
"PRIMARY KEY (accountId)," +
|
||||
"FOREIGN KEY (accountId) REFERENCES accounts(id))";
|
||||
|
||||
@ -29,14 +28,12 @@ public class BanWaveRepository extends MinecraftRepository
|
||||
"message VARCHAR(255), " +
|
||||
"vl INT, " +
|
||||
"server VARCHAR(32), " +
|
||||
"metadata VARCHAR(10), " +
|
||||
"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, metadata) VALUES (?, ?, ?, ?, ?, ?, ?)";
|
||||
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, metadata FROM banwavePending WHERE accountId = ?";
|
||||
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()
|
||||
@ -69,25 +66,22 @@ public class BanWaveRepository extends MinecraftRepository
|
||||
info.setMessage(resultSet.getString(4));
|
||||
info.setVl(resultSet.getInt(5));
|
||||
info.setServer(resultSet.getString(6));
|
||||
info.setMessage(resultSet.getString(7));
|
||||
|
||||
callback.run(info);
|
||||
}
|
||||
}, new ColumnInt("accountId", accountId));
|
||||
}
|
||||
|
||||
boolean insertBanWaveInfo(int accountId, long timeToBan, String hackType, String message, int vl, String server, String metadata)
|
||||
void insertBanWaveInfo(int accountId, long timeToBan, String hackType, String message, int vl, String server)
|
||||
{
|
||||
int affectedRows = executeInsert(INSERT_PENDING, null,
|
||||
executeInsert(INSERT_PENDING, null,
|
||||
new ColumnInt("accountId", accountId),
|
||||
new ColumnLong("timeToBan", timeToBan),
|
||||
new ColumnVarChar("hacktype", 64, hackType),
|
||||
new ColumnVarChar("message", 255, message),
|
||||
new ColumnInt("vl", vl),
|
||||
new ColumnVarChar("server", 32, server),
|
||||
new ColumnVarChar("metadata", 10, metadata)
|
||||
new ColumnVarChar("server", 32, server)
|
||||
);
|
||||
return affectedRows > 0;
|
||||
}
|
||||
|
||||
void flagDone(BanWaveInfo info)
|
||||
|
@ -1,24 +0,0 @@
|
||||
package mineplex.core.antihack.commands;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import mineplex.core.antihack.AntiHack;
|
||||
import mineplex.core.command.CommandBase;
|
||||
import mineplex.core.common.Rank;
|
||||
import mineplex.core.common.util.F;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
|
||||
public class AnticheatOffCommand extends CommandBase<AntiHack>
|
||||
{
|
||||
public AnticheatOffCommand(AntiHack plugin)
|
||||
{
|
||||
super(plugin, Rank.DEVELOPER, "acoff");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Execute(Player caller, String[] args)
|
||||
{
|
||||
Plugin.disableAnticheat();
|
||||
UtilPlayer.message(caller, F.main(Plugin.getName(), "Disabled anticheat"));
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
package mineplex.core.antihack.commands;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import mineplex.core.antihack.AntiHack;
|
||||
import mineplex.core.command.CommandBase;
|
||||
import mineplex.core.common.Rank;
|
||||
import mineplex.core.common.util.F;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
|
||||
public class AnticheatOnCommand extends CommandBase<AntiHack>
|
||||
{
|
||||
public AnticheatOnCommand(AntiHack plugin)
|
||||
{
|
||||
super(plugin, Rank.DEVELOPER, "acon");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Execute(Player caller, String[] args)
|
||||
{
|
||||
Plugin.enableAnticheat();
|
||||
UtilPlayer.message(caller, F.main(Plugin.getName(), "Enabled anticheat"));
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
package mineplex.core.antihack.commands;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import mineplex.core.antihack.AntiHack;
|
||||
import mineplex.core.command.CommandBase;
|
||||
import mineplex.core.common.Rank;
|
||||
import mineplex.core.common.util.F;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
|
||||
public class DetailedMessagesCommand extends CommandBase<AntiHack>
|
||||
{
|
||||
public DetailedMessagesCommand(AntiHack plugin)
|
||||
{
|
||||
super(plugin, Rank.DEVELOPER, "detailedmessages");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Execute(Player caller, String[] args)
|
||||
{
|
||||
if (Plugin.toggleDetailedMessage(caller))
|
||||
{
|
||||
UtilPlayer.message(caller, F.main(Plugin.getName(), "Detailed messages enabled"));
|
||||
}
|
||||
else
|
||||
{
|
||||
UtilPlayer.message(caller, F.main(Plugin.getName(), "Detailed messages disabled"));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
package mineplex.core.antihack.commands;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import com.mineplex.anticheat.MineplexAnticheat;
|
||||
import com.mineplex.anticheat.checks.Check;
|
||||
import com.mineplex.anticheat.checks.CheckManager;
|
||||
|
||||
import mineplex.core.antihack.AntiHack;
|
||||
import mineplex.core.command.CommandBase;
|
||||
import mineplex.core.common.Rank;
|
||||
import mineplex.core.common.util.F;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
|
||||
public class GetVlsCommand extends CommandBase<AntiHack>
|
||||
{
|
||||
public GetVlsCommand(AntiHack plugin)
|
||||
{
|
||||
super(plugin, Rank.DEVELOPER, "getvls");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Execute(Player caller, String[] args)
|
||||
{
|
||||
if (args.length > 0)
|
||||
{
|
||||
Player p = Bukkit.getPlayerExact(args[0]);
|
||||
if (p != null)
|
||||
{
|
||||
CheckManager manager = MineplexAnticheat.getPlugin(MineplexAnticheat.class).getCheckManager();
|
||||
for (Check check : manager.getActiveChecks())
|
||||
{
|
||||
UtilPlayer.message(caller, F.desc(check.getName(), String.valueOf(check.getViolationLevel(p))));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UtilPlayer.message(caller, F.main(Plugin.getName(), "Could not find player"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UtilPlayer.message(caller, F.main(Plugin.getName(), "No player specified"));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
package mineplex.core.antihack.commands;
|
||||
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import mineplex.core.antihack.AntiHack;
|
||||
import mineplex.core.antihack.animations.BanwaveAnimationSpin;
|
||||
import mineplex.core.command.CommandBase;
|
||||
import mineplex.core.common.Rank;
|
||||
import mineplex.core.common.util.C;
|
||||
import mineplex.core.common.util.F;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
|
||||
public class TestBanCommand extends CommandBase<AntiHack>
|
||||
{
|
||||
public TestBanCommand(AntiHack plugin)
|
||||
{
|
||||
super(plugin, Rank.DEVELOPER, "testban");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Execute(Player caller, String[] args)
|
||||
{
|
||||
if (args.length > 0)
|
||||
{
|
||||
Player p = Bukkit.getPlayerExact(args[0]);
|
||||
if (p != null)
|
||||
{
|
||||
new BanwaveAnimationSpin().run(p, () ->
|
||||
{
|
||||
String reason = C.cRed + C.Bold + "You are banned for permanent by Test" +
|
||||
"\n" + C.cWhite + "Seems to be speeding up time. (" + ThreadLocalRandom.current().nextInt(200, 400) + " packets/150 ms)" +
|
||||
"\n" + C.cDGreen + "Unfairly banned? Appeal at " + C.cGreen + "www.mineplex.com/appeals";
|
||||
p.kickPlayer(reason);
|
||||
|
||||
Plugin.announceBan(p);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
UtilPlayer.message(caller, F.main(Plugin.getName(), "Could not find player"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UtilPlayer.message(caller, F.main(Plugin.getName(), "No player specified"));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,129 +0,0 @@
|
||||
package mineplex.core.antihack.guardians;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import mineplex.core.MiniPlugin;
|
||||
import mineplex.core.PlayerSelector;
|
||||
import mineplex.core.ReflectivelyCreateMiniPlugin;
|
||||
import mineplex.core.common.Rank;
|
||||
import mineplex.core.common.util.UtilLambda;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Function;
|
||||
|
||||
@ReflectivelyCreateMiniPlugin
|
||||
public class GuardianManager extends MiniPlugin
|
||||
{
|
||||
private static final int MAX_STALKED_PLAYERS = 3;
|
||||
private static final int STALK_COOLDOWN_TIME_SECONDS = 5;
|
||||
|
||||
private static final int MIN_STALK_TIME = 10 * 20;
|
||||
private static final int MAX_STALK_TIME = 20 * 20;
|
||||
private static final int MAX_MIN_DIFF = MAX_STALK_TIME - MIN_STALK_TIME;
|
||||
private static final Function<Integer, Double> STALK_END_PROBABILITY_EQUATION = x ->
|
||||
{
|
||||
return 1.0/ MAX_MIN_DIFF * x; // linear equation with points (0, 0) and (diff, 1)
|
||||
};
|
||||
|
||||
private final Cache<UUID, Boolean> _stalkingCooldown = CacheBuilder.newBuilder()
|
||||
.concurrencyLevel(1)
|
||||
.expireAfterWrite(STALK_COOLDOWN_TIME_SECONDS, TimeUnit.SECONDS)
|
||||
.build();
|
||||
private final List<UUID> _stalking = new ArrayList<>();
|
||||
private List<AntiHackGuardian> _guardians = new ArrayList<>();
|
||||
|
||||
private GuardianManager()
|
||||
{
|
||||
super("GuardianManager");
|
||||
|
||||
this._plugin.getServer().getScheduler().runTaskTimer(this._plugin, () ->
|
||||
{
|
||||
for (AntiHackGuardian guardian : this._guardians)
|
||||
{
|
||||
if (guardian.getTarget() != null && !guardian.getTarget().isOnline())
|
||||
{
|
||||
this._stalking.remove(guardian.getTarget().getUniqueId());
|
||||
guardian.stopTargeting();
|
||||
}
|
||||
else if (guardian.getTargetingTime() > MIN_STALK_TIME)
|
||||
{
|
||||
double threshold = STALK_END_PROBABILITY_EQUATION.apply(guardian.getTargetingTime() - MIN_STALK_TIME);
|
||||
if (Math.random() <= threshold)
|
||||
{
|
||||
this._stalking.remove(guardian.getTarget().getUniqueId());
|
||||
_stalkingCooldown.put(guardian.getTarget().getUniqueId(), true);
|
||||
guardian.stopTargeting();
|
||||
}
|
||||
}
|
||||
guardian.tick();
|
||||
}
|
||||
}, 0L, 1L);
|
||||
|
||||
this._plugin.getServer().getScheduler().runTaskTimer(this._plugin, () ->
|
||||
{
|
||||
if (_stalking.size() >= MAX_STALKED_PLAYERS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_guardians.size() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<Player> targets = PlayerSelector.selectPlayers(
|
||||
UtilLambda.and(
|
||||
PlayerSelector.NOT_VANISHED,
|
||||
PlayerSelector.hasAnyRank(false,
|
||||
Rank.ALL,
|
||||
Rank.ULTRA,
|
||||
Rank.HERO,
|
||||
Rank.LEGEND,
|
||||
Rank.TITAN,
|
||||
Rank.TWITCH,
|
||||
Rank.YOUTUBE_SMALL,
|
||||
Rank.YOUTUBE,
|
||||
Rank.MEDIA,
|
||||
Rank.ADMIN,
|
||||
Rank.DEVELOPER,
|
||||
Rank.OWNER,
|
||||
Rank.LT
|
||||
),
|
||||
player -> !_stalking.contains(player.getUniqueId()),
|
||||
player -> _stalkingCooldown.getIfPresent(player.getUniqueId()) == null
|
||||
));
|
||||
|
||||
while (_stalking.size() < MAX_STALKED_PLAYERS && targets.size() > 0)
|
||||
{
|
||||
Player target = targets.remove(ThreadLocalRandom.current().nextInt(targets.size()));
|
||||
|
||||
int start = ThreadLocalRandom.current().nextInt(_guardians.size());
|
||||
|
||||
for (int i = start, j = 0; j < _guardians.size(); i++, j++)
|
||||
{
|
||||
if (i >= _guardians.size())
|
||||
{
|
||||
i -= _guardians.size();
|
||||
}
|
||||
AntiHackGuardian guardian = _guardians.get(i);
|
||||
if (!guardian.isTargeting())
|
||||
{
|
||||
guardian.target(target);
|
||||
_stalking.add(target.getUniqueId());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 0L, 20L);
|
||||
}
|
||||
|
||||
public void registerGuardian(AntiHackGuardian guardian)
|
||||
{
|
||||
this._guardians.add(guardian);
|
||||
}
|
||||
}
|
@ -1,196 +0,0 @@
|
||||
package mineplex.core.antihack.logging;
|
||||
|
||||
import com.mineplex.anticheat.checks.Check;
|
||||
import com.mineplex.anticheat.checks.CheckManager;
|
||||
|
||||
import gnu.trove.map.TIntObjectMap;
|
||||
|
||||
import mineplex.core.antihack.ViolationLevels;
|
||||
import mineplex.core.database.MinecraftRepository;
|
||||
import mineplex.serverdata.database.DBPool;
|
||||
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class AnticheatDatabase extends MinecraftRepository
|
||||
{
|
||||
/*
|
||||
CREATE TABLE IF NOT EXISTS anticheat_vl_logs (accountId INT, checkId INT, maxViolations INT, totalAlerts INT, sinceLastBan INT, PRIMARY KEY(accountId, checkId));
|
||||
CREATE TABLE IF NOT EXISTS anticheat_ban_metadata (id INT NOT NULL AUTO_INCREMENT, accountId INT, banId CHAR(10) NOT NULL, data MEDIUMTEXT NOT NULL, PRIMARY KEY(id));
|
||||
*/
|
||||
|
||||
private static final String INSERT_INTO_METADATA = "INSERT INTO anticheat_ban_metadata (accountId, banId, data) VALUES (?, ?, ?);";
|
||||
|
||||
private static final String UPDATE_VIOLATIONS = "INSERT INTO anticheat_vl_logs (accountId, checkId, "
|
||||
+ "maxViolations, sinceLastBan, totalAlerts) VALUES (?, ?, ?, ?, ?) ON DUPLICATE KEY"
|
||||
+ " UPDATE maxViolations = VALUES(maxViolations), totalAlerts = VALUES(totalAlerts), sinceLastBan = VALUES(sinceLastBan);";
|
||||
|
||||
private static final String CLEAR_LAST_BAN_VIOLATIONS = "UPDATE anticheat_vl_logs SET sinceLastBan = 0 WHERE accountId = ?;";
|
||||
|
||||
private static final String GET_VLS = "SELECT checkId, maxViolations, sinceLastBan, totalAlerts FROM anticheat_vl_logs";
|
||||
|
||||
private static final String GET_VLS_BY_ACCOUNT_ID = GET_VLS + " WHERE accountId = ?";
|
||||
|
||||
private static final String GET_VLS_FOR_CHECK = GET_VLS + " WHERE checkId = ? AND accountId = ?";
|
||||
|
||||
|
||||
public AnticheatDatabase(JavaPlugin plugin)
|
||||
{
|
||||
super(plugin, DBPool.getAccount());
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit a set of user violation changes batch style.
|
||||
*
|
||||
* @param uploadQueue the {@link TIntObjectMap} describing the changes.
|
||||
*/
|
||||
public void saveViolationLevels(Map<Integer, ViolationLevels> uploadQueue)
|
||||
{
|
||||
try (Connection connection = getConnection())
|
||||
{
|
||||
PreparedStatement preparedStatement = connection.prepareStatement(UPDATE_VIOLATIONS);
|
||||
|
||||
uploadQueue.forEach((accountId, vls) ->
|
||||
{
|
||||
CheckManager.AVAILABLE_CHECKS.values().forEach(check ->
|
||||
{
|
||||
int checkId = CheckManager.getCheckId(check),
|
||||
maxVls = vls.getMaxViolationsForCheck(check),
|
||||
maxVlsSinceLastBan = vls.getLastBanViolationsForCheck(check),
|
||||
totalAlerts = vls.getTotalAlertsForCheck(check);
|
||||
|
||||
// if neither value has been set don't store anything
|
||||
if (maxVls < 0 && totalAlerts < 0 && maxVlsSinceLastBan < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
maxVls = Math.max(maxVls, 0);
|
||||
maxVlsSinceLastBan = Math.max(maxVlsSinceLastBan, 0);
|
||||
totalAlerts = Math.max(totalAlerts, 0);
|
||||
|
||||
try
|
||||
{
|
||||
preparedStatement.setInt(1, accountId);
|
||||
preparedStatement.setInt(2, checkId);
|
||||
preparedStatement.setInt(3, maxVls);
|
||||
preparedStatement.setInt(4, maxVlsSinceLastBan);
|
||||
preparedStatement.setInt(5, totalAlerts);
|
||||
preparedStatement.addBatch();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
preparedStatement.executeBatch();
|
||||
}
|
||||
catch (SQLException ex)
|
||||
{
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to retrieve violation levels for the given account id.
|
||||
*
|
||||
* @param accountId The account id;
|
||||
* @return an {@link Optional} describing the user's violation levels, or an empty one if none
|
||||
* are found.
|
||||
* @throws SQLException On failing to connect to the database.
|
||||
*/
|
||||
public Optional<ViolationLevels> getViolationLevels(int accountId)
|
||||
{
|
||||
ViolationLevels levels = new ViolationLevels();
|
||||
|
||||
try (Connection connection = getConnection())
|
||||
{
|
||||
PreparedStatement statement = connection.prepareStatement(GET_VLS_BY_ACCOUNT_ID);
|
||||
statement.setInt(1, accountId);
|
||||
|
||||
ResultSet result = statement.executeQuery();
|
||||
|
||||
while (result.next())
|
||||
{
|
||||
int checkId = result.getInt("checkId");
|
||||
Class<? extends Check> checkType = CheckManager.getCheckById(checkId);
|
||||
if (checkType == null)
|
||||
{
|
||||
System.err.println("Whoops. Unintended refactor?");
|
||||
continue;
|
||||
}
|
||||
levels.updateMaxViolations(checkType, result.getInt("maxViolations"));
|
||||
levels.updateMaxViolationsSinceLastBan(checkType, result.getInt("sinceLastBan"));
|
||||
levels.setTotalAlerts(checkType, result.getInt("totalAlerts"));
|
||||
}
|
||||
}
|
||||
catch (SQLException ex)
|
||||
{
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
return Optional.of(levels);
|
||||
}
|
||||
|
||||
public void clearLastBan(int accountId, Runnable after)
|
||||
{
|
||||
try (Connection connection = getConnection())
|
||||
{
|
||||
PreparedStatement statement = connection.prepareStatement(CLEAR_LAST_BAN_VIOLATIONS);
|
||||
statement.setInt(1, accountId);
|
||||
|
||||
statement.executeUpdate();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (after != null)
|
||||
after.run();
|
||||
}
|
||||
}
|
||||
|
||||
public void saveMetadata(int accountId, String id, String base64, Runnable after)
|
||||
{
|
||||
try (Connection connection = getConnection())
|
||||
{
|
||||
PreparedStatement statement = connection.prepareStatement(INSERT_INTO_METADATA);
|
||||
statement.setInt(1, accountId);
|
||||
statement.setString(2, id);
|
||||
statement.setString(3, base64);
|
||||
|
||||
statement.executeUpdate();
|
||||
}
|
||||
catch (SQLException ex)
|
||||
{
|
||||
ex.printStackTrace();
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (after != null)
|
||||
after.run();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initialize()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void update()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
package mineplex.core.antihack.logging;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
|
||||
import mineplex.core.common.util.UtilServer;
|
||||
|
||||
public abstract class AnticheatMetadata implements Listener
|
||||
{
|
||||
public AnticheatMetadata()
|
||||
{
|
||||
UtilServer.RegisterEvents(this);
|
||||
}
|
||||
|
||||
public abstract String getId();
|
||||
|
||||
public abstract JsonElement build(UUID player);
|
||||
|
||||
public abstract void remove(UUID player);
|
||||
}
|
@ -1,214 +0,0 @@
|
||||
package mineplex.core.antihack.logging;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.player.PlayerLoginEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.tukaani.xz.LZMA2Options;
|
||||
import org.tukaani.xz.XZ;
|
||||
import org.tukaani.xz.XZOutputStream;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.mineplex.anticheat.api.PlayerViolationEvent;
|
||||
import com.mineplex.anticheat.checks.Check;
|
||||
|
||||
import mineplex.core.MiniPlugin;
|
||||
import mineplex.core.ReflectivelyCreateMiniPlugin;
|
||||
import mineplex.core.account.CoreClientManager;
|
||||
import mineplex.core.antihack.AntiHack;
|
||||
import mineplex.core.antihack.ViolationLevels;
|
||||
import mineplex.core.antihack.logging.builtin.PartyInfoMetadata;
|
||||
import mineplex.core.antihack.logging.builtin.PlayerInfoMetadata;
|
||||
import mineplex.core.antihack.logging.builtin.ServerInfoMetadata;
|
||||
import mineplex.core.antihack.logging.builtin.ViolationInfoMetadata;
|
||||
import mineplex.core.command.CommandBase;
|
||||
import mineplex.core.common.Rank;
|
||||
import mineplex.core.common.util.F;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
import mineplex.core.common.util.UtilServer;
|
||||
|
||||
@ReflectivelyCreateMiniPlugin
|
||||
public class AntihackLogger extends MiniPlugin
|
||||
{
|
||||
public static final Gson GSON = new Gson();
|
||||
|
||||
private static final int PUSH_QUEUE_TIME_IN_SECONDS = 60;
|
||||
|
||||
private final CoreClientManager _clientManager = require(CoreClientManager.class);
|
||||
|
||||
private final Map<Integer, ViolationLevels> _violationLevels = new ConcurrentHashMap<>();
|
||||
|
||||
private final Map<String, AnticheatMetadata> _metadata = new HashMap<>();
|
||||
|
||||
private final AnticheatDatabase _db;
|
||||
|
||||
private AntihackLogger()
|
||||
{
|
||||
super("AnticheatPlugin");
|
||||
|
||||
_db = new AnticheatDatabase(getPlugin());
|
||||
|
||||
runSyncTimer(this::pushQueuedViolationChanges, 20, 20 * PUSH_QUEUE_TIME_IN_SECONDS);
|
||||
|
||||
registerMetadata(new ServerInfoMetadata());
|
||||
registerMetadata(new ViolationInfoMetadata());
|
||||
registerMetadata(new PartyInfoMetadata());
|
||||
registerMetadata(new PlayerInfoMetadata());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable()
|
||||
{
|
||||
pushQueuedViolationChanges();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void addCommands()
|
||||
{
|
||||
if (UtilServer.isTestServer())
|
||||
{
|
||||
addCommand(new CommandBase<AntihackLogger>(this, Rank.SNR_MODERATOR, "savemetadata")
|
||||
{
|
||||
@Override
|
||||
public void Execute(Player caller, String[] args)
|
||||
{
|
||||
if (args.length == 1)
|
||||
{
|
||||
Player player = Bukkit.getPlayer(args[0]);
|
||||
if (player != null)
|
||||
{
|
||||
JsonObject custom = new JsonObject();
|
||||
custom.addProperty("is-test-metadata", true);
|
||||
String id = AntiHack.generateId();
|
||||
saveMetadata(player, id, () ->
|
||||
{
|
||||
UtilPlayer.message(caller, F.main(getName(), "Saved metadata for " + player.getName() + " with id " + id));
|
||||
}, custom);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void pushQueuedViolationChanges()
|
||||
{
|
||||
Map<Integer, ViolationLevels> clone = new HashMap<>(_violationLevels);
|
||||
runAsync(() -> _db.saveViolationLevels(clone));
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onCheckFail(PlayerViolationEvent event)
|
||||
{
|
||||
ViolationLevels playerVls = _violationLevels.get(_clientManager.getAccountId(event.getPlayer()));
|
||||
Class<? extends Check> check = event.getCheckClass();
|
||||
playerVls.updateMaxViolations(check, event.getViolations());
|
||||
playerVls.updateMaxViolationsSinceLastBan(check, event.getViolations());
|
||||
playerVls.incrementAlerts(check);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onLoad(PlayerLoginEvent event)
|
||||
{
|
||||
runAsync(() ->
|
||||
{
|
||||
int accountId = _clientManager.getAccountId(event.getPlayer());
|
||||
|
||||
_db.getViolationLevels(accountId)
|
||||
.ifPresent(vls ->
|
||||
{
|
||||
_violationLevels.put(accountId, vls);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onQuit(PlayerQuitEvent event)
|
||||
{
|
||||
Player player = event.getPlayer();
|
||||
int accountId =_clientManager.getAccountId(event.getPlayer());
|
||||
|
||||
ViolationLevels levels = _violationLevels.get(accountId);
|
||||
|
||||
if (levels != null)
|
||||
{
|
||||
Map<Integer, ViolationLevels> clone = new HashMap<>();
|
||||
clone.put(accountId, levels);
|
||||
|
||||
runAsync(() -> _db.saveViolationLevels(clone));
|
||||
}
|
||||
|
||||
_metadata.values().forEach(metadata -> metadata.remove(event.getPlayer().getUniqueId()));
|
||||
}
|
||||
|
||||
public void saveMetadata(Player player, String id, Runnable after, JsonObject custom)
|
||||
{
|
||||
runAsync(() ->
|
||||
{
|
||||
JsonObject info = new JsonObject();
|
||||
|
||||
for (AnticheatMetadata anticheatMetadata : _metadata.values())
|
||||
{
|
||||
try
|
||||
{
|
||||
info.add(anticheatMetadata.getId(), anticheatMetadata.build(player.getUniqueId()));
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
info.add("custom", custom == null ? JsonNull.INSTANCE: custom);
|
||||
|
||||
String str = GSON.toJson(info);
|
||||
byte[] b = str.getBytes(StandardCharsets.UTF_8);
|
||||
|
||||
ByteArrayOutputStream bout = new ByteArrayOutputStream();
|
||||
|
||||
try
|
||||
{
|
||||
XZOutputStream o2 = new XZOutputStream(bout, new LZMA2Options(LZMA2Options.PRESET_MIN), XZ.CHECK_NONE);
|
||||
o2.write(b);
|
||||
o2.close();
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
// Should never happen
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
String base64 = Base64.getEncoder().encodeToString(bout.toByteArray());
|
||||
|
||||
_db.saveMetadata(_clientManager.getAccountId(player), id, base64, after);
|
||||
});
|
||||
}
|
||||
|
||||
public void registerMetadata(AnticheatMetadata metadata)
|
||||
{
|
||||
if (!this._metadata.containsKey(metadata.getId()))
|
||||
{
|
||||
this._metadata.put(metadata.getId(), metadata);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalArgumentException("Attempting to register: " + metadata.getId());
|
||||
}
|
||||
}
|
||||
|
||||
public void resetViolations(Player player, Runnable after)
|
||||
{
|
||||
_db.clearLastBan(_clientManager.getAccountId(player), after);
|
||||
}
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
package mineplex.core.antihack.logging.builtin;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
|
||||
import mineplex.core.antihack.logging.AnticheatMetadata;
|
||||
import mineplex.core.party.Party;
|
||||
import mineplex.core.party.PartyManager;
|
||||
|
||||
import static mineplex.core.Managers.require;
|
||||
|
||||
public class PartyInfoMetadata extends AnticheatMetadata
|
||||
{
|
||||
private static final String KEY_OWNER = "owner";
|
||||
private static final String KEY_MEMBERS = "members";
|
||||
|
||||
@Override
|
||||
public String getId()
|
||||
{
|
||||
return "party-info";
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement build(UUID player)
|
||||
{
|
||||
Party party = require(PartyManager.class).getPlayerParties().get(player);
|
||||
if (party != null)
|
||||
{
|
||||
JsonObject partyData = new JsonObject();
|
||||
partyData.addProperty(KEY_OWNER, party.getOwner());
|
||||
|
||||
JsonArray members = new JsonArray();
|
||||
party.getMembers().forEach(m -> members.add(new JsonPrimitive(m)));
|
||||
|
||||
partyData.add(KEY_MEMBERS, members);
|
||||
|
||||
return partyData;
|
||||
}
|
||||
else
|
||||
{
|
||||
return JsonNull.INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(UUID player)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
package mineplex.core.antihack.logging.builtin;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import mineplex.core.account.CoreClientManager;
|
||||
import mineplex.core.antihack.logging.AnticheatMetadata;
|
||||
|
||||
import static mineplex.core.Managers.require;
|
||||
|
||||
public class PlayerInfoMetadata extends AnticheatMetadata
|
||||
{
|
||||
private static final String KEY_UUID = "uuid";
|
||||
private static final String KEY_ACCOUNT_ID = "accountid";
|
||||
private static final String KEY_NAME = "name";
|
||||
|
||||
private final CoreClientManager _clientManager = require(CoreClientManager.class);
|
||||
|
||||
@Override
|
||||
public String getId()
|
||||
{
|
||||
return "player-info";
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement build(UUID player)
|
||||
{
|
||||
JsonObject object = new JsonObject();
|
||||
object.addProperty(KEY_UUID, player.toString());
|
||||
|
||||
Player bPlayer = Bukkit.getPlayer(player);
|
||||
if (bPlayer != null)
|
||||
{
|
||||
object.addProperty(KEY_NAME, bPlayer.getName());
|
||||
object.addProperty(KEY_ACCOUNT_ID, _clientManager.getAccountId(bPlayer));
|
||||
}
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(UUID player)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
package mineplex.core.antihack.logging.builtin;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import mineplex.core.antihack.logging.AnticheatMetadata;
|
||||
import mineplex.core.common.util.UtilServer;
|
||||
|
||||
public class ServerInfoMetadata extends AnticheatMetadata
|
||||
{
|
||||
private static final String KEY_SERVER_NAME = "server-name";
|
||||
private static final String KEY_SERVER_REGION = "server-region";
|
||||
private static final String KEY_SERVER_GROUP = "server-group";
|
||||
|
||||
@Override
|
||||
public String getId()
|
||||
{
|
||||
return "server-info";
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement build(UUID player)
|
||||
{
|
||||
JsonObject info = new JsonObject();
|
||||
info.addProperty(KEY_SERVER_NAME, UtilServer.getServerName());
|
||||
info.addProperty(KEY_SERVER_REGION, UtilServer.getRegion().name());
|
||||
info.addProperty(KEY_SERVER_GROUP, UtilServer.getGroup());
|
||||
return info;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(UUID player)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@ -1,154 +0,0 @@
|
||||
package mineplex.core.antihack.logging.builtin;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import net.minecraft.server.v1_8_R3.MinecraftServer;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.mineplex.anticheat.api.CheckDisabledEvent;
|
||||
import com.mineplex.anticheat.api.PlayerViolationEvent;
|
||||
import com.mineplex.anticheat.checks.Check;
|
||||
|
||||
import mineplex.core.antihack.logging.AnticheatMetadata;
|
||||
|
||||
import gnu.trove.map.TObjectIntMap;
|
||||
import gnu.trove.map.TObjectLongMap;
|
||||
import gnu.trove.map.hash.TObjectIntHashMap;
|
||||
import gnu.trove.map.hash.TObjectLongHashMap;
|
||||
|
||||
public class ViolationInfoMetadata extends AnticheatMetadata
|
||||
{
|
||||
private static final Location MUTABLE_LOCATION = new Location(null, 0, 0, 0);
|
||||
|
||||
private static final String KEY_JOIN_TIME_MS = "join-time-ms";
|
||||
private static final String KEY_JOIN_TIME_TICK = "join-time-tick";
|
||||
|
||||
private static final String KEY_CURRENT_TIME = "current-time";
|
||||
private static final String KEY_MS = "ms";
|
||||
private static final String KEY_TICK = "tick";
|
||||
|
||||
private static final String KEY_VIOLATION_INFO = "violation-info";
|
||||
private static final String KEY_VL = "current-vl";
|
||||
private static final String KEY_MESSAGE = "msg";
|
||||
|
||||
private static final String KEY_PLAYER_INFO = "player-info";
|
||||
private static final String KEY_LOCATION = "loc";
|
||||
private static final String KEY_WORLD = "world";
|
||||
private static final String KEY_X = "x";
|
||||
private static final String KEY_Y = "y";
|
||||
private static final String KEY_Z = "z";
|
||||
private static final String KEY_YAW = "yaw";
|
||||
private static final String KEY_PITCH = "pitch";
|
||||
|
||||
private static final JsonObject VAL_CHECK_DISABLED;
|
||||
|
||||
static
|
||||
{
|
||||
VAL_CHECK_DISABLED = new JsonObject();
|
||||
VAL_CHECK_DISABLED.addProperty(KEY_MESSAGE, "disabled");
|
||||
}
|
||||
|
||||
private TObjectLongMap<UUID> _joinTime = new TObjectLongHashMap<>();
|
||||
private TObjectIntMap<UUID> _joinTimeTick = new TObjectIntHashMap<>();
|
||||
private Map<UUID, Map<Class<? extends Check>, List<JsonObject>>> _violations = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public String getId()
|
||||
{
|
||||
return "violation-info";
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement build(UUID player)
|
||||
{
|
||||
JsonObject object = new JsonObject();
|
||||
object.addProperty(KEY_JOIN_TIME_MS, _joinTime.get(player));
|
||||
object.addProperty(KEY_JOIN_TIME_TICK, _joinTimeTick.get(player));
|
||||
_violations.get(player).forEach((check, list) ->
|
||||
{
|
||||
JsonArray checkElem = new JsonArray();
|
||||
list.forEach(checkElem::add);
|
||||
object.add(check.getName(), checkElem);
|
||||
});
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(UUID player)
|
||||
{
|
||||
_joinTime.remove(player);
|
||||
_joinTimeTick.remove(player);
|
||||
_violations.remove(player);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onJoin(PlayerJoinEvent event)
|
||||
{
|
||||
long thisMs = System.currentTimeMillis();
|
||||
int thisTick = MinecraftServer.getServer().at();
|
||||
_joinTime.put(event.getPlayer().getUniqueId(), thisMs);
|
||||
_joinTimeTick.put(event.getPlayer().getUniqueId(), thisTick);
|
||||
_violations.put(event.getPlayer().getUniqueId(), new HashMap<>());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onDisabledCheck(CheckDisabledEvent event)
|
||||
{
|
||||
_violations.values().forEach(map ->
|
||||
{
|
||||
List<JsonObject> data = map.get(event.getCheck());
|
||||
if (data != null)
|
||||
{
|
||||
data.add(VAL_CHECK_DISABLED);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onViolation(PlayerViolationEvent event)
|
||||
{
|
||||
long thisMs = System.currentTimeMillis();
|
||||
int thisTick = MinecraftServer.getServer().at();
|
||||
|
||||
List<JsonObject> violations = _violations.get(event.getPlayer().getUniqueId()).computeIfAbsent(event.getCheckClass(), key -> new ArrayList<>());
|
||||
|
||||
JsonObject currentTime = new JsonObject();
|
||||
currentTime.addProperty(KEY_MS, thisMs);
|
||||
currentTime.addProperty(KEY_TICK, thisTick);
|
||||
|
||||
JsonObject violationInfo = new JsonObject();
|
||||
violationInfo.addProperty(KEY_VL, event.getViolations());
|
||||
violationInfo.addProperty(KEY_MESSAGE, event.getMessage());
|
||||
|
||||
event.getPlayer().getLocation(MUTABLE_LOCATION);
|
||||
|
||||
JsonObject playerInfo = new JsonObject();
|
||||
JsonObject location = new JsonObject();
|
||||
location.addProperty(KEY_WORLD, MUTABLE_LOCATION.getWorld().getName());
|
||||
location.addProperty(KEY_X, MUTABLE_LOCATION.getX());
|
||||
location.addProperty(KEY_Y, MUTABLE_LOCATION.getY());
|
||||
location.addProperty(KEY_Z, MUTABLE_LOCATION.getZ());
|
||||
location.addProperty(KEY_YAW, MUTABLE_LOCATION.getYaw());
|
||||
location.addProperty(KEY_PITCH, MUTABLE_LOCATION.getPitch());
|
||||
|
||||
playerInfo.add(KEY_LOCATION, location);
|
||||
|
||||
JsonObject data = new JsonObject();
|
||||
data.add(KEY_CURRENT_TIME, currentTime);
|
||||
data.add(KEY_VIOLATION_INFO, violationInfo);
|
||||
data.add(KEY_PLAYER_INFO, playerInfo);
|
||||
|
||||
violations.add(data);
|
||||
}
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
package mineplex.core.antihack.redisnotifications;
|
||||
|
||||
import mineplex.serverdata.commands.ServerCommand;
|
||||
|
||||
public class GwenBanNotification extends ServerCommand
|
||||
{
|
||||
private final String _serverName;
|
||||
private final String _playerName;
|
||||
private final String _playerUUID;
|
||||
private final String _hackType;
|
||||
private final String _metadataId;
|
||||
|
||||
public GwenBanNotification(String serverName, String playerName, String playerUUID, String hackType, String metadataId)
|
||||
{
|
||||
_serverName = serverName;
|
||||
_playerName = playerName;
|
||||
_playerUUID = playerUUID;
|
||||
_hackType = hackType;
|
||||
_metadataId = metadataId;
|
||||
}
|
||||
|
||||
public String getServerName()
|
||||
{
|
||||
return _serverName;
|
||||
}
|
||||
|
||||
public String getPlayerName()
|
||||
{
|
||||
return _playerName;
|
||||
}
|
||||
|
||||
public String getPlayerUUID()
|
||||
{
|
||||
return _playerUUID;
|
||||
}
|
||||
|
||||
public String getHackType()
|
||||
{
|
||||
return _hackType;
|
||||
}
|
||||
|
||||
public String getMetadataId()
|
||||
{
|
||||
return _metadataId;
|
||||
}
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
package mineplex.core.antihack.redisnotifications;
|
||||
|
||||
import mineplex.serverdata.commands.ServerCommand;
|
||||
|
||||
public class GwenBanwaveNotification extends ServerCommand
|
||||
{
|
||||
private final String _serverName;
|
||||
private final String _playerName;
|
||||
private final String _playerUUID;
|
||||
private final String _hackType;
|
||||
private final String _metadataId;
|
||||
private final long _timeToBan;
|
||||
|
||||
public GwenBanwaveNotification(String serverName, String playerName, String playerUUID, String hackType, String metadataId, long timeToBan)
|
||||
{
|
||||
_serverName = serverName;
|
||||
_playerName = playerName;
|
||||
_playerUUID = playerUUID;
|
||||
_hackType = hackType;
|
||||
_metadataId = metadataId;
|
||||
_timeToBan = timeToBan;
|
||||
}
|
||||
|
||||
public String getServerName()
|
||||
{
|
||||
return _serverName;
|
||||
}
|
||||
|
||||
public String getPlayerName()
|
||||
{
|
||||
return _playerName;
|
||||
}
|
||||
|
||||
public String getPlayerUUID()
|
||||
{
|
||||
return _playerUUID;
|
||||
}
|
||||
|
||||
public String getHackType()
|
||||
{
|
||||
return _hackType;
|
||||
}
|
||||
|
||||
public String getMetadataId()
|
||||
{
|
||||
return _metadataId;
|
||||
}
|
||||
|
||||
public long getTimeToBan()
|
||||
{
|
||||
return _timeToBan;
|
||||
}
|
||||
}
|
172
Plugins/Mineplex.Core/src/mineplex/core/antihack/types/Fly.java
Normal file
172
Plugins/Mineplex.Core/src/mineplex/core/antihack/types/Fly.java
Normal file
@ -0,0 +1,172 @@
|
||||
package mineplex.core.antihack.types;
|
||||
|
||||
import java.util.AbstractMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import mineplex.core.MiniPlugin;
|
||||
import mineplex.core.antihack.AntiHack;
|
||||
import mineplex.core.antihack.Detector;
|
||||
import mineplex.core.common.util.UtilBlock;
|
||||
import mineplex.core.common.util.UtilMath;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
public class Fly extends MiniPlugin implements Detector
|
||||
{
|
||||
private AntiHack Host;
|
||||
|
||||
private HashMap<Player, Entry<Integer, Double>> _floatTicks = new HashMap<Player, Entry<Integer, Double>>(); //Ticks, PrevY
|
||||
private HashMap<Player, Entry<Integer, Double>> _hoverTicks = new HashMap<Player, Entry<Integer, Double>>(); //Ticks, PrevY
|
||||
private HashMap<Player, Entry<Integer, Double>> _riseTicks = new HashMap<Player, Entry<Integer, Double>>(); //Ticks, PrevY
|
||||
|
||||
public Fly (AntiHack host)
|
||||
{
|
||||
super("Fly Detector", host.getPlugin());
|
||||
Host = host;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void updateFlyhack(PlayerMoveEvent event)
|
||||
{
|
||||
if (!Host.isEnabled())
|
||||
return;
|
||||
|
||||
Player player = event.getPlayer();
|
||||
|
||||
//100% Valid
|
||||
if (Host.isValid(player, true))
|
||||
Reset(player);
|
||||
|
||||
//Hasn't moved, just looking around
|
||||
if (UtilMath.offset(event.getFrom(), event.getTo()) <= 0)
|
||||
{
|
||||
updateFloat(player);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
_floatTicks.remove(player);
|
||||
}
|
||||
|
||||
updateHover(player);
|
||||
updateRise(player);
|
||||
}
|
||||
|
||||
private void updateFloat(Player player)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
if (_floatTicks.containsKey(player))
|
||||
{
|
||||
if (player.getLocation().getY() == _floatTicks.get(player).getValue())
|
||||
{
|
||||
count = _floatTicks.get(player).getKey() + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (count > Host.FloatHackTicks)
|
||||
{
|
||||
Host.addSuspicion(player, "Fly (Float)");
|
||||
count -= 2;
|
||||
}
|
||||
|
||||
_floatTicks.put(player, new AbstractMap.SimpleEntry<Integer, Double>(count, player.getLocation().getY()));
|
||||
}
|
||||
|
||||
private void updateHover(Player player)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
if (_hoverTicks.containsKey(player))
|
||||
{
|
||||
if (player.getLocation().getY() == _hoverTicks.get(player).getValue())
|
||||
{
|
||||
count = _hoverTicks.get(player).getKey() + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
count = 0;
|
||||
}
|
||||
|
||||
//player.sendMessage(count + " - " + player.getLocation().getY() + " vs " + _hoverTicks.get(player).getValue());
|
||||
}
|
||||
|
||||
if (count > Host.HoverHackTicks)
|
||||
{
|
||||
Host.addSuspicion(player, "Fly (Hover)");
|
||||
count -= 2;
|
||||
}
|
||||
|
||||
_hoverTicks.put(player, new AbstractMap.SimpleEntry<Integer, Double>(count, player.getLocation().getY()));
|
||||
}
|
||||
|
||||
private void updateRise(Player player)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
if (_riseTicks.containsKey(player))
|
||||
{
|
||||
if (player.getLocation().getY() >= _riseTicks.get(player).getValue())
|
||||
{
|
||||
boolean nearBlocks = false;
|
||||
for (Block block : UtilBlock.getSurrounding(player.getLocation().getBlock(), true))
|
||||
{
|
||||
if (block.getType() != Material.AIR)
|
||||
{
|
||||
nearBlocks = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (PotionEffect effect : player.getActivePotionEffects())
|
||||
if (effect.getType() == PotionEffectType.JUMP || effect.getType().equals(PotionEffectType.JUMP))
|
||||
nearBlocks = true;
|
||||
|
||||
if (nearBlocks)
|
||||
{
|
||||
count = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
count = _riseTicks.get(player).getKey() + 1;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (count > Host.RiseHackTicks)
|
||||
{
|
||||
//Only give Offense if actually rising - initial ticks can be trigged via Hover.
|
||||
if (player.getLocation().getY() > _riseTicks.get(player).getValue())
|
||||
Host.addSuspicion(player, "Fly (Rise)");
|
||||
|
||||
count -= 2;
|
||||
}
|
||||
|
||||
_riseTicks.put(player, new AbstractMap.SimpleEntry<Integer, Double>(count, player.getLocation().getY()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Reset(Player player)
|
||||
{
|
||||
_floatTicks.remove(player);
|
||||
_hoverTicks.remove(player);
|
||||
_riseTicks.remove(player);
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
package mineplex.core.antihack.types;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import mineplex.core.MiniPlugin;
|
||||
import mineplex.core.antihack.AntiHack;
|
||||
import mineplex.core.antihack.Detector;
|
||||
import mineplex.core.common.util.C;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
import mineplex.core.common.util.UtilServer;
|
||||
import mineplex.core.common.util.UtilTime;
|
||||
import mineplex.core.updater.UpdateType;
|
||||
import mineplex.core.updater.event.UpdateEvent;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
|
||||
public class Idle extends MiniPlugin implements Detector
|
||||
{
|
||||
private AntiHack Host;
|
||||
|
||||
private HashMap<Player, Long> _idleTime = new HashMap<Player, Long>();
|
||||
|
||||
public Idle (AntiHack host)
|
||||
{
|
||||
super("Idle Detector", host.getPlugin());
|
||||
Host = host;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void updateFlyhack(PlayerMoveEvent event)
|
||||
{
|
||||
if (!Host.isEnabled())
|
||||
return;
|
||||
|
||||
Player player = event.getPlayer();
|
||||
|
||||
_idleTime.put(player, System.currentTimeMillis());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void updateFreeCam(UpdateEvent event)
|
||||
{
|
||||
if (!Host.isEnabled())
|
||||
return;
|
||||
|
||||
if (event.getType() != UpdateType.FAST)
|
||||
return;
|
||||
|
||||
for (Player player : UtilServer.getPlayers())
|
||||
{
|
||||
//100% Valid
|
||||
if (Host.isValid(player, true))
|
||||
continue;
|
||||
|
||||
if (!_idleTime.containsKey(player))
|
||||
continue;
|
||||
|
||||
if (!UtilTime.elapsed(_idleTime.get(player), Host.IdleTime))
|
||||
continue;
|
||||
|
||||
//Host.addSuspicion(player, "Lag / Fly (Idle)");
|
||||
//player.kickPlayer(C.cGold + "Mineplex " + C.cRed + "Anti-Cheat " + C.cWhite + "Kicked for Lag / Fly (Idle)");
|
||||
|
||||
UtilPlayer.message(player, C.cRed + C.Bold + "Mineplex Anti-Cheat detected Lagging / Fly (Idle)");
|
||||
UtilPlayer.message(player, C.cRed + C.Bold + "You have been returned to Lobby.");
|
||||
Host.Portal.sendPlayerToServer(player, "Lobby");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Reset(Player player)
|
||||
{
|
||||
_idleTime.remove(player);
|
||||
}
|
||||
}
|
@ -0,0 +1,123 @@
|
||||
package mineplex.core.antihack.types;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import mineplex.core.MiniPlugin;
|
||||
import mineplex.core.antihack.AntiHack;
|
||||
import mineplex.core.antihack.Detector;
|
||||
import mineplex.core.common.util.UtilEvent;
|
||||
import mineplex.core.common.util.UtilMath;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
import mineplex.core.common.util.UtilServer;
|
||||
import mineplex.core.updater.UpdateType;
|
||||
import mineplex.core.updater.event.UpdateEvent;
|
||||
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
|
||||
public class Reach extends MiniPlugin implements Detector
|
||||
{
|
||||
private AntiHack Host;
|
||||
|
||||
private HashMap<Player, ArrayList<Location>> _history = new HashMap<Player, ArrayList<Location>>();
|
||||
|
||||
public Reach (AntiHack host)
|
||||
{
|
||||
super("Reach Detector", host.getPlugin());
|
||||
Host = host;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void recordMove(UpdateEvent event)
|
||||
{
|
||||
if (!Host.isEnabled())
|
||||
return;
|
||||
|
||||
if (event.getType() != UpdateType.TICK)
|
||||
return;
|
||||
|
||||
for (Player player : UtilServer.getPlayers())
|
||||
{
|
||||
if (player.getGameMode() != GameMode.SURVIVAL || UtilPlayer.isSpectator(player))
|
||||
continue;
|
||||
|
||||
if (!_history.containsKey(player))
|
||||
_history.put(player, new ArrayList<Location>());
|
||||
|
||||
_history.get(player).add(0, player.getLocation());
|
||||
|
||||
while (_history.get(player).size() > 40)
|
||||
{
|
||||
_history.get(player).remove(_history.get(player).size()-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void reachDetect(EntityDamageEvent event)
|
||||
{
|
||||
if (event.getCause() != DamageCause.ENTITY_ATTACK)
|
||||
return;
|
||||
|
||||
if (!(event.getEntity() instanceof Player))
|
||||
return;
|
||||
|
||||
LivingEntity damagerEntity = UtilEvent.GetDamagerEntity(event, false);
|
||||
|
||||
if (!(damagerEntity instanceof Player))
|
||||
return;
|
||||
|
||||
Player damager = (Player)damagerEntity;
|
||||
Player damagee = (Player)event.getEntity();
|
||||
|
||||
if (!isInRange(damager.getLocation(), damagee.getLocation()))
|
||||
{
|
||||
ArrayList<Location> damageeHistory = _history.get(damagee);
|
||||
|
||||
if (damageeHistory != null)
|
||||
{
|
||||
for (Location historyLoc : damageeHistory)
|
||||
{
|
||||
if (isInRange(damager.getLocation(), historyLoc))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Host.addSuspicion(damager, "Reach");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isInRange(Location a, Location b)
|
||||
{
|
||||
//2d Range
|
||||
double distFlat = UtilMath.offset2d(a, b); //Limit is 3.40
|
||||
if (distFlat > 3.4)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//3d Range
|
||||
double dist = UtilMath.offset(a, b); //Limit is 6 (highest i saw was 5.67)
|
||||
if (dist > 6.0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Reset(Player player)
|
||||
{
|
||||
_history.remove(player);
|
||||
}
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
package mineplex.core.antihack.types;
|
||||
|
||||
import java.util.AbstractMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import mineplex.core.MiniPlugin;
|
||||
import mineplex.core.antihack.AntiHack;
|
||||
import mineplex.core.antihack.Detector;
|
||||
import mineplex.core.common.util.UtilEnt;
|
||||
import mineplex.core.common.util.UtilMath;
|
||||
import mineplex.core.common.util.UtilTime;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
public class Speed extends MiniPlugin implements Detector
|
||||
{
|
||||
private AntiHack Host;
|
||||
|
||||
private HashMap<Player, Entry<Integer, Long>> _speedTicks = new HashMap<Player, Entry<Integer, Long>>(); //Ticks, PrevY
|
||||
|
||||
public Speed (AntiHack host)
|
||||
{
|
||||
super("Speed Detector", host.getPlugin());
|
||||
Host = host;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void updateSpeedhack(PlayerMoveEvent event)
|
||||
{
|
||||
if (!Host.isEnabled())
|
||||
return;
|
||||
|
||||
Player player = event.getPlayer();
|
||||
|
||||
//100% Valid
|
||||
if (Host.isValid(player, false))
|
||||
return;
|
||||
|
||||
UpdateSpeed(player, event);
|
||||
}
|
||||
|
||||
private void UpdateSpeed(Player player, PlayerMoveEvent event)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
if (_speedTicks.containsKey(player))
|
||||
{
|
||||
double offset;
|
||||
if (event.getFrom().getY() > event.getTo().getY())
|
||||
{
|
||||
offset = UtilMath.offset2d(event.getFrom(), event.getTo());
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = UtilMath.offset(event.getFrom(), event.getTo());
|
||||
}
|
||||
|
||||
//Limit
|
||||
double limit = 0.74;
|
||||
if (UtilEnt.isGrounded(player))
|
||||
limit = 0.32;
|
||||
|
||||
for (PotionEffect effect : player.getActivePotionEffects())
|
||||
{
|
||||
if (effect.getType().equals(PotionEffectType.SPEED))
|
||||
{
|
||||
if (UtilEnt.isGrounded(player))
|
||||
limit += 0.08 * (effect.getAmplifier() + 1);
|
||||
else
|
||||
limit += 0.04 * (effect.getAmplifier() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
//Check
|
||||
if (offset > limit && !UtilTime.elapsed(_speedTicks.get(player).getValue(), 100))//Counters Lag
|
||||
{
|
||||
count = _speedTicks.get(player).getKey() + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (count > Host.SpeedHackTicks)
|
||||
{
|
||||
Host.addSuspicion(player, "Speed (Fly/Move)");
|
||||
count -= 2;
|
||||
}
|
||||
|
||||
_speedTicks.put(player, new AbstractMap.SimpleEntry<Integer, Long>(count, System.currentTimeMillis()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Reset(Player player)
|
||||
{
|
||||
_speedTicks.remove(player);
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
package mineplex.core.punish;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import mineplex.core.account.CoreClient;
|
||||
@ -168,11 +167,6 @@ public class Punish extends MiniPlugin
|
||||
}
|
||||
|
||||
public void AddPunishment(String playerName, final Category category, final String reason, String callerName, final int severity, boolean ban, long duration, final boolean silent)
|
||||
{
|
||||
AddPunishment(playerName, category, reason, callerName, severity, ban, duration, silent, null);
|
||||
}
|
||||
|
||||
public void AddPunishment(String playerName, final Category category, final String reason, String callerName, final int severity, boolean ban, long duration, final boolean silent, Consumer<PunishmentResponse> callback)
|
||||
{
|
||||
Player player = Bukkit.getPlayerExact(playerName);
|
||||
if (player != null)
|
||||
@ -256,8 +250,8 @@ public class Punish extends MiniPlugin
|
||||
|
||||
if (player != null)
|
||||
player.kickPlayer(kickReason);
|
||||
|
||||
new mineplex.serverdata.commands.PunishCommand(finalPlayerName, true, false, kickReason).publish();
|
||||
else
|
||||
new mineplex.serverdata.commands.PunishCommand(finalPlayerName, true, false, kickReason).publish();
|
||||
}
|
||||
});
|
||||
|
||||
@ -283,8 +277,8 @@ public class Punish extends MiniPlugin
|
||||
UtilPlayer.message(player, F.main("Punish", F.elem(C.cGray + C.Bold + "Reason: ") + reason));
|
||||
player.playSound(player.getLocation(), Sound.CAT_MEOW, 1f, 1f);
|
||||
}
|
||||
|
||||
new mineplex.serverdata.commands.PunishCommand(finalPlayerName, false, finalDuration != 0, F.main("Punish", F.elem(C.cGray + C.Bold + "Report Ban Reason: ") + reason)).publish();
|
||||
else
|
||||
new mineplex.serverdata.commands.PunishCommand(finalPlayerName, false, finalDuration != 0, F.main("Punish", F.elem(C.cGray + C.Bold + "Report Ban Reason: ") + reason)).publish();
|
||||
|
||||
_repository.LoadPunishClient(finalPlayerName, new Callback<PunishClientToken>()
|
||||
{
|
||||
@ -322,8 +316,8 @@ public class Punish extends MiniPlugin
|
||||
UtilPlayer.message(player, F.main("Punish", F.elem(C.cGray + C.Bold + "Reason: ") + reason));
|
||||
player.playSound(player.getLocation(), Sound.CAT_MEOW, 1f, 1f);
|
||||
}
|
||||
|
||||
new mineplex.serverdata.commands.PunishCommand(finalPlayerName, false, finalDuration != 0, F.main("Punish", F.elem(C.cGray + C.Bold + (finalDuration != 0 ? "Mute" : "Warning") + " Reason: ") + reason)).publish();
|
||||
else
|
||||
new mineplex.serverdata.commands.PunishCommand(finalPlayerName, false, finalDuration != 0, F.main("Punish", F.elem(C.cGray + C.Bold + (finalDuration != 0 ? "Mute" : "Warning") + " Reason: ") + reason)).publish();
|
||||
|
||||
_repository.LoadPunishClient(finalPlayerName, new Callback<PunishClientToken>()
|
||||
{
|
||||
@ -334,10 +328,6 @@ public class Punish extends MiniPlugin
|
||||
});
|
||||
}
|
||||
}
|
||||
if (callback != null)
|
||||
{
|
||||
callback.accept(banResult);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -259,6 +259,15 @@ public class PunishPage extends CraftInventoryCustom implements Listener
|
||||
|
||||
|
||||
int flightSeverity = 2;
|
||||
try
|
||||
{
|
||||
if (Managers.get(AntiHack.class).isStrict())
|
||||
{
|
||||
flightSeverity = 3;
|
||||
}
|
||||
}
|
||||
catch (Exception e) {}
|
||||
|
||||
|
||||
AddButton(41, new ShopItem(Material.INK_SACK, (byte)1, "Severity 3",new String[]
|
||||
{
|
||||
|
@ -6,8 +6,7 @@ import mineplex.core.TimingsFix;
|
||||
import mineplex.core.account.CoreClientManager;
|
||||
import mineplex.core.achievement.AchievementManager;
|
||||
import mineplex.core.antihack.AntiHack;
|
||||
import mineplex.core.antihack.guardians.AntiHackGuardian;
|
||||
import mineplex.core.antihack.guardians.GuardianManager;
|
||||
import mineplex.core.antihack.AntiHackGuardian;
|
||||
import mineplex.core.blockrestore.BlockRestore;
|
||||
import mineplex.core.chat.Chat;
|
||||
import mineplex.core.chatsnap.SnapshotManager;
|
||||
@ -140,9 +139,8 @@ public class Clans extends JavaPlugin
|
||||
Creature creature = new Creature(this);
|
||||
|
||||
AntiHack antiHack = require(AntiHack.class);
|
||||
GuardianManager guardianManager = require(GuardianManager.class);
|
||||
|
||||
Bukkit.getScheduler().runTask(this, antiHack::enableAnticheat);
|
||||
antiHack.setKick(false);
|
||||
Bukkit.getScheduler().runTask(this, antiHack::enableNewAnticheat);
|
||||
|
||||
new EternalGiveawayManager(this, _clientManager, serverStatusManager);
|
||||
|
||||
@ -157,7 +155,7 @@ public class Clans extends JavaPlugin
|
||||
Location spawn = new Location(Bukkit.getWorld("world"), -422, 95, 8);
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
guardianManager.registerGuardian(new AntiHackGuardian(spawn.clone(), maxX, minX, maxY, minY, maxZ, minZ));
|
||||
antiHack.registerGuardian(new AntiHackGuardian(spawn.clone(), maxX, minX, maxY, minY, maxZ, minZ));
|
||||
}
|
||||
}
|
||||
|
||||
@ -172,7 +170,7 @@ public class Clans extends JavaPlugin
|
||||
Location spawn = new Location(Bukkit.getWorld("world"), 424, 95, -8);
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
guardianManager.registerGuardian(new AntiHackGuardian(spawn.clone(), maxX, minX, maxY, minY, maxZ, minZ));
|
||||
antiHack.registerGuardian(new AntiHackGuardian(spawn.clone(), maxX, minX, maxY, minY, maxZ, minZ));
|
||||
}
|
||||
}
|
||||
|
||||
@ -187,7 +185,7 @@ public class Clans extends JavaPlugin
|
||||
Location spawn = new Location(Bukkit.getWorld("world"), 9, 210, -393);
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
guardianManager.registerGuardian(new AntiHackGuardian(spawn.clone(), maxX, minX, maxY, minY, maxZ, minZ));
|
||||
antiHack.registerGuardian(new AntiHackGuardian(spawn.clone(), maxX, minX, maxY, minY, maxZ, minZ));
|
||||
}
|
||||
}
|
||||
|
||||
@ -202,7 +200,7 @@ public class Clans extends JavaPlugin
|
||||
Location spawn = new Location(Bukkit.getWorld("world"), 8, 210, 390);
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
guardianManager.registerGuardian(new AntiHackGuardian(spawn.clone(), maxX, minX, maxY, minY, maxZ, minZ));
|
||||
antiHack.registerGuardian(new AntiHackGuardian(spawn.clone(), maxX, minX, maxY, minY, maxZ, minZ));
|
||||
}
|
||||
}
|
||||
|
||||
@ -217,7 +215,7 @@ public class Clans extends JavaPlugin
|
||||
Location spawn = new Location(Bukkit.getWorld("world"), 0, 100, 0);
|
||||
for (int i = 0; i < 40; i++)
|
||||
{
|
||||
guardianManager.registerGuardian(new AntiHackGuardian(spawn.clone(), maxX, minX, maxY, minY, maxZ, minZ));
|
||||
antiHack.registerGuardian(new AntiHackGuardian(spawn.clone(), maxX, minX, maxY, minY, maxZ, minZ));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,8 +5,7 @@ import mineplex.core.PacketsInteractionFix;
|
||||
import mineplex.core.account.CoreClientManager;
|
||||
import mineplex.core.achievement.AchievementManager;
|
||||
import mineplex.core.antihack.AntiHack;
|
||||
import mineplex.core.antihack.guardians.AntiHackGuardian;
|
||||
import mineplex.core.antihack.guardians.GuardianManager;
|
||||
import mineplex.core.antihack.AntiHackGuardian;
|
||||
import mineplex.core.aprilfools.AprilFoolsManager;
|
||||
import mineplex.core.blockrestore.BlockRestore;
|
||||
import mineplex.core.boosters.BoosterManager;
|
||||
@ -121,11 +120,10 @@ public class ClansHub extends JavaPlugin
|
||||
Portal portal = new Portal(this, clientManager, serverStatusManager.getCurrentServerName());
|
||||
|
||||
AntiHack antiHack = require(AntiHack.class);
|
||||
GuardianManager guardianManager = require(GuardianManager.class);
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
guardianManager.registerGuardian(new AntiHackGuardian(new Location(Bukkit.getWorld("world"), 0, 195, 0), 25, -8, 195, 185, 17, -16));
|
||||
antiHack.registerGuardian(new AntiHackGuardian(new Location(Bukkit.getWorld("world"), 0, 195, 0), 25, -8, 195, 185, 17, -16));
|
||||
}
|
||||
|
||||
IgnoreManager ignoreManager = new IgnoreManager(this, clientManager, preferenceManager, portal);
|
||||
|
@ -10,8 +10,7 @@ import mineplex.core.PacketsInteractionFix;
|
||||
import mineplex.core.account.CoreClientManager;
|
||||
import mineplex.core.achievement.AchievementManager;
|
||||
import mineplex.core.antihack.AntiHack;
|
||||
import mineplex.core.antihack.guardians.AntiHackGuardian;
|
||||
import mineplex.core.antihack.guardians.GuardianManager;
|
||||
import mineplex.core.antihack.AntiHackGuardian;
|
||||
import mineplex.core.aprilfools.AprilFoolsManager;
|
||||
import mineplex.core.blockrestore.BlockRestore;
|
||||
import mineplex.core.boosters.BoosterManager;
|
||||
@ -148,11 +147,10 @@ public class Hub extends JavaPlugin implements IRelation
|
||||
Portal portal = new Portal(this, clientManager, serverStatusManager.getCurrentServerName());
|
||||
|
||||
AntiHack antiHack = require(AntiHack.class);
|
||||
GuardianManager guardianManager = require(GuardianManager.class);
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
guardianManager.registerGuardian(new AntiHackGuardian(new Location(Bukkit.getWorld("world"), 0, 100, 0), 50, -50, 105, 95, 50, -50));
|
||||
antiHack.registerGuardian(new AntiHackGuardian(new Location(Bukkit.getWorld("world"), 0, 100, 0), 50, -50, 105, 95, 50, -50));
|
||||
}
|
||||
|
||||
IgnoreManager ignoreManager = new IgnoreManager(this, clientManager, preferenceManager, portal);
|
||||
|
@ -4,7 +4,6 @@ import mineplex.core.CustomTagFix;
|
||||
import mineplex.core.FoodDupeFix;
|
||||
import mineplex.core.PacketsInteractionFix;
|
||||
import mineplex.core.TimingsFix;
|
||||
import mineplex.core.antihack.logging.AntihackLogger;
|
||||
import mineplex.core.chatsnap.SnapshotRepository;
|
||||
import mineplex.core.customdata.CustomDataManager;
|
||||
import mineplex.core.chatsnap.SnapshotManager;
|
||||
@ -66,8 +65,6 @@ import mineplex.core.velocity.VelocityFix;
|
||||
import mineplex.core.visibility.VisibilityManager;
|
||||
import mineplex.minecraft.game.core.combat.CombatManager;
|
||||
import mineplex.minecraft.game.core.damage.DamageManager;
|
||||
|
||||
import nautilus.game.arcade.anticheatmetadata.GameInfoMetadata;
|
||||
import nautilus.game.arcade.game.GameServerConfig;
|
||||
import net.minecraft.server.v1_8_R3.BiomeBase;
|
||||
import net.minecraft.server.v1_8_R3.MinecraftServer;
|
||||
@ -152,7 +149,8 @@ public class Arcade extends JavaPlugin
|
||||
|
||||
Punish punish = new Punish(this, webServerAddress, _clientManager);
|
||||
|
||||
require(AntiHack.class);
|
||||
AntiHack antiHack = require(AntiHack.class);
|
||||
antiHack.setKick(false);
|
||||
|
||||
IgnoreManager ignoreManager = new IgnoreManager(this, _clientManager, preferenceManager, portal);
|
||||
StatsManager statsManager = new StatsManager(this, _clientManager);
|
||||
@ -188,9 +186,7 @@ public class Arcade extends JavaPlugin
|
||||
//Arcade Manager
|
||||
PollManager pollManager = new PollManager(this, _clientManager, _donationManager);
|
||||
_gameManager = new ArcadeManager(this, serverStatusManager, ReadServerConfig(), _clientManager, _donationManager, _damageManager, statsManager, incognito, achievementManager, disguiseManager, creature, teleport, new Blood(this), chat, portal, preferenceManager, inventoryManager, packetHandler, cosmeticManager, projectileManager, petManager, hologramManager, webServerAddress, pollManager, npcmanager, customDataManager, punish, eloManager, thankManager, boosterManager);
|
||||
|
||||
require(AntihackLogger.class).registerMetadata(new GameInfoMetadata());
|
||||
|
||||
|
||||
new GlobalPacketManager(this, _clientManager, serverStatusManager, inventoryManager, _donationManager, petManager, statsManager, _gameManager.getBonusManager().getRewardManager());
|
||||
|
||||
//new BroadcastManager(this, _gameManager);
|
||||
|
@ -1,207 +0,0 @@
|
||||
package nautilus.game.arcade.anticheatmetadata;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import mineplex.core.antihack.logging.AnticheatMetadata;
|
||||
import mineplex.core.common.util.UtilServer;
|
||||
|
||||
import nautilus.game.arcade.ArcadeManager;
|
||||
import nautilus.game.arcade.events.GameStateChangeEvent;
|
||||
import nautilus.game.arcade.game.Game;
|
||||
import nautilus.game.arcade.kit.Kit;
|
||||
import nautilus.game.arcade.kit.ProgressingKit;
|
||||
import nautilus.game.arcade.managers.GameHostManager;
|
||||
import static mineplex.core.Managers.require;
|
||||
|
||||
public class GameInfoMetadata extends AnticheatMetadata
|
||||
{
|
||||
private static final String KEY_GAME_INFO = "game-info";
|
||||
private static final String KEY_GAME_MAP = "map";
|
||||
private static final String KEY_GAME_TYPE = "type";
|
||||
private static final String KEY_GAME_MODE = "mode";
|
||||
private static final String KEY_CURRENT_STATE = "current-state";
|
||||
private static final String KEY_STATE_START_TIME = "current-state-start-time";
|
||||
private static final String KEY_JOIN_GAME_TIME = "join-game-time-ms";
|
||||
|
||||
private static final String KEY_STATE_TIMES = "state-times";
|
||||
|
||||
private static final String KEY_KIT_INFO = "kit-info";
|
||||
private static final String KEY_KIT_NAME = "name";
|
||||
private static final String KEY_KIT_LEVEL = "level";
|
||||
|
||||
private static final String KEY_MPS = "mps";
|
||||
private static final String KEY_OWNER = "owner";
|
||||
|
||||
private static final String KEY_STATS = "stats";
|
||||
|
||||
private static final String KEY_WINNER = "winner";
|
||||
|
||||
private final Map<UUID, JsonArray> _allGames = new HashMap<>();
|
||||
private final Map<UUID, JsonObject> _currentGame = new HashMap<>();
|
||||
|
||||
private final ArcadeManager _arcadeManager = require(ArcadeManager.class);
|
||||
|
||||
@Override
|
||||
public String getId()
|
||||
{
|
||||
return "game-info";
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onJoin(PlayerJoinEvent event)
|
||||
{
|
||||
_allGames.put(event.getPlayer().getUniqueId(), new JsonArray());
|
||||
|
||||
JsonObject currentGame = buildCurrentGame();
|
||||
|
||||
if (currentGame != null)
|
||||
{
|
||||
_currentGame.put(event.getPlayer().getUniqueId(), currentGame);
|
||||
}
|
||||
}
|
||||
|
||||
private JsonObject buildCurrentGame()
|
||||
{
|
||||
Game game = _arcadeManager.GetGame();
|
||||
|
||||
if (game == null)
|
||||
return null;
|
||||
|
||||
JsonObject currentGame = new JsonObject();
|
||||
|
||||
JsonObject gameInfo = new JsonObject();
|
||||
gameInfo.addProperty(KEY_GAME_MAP, game.WorldData.File);
|
||||
gameInfo.addProperty(KEY_GAME_TYPE, game.GetName());
|
||||
gameInfo.addProperty(KEY_GAME_MODE, game.GetMode());
|
||||
gameInfo.addProperty(KEY_CURRENT_STATE, game.GetState().name());
|
||||
gameInfo.addProperty(KEY_STATE_START_TIME, game.GetStateTime());
|
||||
gameInfo.addProperty(KEY_JOIN_GAME_TIME, System.currentTimeMillis());
|
||||
|
||||
if (_arcadeManager.GetGameHostManager() != null && _arcadeManager.GetGameHostManager().isPrivateServer())
|
||||
{
|
||||
GameHostManager gameHostManager = _arcadeManager.GetGameHostManager();
|
||||
|
||||
JsonObject mpsInfo = new JsonObject();
|
||||
mpsInfo.addProperty(KEY_OWNER, _arcadeManager.GetHost());
|
||||
|
||||
currentGame.add(KEY_MPS, mpsInfo);
|
||||
}
|
||||
|
||||
currentGame.add(KEY_GAME_INFO, gameInfo);
|
||||
|
||||
JsonObject stateStartTimes = new JsonObject();
|
||||
stateStartTimes.addProperty(game.GetState().name(), game.GetStateTime());
|
||||
|
||||
currentGame.add(KEY_STATE_TIMES, stateStartTimes);
|
||||
|
||||
return currentGame;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onStateChange(GameStateChangeEvent event)
|
||||
{
|
||||
if (event.GetState() == Game.GameState.Recruit)
|
||||
{
|
||||
for (Player player : UtilServer.getPlayersCollection())
|
||||
{
|
||||
if (!_currentGame.containsKey(player.getUniqueId()))
|
||||
{
|
||||
_currentGame.put(player.getUniqueId(), buildCurrentGame());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (event.GetState() == Game.GameState.Live)
|
||||
{
|
||||
_currentGame.forEach((id, obj) ->
|
||||
{
|
||||
Player player = Bukkit.getPlayer(id);
|
||||
if (player != null)
|
||||
{
|
||||
Kit kit = event.GetGame().GetKit(player);
|
||||
if (kit != null)
|
||||
{
|
||||
JsonObject kitInfo = new JsonObject();
|
||||
kitInfo.addProperty(KEY_KIT_NAME, kit.GetName());
|
||||
|
||||
if (kit instanceof ProgressingKit)
|
||||
{
|
||||
ProgressingKit pk = (ProgressingKit) kit;
|
||||
kitInfo.addProperty(KEY_KIT_LEVEL, pk.getLevel(player.getUniqueId()));
|
||||
}
|
||||
|
||||
obj.add(KEY_KIT_INFO, kitInfo);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
_currentGame.values().forEach(obj ->
|
||||
{
|
||||
obj.get(KEY_STATE_TIMES).getAsJsonObject().addProperty(event.GetState().name(), System.currentTimeMillis());
|
||||
});
|
||||
|
||||
if (event.GetState() == Game.GameState.Dead)
|
||||
{
|
||||
new ArrayList<>(_currentGame.keySet()).forEach(ent -> archivePlayer(event.GetGame(), ent));
|
||||
}
|
||||
}
|
||||
|
||||
private void archivePlayer(Game game, UUID uuid)
|
||||
{
|
||||
JsonObject gameObj = _currentGame.remove(uuid);
|
||||
|
||||
if (gameObj == null)
|
||||
return;
|
||||
|
||||
_allGames.get(uuid).add(gameObj);
|
||||
|
||||
if (game == null)
|
||||
return;
|
||||
|
||||
Player player = Bukkit.getPlayer(uuid);
|
||||
|
||||
if (player == null)
|
||||
return;
|
||||
|
||||
Map<String, Integer> stats = game.GetStats().get(player);
|
||||
|
||||
if (stats != null)
|
||||
{
|
||||
JsonObject statsObject = new JsonObject();
|
||||
stats.forEach(statsObject::addProperty);
|
||||
|
||||
gameObj.add(KEY_STATS, statsObject);
|
||||
}
|
||||
|
||||
gameObj.addProperty(KEY_WINNER, game.Winner);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement build(UUID player)
|
||||
{
|
||||
archivePlayer(_arcadeManager.GetGame(), player);
|
||||
|
||||
return _allGames.get(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(UUID player)
|
||||
{
|
||||
_allGames.remove(player);
|
||||
_currentGame.remove(player);
|
||||
}
|
||||
}
|
@ -82,9 +82,6 @@ import nautilus.game.arcade.events.GameStateChangeEvent;
|
||||
import nautilus.game.arcade.events.PlayerGameRespawnEvent;
|
||||
import nautilus.game.arcade.events.PlayerStateChangeEvent;
|
||||
import nautilus.game.arcade.game.GameTeam.PlayerState;
|
||||
import nautilus.game.arcade.game.games.build.Build;
|
||||
import nautilus.game.arcade.game.games.draw.Draw;
|
||||
import nautilus.game.arcade.game.games.speedbuilders.SpeedBuilders;
|
||||
import nautilus.game.arcade.game.modules.Module;
|
||||
import nautilus.game.arcade.kit.ChampionsKit;
|
||||
import nautilus.game.arcade.kit.Kit;
|
||||
@ -743,14 +740,11 @@ public abstract class Game implements Listener
|
||||
|
||||
if (this._gameState == Game.GameState.Prepare)
|
||||
{
|
||||
if (!(this instanceof SpeedBuilders) && !(this instanceof Build) && !(this instanceof Draw))
|
||||
{
|
||||
Managers.get(AntiHack.class).enableAnticheat();
|
||||
}
|
||||
Managers.get(AntiHack.class).enableNewAnticheat();
|
||||
}
|
||||
else if (this._gameState == Game.GameState.End)
|
||||
{
|
||||
Managers.get(AntiHack.class).disableAnticheat();
|
||||
Managers.get(AntiHack.class).disableNewAnticheat();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1230,7 +1230,17 @@ public class GameFlagManager implements Listener
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@EventHandler
|
||||
public void AntiHackStrict(GameStateChangeEvent event)
|
||||
{
|
||||
if (event.GetState() == GameState.Prepare || event.GetState() == GameState.Live)
|
||||
Managers.get(AntiHack.class).setStrict(event.GetGame().StrictAntiHack);
|
||||
|
||||
else
|
||||
Managers.get(AntiHack.class).setStrict(true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void PlayerKillCommandCancel(PlayerCommandPreprocessEvent event)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user