+ Added the FastBreak check

+ Added the FastPlace check
= Fixed the WaterWalk check
= Added more stuff to the instructions
= Renamed some of the configuration's nodes
This commit is contained in:
NeatMonster 2012-04-06 23:13:49 +02:00
parent fcc0a169af
commit 7211f2cc4d
17 changed files with 248 additions and 20 deletions

View File

@ -203,6 +203,9 @@
-------------------- BLOCKBREAK Permissions for CHECKS -------------------------
- nocheatplus.checks.blockbreak.fastbreak
Allows the player to break blocks very quickly.
- nocheatplus.checks.blockbreak.reach
Allows the player to break blocks that are further away than usual.
@ -215,6 +218,9 @@
-------------------- BLOCKPLACE Permissions for CHECKS -------------------------
- nocheatplus.checks.blockplace.fastplace
Allows the player to place blocks very quickly.
- nocheatplus.checks.blockplace.reach
Allows the player to place blocks that are further away than usual.
@ -351,6 +357,18 @@
config.yml file. It is further split into logical sections
--------------------------------------------------------------------------------
----------------------------- CLIENT MODS Section ------------------------------
--------------------------------------------------------------------------------
Everything that in has to do with the client mods can be found at this part of
the config.yml.
allow:
Allow all your players to use all the client mods (Zombe, CJB, Rei's Minimap,
Minecraft AutoMap).
--------------------------------------------------------------------------------
-------------------------------- LOGGING Section -------------------------------
--------------------------------------------------------------------------------
@ -653,8 +671,28 @@
---------------------------- BLOCKBREAK Subsection -----------------------------
Checks that at least technically have to do with the player breaking blocks.
1) FASTBREAK:
This check will prevent players from breaking blocks too quickly by checking
the interval of time elapsed since they've broken their last block. This
should prevent players from using the features called "Smasher", "Click
Nuker" and "Creative Nuker" of their griefing client.
active:
Should players be checked for this behaviour.
actions:
What should happen if the player is considered to cheat this way. The
default is to prevent him from breaking the block ("cancel" breaking)
and on repeated offenses to log messages about it. If the Violation
Level becomes too hight, the player will be kicked. The Violation Level
(VL) is the difference between the usual minimum time it takes to break
two blocks and the real time elapsed. The VL increases with every failed
attempt to break a block, and decreases with every successful attempt.
1) REACH:
2) REACH:
Players may slightly increase the distance at which they can break
blocks. This check will try to identify that by comparing player and
@ -672,7 +710,7 @@
with every failed attempt to break a block out of reach, and decreases
with every successful attempt.
2) DIRECTION:
3) DIRECTION:
Players may break blocks without really looking at them. This is often
combined with breaking a lot of blocks surrounding the player at the same
@ -702,7 +740,7 @@
block. It increases with every failure and decreases with every
successful block break.
3) NOSWING:
4) NOSWING:
Players may break blocks without moving their arm. This is confusing for
nearby players, as they won't see who broke the blocks.
@ -721,8 +759,27 @@
---------------------------- BLOCKPLACE Subsection -----------------------------
Checks that at least technically have to do with the player placing blocks.
1) FASTPLACE:
This check will prevent players from placing blocks too quicly by checking
the interval of time elapsed since they've placed their last block. This
should prevent players from using the features called "FastPlace" and
"Build" of their griefing client.
active:
Should players be checked for this behaviour.
actions:
What should happen if the player is considered to cheat this way. The
default is to prevent him from placing the block ("cancel" placing)
and on repeated offenses to log messages about it. If the Violation
Level becomes too hight, the player will be kicked. The Violation Level
(VL) is the difference between the usual minimum time it takes to place
two blocks and the real time elapsed. The VL increases with every failed
attempt to place a block, and decreases with every successful attempt.
1) REACH:
2) REACH:
Players may slightly increase the distance at which they can place
blocks. This check will try to identify that by comparing player and
@ -740,7 +797,7 @@
with every failed attempt to place a block out of reach, and decreases
with every successful attempt.
2) DIRECTION:
3) DIRECTION:
Players may place blocks without really looking at them. This is often
combined with placing a lot of blocks in a certain shape.

View File

