New checks inventory.instantbow and inventory.instantfood

This commit is contained in:
Evenprime 2012-02-08 22:23:13 +01:00
parent 7f63028be0
commit aed49a3f91
18 changed files with 321 additions and 60 deletions

View File

@ -128,6 +128,23 @@ checks:
actions:
What should happen when a player goes beyond the set limit. Default settings log
a message and kick the player from the server.
instantbow:
Players may attack extremely fast and with a fully charged bow without
waiting for it to be fully pulled back.
active:
Should players be checked for this behaviour.
actions:
What should happen if the player fails this check. Default is to stop
the attack ("cancel" it) and log messages.
instanteat:
Players may eat various kinds of food instantly instead of waiting the
usual time munching on the item.
active:
Should players be checked for this behaviour.
actions:
What should happen if the player fails this check. Default is to deny
them the food level gain ("cancel" it) and log messages. Sadly it's
not possible to prevent the food item to get lost anyway.
moving:
All checks that have to do with player movement

View File

@ -87,3 +87,7 @@ permissions:
children:
nocheat.checks.inventory.drop:
description: Allow a player to drop more items in a short timeframe than the defined limit
nocheat.checks.inventory.instanteat:
description: Allow a player to eat food faster than normally possible
nocheat.checks.inventory.instantbow:
description: Allow a player to charge his bow faster than usual

View File

@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>cc.co.evenprime.bukkit</groupId>
<artifactId>NoCheat</artifactId>
<version>3.1.2</version>
<version>3.2.0</version>
<packaging>jar</packaging>
<name>NoCheat</name>
<properties>

View File

