diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/Rank.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/Rank.java index bf94c07e8..eb6e85ad6 100644 --- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/Rank.java +++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/Rank.java @@ -13,8 +13,9 @@ public enum Rank ADMIN("Admin", ChatColor.RED), MODERATOR("Mod", ChatColor.GOLD), HELPER("Helper", ChatColor.YELLOW), - MAPDEV("Mapper", ChatColor.LIGHT_PURPLE), - YOUTUBE("Hero", ChatColor.LIGHT_PURPLE), + MAPDEV("Mapper", ChatColor.GOLD), + YOUTUBE("YT", ChatColor.LIGHT_PURPLE), + HERO("Hero", ChatColor.LIGHT_PURPLE), ULTRA("Ultra", ChatColor.AQUA), ALL("All", ChatColor.GREEN); diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilFirework.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilFirework.java new file mode 100644 index 000000000..cb010c2c5 --- /dev/null +++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilFirework.java @@ -0,0 +1,124 @@ +package mineplex.core.common.util; + +import java.lang.reflect.Method; + +import org.bukkit.FireworkEffect; +import org.bukkit.Location; +import org.bukkit.entity.Firework; +import org.bukkit.inventory.meta.FireworkMeta; +import org.bukkit.util.Vector; + +public class UtilFirework +{ + private static Method world_getHandle = null; + private static Method nms_world_broadcastEntityEffect = null; + private static Method firework_getHandle = null; + + public static void playFirework(Location loc, FireworkEffect fe) + { + try + { + Firework fw = (Firework) loc.getWorld().spawn(loc, Firework.class); + + Object nms_world = null; + Object nms_firework = null; + + + if(world_getHandle == null) + { + world_getHandle = getMethod(loc.getWorld().getClass(), "getHandle"); + firework_getHandle = getMethod(fw.getClass(), "getHandle"); + } + + nms_world = world_getHandle.invoke(loc.getWorld(), (Object[]) null); + nms_firework = firework_getHandle.invoke(fw, (Object[]) null); + + if(nms_world_broadcastEntityEffect == null) + { + nms_world_broadcastEntityEffect = getMethod(nms_world.getClass(), "broadcastEntityEffect"); + } + + FireworkMeta data = (FireworkMeta) fw.getFireworkMeta(); + data.clearEffects(); + data.setPower(1); + data.addEffect(fe); + fw.setFireworkMeta(data); + + nms_world_broadcastEntityEffect.invoke(nms_world, new Object[] {nms_firework, (byte) 17}); + + fw.remove(); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + private static Method getMethod(Class cl, String method) + { + for(Method m : cl.getMethods()) + { + if(m.getName().equals(method)) + { + return m; + } + } + return null; + } + + public static Firework launchFirework(Location loc, FireworkEffect fe, Vector dir) + { + try + { + Firework fw = (Firework) loc.getWorld().spawn(loc, Firework.class); + + FireworkMeta data = (FireworkMeta) fw.getFireworkMeta(); + data.clearEffects(); + data.setPower(1); + data.addEffect(fe); + fw.setFireworkMeta(data); + + fw.setVelocity(dir); + + return fw; + } + catch (Exception e) + { + e.printStackTrace(); + } + + return null; + } + + public void detonateFirework(Firework fw) + { + try + { + Object nms_world = null; + Object nms_firework = null; + + + if(world_getHandle == null) + { + world_getHandle = getMethod(fw.getWorld().getClass(), "getHandle"); + firework_getHandle = getMethod(fw.getClass(), "getHandle"); + } + + nms_world = world_getHandle.invoke(fw.getWorld(), (Object[]) null); + nms_firework = firework_getHandle.invoke(fw, (Object[]) null); + + if(nms_world_broadcastEntityEffect == null) + { + nms_world_broadcastEntityEffect = getMethod(nms_world.getClass(), "broadcastEntityEffect"); + } + + nms_world_broadcastEntityEffect.invoke(nms_world, new Object[] {nms_firework, (byte) 17}); + + fw.remove(); + } + catch (Exception e) + { + e.printStackTrace(); + } + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHack.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHack.java index d1b351b6c..4425d0b3a 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHack.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHack.java @@ -1,18 +1,19 @@ package mineplex.core.antihack; -import java.util.AbstractMap; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; -import java.util.Map.Entry; +import java.util.Iterator; import mineplex.core.MiniPlugin; +import mineplex.core.antihack.types.*; import mineplex.core.common.util.C; -import mineplex.core.common.util.UtilAlg; import mineplex.core.common.util.UtilEnt; -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.punish.Category; +import mineplex.core.punish.Punish; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; @@ -23,369 +24,280 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerTeleportEvent; +import org.bukkit.event.player.PlayerToggleFlightEvent; 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; - private static Object _offensesSynch = new Object(); - private AntiHackRepository _repository; + public Punish Punish; - //Record Offesnes - private HashMap> _offenses = new HashMap>(); + //Record Offenses + private HashMap>> _suspicion = new HashMap>>(); + + //Some suspicions will not become offenses, for example, using double jump will remove suspicion 2 seconds prior + private HashMap>> _offense = new HashMap>>(); //Ignore Player - private HashSet _ignoreSecondary = 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(); - - private HashMap _lastMove = new HashMap(); //Ticks, PrevY - - private HashMap> _speedTicks = new HashMap>(); //Ticks, PrevY - + //Player Info + private HashSet _velocityEvent = new HashSet(); + private HashMap _lastMoveEvent = new HashMap(); + //Hack Requirements - private int _floatHackTicks = 6; - private int _hoverHackTicks = 4; - private int _riseHackTicks = 6; - private int _speedHackTicks = 6; - private int _freecamTime = 8000; + public int FloatHackTicks = 6; + public int HoverHackTicks = 4; + public int RiseHackTicks = 10; + public int SpeedHackTicks = 6; + public int IdleTime = 16000; - protected AntiHack(JavaPlugin plugin) + //Other Times + public int FlightTriggerCancel = 2000; + + public ArrayList _detectors; + + protected AntiHack(JavaPlugin plugin, Punish punish) { super("AntiHack", plugin); - _repository = new AntiHackRepository(this, plugin.getConfig().getString("serverstatus.name")); - _repository.initialize(); + Punish = punish; + + //_repository = new AntiHackRepository(this, plugin.getConfig().getString("serverstatus.name")); + //_repository.initialize(); + + _detectors = new ArrayList(); + + _detectors.add(new Fly(this)); + _detectors.add(new Idle(this)); + _detectors.add(new Speed(this)); } - public static void Initialize(JavaPlugin plugin) + public static void Initialize(JavaPlugin plugin, Punish punish) { - Instance = new AntiHack(plugin); + Instance = new AntiHack(plugin, punish); } @EventHandler - public void PlayerTeleport(PlayerTeleportEvent event) + public void playerMove(PlayerMoveEvent event) + { + _lastMoveEvent.put(event.getPlayer(), System.currentTimeMillis()); + } + + @EventHandler + public void playerTeleport(PlayerTeleportEvent event) { _ignore.put(event.getPlayer(), System.currentTimeMillis() + 2000); } - + @EventHandler - public void PlayerVelocity(PlayerVelocityEvent event) + public void playerVelocity(PlayerVelocityEvent event) { - _ignore.put(event.getPlayer(), System.currentTimeMillis() + 2000); - _ignoreSecondary.add(event.getPlayer()); + _velocityEvent.add(event.getPlayer()); } @EventHandler - public void PlayerQuit(PlayerQuitEvent event) + public void playerToggleFly(PlayerToggleFlightEvent event) + { + Player player = event.getPlayer(); + + if (!_suspicion.containsKey(player)) + return; + + //Remove all infractions within last 2 seconds. + for (ArrayList offenseList : _suspicion.get(player).values()) + { + Iterator offenseIterator = offenseList.iterator(); + + while (offenseIterator.hasNext()) + { + long time = offenseIterator.next(); + + if (!UtilTime.elapsed(time, FlightTriggerCancel)) + offenseIterator.remove(); + } + } + } + + @EventHandler + public void playerQuit(PlayerQuitEvent event) { ResetAll(event.getPlayer()); } @EventHandler - public void UpdateFlyhack(PlayerMoveEvent event) - { - Player player = event.getPlayer(); - - _lastMove.put(player, System.currentTimeMillis()); - - //Start Ignore - if (_ignoreSecondary.contains(player) && event.getTo().getY() > event.getFrom().getY()) - { - _ignore.put(player, System.currentTimeMillis() + 2000); - _ignoreSecondary.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) - { - UpdateFloat(player); - return; - } - - UpdateHover(player); - UpdateRise(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 - { - _lastMove.put(player, System.currentTimeMillis()); - continue; - } - - if (!_lastMove.containsKey(player)) - continue; - - if (!UtilTime.elapsed(_lastMove.get(player), _freecamTime)) - continue; - - AddOffense(player, "Lagging / Fly (Idle) / FreeCam"); - //player.kickPlayer(C.cGold + "Mineplex " + C.cRed + "Anti-Hack " + C.cWhite + "Kicked for Lagging / Fly (Idle) / Free Cam."); - } - } - - @EventHandler - public void UpdateSpeedhack(PlayerMoveEvent event) + public void startIgnore(PlayerMoveEvent event) { Player player = event.getPlayer(); - //Start Ignore - if (_ignoreSecondary.contains(player) && event.getTo().getY() > event.getFrom().getY()) + if (_velocityEvent.remove(player)) { - _ignore.put(player, System.currentTimeMillis() + 2000); - _ignoreSecondary.remove(player); + setIgnore(player, 2000); } - //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; + //Initial Move (or Lag) Ignore + if (_lastMoveEvent.containsKey(player)) + { + long timeBetweenPackets = System.currentTimeMillis() - _lastMoveEvent.get(player); + + if (timeBetweenPackets > 1000) + { + setIgnore(player, 2000); + } + } + } + + public void setIgnore(Player player, long time) + { + //Wipe Detection + for (Detector detector : _detectors) + detector.Reset(player); + + //Already ignoring for a longer period + if (_ignore.containsKey(player) && _ignore.get(player) > System.currentTimeMillis() + time) + return; + + //Add Ignore + _ignore.put(player, System.currentTimeMillis() + time); + } + + public boolean isValid(Player player, boolean groundValid) + { + if (player.isFlying() || player.isInsideVehicle() || player.getGameMode() != GameMode.SURVIVAL) + { + return true; + } + + if (groundValid) + { + if (UtilEnt.onBlock(player) || player.getLocation().getBlock().getType() != Material.AIR) + { + return true; + } + } + + return (_ignore.containsKey(player) && System.currentTimeMillis() < _ignore.get(player)); + } + + public void addSuspicion(Player player, String type) + { + //Add Offense + //synchronized (getOffensesSynch()) + { + if (!_suspicion.containsKey(player)) + _suspicion.put(player, new HashMap>()); + + if (!_suspicion.get(player).containsKey(type)) + _suspicion.get(player).put(type, new ArrayList()); + + _suspicion.get(player).get(type).add(System.currentTimeMillis()); } - UpdateSpeed(player, event); + for (Player admin : UtilServer.getPlayers()) + if (admin.isOp() && admin.getGameMode() == GameMode.CREATIVE) + UtilPlayer.message(admin, C.cGold + C.Bold + player.getName() + " suspected for " + type + "."); + + //Print (Debug) + //System.out.println("[Offense] " + player.getName() + " received suspicion for " + type + "."); } - public HashMap> getOffenses() - { - return _offenses; - } - - public Object getOffensesSynch() - { - return _offensesSynch; - } - @EventHandler - public void updateDatabase(UpdateEvent event) + public void processOffenses(UpdateEvent event) { - if (event.getType() != UpdateType.SLOWER) + if (event.getType() != UpdateType.SEC) return; - _repository.saveOffenses(); - } - - 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 > _floatHackTicks) + for (Player player : _suspicion.keySet()) { - AddOffense(player, "Fly (Float)"); - count = 0; - } - - _floatTicks.put(player, new AbstractMap.SimpleEntry(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; - } - } - - if (count > _hoverHackTicks) - { - AddOffense(player, "Fly (Hover)"); - count = 0; - } - - _hoverTicks.put(player, new AbstractMap.SimpleEntry(count, player.getLocation().getY())); - } - - private void UpdateRise(Player player) - { - int count = 0; - - if (_riseTicks.containsKey(player)) - { - if (player.getLocation().getY() > _riseTicks.get(player).getValue()) - { - count = _riseTicks.get(player).getKey() + 1; - } - else - { - count = 0; - } - } - - if (count > _riseHackTicks) - { - AddOffense(player, "Fly (Rise)"); - count = 0; - } - - _riseTicks.put(player, new AbstractMap.SimpleEntry(count, player.getLocation().getY())); - } - - private void UpdateMomentum(Player player, PlayerMoveEvent event) - { - 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)) - { - double offset; - if (event.getFrom().getY() > event.getTo().getY()) - { - offset = UtilMath.offset2d(event.getFrom(), event.getTo()); - } - else - { - offset = UtilMath.offset(event.getFrom(), event.getTo()); - } + if (!_offense.containsKey(player)) + _offense.put(player, new HashMap>()); - //Limit - double limit = 0.74; - if (UtilEnt.isGrounded(player)) - limit = 0.32; - - for (PotionEffect effect : player.getActivePotionEffects()) + for (String type : _suspicion.get(player).keySet()) { - if (effect.getType().equals(PotionEffectType.SPEED)) - { - if (UtilEnt.isGrounded(player)) - limit += 0.08 * (effect.getAmplifier() + 1); - else - limit += 0.04 * (effect.getAmplifier() + 1); + if (!_offense.get(player).containsKey(type)) + _offense.get(player).put(type, new ArrayList()); + + Iterator offenseIterator = _suspicion.get(player).get(type).iterator(); + + while (offenseIterator.hasNext()) + { + long time = offenseIterator.next(); + + //Suspicion turns into Offense + if (UtilTime.elapsed(time, FlightTriggerCancel)) + { + offenseIterator.remove(); + _offense.get(player).get(type).add(time); + } } } - - //Check - if (offset > limit && !UtilTime.elapsed(_speedTicks.get(player).getValue(), 150))//Counters Lag - { - count = _speedTicks.get(player).getKey() + 1; - } - else - { - count = 0; - } } - - if (count > _speedHackTicks) - { - AddOffense(player, "Speed (Fly/Move)"); - count = 0; - } - - _speedTicks.put(player, new AbstractMap.SimpleEntry(count, System.currentTimeMillis())); } - private void AddOffense(Player player, String type) + @EventHandler + public void generateReports(UpdateEvent event) { - synchronized (getOffensesSynch()) - { - if (!_offenses.containsKey(player)) - _offenses.put(player, new HashMap()); - - int previous = 0; - if (_offenses.get(player).containsKey(type)) - previous = _offenses.get(player).get(type); - - _offenses.get(player).put(type, previous + 1); - } - - //Staff - for (Player other : UtilServer.getPlayers()) - if (other.isOp() && other.getGameMode() == GameMode.CREATIVE) - UtilPlayer.message(other, C.cGold + C.Bold + player.getName() + " received offense for " + type + "."); + if (event.getType() != UpdateType.SLOW) + return; - //Print (Debug) - System.out.println("[Offense] " + player.getName() + " received offense for " + type + "."); - } - - private void ResetFly(Player player) - { - _floatTicks.remove(player); - _hoverTicks.remove(player); - _riseTicks.remove(player); - _momentum.remove(player); + for (Player player : _offense.keySet()) + { + String out = ""; + int total = 0; + + for (String type : _offense.get(player).keySet()) + { + //Remove Old Offenses + Iterator offenseIterator = _suspicion.get(player).get(type).iterator(); + while (offenseIterator.hasNext()) + { + long time = offenseIterator.next(); + + if (UtilTime.elapsed(time, 300000)) + offenseIterator.remove(); + } + + //Count + int count = _offense.get(player).get(type).size(); + total += count; + + out += count + " " + type + ", "; + } + + if (out.length() > 0) + out = out.substring(0, out.length() - 2); + + String severity = ""; + if (total > 30) severity = "Extreme"; + else if (total > 20) severity = "High"; + else if (total > 10) severity = "Medium"; + else if (total > 5) severity = "Low"; + else + return; + + //Send Report + sendReport(player, out, severity); + } } + public void sendReport(Player player, String report, String severity) + { + //XXX Send to Database for Staff + + if (severity.equals("Extreme")) + { + Punish.AddPunishment(player.getName(), Category.Hacking, report, null, 1, true, 86400000); + } + } + private void ResetAll(Player player) { - ResetFly(player); - - _lastMove.remove(player); - - _speedTicks.remove(player); - _ignore.remove(player); - _ignoreSecondary.remove(player); - - synchronized (getOffensesSynch()) - { - _offenses.remove(player); - } + _lastMoveEvent.remove(player); + + for (Detector detector : _detectors) + detector.Reset(player); } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHackRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHackRepository.java index 0c75ecb82..4cde80c7a 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHackRepository.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHackRepository.java @@ -86,6 +86,7 @@ public class AntiHackRepository preparedStatement = connection.prepareStatement(UPDATE_PLAYER_OFFENSES); + /* XXX synchronized (_plugin.getOffensesSynch()) { for (Player offender : _plugin.getOffenses().keySet()) @@ -102,6 +103,7 @@ public class AntiHackRepository _plugin.getOffenses().clear(); } + */ preparedStatement.executeBatch(); } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/Detector.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/Detector.java new file mode 100644 index 000000000..5cfec165e --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/Detector.java @@ -0,0 +1,8 @@ +package mineplex.core.antihack; + +import org.bukkit.entity.Player; + +public interface Detector +{ + public void Reset(Player player); +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/types/Fly.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/types/Fly.java new file mode 100644 index 000000000..d7d56863b --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/types/Fly.java @@ -0,0 +1,155 @@ +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.UtilAlg; +import mineplex.core.common.util.UtilMath; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.util.Vector; + +public class Fly extends MiniPlugin implements Detector +{ + private AntiHack Host; + + 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(); + + public Fly (AntiHack host) + { + super("Fly Detector", host.GetPlugin()); + Host = host; + } + + @EventHandler(priority = EventPriority.MONITOR) + public void updateFlyhack(PlayerMoveEvent event) + { + Player player = event.getPlayer(); + + //100% Valid + if (Host.isValid(player, true)) + return; + + //Hasn't moved, just looking around + if (UtilMath.offset(event.getFrom(), event.getTo()) <= 0) + { + updateFloat(player); + return; + } + + updateHover(player); + updateRise(player); + updateMomentum(player, event); + } + + 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 = 0; + } + + _floatTicks.put(player, new AbstractMap.SimpleEntry(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; + } + } + + if (count > Host.HoverHackTicks) + { + Host.addSuspicion(player, "Fly (Hover)"); + count = 0; + } + + _hoverTicks.put(player, new AbstractMap.SimpleEntry(count, player.getLocation().getY())); + } + + private void updateRise(Player player) + { + int count = 0; + + if (_riseTicks.containsKey(player)) + { + if (player.getLocation().getY() > _riseTicks.get(player).getValue()) + { + count = _riseTicks.get(player).getKey() + 1; + } + else + { + count = 0; + } + } + + if (count > Host.RiseHackTicks) + { + Host.addSuspicion(player, "Fly (Rise)"); + count = 0; + } + + _riseTicks.put(player, new AbstractMap.SimpleEntry(count, player.getLocation().getY())); + } + + private void updateMomentum(Player player, PlayerMoveEvent event) + { + 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.4) //Ignore low velocity switch + { + Host.addSuspicion(player, "Fly (Momentum)"); + } + + _momentum.put(player, newVel); + } + + @Override + public void Reset(Player player) + { + _floatTicks.remove(player); + _hoverTicks.remove(player); + _riseTicks.remove(player); + _momentum.remove(player); + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/types/Idle.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/types/Idle.java new file mode 100644 index 000000000..aae7b5e7e --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/types/Idle.java @@ -0,0 +1,67 @@ +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.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 _idleTime = new HashMap(); + + public Idle (AntiHack host) + { + super("Idle Detector", host.GetPlugin()); + Host = host; + } + + @EventHandler(priority = EventPriority.MONITOR) + public void updateFlyhack(PlayerMoveEvent event) + { + Player player = event.getPlayer(); + + _idleTime.put(player, System.currentTimeMillis()); + } + + @EventHandler(priority = EventPriority.MONITOR) + public void updateFreeCam(UpdateEvent event) + { + 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)"); + } + } + + @Override + public void Reset(Player player) + { + _idleTime.remove(player); + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/types/Speed.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/types/Speed.java new file mode 100644 index 000000000..46fc6d305 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/types/Speed.java @@ -0,0 +1,102 @@ +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> _speedTicks = new HashMap>(); //Ticks, PrevY + + public Speed (AntiHack host) + { + super("Speed Detector", host.GetPlugin()); + Host = host; + } + + @EventHandler(priority = EventPriority.MONITOR) + public void updateSpeedhack(PlayerMoveEvent event) + { + 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(), 150))//Counters Lag + { + count = _speedTicks.get(player).getKey() + 1; + } + else + { + count = 0; + } + } + + if (count > Host.SpeedHackTicks) + { + Host.addSuspicion(player, "Speed (Fly/Move)"); + count = 0; + } + + _speedTicks.put(player, new AbstractMap.SimpleEntry(count, System.currentTimeMillis())); + } + + @Override + public void Reset(Player player) + { + _speedTicks.remove(player); + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/punish/Punish.java b/Plugins/Mineplex.Core/src/mineplex/core/punish/Punish.java index 21800a0f6..23539ef83 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/punish/Punish.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/punish/Punish.java @@ -198,20 +198,20 @@ public class Punish extends MiniPlugin if (sentence == PunishmentSentence.Ban) { if (caller == null) - System.out.println(F.main(GetName(), F.elem(caller == null ? "Mineplex Enjin Server" : caller.getName()) + " banned " + F.elem(playerName) + " because of " + F.elem(reason) + " for " + durationString + ".")); + System.out.println(F.main(GetName(), F.elem(caller == null ? "Mineplex Anti-Cheat" : caller.getName()) + " banned " + F.elem(playerName) + " because of " + F.elem(reason) + " for " + durationString + ".")); - UtilPlayer.kick(UtilPlayer.searchOnline(null, playerName, false), GetName(), caller == null ? "Mineplex Enjin Server" : caller.getName() + " banned you because of " + F.elem(reason) + " for " + + UtilPlayer.kick(UtilPlayer.searchOnline(null, playerName, false), GetName(), caller == null ? "Mineplex Anti-Cheat" : caller.getName() + " banned you because of " + F.elem(reason) + " for " + durationString + "."); - UtilServer.broadcast(F.main(GetName(), F.elem(caller == null ? "Mineplex Enjin Server" : caller.getName()) + " banned " + F.elem(playerName) + " because of " + F.elem(reason) + " for " + durationString + ".")); + UtilServer.broadcast(F.main(GetName(), F.elem(caller == null ? "Mineplex Anti-Cheat" : caller.getName()) + " banned " + F.elem(playerName) + " because of " + F.elem(reason) + " for " + durationString + ".")); } else { if (caller == null) - System.out.println(F.main(GetName(), F.elem(caller == null ? "Mineplex Enjin Server" : caller.getName()) + " muted " + F.elem(playerName) + " because of " + F.elem(reason) + " for " + + System.out.println(F.main(GetName(), F.elem(caller == null ? "Mineplex Anti-Cheat" : caller.getName()) + " muted " + F.elem(playerName) + " because of " + F.elem(reason) + " for " + durationString + ".")); - UtilServer.broadcast(F.main(GetName(), F.elem(caller == null ? "Mineplex Enjin Server" : caller.getName()) + " muted " + F.elem(playerName) + " because of " + F.elem(reason) + " for " + + UtilServer.broadcast(F.main(GetName(), F.elem(caller == null ? "Mineplex Anti-Cheat" : caller.getName()) + " muted " + F.elem(playerName) + " because of " + F.elem(reason) + " for " + durationString + ".")); _repository.LoadPunishClient(playerName, new Callback() @@ -224,7 +224,7 @@ public class Punish extends MiniPlugin } } } - }, playerName, category.toString(), sentence, reason, duration, caller == null ? "Mineplex Enjin Server" : caller.getName(), severity, System.currentTimeMillis()); + }, playerName, category.toString(), sentence, reason, duration, caller == null ? "Mineplex Anti-Cheat" : caller.getName(), severity, System.currentTimeMillis()); } public void LoadClient(PunishClientToken token) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/mount/Mount.java b/Plugins/Mineplex.Hub/src/mineplex/hub/mount/Mount.java index bf6c8f5b4..2217b7cea 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/mount/Mount.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/mount/Mount.java @@ -96,7 +96,7 @@ public class Mount extends SalesPackageBase implements Listener @EventHandler public void UpdateHorse(UpdateEvent event) { - if (event.getType() != UpdateType.FAST) + if (event.getType() != UpdateType.SEC) return; Iterator activeIterator = _active.keySet().iterator(); @@ -134,7 +134,7 @@ public class Mount extends SalesPackageBase implements Listener target.add(UtilAlg.getTrajectory(horse, player).multiply(12)); nav.a(target.getX(), target.getY(), target.getZ(), 1.4f); } - else if (UtilMath.offset(horse, player) > 43) + else if (UtilMath.offset(horse, player) > 4) { nav.a(target.getX(), target.getY(), target.getZ(), 1.4f); } diff --git a/Plugins/Nautilus.Game.Arcade/.classpath b/Plugins/Nautilus.Game.Arcade/.classpath index 51a03d2ae..1400f9d59 100644 --- a/Plugins/Nautilus.Game.Arcade/.classpath +++ b/Plugins/Nautilus.Game.Arcade/.classpath @@ -9,5 +9,6 @@ + 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 f8f15c680..9df45dd51 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/Arcade.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/Arcade.java @@ -14,6 +14,7 @@ import mineplex.core.antihack.AntiHack; import mineplex.core.antistack.AntiStack; import mineplex.core.blockrestore.BlockRestore; import mineplex.core.command.CommandCenter; +import mineplex.core.common.Rank; import mineplex.core.common.util.FileUtil; import mineplex.core.common.util.UtilServer; import mineplex.core.creature.Creature; @@ -101,7 +102,7 @@ public class Arcade extends JavaPlugin implements INautilusPlugin, IPlugin CommandCenter.Initialize(this, _clientManager); - AntiHack.Initialize(this); + ItemStackFactory.Initialize(this, false); Recharge.Initialize(this); @@ -113,7 +114,7 @@ public class Arcade extends JavaPlugin implements INautilusPlugin, IPlugin AntiStack antistack = new AntiStack(this); GetCreature(); - GetSpawn(); + GetSpawn(); GetTeleport(); new FileUpdater(this, new Portal(this)); new ServerStatusManager(this, new LagMeter(this, _clientManager)); @@ -130,7 +131,10 @@ public class Arcade extends JavaPlugin implements INautilusPlugin, IPlugin //new AntiStack(); Scheduler.Initialize(this); //new Information(this); - new Punish(this, GetWebServerAddress()); + + Punish punish = new Punish(this, GetWebServerAddress()); + AntiHack.Initialize(this, punish); + new MemoryFix(this); //Updates @@ -139,7 +143,7 @@ public class Arcade extends JavaPlugin implements INautilusPlugin, IPlugin @Override - public void onDisable() + public void onDisable() { GetModules().onDisable(); diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/GameFactory.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/GameFactory.java index 4d46d2c7d..ba5925197 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/GameFactory.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/GameFactory.java @@ -9,6 +9,7 @@ import nautilus.game.arcade.game.games.baconbrawl.BaconBrawl; import nautilus.game.arcade.game.games.barbarians.Barbarians; import nautilus.game.arcade.game.games.bridge.Bridge; import nautilus.game.arcade.game.games.castlesiege.CastleSiege; +import nautilus.game.arcade.game.games.champions.Champions; import nautilus.game.arcade.game.games.deathtag.DeathTag; import nautilus.game.arcade.game.games.dragonescape.DragonEscape; import nautilus.game.arcade.game.games.dragonriders.DragonRiders; @@ -46,6 +47,7 @@ public class GameFactory else if (gameType == GameType.BaconBrawl) return new BaconBrawl(_manager); else if (gameType == GameType.Bridge) return new Bridge(_manager); else if (gameType == GameType.CastleSiege) return new CastleSiege(_manager, pastTeams); + else if (gameType == GameType.Champions) return new Champions(_manager); else if (gameType == GameType.DeathTag) return new DeathTag(_manager); else if (gameType == GameType.Dragons) return new Dragons(_manager); else if (gameType == GameType.DragonEscape) return new DragonEscape(_manager); diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/GameType.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/GameType.java index 51c44ce96..db2e6cff8 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/GameType.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/GameType.java @@ -7,6 +7,7 @@ public enum GameType Barbarians("A Barbarians Life"), Bridge("The Bridges"), CastleSiege("Castle Siege"), + Champions("Champions"), DeathTag("Death Tag"), DragonEscape("Dragon Escape"), DragonRiders("Dragon Riders"), diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/champions/Champions.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/champions/Champions.java new file mode 100644 index 000000000..3491bf555 --- /dev/null +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/champions/Champions.java @@ -0,0 +1,176 @@ +package nautilus.game.arcade.game.games.champions; + +import java.util.ArrayList; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.ItemDespawnEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; + +import mineplex.core.common.util.C; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.minecraft.game.classcombat.shop.ClassCombatCustomBuildShop; +import nautilus.game.arcade.ArcadeManager; +import nautilus.game.arcade.GameType; +import nautilus.game.arcade.events.GameStateChangeEvent; +import nautilus.game.arcade.game.GameTeam; +import nautilus.game.arcade.game.TeamGame; +import nautilus.game.arcade.game.games.champions.kits.*; +import nautilus.game.arcade.game.games.champions.map.*; +import nautilus.game.arcade.kit.Kit; + +public class Champions extends TeamGame +{ + //Class Combat + private ClassCombatCustomBuildShop _shop; + + //Map Data + private ArrayList _points = new ArrayList(); + private ArrayList _emerald = new ArrayList(); + private ArrayList _resupply = new ArrayList(); + + //Scoreboard + private ArrayList _lastScoreboard = new ArrayList(); + + //Scores + private int _redScore = 0; + private int _blueScore = 0; + + public Champions(ArcadeManager manager) + { + super(manager, GameType.Champions, + + new Kit[] + { + new KitKnight(manager) + }, + + new String[] + { + "DOMMA DOMMA DOMMA", + "...?", + "DOMMA!" + + }); + + this.DeathOut = false; + this.PrepareFreeze = false; + + _shop = new ClassCombatCustomBuildShop(null, null, manager.GetDonation(), "Class Setup"); + } + + @Override + public void ParseData() + { + for (String pointName : WorldData.GetAllCustomLocs().keySet()) + { + _points.add(new CapturePoint(this, pointName, WorldData.GetAllCustomLocs().get(pointName).get(0))); + } + + for (Location loc : WorldData.GetDataLocs("YELLOW")) + { + _resupply.add(new Resupply(this, loc)); + } + + for (Location loc : WorldData.GetDataLocs("LIME")) + { + _emerald.add(new Emerald(this, loc)); + } + } + + @EventHandler + public void CustomTeamGeneration(GameStateChangeEvent event) + { + if (event.GetState() != GameState.Recruit) + return; + + /* + for (GameTeam team : GetTeamList()) + if (team.GetColor() == ChatColor.AQUA) + team.SetColor(ChatColor.BLUE); + */ + } + + @EventHandler + public void Updates(UpdateEvent event) + { + if (event.getType() == UpdateType.FAST) + for (CapturePoint cur : _points) + cur.Update(); + + if (event.getType() == UpdateType.FAST) + for (Emerald cur : _emerald) + cur.Update(); + } + + @EventHandler + public void PowerupPickup(PlayerPickupItemEvent event) + { + for (Emerald cur : _emerald) + cur.Pickup(event.getPlayer(), event.getItem()); + } + + public void AddScore(GameTeam team, int score) + { + if (team.GetColor() == ChatColor.RED) + _redScore += score; + else + _blueScore += score; + } + + //Dont allow powerups to despawn + @EventHandler + public void ItemDespawn(ItemDespawnEvent event) + { + event.setCancelled(true); + } + + @Override + @EventHandler + public void ScoreboardUpdate(UpdateEvent event) + { + if (event.getType() != UpdateType.FAST) + return; + + if (!InProgress()) + return; + + //Wipe Last + for (String string : _lastScoreboard) + { + GetScoreboard().resetScores(Bukkit.getOfflinePlayer(string)); + } + _lastScoreboard.clear(); + + //Scores + String redScore = _redScore + C.cRed + C.Bold + " Red"; + _lastScoreboard.add(redScore); + GetObjectiveSide().getScore(Bukkit.getOfflinePlayer(redScore)).setScore(8); + + String blueScore = _blueScore + C.cAqua + C.Bold + " Blue"; + _lastScoreboard.add(blueScore); + GetObjectiveSide().getScore(Bukkit.getOfflinePlayer(blueScore)).setScore(7); + + _lastScoreboard.add(" "); + GetObjectiveSide().getScore(Bukkit.getOfflinePlayer(" ")).setScore(6); + + //Write New + for (int i=0 ; i<_points.size() ; i++) + { + CapturePoint cp = _points.get(i); + + String out = cp.GetScoreboardName(); + + if (out.length() >= 16) + out = out.substring(0, 15); + + _lastScoreboard.add(out); + GetObjectiveSide().getScore(Bukkit.getOfflinePlayer(out)).setScore(5 - i); + } + } + + +} diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/champions/kits/KitKnight.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/champions/kits/KitKnight.java new file mode 100644 index 000000000..5ef68e699 --- /dev/null +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/champions/kits/KitKnight.java @@ -0,0 +1,58 @@ +package nautilus.game.arcade.game.games.champions.kits; + +import java.util.HashMap; + +import org.bukkit.Material; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import mineplex.core.itemstack.ItemStackFactory; +import mineplex.minecraft.game.classcombat.Class.ClientClass; +import nautilus.game.arcade.ArcadeManager; +import nautilus.game.arcade.kit.Kit; +import nautilus.game.arcade.kit.KitAvailability; +import nautilus.game.arcade.kit.Perk; + +public class KitKnight extends Kit +{ + private HashMap _class = new HashMap(); + + public KitKnight(ArcadeManager manager) + { + super(manager, "Knight", KitAvailability.Free, + new String[] + { + + }, + new Perk[] + { + + }, + EntityType.ZOMBIE, + new ItemStack(Material.IRON_SWORD)); + + } + + @Override + public void ApplyKit(Player player) + { + + } + + @Override + public void GiveItems(Player player) + { + player.getInventory().addItem(ItemStackFactory.Instance.CreateStack(Material.IRON_SWORD)); + } + + @Override + public void SpawnCustom(LivingEntity ent) + { + ent.getEquipment().setHelmet(new ItemStack(Material.IRON_HELMET)); + ent.getEquipment().setChestplate(new ItemStack(Material.IRON_CHESTPLATE)); + ent.getEquipment().setLeggings(new ItemStack(Material.IRON_LEGGINGS)); + ent.getEquipment().setBoots(new ItemStack(Material.IRON_BOOTS)); + } +} diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/champions/map/CapturePoint.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/champions/map/CapturePoint.java new file mode 100644 index 000000000..db06aac4a --- /dev/null +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/champions/map/CapturePoint.java @@ -0,0 +1,326 @@ +package nautilus.game.arcade.game.games.champions.map; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; + +import mineplex.core.common.util.UtilFirework; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilTime; +import nautilus.game.arcade.game.GameTeam; +import nautilus.game.arcade.game.games.champions.Champions; + +import org.bukkit.ChatColor; +import org.bukkit.Color; +import org.bukkit.Effect; +import org.bukkit.FireworkEffect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.FireworkEffect.Type; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; + +public class CapturePoint +{ + private Champions Host; + + private String _name; + + //Locations + private ArrayList _floor = new ArrayList(); + private ArrayList _indicators = new ArrayList(); + private Location _loc; + + //Capture + private double _captureMax = 24; + private double _captureRate = 1; + private double _captureAmount = 0; + private GameTeam _owner = null; + private boolean _captured = false; + private ArrayList _captureFloor = new ArrayList(); + private long _decayDelay = 0; + + public CapturePoint(Champions host, String name, Location loc) + { + Host = host; + + _name = name; + + for (int x=-3 ; x<= 3 ; x++) + { + for (int z=-3 ; z<= 3 ; z++) + { + //Indicators + if (Math.abs(x) == 3 && Math.abs(z) == 3) + { + Block ind = loc.getBlock().getRelative(x, 3, z); + ind.setType(Material.WOOL); + _indicators.add(ind); + } + + //Floors + if (Math.abs(x) <= 2 && Math.abs(z) <= 2) + { + if (x != 0 || z != 0) + { + Block floor = loc.getBlock().getRelative(x, -2, z); + floor.setType(Material.WOOL); + _floor.add(floor); + } + } + } + } + + //Firework + _loc = loc; + } + + public void Update() + { + CaptureUpdate(); + Points(); + } + + private void Points() + { + if (!_captured) + return; + + Host.AddScore(_owner, 8); + } + + private void CaptureUpdate() + { + //Who's on the CP? + GameTeam teamA = null; + int countA = 0; + + GameTeam teamB = null; + int countB = 0; + + for (GameTeam team : Host.GetTeamList()) + { + for (Player player : team.GetPlayers(true)) + { + if (Math.abs(_loc.getX() - player.getLocation().getX()) > 2.5) + continue; + + if (Math.abs(_loc.getY() - player.getLocation().getY()) > 2.5) + continue; + + if (Math.abs(_loc.getZ() - player.getLocation().getZ()) > 2.5) + continue; + + if (teamA == null || teamA.equals(team)) + { + teamA = team; + countA += 1; + } + else + { + teamB = team; + countB += 1; + } + } + } + + //No one around (DEGENERATE CAPTURE) + if (teamA == null) + { + if (_captureAmount > 0) + RegenDegen(); + + return; + } + + + //Capture + if (teamB == null) + Capture(teamA, countA); + + else if (countA > countB) + Capture(teamA, countA-countB); + + else if (countB > countA) + Capture(teamB, countB-countA); + } + + private void RegenDegen() + { + if (!UtilTime.elapsed(_decayDelay, 2000)) + return; + + //Degen + if (!_captured) + { + _captureAmount = Math.max(0, (_captureAmount - (_captureRate*1))); + + //Floor Color + while ((double)_captureFloor.size()/((double)_captureFloor.size() + (double)_floor.size()) > _captureAmount/_captureMax) + { + Block block = _captureFloor.remove(UtilMath.r(_captureFloor.size())); + + _floor.add(block); + + block.setData((byte)0); + } + + //Set Uncaptured + if (_captureAmount == 0) + { + _captured = false; + _owner = null; + + //Indicators + for (Block block : _indicators) + { + block.setData((byte)0); + } + } + + //Effect + for (Block block : _indicators) + block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, 35); + } + //Regen + else if (_captureAmount < _captureMax) + { + _captureAmount = Math.min(_captureMax, (_captureAmount + (_captureRate*1))); + + //Floor Color + while ((double)_captureFloor.size()/((double)_captureFloor.size() + (double)_floor.size()) < _captureAmount/_captureMax) + { + Block block = _floor.remove(UtilMath.r(_floor.size())); + + _captureFloor.add(block); + + if (_owner.GetColor() == ChatColor.RED) block.setData((byte)14); + else block.setData((byte)11); + } + + //Effect + for (Block block : _indicators) + { + if (_owner.GetColor() == ChatColor.RED) + block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, 152); + else + block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, 22); + } + + } + } + + public void Capture(GameTeam team, int count) + { + //Decay Delay + _decayDelay = System.currentTimeMillis(); + + //Defend Score + if (_captured) + Host.AddScore(_owner, count); + + //Color + Color color = Color.RED; + if (team.GetColor() == ChatColor.AQUA) + color = Color.BLUE; + + //Count Up + if (_owner != null && _owner.equals(team)) + { + _captureAmount = Math.min(_captureMax, (_captureAmount + (_captureRate*count))); + + //Floor Color + while ((double)_captureFloor.size()/((double)_captureFloor.size() + (double)_floor.size()) < _captureAmount/_captureMax) + { + Block block = _floor.remove(UtilMath.r(_floor.size())); + + _captureFloor.add(block); + + if (team.GetColor() == ChatColor.RED) block.setData((byte)14); + else block.setData((byte)11); + } + + //Set Fully Captured + if (_captureAmount == _captureMax && !_captured) + { + _captured = true; + + //Firework + + Firework(_loc, color, true); + + //Indicators + for (Block block : _indicators) + { + if (team.GetColor() == ChatColor.RED) block.setData((byte)14); + else block.setData((byte)11); + } + } + } + //Count Down + else + { + //Given if the other team hadnt actually captured it fully + int bonus = 0; + if (!_captured) + bonus = 1; + + _captureAmount = Math.max(0, (_captureAmount - ((_captureRate*count)+bonus))); + + //Floor Color + while ((double)_captureFloor.size()/((double)_captureFloor.size() + (double)_floor.size()) > _captureAmount/_captureMax) + { + Block block = _captureFloor.remove(UtilMath.r(_captureFloor.size())); + + _floor.add(block); + + block.setData((byte)0); + } + + //Set Uncaptured + if (_captureAmount == 0) + { + _captured = false; + _owner = team; + + //Indicators + for (Block block : _indicators) + { + block.setData((byte)0); + } + } + } + + if (_captureAmount != _captureMax) + Indicate(color); + } + + public void Firework(Location loc, Color color, boolean major) + { + if (!major) + UtilFirework.playFirework(loc, FireworkEffect.builder().flicker(false).withColor(color).with(Type.BURST).trail(false).build()); + else + UtilFirework.playFirework(loc, FireworkEffect.builder().flicker(true).withColor(color).with(Type.BALL_LARGE).trail(true).build()); + } + + public void Indicate(Color color) + { + for (Block block : _indicators) + Firework(block.getLocation().add(0.5, 0.5, 0.5), color, false); + } + + public String GetScoreboardName() + { + String out = ""; + if (_captured) + out = _owner.GetColor() + _name; + else + out = _name; + + + if (out.length() > 16) + out = out.substring(0, 16); + + return out; + } +} diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/champions/map/Emerald.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/champions/map/Emerald.java new file mode 100644 index 000000000..219327cba --- /dev/null +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/champions/map/Emerald.java @@ -0,0 +1,100 @@ +package nautilus.game.arcade.game.games.champions.map; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilFirework; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTime; +import nautilus.game.arcade.game.GameTeam; +import nautilus.game.arcade.game.games.champions.Champions; + +import org.bukkit.Color; +import org.bukkit.FireworkEffect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.FireworkEffect.Type; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Item; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.Vector; + +public class Emerald +{ + private Champions Host; + + private Location _loc; + + private long _time; + private Item _ent; + + public Emerald(Champions host, Location loc) + { + Host = host; + + _time = System.currentTimeMillis(); + + _loc = loc; + + _loc.getBlock().getRelative(BlockFace.DOWN).setType(Material.IRON_BLOCK); + } + + public void Update() + { + if (_ent != null) + { + if (!_ent.isValid()) + { + _ent.remove(); + _ent = null; + } + + return; + } + + if (!UtilTime.elapsed(_time, 60000)) + return; + + //Spawn + _ent = _loc.getWorld().dropItem(_loc.clone().add(0, 1, 0), new ItemStack(Material.EMERALD)); + _ent.setVelocity(new Vector(0,0,0)); + _ent.teleport(_loc); + + //Block + _loc.getBlock().getRelative(BlockFace.DOWN).setType(Material.EMERALD_BLOCK); + + //Firework + UtilFirework.playFirework(_loc, FireworkEffect.builder().flicker(false).withColor(Color.GREEN).with(Type.BURST).trail(true).build()); + } + + public void Pickup(Player player, Item item) + { + if (_ent == null) + return; + + if (!_ent.equals(item)) + return; + + if (!Host.IsAlive(player)) + return; + + GameTeam team = Host.GetTeam(player); + if (team == null) return; + + //Remove + _ent.remove(); + _ent = null; + _time = System.currentTimeMillis(); + _loc.getBlock().getRelative(BlockFace.DOWN).setType(Material.IRON_BLOCK); + + //Give Points + Host.AddScore(team, 500); + + //Inform + UtilPlayer.message(player, C.cGreen + C.Bold + "You scored 500 Points for your team!"); + + //Firework + UtilFirework.playFirework(_loc, FireworkEffect.builder().flicker(false).withColor(Color.GREEN).with(Type.BALL_LARGE).trail(true).build()); + } +} diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/champions/map/Resupply.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/champions/map/Resupply.java new file mode 100644 index 000000000..b84ac3fd9 --- /dev/null +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/champions/map/Resupply.java @@ -0,0 +1,100 @@ +package nautilus.game.arcade.game.games.champions.map; + +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilFirework; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilTime; +import nautilus.game.arcade.game.GameTeam; +import nautilus.game.arcade.game.games.champions.Champions; + +import org.bukkit.Color; +import org.bukkit.FireworkEffect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.FireworkEffect.Type; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Item; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.Vector; + +public class Resupply +{ + private Champions Host; + + private Location _loc; + + private long _time; + private Item _ent; + + public Resupply(Champions host, Location loc) + { + Host = host; + + _time = System.currentTimeMillis(); + + _loc = loc; + + _loc.getBlock().getRelative(BlockFace.DOWN).setType(Material.IRON_BLOCK); + } + + public void Update() + { + if (_ent != null) + { + if (!_ent.isValid()) + { + _ent.remove(); + _ent = null; + } + + return; + } + + if (!UtilTime.elapsed(_time, 60000)) + return; + + //Spawn + _ent = _loc.getWorld().dropItem(_loc.clone().add(0, 1, 0), new ItemStack(Material.CHEST)); + _ent.setVelocity(new Vector(0,0,0)); + _ent.teleport(_loc); + + //Block + _loc.getBlock().getRelative(BlockFace.DOWN).setType(Material.GOLD_BLOCK); + + //Firework + UtilFirework.playFirework(_loc, FireworkEffect.builder().flicker(false).withColor(Color.YELLOW).with(Type.BURST).trail(true).build()); + } + + public void Pickup(Player player, Item item) + { + if (_ent == null) + return; + + if (!_ent.equals(item)) + return; + + if (!Host.IsAlive(player)) + return; + + GameTeam team = Host.GetTeam(player); + if (team == null) return; + + //Remove + _ent.remove(); + _ent = null; + _time = System.currentTimeMillis(); + _loc.getBlock().getRelative(BlockFace.DOWN).setType(Material.IRON_BLOCK); + + //Give Points + Host.AddScore(team, 500); + + //Inform + UtilPlayer.message(player, C.cYellow + C.Bold + "Your inventory was restocked!"); + + //Firework + UtilFirework.playFirework(_loc, FireworkEffect.builder().flicker(false).withColor(Color.YELLOW).with(Type.BALL_LARGE).trail(true).build()); + } +} diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/halloween/creatures/CreatureBase.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/halloween/creatures/CreatureBase.java index b6cefd5da..95bcd4d53 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/halloween/creatures/CreatureBase.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/halloween/creatures/CreatureBase.java @@ -16,11 +16,11 @@ import org.bukkit.event.entity.EntityTargetEvent; import org.bukkit.util.Vector; public abstract class CreatureBase -{ - public Game Host; +{ + public Game Host; private String _name; - private T _ent; + private T _ent; private Location _target; private long _targetTime; @@ -28,7 +28,7 @@ public abstract class CreatureBase public CreatureBase(Game game, String name, Class mobClass, Location loc) { Host = game; - _name = name; + _name = name; game.CreatureAllowOverride = true; _ent = loc.getWorld().spawn(loc, mobClass); diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/world/WorldData.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/world/WorldData.java index 7bc5af3ab..9bea22cbf 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/world/WorldData.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/world/WorldData.java @@ -457,6 +457,11 @@ public class WorldData return CustomLocs.get(id); } + + public HashMap> GetAllCustomLocs() + { + return CustomLocs; + } public Location GetRandomXZ() {