@ -50,6 +50,8 @@ permissions:
nocheatplus.checks.blockbreak:
description: Allow the player to bypass all blockbreak checks
children:
nocheatplus.checks.blockbreak.fastbreak:
description: Allow a player to break blocks very quickly
nocheatplus.checks.blockbreak.reach:
description: Allow a player to break blocks at maximum range (about 6-7 blocks, in creative mode unlimited)
nocheatplus.checks.blockbreak.direction:
@ -59,6 +61,8 @@ permissions:
nocheatplus.checks.blockplace:
description: Allow the player to bypass all blockplace checks
children:
nocheatplus.checks.blockplace.fastplace:
description: Allow a player to place blocks very quickly
nocheatplus.checks.blockplace.reach:
description: Allow a player to place blocks at maximum range (about 6-7 blocks)
nocheatplus.checks.blockplace.direction:

View File

@ -4,7 +4,7 @@
<!-- Informations -->
<name>NoCheatPlus</name>
<version>3.5.1</version>
<version>3.5.2</version>
<description>Detect and fight the exploitation of various flaws/bugs in Minecraft.</description>
<url>http://dev.bukkit.org/server-mods/nocheatplus</url>

View File

@ -189,7 +189,7 @@ public class NoCheatPlus extends JavaPlugin implements Listener {
public void onPlayerJoin(final PlayerJoinEvent event) {
final Player player = event.getPlayer();
if (conf.getConfigurationCacheForWorld(player.getWorld().getName()).getConfiguration()
.getBoolean(ConfPaths.ALLOW_CLIENT_MODS))
.getBoolean(ConfPaths.CLIENT_MODS_ALLOW))
return;
String message = "";
// Disable Zombe's fly mod

View File

@ -24,6 +24,7 @@ import org.bukkit.event.player.PlayerInteractEvent;
*/
public class BlockBreakCheckListener implements Listener, EventManager {
private final FastBreakCheck fastBreakCheck;
private final NoswingCheck noswingCheck;
private final ReachCheck reachCheck;
private final DirectionCheck directionCheck;
@ -31,6 +32,7 @@ public class BlockBreakCheckListener implements Listener, EventManager {
public BlockBreakCheckListener(final NoCheatPlus plugin) {
fastBreakCheck = new FastBreakCheck(plugin);
noswingCheck = new NoswingCheck(plugin);
reachCheck = new ReachCheck(plugin);
directionCheck = new DirectionCheck(plugin);
@ -84,16 +86,20 @@ public class BlockBreakCheckListener implements Listener, EventManager {
// computationally cheap checks first, because it may save us from
// doing the computationally expensive checks.
// First NoSwing: Did the arm of the player move before breaking this
// First FastPlace: Has the player broken blocks too quickly?
if (cc.fastBreakCheck && !player.hasPermission(Permissions.BLOCKBREAK_FASTBREAK))
cancelled = fastBreakCheck.check(player, data, cc);
// Second NoSwing: Did the arm of the player move before breaking this
// block?
if (cc.noswingCheck && !player.hasPermission(Permissions.BLOCKBREAK_NOSWING))
if (!cancelled && cc.noswingCheck && !player.hasPermission(Permissions.BLOCKBREAK_NOSWING))
cancelled = noswingCheck.check(player, data, cc);
// Second Reach: Is the block really in reach distance
// Third Reach: Is the block really in reach distance
if (!cancelled && cc.reachCheck && !player.hasPermission(Permissions.BLOCKBREAK_REACH))
cancelled = reachCheck.check(player, data, cc);
// Third Direction: Did the player look at the block at all
// Forth Direction: Did the player look at the block at all
if (!cancelled && cc.directionCheck && !player.hasPermission(Permissions.BLOCKBREAK_DIRECTION))
cancelled = directionCheck.check(player, data, cc);
@ -148,6 +154,8 @@ public class BlockBreakCheckListener implements Listener, EventManager {
final BlockBreakConfig bb = BlockBreakCheck.getConfig(cc);
if (bb.fastBreakCheck)
s.add("blockbreak.fastbreak");
if (bb.directionCheck)
s.add("blockbreak.direction");
if (bb.reachCheck)

View File

@ -14,6 +14,10 @@ import me.neatmonster.nocheatplus.config.Permissions;
*/
public class BlockBreakConfig implements ConfigItem {
public final boolean fastBreakCheck;
public final int fastBreakInterval;
public final ActionList fastBreakActions;
public final boolean reachCheck;
public final double reachDistance;
public final ActionList reachActions;
@ -28,6 +32,9 @@ public class BlockBreakConfig implements ConfigItem {
public BlockBreakConfig(final NoCheatPlusConfiguration data) {
fastBreakCheck = data.getBoolean(ConfPaths.BLOCKBREAK_FASTBREAK_CHECK);
fastBreakInterval = data.getInt(ConfPaths.BLOCKBREAK_FASTBREAK_INTERVAL);
fastBreakActions = data.getActionList(ConfPaths.BLOCKBREAK_FASTBREAK_ACTIONS, Permissions.BLOCKBREAK_FASTBREAK);
reachCheck = data.getBoolean(ConfPaths.BLOCKBREAK_REACH_CHECK);
reachDistance = 535D / 100D;
reachActions = data.getActionList(ConfPaths.BLOCKBREAK_REACH_ACTIONS, Permissions.BLOCKBREAK_REACH);

View File

@ -10,10 +10,14 @@ import me.neatmonster.nocheatplus.data.SimpleLocation;
public class BlockBreakData implements DataItem {
// Keep track of violation levels for the three checks
public double fastBreakVL = 0.0D;
public double reachVL = 0.0D;
public double directionVL = 0.0D;
public double noswingVL = 0.0D;
// Used the know when the player has broke his previous block
public long lastBreakTime = 0;
// Used for the penalty time feature of the direction check
public long directionLastViolationTime = 0;

View File

@ -0,0 +1,49 @@
package me.neatmonster.nocheatplus.checks.blockbreak;
import java.util.Locale;
import me.neatmonster.nocheatplus.NoCheatPlus;
import me.neatmonster.nocheatplus.NoCheatPlusPlayer;
import me.neatmonster.nocheatplus.actions.ParameterName;
import me.neatmonster.nocheatplus.data.Statistics.Id;
public class FastBreakCheck extends BlockBreakCheck {
public FastBreakCheck(final NoCheatPlus plugin) {
super(plugin, "blockbreak.fastbreak");
}
public boolean check(final NoCheatPlusPlayer player, final BlockBreakData data, final BlockBreakConfig cc) {
boolean cancel = false;
// Has the player broke blocks too quickly
if (data.lastBreakTime != 0 && System.currentTimeMillis() - data.lastBreakTime < cc.fastBreakInterval) {
// He failed, increase vl and statistics
data.fastBreakVL += cc.fastBreakInterval - System.currentTimeMillis() + data.lastBreakTime;
incrementStatistics(player, Id.BB_FASTBREAK, cc.fastBreakInterval - System.currentTimeMillis()
+ data.lastBreakTime);
// Execute whatever actions are associated with this check and the
// violation level and find out if we should cancel the event
cancel = executeActions(player, cc.fastBreakActions, data.fastBreakVL);
} else
// Reward with lowering of the violation level
data.fastBreakVL *= 0.90D;
data.lastBreakTime = System.currentTimeMillis();
return cancel;
}
@Override
public String getParameter(final ParameterName wildcard, final NoCheatPlusPlayer player) {
if (wildcard == ParameterName.VIOLATIONS)
return String.format(Locale.US, "%d", (int) getData(player).fastBreakVL);
else
return super.getParameter(wildcard, player);
}
}

View File

@ -21,6 +21,7 @@ import org.bukkit.event.block.BlockPlaceEvent;
*/
public class BlockPlaceCheckListener implements Listener, EventManager {
private final FastPlaceCheck fastPlaceCheck;
private final ReachCheck reachCheck;
private final DirectionCheck directionCheck;
private final NoCheatPlus plugin;
@ -29,6 +30,7 @@ public class BlockPlaceCheckListener implements Listener, EventManager {
this.plugin = plugin;
fastPlaceCheck = new FastPlaceCheck(plugin);
reachCheck = new ReachCheck(plugin);
directionCheck = new DirectionCheck(plugin);
}
@ -39,6 +41,8 @@ public class BlockPlaceCheckListener implements Listener, EventManager {
final BlockPlaceConfig bp = BlockPlaceCheck.getConfig(cc);
if (bp.fastPlaceCheck)
s.add("blockplace.fastplace");
if (bp.reachCheck)
s.add("blockplace.reach");
if (bp.directionCheck)
@ -72,11 +76,15 @@ public class BlockPlaceCheckListener implements Listener, EventManager {
// Now do the actual checks
// First the reach check
if (cc.reachCheck && !player.hasPermission(Permissions.BLOCKPLACE_REACH))
// First the fastplace check
if (cc.fastPlaceCheck && !player.hasPermission(Permissions.BLOCKPLACE_FASTPLACE))
cancelled = fastPlaceCheck.check(player, data, cc);
// Second the reach check
if (!cancelled && cc.reachCheck && !player.hasPermission(Permissions.BLOCKPLACE_REACH))
cancelled = reachCheck.check(player, data, cc);
// Second the direction check
// Third the direction check
if (!cancelled && cc.directionCheck && !player.hasPermission(Permissions.BLOCKPLACE_DIRECTION))
cancelled = directionCheck.check(player, data, cc);

View File

@ -14,6 +14,10 @@ import me.neatmonster.nocheatplus.config.Permissions;
*/
public class BlockPlaceConfig implements ConfigItem {
public final boolean fastPlaceCheck;
public final int fastPlaceInterval;
public final ActionList fastPlaceActions;
public final boolean reachCheck;
public final double reachDistance;
public final ActionList reachActions;
@ -25,6 +29,10 @@ public class BlockPlaceConfig implements ConfigItem {
public BlockPlaceConfig(final NoCheatPlusConfiguration data) {
fastPlaceCheck = data.getBoolean(ConfPaths.BLOCKPLACE_FASTPLACE_CHECK);
fastPlaceInterval = data.getInt(ConfPaths.BLOCKPLACE_FASTPLACE_INTERVAL);
fastPlaceActions = data.getActionList(ConfPaths.BLOCKPLACE_FASTPLACE_ACTIONS, Permissions.BLOCKPLACE_FASTPLACE);
reachCheck = data.getBoolean(ConfPaths.BLOCKPLACE_REACH_CHECK);
reachDistance = 535D / 100D;
reachActions = data.getActionList(ConfPaths.BLOCKPLACE_REACH_ACTIONS, Permissions.BLOCKPLACE_REACH);

View File

@ -10,9 +10,13 @@ import me.neatmonster.nocheatplus.data.SimpleLocation;
public class BlockPlaceData implements DataItem {
// Keep track of violation levels for the two checks
public double fastPlaceVL = 0.0D;
public double reachVL = 0.0D;
public double directionVL = 0.0D;
// Used the know when the player has placed his previous block
public long lastPlaceTime = 0;
// Used for the penalty time feature of the direction check
public long directionLastViolationTime = 0;

View File

@ -0,0 +1,48 @@
package me.neatmonster.nocheatplus.checks.blockplace;
import java.util.Locale;
import me.neatmonster.nocheatplus.NoCheatPlus;
import me.neatmonster.nocheatplus.NoCheatPlusPlayer;
import me.neatmonster.nocheatplus.actions.ParameterName;
import me.neatmonster.nocheatplus.data.Statistics.Id;
public class FastPlaceCheck extends BlockPlaceCheck {
public FastPlaceCheck(final NoCheatPlus plugin) {
super(plugin, "blockplace.fastplace");
}
public boolean check(final NoCheatPlusPlayer player, final BlockPlaceData data, final BlockPlaceConfig cc) {
boolean cancel = false;
// Has the player placed blocks too quickly
if (data.lastPlaceTime != 0 && System.currentTimeMillis() - data.lastPlaceTime < cc.fastPlaceInterval) {
// He failed, increase vl and statistics
data.fastPlaceVL += cc.fastPlaceInterval - System.currentTimeMillis() + data.lastPlaceTime;
incrementStatistics(player, Id.BP_FASTPLACE, cc.fastPlaceInterval - System.currentTimeMillis()
+ data.lastPlaceTime);
// Execute whatever actions are associated with this check and the
// violation level and find out if we should cancel the event
cancel = executeActions(player, cc.fastPlaceActions, data.fastPlaceVL);
} else
// Reward with lowering of the violation level
data.fastPlaceVL *= 0.90D;
data.lastPlaceTime = System.currentTimeMillis();
return cancel;
}
@Override
public String getParameter(final ParameterName wildcard, final NoCheatPlusPlayer player) {
if (wildcard == ParameterName.VIOLATIONS)
return String.format(Locale.US, "%d", (int) getData(player).fastPlaceVL);
else
return super.getParameter(wildcard, player);
}
}

View File

@ -69,8 +69,8 @@ public class WaterWalkCheck extends MovingCheck {
// Was one of the actions a cancel? Then do it
if (cancel)
newToLocation = from;
} else if (fromLiquid && fromBukkitLiquid && !toLiquid && (deltaX < 0.27D || deltaX > 0.29D)
&& (deltaZ < 0.27D || deltaZ > 0.29D)) {
} else if (fromLiquid && fromBukkitLiquid && !toLiquid && (deltaX < 0.28D || deltaX > 0.31D)
&& (deltaZ < 0.28D || deltaZ > 0.31D)) {
// If the player is trying to jump while being in water
// Increment violation counter
data.waterWalkVL += resultXZ;

View File

@ -8,6 +8,9 @@ package me.neatmonster.nocheatplus.config;
*/
public abstract class ConfPaths {
private final static String CLIENT_MODS = "clientmods.";
public final static String CLIENT_MODS_ALLOW = CLIENT_MODS + "allow";
private final static String LOGGING = "logging.";
public final static String LOGGING_ACTIVE = LOGGING + "active";
public final static String LOGGING_PREFIX = LOGGING + "prefix";
@ -75,6 +78,11 @@ public abstract class ConfPaths {
private final static String BLOCKBREAK = CHECKS + "blockbreak.";
private final static String BLOCKBREAK_FASTBREAK = BLOCKBREAK + "fastbreak.";
public final static String BLOCKBREAK_FASTBREAK_CHECK = BLOCKBREAK_FASTBREAK + "active";
public final static String BLOCKBREAK_FASTBREAK_INTERVAL = BLOCKBREAK_FASTBREAK + "interval";
public final static String BLOCKBREAK_FASTBREAK_ACTIONS = BLOCKBREAK_FASTBREAK + "actions";
private final static String BLOCKBREAK_REACH = BLOCKBREAK + "reach.";
public final static String BLOCKBREAK_REACH_CHECK = BLOCKBREAK_REACH + "active";
public final static String BLOCKBREAK_REACH_ACTIONS = BLOCKBREAK_REACH + "actions";
@ -91,6 +99,11 @@ public abstract class ConfPaths {
private final static String BLOCKPLACE = CHECKS + "blockplace.";
private final static String BLOCKPLACE_FASTPLACE = BLOCKPLACE + "fastplace.";
public final static String BLOCKPLACE_FASTPLACE_CHECK = BLOCKPLACE_FASTPLACE + "active";
public final static String BLOCKPLACE_FASTPLACE_INTERVAL = BLOCKPLACE_FASTPLACE + "interval";
public final static String BLOCKPLACE_FASTPLACE_ACTIONS = BLOCKPLACE_FASTPLACE + "actions";
private final static String BLOCKPLACE_REACH = BLOCKPLACE + "reach.";
public final static String BLOCKPLACE_REACH_CHECK = BLOCKPLACE_REACH + "active";
public final static String BLOCKPLACE_REACH_ACTIONS = BLOCKPLACE_REACH + "actions";
@ -146,8 +159,6 @@ public abstract class ConfPaths {
public static final String FIGHT_INSTANTHEAL_CHECK = FIGHT_INSTANTHEAL + "active";
public final static String FIGHT_INSTANTHEAL_ACTIONS = FIGHT_INSTANTHEAL + "actions";
public final static String ALLOW_CLIENT_MODS = "allowclientmods";
public final static String STRINGS = "strings";
}

View File

@ -14,6 +14,10 @@ public class DefaultConfiguration extends NoCheatPlusConfiguration {
options().header("Main configuration file for NoCheatPlus. Read \"Instructions.txt\"");
/** CLIENT MODS **/
set(ConfPaths.CLIENT_MODS_ALLOW, false);
/** LOGGING **/
set(ConfPaths.LOGGING_ACTIVE, true);
@ -66,6 +70,11 @@ public class DefaultConfiguration extends NoCheatPlusConfiguration {
/*** BLOCKBREAK ***/
set(ConfPaths.BLOCKBREAK_FASTBREAK_CHECK, true);
set(ConfPaths.BLOCKBREAK_FASTBREAK_INTERVAL, 145);
set(ConfPaths.BLOCKBREAK_FASTBREAK_ACTIONS,
"cancel vl>1000 log:bbfastbreak:3:5:cif cancel vl>4000 log:waterwalk:3:5:cif cmd:kick cancel");
set(ConfPaths.BLOCKBREAK_REACH_CHECK, true);
set(ConfPaths.BLOCKBREAK_REACH_ACTIONS, "cancel vl>5 log:bbreach:0:2:if cancel");
@ -79,6 +88,11 @@ public class DefaultConfiguration extends NoCheatPlusConfiguration {
/*** BLOCKPLACE ***/
set(ConfPaths.BLOCKPLACE_FASTPLACE_CHECK, true);
set(ConfPaths.BLOCKPLACE_FASTPLACE_INTERVAL, 145);
set(ConfPaths.BLOCKPLACE_FASTPLACE_ACTIONS,
"cancel vl>100 log:bpfastplace:3:5:cif cancel vl>2000 log:waterwalk:3:5:cif cmd:kick cancel");
set(ConfPaths.BLOCKPLACE_REACH_CHECK, true);
set(ConfPaths.BLOCKPLACE_REACH_ACTIONS, "cancel vl>5 log:bpreach:0:2:if cancel");
@ -125,8 +139,6 @@ public class DefaultConfiguration extends NoCheatPlusConfiguration {
set(ConfPaths.FIGHT_INSTANTHEAL_CHECK, true);
set(ConfPaths.FIGHT_INSTANTHEAL_ACTIONS, "log:fheal:1:1:if cancel");
set(ConfPaths.ALLOW_CLIENT_MODS, false);
set(ConfPaths.STRINGS + ".drop",
"[player] failed [check]: Tried to drop more items than allowed. VL [violations]");
set(ConfPaths.STRINGS + ".moveshort", "[player] failed [check]. VL [violations]");
@ -138,11 +150,15 @@ public class DefaultConfiguration extends NoCheatPlusConfiguration {
"[player] failed [check]: Sent [packets] more packets than expected. Total violation level [violations]");
set(ConfPaths.STRINGS + ".waterwalk",
"[player] failed [check]: tried to walk on water. Total violation level [violations]");
set(ConfPaths.STRINGS + ".bbfastbreak",
"[player] failed [check]: tried to break too much blocks. Total violation level [violations]");
set(ConfPaths.STRINGS + ".bbreach",
"[player] failed [check]: tried to interact with a block over distance [reachdistance]. VL [violations]");
set(ConfPaths.STRINGS + ".bbdirection",
"[player] failed [check]: tried to interact with a block out of line of sight. VL [violations]");
set(ConfPaths.STRINGS + ".bbnoswing", "[player] failed [check]: Didn't swing arm. VL [violations]");
set(ConfPaths.STRINGS + ".bpfastplace",
"[player] failed [check]: tried to place too much blocks. Total violation level [violations]");
set(ConfPaths.STRINGS + ".bpreach",
"[player] failed [check]: tried to interact with a block over distance [reachdistance]. VL [violations]");
set(ConfPaths.STRINGS + ".bpdirection",

View File

@ -18,11 +18,13 @@ public class Permissions {
/** CHECKS **/
private static final String BLOCKBREAK = CHECKS + ".blockbreak";
public static final String BLOCKBREAK_FASTBREAK = BLOCKBREAK + ".fastbreak";
public static final String BLOCKBREAK_REACH = BLOCKBREAK + ".reach";
public static final String BLOCKBREAK_DIRECTION = BLOCKBREAK + ".direction";
public static final String BLOCKBREAK_NOSWING = BLOCKBREAK + ".noswing";
private static final String BLOCKPLACE = CHECKS + ".blockplace";
public static final String BLOCKPLACE_FASTPLACE = BLOCKPLACE + ".fastplace";
public static final String BLOCKPLACE_REACH = BLOCKPLACE + ".reach";
public static final String BLOCKPLACE_DIRECTION = BLOCKPLACE + ".direction";

View File

@ -9,9 +9,11 @@ public class Statistics {
public enum Id {
BB_FASTBREAK("blockbreak.fastbreak"),
BB_DIRECTION("blockbreak.direction"),
BB_NOSWING("blockbreak.noswing"),
BB_REACH("blockbreak.reach"),
BP_FASTPLACE("blockplace.fastplace"),
BP_DIRECTION("blockplace.direction"),
BP_REACH("blockplace.reach"),
CHAT_COLOR("chat.color"),