@ -5,7 +5,7 @@ package cc.co.evenprime.bukkit.nocheat.actions;
*
*/
public enum ParameterName {
PLAYER("player"), LOCATION("location"), WORLD("world"), VIOLATIONS("violations"), MOVEDISTANCE("movedistance"), REACHDISTANCE("reachdistance"), FALLDISTANCE("falldistance"), LOCATION_TO("locationto"), CHECK("check"), PACKETS("packets"), TEXT("text"), PLACE_LOCATION("placelocation"), PLACE_AGAINST("placeagainst"), BLOCK_TYPE("blocktype"), LIMIT("limit");
PLAYER("player"), LOCATION("location"), WORLD("world"), VIOLATIONS("violations"), MOVEDISTANCE("movedistance"), REACHDISTANCE("reachdistance"), FALLDISTANCE("falldistance"), LOCATION_TO("locationto"), CHECK("check"), PACKETS("packets"), TEXT("text"), PLACE_LOCATION("placelocation"), PLACE_AGAINST("placeagainst"), BLOCK_TYPE("blocktype"), LIMIT("limit"), FOOD("food");
private final String s;

View File

@ -1,9 +1,12 @@
package cc.co.evenprime.bukkit.nocheat.checks;
import java.util.HashSet;
import java.util.Set;
import net.minecraft.server.Block;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
import cc.co.evenprime.bukkit.nocheat.NoCheatPlayer;
import cc.co.evenprime.bukkit.nocheat.data.PreciseLocation;
@ -68,27 +71,29 @@ public class CheckUtil {
return Math.max(distance - limit, 0.0D);
}
private final static double magic = 0.45D;
private final static double magic2 = 0.55D;
private final static double magic = 0.45D;
private final static double magic2 = 0.55D;
private static final int NONSOLID = 1; // 0x00000001
private static final int SOLID = 2; // 0x00000010
private static final int NONSOLID = 1; // 0x00000001
private static final int SOLID = 2; // 0x00000010
// All liquids are "nonsolid" too
private static final int LIQUID = 4 | NONSOLID; // 0x00000101
private static final int LIQUID = 4 | NONSOLID; // 0x00000101
// All ladders are "nonsolid" and "solid" too
private static final int LADDER = 8 | NONSOLID | SOLID; // 0x00001011
private static final int LADDER = 8 | NONSOLID | SOLID; // 0x00001011
// All fences are solid - fences are treated specially due
// to being 1.5 blocks high
private static final int FENCE = 16 | SOLID | NONSOLID; // 0x00010010
private static final int FENCE = 16 | SOLID | NONSOLID; // 0x00010010
private static final int INGROUND = 128;
private static final int ONGROUND = 256;
private static final int INGROUND = 128;
private static final int ONGROUND = 256;
// Until I can think of a better way to determine if a block is solid or
// not, this is what I'll do
private static final int types[];
private static final int types[];
private static final Set<Material> foods = new HashSet<Material>();
static {
types = new int[256];
@ -162,6 +167,22 @@ public class CheckUtil {
* }
* }
*/
foods.add(Material.APPLE);
foods.add(Material.BREAD);
foods.add(Material.COOKED_BEEF);
foods.add(Material.COOKED_CHICKEN);
foods.add(Material.COOKED_FISH);
foods.add(Material.COOKIE);
foods.add(Material.GOLDEN_APPLE);
foods.add(Material.GRILLED_PORK);
foods.add(Material.MELON);
foods.add(Material.MUSHROOM_SOUP);
foods.add(Material.PORK);
foods.add(Material.RAW_BEEF);
foods.add(Material.RAW_CHICKEN);
foods.add(Material.RAW_FISH);
foods.add(Material.ROTTEN_FLESH);
foods.add(Material.SPIDER_EYE);
}
/**
@ -326,4 +347,10 @@ public class CheckUtil {
return types[typeId];
}
public static boolean isFood(ItemStack item) {
if(item == null)
return false;
return foods.contains(item.getType());
}
}

View File

@ -58,7 +58,7 @@ public class FightCheckListener implements Listener, EventManager {
final NoCheatPlayer player = plugin.getPlayer(damager);
final FightConfig cc = FightCheck.getConfig(player.getConfigurationStore());
if(!cc.check || player.hasPermission(Permissions.FIGHT)) {
if(!cc.damageChecks || player.hasPermission(Permissions.FIGHT)) {
return;
}
@ -112,13 +112,13 @@ public class FightCheckListener implements Listener, EventManager {
FightConfig f = FightCheck.getConfig(cc);
if(f.check && f.directionCheck)
if(f.directionCheck)
s.add("fight.direction");
if(f.check && f.noswingCheck)
if(f.noswingCheck)
s.add("fight.noswing");
if(f.check && f.reachCheck)
if(f.reachCheck)
s.add("fight.reach");
if(f.check && f.speedCheck)
if(f.speedCheck)
s.add("fight.speed");
return s;
}

View File

@ -7,7 +7,6 @@ import cc.co.evenprime.bukkit.nocheat.config.NoCheatConfiguration;
public class FightConfig implements ConfigItem {
public final boolean check;
public final boolean directionCheck;
public final double directionPrecision;
public final ActionList directionActions;
@ -22,6 +21,8 @@ public class FightConfig implements ConfigItem {
public final ActionList speedActions;
public final boolean speedCheck;
public final boolean damageChecks;
public FightConfig(NoCheatConfiguration data) {
directionCheck = data.getBoolean(ConfPaths.FIGHT_DIRECTION_CHECK);
@ -38,6 +39,6 @@ public class FightConfig implements ConfigItem {
speedActions = data.getActionList(ConfPaths.FIGHT_SPEED_ACTIONS);
speedAttackLimit = data.getInt(ConfPaths.FIGHT_SPEED_ATTACKLIMIT);
check = directionCheck || noswingCheck || reachCheck || speedCheck;
damageChecks = directionCheck || noswingCheck || reachCheck || speedCheck;
}
}

View File

@ -15,6 +15,9 @@ public class FightData implements DataItem {
public double reachVL;
public double reachTotalVL;
public int reachFailed;
public int speedVL;
public int speedTotalVL;
public int speedFailed;
public long directionLastViolationTime;
public long reachLastViolationTime;
@ -25,17 +28,19 @@ public class FightData implements DataItem {
public long speedTime;
public int speedAttackCount;
public int speedVL;
public int speedTotalVL;
public int speedFailed;
@Override
public void collectData(Map<String, Object> map) {
map.put("fight.direction.vl", (int) directionTotalVL);
map.put("fight.noswing.vl", (int) noswingTotalVL);
map.put("fight.reach.vl", (int) reachTotalVL);
map.put("fight.direction.failed", directionFailed);
map.put("fight.noswing.failed", noswingFailed);
map.put("fight.speed.vl", (int) speedTotalVL);
map.put("fight.direction.failed", (int) directionFailed);
map.put("fight.noswing.failed", (int) noswingFailed);
map.put("fight.reach.failed", (int) reachFailed);
map.put("fight.speed.failed", (int) speedFailed);
}
}

View File

@ -12,7 +12,6 @@ public class DropCheck extends InventoryCheck {
super(plugin, "inventory.drop", Permissions.INVENTORY_DROP);
}
@Override
public boolean check(NoCheatPlayer player, InventoryData data, InventoryConfig cc) {
boolean cancel = false;
@ -42,11 +41,6 @@ public class DropCheck extends InventoryCheck {
return cancel;
}
@Override
public boolean isEnabled(InventoryConfig cc) {
return cc.dropCheck;
}
public String getParameter(ParameterName wildcard, NoCheatPlayer player) {
if(wildcard == ParameterName.VIOLATIONS)

View File

@ -0,0 +1,49 @@
package cc.co.evenprime.bukkit.nocheat.checks.inventory;
import java.util.Locale;
import org.bukkit.event.entity.EntityShootBowEvent;
import cc.co.evenprime.bukkit.nocheat.NoCheat;
import cc.co.evenprime.bukkit.nocheat.NoCheatPlayer;
import cc.co.evenprime.bukkit.nocheat.actions.ParameterName;
import cc.co.evenprime.bukkit.nocheat.config.Permissions;
public class InstantBowCheck extends InventoryCheck {
public InstantBowCheck(NoCheat plugin) {
super(plugin, "fight.instantbow", Permissions.INVENTORY_INSTANTBOW);
}
public boolean check(NoCheatPlayer player, EntityShootBowEvent event, InventoryData data, InventoryConfig cc) {
boolean cancelled = false;
long time = System.currentTimeMillis();
float bowForce = event.getForce();
long expectedTimeWhenStringDrawn = data.lastBowInteractTime + (int) (bowForce * bowForce * 700F);
if(expectedTimeWhenStringDrawn < time) {
// Acceptable, reduce VL
data.instantBowVL *= 0.98D;
} else if(data.lastBowInteractTime > time) {
// Security, if time ran backwards, reset
data.lastBowInteractTime = 0;
} else {
// Seems fishy, increase violation level
int vl = ((int) (expectedTimeWhenStringDrawn - time)) / 100;
data.instantBowVL += vl;
data.instantBowTotalVL += vl;
data.instantBowFailed++;
cancelled = executeActions(player, cc.bowActions.getActions(data.instantBowVL));
}
return cancelled;
}
public String getParameter(ParameterName wildcard, NoCheatPlayer player) {
if(wildcard == ParameterName.VIOLATIONS)
return String.format(Locale.US, "%d", (int) getData(player.getDataStore()).instantBowVL);
else
return super.getParameter(wildcard, player);
}
}

View File

@ -0,0 +1,55 @@
package cc.co.evenprime.bukkit.nocheat.checks.inventory;
import java.util.Locale;
import org.bukkit.event.entity.FoodLevelChangeEvent;
import cc.co.evenprime.bukkit.nocheat.NoCheat;
import cc.co.evenprime.bukkit.nocheat.NoCheatPlayer;
import cc.co.evenprime.bukkit.nocheat.actions.ParameterName;
import cc.co.evenprime.bukkit.nocheat.config.Permissions;
public class InstantEatCheck extends InventoryCheck {
public InstantEatCheck(NoCheat plugin) {
super(plugin, "inventory.instanteat", Permissions.INVENTORY_INSTANTEAT);
}
public boolean check(NoCheatPlayer player, FoodLevelChangeEvent event, InventoryData data, InventoryConfig cc) {
// Seems to be not the result of eating
if(data.foodMaterial == null || event.getFoodLevel() <= player.getPlayer().getFoodLevel())
return false;
boolean cancelled = false;
long time = System.currentTimeMillis();
long expectedTimeWhenEatingFinished = data.lastEatInteractTime + 700;
if(expectedTimeWhenEatingFinished < time) {
// Acceptable, reduce VL
data.instantEatVL *= 0.98D;
} else if(data.lastEatInteractTime > time) {
// Security, if time ran backwards, reset
data.lastEatInteractTime = 0;
} else {
// Seems fishy, increase violation level
int vl = ((int) (expectedTimeWhenEatingFinished - time)) / 100;
data.instantEatVL += vl;
data.instantEatTotalVL += vl;
data.instantEatFailed++;
cancelled = executeActions(player, cc.eatActions.getActions(data.instantEatVL));
}
return cancelled;
}
public String getParameter(ParameterName wildcard, NoCheatPlayer player) {
if(wildcard == ParameterName.VIOLATIONS)
return String.format(Locale.US, "%d", getData(player.getDataStore()).instantEatVL);
else if(wildcard == ParameterName.FOOD)
return getData(player.getDataStore()).foodMaterial.toString();
else
return super.getParameter(wildcard, player);
}
}

View File

@ -1,7 +1,6 @@
package cc.co.evenprime.bukkit.nocheat.checks.inventory;
import cc.co.evenprime.bukkit.nocheat.NoCheat;
import cc.co.evenprime.bukkit.nocheat.NoCheatPlayer;
import cc.co.evenprime.bukkit.nocheat.checks.Check;
import cc.co.evenprime.bukkit.nocheat.config.ConfigurationCacheStore;
import cc.co.evenprime.bukkit.nocheat.data.DataStore;
@ -14,10 +13,6 @@ public abstract class InventoryCheck extends Check {
super(plugin, id, name, permission);
}
public abstract boolean check(NoCheatPlayer player, InventoryData data, InventoryConfig cc);
public abstract boolean isEnabled(InventoryConfig cc);
public static InventoryData getData(DataStore base) {
InventoryData data = base.get(id);
if(data == null) {

View File

@ -1,29 +1,37 @@
package cc.co.evenprime.bukkit.nocheat.checks.inventory;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.entity.EntityShootBowEvent;
import org.bukkit.event.entity.FoodLevelChangeEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import cc.co.evenprime.bukkit.nocheat.EventManager;
import cc.co.evenprime.bukkit.nocheat.NoCheat;
import cc.co.evenprime.bukkit.nocheat.NoCheatPlayer;
import cc.co.evenprime.bukkit.nocheat.checks.CheckUtil;
import cc.co.evenprime.bukkit.nocheat.config.ConfigurationCacheStore;
import cc.co.evenprime.bukkit.nocheat.config.Permissions;
public class InventoryCheckListener implements Listener, EventManager {
private final List<InventoryCheck> checks;
private final NoCheat plugin;
private final DropCheck dropCheck;
private final InstantBowCheck instantBowCheck;
private final InstantEatCheck instantEatCheck;
private final NoCheat plugin;
public InventoryCheckListener(NoCheat plugin) {
this.checks = new ArrayList<InventoryCheck>(1);
// Don't use this check now, it's buggy
this.checks.add(new DropCheck(plugin));
this.dropCheck = new DropCheck(plugin);
this.instantBowCheck = new InstantBowCheck(plugin);
this.instantEatCheck = new InstantEatCheck(plugin);
this.plugin = plugin;
}
@ -36,20 +44,17 @@ public class InventoryCheckListener implements Listener, EventManager {
final NoCheatPlayer player = plugin.getPlayer(event.getPlayer());
final InventoryConfig cc = InventoryCheck.getConfig(player.getConfigurationStore());
final InventoryData data = InventoryCheck.getData(player.getDataStore());
if(!cc.check || player.hasPermission(Permissions.INVENTORY) || player.isDead()) {
if(player.hasPermission(Permissions.INVENTORY) || player.isDead()) {
return;
}
final InventoryData data = InventoryCheck.getData(player.getDataStore());
boolean cancelled = false;
for(InventoryCheck check : checks) {
// If it should be executed, do it
if(!cancelled && check.isEnabled(cc) && !player.hasPermission(check.getPermission())) {
cancelled = check.check(player, data, cc);
}
// If it should be executed, do it
if(cc.dropCheck && !player.hasPermission(dropCheck.getPermission())) {
cancelled = dropCheck.check(player, data, cc);
}
if(cancelled) {
@ -59,12 +64,71 @@ public class InventoryCheckListener implements Listener, EventManager {
}
}
@EventHandler(priority = EventPriority.LOWEST)
public void interact(final PlayerInteractEvent event) {
if(!event.hasItem() || event.getAction() != Action.RIGHT_CLICK_AIR || event.getAction() != Action.RIGHT_CLICK_BLOCK)
return;
NoCheatPlayer player = plugin.getPlayer(event.getPlayer());
final InventoryData data = InventoryCheck.getData(player.getDataStore());
if(event.getItem().getType() == Material.BOW) {
data.lastBowInteractTime = System.currentTimeMillis();
} else if(CheckUtil.isFood(event.getItem())) {
// Remember food Material, because we don't have that info in the other event
data.foodMaterial = event.getItem().getType();
data.lastFoodInteractTime = System.currentTimeMillis();
} else {
data.lastBowInteractTime = 0;
data.lastFoodInteractTime = 0;
data.foodMaterial = null;
}
}
@EventHandler(priority = EventPriority.LOWEST)
public void foodchanged(final FoodLevelChangeEvent event) {
if(!event.isCancelled() && event.getEntity() instanceof Player) {
final NoCheatPlayer player = plugin.getPlayer((Player) event.getEntity());
final InventoryConfig cc = InventoryCheck.getConfig(player.getConfigurationStore());
final InventoryData data = InventoryCheck.getData(player.getDataStore());
if(cc.eatCheck && !player.hasPermission(instantEatCheck.getPermission())) {
boolean cancelled = instantEatCheck.check(player, event, data, cc);
event.setCancelled(cancelled);
}
data.foodMaterial = null;
}
}
@EventHandler(priority = EventPriority.LOWEST)
public void bowfired(final EntityShootBowEvent event) {
if(!event.isCancelled() && event.getEntity() instanceof Player) {
final NoCheatPlayer player = plugin.getPlayer((Player) event.getEntity());
final InventoryConfig cc = InventoryCheck.getConfig(player.getConfigurationStore());
if(cc.bowCheck && !player.hasPermission(instantBowCheck.getPermission())) {
final InventoryData data = InventoryCheck.getData(player.getDataStore());
boolean cancelled = instantBowCheck.check(player, event, data, cc);
event.setCancelled(cancelled);
}
}
}
public List<String> getActiveChecks(ConfigurationCacheStore cc) {
LinkedList<String> s = new LinkedList<String>();
InventoryConfig i = InventoryCheck.getConfig(cc);
if(i.check && i.dropCheck)
if(i.dropCheck)
s.add("inventory.dropCheck");
if(i.bowCheck)
s.add("inventory.instantbow");
if(i.eatCheck)
s.add("inventory.instanteat");
return s;
}
}

View File

@ -7,13 +7,17 @@ import cc.co.evenprime.bukkit.nocheat.config.NoCheatConfiguration;
public class InventoryConfig implements ConfigItem {
public final boolean check;
public final boolean dropCheck;
public final long dropTimeFrame;
public final int dropLimit;
public final ActionList dropActions;
public final boolean bowCheck;
public final ActionList bowActions;
public final boolean eatCheck;
public final ActionList eatActions;
public InventoryConfig(NoCheatConfiguration data) {
dropCheck = data.getBoolean(ConfPaths.INVENTORY_DROP_CHECK);
@ -21,6 +25,10 @@ public class InventoryConfig implements ConfigItem {
dropLimit = data.getInt(ConfPaths.INVENTORY_DROP_LIMIT);
dropActions = data.getActionList(ConfPaths.INVENTORY_DROP_ACTIONS);
check = dropCheck;
bowCheck = data.getBoolean(ConfPaths.INVENTORY_INSTANTBOW_CHECK);
bowActions = data.getActionList(ConfPaths.INVENTORY_INSTANTBOW_ACTIONS);
eatCheck = data.getBoolean(ConfPaths.INVENTORY_INSTANTEAT_CHECK);
eatActions = data.getActionList(ConfPaths.INVENTORY_INSTANTEAT_ACTIONS);
}
}

View File

@ -1,19 +1,40 @@
package cc.co.evenprime.bukkit.nocheat.checks.inventory;
import java.util.Map;
import org.bukkit.Material;
import cc.co.evenprime.bukkit.nocheat.DataItem;
public class InventoryData implements DataItem {
public int dropVL = 0;
public double dropTotalVL = 0;
public int dropFailed = 0;
public long dropLastTime;
public int dropCount;
public int dropVL;
public double dropTotalVL;
public int dropFailed;
public long dropLastTime;
public int dropCount;
public int instantBowVL;
public int instantBowTotalVL;
public int instantBowFailed;
public double instantEatVL;
public int instantEatTotalVL;
public int instantEatFailed;
public long lastBowInteractTime;
public int lastEatInteractTime;
public Material foodMaterial;
public long lastFoodInteractTime;
public int newFoodLevel;
@Override
public void collectData(Map<String, Object> map) {
map.put("inventory.drop.vl", (int) dropTotalVL);
map.put("inventory.drop.failed", (int) dropFailed);
map.put("inventory.instantbow.vl", (int) instantBowTotalVL);
map.put("inventory.instantbow.failed", (int) instantBowFailed);
map.put("inventory.instanteat.vl", (int) instantEatTotalVL);
map.put("inventory.instanteat.failed", (int) instantEatFailed);
}
}

View File

@ -17,12 +17,23 @@ public abstract class ConfPaths {
public final static String LOGGING_DEBUGMESSAGES = LOGGING + "debugmessages";
private final static String CHECKS = "checks.";
private final static String INVENTORY_DROP = CHECKS + "inventory.drop.";
private final static String INVENTORY = "CHECKS" + "inventory.";
private final static String INVENTORY_DROP = INVENTORY + "drop.";
public final static String INVENTORY_DROP_CHECK = INVENTORY_DROP + "active";
public final static String INVENTORY_DROP_TIMEFRAME = INVENTORY_DROP + "time";
public final static String INVENTORY_DROP_LIMIT = INVENTORY_DROP + "limit";
public final static String INVENTORY_DROP_ACTIONS = INVENTORY_DROP + "actions";
private static final String INVENTORY_INSTANTBOW = INVENTORY + "instantbow.";
public final static String INVENTORY_INSTANTBOW_CHECK = INVENTORY_INSTANTBOW + "active";
public static final String INVENTORY_INSTANTBOW_ACTIONS = INVENTORY_INSTANTBOW + "actions";
private static final String INVENTORY_INSTANTEAT = INVENTORY + "instanteat.";
public final static String INVENTORY_INSTANTEAT_CHECK = INVENTORY_INSTANTEAT + "active";
public static final String INVENTORY_INSTANTEAT_ACTIONS = INVENTORY_INSTANTEAT + "actions";
private final static String MOVING = CHECKS + "moving.";
private final static String MOVING_RUNFLY = MOVING + "runfly.";

View File

@ -30,6 +30,12 @@ public class DefaultConfiguration extends NoCheatConfiguration {
set(ConfPaths.INVENTORY_DROP_LIMIT, 100);
set(ConfPaths.INVENTORY_DROP_ACTIONS, "log:drop:0:1:cif cmd:kick");
set(ConfPaths.INVENTORY_INSTANTBOW_CHECK, true);
set(ConfPaths.INVENTORY_INSTANTBOW_ACTIONS, "log:ibow:2:5:if cancel");
set(ConfPaths.INVENTORY_INSTANTEAT_CHECK, true);
set(ConfPaths.INVENTORY_INSTANTEAT_ACTIONS, "log:ieat:2:5:if cancel");
/*** MOVING ***/
set(ConfPaths.MOVING_RUNFLY_CHECK, true);
set(ConfPaths.MOVING_RUNFLY_ALLOWFASTSNEAKING, false);
@ -118,6 +124,8 @@ public class DefaultConfiguration extends NoCheatConfiguration {
set(ConfPaths.STRINGS + ".freach", "[player] failed [check]: tried to attack entity out of reach. VL [violations]");
set(ConfPaths.STRINGS + ".fspeed", "[player] failed [check]: tried to attack more than [limit] times per second. VL [violations]");
set(ConfPaths.STRINGS + ".fnoswing", "[player] failed [check]: Didn't swing arm. VL [violations]");
set(ConfPaths.STRINGS + ".ibow", "[player] failed [check]: Fires bow to fast. VL [violations]");
set(ConfPaths.STRINGS + ".ieat", "[player] failed [check]: Eats food [food] too fast. VL [violations]");
set(ConfPaths.STRINGS + ".kick", "kick [player]");
// Update internal factory based on all the new entries to the "actions" section

View File

@ -43,6 +43,8 @@ public class Permissions {
public static final String INVENTORY = CHECKS + ".inventory";
public static final String INVENTORY_DROP = INVENTORY + ".drop";
public static final String INVENTORY_INSTANTBOW = INVENTORY + ".instantbow";
public static final String INVENTORY_INSTANTEAT = INVENTORY + ".instanteat";
private Permissions() {}
}