diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilBlock.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilBlock.java
index 89becbdc4..0d1157d40 100644
--- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilBlock.java
+++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilBlock.java
@@ -9,6 +9,7 @@ import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
+import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
public class UtilBlock
diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilEnt.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilEnt.java
index 2e68c6be4..91eb6d961 100644
--- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilEnt.java
+++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilEnt.java
@@ -15,6 +15,7 @@ import net.minecraft.server.v1_6_R3.PathfinderGoalSelector;
import org.bukkit.GameMode;
import org.bukkit.Location;
+import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.BlockFace;
import org.bukkit.craftbukkit.v1_6_R3.entity.CraftEntity;
@@ -373,4 +374,38 @@ public class UtilEnt
damagee.getWorld().playSound(damagee.getLocation(), sound, 1.5f + (float)(0.5f * Math.random()), 0.8f + (float)(0.4f * Math.random()));
}
+
+ public static boolean onBlock(Player player)
+ {
+ //Side Standing
+ double xMod = player.getLocation().getX() % 1;
+ if (player.getLocation().getX() < 0)
+ xMod += 1;
+
+ double zMod = player.getLocation().getZ() % 1;
+ if (player.getLocation().getZ() < 0)
+ zMod += 1;
+
+ int xMin = 0;
+ int xMax = 0;
+ int zMin = 0;
+ int zMax = 0;
+
+ if (xMod < 0.3) xMin = -1;
+ if (xMod > 0.7) xMax = 1;
+
+ if (zMod < 0.3) zMin = -1;
+ if (zMod > 0.7) zMax = 1;
+
+ for (int x=xMin ; x<=xMax ; x++)
+ {
+ for (int z=zMin ; z<=zMax ; z++)
+ {
+ if (player.getLocation().add(x, -0.5, z).getBlock().getType() != Material.AIR)
+ return true;
+ }
+ }
+
+ return false;
+ }
}
diff --git a/Plugins/Mineplex.Core/.project b/Plugins/Mineplex.Core/.project
index 693dd7cbc..ffc9239da 100644
--- a/Plugins/Mineplex.Core/.project
+++ b/Plugins/Mineplex.Core/.project
@@ -12,11 +12,15 @@
org.eclipse.ui.externaltools.ExternalToolBuilder
- auto,full,incremental,
+ full,incremental,
LaunchConfigHandle
- <project>/.externalToolBuilders/Core.launch
+ <project>/.externalToolBuilders/Core Builder.launch
+
+
+ incclean
+ true
diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHack.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHack.java
index c65fce9b3..33e41825e 100644
--- a/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHack.java
+++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHack.java
@@ -2,15 +2,18 @@ package mineplex.core.antihack;
import java.util.AbstractMap;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map.Entry;
import mineplex.core.MiniPlugin;
-import mineplex.core.common.util.F;
+import mineplex.core.common.util.C;
+import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilEnt;
-import mineplex.core.common.util.UtilGear;
import mineplex.core.common.util.UtilMath;
-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.GameMode;
import org.bukkit.Material;
@@ -20,7 +23,10 @@ import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerVelocityEvent;
import org.bukkit.plugin.java.JavaPlugin;
-
+import org.bukkit.potion.PotionEffect;
+import org.bukkit.potion.PotionEffectType;
+import org.bukkit.util.Vector;
+
public class AntiHack extends MiniPlugin
{
public static AntiHack Instance;
@@ -29,22 +35,29 @@ public class AntiHack extends MiniPlugin
private HashMap> _offenses = new HashMap>();
//Ignore Player
+ private HashSet _ignoreStart = new HashSet();
private HashMap _ignore = new HashMap();
//Hack Data
- private HashMap> _floatTicks = new HashMap>(); //Ticks, PrevY
- private HashMap> _hoverTicks = new HashMap>(); //Ticks, PrevY
- private HashMap> _riseTicks = new HashMap>(); //Ticks, PrevY
- private HashMap> _momentum = new HashMap>(); //Momentum, PrevY
-
+ private HashMap> _floatTicks = new HashMap>(); //Ticks, PrevY
+ private HashMap> _hoverTicks = new HashMap>(); //Ticks, PrevY
+ private HashMap> _riseTicks = new HashMap>(); //Ticks, PrevY
+ private HashMap _momentum = new HashMap();
+
+ private HashMap _lastMove = new HashMap(); //Ticks, PrevY
+
+ private HashMap> _speedTicks = new HashMap>(); //Ticks, PrevY
+
//Hack Requirements
- private int _floatHackTicks = 20;
- private int _hoverHackTicks = 20;
- private int _riseHackTicks = 20;
-
+ private int _floatHackTicks = 4;
+ private int _hoverHackTicks = 4;
+ private int _riseHackTicks = 8;
+ private int _speedHackTicks = 4;
+ private int _freecamTime = 8000;
+
protected AntiHack(JavaPlugin plugin)
{
- super("Recharge", plugin);
+ super("AntiHack", plugin);
}
public static void Initialize(JavaPlugin plugin)
@@ -55,29 +68,38 @@ public class AntiHack extends MiniPlugin
@EventHandler
public void PlayerVelocity(PlayerVelocityEvent event)
{
- _ignore.put(event.getPlayer(), System.currentTimeMillis() + 2000);
+ _ignoreStart.add(event.getPlayer());
}
@EventHandler
public void PlayerQuit(PlayerQuitEvent event)
{
- Reset(event.getPlayer());
+ ResetAll(event.getPlayer());
}
@EventHandler
- public void Update(PlayerMoveEvent event)
+ public void UpdateFlyhack(PlayerMoveEvent event)
{
Player player = event.getPlayer();
+
+ _lastMove.put(player, System.currentTimeMillis());
- //Allowed 'cheaty' movement
- if (UtilEnt.isGrounded(player) || player.getLocation().getBlock().getType() != Material.AIR || //Grounded + Swimming/Ladder/etc
- player.isFlying() || player.isInsideVehicle() || player.getGameMode() != GameMode.SURVIVAL || //Flying + Vehicle + Gamemode
- (_ignore.containsKey(player) && System.currentTimeMillis() < _ignore.get(player))) //Ignore
+ //Start Ignore
+ if (_ignoreStart.contains(player) && event.getTo().getY() > event.getFrom().getY())
{
- Reset(player);
- return;
+ _ignore.put(player, System.currentTimeMillis() + 2000);
+ _ignoreStart.remove(player);
}
+ //Allowed 'cheaty' movement
+ if (UtilEnt.onBlock(player) || player.getLocation().getBlock().getType() != Material.AIR || //Grounded + Swimming/Ladder/etc
+ player.isFlying() || player.isInsideVehicle() || player.getGameMode() != GameMode.SURVIVAL || //Flying + Vehicle + Gamemode
+ (_ignore.containsKey(player) && System.currentTimeMillis() < _ignore.get(player))) //Ignore
+ {
+ ResetFly(player);
+ return;
+ }
+
//Not actually moved, just looking around
if (UtilMath.offset(event.getFrom(), event.getTo()) <= 0)
{
@@ -87,7 +109,56 @@ public class AntiHack extends MiniPlugin
UpdateHover(player);
UpdateRise(player);
- UpdateMomentum(player);
+ UpdateMomentum(player, event);
+ }
+
+ @EventHandler
+ public void UpdateFreeCam(UpdateEvent event)
+ {
+ if (event.getType() != UpdateType.FAST)
+ return;
+
+ for (Player player : UtilServer.getPlayers())
+ {
+ //Allowed 'cheaty' movement
+ if (UtilEnt.onBlock(player) || player.getLocation().getBlock().getType() != Material.AIR || //Grounded + Swimming/Ladder/etc
+ player.isFlying() || player.isInsideVehicle() || player.getGameMode() != GameMode.SURVIVAL || //Flying + Vehicle + Gamemode
+ (_ignore.containsKey(player) && System.currentTimeMillis() < _ignore.get(player))) //Ignore
+ {
+ continue;
+ }
+
+ if (!_lastMove.containsKey(player))
+ continue;
+
+ if (!UtilTime.elapsed(_lastMove.get(player), _freecamTime))
+ continue;
+
+ player.kickPlayer(C.cGold + "Mineplex " + C.cRed + "Anti-Hack " + C.cWhite + "Kicked for Lagging / Free Cam.");
+ }
+ }
+
+ @EventHandler
+ public void UpdateSpeedhack(PlayerMoveEvent event)
+ {
+ Player player = event.getPlayer();
+
+ //Start Ignore
+ if (_ignoreStart.contains(player) && event.getTo().getY() > event.getFrom().getY())
+ {
+ _ignore.put(player, System.currentTimeMillis() + 2000);
+ _ignoreStart.remove(player);
+ }
+
+ //Allowed 'cheaty' movement
+ if (player.isFlying() || player.isInsideVehicle() || player.getGameMode() != GameMode.SURVIVAL || //Flying + Vehicle + Gamemode
+ (_ignore.containsKey(player) && System.currentTimeMillis() < _ignore.get(player))) //Ignore
+ {
+ _speedTicks.remove(player);
+ return;
+ }
+
+ UpdateSpeed(player, event);
}
private void UpdateFloat(Player player)
@@ -108,13 +179,13 @@ public class AntiHack extends MiniPlugin
if (count > _floatHackTicks)
{
- AddOffense(player, "Float");
+ AddOffense(player, "Fly (Float)");
count = 0;
}
_floatTicks.put(player, new AbstractMap.SimpleEntry(count, player.getLocation().getY()));
}
-
+
private void UpdateHover(Player player)
{
int count = 0;
@@ -133,7 +204,7 @@ public class AntiHack extends MiniPlugin
if (count > _hoverHackTicks)
{
- AddOffense(player, "Hover");
+ AddOffense(player, "Fly (Hover)");
count = 0;
}
@@ -158,32 +229,80 @@ public class AntiHack extends MiniPlugin
if (count > _riseHackTicks)
{
- AddOffense(player, "Rise");
+ AddOffense(player, "Fly (Rise)");
count = 0;
}
_riseTicks.put(player, new AbstractMap.SimpleEntry(count, player.getLocation().getY()));
}
-
- private void UpdateMomentum(Player player)
+
+ private void UpdateMomentum(Player player, PlayerMoveEvent event)
{
- double newMomentum = 0;
-
- if (_momentum.containsKey(player))
+ if (!_momentum.containsKey(player))
+ _momentum.put(player, UtilAlg.getTrajectory2d(event.getFrom(), event.getTo()));
+
+ Vector newVel = UtilAlg.getTrajectory2d(event.getFrom(), event.getTo());
+ Vector oldVel = _momentum.get(player);
+
+ //Not within 90 degrees of rotation in perfect circle
+ if (oldVel.subtract(newVel).length() > 1.42 && UtilMath.offset2d(event.getFrom(), event.getTo()) > 0.3) //Ignore low velocity switch
+ {
+ AddOffense(player, "Fly (Momentum)");
+ }
+
+ _momentum.put(player, newVel);
+ }
+
+ private void UpdateSpeed(Player player, PlayerMoveEvent event)
+ {
+ int count = 0;
+
+ if (_speedTicks.containsKey(player))
{
- newMomentum = player.getLocation().getY() - _riseTicks.get(player).getValue();
- double oldMomentum = _riseTicks.get(player).getKey();
-
- if (oldMomentum < 0 && newMomentum > 0)
+ double offset;
+ if (event.getFrom().getY() > event.getTo().getY())
{
- AddOffense(player, "Momentum");
- return;
+ 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(), 200))//Counters Lag
+ {
+ count = _speedTicks.get(player).getKey() + 1;
+ }
+ else
+ {
+ count = 0;
}
}
- _momentum.put(player, new AbstractMap.SimpleEntry(newMomentum, player.getLocation().getY()));
- }
+ if (count > _speedHackTicks)
+ {
+ AddOffense(player, "Speed");
+ count = 0;
+ }
+ _speedTicks.put(player, new AbstractMap.SimpleEntry(count, System.currentTimeMillis()));
+ }
+
private void AddOffense(Player player, String type)
{
if (!_offenses.containsKey(player))
@@ -194,17 +313,29 @@ public class AntiHack extends MiniPlugin
previous = _offenses.get(player).get(type);
_offenses.get(player).put(type, previous + 1);
-
- //Report (Debug)
- for (Player admin : UtilServer.getPlayers())
- if (admin.isOp() && UtilGear.isMat(admin.getItemInHand(), Material.BOOK_AND_QUILL))
- UtilPlayer.message(admin, F.main("Anti-Hack", F.elem(player.getName()) + " fired offense for " + F.elem(type) + "."));
+
+ //Print (Debug)
+ System.out.println("[Offense] " + player.getName() + " received offense for " + type + ".");
}
- private void Reset(Player player)
+ private void ResetFly(Player player)
{
+ _floatTicks.remove(player);
_hoverTicks.remove(player);
_riseTicks.remove(player);
_momentum.remove(player);
}
+
+ private void ResetAll(Player player)
+ {
+ ResetFly(player);
+
+ _lastMove.remove(player);
+
+ _speedTicks.remove(player);
+
+ _ignore.remove(player);
+ _ignoreStart.remove(player);
+ _offenses.remove(player);
+ }
}
diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/Arcade.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/Arcade.java
index 5b8d5063b..ad8a7eab9 100644
--- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/Arcade.java
+++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/Arcade.java
@@ -10,6 +10,7 @@ import java.io.InputStreamReader;
import me.chiss.Core.Config.Config;
import mineplex.core.account.CoreClientManager;
+import mineplex.core.antihack.AntiHack;
import mineplex.core.antistack.AntiStack;
import mineplex.core.blockrestore.BlockRestore;
import mineplex.core.command.CommandCenter;
@@ -93,12 +94,14 @@ public class Arcade extends JavaPlugin implements INautilusPlugin, IPlugin
getConfig().set(WEB_CONFIG, getConfig().getString(WEB_CONFIG));
saveConfig();
- //Init Modules
+ //Init Modules
GetModules();
_clientManager = CoreClientManager.Initialize(this, GetWebServerAddress());
CommandCenter.Initialize(this, _clientManager);
+
+ AntiHack.Initialize(this);
ItemStackFactory.Initialize(this, false);
Recharge.Initialize(this);