Decouple and put all exploit fixes in their own listener.
This commit is contained in:
parent
af094b6647
commit
c098171759
@ -14,7 +14,8 @@ import com.massivecraft.factions.integration.SpoutFeatures;
|
|||||||
import com.massivecraft.factions.integration.Worldguard;
|
import com.massivecraft.factions.integration.Worldguard;
|
||||||
import com.massivecraft.factions.listeners.FactionsChatListener;
|
import com.massivecraft.factions.listeners.FactionsChatListener;
|
||||||
import com.massivecraft.factions.listeners.FactionsEntityListener;
|
import com.massivecraft.factions.listeners.FactionsEntityListener;
|
||||||
import com.massivecraft.factions.listeners.FactionsExploitListener;
|
import com.massivecraft.factions.listeners.FactionsListenerExploit;
|
||||||
|
import com.massivecraft.factions.listeners.FactionsListenerMain;
|
||||||
import com.massivecraft.factions.listeners.FactionsPlayerListener;
|
import com.massivecraft.factions.listeners.FactionsPlayerListener;
|
||||||
import com.massivecraft.factions.task.AutoLeaveTask;
|
import com.massivecraft.factions.task.AutoLeaveTask;
|
||||||
import com.massivecraft.factions.task.EconLandRewardTask;
|
import com.massivecraft.factions.task.EconLandRewardTask;
|
||||||
@ -45,7 +46,6 @@ public class Factions extends MPlugin
|
|||||||
public FactionsPlayerListener playerListener;
|
public FactionsPlayerListener playerListener;
|
||||||
public FactionsChatListener chatListener;
|
public FactionsChatListener chatListener;
|
||||||
public FactionsEntityListener entityListener;
|
public FactionsEntityListener entityListener;
|
||||||
public FactionsExploitListener exploitListener;
|
|
||||||
|
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
// OVERRIDE
|
// OVERRIDE
|
||||||
@ -83,8 +83,12 @@ public class Factions extends MPlugin
|
|||||||
EconLandRewardTask.get().schedule(this);
|
EconLandRewardTask.get().schedule(this);
|
||||||
|
|
||||||
// Register Event Handlers
|
// Register Event Handlers
|
||||||
MainListener.get().setup();
|
FactionsListenerMain.get().setup();
|
||||||
|
// TODO: Chat goes here
|
||||||
|
FactionsListenerExploit.get().setup();
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: Get rid of these
|
||||||
this.playerListener = new FactionsPlayerListener();
|
this.playerListener = new FactionsPlayerListener();
|
||||||
getServer().getPluginManager().registerEvents(this.playerListener, this);
|
getServer().getPluginManager().registerEvents(this.playerListener, this);
|
||||||
|
|
||||||
@ -94,8 +98,7 @@ public class Factions extends MPlugin
|
|||||||
this.entityListener = new FactionsEntityListener();
|
this.entityListener = new FactionsEntityListener();
|
||||||
getServer().getPluginManager().registerEvents(this.entityListener, this);
|
getServer().getPluginManager().registerEvents(this.entityListener, this);
|
||||||
|
|
||||||
this.exploitListener = new FactionsExploitListener();
|
|
||||||
getServer().getPluginManager().registerEvents(this.exploitListener, this);
|
|
||||||
|
|
||||||
postEnable();
|
postEnable();
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
package com.massivecraft.factions.listeners;
|
package com.massivecraft.factions.listeners;
|
||||||
|
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
@ -16,7 +14,6 @@ import org.bukkit.entity.Entity;
|
|||||||
import org.bukkit.entity.LivingEntity;
|
import org.bukkit.entity.LivingEntity;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.entity.Projectile;
|
import org.bukkit.entity.Projectile;
|
||||||
import org.bukkit.entity.TNTPrimed;
|
|
||||||
import org.bukkit.entity.Wither;
|
import org.bukkit.entity.Wither;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
@ -127,30 +124,6 @@ public class FactionsEntityListener implements Listener
|
|||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TNT in water/lava doesn't normally destroy any surrounding blocks, which is usually desired behavior, but...
|
|
||||||
// this optional change below provides workaround for waterwalling providing perfect protection,
|
|
||||||
// and makes cheap (non-obsidian) TNT cannons require minor maintenance between shots
|
|
||||||
Block center = event.getLocation().getBlock();
|
|
||||||
if (event.getEntity() instanceof TNTPrimed && ConfServer.handleExploitTNTWaterlog && center.isLiquid())
|
|
||||||
{
|
|
||||||
// a single surrounding block in all 6 directions is broken if the material is weak enough
|
|
||||||
List<Block> targets = new ArrayList<Block>();
|
|
||||||
targets.add(center.getRelative(0, 0, 1));
|
|
||||||
targets.add(center.getRelative(0, 0, -1));
|
|
||||||
targets.add(center.getRelative(0, 1, 0));
|
|
||||||
targets.add(center.getRelative(0, -1, 0));
|
|
||||||
targets.add(center.getRelative(1, 0, 0));
|
|
||||||
targets.add(center.getRelative(-1, 0, 0));
|
|
||||||
for (Block target : targets)
|
|
||||||
{
|
|
||||||
int id = target.getTypeId();
|
|
||||||
// ignore air, bedrock, water, lava, obsidian, enchanting table, etc.... too bad we can't get a blast resistance value through Bukkit yet
|
|
||||||
if (id != 0 && (id < 7 || id > 11) && id != 49 && id != 90 && id != 116 && id != 119 && id != 120 && id != 130)
|
|
||||||
target.breakNaturally();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// mainly for flaming arrows; don't want allies or people in safe zones to be ignited even after damage event is cancelled
|
// mainly for flaming arrows; don't want allies or people in safe zones to be ignited even after damage event is cancelled
|
||||||
|
@ -1,68 +0,0 @@
|
|||||||
package com.massivecraft.factions.listeners;
|
|
||||||
|
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.event.block.BlockFromToEvent;
|
|
||||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
|
|
||||||
import com.massivecraft.factions.ConfServer;
|
|
||||||
|
|
||||||
|
|
||||||
public class FactionsExploitListener implements Listener
|
|
||||||
{
|
|
||||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
|
||||||
public void obsidianGenerator(BlockFromToEvent event)
|
|
||||||
{
|
|
||||||
if (!ConfServer.handleExploitObsidianGenerators) return;
|
|
||||||
|
|
||||||
// thanks to ObGenBlocker and WorldGuard for this method
|
|
||||||
Block block = event.getToBlock();
|
|
||||||
int source = event.getBlock().getTypeId();
|
|
||||||
int target = block.getTypeId();
|
|
||||||
if ((target == 55 || target == 132) && (source == 0 || source == 10 || source == 11))
|
|
||||||
block.setTypeId(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
|
||||||
public void enderPearlTeleport(PlayerTeleportEvent event)
|
|
||||||
{
|
|
||||||
if (!ConfServer.handleExploitEnderPearlClipping) return;
|
|
||||||
if (event.getCause() != PlayerTeleportEvent.TeleportCause.ENDER_PEARL) return;
|
|
||||||
|
|
||||||
// this exploit works when the target location is within 0.31 blocks or so of a door or glass block or similar...
|
|
||||||
Location target = event.getTo();
|
|
||||||
Location from = event.getFrom();
|
|
||||||
|
|
||||||
// blocks who occupy less than 1 block width or length wise need to be handled differently
|
|
||||||
Material mat = event.getTo().getBlock().getType();
|
|
||||||
if (
|
|
||||||
((mat == Material.THIN_GLASS || mat == Material.IRON_FENCE) && clippingThrough(target, from, 0.65))
|
|
||||||
|| ((mat == Material.FENCE || mat == Material.NETHER_FENCE) && clippingThrough(target, from, 0.45))
|
|
||||||
)
|
|
||||||
{
|
|
||||||
event.setTo(from);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// simple fix otherwise: ender pearl target locations are standardized to be in the center (X/Z) of the target block, not at the edges
|
|
||||||
target.setX(target.getBlockX() + 0.5);
|
|
||||||
target.setZ(target.getBlockZ() + 0.5);
|
|
||||||
event.setTo(target);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean clippingThrough(Location target, Location from, double thickness)
|
|
||||||
{
|
|
||||||
return
|
|
||||||
(
|
|
||||||
(from.getX() > target.getX() && (from.getX() - target.getX() < thickness))
|
|
||||||
|| (target.getX() > from.getX() && (target.getX() - from.getX() < thickness))
|
|
||||||
|| (from.getZ() > target.getZ() && (from.getZ() - target.getZ() < thickness))
|
|
||||||
|| (target.getZ() > from.getZ() && (target.getZ() - from.getZ() < thickness))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,191 @@
|
|||||||
|
package com.massivecraft.factions.listeners;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.entity.TNTPrimed;
|
||||||
|
import org.bukkit.event.block.BlockFromToEvent;
|
||||||
|
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||||
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
|
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.util.NumberConversions;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
|
||||||
|
import com.massivecraft.factions.ConfServer;
|
||||||
|
import com.massivecraft.factions.Factions;
|
||||||
|
import com.massivecraft.mcore.util.SenderUtil;
|
||||||
|
import com.massivecraft.mcore.util.Txt;
|
||||||
|
|
||||||
|
|
||||||
|
public class FactionsListenerExploit implements Listener
|
||||||
|
{
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INSTANCE & CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static FactionsListenerExploit i = new FactionsListenerExploit();
|
||||||
|
public static FactionsListenerExploit get() { return i; }
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// SETUP
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public void setup()
|
||||||
|
{
|
||||||
|
Bukkit.getPluginManager().registerEvents(this, Factions.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INTERACT SPAM
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// TODO: Now that I decoupled this one it may be to sensitive.
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||||
|
public void interactSpam(PlayerInteractEvent event)
|
||||||
|
{
|
||||||
|
if (!ConfServer.handleExploitInteractionSpam) return;
|
||||||
|
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
String playerId = SenderUtil.getSenderId(player);
|
||||||
|
|
||||||
|
InteractAttemptSpam attempt = interactSpammers.get(playerId);
|
||||||
|
if (attempt == null)
|
||||||
|
{
|
||||||
|
attempt = new InteractAttemptSpam();
|
||||||
|
interactSpammers.put(playerId, attempt);
|
||||||
|
}
|
||||||
|
|
||||||
|
int count = attempt.increment();
|
||||||
|
if (count >= 10)
|
||||||
|
{
|
||||||
|
player.sendMessage(Txt.parse("<b>Ouch, that is starting to hurt. You should give it a rest."));
|
||||||
|
player.damage(NumberConversions.floor((double)count / 10));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// for handling people who repeatedly spam attempts to open a door (or similar) in another faction's territory
|
||||||
|
private Map<String, InteractAttemptSpam> interactSpammers = new HashMap<String, InteractAttemptSpam>();
|
||||||
|
private static class InteractAttemptSpam
|
||||||
|
{
|
||||||
|
private int attempts = 0;
|
||||||
|
private long lastAttempt = System.currentTimeMillis();
|
||||||
|
|
||||||
|
// returns the current attempt count
|
||||||
|
public int increment()
|
||||||
|
{
|
||||||
|
long Now = System.currentTimeMillis();
|
||||||
|
if (Now > lastAttempt + 2000)
|
||||||
|
attempts = 1;
|
||||||
|
else
|
||||||
|
attempts++;
|
||||||
|
lastAttempt = Now;
|
||||||
|
return attempts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OBSIDIAN GENERATORS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||||
|
public void obsidianGenerators(BlockFromToEvent event)
|
||||||
|
{
|
||||||
|
if (!ConfServer.handleExploitObsidianGenerators) return;
|
||||||
|
|
||||||
|
// thanks to ObGenBlocker and WorldGuard for this method
|
||||||
|
Block block = event.getToBlock();
|
||||||
|
int source = event.getBlock().getTypeId();
|
||||||
|
int target = block.getTypeId();
|
||||||
|
if ((target == 55 || target == 132) && (source == 0 || source == 10 || source == 11))
|
||||||
|
{
|
||||||
|
block.setTypeId(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// ENDER PEARL CLIPPING
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||||
|
public void enderPearlClipping(PlayerTeleportEvent event)
|
||||||
|
{
|
||||||
|
if (!ConfServer.handleExploitEnderPearlClipping) return;
|
||||||
|
if (event.getCause() != PlayerTeleportEvent.TeleportCause.ENDER_PEARL) return;
|
||||||
|
|
||||||
|
// this exploit works when the target location is within 0.31 blocks or so of a door or glass block or similar...
|
||||||
|
Location target = event.getTo();
|
||||||
|
Location from = event.getFrom();
|
||||||
|
|
||||||
|
// blocks who occupy less than 1 block width or length wise need to be handled differently
|
||||||
|
Material mat = event.getTo().getBlock().getType();
|
||||||
|
if (
|
||||||
|
((mat == Material.THIN_GLASS || mat == Material.IRON_FENCE) && clippingThrough(target, from, 0.65))
|
||||||
|
|| ((mat == Material.FENCE || mat == Material.NETHER_FENCE) && clippingThrough(target, from, 0.45))
|
||||||
|
)
|
||||||
|
{
|
||||||
|
event.setTo(from);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// simple fix otherwise: ender pearl target locations are standardized to be in the center (X/Z) of the target block, not at the edges
|
||||||
|
target.setX(target.getBlockX() + 0.5);
|
||||||
|
target.setZ(target.getBlockZ() + 0.5);
|
||||||
|
event.setTo(target);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean clippingThrough(Location target, Location from, double thickness)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
(
|
||||||
|
(from.getX() > target.getX() && (from.getX() - target.getX() < thickness))
|
||||||
|
|| (target.getX() > from.getX() && (target.getX() - from.getX() < thickness))
|
||||||
|
|| (from.getZ() > target.getZ() && (from.getZ() - target.getZ() < thickness))
|
||||||
|
|| (target.getZ() > from.getZ() && (target.getZ() - from.getZ() < thickness))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// TNT WATERLOG
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// TNT in water/lava doesn't normally destroy any surrounding blocks, which is usually desired behavior, but...
|
||||||
|
// this optional change below provides workaround for waterwalling providing perfect protection,
|
||||||
|
// and makes cheap (non-obsidian) TNT cannons require minor maintenance between shots
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
|
public void tntWaterlog(EntityExplodeEvent event)
|
||||||
|
{
|
||||||
|
if (!ConfServer.handleExploitEnderPearlClipping) return;
|
||||||
|
if (!(event.getEntity() instanceof TNTPrimed)) return;
|
||||||
|
|
||||||
|
Block center = event.getLocation().getBlock();
|
||||||
|
if (!center.isLiquid()) return;
|
||||||
|
|
||||||
|
// a single surrounding block in all 6 directions is broken if the material is weak enough
|
||||||
|
List<Block> targets = new ArrayList<Block>();
|
||||||
|
targets.add(center.getRelative(0, 0, 1));
|
||||||
|
targets.add(center.getRelative(0, 0, -1));
|
||||||
|
targets.add(center.getRelative(0, 1, 0));
|
||||||
|
targets.add(center.getRelative(0, -1, 0));
|
||||||
|
targets.add(center.getRelative(1, 0, 0));
|
||||||
|
targets.add(center.getRelative(-1, 0, 0));
|
||||||
|
for (Block target : targets)
|
||||||
|
{
|
||||||
|
int id = target.getTypeId();
|
||||||
|
// ignore air, bedrock, water, lava, obsidian, enchanting table, etc.... too bad we can't get a blast resistance value through Bukkit yet
|
||||||
|
if (id != 0 && (id < 7 || id > 11) && id != 49 && id != 90 && id != 116 && id != 119 && id != 120 && id != 130)
|
||||||
|
{
|
||||||
|
target.breakNaturally();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.massivecraft.factions;
|
package com.massivecraft.factions.listeners;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@ -30,18 +30,25 @@ import org.bukkit.event.player.PlayerTeleportEvent;
|
|||||||
import org.bukkit.event.server.PluginDisableEvent;
|
import org.bukkit.event.server.PluginDisableEvent;
|
||||||
import org.bukkit.event.server.PluginEnableEvent;
|
import org.bukkit.event.server.PluginEnableEvent;
|
||||||
|
|
||||||
|
import com.massivecraft.factions.BoardColl;
|
||||||
|
import com.massivecraft.factions.ConfServer;
|
||||||
|
import com.massivecraft.factions.FFlag;
|
||||||
|
import com.massivecraft.factions.FPerm;
|
||||||
|
import com.massivecraft.factions.FPlayer;
|
||||||
|
import com.massivecraft.factions.Faction;
|
||||||
|
import com.massivecraft.factions.Factions;
|
||||||
import com.massivecraft.factions.integration.SpoutFeatures;
|
import com.massivecraft.factions.integration.SpoutFeatures;
|
||||||
import com.massivecraft.mcore.ps.PS;
|
import com.massivecraft.mcore.ps.PS;
|
||||||
|
|
||||||
public class MainListener implements Listener
|
public class FactionsListenerMain implements Listener
|
||||||
{
|
{
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
// INSTANCE & CONSTRUCT
|
// INSTANCE & CONSTRUCT
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
|
|
||||||
private static MainListener i = new MainListener();
|
private static FactionsListenerMain i = new FactionsListenerMain();
|
||||||
public static MainListener get() { return i; }
|
public static FactionsListenerMain get() { return i; }
|
||||||
public MainListener() {}
|
public FactionsListenerMain() {}
|
||||||
|
|
||||||
// -------------------------------------------- //
|
// -------------------------------------------- //
|
||||||
// SETUP
|
// SETUP
|
@ -1,9 +1,7 @@
|
|||||||
package com.massivecraft.factions.listeners;
|
package com.massivecraft.factions.listeners;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
@ -20,7 +18,6 @@ import org.bukkit.event.player.PlayerInteractEvent;
|
|||||||
import org.bukkit.event.player.PlayerJoinEvent;
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
import org.bukkit.event.player.PlayerKickEvent;
|
import org.bukkit.event.player.PlayerKickEvent;
|
||||||
import org.bukkit.event.player.PlayerMoveEvent;
|
import org.bukkit.event.player.PlayerMoveEvent;
|
||||||
import org.bukkit.util.NumberConversions;
|
|
||||||
|
|
||||||
import com.massivecraft.factions.BoardColl;
|
import com.massivecraft.factions.BoardColl;
|
||||||
import com.massivecraft.factions.ConfServer;
|
import com.massivecraft.factions.ConfServer;
|
||||||
@ -137,23 +134,6 @@ public class FactionsPlayerListener implements Listener
|
|||||||
if ( ! canPlayerUseBlock(player, block, false))
|
if ( ! canPlayerUseBlock(player, block, false))
|
||||||
{
|
{
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
if (ConfServer.handleExploitInteractionSpam)
|
|
||||||
{
|
|
||||||
String name = player.getName();
|
|
||||||
InteractAttemptSpam attempt = interactSpammers.get(name);
|
|
||||||
if (attempt == null)
|
|
||||||
{
|
|
||||||
attempt = new InteractAttemptSpam();
|
|
||||||
interactSpammers.put(name, attempt);
|
|
||||||
}
|
|
||||||
int count = attempt.increment();
|
|
||||||
if (count >= 10)
|
|
||||||
{
|
|
||||||
FPlayer me = FPlayerColl.get().get(name);
|
|
||||||
me.msg("<b>Ouch, that is starting to hurt. You should give it a rest.");
|
|
||||||
player.damage(NumberConversions.floor((double)count / 10));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,27 +147,6 @@ public class FactionsPlayerListener implements Listener
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// for handling people who repeatedly spam attempts to open a door (or similar) in another faction's territory
|
|
||||||
private Map<String, InteractAttemptSpam> interactSpammers = new HashMap<String, InteractAttemptSpam>();
|
|
||||||
private static class InteractAttemptSpam
|
|
||||||
{
|
|
||||||
private int attempts = 0;
|
|
||||||
private long lastAttempt = System.currentTimeMillis();
|
|
||||||
|
|
||||||
// returns the current attempt count
|
|
||||||
public int increment()
|
|
||||||
{
|
|
||||||
long Now = System.currentTimeMillis();
|
|
||||||
if (Now > lastAttempt + 2000)
|
|
||||||
attempts = 1;
|
|
||||||
else
|
|
||||||
attempts++;
|
|
||||||
lastAttempt = Now;
|
|
||||||
return attempts;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// TODO: Refactor ! justCheck -> to informIfNot
|
// TODO: Refactor ! justCheck -> to informIfNot
|
||||||
// TODO: Possibly incorporate pain build...
|
// TODO: Possibly incorporate pain build...
|
||||||
public static boolean playerCanUseItemHere(Player player, Location loc, Material material, boolean justCheck)
|
public static boolean playerCanUseItemHere(Player player, Location loc, Material material, boolean justCheck)
|
||||||
|
Loading…
Reference in New Issue
Block a user