New setting "handleExploitInteractionSpam" (defaults to true). If enabled, players will begin to take injury if they rapidly try interacting with anything in another faction's territory. This is to prevent people from spam-clicking on doors and chests and such in the hopes that they'll get one through. After 10 rapid interaction attempts in a row, every click will cause them damage; the damage amount is a half heart of damage for every 10 clicks (up to 1 heart at 20 clicks, 1.5 hearts at 30, etc.). After the player has stopped trying for 2 seconds, their failed interaction counter will reset.

Also removed our old workaround fix code for the bug where half-step placement wasn't detected, since the Bukkit team fixed that in 1.1-R4.
This commit is contained in:
Brettflan 2012-03-19 07:59:44 -05:00
parent 03b0a2bb5f
commit d31bac8da8
2 changed files with 43 additions and 20 deletions

View File

@ -94,6 +94,7 @@ public class Conf
// prevent some potential exploits
public static boolean handleExploitObsidianGenerators = true;
public static boolean handleExploitEnderPearlClipping = true;
public static boolean handleExploitInteractionSpam = true;
public static boolean homesEnabled = true;
public static boolean homesMustBeInClaimedTerritory = true;

View File

@ -1,11 +1,12 @@
package com.massivecraft.factions.listeners;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
@ -19,6 +20,7 @@ import org.bukkit.event.player.PlayerKickEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.util.NumberConversions;
import com.massivecraft.factions.Board;
import com.massivecraft.factions.Conf;
@ -224,6 +226,23 @@ public class FactionsPlayerListener implements Listener
if ( ! canPlayerUseBlock(player, block, false))
{
event.setCancelled(true);
if (Conf.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 = FPlayers.i.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;
}
@ -232,25 +251,6 @@ public class FactionsPlayerListener implements Listener
return; // only interested on right-clicks for below
}
// workaround fix for new CraftBukkit 1.1-R1 bug where half-step on half-step placement doesn't trigger BlockPlaceEvent
if (
event.hasItem()
&&
event.getItem().getType() == Material.STEP
&&
block.getType() == Material.STEP
&&
event.getBlockFace() == BlockFace.UP
&&
event.getItem().getData().getData() == block.getData()
&&
! FactionsBlockListener.playerCanBuildDestroyBlock(player, block.getLocation(), "build", false)
)
{
event.setCancelled(true);
return;
}
if ( ! playerCanUseItemHere(player, block.getLocation(), event.getMaterial(), false))
{
event.setCancelled(true);
@ -258,6 +258,28 @@ 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;
}
}
public static boolean playerCanUseItemHere(Player player, Location location, Material material, boolean justCheck)
{
String name = player.getName();