From a6ae2d1e90f82c9bbdcf445fd6bffa7537a41825 Mon Sep 17 00:00:00 2001 From: Evenprime Date: Sat, 22 Oct 2011 17:03:45 +0200 Subject: [PATCH] Don't allow people to hit themself with close-combat weapons/punches Some changes to default config (again). --- plugin.yml | 5 +- .../nocheat/checks/fight/DirectionCheck.java | 68 +++++++++++++++++++ .../nocheat/checks/fight/FightCheck.java | 61 ++++------------- .../nocheat/checks/fight/SelfhitCheck.java | 39 +++++++++++ .../bukkit/nocheat/config/Configuration.java | 4 ++ .../nocheat/config/DefaultConfiguration.java | 16 ++++- .../bukkit/nocheat/config/Permissions.java | 1 + .../bukkit/nocheat/config/cache/CCFight.java | 4 ++ .../bukkit/nocheat/data/FightData.java | 1 + 9 files changed, 150 insertions(+), 49 deletions(-) create mode 100644 src/cc/co/evenprime/bukkit/nocheat/checks/fight/DirectionCheck.java create mode 100644 src/cc/co/evenprime/bukkit/nocheat/checks/fight/SelfhitCheck.java diff --git a/plugin.yml b/plugin.yml index 362aab5b..a62d5eed 100644 --- a/plugin.yml +++ b/plugin.yml @@ -3,7 +3,7 @@ name: NoCheat author: Evenprime main: cc.co.evenprime.bukkit.nocheat.NoCheat -version: 2.13 +version: 2.13a commands: nocheat: @@ -70,4 +70,5 @@ permissions: children: nocheat.checks.fight.direction: description: Allow a player to attack players and monster even if they are not in his field of view - + nocheat.checks.fight.selfhit: + description: Allow a player to attack himself with close combat attacks (punching, swords, etc.) diff --git a/src/cc/co/evenprime/bukkit/nocheat/checks/fight/DirectionCheck.java b/src/cc/co/evenprime/bukkit/nocheat/checks/fight/DirectionCheck.java new file mode 100644 index 00000000..bf30c1d9 --- /dev/null +++ b/src/cc/co/evenprime/bukkit/nocheat/checks/fight/DirectionCheck.java @@ -0,0 +1,68 @@ +package cc.co.evenprime.bukkit.nocheat.checks.fight; + +import org.bukkit.craftbukkit.entity.CraftEntity; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +import cc.co.evenprime.bukkit.nocheat.NoCheat; +import cc.co.evenprime.bukkit.nocheat.checks.CheckUtil; +import cc.co.evenprime.bukkit.nocheat.config.cache.ConfigurationCache; +import cc.co.evenprime.bukkit.nocheat.data.BaseData; + +public class DirectionCheck { + + private final NoCheat plugin; + + public DirectionCheck(NoCheat plugin) { + this.plugin = plugin; + } + + public boolean check(final Player player, final BaseData data, final Entity damagee, final ConfigurationCache cc) { + + boolean cancel = false; + + final long time = System.currentTimeMillis(); + + // Get the width of the damagee + net.minecraft.server.Entity entity = ((CraftEntity) damagee).getHandle(); + + final float width = entity.length > entity.width ? entity.length : entity.width; + + // height = 2.0D as minecraft doesn't store the height of entities, + // and that should be enough. Because entityLocations are always set + // to center bottom of the hitbox, increase "y" location by 1/2 + // height to get the "center" of the hitbox + final double off = CheckUtil.directionCheck(player, entity.locX, entity.locY + 1.0D, entity.locZ, width, 2.0D, cc.fight.directionPrecision); + + if(off < 0.1D) { + // Player did probably nothing wrong + // reduce violation counter + data.fight.violationLevel *= 0.80D; + } else { + // Player failed the check + // Increment violation counter + if(!plugin.skipCheck()) { + data.fight.violationLevel += Math.sqrt(off); + } + + // Prepare some event-specific values for logging and custom + // actions + data.log.check = "fight.direction"; + + cancel = plugin.execute(player, cc.fight.directionActions, (int) data.fight.violationLevel, data.fight.history, cc); + + if(cancel) { + // Needed to calculate penalty times + data.fight.directionLastViolationTime = time; + } + } + + // If the player is still in penalty time, cancel the event anyway + if(data.fight.directionLastViolationTime + cc.fight.directionPenaltyTime >= time) { + return true; + } + + return cancel; + } + +} diff --git a/src/cc/co/evenprime/bukkit/nocheat/checks/fight/FightCheck.java b/src/cc/co/evenprime/bukkit/nocheat/checks/fight/FightCheck.java index 4e2c700f..7b2f2673 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/checks/fight/FightCheck.java +++ b/src/cc/co/evenprime/bukkit/nocheat/checks/fight/FightCheck.java @@ -1,11 +1,9 @@ package cc.co.evenprime.bukkit.nocheat.checks.fight; -import org.bukkit.craftbukkit.entity.CraftEntity; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import cc.co.evenprime.bukkit.nocheat.NoCheat; -import cc.co.evenprime.bukkit.nocheat.checks.CheckUtil; import cc.co.evenprime.bukkit.nocheat.config.Permissions; import cc.co.evenprime.bukkit.nocheat.config.cache.ConfigurationCache; import cc.co.evenprime.bukkit.nocheat.data.BaseData; @@ -16,63 +14,34 @@ import cc.co.evenprime.bukkit.nocheat.data.BaseData; */ public class FightCheck { - private final NoCheat plugin; + private final NoCheat plugin; + + private final DirectionCheck directionCheck; + private final SelfhitCheck selfhitCheck; public FightCheck(NoCheat plugin) { this.plugin = plugin; + + this.directionCheck = new DirectionCheck(plugin); + this.selfhitCheck = new SelfhitCheck(plugin); } public boolean check(final Player player, final Entity damagee, final ConfigurationCache cc) { boolean cancel = false; - final boolean directionCheck = cc.fight.directionCheck && !player.hasPermission(Permissions.FIGHT_DIRECTION); + final boolean selfhitcheck = cc.fight.selfhitCheck && !player.hasPermission(Permissions.FIGHT_SELFHIT); + final boolean directioncheck = cc.fight.directionCheck && !player.hasPermission(Permissions.FIGHT_DIRECTION); - if(directionCheck) { + BaseData data = plugin.getData(player.getName()); - final long time = System.currentTimeMillis(); + if(directioncheck) { + cancel = directionCheck.check(player, data, damagee, cc); + } - // Get the width of the damagee - net.minecraft.server.Entity entity = ((CraftEntity) damagee).getHandle(); - - float width = entity.length > entity.width ? entity.length : entity.width; - - // height = 2.0D as minecraft doesn't store the height of entities, - // and that should be enough. Because entityLocations are always set - // to center bottom of the hitbox, increase "y" location by 1/2 - // height to get the "center" of the hitbox - double off = CheckUtil.directionCheck(player, entity.locX, entity.locY + 1.0D, entity.locZ, width, 2.0D, cc.fight.directionPrecision); - - BaseData data = plugin.getData(player.getName()); - - if(off < 0.1D) { - // Player did probably nothing wrong - // reduce violation counter - data.fight.violationLevel *= 0.80D; - } else { - // Player failed the check - // Increment violation counter - if(!plugin.skipCheck()) { - data.fight.violationLevel += Math.sqrt(off); - } - - // Prepare some event-specific values for logging and custom - // actions - data.log.check = "fight.direction"; - - cancel = plugin.execute(player, cc.fight.directionActions, (int) data.fight.violationLevel, data.fight.history, cc); - - if(cancel) { - // Needed to calculate penalty times - data.fight.directionLastViolationTime = time; - } - } - - // If the player is still in penalty time, cancel the event anyway - if(data.fight.directionLastViolationTime + cc.fight.directionPenaltyTime >= time) { - return true; - } + if(!cancel && selfhitcheck) { + cancel = selfhitCheck.check(player, data, damagee, cc); } return cancel; diff --git a/src/cc/co/evenprime/bukkit/nocheat/checks/fight/SelfhitCheck.java b/src/cc/co/evenprime/bukkit/nocheat/checks/fight/SelfhitCheck.java new file mode 100644 index 00000000..6656d785 --- /dev/null +++ b/src/cc/co/evenprime/bukkit/nocheat/checks/fight/SelfhitCheck.java @@ -0,0 +1,39 @@ +package cc.co.evenprime.bukkit.nocheat.checks.fight; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +import cc.co.evenprime.bukkit.nocheat.NoCheat; +import cc.co.evenprime.bukkit.nocheat.config.cache.ConfigurationCache; +import cc.co.evenprime.bukkit.nocheat.data.BaseData; + +public class SelfhitCheck { + + private final NoCheat plugin; + + public SelfhitCheck(NoCheat plugin) { + this.plugin = plugin; + } + + public boolean check(final Player player, final BaseData data, final Entity damagee, final ConfigurationCache cc) { + + boolean cancel = false; + + if(player.equals(damagee)) { + + // Player failed the check obviously + + data.fight.selfhitviolationLevel += 1; + // Prepare some event-specific values for logging and custom + // actions + data.log.check = "fight.selfhit"; + + cancel = plugin.execute(player, cc.fight.selfhitActions, (int) data.fight.selfhitviolationLevel, data.fight.history, cc); + } else { + data.fight.selfhitviolationLevel *= 0.99D; + } + + return cancel; + } + +} diff --git a/src/cc/co/evenprime/bukkit/nocheat/config/Configuration.java b/src/cc/co/evenprime/bukkit/nocheat/config/Configuration.java index a8af6407..c8a0a081 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/config/Configuration.java +++ b/src/cc/co/evenprime/bukkit/nocheat/config/Configuration.java @@ -103,6 +103,10 @@ public abstract class Configuration { public final static OptionNode FIGHT_DIRECTION_PENALTYTIME = new OptionNode("penaltytime", FIGHT_DIRECTION, DataType.INTEGER); public final static OptionNode FIGHT_DIRECTION_ACTIONS = new OptionNode("actions", FIGHT_DIRECTION, DataType.ACTIONLIST); + private final static OptionNode FIGHT_SELFHIT = new OptionNode("selfhit", FIGHT, DataType.PARENT); + public static final OptionNode FIGHT_SELFHIT_CHECK = new OptionNode("check", FIGHT_SELFHIT, DataType.BOOLEAN); + public final static OptionNode FIGHT_SELFHIT_ACTIONS = new OptionNode("actions", FIGHT_SELFHIT, DataType.ACTIONLIST); + private final Map values; private final Configuration defaults; diff --git a/src/cc/co/evenprime/bukkit/nocheat/config/DefaultConfiguration.java b/src/cc/co/evenprime/bukkit/nocheat/config/DefaultConfiguration.java index 42dc4bd9..2f9fd471 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/config/DefaultConfiguration.java +++ b/src/cc/co/evenprime/bukkit/nocheat/config/DefaultConfiguration.java @@ -154,8 +154,15 @@ public class DefaultConfiguration extends Configuration { ActionList directionActionList = new ActionList(); directionActionList.setActions(0, action.getActions("fightCancel".split(" "))); - directionActionList.setActions(5, action.getActions("fightDirectionLog fightCancel".split(" "))); + directionActionList.setActions(5, action.getActions("fightDirectionLogLow fightCancel".split(" "))); + directionActionList.setActions(20, action.getActions("fightDirectionLog fightCancel".split(" "))); + directionActionList.setActions(50, action.getActions("fightDirectionLogHigh fightCancel".split(" "))); setValue(FIGHT_DIRECTION_ACTIONS, directionActionList); + + setValue(FIGHT_SELFHIT_CHECK, true); + ActionList selfhitActionList = new ActionList(); + selfhitActionList.setActions(0, action.getActions("fightSelfhitLog fightCancel".split(" "))); + setValue(FIGHT_SELFHIT_ACTIONS, selfhitActionList); } } @@ -235,7 +242,14 @@ public class DefaultConfiguration extends Configuration { w(w, "log onliquidLog 2 5 med [player] failed [check]: tried to place a [blocktype] block at [placelocation] against block at [placeagainst]. VL [violations]"); w(w, "log spamLog 0 5 med [player] failed [check]: Last sent message \"[text]\". VL [violations]"); w(w, "log nofallLog 0 5 med [player] failed [check]: tried to avoid fall damage for ~[falldistance] blocks. VL [violations]"); + w(w, ""); + w(w, ""); + w(w, "# Some log messages related to fighting, displaying the same text, but with different level (Info, Warning, Severe)"); + w(w, "log fightDirectionLogLow 0 5 low [player] failed [check]: tried to attack out of sight entity. Total violation level so far [violations]."); w(w, "log fightDirectionLog 0 5 med [player] failed [check]: tried to attack out of sight entity. Total violation level so far [violations]."); + w(w, "log fightDirectionLogHigh 0 5 high [player] failed [check]: tried to attack out of sight entity. Total violation level so far [violations]."); + w(w, ""); + w(w, "log fightSelfhitlog 0 1 high [player] failed [check]: tried to attack himself. Total violation level so far [violations]."); w(w, ""); w(w, "# SPECIAL Actions: They will do something check dependant, usually cancel an event."); w(w, "# - They start with the word 'special'"); diff --git a/src/cc/co/evenprime/bukkit/nocheat/config/Permissions.java b/src/cc/co/evenprime/bukkit/nocheat/config/Permissions.java index 8721b8e4..c07d2b0d 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/config/Permissions.java +++ b/src/cc/co/evenprime/bukkit/nocheat/config/Permissions.java @@ -31,6 +31,7 @@ public class Permissions { public static final String FIGHT = CHECKS + ".fight"; public static final String FIGHT_DIRECTION = FIGHT + ".direction"; + public static final String FIGHT_SELFHIT = FIGHT + ".selfhit"; public final static String ADMIN_CHATLOG = ADMIN + ".chatlog"; public static final String ADMIN_PERMLIST = ADMIN + ".permlist"; diff --git a/src/cc/co/evenprime/bukkit/nocheat/config/cache/CCFight.java b/src/cc/co/evenprime/bukkit/nocheat/config/cache/CCFight.java index 14b9202f..2f686df6 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/config/cache/CCFight.java +++ b/src/cc/co/evenprime/bukkit/nocheat/config/cache/CCFight.java @@ -10,6 +10,8 @@ public class CCFight { public final double directionPrecision; public final ActionList directionActions; public final long directionPenaltyTime; + public final boolean selfhitCheck; + public final ActionList selfhitActions; public CCFight(Configuration data) { @@ -18,5 +20,7 @@ public class CCFight { directionPrecision = ((double) (data.getInteger(Configuration.FIGHT_DIRECTION_PRECISION))) / 100D; directionPenaltyTime = data.getInteger(Configuration.FIGHT_DIRECTION_PENALTYTIME); directionActions = data.getActionList(Configuration.FIGHT_DIRECTION_ACTIONS); + selfhitCheck = data.getBoolean(Configuration.FIGHT_SELFHIT_CHECK); + selfhitActions = data.getActionList(Configuration.FIGHT_SELFHIT_ACTIONS); } } diff --git a/src/cc/co/evenprime/bukkit/nocheat/data/FightData.java b/src/cc/co/evenprime/bukkit/nocheat/data/FightData.java index 2c637056..771c8299 100644 --- a/src/cc/co/evenprime/bukkit/nocheat/data/FightData.java +++ b/src/cc/co/evenprime/bukkit/nocheat/data/FightData.java @@ -5,5 +5,6 @@ public class FightData extends Data { public double violationLevel = 0; public long directionLastViolationTime = 0; public final ExecutionHistory history = new ExecutionHistory(); + public double selfhitviolationLevel = 0; }