mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2025-04-08 12:35:45 +02:00
Complete rewrite of internal configuration and action execution system
for performance removed noclip check, itemdrop check andgui editor
This commit is contained in:
parent
3d28e5738f
commit
a8342b0681
manifestplugin.yml
src/cc/co/evenprime/bukkit/nocheat
DefaultConfiguration.javaExplainations.javaNoCheat.java
actions
checks
blockbreak
blockplace
chat
interact
moving
config
Configuration.javaConfigurationManager.javaDefaultConfiguration.javaExplainations.javaFlatFileAction.javaFlatFileConfiguration.javaOptionNode.javaPermissions.java
cache
CCBlockBreak.javaCCBlockPlace.javaCCChat.javaCCDebug.javaCCInteract.javaCCLogging.javaCCMoving.javaConfigurationCache.java
tree
data
events
BlockBreakEventManager.javaBlockPlaceEventManager.javaPlayerChatEventManager.javaPlayerInteractEventManager.javaPlayerItemDropEventManager.javaPlayerMoveEventManager.javaPlayerTeleportEventManager.java
file
log
wizard
2
manifest
2
manifest
@ -1,2 +0,0 @@
|
||||
Manifest-Version: 1.0
|
||||
Main-Class: cc.co.evenprime.bukkit.nocheat.wizard.Wizard
|
16
plugin.yml
16
plugin.yml
@ -3,14 +3,14 @@ name: NoCheat
|
||||
author: Evenprime
|
||||
|
||||
main: cc.co.evenprime.bukkit.nocheat.NoCheat
|
||||
version: 2.08c
|
||||
version: 2.09
|
||||
|
||||
commands:
|
||||
nocheat:
|
||||
description: NoCheat command(s)
|
||||
permission: nocheat.admin.permlist
|
||||
usage: |
|
||||
/<command> permlist player [permission] to list the NoCheat relevant permissions of the player, optionally only those starting with [permission]
|
||||
nocheat:
|
||||
description: NoCheat command(s)
|
||||
usage: |
|
||||
/<command> permlist player [permission] - to list the NoCheat relevant permissions of the player, optionally only those starting with [permission]
|
||||
/<command> reload - to reload NoCheats configuration file(s), without reloading the plugin itself
|
||||
|
||||
permissions:
|
||||
nocheat:
|
||||
@ -23,6 +23,8 @@ permissions:
|
||||
description: Show log messages in the players chat
|
||||
nocheat.admin.permlist:
|
||||
description: allow use of the "nocheat permlist" command
|
||||
nocheat.admin.reload:
|
||||
description: allow use of the "nocheat reload" command
|
||||
nocheat.checks:
|
||||
description: Allow the player to bypass all checks
|
||||
children:
|
||||
@ -37,8 +39,6 @@ permissions:
|
||||
description: Allow a player to move through water without slowdown
|
||||
nocheat.checks.moving.sneaking:
|
||||
description: Allow a player to sneak without slowdown
|
||||
nocheat.checks.moving.noclip:
|
||||
description: Allow a player to walk through walls
|
||||
nocheat.checks.moving.nofall:
|
||||
description: Allow a player to cheat and not take fall damage at all
|
||||
nocheat.checks.moving.morepackets:
|
||||
|
@ -1,377 +0,0 @@
|
||||
package cc.co.evenprime.bukkit.nocheat;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.ActionListOption;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.BooleanOption;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.ConfigurationTree;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.IntegerOption;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.LogLevelOption;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.MediumStringOption;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.ParentOption;
|
||||
import cc.co.evenprime.bukkit.nocheat.log.LogLevel;
|
||||
|
||||
/**
|
||||
* The place where the structure of the configuration tree is defined, the
|
||||
* default settings are defined, the default files are defined.
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public class DefaultConfiguration {
|
||||
|
||||
/**
|
||||
* Create a full default options tree
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static ConfigurationTree buildDefaultConfigurationTree() {
|
||||
|
||||
ConfigurationTree root = new ConfigurationTree();
|
||||
|
||||
/*** LOGGING section ***/
|
||||
{
|
||||
ParentOption loggingNode = new ParentOption("logging");
|
||||
root.add(loggingNode);
|
||||
|
||||
loggingNode.add(new BooleanOption("active", true, true));
|
||||
loggingNode.add(new MediumStringOption("filename", "nocheat.log"));
|
||||
loggingNode.add(new LogLevelOption("filelevel", LogLevel.LOW));
|
||||
loggingNode.add(new LogLevelOption("consolelevel", LogLevel.HIGH));
|
||||
loggingNode.add(new LogLevelOption("chatlevel", LogLevel.MED));
|
||||
}
|
||||
|
||||
/*** LOGGING section ***/
|
||||
{
|
||||
ParentOption debugNode = new ParentOption("debug");
|
||||
root.add(debugNode);
|
||||
|
||||
debugNode.add(new BooleanOption("showactivechecks", false, false));
|
||||
}
|
||||
|
||||
/*** MOVING ***/
|
||||
{
|
||||
ParentOption movingNode = new ParentOption("moving");
|
||||
root.add(movingNode);
|
||||
|
||||
movingNode.add(new BooleanOption("check", true, true));
|
||||
|
||||
movingNode.add(new BooleanOption("identifycreativemode", true, false));
|
||||
|
||||
/**** MOVING.WALKING ****/
|
||||
{
|
||||
ParentOption runflyNode = new ParentOption("runfly");
|
||||
movingNode.add(runflyNode);
|
||||
|
||||
runflyNode.add(new BooleanOption("check", true, true));
|
||||
|
||||
runflyNode.add(new IntegerOption("walkingspeedlimit", 22));
|
||||
runflyNode.add(new IntegerOption("sprintingspeedlimit", 40));
|
||||
runflyNode.add(new IntegerOption("jumpheight", 135));
|
||||
|
||||
runflyNode.add(new BooleanOption("checksneaking", true, false));
|
||||
runflyNode.add(new IntegerOption("sneakingspeedlimit", 14));
|
||||
|
||||
runflyNode.add(new BooleanOption("checkswimming", true, false));
|
||||
runflyNode.add(new IntegerOption("swimmingspeedlimit", 18));
|
||||
|
||||
ActionListOption walkactions = new ActionListOption("actions");
|
||||
runflyNode.add(walkactions);
|
||||
walkactions.add(0, "moveLogLowShort moveCancel");
|
||||
walkactions.add(100, "moveLogMedShort moveCancel");
|
||||
walkactions.add(400, "moveLogHighShort moveCancel");
|
||||
|
||||
runflyNode.add(new BooleanOption("checknofall", true, false));
|
||||
runflyNode.add(new IntegerOption("nofallmultiplier", 120));
|
||||
ActionListOption nofallactions = new ActionListOption("nofallactions");
|
||||
runflyNode.add(nofallactions);
|
||||
nofallactions.add(0, "nofallLog nofallDamage");
|
||||
|
||||
runflyNode.add(new BooleanOption("allowlimitedflying", false, false));
|
||||
|
||||
runflyNode.add(new IntegerOption("flyingspeedlimitvertical", 100));
|
||||
runflyNode.add(new IntegerOption("flyingspeedlimithorizontal", 60));
|
||||
|
||||
ActionListOption flyactions = new ActionListOption("flyingactions");
|
||||
runflyNode.add(flyactions);
|
||||
flyactions.add(0, "moveLogLowShort moveCancel");
|
||||
flyactions.add(100, "moveLogMedShort moveCancel");
|
||||
flyactions.add(400, "moveLogHighShort moveCancel");
|
||||
}
|
||||
|
||||
/**** MOVING.MOREPACKETS ****/
|
||||
{
|
||||
ParentOption morePacketsNode = new ParentOption("morepackets");
|
||||
movingNode.add(morePacketsNode);
|
||||
|
||||
morePacketsNode.add(new BooleanOption("check", true, true));
|
||||
|
||||
ActionListOption actions = new ActionListOption("actions");
|
||||
|
||||
morePacketsNode.add(actions);
|
||||
|
||||
actions.add(0, "morepacketsLow moveCancel");
|
||||
actions.add(30, "morepacketsMed moveCancel");
|
||||
actions.add(60, "morepacketsHigh moveCancel");
|
||||
}
|
||||
|
||||
/**** MOVING.NOCLIP ****/
|
||||
{
|
||||
ParentOption noclipNode = new ParentOption("noclip");
|
||||
movingNode.add(noclipNode);
|
||||
|
||||
noclipNode.add(new BooleanOption("check", false, true));
|
||||
ActionListOption actions = new ActionListOption("actions");
|
||||
|
||||
noclipNode.add(actions);
|
||||
|
||||
actions.add(1, "noclipLog");
|
||||
}
|
||||
}
|
||||
|
||||
/****** BLOCKBREAK ******/
|
||||
{
|
||||
ParentOption interactNode = new ParentOption("blockbreak");
|
||||
root.add(interactNode);
|
||||
|
||||
interactNode.add(new BooleanOption("check", true, true));
|
||||
|
||||
/**** BLOCKBREAK.REACH ****/
|
||||
{
|
||||
ParentOption reachNode = new ParentOption("reach");
|
||||
interactNode.add(reachNode);
|
||||
|
||||
reachNode.add(new BooleanOption("check", true, true));
|
||||
reachNode.add(new IntegerOption("reachlimit", 485));
|
||||
|
||||
ActionListOption actions = new ActionListOption("actions");
|
||||
|
||||
reachNode.add(actions);
|
||||
|
||||
actions.add(0, "reachLog blockbreakCancel");
|
||||
}
|
||||
|
||||
/**** BLOCKBREAK.DIRECTION ****/
|
||||
{
|
||||
ParentOption directionNode = new ParentOption("direction");
|
||||
interactNode.add(directionNode);
|
||||
|
||||
directionNode.add(new BooleanOption("check", true, true));
|
||||
|
||||
directionNode.add(new BooleanOption("checkinstabreakblocks", false, false));
|
||||
|
||||
ActionListOption actions = new ActionListOption("actions");
|
||||
|
||||
directionNode.add(actions);
|
||||
|
||||
actions.add(0, "directionLog blockbreakCancel");
|
||||
}
|
||||
}
|
||||
|
||||
/****** BLOCKPLACE ******/
|
||||
{
|
||||
ParentOption blockPlaceNode = new ParentOption("blockplace");
|
||||
root.add(blockPlaceNode);
|
||||
|
||||
blockPlaceNode.add(new BooleanOption("check", true, true));
|
||||
|
||||
/**** BLOCKPLACE.REACH ****/
|
||||
{
|
||||
ParentOption reachNode = new ParentOption("reach");
|
||||
blockPlaceNode.add(reachNode);
|
||||
|
||||
reachNode.add(new BooleanOption("check", true, true));
|
||||
reachNode.add(new IntegerOption("reachlimit", 485));
|
||||
|
||||
ActionListOption actions = new ActionListOption("actions");
|
||||
|
||||
reachNode.add(actions);
|
||||
|
||||
actions.add(0, "reachLog blockplaceCancel");
|
||||
}
|
||||
|
||||
/**** BLOCKPLACE.ONLIQUID ****/
|
||||
{
|
||||
ParentOption onliquidNode = new ParentOption("onliquid");
|
||||
blockPlaceNode.add(onliquidNode);
|
||||
|
||||
onliquidNode.add(new BooleanOption("check", true, true));
|
||||
|
||||
ActionListOption actions = new ActionListOption("actions");
|
||||
|
||||
onliquidNode.add(actions);
|
||||
|
||||
actions.add(0, "onliquidLog blockplaceCancel");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/****** INTERACT ******/
|
||||
{
|
||||
ParentOption interactNode = new ParentOption("interact");
|
||||
root.add(interactNode);
|
||||
|
||||
interactNode.add(new BooleanOption("check", true, true));
|
||||
|
||||
/**** BLOCKBREAK.REACH ****/
|
||||
{
|
||||
ParentOption durabilityNode = new ParentOption("durability");
|
||||
interactNode.add(durabilityNode);
|
||||
|
||||
durabilityNode.add(new BooleanOption("check", true, true));
|
||||
|
||||
ActionListOption actions = new ActionListOption("actions");
|
||||
|
||||
durabilityNode.add(actions);
|
||||
|
||||
actions.add(0, "durabilityLog interactCancel");
|
||||
}
|
||||
}
|
||||
|
||||
/****** CHAT ******/
|
||||
{
|
||||
ParentOption chatNode = new ParentOption("chat");
|
||||
root.add(chatNode);
|
||||
|
||||
chatNode.add(new BooleanOption("check", true, true));
|
||||
|
||||
/**** CHAT.SPAM ****/
|
||||
{
|
||||
ParentOption spamNode = new ParentOption("spam");
|
||||
chatNode.add(spamNode);
|
||||
|
||||
spamNode.add(new BooleanOption("check", false, true));
|
||||
spamNode.add(new IntegerOption("timeframe", 5));
|
||||
spamNode.add(new IntegerOption("limit", 5));
|
||||
|
||||
ActionListOption actions = new ActionListOption("actions");
|
||||
|
||||
spamNode.add(actions);
|
||||
|
||||
actions.add(0, "spamLog spamCancel");
|
||||
}
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
public static void writeActionFile(File file) {
|
||||
BufferedWriter w;
|
||||
|
||||
try {
|
||||
if(!file.exists()) {
|
||||
try {
|
||||
file.getParentFile().mkdirs();
|
||||
file.createNewFile();
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
w = new BufferedWriter(new FileWriter(file));
|
||||
|
||||
w(w, "# This file contains the definitions of the default actions of NoCheat.");
|
||||
w(w, "# DO NOT EDIT THIS FILE DIRECTLY. If you want to change any of these, copy");
|
||||
w(w, "# them to your \"actions.txt\" file and modify them there. If an action with");
|
||||
w(w, "# the same name exists here and in your file, yours will be used.");
|
||||
w(w, "");
|
||||
w.flush();
|
||||
w.close();
|
||||
} catch(IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void writeDefaultActionFile(File file) {
|
||||
|
||||
BufferedWriter w;
|
||||
|
||||
try {
|
||||
if(!file.exists()) {
|
||||
try {
|
||||
file.getParentFile().mkdirs();
|
||||
file.createNewFile();
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
w = new BufferedWriter(new FileWriter(file));
|
||||
|
||||
w(w, "# This file contains the definitions of the default actions of NoCheat.");
|
||||
w(w, "# DO NOT EDIT THIS FILE DIRECTLY. If you want to change any of these, copy");
|
||||
w(w, "# them to your \"actions.txt\" file and modify them there. If an action with");
|
||||
w(w, "# the same name exists here and in your file, yours will be used.");
|
||||
w(w, "#");
|
||||
w(w, "# LOG Actions: They will print messages in your log file, console, chat, ...");
|
||||
w(w, "# - They start with the word 'log'");
|
||||
w(w, "# - Then comes their name. That name is used in the config file to identify them");
|
||||
w(w, "# - Then comes the 'delay', that is how often has this action to be called before it really gets executed");
|
||||
w(w, "# - Then comes the 'repeat', that is how many seconds have to be between two executions of the action");
|
||||
w(w, "# - Then comes the 'loglevel', that is how the log message gets categorized (low, med, high)");
|
||||
w(w, "# - Then comes the 'message', depending on where the action is used, different keywords in [ ] may be used");
|
||||
w(w, "");
|
||||
w(w, "# Gives a very short log message of the violation, only containing name, violation type and total violation value, at most once every 15 seconds, only if more than 3 violations happened within the last minute (low) and immediatly (med,high)");
|
||||
w(w, "log moveLogLowShort 3 15 low NC: [player] failed [check]");
|
||||
w(w, "log moveLogMedShort 0 15 med NC: [player] failed [check]");
|
||||
w(w, "log moveLogHighShort 0 15 high NC: [player] failed [check]");
|
||||
w(w, "");
|
||||
w(w, "# Gives a log message of the violation, only containing name, violation type and total violation value, at most once every second, only if more than 5 violations happened within the last minute (low) and immediatly (med,high)");
|
||||
w(w, "log morepacketsLow 5 1 low NC: [player] failed [check]: Sent [packets] more packets than expected. Total violation level [violations].");
|
||||
w(w, "log morepacketsMed 0 1 med NC: [player] failed [check]: Sent [packets] more packets than expected. Total violation level [violations].");
|
||||
w(w, "log morepacketsHigh 0 1 high NC: [player] failed [check]: Sent [packets] more packets than expected. Total violation level [violations].");
|
||||
w(w, "");
|
||||
w(w, "# Gives a lengthy log message of the violation, containing name, location, violation type and total violation, at most once every 15 seconds, only if more than 3 violations happened within the last minute (low) and immediatly (med,high)");
|
||||
w(w, "log moveLogLowLong 3 15 low NC: [player] in [world] at [location] moving to [locationto] over distance [distance] failed check [check]. Total violation level so far [violations].");
|
||||
w(w, "log moveLogMedLong 0 15 med NC: [player] in [world] at [location] moving to [locationto] over distance [distance] failed check [check]. Total violation level so far [violations].");
|
||||
w(w, "log moveLogHighLong 0 15 high NC: [player] in [world] at [location] moving to [locationto] over distance [distance] failed check [check]. Total violation level so far [violations].");
|
||||
w(w, "");
|
||||
w(w, "# Some other log messages that are limited a bit by default, to avoid too extreme spam");
|
||||
w(w, "log noclipLog 0 1 high NC: [player] failed [check]: at [location] to [locationto].");
|
||||
w(w, "log reachLog 0 1 med NC: [player] failed [check]: tried to interact with a block over distance [distance].");
|
||||
w(w, "log directionLog 2 1 med NC: [player] failed [check]: tried to destroy a block out of line of sight.");
|
||||
w(w, "log durabilityLog 0 1 med NC: [player] failed [check]: tried to use infinity durability hack.");
|
||||
w(w, "log onliquidLog 2 1 med NC: [player] failed [check]: tried to place a [blocktype] block at [placelocation] against block at [placeagainst].");
|
||||
w(w, "log spamLog 0 4 med NC: [player] failed [check]: Last sent message \"[text]\".");
|
||||
w(w, "log nofallLog 0 1 med NC: [player] failed [check]: tried to avoid fall damage for ~[distance] blocks.");
|
||||
w(w, "");
|
||||
w(w, "# SPECIAL Actions: They will do something check dependant, usually cancel an event.");
|
||||
w(w, "# - They start with the word 'special'");
|
||||
w(w, "# - Then comes their name. That name is used in the config file to identify them");
|
||||
w(w, "# - Then comes the 'delay', that is how often has this action to be called before it really gets executed");
|
||||
w(w, "# - Then comes the 'repeat', that is how many seconds have to be between two executions of the action");
|
||||
w(w, "# - Then come further instructions, if necessary");
|
||||
w(w, "");
|
||||
w(w, "# Cancels the event in case of an violation. Always. No delay. These are equivalent. The different names are just for better readability");
|
||||
w(w, "special moveCancel 0 0");
|
||||
w(w, "special blockbreakCancel 0 0");
|
||||
w(w, "special blockplaceCancel 0 0");
|
||||
w(w, "special interactCancel 0 0");
|
||||
w(w, "special spamCancel 0 0");
|
||||
w(w, "special nofallDamage 0 0");
|
||||
w(w, "");
|
||||
w(w, "# CONSOLECOMMAND Actions: They will execute a command as if it were typed into the console.");
|
||||
w(w, "# - They start with the word 'consolecommand'");
|
||||
w(w, "# - Then comes their name. That name is used in the config file to identify them");
|
||||
w(w, "# - Then comes the 'delay', that is how often has this action to be called before it really gets executed");
|
||||
w(w, "# - Then comes the 'repeat', that is how many seconds have to be between two executions of the action");
|
||||
w(w, "# - Then comes the command. You can use the same [ ] that you use for log actions. You'll most likely want to use [player] at some point.");
|
||||
w(w, "");
|
||||
w(w, "# E.g. Kick a player");
|
||||
w(w, "consolecommand kick 0 0 kick [player]");
|
||||
w.flush();
|
||||
w.close();
|
||||
} catch(IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void w(BufferedWriter writer, String text) throws IOException {
|
||||
writer.write(text);
|
||||
writer.newLine();
|
||||
}
|
||||
|
||||
}
|
@ -1,103 +0,0 @@
|
||||
package cc.co.evenprime.bukkit.nocheat;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Textual explainations of options, will be displayed in the gui tool and the
|
||||
* descriptions.txt file.
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public class Explainations {
|
||||
|
||||
private static final Map<String, String> explainations = new HashMap<String, String>();
|
||||
|
||||
static {
|
||||
|
||||
set("logging.active", "Should NoCheat related messages get logged at all. Some messages may still appear, e.g. error\n messages, even if this option is deactivated");
|
||||
|
||||
set("logging.filename", "Where logs that go to the logfile are stored. You can have different files for different worlds.");
|
||||
set("logging.filelevel", "What log-level need messages to have to get stored in the logfile. Values are:\n low: all messages\n med: med and high messages only\n high: high messages only\n off: no messages at all.");
|
||||
set("logging.consolelevel", "What log-level need messages to have to get displayed in your server console. Values are:\n low: all messages\n med: med and high messages only\n high: high messages only\n off: no messages at all.");
|
||||
set("logging.chatlevel", "What log-level need messages to have to get displayed in the ingame chat. Values are:\n low: all messages\n med: med and high messages only\n high: high messages only\n off: no messages at all.");
|
||||
|
||||
set("debug.showactivechecks", "Print to the console an overview of all checks that are enabled when NoCheat gets loaded.");
|
||||
|
||||
set("moving.check", "If true, do various checks on PlayerMove events.");
|
||||
set("moving.identifycreativemode", "If true, NoCheat will automatically identify if players are in creative mode and will allow them to fly, avoid fall damage etc.");
|
||||
|
||||
set("moving.runfly.check", "If true, check if a player is walking/sprinting/sneaking/swimming too fast/high.");
|
||||
set("moving.runfly.walkingspeedlimit", "Set the speed limit for moving horizontal under 'normal' conditions.\nUnit is 1/100 of a block, default is 22.");
|
||||
set("moving.runfly.sprintingspeedlimit", "Set the speed limit for moving horizontal while sprinting.\nUnit is 1/100 of a block, default is 40.");
|
||||
set("moving.runfly.jumpheight", "Set how high a player is allowed to jump.\nUnit is 1/100 of a block, default is 135.");
|
||||
set("moving.runfly.checkswimming", "Use a seperate speed limit for swimming players.");
|
||||
set("moving.runfly.swimmingspeedlimit", "Set the speed limit for moving horizontal while in water.\nUnit is 1/100 of a block, default is 18");
|
||||
set("moving.runfly.checksneaking", "Use a seperate speed limit for sneaking players.");
|
||||
set("moving.runfly.sneakingspeedlimit", "Set the speed limit for moving horizontal while sneaking.\nUnit is 1/100 of a block, default is 14");
|
||||
set("moving.runfly.actions", "What should be done if a player moves faster than the speed limit(s) or jumps higher than allowed.\nUnits are in 1/100 of a block above the limit.");
|
||||
|
||||
set("moving.runfly.checknofall", "If true, check if a player is avoiding fall damage by using a nofall hack. EXPERIMENTAL! Feedback is appreciated.");
|
||||
set("moving.runfly.nofallmultiplier", "How many percent falldamage should be dealt to the player.\nNoCheat will almost always underestimate fall damage, using a value bigger than 100 is advised.\nUnit is percent of the estimated original fall damage, default is 200.");
|
||||
set("moving.runfly.nofallactions", "What should be done if a player is detected as avoiding fall damage.\nUnit is number of blocks the player fell down.");
|
||||
|
||||
set("moving.runfly.allowlimitedflying", "If true, instead of doing the above checks for walking/sprinting/swimming/sneaking,\nallow flying and only limit the flying speed.");
|
||||
set("moving.runfly.flyingspeedlimitvertical", "Set the speed limit for moving vertical while flying.\nUnit is 1/100 of a block, default is 100.");
|
||||
set("moving.runfly.flyingspeedlimithorizontal", "Set the speed limit for moving horizontal while flying.\nUnit is 1/100 of a block, default is 60.");
|
||||
set("moving.runfly.flyingactions", "What should be done if a player flies faster than the speed limit(s). \nUnits are in 1/100 of a block above the speedlimit.");
|
||||
|
||||
|
||||
set("moving.morepackets.check", "If true, check if a player is sending too many 'move-packets' per second. In a normal game, the player won't send more than 22 packets per second.");
|
||||
set("moving.morepackets.actions", "What should be done if a player sends more 'move-packets' than normal.\nUnits are packets per second above the limit.");
|
||||
|
||||
set("moving.noclip.check", "If true, check if a player is moving into a solid wall. EXPERIMENTAL! DOESN'T WORK RELIABLY! USE WITH CAUTION AND ONLY FOR NOTIFICATIONS!");
|
||||
set("moving.noclip.actions", "What should be done if a player moves into a wall.\nUnit is number of walls a player walks into/through.");
|
||||
|
||||
set("blockbreak.check", "If true, do various checks on BlockBreak events.");
|
||||
|
||||
set("blockbreak.reach.check", "If true, check if a player is breaking blocks that are too far away.");
|
||||
set("blockbreak.reach.reachlimit", "Set the distance limit for breaking blocks.\nUnit is 1/100 of a block, default is 485");
|
||||
set("blockbreak.reach.actions", "What should be done if a player is breaking blocks that are too far away.\nUnit is number of break(attempt)s beyond the limit.");
|
||||
|
||||
set("blockbreak.direction.check", "If true, check if a player is looking at the block that he's breaking.");
|
||||
set("blockbreak.direction.checkinstabreakblocks", "If true, NoCheat will also check for direction for Instant-Breaking blocks.\nTHIS WILL CAUSE FALSE POSITIVES, when a player keeps his mouse button pressed and moves the mouse fast over the screen.");
|
||||
set("blockbreak.direction.actions", "What should be done if a player is breaking blocks that are not in his line of sight.\nUnit is number of break(attempt)s outside the line of sight.");
|
||||
|
||||
set("blockplace.check", "If true, do various checks on BlockPlace events.");
|
||||
|
||||
set("blockplace.reach.check", "If true, check if a player is placing blocks at locations too far away.");
|
||||
set("blockplace.reach.reachlimit", "Set the distance limit for placing blocks.\nUnit is 1/100 of a block, default is 485");
|
||||
set("blockplace.reach.actions", "What should be done if a player is placing blocks that are too far away.\nUnit is number of place(attempt)s beyond the limit.");
|
||||
|
||||
set("blockplace.onliquid.check", "If true, check if a player is trying to place non-liquid blocks against liquid blocks\nIn a normal Minecraft game, it is impossible to place a block without it touching something that is considered solid (neither air nor a liquid).\nBut if people use a modified client, to can do that. This check tries to identify that trick.");
|
||||
set("blockplace.onliquid.actions", "What should be done if a player is is trying to place non-liquid blocks against liquid blocks.\nUnit is number of place(attempt)s.");
|
||||
|
||||
set("interact.check", "If true, do various checks on PlayerInteract events.");
|
||||
|
||||
set("interact.durability.check", "If true, check if a player is using a hack that provides infinite durability items.");
|
||||
set("interact.durability.actions", "What should be done if a player is trying to use the hack.\nUnit is number of uses or attempts to use the hack.");
|
||||
|
||||
set("chat.check", "If true, do various checks on PlayerChat events.");
|
||||
|
||||
set("chat.spam.check", "If true, check if a player is spamming the chat.");
|
||||
set("chat.spam.timeframe", "Over what timeframe (in seconds) should the messages be counted?\nWhen the time is over, counting starts at 0 again.");
|
||||
set("chat.spam.limit", "How many messages per timeframe may the player send without it counting as spamming?");
|
||||
set("chat.spam.actions", "What should be done if a player is trying to spam the chat.\nUnit is number of chat messages above the limit you declared above.");
|
||||
|
||||
}
|
||||
|
||||
private static void set(String id, String text) {
|
||||
explainations.put(id, text);
|
||||
}
|
||||
|
||||
public static String get(String id) {
|
||||
String result = explainations.get(id);
|
||||
|
||||
if(result == null) {
|
||||
result = "No description available";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
@ -14,6 +14,7 @@ import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.ActionManager;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.ConfigurationManager;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.Permissions;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.cache.ConfigurationCache;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.DataManager;
|
||||
|
||||
@ -21,7 +22,6 @@ import cc.co.evenprime.bukkit.nocheat.events.BlockPlaceEventManager;
|
||||
import cc.co.evenprime.bukkit.nocheat.events.BlockBreakEventManager;
|
||||
import cc.co.evenprime.bukkit.nocheat.events.EventManager;
|
||||
import cc.co.evenprime.bukkit.nocheat.events.PlayerChatEventManager;
|
||||
import cc.co.evenprime.bukkit.nocheat.events.PlayerItemDropEventManager;
|
||||
import cc.co.evenprime.bukkit.nocheat.events.PlayerInteractEventManager;
|
||||
import cc.co.evenprime.bukkit.nocheat.events.PlayerMoveEventManager;
|
||||
import cc.co.evenprime.bukkit.nocheat.events.PlayerTeleportEventManager;
|
||||
@ -42,6 +42,7 @@ public class NoCheat extends JavaPlugin {
|
||||
private ConfigurationManager conf;
|
||||
private LogManager log;
|
||||
private DataManager data;
|
||||
private ActionManager action;
|
||||
|
||||
private List<EventManager> eventManagers = new LinkedList<EventManager>();
|
||||
|
||||
@ -51,8 +52,6 @@ public class NoCheat extends JavaPlugin {
|
||||
private long lastIngamesecondDuration = 0L;
|
||||
private boolean skipCheck = false;
|
||||
|
||||
private ActionManager action;
|
||||
|
||||
public NoCheat() {
|
||||
|
||||
}
|
||||
@ -76,18 +75,16 @@ public class NoCheat extends JavaPlugin {
|
||||
// First set up logging
|
||||
this.log = new LogManager(this);
|
||||
|
||||
log.logToConsole(LogLevel.LOW, "[NoCheat] This version is for CB #1185. It may break at any time and for any other version.");
|
||||
log.logToConsole(LogLevel.LOW, "[NoCheat] This version is for CB #1240. It may break at any time and for any other version.");
|
||||
|
||||
this.data = new DataManager();
|
||||
|
||||
this.action = new ActionManager(log);
|
||||
this.action = new ActionManager();
|
||||
|
||||
// parse the nocheat.yml config file
|
||||
this.conf = new ConfigurationManager(this.getDataFolder().getPath(), action);
|
||||
|
||||
eventManagers.add(new PlayerMoveEventManager(this));
|
||||
eventManagers.add(new PlayerTeleportEventManager(this));
|
||||
eventManagers.add(new PlayerItemDropEventManager(this));
|
||||
eventManagers.add(new PlayerInteractEventManager(this));
|
||||
eventManagers.add(new PlayerChatEventManager(this));
|
||||
eventManagers.add(new BlockBreakEventManager(this));
|
||||
@ -197,6 +194,12 @@ public class NoCheat extends JavaPlugin {
|
||||
if(command.getName().equalsIgnoreCase("nocheat") && args.length > 0) {
|
||||
if(args[0].equalsIgnoreCase("permlist") && args.length >= 2) {
|
||||
// permlist command was used CORRECTLY
|
||||
|
||||
// Does the sender have permission?
|
||||
if(sender instanceof Player && !sender.hasPermission(Permissions.ADMIN_PERMLIST)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the player names
|
||||
Player player = this.getServer().getPlayerExact(args[1]);
|
||||
if(player == null) {
|
||||
@ -219,6 +222,16 @@ public class NoCheat extends JavaPlugin {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} else if(args[0].equalsIgnoreCase("reload")) {
|
||||
// reload command was used
|
||||
|
||||
// Does the sender have permission?
|
||||
if(sender instanceof Player && !sender.hasPermission(Permissions.ADMIN_RELOAD)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.conf.cleanup();
|
||||
this.conf = new ConfigurationManager(this.getDataFolder().getPath(), this.action);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -1,19 +1,77 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.actions;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.NoCheat;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.history.ActionHistory;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.types.Action;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.types.ConsolecommandAction;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.types.LogAction;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.types.SpecialAction;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.cache.ConfigurationCache;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.LogData;
|
||||
|
||||
/**
|
||||
* An ActionExecutor does exactly that, executing actions.
|
||||
* Will trace the history of action executions to decide if an action 'really'
|
||||
* gets executed.
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public interface ActionExecutor {
|
||||
public class ActionExecutor {
|
||||
|
||||
public abstract boolean executeActions(Player player, ActionList actions, int violationLevel, HashMap<String, String> hashMap, ConfigurationCache cc);
|
||||
private final Map<Player, ActionHistory> actionHistory = new HashMap<Player, ActionHistory>();
|
||||
private final NoCheat plugin;
|
||||
|
||||
private final ConsoleCommandSender ccsender;
|
||||
|
||||
public ActionExecutor(NoCheat plugin) {
|
||||
this.plugin = plugin;
|
||||
this.ccsender = new ConsoleCommandSender(plugin.getServer());
|
||||
}
|
||||
|
||||
public boolean executeActions(Player player, ActionList actions, int violationLevel, LogData data, ConfigurationCache cc) {
|
||||
|
||||
boolean special = false;
|
||||
|
||||
// Always set this here "by hand"
|
||||
data.violationLevel = violationLevel;
|
||||
|
||||
long time = System.currentTimeMillis() / 1000;
|
||||
|
||||
for(Action ac : actions.getActions(violationLevel)) {
|
||||
|
||||
if(getHistory(player).executeAction(ac, time)) {
|
||||
if(ac instanceof LogAction) {
|
||||
LogAction l = (LogAction) ac;
|
||||
plugin.getLogManager().log(l.level, l.getMessage(data), cc);
|
||||
} else if(ac instanceof SpecialAction) {
|
||||
special = true;
|
||||
} else if(ac instanceof ConsolecommandAction) {
|
||||
executeConsoleCommand(((ConsolecommandAction) ac).getCommand(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return special;
|
||||
}
|
||||
|
||||
private ActionHistory getHistory(Player player) {
|
||||
|
||||
ActionHistory history = actionHistory.get(player);
|
||||
|
||||
if(history == null) {
|
||||
history = new ActionHistory();
|
||||
actionHistory.put(player, history);
|
||||
}
|
||||
|
||||
return history;
|
||||
}
|
||||
|
||||
private void executeConsoleCommand(String command) {
|
||||
ccsender.executeConsoleCommand(command);
|
||||
}
|
||||
}
|
||||
|
@ -1,112 +0,0 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.actions;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.NoCheat;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.history.ActionHistory;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.types.Action;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.types.ConsolecommandAction;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.types.LogAction;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.types.SpecialAction;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.cache.ConfigurationCache;
|
||||
import cc.co.evenprime.bukkit.nocheat.log.LogLevel;
|
||||
import cc.co.evenprime.bukkit.nocheat.log.LogManager;
|
||||
|
||||
/**
|
||||
* Implementation of ActionExecutor, that will trace the history of action
|
||||
* executions to decide if an action 'really' gets executed.
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public class ActionExecutorWithHistory implements ActionExecutor {
|
||||
|
||||
private final Map<Player, ActionHistory> actionHistory = new HashMap<Player, ActionHistory>();
|
||||
private final ActionManager actionManager;
|
||||
private final LogManager log;
|
||||
|
||||
private final ConsoleCommandSender ccsender;
|
||||
|
||||
public ActionExecutorWithHistory(NoCheat plugin) {
|
||||
this.actionManager = plugin.getActionManager();
|
||||
this.log = plugin.getLogManager();
|
||||
this.ccsender = new ConsoleCommandSender(plugin.getServer());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* cc.co.evenprime.bukkit.nocheat.actions.ActionExecutor#executeActions(
|
||||
* org.bukkit.entity.Player,
|
||||
* cc.co.evenprime.bukkit.nocheat.actions.ActionList, double,
|
||||
* java.util.HashMap,
|
||||
* cc.co.evenprime.bukkit.nocheat.config.cache.ConfigurationCache)
|
||||
*/
|
||||
@Override
|
||||
public boolean executeActions(Player player, ActionList actions, int violationLevel, HashMap<String, String> hashMap, ConfigurationCache cc) {
|
||||
|
||||
boolean special = false;
|
||||
|
||||
for(String a : actions.getActions(violationLevel)) {
|
||||
Action ac = actionManager.getActionByName(a);
|
||||
|
||||
Map<String, String> map = null;
|
||||
if(ac != null) {
|
||||
if(getHistory(player).executeAction(ac, System.currentTimeMillis())) {
|
||||
if(ac instanceof LogAction) {
|
||||
if(map == null)
|
||||
map = generateHashMap(player, violationLevel, hashMap);
|
||||
LogAction l = (LogAction) ac;
|
||||
log.log(l.level, l.getLogMessage(map), cc);
|
||||
} else if(ac instanceof SpecialAction) {
|
||||
special = true;
|
||||
} else if(ac instanceof ConsolecommandAction) {
|
||||
if(map == null)
|
||||
map = generateHashMap(player, violationLevel, hashMap);
|
||||
executeConsoleCommand(((ConsolecommandAction) ac).getCommand(map));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log.logToConsole(LogLevel.HIGH, "NoCheat: Couldn't find action " + a + ". You need to define it properly to use it in your config file!");
|
||||
}
|
||||
}
|
||||
|
||||
return special;
|
||||
}
|
||||
|
||||
private HashMap<String, String> generateHashMap(Player player, double violationLevel, HashMap<String, String> map) {
|
||||
HashMap<String, String> newMap = new HashMap<String, String>();
|
||||
|
||||
newMap.put(LogAction.PLAYER, player.getName());
|
||||
Location l = player.getLocation();
|
||||
newMap.put(LogAction.LOCATION, String.format(Locale.US, "%.2f,%.2f,%.2f", l.getX(), l.getY(), l.getZ()));
|
||||
newMap.put(LogAction.WORLD, player.getWorld().getName());
|
||||
newMap.put(LogAction.VIOLATIONS, String.format(Locale.US, "%.2f", violationLevel));
|
||||
|
||||
newMap.putAll(map);
|
||||
|
||||
return newMap;
|
||||
}
|
||||
|
||||
private ActionHistory getHistory(Player player) {
|
||||
|
||||
ActionHistory history = actionHistory.get(player);
|
||||
|
||||
if(history == null) {
|
||||
history = new ActionHistory();
|
||||
actionHistory.put(player, history);
|
||||
}
|
||||
|
||||
return history;
|
||||
}
|
||||
|
||||
private void executeConsoleCommand(String command) {
|
||||
ccsender.executeConsoleCommand(command);
|
||||
}
|
||||
}
|
@ -2,7 +2,11 @@ package cc.co.evenprime.bukkit.nocheat.actions;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.types.Action;
|
||||
|
||||
/**
|
||||
* A list of actions, that associates actions and a treshold. It allows to
|
||||
@ -14,35 +18,11 @@ import java.util.List;
|
||||
public class ActionList {
|
||||
|
||||
public ActionList() {}
|
||||
|
||||
private final static Action[] emptyArray = new Action[0];
|
||||
|
||||
private final List<ActionListEntry> actionList = new ArrayList<ActionListEntry>();
|
||||
|
||||
private class ActionListEntry implements Comparable<ActionListEntry> {
|
||||
|
||||
public final ArrayList<String> actions = new ArrayList<String>();
|
||||
public final double treshold;
|
||||
|
||||
public ActionListEntry(double treshold, String[] actionNames) {
|
||||
|
||||
this.treshold = treshold;
|
||||
|
||||
for(String actionName : actionNames) {
|
||||
if(actionName != null && actionName.length() > 0) {
|
||||
actions.add(actionName.toLowerCase());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ActionListEntry entry) {
|
||||
if(treshold < entry.treshold) {
|
||||
return -1;
|
||||
} else if(treshold == entry.treshold) {
|
||||
return 0;
|
||||
} else
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
private final Map<Integer, Action[]> actions = new HashMap<Integer, Action[]>();
|
||||
private final List<Integer> tresholds = new ArrayList<Integer>();
|
||||
|
||||
/**
|
||||
* Add an entry to this actionList. The list will be sorted by tresholds
|
||||
@ -51,9 +31,14 @@ public class ActionList {
|
||||
* @param treshold
|
||||
* @param actionNames
|
||||
*/
|
||||
public void addEntry(double treshold, String[] actionNames) {
|
||||
this.actionList.add(new ActionListEntry(treshold, actionNames));
|
||||
Collections.sort(this.actionList);
|
||||
public void setActions(Integer treshold, Action[] actions) {
|
||||
|
||||
if(!this.tresholds.contains(treshold)) {
|
||||
this.tresholds.add(treshold);
|
||||
Collections.sort(this.tresholds);
|
||||
}
|
||||
|
||||
this.actions.put(treshold, actions);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -64,19 +49,23 @@ public class ActionList {
|
||||
* @param violationLevel
|
||||
* @return
|
||||
*/
|
||||
public List<String> getActions(int vl) {
|
||||
public Action[] getActions(Integer vl) {
|
||||
|
||||
ActionListEntry result = null;
|
||||
|
||||
for(ActionListEntry entry : actionList) {
|
||||
if(entry.treshold <= vl) {
|
||||
result = entry;
|
||||
Integer result = null;
|
||||
|
||||
for(Integer treshold : tresholds) {
|
||||
if(treshold <= vl) {
|
||||
result = treshold;
|
||||
}
|
||||
}
|
||||
|
||||
if(result != null)
|
||||
return result.actions;
|
||||
return actions.get(result);
|
||||
else
|
||||
return Collections.emptyList();
|
||||
return emptyArray;
|
||||
}
|
||||
|
||||
public List<Integer> getTresholds() {
|
||||
return tresholds;
|
||||
}
|
||||
}
|
||||
|
@ -4,123 +4,36 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.types.Action;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.types.SpecialAction;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.types.ConsolecommandAction;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.types.LogAction;
|
||||
import cc.co.evenprime.bukkit.nocheat.log.LogLevel;
|
||||
import cc.co.evenprime.bukkit.nocheat.log.LogManager;
|
||||
|
||||
/**
|
||||
* The ActionManager creates the specific actions and stores them with their
|
||||
* unique name.
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public class ActionManager {
|
||||
|
||||
private final Map<String, Action> actionIdsToActionMap = new HashMap<String, Action>();
|
||||
private final Map<String, Action> actions;
|
||||
|
||||
private final LogManager log;
|
||||
|
||||
private final String[] knownTypes = {"log", "consolecommand", "special"};
|
||||
|
||||
public ActionManager(LogManager log) {
|
||||
this.log = log;
|
||||
public ActionManager() {
|
||||
this.actions = new HashMap<String, Action>();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param name
|
||||
* To identify the action by a name. Same name means same action
|
||||
*
|
||||
* @param actionId
|
||||
* Actual string describing the action (may be more than a string
|
||||
* in future)
|
||||
* @return
|
||||
*/
|
||||
public void createActionFromStrings(String type, String actionId, String stringDelay, String stringRepeat, String theRest) {
|
||||
public void addAction(Action action) {
|
||||
|
||||
this.actions.put(action.name.toLowerCase(), action);
|
||||
}
|
||||
|
||||
Action action = null;
|
||||
public Action getAction(String actionName) {
|
||||
|
||||
type = type.toLowerCase();
|
||||
actionId = actionId.toLowerCase();
|
||||
return this.actions.get(actionName.toLowerCase());
|
||||
}
|
||||
|
||||
int delay;
|
||||
try {
|
||||
delay = Integer.parseInt(stringDelay);
|
||||
} catch(NumberFormatException e) {
|
||||
log.logToConsole(LogLevel.HIGH, "Can't parse action: \"" + actionId + "\", first parameter " + stringDelay + " not a number");
|
||||
return;
|
||||
public Action[] getActions(String[] actionNames) {
|
||||
Action[] result = new Action[actionNames.length];
|
||||
|
||||
for(int i = 0; i < actionNames.length; i++) {
|
||||
result[i] = getAction(actionNames[i]);
|
||||
}
|
||||
|
||||
int repeat;
|
||||
try {
|
||||
repeat = Integer.parseInt(stringRepeat);
|
||||
} catch(NumberFormatException e) {
|
||||
log.logToConsole(LogLevel.HIGH, "Can't parse action: \"" + actionId + "\", second parameter " + stringRepeat + " not a number");
|
||||
return;
|
||||
}
|
||||
|
||||
// Log actions have the form delay|repeat|level|message
|
||||
if(type.equals("log")) {
|
||||
|
||||
String[] pieces = null;
|
||||
|
||||
if(theRest != null) {
|
||||
pieces = theRest.split("\\s+", 2);
|
||||
if(pieces == null || pieces.length < 2) {
|
||||
log.logToConsole(LogLevel.HIGH, "Can't parse log action: \"" + actionId + "\", missing parameters");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
action = createLogActionFromString(delay, repeat, pieces[0], pieces[1]);
|
||||
} else if(type.equals("special")) {
|
||||
action = createCancelActionFromString(delay, repeat);
|
||||
} else if(type.equals("consolecommand")) {
|
||||
if(theRest == null) {
|
||||
log.logToConsole(LogLevel.HIGH, "Can't parse consolecommand action: \"" + actionId + "\", missing parameter");
|
||||
return;
|
||||
}
|
||||
action = createConsolecommandActionFromString(delay, repeat, theRest);
|
||||
} else {
|
||||
log.logToConsole(LogLevel.HIGH, "Can't parse action: \"" + actionId + "\", unknown action type");
|
||||
return;
|
||||
}
|
||||
|
||||
if(action != null) {
|
||||
this.actionIdsToActionMap.put(actionId, action);
|
||||
}
|
||||
}
|
||||
|
||||
public String[] getKnownTypes() {
|
||||
return knownTypes;
|
||||
}
|
||||
|
||||
private ConsolecommandAction createConsolecommandActionFromString(int delay, int repeat, String command) {
|
||||
|
||||
return new ConsolecommandAction(delay, repeat, command);
|
||||
}
|
||||
|
||||
private SpecialAction createCancelActionFromString(int delay, int repeat) {
|
||||
|
||||
return new SpecialAction(delay, repeat);
|
||||
|
||||
}
|
||||
|
||||
private Action createLogActionFromString(int delay, int repeat, String logLevel, String message) {
|
||||
|
||||
LogLevel level = LogLevel.getLogLevelFromString(logLevel);
|
||||
|
||||
if(level.equals(LogLevel.OFF)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new LogAction(delay, repeat, level, message);
|
||||
}
|
||||
|
||||
public Action getActionByName(String name) {
|
||||
return actionIdsToActionMap.get(name.toLowerCase());
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,12 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.actions.history;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.types.Action;
|
||||
|
||||
/**
|
||||
* Store last 60 seconds of action executions
|
||||
* Store amount of action executions for last 60 seconds
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
@ -16,25 +15,61 @@ public class ActionHistory {
|
||||
|
||||
private class ExecutionHistoryEntry {
|
||||
|
||||
private final LinkedList<Long> executionTimes = new LinkedList<Long>();
|
||||
private final long monitoredTimeFrame = 60000;
|
||||
private long lastExecution = 0;
|
||||
private final int executionTimes[];
|
||||
private long lastExecution = 0;
|
||||
private int totalEntries = 0;
|
||||
private long lastClearedTime = 0;
|
||||
|
||||
public ExecutionHistoryEntry() {}
|
||||
public ExecutionHistoryEntry(int monitoredTimeFrame) {
|
||||
this.executionTimes = new int[monitoredTimeFrame];
|
||||
}
|
||||
|
||||
public void addCounter(Long time) {
|
||||
/**
|
||||
* Remember an execution at the specific time
|
||||
*/
|
||||
public void addCounter(long time) {
|
||||
// clear out now outdated values from the array
|
||||
if(time - lastClearedTime > 0) {
|
||||
// Clear the next few fields of the array
|
||||
clearTimes(lastClearedTime + 1, time - lastClearedTime);
|
||||
lastClearedTime = time + 1;
|
||||
}
|
||||
|
||||
executionTimes[(int) (time % executionTimes.length)]++;
|
||||
totalEntries++;
|
||||
}
|
||||
|
||||
synchronized(executionTimes) {
|
||||
while(!executionTimes.isEmpty() && executionTimes.getFirst() < time - monitoredTimeFrame) {
|
||||
executionTimes.removeFirst();
|
||||
/**
|
||||
* Clean parts of the array
|
||||
*
|
||||
* @param start
|
||||
* @param length
|
||||
*/
|
||||
private void clearTimes(long start, long length) {
|
||||
|
||||
if(length <= 0) {
|
||||
return; // nothing to do (yet)
|
||||
}
|
||||
if(length > executionTimes.length) {
|
||||
length = executionTimes.length;
|
||||
}
|
||||
|
||||
int j = (int) start % executionTimes.length;
|
||||
|
||||
for(int i = 0; i < length; i++) {
|
||||
if(j == executionTimes.length) {
|
||||
j = 0;
|
||||
}
|
||||
|
||||
totalEntries -= executionTimes[j];
|
||||
executionTimes[j] = 0;
|
||||
|
||||
executionTimes.addLast(time);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
public int getCounter() {
|
||||
return executionTimes.size();
|
||||
return totalEntries;
|
||||
}
|
||||
|
||||
public long getLastExecution() {
|
||||
@ -55,11 +90,12 @@ public class ActionHistory {
|
||||
/**
|
||||
* Returns true, if the action should be executed, because all time
|
||||
* criteria have been met. Will add a entry with the time to a list
|
||||
* which will influence further requests, so only use once per
|
||||
* check!
|
||||
* which will influence further requests, so only use once and remember
|
||||
* the result
|
||||
*
|
||||
* @param action
|
||||
* @param time
|
||||
* a time IN SECONDS
|
||||
* @return
|
||||
*/
|
||||
public boolean executeAction(Action action, long time) {
|
||||
@ -67,7 +103,7 @@ public class ActionHistory {
|
||||
ExecutionHistoryEntry entry = executionHistory.get(action);
|
||||
|
||||
if(entry == null) {
|
||||
entry = new ExecutionHistoryEntry();
|
||||
entry = new ExecutionHistoryEntry(60);
|
||||
executionHistory.put(action, entry);
|
||||
}
|
||||
|
||||
@ -75,8 +111,8 @@ public class ActionHistory {
|
||||
entry.addCounter(time);
|
||||
|
||||
if(entry.getCounter() > action.delay) {
|
||||
// Execute action?
|
||||
if(entry.getLastExecution() <= time - action.repeat * 1000) {
|
||||
// Execute action?
|
||||
if(entry.getLastExecution() <= time - action.repeat) {
|
||||
// Execute action!
|
||||
entry.setLastExecution(time);
|
||||
return true;
|
||||
|
@ -14,15 +14,17 @@ public abstract class Action {
|
||||
* Delay in violations (only do if there were more than "delay" exceptions
|
||||
* in last 60 seconds)
|
||||
*/
|
||||
public final int delay;
|
||||
public final int delay;
|
||||
|
||||
/**
|
||||
* Repeat only every "repeat" seconds
|
||||
*/
|
||||
public final int repeat;
|
||||
public final int repeat;
|
||||
|
||||
public Action(int delay, int repeat) {
|
||||
public final String name;
|
||||
|
||||
public Action(String name, int delay, int repeat) {
|
||||
this.name = name;
|
||||
this.delay = delay;
|
||||
this.repeat = repeat;
|
||||
}
|
||||
|
@ -0,0 +1,164 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.actions.types;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.data.LogData;
|
||||
|
||||
public abstract class ActionWithParameters extends Action {
|
||||
|
||||
protected enum WildCard {
|
||||
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");
|
||||
|
||||
private final String s;
|
||||
|
||||
private WildCard(String s) {
|
||||
this.s = s;
|
||||
}
|
||||
|
||||
private static final WildCard get(String s) {
|
||||
for(WildCard c : WildCard.values()) {
|
||||
if(c.s.equals(s)) {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected final ArrayList<Object> messageParts;
|
||||
|
||||
public ActionWithParameters(String name, int delay, int repeat, String message) {
|
||||
super(name, delay, repeat);
|
||||
|
||||
messageParts = new ArrayList<Object>();
|
||||
|
||||
parseMessage(message);
|
||||
}
|
||||
|
||||
protected void parseMessage(String message) {
|
||||
String parts[] = message.split("\\[", 2);
|
||||
|
||||
// No opening braces left
|
||||
if(parts.length != 2) {
|
||||
messageParts.add(message);
|
||||
}
|
||||
// Found an opening brace
|
||||
else {
|
||||
String parts2[] = parts[1].split("\\]", 2);
|
||||
|
||||
// Found no matching closing brace
|
||||
if(parts2.length != 2) {
|
||||
messageParts.add(message);
|
||||
}
|
||||
// Found a matching closing brace
|
||||
else {
|
||||
WildCard w = WildCard.get(parts2[0]);
|
||||
|
||||
if(w != null) {
|
||||
// Found an existing wildcard inbetween the braces
|
||||
messageParts.add(parts[0]);
|
||||
messageParts.add(w);
|
||||
|
||||
// Go further down recursive
|
||||
parseMessage(parts2[1]);
|
||||
} else {
|
||||
messageParts.add(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a log message with all the wildcards replaced with data from LogData
|
||||
*
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
public String getMessage(LogData data) {
|
||||
StringBuilder log = new StringBuilder(100); // Should be big enough most
|
||||
// of the time
|
||||
|
||||
for(Object part : messageParts) {
|
||||
if(part instanceof String) {
|
||||
log.append((String) part);
|
||||
} else {
|
||||
log.append(getParameter((WildCard) part, data));
|
||||
}
|
||||
}
|
||||
|
||||
return log.toString();
|
||||
}
|
||||
|
||||
private String getParameter(WildCard wildcard, LogData data) {
|
||||
// The == is correct here, as these really are identical objects, not
|
||||
// only equal
|
||||
switch (wildcard) {
|
||||
case PLAYER:
|
||||
return data.player.getName();
|
||||
|
||||
case CHECK:
|
||||
return data.check;
|
||||
|
||||
case LOCATION:
|
||||
Location l = data.player.getLocation();
|
||||
return String.format(Locale.US, "%.2f,%.2f,%.2f", l.getX(), l.getY(), l.getZ());
|
||||
|
||||
case WORLD:
|
||||
return data.player.getWorld().getName();
|
||||
|
||||
case VIOLATIONS:
|
||||
return String.format(Locale.US, "%.2f", data.violationLevel);
|
||||
|
||||
case MOVEDISTANCE:
|
||||
Location l2 = data.player.getLocation();
|
||||
Location t = data.toLocation;
|
||||
if(t != null) {
|
||||
return String.format(Locale.US, "%.2f,%.2f,%.2f", t.getX() - l2.getX(), t.getY() - l2.getY(), t.getZ() - l2.getZ());
|
||||
} else {
|
||||
return "null";
|
||||
}
|
||||
case REACHDISTANCE:
|
||||
return String.format(Locale.US, "%.2f", data.reachdistance);
|
||||
|
||||
case FALLDISTANCE:
|
||||
return String.format(Locale.US, "%.2f", data.falldistance);
|
||||
|
||||
case LOCATION_TO:
|
||||
Location to = data.toLocation;
|
||||
return String.format(Locale.US, "%.2f,%.2f,%.2f", to.getX(), to.getY(), to.getZ());
|
||||
|
||||
case PACKETS:
|
||||
return String.valueOf(data.packets);
|
||||
|
||||
case TEXT:
|
||||
return data.text;
|
||||
|
||||
case PLACE_LOCATION:
|
||||
Block block = data.placed;
|
||||
if(block != null) {
|
||||
return String.format(Locale.US, "%d %d %d", block.getX(), block.getY(), block.getZ());
|
||||
} else {
|
||||
return "null";
|
||||
}
|
||||
|
||||
case PLACE_AGAINST:
|
||||
Block blocka = data.placedAgainst;
|
||||
if(blocka == null) {
|
||||
return "null";
|
||||
}
|
||||
return String.format(Locale.US, "%d %d %d", blocka.getX(), blocka.getY(), blocka.getZ());
|
||||
|
||||
case BLOCK_TYPE:
|
||||
return data.placedMaterial.toString();
|
||||
|
||||
default:
|
||||
return "Evenprime was lazy and forgot to define " + wildcard + ".";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.actions.types;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.LogData;
|
||||
|
||||
/**
|
||||
* Execute a command by imitating an admin typing the command directly into the
|
||||
@ -10,24 +9,15 @@ import java.util.Map.Entry;
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public class ConsolecommandAction extends Action {
|
||||
public class ConsolecommandAction extends ActionWithParameters {
|
||||
|
||||
private final String command;
|
||||
public ConsolecommandAction(String name, int delay, int repeat, String command) {
|
||||
super(name, delay, repeat, command);
|
||||
|
||||
public ConsolecommandAction(int delay, int repeat, String command) {
|
||||
super(delay, repeat);
|
||||
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
public String getCommand(Map<String, String> map) {
|
||||
public String getCommand(LogData ldata) {
|
||||
|
||||
String com = command;
|
||||
|
||||
for(Entry<String, String> entry : map.entrySet()) {
|
||||
com = com.replaceAll(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
return com;
|
||||
return super.getMessage(ldata);
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.actions.types;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.data.LogData;
|
||||
import cc.co.evenprime.bukkit.nocheat.log.LogLevel;
|
||||
|
||||
/**
|
||||
@ -11,43 +9,17 @@ import cc.co.evenprime.bukkit.nocheat.log.LogLevel;
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public class LogAction extends Action {
|
||||
public class LogAction extends ActionWithParameters {
|
||||
|
||||
// Default stuff
|
||||
public static final String PLAYER = "\\[player\\]";
|
||||
public static final String LOCATION = "\\[location\\]";
|
||||
public static final String WORLD = "\\[world\\]";
|
||||
public static final String VIOLATIONS = "\\[violations\\]";
|
||||
|
||||
// Event dependent stuff
|
||||
public static final String DISTANCE = "\\[distance\\]";
|
||||
public static final String LOCATION_TO = "\\[locationto\\]";
|
||||
public static final String CHECK = "\\[check\\]";
|
||||
public static final String PACKETS = "\\[packets\\]";
|
||||
public static final String TEXT = "\\[text\\]";
|
||||
|
||||
public static final String PLACE_LOCATION = "\\[placelocation\\]";
|
||||
public static final String PLACE_AGAINST = "\\[placeagainst\\]";
|
||||
public static final String BLOCK_TYPE = "\\[blocktype\\]";
|
||||
|
||||
public final LogLevel level;
|
||||
private final String message;
|
||||
|
||||
public LogAction(int delay, int repeat, LogLevel level, String message) {
|
||||
super(delay, repeat);
|
||||
public final LogLevel level;
|
||||
|
||||
public LogAction(String name, int delay, int repeat, LogLevel level, String message) {
|
||||
super(name, delay, repeat, message);
|
||||
|
||||
this.level = level;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getLogMessage(Map<String, String> values) {
|
||||
String log = message;
|
||||
|
||||
for(Entry<String, String> entry : values.entrySet()) {
|
||||
log = log.replaceAll(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
return log;
|
||||
|
||||
public String getMessage(LogData ldata) {
|
||||
return super.getMessage(ldata);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ package cc.co.evenprime.bukkit.nocheat.actions.types;
|
||||
*/
|
||||
public class SpecialAction extends Action {
|
||||
|
||||
public SpecialAction(int delay, int repeat) {
|
||||
super(delay, repeat);
|
||||
public SpecialAction(String name, int delay, int repeat) {
|
||||
super(name, delay, repeat);
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,12 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.checks.blockbreak;
|
||||
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.NoCheat;
|
||||
import cc.co.evenprime.bukkit.nocheat.Permissions;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.Permissions;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.cache.ConfigurationCache;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.BlockBreakData;
|
||||
|
||||
|
@ -1,17 +1,14 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.checks.blockbreak;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.NoCheat;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.ActionExecutor;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.ActionExecutorWithHistory;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.types.LogAction;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.cache.ConfigurationCache;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.BlockBreakData;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.LogData;
|
||||
|
||||
/**
|
||||
* The DirectionCheck will find out if a player tried to interact with something
|
||||
@ -23,9 +20,11 @@ import cc.co.evenprime.bukkit.nocheat.data.BlockBreakData;
|
||||
public class DirectionCheck {
|
||||
|
||||
private final ActionExecutor action;
|
||||
private final NoCheat plugin;
|
||||
|
||||
public DirectionCheck(NoCheat plugin) {
|
||||
this.action = new ActionExecutorWithHistory(plugin);
|
||||
this.plugin = plugin;
|
||||
this.action = new ActionExecutor(plugin);
|
||||
}
|
||||
|
||||
public boolean check(Player player, double factor, double x1, double y1, double z1, Block brokenBlock, BlockBreakData data, ConfigurationCache cc) {
|
||||
@ -51,10 +50,10 @@ public class DirectionCheck {
|
||||
data.directionViolationLevel += 1;
|
||||
|
||||
// Prepare some event-specific values for logging and custom actions
|
||||
HashMap<String, String> params = new HashMap<String, String>();
|
||||
params.put(LogAction.CHECK, "blockbreak.direction");
|
||||
LogData ldata = plugin.getDataManager().getLogData(player);
|
||||
ldata.check = "blockbreak.direction";
|
||||
|
||||
cancel = action.executeActions(player, cc.blockbreak.directionActions, (int) data.directionViolationLevel, params, cc);
|
||||
cancel = action.executeActions(player, cc.blockbreak.directionActions, (int) data.directionViolationLevel, ldata, cc);
|
||||
}
|
||||
|
||||
return cancel;
|
||||
|
@ -1,17 +1,13 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.checks.blockbreak;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.NoCheat;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.ActionExecutor;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.ActionExecutorWithHistory;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.types.LogAction;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.cache.ConfigurationCache;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.BlockBreakData;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.LogData;
|
||||
|
||||
/**
|
||||
* The reach check will find out if a player interacts with something that's too
|
||||
@ -22,29 +18,30 @@ import cc.co.evenprime.bukkit.nocheat.data.BlockBreakData;
|
||||
*/
|
||||
public class ReachCheck {
|
||||
|
||||
private final NoCheat plugin;
|
||||
private final ActionExecutor action;
|
||||
|
||||
public ReachCheck(NoCheat plugin) {
|
||||
this.action = new ActionExecutorWithHistory(plugin);
|
||||
this.plugin = plugin;
|
||||
this.action = new ActionExecutor(plugin);
|
||||
}
|
||||
|
||||
public boolean check(Player player, double distance, BlockBreakData data, ConfigurationCache cc) {
|
||||
|
||||
boolean cancel = false;
|
||||
|
||||
double limit = player.getGameMode() == GameMode.CREATIVE ? cc.blockbreak.reachDistance + 2 : cc.blockbreak.reachDistance;
|
||||
double limit = player.getGameMode() == GameMode.CREATIVE ? cc.blockbreak.reachDistance + 2 : cc.blockbreak.reachDistance;
|
||||
if(distance > limit) {
|
||||
// Player failed the check
|
||||
|
||||
|
||||
// Increment violation counter
|
||||
data.reachViolationLevel += 1;
|
||||
|
||||
// Prepare some event-specific values for logging and custom actions
|
||||
HashMap<String, String> params = new HashMap<String, String>();
|
||||
params.put(LogAction.CHECK, "blockbreak.reach");
|
||||
params.put(LogAction.DISTANCE, String.format(Locale.US, "%.2f", distance));
|
||||
cancel = action.executeActions(player, cc.blockbreak.reachActions, (int) data.reachViolationLevel, params, cc);
|
||||
LogData ldata = plugin.getDataManager().getLogData(player);
|
||||
|
||||
ldata.check = "blockbreak.reach";
|
||||
ldata.reachdistance = distance;
|
||||
cancel = action.executeActions(player, cc.blockbreak.reachActions, (int) data.reachViolationLevel, ldata, cc);
|
||||
} else {
|
||||
data.reachViolationLevel *= 0.9D;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.NoCheat;
|
||||
import cc.co.evenprime.bukkit.nocheat.Permissions;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.Permissions;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.cache.ConfigurationCache;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.BlockPlaceData;
|
||||
|
||||
|
@ -1,8 +1,5 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.checks.blockplace;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
@ -10,10 +7,9 @@ import org.bukkit.entity.Player;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.NoCheat;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.ActionExecutor;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.ActionExecutorWithHistory;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.types.LogAction;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.cache.ConfigurationCache;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.BlockPlaceData;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.LogData;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -22,10 +18,12 @@ import cc.co.evenprime.bukkit.nocheat.data.BlockPlaceData;
|
||||
*/
|
||||
public class OnLiquidCheck {
|
||||
|
||||
private final NoCheat plugin;
|
||||
private final ActionExecutor action;
|
||||
|
||||
public OnLiquidCheck(NoCheat plugin) {
|
||||
action = new ActionExecutorWithHistory(plugin);
|
||||
this.plugin = plugin;
|
||||
action = new ActionExecutor(plugin);
|
||||
}
|
||||
|
||||
public boolean check(Player player, Block blockPlaced, Block blockPlacedAgainst, BlockPlaceData data, ConfigurationCache cc) {
|
||||
@ -40,18 +38,12 @@ public class OnLiquidCheck {
|
||||
// all ok
|
||||
} else {
|
||||
data.onliquidViolationLevel += 1;
|
||||
HashMap<String, String> params = new HashMap<String, String>();
|
||||
params.put(LogAction.CHECK, "blockplace.onliquid");
|
||||
params.put(LogAction.BLOCK_TYPE, blockPlaced.getType().toString());
|
||||
params.put(LogAction.PLACE_LOCATION, String.format(Locale.US, "%d %d %d", blockPlaced.getX(), blockPlaced.getY(), blockPlaced.getZ()));
|
||||
if(blockPlacedAgainst != null) {
|
||||
params.put(LogAction.PLACE_AGAINST, String.format(Locale.US, "%d %d %d", blockPlacedAgainst.getX(), blockPlacedAgainst.getY(), blockPlacedAgainst.getZ()));
|
||||
}
|
||||
else {
|
||||
params.put(LogAction.PLACE_AGAINST, "null");
|
||||
}
|
||||
LogData ldata = plugin.getDataManager().getLogData(player);
|
||||
ldata.check = "blockplace.onliquid";
|
||||
ldata.placed = blockPlaced;
|
||||
ldata.placedAgainst = blockPlacedAgainst;
|
||||
|
||||
cancel = action.executeActions(player, cc.blockplace.onliquidActions, (int) data.onliquidViolationLevel, params, cc);
|
||||
cancel = action.executeActions(player, cc.blockplace.onliquidActions, (int) data.onliquidViolationLevel, ldata, cc);
|
||||
}
|
||||
|
||||
data.onliquidViolationLevel *= 0.95D; // Reduce level over time
|
||||
|
@ -1,8 +1,5 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.checks.blockplace;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -10,10 +7,9 @@ import org.bukkit.util.Vector;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.NoCheat;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.ActionExecutor;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.ActionExecutorWithHistory;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.types.LogAction;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.cache.ConfigurationCache;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.BlockPlaceData;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.LogData;
|
||||
|
||||
/**
|
||||
* The reach check will find out if a player interacts with something that's too
|
||||
@ -24,23 +20,25 @@ import cc.co.evenprime.bukkit.nocheat.data.BlockPlaceData;
|
||||
*/
|
||||
public class ReachCheck {
|
||||
|
||||
private final NoCheat plugin;
|
||||
private final ActionExecutor action;
|
||||
|
||||
public ReachCheck(NoCheat plugin) {
|
||||
this.action = new ActionExecutorWithHistory(plugin);
|
||||
this.plugin = plugin;
|
||||
this.action = new ActionExecutor(plugin);
|
||||
}
|
||||
|
||||
public boolean check(Player player, Block blockPlaced, Block placedAgainstBlock, BlockPlaceData data, ConfigurationCache cc) {
|
||||
|
||||
boolean cancel = false;
|
||||
|
||||
|
||||
Location eyes = player.getEyeLocation();
|
||||
|
||||
final double x1 = ((double) placedAgainstBlock.getX()) - eyes.getX();
|
||||
final double y1 = ((double) placedAgainstBlock.getY()) - eyes.getY();
|
||||
final double z1 = ((double) placedAgainstBlock.getZ()) - eyes.getZ();
|
||||
|
||||
double distance = new Vector(x1 + 0.5, y1 + + 0.5, z1 + + 0.5).length();
|
||||
double distance = new Vector(x1 + 0.5, y1 + +0.5, z1 + +0.5).length();
|
||||
|
||||
if(distance > cc.blockplace.reachDistance) {
|
||||
// Player failed the check
|
||||
@ -49,10 +47,11 @@ public class ReachCheck {
|
||||
data.reachViolationLevel += 1;
|
||||
|
||||
// Prepare some event-specific values for logging and custom actions
|
||||
HashMap<String, String> params = new HashMap<String, String>();
|
||||
params.put(LogAction.CHECK, "blockplace.reach");
|
||||
params.put(LogAction.DISTANCE, String.format(Locale.US, "%.2f", distance));
|
||||
cancel = action.executeActions(player, cc.blockplace.reachActions, (int) data.reachViolationLevel, params, cc);
|
||||
LogData ldata = plugin.getDataManager().getLogData(player);
|
||||
ldata.check = "blockplace.reach";
|
||||
ldata.reachdistance = distance;
|
||||
|
||||
cancel = action.executeActions(player, cc.blockplace.reachActions, (int) data.reachViolationLevel, ldata, cc);
|
||||
} else {
|
||||
data.reachViolationLevel *= 0.9D;
|
||||
}
|
||||
|
@ -1,22 +1,18 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.checks.chat;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.NoCheat;
|
||||
import cc.co.evenprime.bukkit.nocheat.Permissions;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.ActionExecutor;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.ActionExecutorWithHistory;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.types.LogAction;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.Permissions;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.cache.ConfigurationCache;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.ChatData;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.LogData;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class ChatCheck {
|
||||
|
||||
@ -25,8 +21,8 @@ public class ChatCheck {
|
||||
|
||||
public ChatCheck(NoCheat plugin) {
|
||||
|
||||
action = new ActionExecutorWithHistory(plugin);
|
||||
this.plugin = plugin;
|
||||
action = new ActionExecutor(plugin);
|
||||
}
|
||||
|
||||
public boolean check(Player player, String message, ChatData data, ConfigurationCache cc) {
|
||||
@ -50,14 +46,15 @@ public class ChatCheck {
|
||||
|
||||
// Prepare some event-specific values for logging and custom
|
||||
// actions
|
||||
HashMap<String, String> params = new HashMap<String, String>();
|
||||
params.put(LogAction.CHECK, "chat.spam");
|
||||
// Escape the message, to avoid errors
|
||||
params.put(LogAction.TEXT, Matcher.quoteReplacement(message));
|
||||
cancel = action.executeActions(player, cc.chat.spamActions, data.messageCount - cc.chat.spamLimit, params, cc);
|
||||
LogData ldata = plugin.getDataManager().getLogData(player);
|
||||
|
||||
ldata.check = "chat.spam";
|
||||
ldata.text = message;
|
||||
|
||||
cancel = action.executeActions(player, cc.chat.spamActions, data.messageCount - cc.chat.spamLimit, ldata, cc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return cancel;
|
||||
}
|
||||
|
||||
|
@ -1,16 +1,13 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.checks.interact;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.NoCheat;
|
||||
import cc.co.evenprime.bukkit.nocheat.Permissions;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.ActionExecutor;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.ActionExecutorWithHistory;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.types.LogAction;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.Permissions;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.cache.ConfigurationCache;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.InteractData;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.LogData;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -19,10 +16,12 @@ import cc.co.evenprime.bukkit.nocheat.data.InteractData;
|
||||
*/
|
||||
public class InteractCheck {
|
||||
|
||||
private final NoCheat plugin;
|
||||
private final ActionExecutor action;
|
||||
|
||||
public InteractCheck(NoCheat plugin) {
|
||||
action = new ActionExecutorWithHistory(plugin);
|
||||
this.plugin = plugin;
|
||||
action = new ActionExecutor(plugin);
|
||||
}
|
||||
|
||||
public boolean check(Player player, InteractData data, ConfigurationCache cc) {
|
||||
@ -36,10 +35,11 @@ public class InteractCheck {
|
||||
if(player.getInventory().getHeldItemSlot() == 9) {
|
||||
|
||||
data.violationLevel += 1;
|
||||
HashMap<String, String> params = new HashMap<String, String>();
|
||||
params.put(LogAction.CHECK, "interact.durability");
|
||||
|
||||
cancel = action.executeActions(player, cc.interact.durabilityActions, (int) data.violationLevel, params, cc);
|
||||
LogData ldata = plugin.getDataManager().getLogData(player);
|
||||
ldata.check = "interact.durability";
|
||||
|
||||
cancel = action.executeActions(player, cc.interact.durabilityActions, (int) data.violationLevel, ldata, cc);
|
||||
}
|
||||
|
||||
data.violationLevel *= 0.95D; // Reduce level over time
|
||||
|
@ -1,11 +1,5 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.checks.moving;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
|
||||
import net.minecraft.server.EntityPlayer;
|
||||
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
@ -13,9 +7,8 @@ import org.bukkit.entity.Player;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.NoCheat;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.ActionExecutor;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.ActionExecutorWithHistory;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.types.LogAction;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.cache.ConfigurationCache;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.LogData;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.MovingData;
|
||||
|
||||
/**
|
||||
@ -28,14 +21,14 @@ import cc.co.evenprime.bukkit.nocheat.data.MovingData;
|
||||
*/
|
||||
public class FlyingCheck {
|
||||
|
||||
private final NoCheat plugin;
|
||||
private final ActionExecutor action;
|
||||
|
||||
private static Method isRunningMethod;
|
||||
|
||||
private static final double creativeSpeed = 0.60D;
|
||||
|
||||
public FlyingCheck(NoCheat plugin) {
|
||||
this.action = new ActionExecutorWithHistory(plugin);
|
||||
this.plugin = plugin;
|
||||
this.action = new ActionExecutor(plugin);
|
||||
}
|
||||
|
||||
public Location check(Player player, Location from, Location to, ConfigurationCache cc, MovingData data) {
|
||||
@ -60,30 +53,26 @@ public class FlyingCheck {
|
||||
|
||||
result += Math.max(0.0D, horizontalDistance - data.horizFreedom - speedLimitHorizontal);
|
||||
|
||||
if(isRunningMethod == null) {
|
||||
isRunningMethod = getIsRunningMethod();
|
||||
}
|
||||
|
||||
boolean sprinting = true;
|
||||
|
||||
|
||||
try {
|
||||
sprinting = !(player instanceof CraftPlayer) || isRunningMethod.invoke(((CraftPlayer) player).getHandle()).equals(true);
|
||||
sprinting = !(player instanceof CraftPlayer) || player.isSprinting();
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
data.bunnyhopdelay--;
|
||||
|
||||
|
||||
// Did he go too far?
|
||||
if(result > 0 && sprinting) {
|
||||
|
||||
|
||||
// Try to treat it as a the "bunnyhop" problem
|
||||
if(data.bunnyhopdelay <= 0 && result < 0.4D) {
|
||||
data.bunnyhopdelay = 3;
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// super simple, just check distance compared to max distance
|
||||
result += Math.max(0.0D, yDistance - data.vertFreedom - cc.moving.flyingSpeedLimitVertical);
|
||||
result = result * 100;
|
||||
@ -94,12 +83,12 @@ public class FlyingCheck {
|
||||
data.runflyViolationLevel += result;
|
||||
|
||||
// Prepare some event-specific values for logging and custom actions
|
||||
HashMap<String, String> params = new HashMap<String, String>();
|
||||
params.put(LogAction.DISTANCE, String.format(Locale.US, "%.2f,%.2f,%.2f", xDistance, yDistance, zDistance));
|
||||
params.put(LogAction.LOCATION_TO, String.format(Locale.US, "%.2f,%.2f,%.2f", to.getX(), to.getY(), to.getZ()));
|
||||
params.put(LogAction.CHECK, "flying/toofast");
|
||||
LogData ldata = plugin.getDataManager().getLogData(player);
|
||||
|
||||
boolean cancel = action.executeActions(player, cc.moving.flyingActions, (int) data.runflyViolationLevel, params, cc);
|
||||
ldata.toLocation = to;
|
||||
ldata.check = "flying/toofast";
|
||||
|
||||
boolean cancel = action.executeActions(player, cc.moving.flyingActions, (int) data.runflyViolationLevel, ldata, cc);
|
||||
|
||||
// Was one of the actions a cancel? Then really do it
|
||||
if(cancel) {
|
||||
@ -117,18 +106,4 @@ public class FlyingCheck {
|
||||
|
||||
return newToLocation;
|
||||
}
|
||||
|
||||
private Method getIsRunningMethod() {
|
||||
try {
|
||||
return EntityPlayer.class.getMethod("isSprinting");
|
||||
} catch(NoSuchMethodException e) {
|
||||
try {
|
||||
return EntityPlayer.class.getMethod("at");
|
||||
} catch(Exception e1) {
|
||||
// TODO Auto-generated catch block
|
||||
e1.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,12 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.checks.moving;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.NoCheat;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.ActionExecutor;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.ActionExecutorWithHistory;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.types.LogAction;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.cache.ConfigurationCache;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.LogData;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.MovingData;
|
||||
|
||||
/**
|
||||
@ -28,12 +25,12 @@ public class MorePacketsCheck {
|
||||
|
||||
private final ActionExecutor action;
|
||||
|
||||
private final long packetsPerTimeframe = 22;
|
||||
private final double bufferLimit = 30;
|
||||
private final int packetsPerTimeframe = 22;
|
||||
private final int bufferLimit = 30;
|
||||
private final NoCheat plugin;
|
||||
|
||||
public MorePacketsCheck(NoCheat plugin) {
|
||||
this.action = new ActionExecutorWithHistory(plugin);
|
||||
this.action = new ActionExecutor(plugin);
|
||||
|
||||
this.plugin = plugin;
|
||||
}
|
||||
@ -105,9 +102,9 @@ public class MorePacketsCheck {
|
||||
// ticks since last time
|
||||
if(ingameSeconds != data.lastElapsedIngameSeconds) {
|
||||
|
||||
long limit = (packetsPerTimeframe * plugin.getIngameSecondDuration()) / 1000L;
|
||||
int limit = (int) ((packetsPerTimeframe * plugin.getIngameSecondDuration()) / 1000L);
|
||||
|
||||
long difference = limit - data.morePacketsCounter;
|
||||
int difference = limit - data.morePacketsCounter;
|
||||
|
||||
data.morePacketsBuffer = data.morePacketsBuffer + difference;
|
||||
if(data.morePacketsBuffer > bufferLimit)
|
||||
@ -125,14 +122,13 @@ public class MorePacketsCheck {
|
||||
if(!plugin.skipCheck() && packetsAboveLimit > 0) {
|
||||
data.morePacketsViolationLevel += packetsAboveLimit;
|
||||
|
||||
HashMap<String, String> params = new HashMap<String, String>();
|
||||
|
||||
LogData ldata = plugin.getDataManager().getLogData(player);
|
||||
// Packets above limit
|
||||
params.put(LogAction.PACKETS, String.valueOf(data.morePacketsCounter - limit));
|
||||
params.put(LogAction.CHECK, "morepackets");
|
||||
ldata.packets = data.morePacketsCounter - limit;
|
||||
ldata.check = "moving/morepackets";
|
||||
|
||||
boolean cancel = false;
|
||||
cancel = action.executeActions(player, cc.moving.morePacketsActions, (int) data.morePacketsViolationLevel, params, cc);
|
||||
cancel = action.executeActions(player, cc.moving.morePacketsActions, (int) data.morePacketsViolationLevel, ldata, cc);
|
||||
|
||||
// Only do the cancel if the player didn't change worlds
|
||||
// inbetween
|
||||
|
@ -15,17 +15,15 @@ import org.bukkit.World;
|
||||
*/
|
||||
public class MovingEventHelper {
|
||||
|
||||
// private final double magic = 0.30000001192092896D;
|
||||
// private final double magic2 = 0.69999998807907103D;
|
||||
private final double magic = 0.45D;
|
||||
private final double magic2 = 0.55D;
|
||||
|
||||
// Block types that may need to be treated specially
|
||||
private static final int NONSOLID = 1; // 0x00000001
|
||||
private static final int SOLID = 2; // 0x00000010
|
||||
private static final int LIQUID = 4 | NONSOLID; // 0x00000101
|
||||
private static final int NONSOLID = 1; // 0x00000001
|
||||
private static final int SOLID = 2; // 0x00000010
|
||||
private static final int LIQUID = 4 | NONSOLID; // 0x00000101
|
||||
private static final int LADDER = 8 | NONSOLID | SOLID; // 0x00001011
|
||||
private static final int FENCE = 16 | SOLID; // 0x00010000
|
||||
private static final int FENCE = 16 | SOLID; // 0x00010000
|
||||
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
|
||||
|
@ -1,22 +1,12 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.checks.moving;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
|
||||
import net.minecraft.server.DamageSource;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.entity.CraftEntity;
|
||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Event.Type;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.NoCheat;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.ActionExecutor;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.ActionExecutorWithHistory;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.types.LogAction;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.cache.ConfigurationCache;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.LogData;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.MovingData;
|
||||
|
||||
/**
|
||||
@ -29,11 +19,11 @@ import cc.co.evenprime.bukkit.nocheat.data.MovingData;
|
||||
public class NoFallCheck {
|
||||
|
||||
private final ActionExecutor action;
|
||||
private final NoCheat plugin;
|
||||
private final NoCheat plugin;
|
||||
|
||||
public NoFallCheck(NoCheat plugin) {
|
||||
this.action = new ActionExecutorWithHistory(plugin);
|
||||
this.plugin = plugin;
|
||||
this.action = new ActionExecutor(plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -41,7 +31,7 @@ public class NoFallCheck {
|
||||
*
|
||||
*/
|
||||
public void check(final Player player, final Location from, final boolean fromOnOrInGround, final Location to, final boolean toOnOrInGround, final ConfigurationCache cc, final MovingData data) {
|
||||
|
||||
|
||||
double oldY = from.getY();
|
||||
double newY = to.getY();
|
||||
|
||||
@ -50,34 +40,36 @@ public class NoFallCheck {
|
||||
// Start with zero fall distance
|
||||
data.fallDistance = 0F;
|
||||
}
|
||||
|
||||
|
||||
// If we increased fall height before for no good reason, reduce now by the same amount
|
||||
if(player.getFallDistance() > data.lastAddedFallDistance) {
|
||||
player.setFallDistance(player.getFallDistance() - data.lastAddedFallDistance);
|
||||
}
|
||||
|
||||
data.lastAddedFallDistance = 0;
|
||||
|
||||
|
||||
// We want to know if the fallDistance recorded by the game is smaller
|
||||
// than the fall distance recorded by the plugin
|
||||
// than the fall distance recorded by the plugin
|
||||
float difference = data.fallDistance - player.getFallDistance();
|
||||
|
||||
if(difference > 1.0F && toOnOrInGround && data.fallDistance > 2.0F) {
|
||||
data.nofallViolationLevel += difference;
|
||||
// Prepare some event-specific values for logging and custom actions
|
||||
HashMap<String, String> params = new HashMap<String, String>();
|
||||
params.put(LogAction.DISTANCE, String.format(Locale.US, "%.2f", difference));
|
||||
params.put(LogAction.CHECK, "nofall");
|
||||
|
||||
// Prepare some event-specific values for logging and custom actions
|
||||
LogData ldata = plugin.getDataManager().getLogData(player);
|
||||
ldata.falldistance = data.fallDistance;
|
||||
ldata.check = "moving/nofall";
|
||||
|
||||
boolean cancel = action.executeActions(player, cc.moving.nofallActions, (int) data.nofallViolationLevel, params, cc);
|
||||
|
||||
// If "cancelled", the fall damage gets dealt in a way that's visible to other plugins
|
||||
if(cancel) {
|
||||
boolean cancel = action.executeActions(player, cc.moving.nofallActions, (int) data.nofallViolationLevel, ldata, cc);
|
||||
|
||||
// If "cancelled", the fall damage gets dealt in a way that's visible to other plugins
|
||||
if(cancel) {
|
||||
// Increase the fall distance a bit :)
|
||||
float totalDistance = data.fallDistance + difference * (cc.moving.nofallMultiplier - 1.0F);
|
||||
|
||||
player.setFallDistance(totalDistance);
|
||||
}
|
||||
|
||||
|
||||
data.fallDistance = 0F;
|
||||
}
|
||||
|
||||
|
@ -1,148 +0,0 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.checks.moving;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.NoCheat;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.ActionExecutor;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.ActionExecutorWithHistory;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.types.LogAction;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.cache.ConfigurationCache;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.MovingData;
|
||||
|
||||
/**
|
||||
* A simple NoClip check. It tries to identify players that walk into/through
|
||||
* walls by remembering their last location and whenever they move into or
|
||||
* through a wall (with their upper body), this check should identify it.
|
||||
* EXPERIMENTAL!!
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public class NoclipCheck {
|
||||
|
||||
private final double bodyHeight = 1.1;
|
||||
private final ActionExecutor action;
|
||||
|
||||
public NoclipCheck(NoCheat plugin) {
|
||||
this.action = new ActionExecutorWithHistory(plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate if and how much the player "failed" this check. The check
|
||||
* should not modify any data
|
||||
*
|
||||
*/
|
||||
public Location check(final Player player, final Location from, final Location to, final MovingEventHelper helper, final ConfigurationCache cc, final MovingData data) {
|
||||
|
||||
/*** THE CHECK ***/
|
||||
Location current = from.clone();
|
||||
|
||||
final double distanceX = to.getX() - current.getX();
|
||||
final double distanceY = to.getY() - current.getY();
|
||||
final double distanceZ = to.getZ() - current.getZ();
|
||||
|
||||
current.setY(current.getY() + bodyHeight);
|
||||
|
||||
double distance = Math.abs(distanceX) > Math.abs(distanceY) ? (Math.abs(distanceX) > Math.abs(distanceZ) ? Math.abs(distanceX) : Math.abs(distanceZ)) : (Math.abs(distanceY) > Math.abs(distanceZ) ? Math.abs(distanceY) : Math.abs(distanceZ));
|
||||
int steps = (int) (distance / 0.1) + 1;
|
||||
|
||||
double divideBy = distance * 10D;
|
||||
|
||||
final double stepX = distanceX / divideBy;
|
||||
final double stepY = distanceY / divideBy;
|
||||
final double stepZ = distanceZ / divideBy;
|
||||
|
||||
final World world = from.getWorld();
|
||||
|
||||
int oldX, oldY, oldZ;
|
||||
int newX, newY, newZ;
|
||||
if(Math.abs(data.noclipX - current.getBlockX()) > 1 || Math.abs(data.noclipY - current.getBlockY()) > 1 || Math.abs(data.noclipZ - current.getBlockZ()) > 1) {
|
||||
oldX = newX = current.getBlockX();
|
||||
oldY = newY = current.getBlockY();
|
||||
oldZ = newZ = current.getBlockZ();
|
||||
} else {
|
||||
oldX = newX = data.noclipX;
|
||||
oldY = newY = data.noclipY;
|
||||
oldZ = newZ = data.noclipZ;
|
||||
}
|
||||
|
||||
int violationLevel = 0;
|
||||
|
||||
for(int i = 0; i < steps; i++) {
|
||||
|
||||
newX = current.getBlockX();
|
||||
newY = current.getBlockY();
|
||||
newZ = current.getBlockZ();
|
||||
|
||||
final boolean xChanged = newX != oldX;
|
||||
final boolean yChanged = newY != oldY;
|
||||
final boolean zChanged = newZ != oldZ;
|
||||
|
||||
boolean failed = false;
|
||||
// Looks scarier than it is
|
||||
if(!failed && (xChanged || yChanged || zChanged)) {
|
||||
failed = check(helper, world, newX, newY, newZ);
|
||||
|
||||
if(!failed && xChanged && (yChanged || zChanged)) {
|
||||
failed = check(helper, world, oldX, newY, newZ);
|
||||
}
|
||||
|
||||
if(!failed && yChanged && (xChanged || zChanged)) {
|
||||
failed = check(helper, world, newX, oldY, newZ);
|
||||
}
|
||||
|
||||
if(!failed && zChanged && (xChanged || yChanged)) {
|
||||
failed = check(helper, world, newX, newY, oldZ);
|
||||
}
|
||||
|
||||
oldX = newX;
|
||||
oldY = newY;
|
||||
oldZ = newZ;
|
||||
}
|
||||
|
||||
// Determine if the block can be passed by the player
|
||||
if(failed) {
|
||||
violationLevel++;
|
||||
}
|
||||
|
||||
current.add(stepX, stepY, stepZ);
|
||||
}
|
||||
|
||||
if(violationLevel > 0) {
|
||||
// Prepare some event-specific values for logging and custom
|
||||
// actions
|
||||
HashMap<String, String> params = new HashMap<String, String>();
|
||||
params.put(LogAction.DISTANCE, String.format(Locale.US, "%.2f,%.2f,%.2f", to.getX() - from.getX(), to.getY() - from.getY(), to.getZ() - from.getZ()));
|
||||
params.put(LogAction.LOCATION_TO, String.format(Locale.US, "%.2f,%.2f,%.2f", to.getX(), to.getY(), to.getZ()));
|
||||
params.put(LogAction.CHECK, "noclip");
|
||||
|
||||
/*boolean cancelled =*/ action.executeActions(player, cc.moving.noclipActions, violationLevel, params, cc);
|
||||
|
||||
// TODO: UNCOMMENT, WHEN THE CHECK WORKS RELIABLY
|
||||
|
||||
//if(cancelled) {
|
||||
// return new Location(from.getWorld(), data.noclipX + 0.5, data.noclipY - ((int) bodyHeight), data.noclipZ + 0.5, to.getPitch(), to.getYaw());
|
||||
//}
|
||||
}
|
||||
|
||||
// We didn't cancel the noclipping, so store the new location
|
||||
data.noclipX = newX;
|
||||
data.noclipY = newY;
|
||||
data.noclipZ = newZ;
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
private final boolean check(MovingEventHelper helper, World world, int x, int y, int z) {
|
||||
if(y < 0 || y > 127) {
|
||||
return false;
|
||||
}
|
||||
return !helper.isNonSolid(helper.types[world.getBlockAt(x, y, z).getTypeId()]);
|
||||
}
|
||||
}
|
@ -6,7 +6,7 @@ import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.NoCheat;
|
||||
import cc.co.evenprime.bukkit.nocheat.Permissions;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.Permissions;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.cache.ConfigurationCache;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.MovingData;
|
||||
|
||||
@ -22,7 +22,6 @@ public class RunFlyCheck {
|
||||
|
||||
private final FlyingCheck flyingCheck;
|
||||
private final RunningCheck runningCheck;
|
||||
private final NoclipCheck noclippingCheck;
|
||||
private final NoFallCheck noFallCheck;
|
||||
private final MorePacketsCheck morePacketsCheck;
|
||||
|
||||
@ -34,7 +33,6 @@ public class RunFlyCheck {
|
||||
this.flyingCheck = new FlyingCheck(plugin);
|
||||
this.noFallCheck = new NoFallCheck(plugin);
|
||||
this.runningCheck = new RunningCheck(plugin, noFallCheck);
|
||||
this.noclippingCheck = new NoclipCheck(plugin);
|
||||
this.morePacketsCheck = new MorePacketsCheck(plugin);
|
||||
}
|
||||
|
||||
@ -74,7 +72,6 @@ public class RunFlyCheck {
|
||||
final boolean runflyCheck = cc.moving.runflyCheck && !player.hasPermission(Permissions.MOVE_RUNFLY);
|
||||
final boolean flyAllowed = cc.moving.allowFlying || player.hasPermission(Permissions.MOVE_FLY) || (player.getGameMode() == GameMode.CREATIVE && cc.moving.identifyCreativeMode);
|
||||
final boolean morepacketsCheck = cc.moving.morePacketsCheck && !player.hasPermission(Permissions.MOVE_MOREPACKETS);
|
||||
final boolean noclipCheck = cc.moving.noclipCheck && !player.hasPermission(Permissions.MOVE_NOCLIP);
|
||||
|
||||
/********************* EXECUTE THE FLY/JUMP/RUNNING CHECK ********************/
|
||||
// If the player is not allowed to fly and not allowed to run
|
||||
@ -92,11 +89,7 @@ public class RunFlyCheck {
|
||||
if(newToLocation == null && morepacketsCheck) {
|
||||
newToLocation = morePacketsCheck.check(player, cc, data);
|
||||
}
|
||||
|
||||
/********* EXECUTE THE NOCLIP CHECK ********************/
|
||||
if(newToLocation == null && noclipCheck) {
|
||||
newToLocation = noclippingCheck.check(player, from, to, helper, cc, data);
|
||||
}
|
||||
|
||||
return newToLocation;
|
||||
}
|
||||
|
||||
|
@ -1,21 +1,14 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.checks.moving;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
|
||||
import net.minecraft.server.EntityPlayer;
|
||||
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.NoCheat;
|
||||
import cc.co.evenprime.bukkit.nocheat.Permissions;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.ActionExecutor;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.ActionExecutorWithHistory;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.types.LogAction;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.Permissions;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.cache.ConfigurationCache;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.LogData;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.MovingData;
|
||||
|
||||
/**
|
||||
@ -29,20 +22,20 @@ import cc.co.evenprime.bukkit.nocheat.data.MovingData;
|
||||
*/
|
||||
public class RunningCheck {
|
||||
|
||||
private final static double maxBonus = 1D;
|
||||
|
||||
private static Method isRunningMethod = null;
|
||||
private final static double maxBonus = 1D;
|
||||
|
||||
// How many move events can a player have in air before he is expected to
|
||||
// lose altitude (or eventually land somewhere)
|
||||
private final static int jumpingLimit = 6;
|
||||
private final static int jumpingLimit = 6;
|
||||
|
||||
private final ActionExecutor action;
|
||||
private final NoCheat plugin;
|
||||
|
||||
private final NoFallCheck noFallCheck;
|
||||
|
||||
public RunningCheck(NoCheat plugin, NoFallCheck noFallCheck) {
|
||||
this.action = new ActionExecutorWithHistory(plugin);
|
||||
this.plugin = plugin;
|
||||
this.action = new ActionExecutor(plugin);
|
||||
this.noFallCheck = noFallCheck;
|
||||
}
|
||||
|
||||
@ -84,17 +77,16 @@ public class RunningCheck {
|
||||
data.runflyViolationLevel += result;
|
||||
|
||||
// Prepare some event-specific values for logging and custom actions
|
||||
HashMap<String, String> params = new HashMap<String, String>();
|
||||
params.put(LogAction.DISTANCE, String.format(Locale.US, "%.2f,%.2f,%.2f", xDistance, to.getY() - from.getY(), zDistance));
|
||||
params.put(LogAction.LOCATION_TO, String.format(Locale.US, "%.2f,%.2f,%.2f", to.getX(), to.getY(), to.getZ()));
|
||||
LogData ldata = plugin.getDataManager().getLogData(player);
|
||||
ldata.toLocation = to;
|
||||
if(resultHoriz > 0 && resultVert > 0)
|
||||
params.put(LogAction.CHECK, "runfly/both");
|
||||
ldata.check = "runfly/both";
|
||||
else if(resultHoriz > 0)
|
||||
params.put(LogAction.CHECK, "runfly/horizontal");
|
||||
ldata.check = "runfly/horizontal";
|
||||
else if(resultVert > 0)
|
||||
params.put(LogAction.CHECK, "runfly/vertical");
|
||||
ldata.check = "runfly/vertical";
|
||||
|
||||
boolean cancel = action.executeActions(player, cc.moving.actions, (int) data.runflyViolationLevel, params, cc);
|
||||
boolean cancel = action.executeActions(player, cc.moving.actions, (int) data.runflyViolationLevel, ldata, cc);
|
||||
|
||||
// Was one of the actions a cancel? Then do it
|
||||
if(cancel) {
|
||||
@ -139,13 +131,9 @@ public class RunningCheck {
|
||||
// How much further did the player move than expected??
|
||||
double distanceAboveLimit = 0.0D;
|
||||
|
||||
if(isRunningMethod == null) {
|
||||
isRunningMethod = getIsRunningMethod();
|
||||
}
|
||||
|
||||
boolean sprinting = true;
|
||||
try {
|
||||
sprinting = !(player instanceof CraftPlayer) || isRunningMethod.invoke(((CraftPlayer) player).getHandle()).equals(true);
|
||||
sprinting = !(player instanceof CraftPlayer) || player.isSprinting();
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -211,18 +199,4 @@ public class RunningCheck {
|
||||
return distanceAboveLimit;
|
||||
|
||||
}
|
||||
|
||||
private Method getIsRunningMethod() {
|
||||
try {
|
||||
return EntityPlayer.class.getMethod("isSprinting");
|
||||
} catch(NoSuchMethodException e) {
|
||||
try {
|
||||
return EntityPlayer.class.getMethod("at");
|
||||
} catch(Exception e1) {
|
||||
// TODO Auto-generated catch block
|
||||
e1.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,24 +1,230 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.config;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.ActionList;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.OptionNode.DataType;
|
||||
import cc.co.evenprime.bukkit.nocheat.log.LogLevel;
|
||||
|
||||
/**
|
||||
* A configuration. It should allow access to settings associated with a string
|
||||
* This class describes a basic configuration for NoCheat. NoCheats
|
||||
* configuration
|
||||
* is based on String,String pairs, and this class provides some convenience
|
||||
* methods
|
||||
* to retrieve and store more complex datatypes based on strings.
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public interface Configuration {
|
||||
public abstract class Configuration {
|
||||
|
||||
public abstract boolean getBoolean(String string);
|
||||
public final static OptionNode ROOT = new OptionNode(null, null, DataType.PARENT);
|
||||
|
||||
public abstract ActionList getActionList(String string);
|
||||
public final static OptionNode LOGGING = new OptionNode("logging", ROOT, DataType.PARENT);
|
||||
public final static OptionNode LOGGING_ACTIVE = new OptionNode("active", LOGGING, DataType.BOOLEAN);
|
||||
public final static OptionNode LOGGING_FILENAME = new OptionNode("filename", LOGGING, DataType.STRING);
|
||||
public final static OptionNode LOGGING_FILELEVEL = new OptionNode("filelevel", LOGGING, DataType.LOGLEVEL);
|
||||
public final static OptionNode LOGGING_CONSOLELEVEL = new OptionNode("consolelevel", LOGGING, DataType.LOGLEVEL);
|
||||
public final static OptionNode LOGGING_CHATLEVEL = new OptionNode("chatlevel", LOGGING, DataType.LOGLEVEL);
|
||||
|
||||
public abstract int getInteger(String string);
|
||||
public final static OptionNode DEBUG = new OptionNode("debug", ROOT, DataType.PARENT);
|
||||
public final static OptionNode DEBUG_SHOWACTIVECHECKS = new OptionNode("showactivechecks", DEBUG, DataType.BOOLEAN);
|
||||
|
||||
public abstract String getString(String string);
|
||||
public final static OptionNode MOVING = new OptionNode("moving", ROOT, DataType.PARENT);
|
||||
public final static OptionNode MOVING_CHECK = new OptionNode("check", MOVING, DataType.BOOLEAN);
|
||||
public final static OptionNode MOVING_IDENTIFYCREATIVEMODE = new OptionNode("identifycreativemode", MOVING, DataType.BOOLEAN);
|
||||
|
||||
public abstract LogLevel getLogLevel(String string);
|
||||
public final static OptionNode MOVING_RUNFLY = new OptionNode("runfly", MOVING, DataType.PARENT);
|
||||
public final static OptionNode MOVING_RUNFLY_CHECK = new OptionNode("check", MOVING_RUNFLY, DataType.BOOLEAN);
|
||||
public final static OptionNode MOVING_RUNFLY_WALKINGSPEEDLIMIT = new OptionNode("alkingspeedlimit", MOVING_RUNFLY, DataType.INTEGER);
|
||||
public final static OptionNode MOVING_RUNFLY_SPRINTINGSPEEDLIMIT = new OptionNode("sprintingspeedlimit", MOVING_RUNFLY, DataType.INTEGER);
|
||||
public final static OptionNode MOVING_RUNFLY_JUMPHEIGHT = new OptionNode("jumpheight", MOVING_RUNFLY, DataType.INTEGER);
|
||||
public final static OptionNode MOVING_RUNFLY_CHECKSNEAKING = new OptionNode("checksneaking", MOVING_RUNFLY, DataType.BOOLEAN);
|
||||
public final static OptionNode MOVING_RUNFLY_SNEAKINGSPEEDLIMIT = new OptionNode("sneakingspeedlimit", MOVING_RUNFLY, DataType.INTEGER);
|
||||
public final static OptionNode MOVING_RUNFLY_CHECKSWIMMING = new OptionNode("checkswimming", MOVING_RUNFLY, DataType.BOOLEAN);
|
||||
public final static OptionNode MOVING_RUNFLY_SWIMMINGSPEEDLIMIT = new OptionNode("swimmingspeedlimit", MOVING_RUNFLY, DataType.INTEGER);
|
||||
public final static OptionNode MOVING_RUNFLY_ACTIONS = new OptionNode("actions", MOVING_RUNFLY, DataType.ACTIONLIST);
|
||||
public final static OptionNode MOVING_RUNFLY_CHECKNOFALL = new OptionNode("checknofall", MOVING_RUNFLY, DataType.BOOLEAN);
|
||||
public final static OptionNode MOVING_RUNFLY_NOFALLMULTIPLIER = new OptionNode("nofallmultiplier", MOVING_RUNFLY, DataType.INTEGER);
|
||||
public final static OptionNode MOVING_RUNFLY_NOFALLACTIONS = new OptionNode("nofallactions", MOVING_RUNFLY, DataType.ACTIONLIST);
|
||||
public final static OptionNode MOVING_RUNFLY_ALLOWLIMITEDFLYING = new OptionNode("allowlimitedflying", MOVING_RUNFLY, DataType.BOOLEAN);
|
||||
public final static OptionNode MOVING_RUNFLY_FLYINGSPEEDLIMITVERTICAL = new OptionNode("flyingspeedlimitvertical", MOVING_RUNFLY, DataType.INTEGER);
|
||||
public final static OptionNode MOVING_RUNFLY_FLYINGSPEEDLIMITHORIZONTAL = new OptionNode("flyingspeedlimithorizontal", MOVING_RUNFLY, DataType.INTEGER);
|
||||
public final static OptionNode MOVING_RUNFLY_FLYINGACTIONS = new OptionNode("flyingactions", MOVING_RUNFLY, DataType.ACTIONLIST);
|
||||
|
||||
public final static OptionNode MOVING_MOREPACKETS = new OptionNode("morepackets", MOVING, DataType.PARENT);
|
||||
public final static OptionNode MOVING_MOREPACKETS_CHECK = new OptionNode("check", MOVING_MOREPACKETS, DataType.BOOLEAN);
|
||||
public final static OptionNode MOVING_MOREPACKETS_ACTIONS = new OptionNode("actions", MOVING_MOREPACKETS, DataType.ACTIONLIST);
|
||||
|
||||
public final static OptionNode BLOCKBREAK = new OptionNode("blockbreak", ROOT, DataType.PARENT);
|
||||
public final static OptionNode BLOCKBREAK_CHECK = new OptionNode("check", BLOCKBREAK, DataType.BOOLEAN);
|
||||
|
||||
public final static OptionNode BLOCKBREAK_REACH = new OptionNode("reach", BLOCKBREAK, DataType.PARENT);
|
||||
public final static OptionNode BLOCKBREAK_REACH_CHECK = new OptionNode("check", BLOCKBREAK_REACH, DataType.BOOLEAN);
|
||||
public final static OptionNode BLOCKBREAK_REACH_LIMIT = new OptionNode("limit", BLOCKBREAK_REACH, DataType.INTEGER);
|
||||
public final static OptionNode BLOCKBREAK_REACH_ACTIONS = new OptionNode("actions", BLOCKBREAK_REACH, DataType.ACTIONLIST);
|
||||
|
||||
public final static OptionNode BLOCKBREAK_DIRECTION = new OptionNode("direction", BLOCKBREAK, DataType.PARENT);
|
||||
public final static OptionNode BLOCKBREAK_DIRECTION_CHECK = new OptionNode("check", BLOCKBREAK_DIRECTION, DataType.BOOLEAN);
|
||||
public static final OptionNode BLOCKBREAK_DIRECTION_CHECKINSTABREAKBLOCKS = new OptionNode("checkinstabreakblocks", BLOCKBREAK_DIRECTION, DataType.BOOLEAN);
|
||||
public final static OptionNode BLOCKBREAK_DIRECTION_ACTIONS = new OptionNode("actions", BLOCKBREAK_DIRECTION, DataType.ACTIONLIST);
|
||||
|
||||
public final static OptionNode BLOCKPLACE = new OptionNode("blockplace", ROOT, DataType.PARENT);
|
||||
public final static OptionNode BLOCKPLACE_CHECK = new OptionNode("check", BLOCKPLACE, DataType.BOOLEAN);
|
||||
|
||||
public final static OptionNode BLOCKPLACE_REACH = new OptionNode("reach", BLOCKPLACE, DataType.PARENT);
|
||||
public final static OptionNode BLOCKPLACE_REACH_CHECK = new OptionNode("check", BLOCKPLACE_REACH, DataType.BOOLEAN);
|
||||
public final static OptionNode BLOCKPLACE_REACH_LIMIT = new OptionNode("limit", BLOCKPLACE_REACH, DataType.INTEGER);
|
||||
public final static OptionNode BLOCKPLACE_REACH_ACTIONS = new OptionNode("actions", BLOCKPLACE_REACH, DataType.ACTIONLIST);
|
||||
|
||||
public final static OptionNode BLOCKPLACE_ONLIQUID = new OptionNode("onliquid", BLOCKPLACE, DataType.PARENT);
|
||||
public final static OptionNode BLOCKPLACE_ONLIQUID_CHECK = new OptionNode("check", BLOCKPLACE_ONLIQUID, DataType.BOOLEAN);
|
||||
public final static OptionNode BLOCKPLACE_ONLIQUID_ACTIONS = new OptionNode("actions", BLOCKPLACE_ONLIQUID, DataType.ACTIONLIST);
|
||||
|
||||
public final static OptionNode INTERACT = new OptionNode("interact", ROOT, DataType.PARENT);
|
||||
public final static OptionNode INTERACT_CHECK = new OptionNode("check", INTERACT, DataType.BOOLEAN);
|
||||
|
||||
public final static OptionNode INTERACT_DURABILITY = new OptionNode("durability", INTERACT, DataType.PARENT);
|
||||
public final static OptionNode INTERACT_DURABILITY_CHECK = new OptionNode("check", INTERACT_DURABILITY, DataType.BOOLEAN);
|
||||
public final static OptionNode INTERACT_DURABILITY_ACTIONS = new OptionNode("actions", INTERACT_DURABILITY, DataType.ACTIONLIST);
|
||||
|
||||
public final static OptionNode CHAT = new OptionNode("chat", ROOT, DataType.PARENT);
|
||||
public final static OptionNode CHAT_CHECK = new OptionNode("check", CHAT, DataType.BOOLEAN);
|
||||
|
||||
public final static OptionNode CHAT_SPAM = new OptionNode("spam", CHAT, DataType.PARENT);
|
||||
public final static OptionNode CHAT_SPAM_CHECK = new OptionNode("check", CHAT_SPAM, DataType.BOOLEAN);
|
||||
public final static OptionNode CHAT_SPAM_TIMEFRAME = new OptionNode("timeframe", CHAT_SPAM, DataType.INTEGER);
|
||||
public final static OptionNode CHAT_SPAM_LIMIT = new OptionNode("limit", CHAT_SPAM, DataType.INTEGER);
|
||||
public final static OptionNode CHAT_SPAM_ACTIONS = new OptionNode("actions", CHAT_SPAM, DataType.ACTIONLIST);
|
||||
|
||||
private final Map<OptionNode, Object> values;
|
||||
private final Configuration defaults;
|
||||
|
||||
public Configuration(Configuration defaults, boolean copyDefaults) {
|
||||
|
||||
this.values = new HashMap<OptionNode, Object>();
|
||||
this.defaults = defaults;
|
||||
|
||||
if(defaults != null && copyDefaults) {
|
||||
deepCopy(defaults, ROOT);
|
||||
}
|
||||
}
|
||||
|
||||
private void deepCopy(Configuration defaults, OptionNode root) {
|
||||
|
||||
if(root.isLeaf()) {
|
||||
this.set(root, defaults.getRecursive(root));
|
||||
} else {
|
||||
for(OptionNode child : root.getChildren()) {
|
||||
deepCopy(defaults, child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getBoolean(OptionNode id) {
|
||||
if(id.getType() != DataType.BOOLEAN) {
|
||||
throw new IllegalArgumentException(id + " is no boolean value!");
|
||||
}
|
||||
|
||||
return (Boolean) getRecursive(id);
|
||||
}
|
||||
|
||||
public String getString(OptionNode id) {
|
||||
if(id.getType() != DataType.STRING) {
|
||||
throw new IllegalArgumentException(id + " is no string value!");
|
||||
}
|
||||
|
||||
return (String) getRecursive(id);
|
||||
}
|
||||
|
||||
public int getInteger(OptionNode id) {
|
||||
if(id.getType() != DataType.INTEGER) {
|
||||
throw new IllegalArgumentException(id + " is no integer value!");
|
||||
}
|
||||
|
||||
return (Integer) getRecursive(id);
|
||||
}
|
||||
|
||||
public LogLevel getLogLevel(OptionNode id) {
|
||||
if(id.getType() != DataType.LOGLEVEL) {
|
||||
throw new IllegalArgumentException(id + " is no loglevel value!");
|
||||
}
|
||||
|
||||
return (LogLevel) getRecursive(id);
|
||||
}
|
||||
|
||||
public ActionList getActionList(OptionNode id) {
|
||||
|
||||
if(id.getType() != DataType.ACTIONLIST) {
|
||||
throw new IllegalArgumentException(id + " is no actionlist value!");
|
||||
}
|
||||
|
||||
return (ActionList) getRecursive(id);
|
||||
}
|
||||
|
||||
public void setValue(OptionNode id, Integer value) {
|
||||
if(id.getType() != DataType.INTEGER) {
|
||||
throw new IllegalArgumentException(id + " is no integer value!");
|
||||
}
|
||||
set(id, value);
|
||||
}
|
||||
|
||||
public void setValue(OptionNode id, LogLevel value) {
|
||||
if(id.getType() != DataType.LOGLEVEL) {
|
||||
throw new IllegalArgumentException(id + " is no loglevel value!");
|
||||
}
|
||||
set(id, value);
|
||||
}
|
||||
|
||||
public void setValue(OptionNode id, Boolean value) {
|
||||
if(id.getType() != DataType.BOOLEAN) {
|
||||
throw new IllegalArgumentException(id + " is no boolean value!");
|
||||
}
|
||||
set(id, value);
|
||||
}
|
||||
|
||||
public void setValue(OptionNode id, String value) {
|
||||
if(id.getType() != DataType.STRING) {
|
||||
throw new IllegalArgumentException(id + " is no string value!");
|
||||
}
|
||||
set(id, value);
|
||||
}
|
||||
|
||||
public void setValue(OptionNode id, ActionList value) {
|
||||
if(id.getType() != DataType.ACTIONLIST) {
|
||||
throw new IllegalArgumentException(id + " is no actionlist value!");
|
||||
}
|
||||
set(id, value);
|
||||
}
|
||||
|
||||
protected void set(OptionNode id, Object value) {
|
||||
if(value == null) {
|
||||
this.values.remove(id);
|
||||
} else {
|
||||
this.values.put(id, value);
|
||||
}
|
||||
}
|
||||
|
||||
protected Object getRecursive(OptionNode id) {
|
||||
Object o = get(id);
|
||||
|
||||
if(o != null) {
|
||||
return o;
|
||||
}
|
||||
|
||||
if(defaults != null) {
|
||||
return defaults.getRecursive(id);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Configuration getDefaults() {
|
||||
return defaults;
|
||||
}
|
||||
|
||||
protected Object get(OptionNode id) {
|
||||
return this.values.get(id);
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,13 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.config;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.logging.FileHandler;
|
||||
import java.util.logging.Formatter;
|
||||
import java.util.logging.Handler;
|
||||
@ -17,18 +15,9 @@ import java.util.logging.Level;
|
||||
import java.util.logging.LogRecord;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.DefaultConfiguration;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.ActionManager;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.types.Action;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.cache.ConfigurationCache;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.ActionListOption;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.ChildOption;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.ConfigurationTree;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.Option;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.ParentOption;
|
||||
import cc.co.evenprime.bukkit.nocheat.file.DescriptionGenerator;
|
||||
import cc.co.evenprime.bukkit.nocheat.file.FlatActionParser;
|
||||
import cc.co.evenprime.bukkit.nocheat.file.FlatConfigGenerator;
|
||||
import cc.co.evenprime.bukkit.nocheat.file.FlatConfigParser;
|
||||
|
||||
/**
|
||||
* Central location for everything that's described in the configuration file(s)
|
||||
@ -49,7 +38,7 @@ public class ConfigurationManager {
|
||||
// map
|
||||
private final Map<File, FileHandler> fileToFileHandlerMap = new HashMap<File, FileHandler>();
|
||||
|
||||
private final ConfigurationTree defaultTree = DefaultConfiguration.buildDefaultConfigurationTree();
|
||||
private final Configuration defaultConfig;
|
||||
|
||||
private class LogFileFormatter extends Formatter {
|
||||
|
||||
@ -85,23 +74,46 @@ public class ConfigurationManager {
|
||||
// private final static String loggerName = "cc.co.evenprime.nocheat";
|
||||
// public final Logger logger = Logger.getLogger(loggerName);
|
||||
|
||||
public ConfigurationManager(String rootConfigFolder, ActionManager action) {
|
||||
public ConfigurationManager(String rootConfigFolder, ActionManager actionManager) {
|
||||
|
||||
// Parse actions file
|
||||
initializeActions(rootConfigFolder, action);
|
||||
// MOVE TO ACTIONMANAGER PARSER OR SOMETHING
|
||||
initializeActions(rootConfigFolder, actionManager);
|
||||
|
||||
defaultConfig = new DefaultConfiguration(actionManager);
|
||||
|
||||
// Setup the configuration tree
|
||||
initializeConfig(rootConfigFolder, action);
|
||||
initializeConfig(rootConfigFolder, actionManager);
|
||||
|
||||
}
|
||||
|
||||
private void initializeActions(String rootConfigFolder, ActionManager action) {
|
||||
private void initializeActions(String rootConfigFolder, ActionManager actionManager) {
|
||||
|
||||
FlatActionParser parser = new FlatActionParser();
|
||||
File defaultActionsFile = new File(rootConfigFolder, defaultActionFileName);
|
||||
|
||||
DefaultConfiguration.writeDefaultActionFile(new File(rootConfigFolder, defaultActionFileName));
|
||||
parser.read(action, new File(rootConfigFolder, defaultActionFileName));
|
||||
parser.read(action, new File(rootConfigFolder, actionFileName));
|
||||
// Write the current default action file into the target folder
|
||||
DefaultConfiguration.writeDefaultActionFile(defaultActionsFile);
|
||||
|
||||
// now parse that file again
|
||||
FlatFileAction parser = new FlatFileAction(defaultActionsFile);
|
||||
List<Action> defaultActions = parser.read();
|
||||
|
||||
for(Action a : defaultActions) {
|
||||
actionManager.addAction(a);
|
||||
}
|
||||
|
||||
// Check if the "custom" action file exists, if not, create one
|
||||
File customActionsFile = new File(rootConfigFolder, actionFileName);
|
||||
if(!customActionsFile.exists()) {
|
||||
DefaultConfiguration.writeActionFile(customActionsFile);
|
||||
}
|
||||
|
||||
parser = new FlatFileAction(customActionsFile);
|
||||
List<Action> customActions = parser.read();
|
||||
|
||||
for(Action a : customActions) {
|
||||
actionManager.addAction(a);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -110,23 +122,28 @@ public class ConfigurationManager {
|
||||
*
|
||||
* @param configurationFile
|
||||
*/
|
||||
private void initializeConfig(String rootConfigFolder, ActionManager actionManager) {
|
||||
private void initializeConfig(String rootConfigFolder, ActionManager action) {
|
||||
|
||||
// First try to obtain and parse the global config file
|
||||
ConfigurationTree root;
|
||||
FlatFileConfiguration root;
|
||||
File globalConfigFile = getGlobalConfigFile(rootConfigFolder);
|
||||
|
||||
root = new FlatFileConfiguration(defaultConfig, true, globalConfigFile);
|
||||
try {
|
||||
root = createFullConfigurationTree(defaultTree, globalConfigFile);
|
||||
root.load(action);
|
||||
} catch(Exception e) {
|
||||
root = DefaultConfiguration.buildDefaultConfigurationTree();
|
||||
|
||||
}
|
||||
|
||||
writeConfigFile(globalConfigFile, root);
|
||||
try {
|
||||
root.save();
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// Create a corresponding Configuration Cache
|
||||
// put the global config on the config map
|
||||
worldnameToConfigCacheMap.put(null, new ConfigurationCache(root, setupFileLogger(new File(rootConfigFolder, root.getString("logging.filename")))));
|
||||
worldnameToConfigCacheMap.put(null, new ConfigurationCache(root, setupFileLogger(new File(rootConfigFolder, root.getString(DefaultConfiguration.LOGGING_FILENAME)))));
|
||||
|
||||
// Try to find world-specific config files
|
||||
Map<String, File> worldFiles = getWorldSpecificConfigFiles(rootConfigFolder);
|
||||
@ -134,25 +151,26 @@ public class ConfigurationManager {
|
||||
for(String worldName : worldFiles.keySet()) {
|
||||
|
||||
File worldConfigFile = worldFiles.get(worldName);
|
||||
|
||||
FlatFileConfiguration world = new FlatFileConfiguration(root, false, worldConfigFile);
|
||||
|
||||
try {
|
||||
ConfigurationTree world = createPartialConfigurationTree(root, worldConfigFile);
|
||||
world.load(action);
|
||||
|
||||
worldnameToConfigCacheMap.put(worldName, createConfigurationCache(rootConfigFolder, world));
|
||||
|
||||
// write the config file back to disk immediately
|
||||
writeConfigFile(worldFiles.get(worldName), world);
|
||||
world.save();
|
||||
|
||||
} catch(IOException e) {
|
||||
System.out.println("NoCheat: Couldn't load world-specific config for " + worldName);
|
||||
}
|
||||
}
|
||||
|
||||
// Write the descriptions-file for the default tree
|
||||
writeDescriptionFile(new File(rootConfigFolder, descriptionsFileName), defaultTree);
|
||||
}
|
||||
|
||||
private ConfigurationCache createConfigurationCache(String rootConfigFolder, Configuration configProvider) {
|
||||
|
||||
return new ConfigurationCache(configProvider, setupFileLogger(new File(rootConfigFolder, configProvider.getString("logging.filename"))));
|
||||
return new ConfigurationCache(configProvider, setupFileLogger(new File(rootConfigFolder, configProvider.getString(DefaultConfiguration.LOGGING_FILENAME))));
|
||||
|
||||
}
|
||||
|
||||
@ -183,88 +201,6 @@ public class ConfigurationManager {
|
||||
return files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a full configuration tree based on a default tree and a
|
||||
* configuration file
|
||||
* The resulting tree will have all settings of the defaultTree with entries
|
||||
* replaced,
|
||||
* if existing, by data from the configurationFile
|
||||
*
|
||||
* @param defaultTree
|
||||
* @param configurationFile
|
||||
* @throws IOException
|
||||
*/
|
||||
public static ConfigurationTree createFullConfigurationTree(ConfigurationTree defaultTree, File configurationFile) throws IOException {
|
||||
|
||||
return yamlToTree(defaultTree, configurationFile, true);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a partial configuration tree based on a default tree and a
|
||||
* configuration file
|
||||
* The resulting tree will only have settings from the configurationFile,
|
||||
* but reference
|
||||
* the defaultTree as its parent.
|
||||
*
|
||||
* @param defaultTree
|
||||
* @param configurationFile
|
||||
* @throws IOException
|
||||
*/
|
||||
public static ConfigurationTree createPartialConfigurationTree(ConfigurationTree defaultTree, File configurationFile) throws IOException {
|
||||
|
||||
ConfigurationTree tree = yamlToTree(defaultTree, configurationFile, false);
|
||||
tree.setParent(defaultTree);
|
||||
|
||||
return tree;
|
||||
|
||||
}
|
||||
|
||||
private static ConfigurationTree yamlToTree(ConfigurationTree defaults, File configurationFile, boolean fullCopy) throws IOException {
|
||||
|
||||
FlatConfigParser source = new FlatConfigParser();
|
||||
source.read(configurationFile);
|
||||
|
||||
ConfigurationTree partial = new ConfigurationTree();
|
||||
|
||||
for(Option o : defaults.getAllOptions()) {
|
||||
if(o instanceof ActionListOption) {
|
||||
ActionListOption o2 = ((ActionListOption) o).clone();
|
||||
partial.add(o.getParent().getFullIdentifier(), o2);
|
||||
// Does the new source have a node for this property??
|
||||
Object prop = source.getProperty(o2.getFullIdentifier());
|
||||
if(prop instanceof Map<?, ?> && prop != null) {
|
||||
// Yes, so we rather take the data from that node
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<Object, Object> m = (Map<Object, Object>) prop;
|
||||
o2.clear();
|
||||
for(Entry<Object, Object> entry : m.entrySet()) {
|
||||
try {
|
||||
o2.add(Integer.parseInt((String) entry.getKey()), (String) entry.getValue());
|
||||
} catch(Exception e) {
|
||||
System.out.println("NoCheat: PROBLEM OFFICER?!?!");
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!fullCopy && prop == null) {
|
||||
o2.setActive(false);
|
||||
}
|
||||
} else if(o instanceof ParentOption) {
|
||||
ParentOption o2 = new ParentOption(o.getIdentifier());
|
||||
partial.add(o.getParent().getFullIdentifier(), o2);
|
||||
} else if(o instanceof ChildOption) {
|
||||
ChildOption o2 = ((ChildOption) o).clone();
|
||||
partial.add(o.getParent().getFullIdentifier(), o2);
|
||||
o2.setStringValue(source.getString(o2.getFullIdentifier(), o2.getStringValue()));
|
||||
if(!fullCopy && source.getProperty(o.getFullIdentifier()) == null) {
|
||||
o2.setActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return partial;
|
||||
}
|
||||
|
||||
private Logger setupFileLogger(File logfile) {
|
||||
|
||||
FileHandler fh = fileToFileHandlerMap.get(logfile);
|
||||
@ -323,51 +259,6 @@ public class ConfigurationManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write configuration to specific file
|
||||
*
|
||||
* @param f
|
||||
*/
|
||||
public static void writeConfigFile(File f, ConfigurationTree configuration) {
|
||||
try {
|
||||
if(f.getParentFile() != null)
|
||||
f.getParentFile().mkdirs();
|
||||
|
||||
f.createNewFile();
|
||||
BufferedWriter w = new BufferedWriter(new FileWriter(f));
|
||||
|
||||
w.write(FlatConfigGenerator.treeToFlatFile(configuration));
|
||||
|
||||
w.flush();
|
||||
w.close();
|
||||
} catch(IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a file with the descriptions of all options of a specific
|
||||
* configuration tree
|
||||
*
|
||||
* @param f
|
||||
*/
|
||||
public static void writeDescriptionFile(File f, ConfigurationTree configuration) {
|
||||
try {
|
||||
if(f.getParentFile() != null)
|
||||
f.getParentFile().mkdirs();
|
||||
|
||||
f.createNewFile();
|
||||
BufferedWriter w = new BufferedWriter(new FileWriter(f));
|
||||
|
||||
w.write(DescriptionGenerator.treeToDescription(configuration));
|
||||
|
||||
w.flush();
|
||||
w.close();
|
||||
} catch(IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cache of the specified world, or the default cache,
|
||||
* if no cache exists for that world.
|
||||
|
@ -0,0 +1,267 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.config;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.ActionList;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.ActionManager;
|
||||
import cc.co.evenprime.bukkit.nocheat.log.LogLevel;
|
||||
|
||||
/**
|
||||
* The place where the structure of the configuration tree is defined, the
|
||||
* default settings are defined, the default files are defined.
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public class DefaultConfiguration extends Configuration {
|
||||
|
||||
public DefaultConfiguration(ActionManager action) {
|
||||
super(null, false);
|
||||
|
||||
/*** LOGGING ***/
|
||||
{
|
||||
setValue(LOGGING_ACTIVE, true);
|
||||
setValue(LOGGING_FILENAME, "nocheat.log");
|
||||
setValue(LOGGING_FILELEVEL, LogLevel.LOW);
|
||||
setValue(LOGGING_CONSOLELEVEL, LogLevel.HIGH);
|
||||
setValue(LOGGING_CHATLEVEL, LogLevel.MED);
|
||||
}
|
||||
|
||||
/*** DEBUG ***/
|
||||
{
|
||||
setValue(DEBUG_SHOWACTIVECHECKS, false);
|
||||
}
|
||||
|
||||
/*** MOVING ***/
|
||||
{
|
||||
setValue(MOVING_CHECK, true);
|
||||
setValue(MOVING_IDENTIFYCREATIVEMODE, true);
|
||||
|
||||
setValue(MOVING_RUNFLY_CHECK, true);
|
||||
|
||||
setValue(MOVING_RUNFLY_WALKINGSPEEDLIMIT, 22);
|
||||
setValue(MOVING_RUNFLY_SPRINTINGSPEEDLIMIT, 40);
|
||||
setValue(MOVING_RUNFLY_JUMPHEIGHT, 135);
|
||||
|
||||
setValue(MOVING_RUNFLY_CHECKSNEAKING, true);
|
||||
setValue(MOVING_RUNFLY_SNEAKINGSPEEDLIMIT, 14);
|
||||
|
||||
setValue(MOVING_RUNFLY_CHECKSWIMMING, true);
|
||||
setValue(MOVING_RUNFLY_SWIMMINGSPEEDLIMIT, 18);
|
||||
|
||||
ActionList movingActionList = new ActionList();
|
||||
movingActionList.setActions(0, action.getActions("moveLogLowShort moveCancel".split(" ")));
|
||||
movingActionList.setActions(100, action.getActions("moveLogMedShort moveCancel".split(" ")));
|
||||
movingActionList.setActions(400, action.getActions("moveLogHighShort moveCancel".split(" ")));
|
||||
setValue(MOVING_RUNFLY_ACTIONS, movingActionList);
|
||||
|
||||
setValue(MOVING_RUNFLY_CHECKNOFALL, true);
|
||||
setValue(MOVING_RUNFLY_NOFALLMULTIPLIER, 200);
|
||||
|
||||
ActionList nofallActionList = new ActionList();
|
||||
nofallActionList.setActions(0, action.getActions("nofallLog nofallDamage".split(" ")));
|
||||
setValue(MOVING_RUNFLY_NOFALLACTIONS, nofallActionList);
|
||||
|
||||
setValue(MOVING_RUNFLY_ALLOWLIMITEDFLYING, false);
|
||||
setValue(MOVING_RUNFLY_FLYINGSPEEDLIMITVERTICAL, 100);
|
||||
setValue(MOVING_RUNFLY_FLYINGSPEEDLIMITHORIZONTAL, 60);
|
||||
|
||||
ActionList flyingActionList = new ActionList();
|
||||
flyingActionList.setActions(0, action.getActions("moveLogLowShort moveCancel".split(" ")));
|
||||
flyingActionList.setActions(100, action.getActions("moveLogMedShort moveCancel".split(" ")));
|
||||
flyingActionList.setActions(400, action.getActions("moveLogHighShort moveCancel".split(" ")));
|
||||
setValue(MOVING_RUNFLY_FLYINGACTIONS, flyingActionList);
|
||||
|
||||
setValue(MOVING_MOREPACKETS_CHECK, true);
|
||||
|
||||
ActionList morepacketsActionList = new ActionList();
|
||||
morepacketsActionList.setActions(0, action.getActions("morepacketsLow moveCancel".split(" ")));
|
||||
morepacketsActionList.setActions(30, action.getActions("morepacketsMed moveCancel".split(" ")));
|
||||
morepacketsActionList.setActions(60, action.getActions("morepacketsHigh moveCancel".split(" ")));
|
||||
setValue(MOVING_MOREPACKETS_ACTIONS, morepacketsActionList);
|
||||
|
||||
}
|
||||
|
||||
/*** BLOCKBREAK ***/
|
||||
{
|
||||
setValue(BLOCKBREAK_CHECK, true);
|
||||
|
||||
setValue(BLOCKBREAK_REACH_CHECK, true);
|
||||
setValue(BLOCKBREAK_REACH_LIMIT, 485);
|
||||
|
||||
ActionList reachActionList = new ActionList();
|
||||
reachActionList.setActions(0, action.getActions("reachLog blockbreakCancel".split(" ")));
|
||||
setValue(BLOCKBREAK_REACH_ACTIONS, reachActionList);
|
||||
|
||||
setValue(BLOCKBREAK_DIRECTION_CHECK, true);
|
||||
|
||||
setValue(BLOCKBREAK_DIRECTION_CHECKINSTABREAKBLOCKS, false);
|
||||
|
||||
ActionList directionActionList = new ActionList();
|
||||
directionActionList.setActions(0, action.getActions("directionLog blockbreakCancel".split(" ")));
|
||||
setValue(BLOCKBREAK_DIRECTION_ACTIONS, directionActionList);
|
||||
}
|
||||
|
||||
/*** BLOCKPLACE ***/
|
||||
{
|
||||
setValue(BLOCKPLACE_CHECK, true);
|
||||
|
||||
setValue(BLOCKPLACE_REACH_CHECK, true);
|
||||
setValue(BLOCKPLACE_REACH_LIMIT, 485);
|
||||
|
||||
ActionList reachActionList = new ActionList();
|
||||
reachActionList.setActions(0, action.getActions("reachLog blockplaceCancel".split(" ")));
|
||||
setValue(BLOCKPLACE_REACH_ACTIONS, reachActionList);
|
||||
|
||||
setValue(BLOCKPLACE_ONLIQUID_CHECK, true);
|
||||
|
||||
ActionList onliquidActionList = new ActionList();
|
||||
onliquidActionList.setActions(0, action.getActions("onliquidLog blockplaceCancel".split(" ")));
|
||||
setValue(BLOCKPLACE_ONLIQUID_ACTIONS, onliquidActionList);
|
||||
|
||||
}
|
||||
|
||||
/*** INTERACT ***/
|
||||
{
|
||||
setValue(INTERACT_CHECK, true);
|
||||
setValue(INTERACT_DURABILITY_CHECK, true);
|
||||
|
||||
ActionList infiniteDurabilityActionList = new ActionList();
|
||||
infiniteDurabilityActionList.setActions(0, action.getActions("durabilityLog interactCancel".split(" ")));
|
||||
setValue(INTERACT_DURABILITY_ACTIONS, infiniteDurabilityActionList);
|
||||
|
||||
}
|
||||
|
||||
/*** CHAT ***/
|
||||
{
|
||||
setValue(CHAT_CHECK, true);
|
||||
|
||||
setValue(CHAT_SPAM_CHECK, true);
|
||||
setValue(CHAT_SPAM_TIMEFRAME, 5);
|
||||
setValue(CHAT_SPAM_LIMIT, 5);
|
||||
|
||||
ActionList spamActionList = new ActionList();
|
||||
spamActionList.setActions(0, action.getActions("spamLog spamCancel".split(" ")));
|
||||
setValue(CHAT_SPAM_ACTIONS, spamActionList);
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeActionFile(File file) {
|
||||
BufferedWriter w;
|
||||
|
||||
try {
|
||||
if(!file.exists()) {
|
||||
try {
|
||||
file.getParentFile().mkdirs();
|
||||
file.createNewFile();
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
w = new BufferedWriter(new FileWriter(file));
|
||||
|
||||
w(w, "# This file contains the definitions of the default actions of NoCheat.");
|
||||
w(w, "# DO NOT EDIT THIS FILE DIRECTLY. If you want to change any of these, copy");
|
||||
w(w, "# them to your \"actions.txt\" file and modify them there. If an action with");
|
||||
w(w, "# the same name exists here and in your file, yours will be used.");
|
||||
w(w, "");
|
||||
w.flush();
|
||||
w.close();
|
||||
} catch(IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void writeDefaultActionFile(File file) {
|
||||
|
||||
BufferedWriter w;
|
||||
|
||||
try {
|
||||
if(!file.exists()) {
|
||||
try {
|
||||
file.getParentFile().mkdirs();
|
||||
file.createNewFile();
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
w = new BufferedWriter(new FileWriter(file));
|
||||
|
||||
w(w, "# This file contains the definitions of the default actions of NoCheat.");
|
||||
w(w, "# DO NOT EDIT THIS FILE DIRECTLY. If you want to change any of these, copy");
|
||||
w(w, "# them to your \"actions.txt\" file and modify them there. If an action with");
|
||||
w(w, "# the same name exists here and in your file, yours will be used.");
|
||||
w(w, "#");
|
||||
w(w, "# LOG Actions: They will print messages in your log file, console, chat, ...");
|
||||
w(w, "# - They start with the word 'log'");
|
||||
w(w, "# - Then comes their name. That name is used in the config file to identify them");
|
||||
w(w, "# - Then comes the 'delay', that is how often has this action to be called before it really gets executed");
|
||||
w(w, "# - Then comes the 'repeat', that is how many seconds have to be between two executions of the action");
|
||||
w(w, "# - Then comes the 'loglevel', that is how the log message gets categorized (low, med, high)");
|
||||
w(w, "# - Then comes the 'message', depending on where the action is used, different keywords in [ ] may be used");
|
||||
w(w, "");
|
||||
w(w, "# Gives a very short log message of the violation, only containing name, violation type and total violation value, at most once every 15 seconds, only if more than 3 violations happened within the last minute (low) and immediatly (med,high)");
|
||||
w(w, "log moveLogLowShort 3 15 low NC: [player] failed [check]");
|
||||
w(w, "log moveLogMedShort 0 15 med NC: [player] failed [check]");
|
||||
w(w, "log moveLogHighShort 0 15 high NC: [player] failed [check]");
|
||||
w(w, "");
|
||||
w(w, "# Gives a log message of the violation, only containing name, violation type and total violation value, at most once every second, only if more than 5 violations happened within the last minute (low) and immediatly (med,high)");
|
||||
w(w, "log morepacketsLow 5 1 low NC: [player] failed [check]: Sent [packets] more packets than expected. Total violation level [violations].");
|
||||
w(w, "log morepacketsMed 0 1 med NC: [player] failed [check]: Sent [packets] more packets than expected. Total violation level [violations].");
|
||||
w(w, "log morepacketsHigh 0 1 high NC: [player] failed [check]: Sent [packets] more packets than expected. Total violation level [violations].");
|
||||
w(w, "");
|
||||
w(w, "# Gives a lengthy log message of the violation, containing name, location, violation type and total violation, at most once every 15 seconds, only if more than 3 violations happened within the last minute (low) and immediatly (med,high)");
|
||||
w(w, "log moveLogLowLong 3 15 low NC: [player] in [world] at [location] moving to [locationto] over distance [movedistance] failed check [check]. Total violation level so far [violations].");
|
||||
w(w, "log moveLogMedLong 0 15 med NC: [player] in [world] at [location] moving to [locationto] over distance [movedistance] failed check [check]. Total violation level so far [violations].");
|
||||
w(w, "log moveLogHighLong 0 15 high NC: [player] in [world] at [location] moving to [locationto] over distance [movedistance] failed check [check]. Total violation level so far [violations].");
|
||||
w(w, "");
|
||||
w(w, "# Some other log messages that are limited a bit by default, to avoid too extreme spam");
|
||||
w(w, "log reachLog 0 1 med NC: [player] failed [check]: tried to interact with a block over distance [reachdistance].");
|
||||
w(w, "log directionLog 2 1 med NC: [player] failed [check]: tried to destroy a block out of line of sight.");
|
||||
w(w, "log durabilityLog 0 1 med NC: [player] failed [check]: tried to use infinity durability hack.");
|
||||
w(w, "log onliquidLog 2 1 med NC: [player] failed [check]: tried to place a [blocktype] block at [placelocation] against block at [placeagainst].");
|
||||
w(w, "log spamLog 0 4 med NC: [player] failed [check]: Last sent message \"[text]\".");
|
||||
w(w, "log nofallLog 0 1 med NC: [player] failed [check]: tried to avoid fall damage for ~[falldistance] blocks.");
|
||||
w(w, "");
|
||||
w(w, "# SPECIAL Actions: They will do something check dependant, usually cancel an event.");
|
||||
w(w, "# - They start with the word 'special'");
|
||||
w(w, "# - Then comes their name. That name is used in the config file to identify them");
|
||||
w(w, "# - Then comes the 'delay', that is how often has this action to be called before it really gets executed");
|
||||
w(w, "# - Then comes the 'repeat', that is how many seconds have to be between two executions of the action");
|
||||
w(w, "# - Then come further instructions, if necessary");
|
||||
w(w, "");
|
||||
w(w, "# Cancels the event in case of an violation. Always. No delay. These are equivalent. The different names are just for better readability");
|
||||
w(w, "special moveCancel 0 0");
|
||||
w(w, "special blockbreakCancel 0 0");
|
||||
w(w, "special blockplaceCancel 0 0");
|
||||
w(w, "special interactCancel 0 0");
|
||||
w(w, "special spamCancel 0 0");
|
||||
w(w, "special nofallDamage 0 0");
|
||||
w(w, "");
|
||||
w(w, "# CONSOLECOMMAND Actions: They will execute a command as if it were typed into the console.");
|
||||
w(w, "# - They start with the word 'consolecommand'");
|
||||
w(w, "# - Then comes their name. That name is used in the config file to identify them");
|
||||
w(w, "# - Then comes the 'delay', that is how often has this action to be called before it really gets executed");
|
||||
w(w, "# - Then comes the 'repeat', that is how many seconds have to be between two executions of the action");
|
||||
w(w, "# - Then comes the command. You can use the same [ ] that you use for log actions. You'll most likely want to use [player] at some point.");
|
||||
w(w, "");
|
||||
w(w, "# E.g. Kick a player");
|
||||
w(w, "consolecommand kick 0 0 kick [player]");
|
||||
w.flush();
|
||||
w.close();
|
||||
} catch(IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void w(BufferedWriter writer, String text) throws IOException {
|
||||
writer.write(text);
|
||||
writer.newLine();
|
||||
}
|
||||
}
|
101
src/cc/co/evenprime/bukkit/nocheat/config/Explainations.java
Normal file
101
src/cc/co/evenprime/bukkit/nocheat/config/Explainations.java
Normal file
@ -0,0 +1,101 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.config;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* Textual explainations of options, will be displayed in the gui tool and the
|
||||
* descriptions.txt file.
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public class Explainations {
|
||||
|
||||
private static final Map<OptionNode, String> explainations = new HashMap<OptionNode, String>();
|
||||
|
||||
static {
|
||||
|
||||
set(Configuration.LOGGING_ACTIVE, "Should NoCheat related messages get logged at all. Some messages may still appear, e.g. error\n messages, even if this option is deactivated");
|
||||
|
||||
set(Configuration.LOGGING_FILENAME, "Where logs that go to the logfile are stored. You can have different files for different worlds.");
|
||||
set(Configuration.LOGGING_FILELEVEL, "What log-level need messages to have to get stored in the logfile. Values are:\n low: all messages\n med: med and high messages only\n high: high messages only\n off: no messages at all.");
|
||||
set(Configuration.LOGGING_CONSOLELEVEL, "What log-level need messages to have to get displayed in your server console. Values are:\n low: all messages\n med: med and high messages only\n high: high messages only\n off: no messages at all.");
|
||||
set(Configuration.LOGGING_CHATLEVEL, "What log-level need messages to have to get displayed in the ingame chat. Values are:\n low: all messages\n med: med and high messages only\n high: high messages only\n off: no messages at all.");
|
||||
|
||||
set(Configuration.DEBUG_SHOWACTIVECHECKS, "Print to the console an overview of all checks that are enabled when NoCheat gets loaded.");
|
||||
|
||||
set(Configuration.MOVING_CHECK, "If true, do various checks on PlayerMove events.");
|
||||
set(Configuration.MOVING_IDENTIFYCREATIVEMODE, "If true, NoCheat will automatically identify if players are in creative mode and will allow them to fly, avoid fall damage etc.");
|
||||
|
||||
set(Configuration.MOVING_RUNFLY_CHECK, "If true, check if a player is walking/sprinting/sneaking/swimming too fast/high.");
|
||||
set(Configuration.MOVING_RUNFLY_WALKINGSPEEDLIMIT, "Set the speed limit for moving horizontal under 'normal' conditions.\nUnit is 1/100 of a block, default is 22.");
|
||||
set(Configuration.MOVING_RUNFLY_SPRINTINGSPEEDLIMIT, "Set the speed limit for moving horizontal while sprinting.\nUnit is 1/100 of a block, default is 40.");
|
||||
set(Configuration.MOVING_RUNFLY_JUMPHEIGHT, "Set how high a player is allowed to jump.\nUnit is 1/100 of a block, default is 135.");
|
||||
set(Configuration.MOVING_RUNFLY_CHECKSWIMMING, "Use a seperate speed limit for swimming players.");
|
||||
set(Configuration.MOVING_RUNFLY_SWIMMINGSPEEDLIMIT, "Set the speed limit for moving horizontal while in water.\nUnit is 1/100 of a block, default is 18");
|
||||
set(Configuration.MOVING_RUNFLY_CHECKSNEAKING, "Use a seperate speed limit for sneaking players.");
|
||||
set(Configuration.MOVING_RUNFLY_SNEAKINGSPEEDLIMIT, "Set the speed limit for moving horizontal while sneaking.\nUnit is 1/100 of a block, default is 14");
|
||||
set(Configuration.MOVING_RUNFLY_ACTIONS, "What should be done if a player moves faster than the speed limit(s) or jumps higher than allowed.\nUnits are in 1/100 of a block above the limit.");
|
||||
|
||||
set(Configuration.MOVING_RUNFLY_CHECKNOFALL, "If true, check if a player is avoiding fall damage by using a nofall hack. EXPERIMENTAL! Feedback is appreciated.");
|
||||
set(Configuration.MOVING_RUNFLY_NOFALLMULTIPLIER, "How many percent falldamage should be dealt to the player.\nNoCheat will almost always underestimate fall damage, using a value bigger than 100 is advised.\nUnit is percent of the estimated original fall damage, default is 200.");
|
||||
set(Configuration.MOVING_RUNFLY_NOFALLACTIONS, "What should be done if a player is detected as avoiding fall damage.\nUnit is number of blocks the player fell down.");
|
||||
|
||||
set(Configuration.MOVING_RUNFLY_ALLOWLIMITEDFLYING, "If true, instead of doing the above checks for walking/sprinting/swimming/sneaking,\nallow flying and only limit the flying speed.");
|
||||
set(Configuration.MOVING_RUNFLY_FLYINGSPEEDLIMITVERTICAL, "Set the speed limit for moving vertical while flying.\nUnit is 1/100 of a block, default is 100.");
|
||||
set(Configuration.MOVING_RUNFLY_FLYINGSPEEDLIMITHORIZONTAL, "Set the speed limit for moving horizontal while flying.\nUnit is 1/100 of a block, default is 60.");
|
||||
set(Configuration.MOVING_RUNFLY_FLYINGACTIONS, "What should be done if a player flies faster than the speed limit(s). \nUnits are in 1/100 of a block above the speedlimit.");
|
||||
|
||||
|
||||
set(Configuration.MOVING_MOREPACKETS_CHECK, "If true, check if a player is sending too many 'move-packets' per second. In a normal game, the player won't send more than 22 packets per second.");
|
||||
set(Configuration.MOVING_MOREPACKETS_ACTIONS, "What should be done if a player sends more 'move-packets' than normal.\nUnits are packets per second above the limit.");
|
||||
|
||||
set(Configuration.BLOCKBREAK_CHECK, "If true, do various checks on BlockBreak events.");
|
||||
|
||||
set(Configuration.BLOCKBREAK_REACH_CHECK, "If true, check if a player is breaking blocks that are too far away.");
|
||||
set(Configuration.BLOCKBREAK_REACH_LIMIT, "Set the distance limit for breaking blocks.\nUnit is 1/100 of a block, default is 485");
|
||||
set(Configuration.BLOCKBREAK_REACH_ACTIONS, "What should be done if a player is breaking blocks that are too far away.\nUnit is number of break(attempt)s beyond the limit.");
|
||||
|
||||
set(Configuration.BLOCKBREAK_DIRECTION_CHECK, "If true, check if a player is looking at the block that he's breaking.");
|
||||
set(Configuration.BLOCKBREAK_DIRECTION_CHECKINSTABREAKBLOCKS, "If true, NoCheat will also check for direction for Instant-Breaking blocks.\nTHIS WILL CAUSE FALSE POSITIVES, when a player keeps his mouse button pressed and moves the mouse fast over the screen.");
|
||||
set(Configuration.BLOCKBREAK_DIRECTION_ACTIONS, "What should be done if a player is breaking blocks that are not in his line of sight.\nUnit is number of break(attempt)s outside the line of sight.");
|
||||
|
||||
set(Configuration.BLOCKPLACE_CHECK, "If true, do various checks on BlockPlace events.");
|
||||
|
||||
set(Configuration.BLOCKPLACE_REACH_CHECK, "If true, check if a player is placing blocks at locations too far away.");
|
||||
set(Configuration.BLOCKPLACE_REACH_LIMIT, "Set the distance limit for placing blocks.\nUnit is 1/100 of a block, default is 485");
|
||||
set(Configuration.BLOCKPLACE_REACH_ACTIONS, "What should be done if a player is placing blocks that are too far away.\nUnit is number of place(attempt)s beyond the limit.");
|
||||
|
||||
set(Configuration.BLOCKPLACE_ONLIQUID_CHECK, "If true, check if a player is trying to place non-liquid blocks against liquid blocks\nIn a normal Minecraft game, it is impossible to place a block without it touching something that is considered solid (neither air nor a liquid).\nBut if people use a modified client, to can do that. This check tries to identify that trick.");
|
||||
set(Configuration.BLOCKPLACE_ONLIQUID_ACTIONS, "What should be done if a player is is trying to place non-liquid blocks against liquid blocks.\nUnit is number of place(attempt)s.");
|
||||
|
||||
set(Configuration.INTERACT_CHECK, "If true, do various checks on PlayerInteract events.");
|
||||
|
||||
set(Configuration.INTERACT_DURABILITY_CHECK, "If true, check if a player is using a hack that provides infinite durability items.");
|
||||
set(Configuration.INTERACT_DURABILITY_ACTIONS, "What should be done if a player is trying to use the hack.\nUnit is number of uses or attempts to use the hack.");
|
||||
|
||||
set(Configuration.CHAT_CHECK, "If true, do various checks on PlayerChat events.");
|
||||
|
||||
set(Configuration.CHAT_SPAM_CHECK, "If true, check if a player is spamming the chat.");
|
||||
set(Configuration.CHAT_SPAM_TIMEFRAME, "Over what timeframe (in seconds) should the messages be counted?\nWhen the time is over, counting starts at 0 again.");
|
||||
set(Configuration.CHAT_SPAM_LIMIT, "How many messages per timeframe may the player send without it counting as spamming?");
|
||||
set(Configuration.CHAT_SPAM_ACTIONS, "What should be done if a player is trying to spam the chat.\nUnit is number of chat messages above the limit you declared above.");
|
||||
|
||||
}
|
||||
|
||||
private static void set(OptionNode id, String text) {
|
||||
explainations.put(id, text);
|
||||
}
|
||||
|
||||
public static String get(OptionNode id) {
|
||||
String result = explainations.get(id);
|
||||
|
||||
if(result == null) {
|
||||
result = "No description available";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
128
src/cc/co/evenprime/bukkit/nocheat/config/FlatFileAction.java
Normal file
128
src/cc/co/evenprime/bukkit/nocheat/config/FlatFileAction.java
Normal file
@ -0,0 +1,128 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.config;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.types.Action;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.types.ConsolecommandAction;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.types.LogAction;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.types.SpecialAction;
|
||||
import cc.co.evenprime.bukkit.nocheat.log.LogLevel;
|
||||
|
||||
public class FlatFileAction {
|
||||
|
||||
private final File file;
|
||||
|
||||
public FlatFileAction(File file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
public List<Action> read() {
|
||||
|
||||
List<Action> actions = new ArrayList<Action>();
|
||||
|
||||
BufferedReader reader;
|
||||
try {
|
||||
reader = new BufferedReader(new FileReader(file));
|
||||
String line = null;
|
||||
while((line = reader.readLine()) != null) {
|
||||
try {
|
||||
if(line.trim().length() > 0 && !line.startsWith("#")) {
|
||||
actions.add(parseLine(line));
|
||||
}
|
||||
} catch(IllegalArgumentException e) {
|
||||
System.out.println("NoCheat: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
reader.close();
|
||||
|
||||
} catch(FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
} catch(IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return actions;
|
||||
}
|
||||
|
||||
private Action parseLine(String line) {
|
||||
|
||||
// Split the line into some parts
|
||||
String parts[] = line.split("\\s+", 5);
|
||||
|
||||
// four pieces is the minimum we need, no matter what it is
|
||||
if(parts.length < 4) {
|
||||
throw new IllegalArgumentException("The line "+line+" of the file "+file.getName()+" is malformed. It has not enough parts.");
|
||||
}
|
||||
|
||||
String type = parts[0];
|
||||
String name = parts[1];
|
||||
|
||||
int delay = 0;
|
||||
try {
|
||||
delay = Integer.parseInt(parts[2]);
|
||||
}
|
||||
catch(Exception e) {
|
||||
throw new IllegalArgumentException("Couldn't parse third parameter of action "+name+" from file "+file.getName()+". It is "+parts[2]+" but should be a number.");
|
||||
}
|
||||
|
||||
int repeat = 0;
|
||||
try {
|
||||
repeat = Integer.parseInt(parts[3]);
|
||||
}
|
||||
catch(Exception e) {
|
||||
throw new IllegalArgumentException("Couldn't parse fourth parameter of action "+name+" from file "+file.getName()+". It is "+parts[2]+" but should be a number.");
|
||||
}
|
||||
|
||||
if(type.equalsIgnoreCase("log")) {
|
||||
// A log action, it seems
|
||||
if(parts.length < 5) {
|
||||
throw new IllegalArgumentException("Missing fifth parameter of action "+name+" from file "+file.getName()+".");
|
||||
}
|
||||
|
||||
return readLogAction(name, delay, repeat, parts[4]);
|
||||
}
|
||||
else if(type.equalsIgnoreCase("consolecommand")) {
|
||||
// A consolecommand action, it seems
|
||||
if(parts.length < 5) {
|
||||
throw new IllegalArgumentException("Missing fifth parameter of action "+name+" from file "+file.getName()+".");
|
||||
}
|
||||
|
||||
return new ConsolecommandAction(name, delay, repeat, parts[4]);
|
||||
}
|
||||
else if(type.equalsIgnoreCase("special")) {
|
||||
// A "special" actions, it seems
|
||||
return new SpecialAction(name, delay, repeat);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Unknown action type "+type+ " of action with name "+name+".");
|
||||
}
|
||||
}
|
||||
|
||||
// Moved outside because of bigger complexity of log message parsing
|
||||
private Action readLogAction(String name, int delay, int repeat, String lastPart) {
|
||||
|
||||
String[] rest = lastPart.split("\\s+", 2);
|
||||
|
||||
if(rest.length < 2) {
|
||||
throw new IllegalArgumentException("Missing sixth parameter of action "+name+" from file "+file.getName()+".");
|
||||
}
|
||||
|
||||
LogLevel level;
|
||||
try {
|
||||
level = LogLevel.getLogLevelFromString(rest[0]);
|
||||
}
|
||||
catch(IllegalArgumentException e) {
|
||||
throw new IllegalArgumentException("Illegal fifth parameter of action "+name+". "+e.getMessage());
|
||||
}
|
||||
|
||||
return new LogAction(name, delay, repeat, level, rest[1]);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,258 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.config;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.ActionList;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.ActionManager;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.types.Action;
|
||||
import cc.co.evenprime.bukkit.nocheat.log.LogLevel;
|
||||
|
||||
public class FlatFileConfiguration extends Configuration {
|
||||
|
||||
private final File file;
|
||||
|
||||
public FlatFileConfiguration(Configuration defaults, boolean copyDefaults, File file) {
|
||||
super(defaults, copyDefaults);
|
||||
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
public void load(ActionManager action) throws IOException {
|
||||
|
||||
BufferedReader r = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
|
||||
|
||||
String line = null;
|
||||
|
||||
while((line = r.readLine()) != null) {
|
||||
parse(line, action);
|
||||
}
|
||||
|
||||
r.close();
|
||||
|
||||
}
|
||||
|
||||
private void parse(String line, ActionManager action) throws IOException {
|
||||
|
||||
line = line.trim();
|
||||
|
||||
// Is it a key/value pair?
|
||||
if(line.startsWith("#") || !line.contains("=")) {
|
||||
return;
|
||||
}
|
||||
|
||||
String pair[] = line.split("=", 2);
|
||||
|
||||
String key = pair[0].trim();
|
||||
String value = pair[1].trim();
|
||||
|
||||
// Find out which option we have in front of us
|
||||
OptionNode node = getOptionNodeForString(ROOT, key);
|
||||
|
||||
if(node == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (node.getType()) {
|
||||
case ACTIONLIST:
|
||||
this.set(node, parseActionList(node, key, removeQuotationMarks(value), action));
|
||||
break;
|
||||
case STRING:
|
||||
this.set(node, removeQuotationMarks(value));
|
||||
break;
|
||||
case INTEGER:
|
||||
this.set(node, Integer.valueOf(removeQuotationMarks(value)));
|
||||
break;
|
||||
case LOGLEVEL:
|
||||
this.set(node, LogLevel.getLogLevelFromString(removeQuotationMarks(value)));
|
||||
break;
|
||||
case BOOLEAN:
|
||||
this.set(node, Boolean.valueOf(removeQuotationMarks(value)));
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown node type " + node.getType());
|
||||
}
|
||||
}
|
||||
|
||||
private ActionList parseActionList(OptionNode node, String key, String value, ActionManager action) {
|
||||
|
||||
String[] s = key.split("\\.");
|
||||
String treshold = s[s.length - 1];
|
||||
|
||||
// See if we already got that actionlist created
|
||||
ActionList al = (ActionList) this.get(node);
|
||||
|
||||
if(al == null || al == this.getDefaults().getRecursive(node)) {
|
||||
al = new ActionList();
|
||||
}
|
||||
int th = Integer.parseInt(treshold);
|
||||
al.setActions(th, action.getActions(value.split("\\s+")));
|
||||
|
||||
return al;
|
||||
}
|
||||
|
||||
|
||||
private OptionNode getOptionNodeForString(OptionNode root, String key) {
|
||||
String parts[] = key.split("\\.", 2);
|
||||
|
||||
for(OptionNode node : root.getChildren()) {
|
||||
// Found the correct node?
|
||||
if(node.getName().equals(parts[0])) {
|
||||
if(node.isLeaf()) {
|
||||
return node;
|
||||
} else {
|
||||
return getOptionNodeForString(node, parts[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void save() {
|
||||
|
||||
try {
|
||||
if(file.getParentFile() != null)
|
||||
file.getParentFile().mkdirs();
|
||||
|
||||
file.createNewFile();
|
||||
BufferedWriter w = new BufferedWriter(new FileWriter(file));
|
||||
|
||||
w.write("# Want to know what these options do? Read at the end of this file.\r\n");
|
||||
|
||||
saveRecursive(w, ROOT);
|
||||
|
||||
w.write("\r\n\r\n");
|
||||
|
||||
saveDescriptionsRecursive(w, ROOT);
|
||||
|
||||
w.flush();
|
||||
w.close();
|
||||
} catch(IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void saveDescriptionsRecursive(BufferedWriter w, OptionNode node) throws IOException {
|
||||
if(!node.isLeaf()) {
|
||||
for(OptionNode o : node.getChildren()) {
|
||||
saveDescriptionsRecursive(w, o);
|
||||
}
|
||||
}
|
||||
|
||||
// Save a leaf node, if it's really stored here
|
||||
Object object = this.get(node);
|
||||
|
||||
if(object == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the full id of the node
|
||||
String id = node.getName();
|
||||
OptionNode i = node;
|
||||
|
||||
while((i = i.getParent()) != null && i.getName() != null && i.getName().length() > 0) {
|
||||
id = i.getName() + "." + id;
|
||||
}
|
||||
|
||||
w.write("\r\n\r\n# " + id + ":\r\n#\r\n");
|
||||
|
||||
String explaination = Explainations.get(node);
|
||||
|
||||
w.write("# " + explaination.replaceAll("\n", "\r\n# "));
|
||||
}
|
||||
|
||||
private void saveRecursive(BufferedWriter w, OptionNode node) throws IOException {
|
||||
|
||||
if(!node.isLeaf()) {
|
||||
|
||||
for(OptionNode o : node.getChildren()) {
|
||||
|
||||
if(node == ROOT) {
|
||||
w.write("\r\n");
|
||||
}
|
||||
|
||||
saveRecursive(w, o);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Save a leaf node, if it's really stored here
|
||||
Object object = this.get(node);
|
||||
|
||||
if(object == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the full id of the node
|
||||
String id = node.getName();
|
||||
OptionNode i = node;
|
||||
|
||||
while((i = i.getParent()) != null && i.getName() != null && i.getName().length() > 0) {
|
||||
id = i.getName() + "." + id;
|
||||
}
|
||||
|
||||
switch (node.getType()) {
|
||||
case ACTIONLIST:
|
||||
saveActionList(w, id, (ActionList) object);
|
||||
break;
|
||||
case STRING:
|
||||
saveString(w, id, (String) object);
|
||||
break;
|
||||
case INTEGER:
|
||||
saveValue(w, id, object.toString());
|
||||
break;
|
||||
case LOGLEVEL:
|
||||
saveValue(w, id, object.toString());
|
||||
break;
|
||||
case BOOLEAN:
|
||||
saveValue(w, id, object.toString());
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown node type " + node.getType());
|
||||
}
|
||||
}
|
||||
|
||||
private void saveActionList(BufferedWriter w, String id, ActionList actionList) throws IOException {
|
||||
for(Integer treshold : actionList.getTresholds()) {
|
||||
String s = "";
|
||||
for(Action s2 : actionList.getActions(treshold)) {
|
||||
s = s + " " + s2.name;
|
||||
}
|
||||
saveValue(w, id + "." + treshold, s.trim());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void saveString(BufferedWriter w, String id, String value) throws IOException {
|
||||
saveValue(w, id, addQuotationMarks(value));
|
||||
}
|
||||
|
||||
private void saveValue(BufferedWriter w, String id, String value) throws IOException {
|
||||
w.write(id + " = " + value + "\r\n");
|
||||
}
|
||||
|
||||
protected String removeQuotationMarks(String s) {
|
||||
|
||||
s = s.trim();
|
||||
|
||||
if(s.startsWith("\"") && s.endsWith("\"")) {
|
||||
return s.substring(1, s.length() - 1);
|
||||
} else if(s.startsWith("\'") && s.endsWith("\'")) {
|
||||
return s.substring(1, s.length() - 1);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
protected String addQuotationMarks(String s) {
|
||||
|
||||
return "\"" + s + "\"";
|
||||
}
|
||||
}
|
60
src/cc/co/evenprime/bukkit/nocheat/config/OptionNode.java
Normal file
60
src/cc/co/evenprime/bukkit/nocheat/config/OptionNode.java
Normal file
@ -0,0 +1,60 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.config;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class OptionNode {
|
||||
|
||||
public enum DataType {
|
||||
PARENT, STRING, BOOLEAN, INTEGER, LOGLEVEL, ACTIONLIST
|
||||
};
|
||||
|
||||
private final String name;
|
||||
private final List<OptionNode> children;
|
||||
private final OptionNode parent;
|
||||
private final DataType type;
|
||||
|
||||
public OptionNode(String name, OptionNode parent, DataType type) {
|
||||
this.name = name;
|
||||
if(type == DataType.PARENT) {
|
||||
this.children = new LinkedList<OptionNode>();
|
||||
} else {
|
||||
this.children = null;
|
||||
}
|
||||
|
||||
if(parent != null) {
|
||||
parent.addChild(this);
|
||||
}
|
||||
|
||||
this.parent = parent;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public void addChild(OptionNode node) {
|
||||
if(this.type != DataType.PARENT) {
|
||||
throw new IllegalArgumentException("Can't a child to a leaf node.");
|
||||
}
|
||||
|
||||
this.children.add(node);
|
||||
}
|
||||
|
||||
public boolean isLeaf() {
|
||||
return this.type != DataType.PARENT;
|
||||
}
|
||||
|
||||
public List<OptionNode> getChildren() {
|
||||
return this.children;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public OptionNode getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public DataType getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package cc.co.evenprime.bukkit.nocheat;
|
||||
package cc.co.evenprime.bukkit.nocheat.config;
|
||||
|
||||
/**
|
||||
* The various permission nodes used by NoCheat
|
||||
@ -17,7 +17,6 @@ public class Permissions {
|
||||
public final static String MOVE_SNEAK = MOVE + ".sneaking";
|
||||
public final static String MOVE_SWIM = MOVE + ".swimming";
|
||||
public final static String MOVE_FLY = MOVE + ".flying";
|
||||
public final static String MOVE_NOCLIP = MOVE + ".noclip";
|
||||
public final static String MOVE_NOFALL = MOVE + ".nofall";
|
||||
public final static String MOVE_MOREPACKETS = MOVE + ".morepackets";
|
||||
|
||||
@ -36,6 +35,8 @@ public class Permissions {
|
||||
public final static String CHAT_SPAM = CHAT + ".spam";
|
||||
|
||||
public final static String ADMIN_CHATLOG = ADMIN + ".chatlog";
|
||||
public static final String ADMIN_PERMLIST = ADMIN + ".permlist";
|
||||
public static final String ADMIN_RELOAD = ADMIN + ".reload";
|
||||
|
||||
private Permissions() {}
|
||||
}
|
@ -2,6 +2,7 @@ package cc.co.evenprime.bukkit.nocheat.config.cache;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.ActionList;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.Configuration;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.DefaultConfiguration;
|
||||
|
||||
/**
|
||||
* Configurations specific for the "BlockBreak" checks
|
||||
@ -22,14 +23,12 @@ public class CCBlockBreak {
|
||||
|
||||
public CCBlockBreak(Configuration data) {
|
||||
|
||||
check = data.getBoolean("blockbreak.check");
|
||||
|
||||
reachCheck = data.getBoolean("blockbreak.reach.check");
|
||||
reachDistance = ((double) data.getInteger("blockbreak.reach.reachlimit")) / 100D;
|
||||
reachActions = data.getActionList("blockbreak.reach.actions");
|
||||
|
||||
directionCheck = data.getBoolean("blockbreak.direction.check");
|
||||
directionActions = data.getActionList("blockbreak.direction.actions");
|
||||
checkinstabreakblocks = data.getBoolean("blockbreak.direction.checkinstabreakblocks");
|
||||
check = data.getBoolean(DefaultConfiguration.BLOCKBREAK_CHECK);
|
||||
reachCheck = data.getBoolean(DefaultConfiguration.BLOCKBREAK_REACH_CHECK);
|
||||
reachDistance = ((double) data.getInteger(DefaultConfiguration.BLOCKBREAK_REACH_LIMIT)) / 100D;
|
||||
reachActions = data.getActionList(DefaultConfiguration.BLOCKBREAK_REACH_ACTIONS);
|
||||
checkinstabreakblocks = data.getBoolean(DefaultConfiguration.BLOCKBREAK_DIRECTION_CHECKINSTABREAKBLOCKS);
|
||||
directionCheck = data.getBoolean(DefaultConfiguration.BLOCKBREAK_DIRECTION_CHECK);
|
||||
directionActions = data.getActionList(DefaultConfiguration.BLOCKBREAK_DIRECTION_ACTIONS);
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package cc.co.evenprime.bukkit.nocheat.config.cache;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.ActionList;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.Configuration;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.DefaultConfiguration;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -20,13 +21,14 @@ public class CCBlockPlace {
|
||||
|
||||
public CCBlockPlace(Configuration data) {
|
||||
|
||||
check = data.getBoolean("blockplace.check");
|
||||
onliquidCheck = data.getBoolean("blockplace.onliquid.check");
|
||||
onliquidActions = data.getActionList("blockplace.onliquid.actions");
|
||||
check = data.getBoolean(DefaultConfiguration.BLOCKPLACE_CHECK);
|
||||
|
||||
onliquidCheck = data.getBoolean(DefaultConfiguration.BLOCKPLACE_ONLIQUID_CHECK);
|
||||
onliquidActions = data.getActionList(DefaultConfiguration.BLOCKPLACE_ONLIQUID_ACTIONS);
|
||||
|
||||
reachCheck = data.getBoolean("blockplace.reach.check");
|
||||
reachDistance = data.getInteger("blockplace.reach.reachlimit");
|
||||
reachActions = data.getActionList("blockplace.reach.actions");
|
||||
reachCheck = data.getBoolean(DefaultConfiguration.BLOCKPLACE_REACH_CHECK);
|
||||
reachDistance = data.getInteger(DefaultConfiguration.BLOCKPLACE_REACH_LIMIT);
|
||||
reachActions = data.getActionList(DefaultConfiguration.BLOCKPLACE_REACH_ACTIONS);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package cc.co.evenprime.bukkit.nocheat.config.cache;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.ActionList;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.Configuration;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.DefaultConfiguration;
|
||||
|
||||
public class CCChat {
|
||||
|
||||
@ -13,11 +14,11 @@ public class CCChat {
|
||||
|
||||
public CCChat(Configuration data) {
|
||||
|
||||
check = data.getBoolean("chat.check");
|
||||
spamCheck = data.getBoolean("chat.spam.check");
|
||||
spamTimeframe = data.getInteger("chat.spam.timeframe");
|
||||
spamLimit = data.getInteger("chat.spam.limit");
|
||||
spamActions = data.getActionList("chat.spam.actions");
|
||||
check = data.getBoolean(DefaultConfiguration.CHAT_CHECK);
|
||||
spamCheck = data.getBoolean(DefaultConfiguration.CHAT_SPAM_CHECK);
|
||||
spamTimeframe = data.getInteger(DefaultConfiguration.CHAT_SPAM_TIMEFRAME);
|
||||
spamLimit = data.getInteger(DefaultConfiguration.CHAT_SPAM_LIMIT);
|
||||
spamActions = data.getActionList(DefaultConfiguration.CHAT_SPAM_ACTIONS);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.config.cache;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.config.Configuration;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.DefaultConfiguration;
|
||||
|
||||
|
||||
public class CCDebug {
|
||||
@ -10,6 +11,6 @@ public class CCDebug {
|
||||
|
||||
public CCDebug(Configuration data) {
|
||||
|
||||
showchecks = data.getBoolean("debug.showactivechecks");
|
||||
showchecks = data.getBoolean(DefaultConfiguration.DEBUG_SHOWACTIVECHECKS);
|
||||
}
|
||||
}
|
||||
|
@ -2,25 +2,24 @@ package cc.co.evenprime.bukkit.nocheat.config.cache;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.ActionList;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.Configuration;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.DefaultConfiguration;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class CCInteract {
|
||||
|
||||
public final boolean check;
|
||||
|
||||
public final boolean durabilityCheck;
|
||||
public final boolean check;
|
||||
|
||||
public final boolean durabilityCheck;
|
||||
public final ActionList durabilityActions;
|
||||
|
||||
public CCInteract(Configuration data) {
|
||||
|
||||
check = data.getBoolean("interact.check");
|
||||
durabilityCheck = data.getBoolean("interact.durability.check");
|
||||
durabilityActions = data.getActionList("interact.durability.actions");
|
||||
check = data.getBoolean(DefaultConfiguration.INTERACT_CHECK);
|
||||
durabilityCheck = data.getBoolean(DefaultConfiguration.INTERACT_DURABILITY_CHECK);
|
||||
durabilityActions = data.getActionList(DefaultConfiguration.INTERACT_DURABILITY_ACTIONS);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package cc.co.evenprime.bukkit.nocheat.config.cache;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.config.Configuration;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.DefaultConfiguration;
|
||||
import cc.co.evenprime.bukkit.nocheat.log.LogLevel;
|
||||
|
||||
/**
|
||||
@ -21,10 +22,10 @@ public class CCLogging {
|
||||
|
||||
public CCLogging(Configuration data, Logger worldSpecificFileLogger) {
|
||||
|
||||
active = data.getBoolean("logging.active");
|
||||
fileLevel = data.getLogLevel("logging.filelevel");
|
||||
consoleLevel = data.getLogLevel("logging.consolelevel");
|
||||
chatLevel = data.getLogLevel("logging.chatlevel");
|
||||
active = data.getBoolean(DefaultConfiguration.LOGGING_ACTIVE);
|
||||
fileLevel = data.getLogLevel(DefaultConfiguration.LOGGING_FILELEVEL);
|
||||
consoleLevel = data.getLogLevel(DefaultConfiguration.LOGGING_CONSOLELEVEL);
|
||||
chatLevel = data.getLogLevel(DefaultConfiguration.LOGGING_CHATLEVEL);
|
||||
|
||||
filelogger = worldSpecificFileLogger;
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package cc.co.evenprime.bukkit.nocheat.config.cache;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.ActionList;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.Configuration;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.DefaultConfiguration;
|
||||
|
||||
/**
|
||||
* Configurations specific for the Move Checks. Every world gets one of these
|
||||
@ -29,9 +30,6 @@ public class CCMoving {
|
||||
public final double flyingSpeedLimitHorizontal;
|
||||
public final ActionList flyingActions;
|
||||
|
||||
public final boolean noclipCheck;
|
||||
public final ActionList noclipActions;
|
||||
|
||||
public final boolean nofallCheck;
|
||||
public final float nofallMultiplier;
|
||||
public final ActionList nofallActions;
|
||||
@ -41,35 +39,31 @@ public class CCMoving {
|
||||
|
||||
public CCMoving(Configuration data) {
|
||||
|
||||
check = data.getBoolean("moving.check");
|
||||
identifyCreativeMode = data.getBoolean("moving.identifycreativemode");
|
||||
check = data.getBoolean(DefaultConfiguration.MOVING_CHECK);
|
||||
identifyCreativeMode = data.getBoolean(DefaultConfiguration.MOVING_IDENTIFYCREATIVEMODE);
|
||||
|
||||
runflyCheck = data.getBoolean(DefaultConfiguration.MOVING_RUNFLY_CHECK);
|
||||
walkingSpeedLimit = ((double) data.getInteger(DefaultConfiguration.MOVING_RUNFLY_WALKINGSPEEDLIMIT)) / 100D;
|
||||
sprintingSpeedLimit = ((double) data.getInteger(DefaultConfiguration.MOVING_RUNFLY_SPRINTINGSPEEDLIMIT)) / 100D;
|
||||
jumpheight = ((double) data.getInteger(DefaultConfiguration.MOVING_RUNFLY_JUMPHEIGHT)) / 100D;
|
||||
actions = data.getActionList(DefaultConfiguration.MOVING_RUNFLY_ACTIONS);
|
||||
|
||||
runflyCheck = data.getBoolean("moving.runfly.check");
|
||||
swimmingCheck = data.getBoolean(DefaultConfiguration.MOVING_RUNFLY_CHECKSWIMMING);
|
||||
swimmingSpeedLimit = ((double) data.getInteger(DefaultConfiguration.MOVING_RUNFLY_SWIMMINGSPEEDLIMIT)) / 100D;
|
||||
sneakingCheck = data.getBoolean(DefaultConfiguration.MOVING_RUNFLY_CHECKSNEAKING);
|
||||
sneakingSpeedLimit = ((double) data.getInteger(DefaultConfiguration.MOVING_RUNFLY_SNEAKINGSPEEDLIMIT)) / 100D;
|
||||
|
||||
walkingSpeedLimit = ((double) data.getInteger("moving.runfly.walkingspeedlimit")) / 100D;
|
||||
sprintingSpeedLimit = ((double) data.getInteger("moving.runfly.sprintingspeedlimit")) / 100D;
|
||||
jumpheight = ((double) data.getInteger("moving.runfly.jumpheight")) / 100D;
|
||||
actions = data.getActionList("moving.runfly.actions");
|
||||
allowFlying = data.getBoolean(DefaultConfiguration.MOVING_RUNFLY_ALLOWLIMITEDFLYING);
|
||||
flyingSpeedLimitVertical = ((double) data.getInteger(DefaultConfiguration.MOVING_RUNFLY_FLYINGSPEEDLIMITVERTICAL)) / 100D;
|
||||
flyingSpeedLimitHorizontal = ((double) data.getInteger(DefaultConfiguration.MOVING_RUNFLY_FLYINGSPEEDLIMITHORIZONTAL)) / 100D;
|
||||
flyingActions = data.getActionList(DefaultConfiguration.MOVING_RUNFLY_FLYINGACTIONS);
|
||||
|
||||
swimmingCheck = data.getBoolean("moving.runfly.checkswimming");
|
||||
swimmingSpeedLimit = ((double) data.getInteger("moving.runfly.swimmingspeedlimit")) / 100D;
|
||||
sneakingCheck = data.getBoolean("moving.runfly.checksneaking");
|
||||
sneakingSpeedLimit = ((double) data.getInteger("moving.runfly.sneakingspeedlimit")) / 100D;
|
||||
nofallCheck = data.getBoolean(DefaultConfiguration.MOVING_RUNFLY_CHECKNOFALL);
|
||||
nofallMultiplier = ((float) data.getInteger(DefaultConfiguration.MOVING_RUNFLY_NOFALLMULTIPLIER)) / 100F;
|
||||
nofallActions = data.getActionList(DefaultConfiguration.MOVING_RUNFLY_NOFALLACTIONS);
|
||||
|
||||
allowFlying = data.getBoolean("moving.runfly.allowlimitedflying");
|
||||
flyingSpeedLimitVertical = ((double) data.getInteger("moving.runfly.flyingspeedlimitvertical")) / 100D;
|
||||
flyingSpeedLimitHorizontal = ((double) data.getInteger("moving.runfly.flyingspeedlimithorizontal")) / 100D;
|
||||
flyingActions = data.getActionList("moving.runfly.flyingactions");
|
||||
|
||||
nofallCheck = data.getBoolean("moving.runfly.checknofall");
|
||||
nofallMultiplier = ((float) data.getInteger("moving.runfly.nofallmultiplier")) / 100F;
|
||||
nofallActions = data.getActionList("moving.runfly.nofallactions");
|
||||
|
||||
noclipCheck = data.getBoolean("moving.noclip.check");
|
||||
noclipActions = data.getActionList("moving.noclip.actions");
|
||||
|
||||
morePacketsCheck = data.getBoolean("moving.morepackets.check");
|
||||
morePacketsActions = data.getActionList("moving.morepackets.actions");
|
||||
morePacketsCheck = data.getBoolean(DefaultConfiguration.MOVING_MOREPACKETS_CHECK);
|
||||
morePacketsActions = data.getActionList(DefaultConfiguration.MOVING_MOREPACKETS_ACTIONS);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import cc.co.evenprime.bukkit.nocheat.config.Configuration;
|
||||
|
||||
/**
|
||||
* A class to keep all configurables of the plugin associated with
|
||||
* a world, everything unmodifiable.
|
||||
* a world, everything unmodifiable for security/performance
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
|
@ -1,50 +0,0 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.config.tree;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* A special node of the configuration tree
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public class ActionListOption extends ChildOption {
|
||||
|
||||
private final LinkedList<ActionOption> actionOptions = new LinkedList<ActionOption>();
|
||||
|
||||
public ActionListOption(String identifier) {
|
||||
super(identifier);
|
||||
}
|
||||
|
||||
public void add(Integer treshold, String actions) {
|
||||
actionOptions.add(new ActionOption(treshold, actions));
|
||||
Collections.sort(actionOptions);
|
||||
}
|
||||
|
||||
public List<ActionOption> getChildOptions() {
|
||||
return actionOptions;
|
||||
}
|
||||
|
||||
public void remove(ActionOption actionOption) {
|
||||
this.actionOptions.remove(actionOption);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionListOption clone() {
|
||||
|
||||
ActionListOption o = new ActionListOption(this.getIdentifier());
|
||||
for(ActionOption ao : getChildOptions()) {
|
||||
o.add(ao.getTreshold(), ao.getStringValue());
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
actionOptions.clear();
|
||||
|
||||
}
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.config.tree;
|
||||
|
||||
/**
|
||||
* A special node of the configuration tree
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public class ActionOption extends ChildOption implements Comparable<ActionOption> {
|
||||
|
||||
private final int treshold;
|
||||
private String value;
|
||||
|
||||
public ActionOption(Integer treshold, String value) {
|
||||
|
||||
super(treshold.toString());
|
||||
this.treshold = treshold;
|
||||
this.value = value;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStringValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setStringValue(String value) {
|
||||
this.value = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getTreshold() {
|
||||
return treshold;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionOption clone() {
|
||||
return new ActionOption(treshold, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ActionOption o) {
|
||||
if(treshold < o.treshold) {
|
||||
return -1;
|
||||
} else if(treshold == o.treshold) {
|
||||
return 0;
|
||||
} else
|
||||
return 1;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "ActionOption " + getFullIdentifier() + " " + getStringValue();
|
||||
}
|
||||
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.config.tree;
|
||||
|
||||
/**
|
||||
* A node of the configuration tree
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public class BooleanOption extends ChildOption {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 2258827414736580449L;
|
||||
|
||||
private boolean value;
|
||||
private boolean isMaster = false;
|
||||
|
||||
public BooleanOption(String name, boolean initialValue, boolean isMaster) {
|
||||
|
||||
super(name);
|
||||
this.value = initialValue;
|
||||
this.isMaster = isMaster;
|
||||
}
|
||||
|
||||
public void setBooleanValue(boolean value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStringValue() {
|
||||
return Boolean.toString(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setStringValue(String value) {
|
||||
try {
|
||||
this.value = Boolean.parseBoolean(value);
|
||||
return true;
|
||||
} catch(Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getBooleanValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BooleanOption clone() {
|
||||
return new BooleanOption(this.getIdentifier(), value, isMaster);
|
||||
}
|
||||
|
||||
public boolean isMaster() {
|
||||
return isMaster;
|
||||
}
|
||||
|
||||
public void setMaster(boolean master) {
|
||||
this.isMaster = master;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "BooleanOption " + this.getFullIdentifier() + " " + getStringValue() + (isMaster ? " master" : "");
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.config.tree;
|
||||
|
||||
/**
|
||||
* A leaf of the configuration tree
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public abstract class ChildOption extends Option implements Cloneable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -4648294833934457776L;
|
||||
|
||||
private String value;
|
||||
|
||||
public ChildOption(String identifier) {
|
||||
super(identifier);
|
||||
}
|
||||
|
||||
public String getStringValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public boolean setStringValue(String string) {
|
||||
this.value = string;
|
||||
return true;
|
||||
}
|
||||
|
||||
public abstract ChildOption clone();
|
||||
}
|
@ -1,239 +0,0 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.config.tree;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.ActionList;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.Configuration;
|
||||
import cc.co.evenprime.bukkit.nocheat.log.LogLevel;
|
||||
|
||||
/**
|
||||
* Only used during parsing of the configuration files and for the GUI wizard
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public class ConfigurationTree implements Configuration {
|
||||
|
||||
// Each tree has a root option that does nothing
|
||||
private final ParentOption root = new ParentOption("");
|
||||
|
||||
// Each tree can have a "parent" tree
|
||||
private ConfigurationTree parent = null;
|
||||
|
||||
/**
|
||||
* Start a new tree
|
||||
*
|
||||
* @param parent
|
||||
*/
|
||||
public ConfigurationTree() {}
|
||||
|
||||
public void setParent(ConfigurationTree parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public ConfigurationTree getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specific option from this tree or its parent(s), if this
|
||||
* tree doesn't contain this option
|
||||
*
|
||||
* @param fullIdentifier
|
||||
* @return
|
||||
*/
|
||||
private Option getOptionRecursive(String fullIdentifier) {
|
||||
|
||||
// Find out the partial identifiers
|
||||
String[] identifiers = fullIdentifier.split("\\.");
|
||||
|
||||
// Start at the root
|
||||
Option o = root;
|
||||
|
||||
// Go through all partial identifiers
|
||||
for(int i = 0; i < identifiers.length; i++) {
|
||||
if(o instanceof ParentOption) {
|
||||
for(Option o2 : ((ParentOption) o).getChildOptions()) {
|
||||
if(o2.getIdentifier().equals(identifiers[i])) {
|
||||
o = o2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else
|
||||
break;
|
||||
}
|
||||
|
||||
// Does the node we last met match our searched node and is it enabled?
|
||||
if(o.getFullIdentifier().equals(fullIdentifier) && o.isActive()) {
|
||||
return o;
|
||||
}
|
||||
// No, then ask our parent (if possible)
|
||||
else if(parent != null) {
|
||||
return parent.getOptionRecursive(fullIdentifier);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specific option from this tree
|
||||
*
|
||||
* @param fullIdentifier
|
||||
* @return
|
||||
*/
|
||||
public Option getOption(String fullIdentifier) {
|
||||
|
||||
// Find out the partial identifiers
|
||||
String[] identifiers = fullIdentifier.split("\\.");
|
||||
|
||||
// Start at the root
|
||||
Option o = root;
|
||||
|
||||
// Go through all partial identifiers
|
||||
for(int i = 0; i < identifiers.length; i++) {
|
||||
if(o instanceof ParentOption) {
|
||||
for(Option o2 : ((ParentOption) o).getChildOptions()) {
|
||||
if(o2.getIdentifier().equals(identifiers[i])) {
|
||||
o = o2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else
|
||||
break;
|
||||
}
|
||||
|
||||
// Does the node we last met match our searched node?
|
||||
if(o.getFullIdentifier().equals(fullIdentifier)) {
|
||||
return o;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a option to this tree, at the specified parent
|
||||
*
|
||||
* @param parent
|
||||
* @param option
|
||||
*/
|
||||
public void add(String parent, Option option) {
|
||||
try {
|
||||
if(parent == null || parent == "") {
|
||||
add(option);
|
||||
} else {
|
||||
ParentOption po = (ParentOption) getOption(parent);
|
||||
po.add(option);
|
||||
}
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a option at the root
|
||||
*
|
||||
* @param option
|
||||
*/
|
||||
public void add(Option option) {
|
||||
root.add(option);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<Option> getAllOptions() {
|
||||
List<Option> options = new ArrayList<Option>();
|
||||
|
||||
ParentOption o = root;
|
||||
|
||||
for(Option o2 : o.getChildOptions()) {
|
||||
if(o2.isActive()) {
|
||||
options.addAll(getAllOptions(o2));
|
||||
}
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
private List<Option> getAllOptions(Option subtree) {
|
||||
|
||||
List<Option> options = new ArrayList<Option>();
|
||||
|
||||
options.add(subtree);
|
||||
|
||||
if(subtree instanceof ParentOption) {
|
||||
for(Option child : ((ParentOption) subtree).getChildOptions()) {
|
||||
options.addAll(getAllOptions(child));
|
||||
}
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* cc.co.evenprime.bukkit.nocheat.config.tree.ConfigurationProvider#getBoolean
|
||||
* (java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public boolean getBoolean(String string) {
|
||||
return ((BooleanOption) this.getOptionRecursive(string)).getBooleanValue();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see cc.co.evenprime.bukkit.nocheat.config.tree.ConfigurationProvider#
|
||||
* getActionList(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public ActionList getActionList(String string) {
|
||||
ActionList actionList = new ActionList();
|
||||
ActionListOption option = (ActionListOption) this.getOptionRecursive(string);
|
||||
|
||||
for(ActionOption ao : option.getChildOptions()) {
|
||||
actionList.addEntry(ao.getTreshold(), ao.getStringValue().split(" "));
|
||||
}
|
||||
return actionList;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* cc.co.evenprime.bukkit.nocheat.config.tree.ConfigurationProvider#getInteger
|
||||
* (java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public int getInteger(String string) {
|
||||
return ((IntegerOption) this.getOptionRecursive(string)).getIntegerValue();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* cc.co.evenprime.bukkit.nocheat.config.tree.ConfigurationProvider#getString
|
||||
* (java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public String getString(String string) {
|
||||
return ((ChildOption) this.getOptionRecursive(string)).getStringValue();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* cc.co.evenprime.bukkit.nocheat.config.tree.ConfigurationProvider#getLogLevel
|
||||
* (java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public LogLevel getLogLevel(String string) {
|
||||
return ((LogLevelOption) this.getOptionRecursive(string)).getLogLevelValue();
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.config.tree;
|
||||
|
||||
/**
|
||||
* A node for the configuration tree
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public class IntegerOption extends StringOption {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 2258827414736580449L;
|
||||
|
||||
public IntegerOption(String name, int initialValue) {
|
||||
|
||||
super(name, String.valueOf(initialValue), 5);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(String value) {
|
||||
|
||||
if(!super.isValid(value))
|
||||
return false;
|
||||
|
||||
try {
|
||||
Integer.parseInt(value);
|
||||
return true;
|
||||
} catch(Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int getIntegerValue() {
|
||||
return Integer.parseInt(this.getStringValue());
|
||||
}
|
||||
|
||||
public IntegerOption clone() {
|
||||
return new IntegerOption(this.getIdentifier(), this.getIntegerValue());
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.config.tree;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.log.LogLevel;
|
||||
|
||||
/**
|
||||
* A node for the configuration tree
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public class LogLevelOption extends ChildOption {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -1609308017422576285L;
|
||||
|
||||
private LogLevel option;
|
||||
|
||||
public LogLevelOption(String identifier, LogLevel initialValue) {
|
||||
|
||||
super(identifier);
|
||||
this.option = initialValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStringValue() {
|
||||
return option.name;
|
||||
}
|
||||
|
||||
public boolean setStringValue(String value) {
|
||||
option = LogLevel.getLogLevelFromString(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setLogLevelValue(LogLevel value) {
|
||||
this.option = value;
|
||||
}
|
||||
|
||||
public LogLevel getLogLevelValue() {
|
||||
return this.option;
|
||||
}
|
||||
|
||||
public LogLevelOption clone() {
|
||||
return new LogLevelOption(this.getIdentifier(), this.option);
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.config.tree;
|
||||
|
||||
/**
|
||||
* A node for the configuration tree
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public class MediumStringOption extends StringOption {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 2258827414736580449L;
|
||||
|
||||
public MediumStringOption(String name, String initialValue) {
|
||||
super(name, initialValue, 30);
|
||||
}
|
||||
|
||||
public MediumStringOption clone() {
|
||||
return new MediumStringOption(this.getIdentifier(), this.getStringValue());
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.config.tree;
|
||||
|
||||
/**
|
||||
* A node for the configuration tree
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public abstract class Option {
|
||||
|
||||
private final String identifier;
|
||||
private Option parent;
|
||||
|
||||
private boolean active = true;
|
||||
|
||||
public Option(String identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
public final String getIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
public final void setParent(Option parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public final Option getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public final String getFullIdentifier() {
|
||||
return (parent == null || parent.getFullIdentifier() == "") ? identifier : parent.getFullIdentifier() + "." + identifier;
|
||||
}
|
||||
|
||||
public void setActive(boolean b) {
|
||||
active = b;
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.config.tree;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* A node for the configuration tree
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public class ParentOption extends Option {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 3162246550749560727L;
|
||||
|
||||
private final LinkedList<Option> children = new LinkedList<Option>();
|
||||
|
||||
public ParentOption(String identifier) {
|
||||
super(identifier);
|
||||
}
|
||||
|
||||
public final Collection<Option> getChildOptions() {
|
||||
return Collections.unmodifiableCollection(children);
|
||||
}
|
||||
|
||||
public final void add(Option option) {
|
||||
children.addLast(option);
|
||||
option.setParent(this);
|
||||
}
|
||||
|
||||
public Option getChild(String identifier) {
|
||||
|
||||
for(Option o : children) {
|
||||
if(o.getIdentifier().equals(identifier)) {
|
||||
return o;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.config.tree;
|
||||
|
||||
/**
|
||||
* A node for the configuration tree
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public abstract class StringOption extends ChildOption {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -8189248456599421250L;
|
||||
|
||||
private String value;
|
||||
private final int length;
|
||||
|
||||
protected StringOption(String name, String initialValue, int preferredLength) {
|
||||
|
||||
super(name);
|
||||
this.value = initialValue;
|
||||
this.length = preferredLength;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStringValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public boolean setStringValue(String value) {
|
||||
if(isValid(value)) {
|
||||
this.value = value;
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean isValid(String value) {
|
||||
return value != null;
|
||||
}
|
||||
|
||||
public int getPreferredLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
public boolean hasPreferredLength() {
|
||||
return length != -1;
|
||||
}
|
||||
}
|
@ -20,6 +20,7 @@ public class DataManager {
|
||||
private final Map<Player, InteractData> interactData = new HashMap<Player, InteractData>();
|
||||
private final Map<Player, BlockPlaceData> blockPlaceData = new HashMap<Player, BlockPlaceData>();
|
||||
private final Map<Player, ChatData> chatData = new HashMap<Player, ChatData>();
|
||||
private final Map<Player, LogData> logData = new HashMap<Player, LogData>();
|
||||
|
||||
public DataManager() {
|
||||
|
||||
@ -102,4 +103,20 @@ public class DataManager {
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public LogData getLogData(Player player) {
|
||||
LogData data;
|
||||
|
||||
// intentionally not thread-safe, because bukkit events are handled
|
||||
// in sequence anyway, so zero chance of two events of the same
|
||||
// player being handled at the same time
|
||||
// And if it still happens by accident, it's no real loss anyway
|
||||
data = logData.get(player);
|
||||
if(data == null) {
|
||||
data = new LogData(player);
|
||||
logData.put(player, data);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
32
src/cc/co/evenprime/bukkit/nocheat/data/LogData.java
Normal file
32
src/cc/co/evenprime/bukkit/nocheat/data/LogData.java
Normal file
@ -0,0 +1,32 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.data;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* Everything that could be relevant for logging or consolecommand actions
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public class LogData {
|
||||
|
||||
// The player never changes
|
||||
public final Player player;
|
||||
public String check;
|
||||
public int violationLevel;
|
||||
public Location toLocation;
|
||||
public int packets;
|
||||
public String text;
|
||||
public Material placedMaterial;
|
||||
public Block placed;
|
||||
public Block placedAgainst;
|
||||
public double reachdistance;
|
||||
public float falldistance;
|
||||
|
||||
public LogData(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
}
|
@ -26,15 +26,11 @@ public class MovingData {
|
||||
public float fallDistance = 0.0F;
|
||||
public float lastAddedFallDistance = 0.0F;
|
||||
|
||||
public int noclipX;
|
||||
public int noclipY;
|
||||
public int noclipZ;
|
||||
|
||||
public double horizontalBuffer;
|
||||
public int bunnyhopdelay = 0;
|
||||
|
||||
public int morePacketsCounter;
|
||||
public double morePacketsBuffer = 50;
|
||||
public int morePacketsBuffer = 50;
|
||||
public Location morePacketsSetbackPoint;
|
||||
public double morePacketsViolationLevel = 0;
|
||||
|
||||
|
@ -13,11 +13,9 @@ import org.bukkit.event.block.BlockListener;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.NoCheat;
|
||||
import cc.co.evenprime.bukkit.nocheat.Permissions;
|
||||
import cc.co.evenprime.bukkit.nocheat.checks.blockbreak.BlockBreakCheck;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.ConfigurationManager;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.Permissions;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.cache.ConfigurationCache;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.DataManager;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.BlockBreakData;
|
||||
|
||||
/**
|
||||
@ -30,14 +28,11 @@ import cc.co.evenprime.bukkit.nocheat.data.BlockBreakData;
|
||||
public class BlockBreakEventManager extends BlockListener implements EventManager {
|
||||
|
||||
private final BlockBreakCheck blockBreakCheck;
|
||||
private final DataManager data;
|
||||
private final ConfigurationManager config;
|
||||
private final NoCheat plugin;
|
||||
|
||||
public BlockBreakEventManager(NoCheat plugin) {
|
||||
|
||||
this.data = plugin.getDataManager();
|
||||
this.config = plugin.getConfigurationManager();
|
||||
|
||||
this.plugin = plugin;
|
||||
this.blockBreakCheck = new BlockBreakCheck(plugin);
|
||||
|
||||
PluginManager pm = Bukkit.getServer().getPluginManager();
|
||||
@ -54,7 +49,7 @@ public class BlockBreakEventManager extends BlockListener implements EventManage
|
||||
}
|
||||
|
||||
final Player player = event.getPlayer();
|
||||
final ConfigurationCache cc = config.getConfigurationCacheForWorld(player.getWorld().getName());
|
||||
final ConfigurationCache cc = plugin.getConfigurationManager().getConfigurationCacheForWorld(player.getWorld().getName());
|
||||
|
||||
// Find out if checks need to be done for that player
|
||||
if(cc.blockbreak.check && !player.hasPermission(Permissions.BLOCKBREAK)) {
|
||||
@ -62,7 +57,7 @@ public class BlockBreakEventManager extends BlockListener implements EventManage
|
||||
boolean cancel = false;
|
||||
|
||||
// Get the player-specific stored data that applies here
|
||||
final BlockBreakData data = this.data.getBlockBreakData(player);
|
||||
final BlockBreakData data = plugin.getDataManager().getBlockBreakData(player);
|
||||
|
||||
cancel = blockBreakCheck.check(player, event.getBlock(), data, cc);
|
||||
|
||||
@ -82,7 +77,7 @@ public class BlockBreakEventManager extends BlockListener implements EventManage
|
||||
|
||||
final Player player = event.getPlayer();
|
||||
// Get the player-specific stored data that applies here
|
||||
final BlockBreakData data = this.data.getBlockBreakData(player);
|
||||
final BlockBreakData data = plugin.getDataManager().getBlockBreakData(player);
|
||||
|
||||
// Remember this location. We ignore block breaks in the block-break
|
||||
// direction check that are insta-breaks
|
||||
|
@ -12,12 +12,10 @@ import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.NoCheat;
|
||||
import cc.co.evenprime.bukkit.nocheat.Permissions;
|
||||
import cc.co.evenprime.bukkit.nocheat.checks.blockplace.BlockPlaceCheck;
|
||||
import cc.co.evenprime.bukkit.nocheat.checks.moving.RunFlyCheck;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.ConfigurationManager;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.Permissions;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.cache.ConfigurationCache;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.DataManager;
|
||||
|
||||
/**
|
||||
* Central location to listen to Block-related events and dispatching them to
|
||||
@ -28,17 +26,14 @@ import cc.co.evenprime.bukkit.nocheat.data.DataManager;
|
||||
*/
|
||||
public class BlockPlaceEventManager extends BlockListener implements EventManager {
|
||||
|
||||
private final RunFlyCheck movingCheck;
|
||||
private final BlockPlaceCheck blockPlaceCheck;
|
||||
private final NoCheat plugin;
|
||||
private final RunFlyCheck movingCheck;
|
||||
private final BlockPlaceCheck blockPlaceCheck;
|
||||
|
||||
private final DataManager data;
|
||||
private final ConfigurationManager config;
|
||||
|
||||
public BlockPlaceEventManager(NoCheat plugin) {
|
||||
|
||||
this.data = plugin.getDataManager();
|
||||
this.config = plugin.getConfigurationManager();
|
||||
public BlockPlaceEventManager(NoCheat p) {
|
||||
|
||||
this.plugin = p;
|
||||
|
||||
this.movingCheck = new RunFlyCheck(plugin);
|
||||
this.blockPlaceCheck = new BlockPlaceCheck(plugin);
|
||||
|
||||
@ -54,7 +49,7 @@ public class BlockPlaceEventManager extends BlockListener implements EventManage
|
||||
if(!event.isCancelled()) {
|
||||
final Player player = event.getPlayer();
|
||||
// Get the player-specific stored data that applies here
|
||||
movingCheck.blockPlaced(player, data.getMovingData(player), event.getBlockPlaced());
|
||||
movingCheck.blockPlaced(player, plugin.getDataManager().getMovingData(player), event.getBlockPlaced());
|
||||
}
|
||||
}
|
||||
}, Priority.Monitor, plugin);
|
||||
@ -67,12 +62,12 @@ public class BlockPlaceEventManager extends BlockListener implements EventManage
|
||||
boolean cancel = false;
|
||||
|
||||
final Player player = event.getPlayer();
|
||||
final ConfigurationCache cc = config.getConfigurationCacheForWorld(player.getWorld().getName());
|
||||
final ConfigurationCache cc = plugin.getConfigurationManager().getConfigurationCacheForWorld(player.getWorld().getName());
|
||||
|
||||
// Find out if checks need to be done for that player
|
||||
if(cc.blockplace.check && !player.hasPermission(Permissions.BLOCKPLACE)) {
|
||||
|
||||
cancel = blockPlaceCheck.check(player, event.getBlockPlaced(), event.getBlockAgainst(), data.getBlockPlaceData(player), cc);
|
||||
cancel = blockPlaceCheck.check(player, event.getBlockPlaced(), event.getBlockAgainst(), plugin.getDataManager().getBlockPlaceData(player), cc);
|
||||
}
|
||||
|
||||
if(cancel) {
|
||||
|
@ -13,28 +13,24 @@ import org.bukkit.event.player.PlayerListener;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.NoCheat;
|
||||
import cc.co.evenprime.bukkit.nocheat.Permissions;
|
||||
import cc.co.evenprime.bukkit.nocheat.checks.chat.ChatCheck;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.ConfigurationManager;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.Permissions;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.cache.ConfigurationCache;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.ChatData;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.DataManager;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class PlayerChatEventManager extends PlayerListener implements EventManager {
|
||||
|
||||
private final ChatCheck chatCheck;
|
||||
private final DataManager data;
|
||||
private final ConfigurationManager config;
|
||||
private final NoCheat plugin;
|
||||
private final ChatCheck chatCheck;
|
||||
|
||||
public PlayerChatEventManager(NoCheat plugin) {
|
||||
|
||||
this.data = plugin.getDataManager();
|
||||
this.config = plugin.getConfigurationManager();
|
||||
this.plugin = plugin;
|
||||
this.chatCheck = new ChatCheck(plugin);
|
||||
|
||||
PluginManager pm = Bukkit.getServer().getPluginManager();
|
||||
@ -51,7 +47,7 @@ public class PlayerChatEventManager extends PlayerListener implements EventManag
|
||||
}
|
||||
|
||||
final Player player = event.getPlayer();
|
||||
final ConfigurationCache cc = config.getConfigurationCacheForWorld(player.getWorld().getName());
|
||||
final ConfigurationCache cc = plugin.getConfigurationManager().getConfigurationCacheForWorld(player.getWorld().getName());
|
||||
|
||||
// Find out if checks need to be done for that player
|
||||
if(cc.chat.check && !player.hasPermission(Permissions.CHAT)) {
|
||||
@ -59,7 +55,7 @@ public class PlayerChatEventManager extends PlayerListener implements EventManag
|
||||
boolean cancel = false;
|
||||
|
||||
// Get the player-specific stored data that applies here
|
||||
final ChatData data = this.data.getChatData(player);
|
||||
final ChatData data = plugin.getDataManager().getChatData(player);
|
||||
|
||||
cancel = chatCheck.check(player, event.getMessage(), data, cc);
|
||||
|
||||
|
@ -12,11 +12,9 @@ import org.bukkit.event.player.PlayerListener;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.NoCheat;
|
||||
import cc.co.evenprime.bukkit.nocheat.Permissions;
|
||||
import cc.co.evenprime.bukkit.nocheat.checks.interact.InteractCheck;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.ConfigurationManager;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.Permissions;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.cache.ConfigurationCache;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.DataManager;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.InteractData;
|
||||
|
||||
/**
|
||||
@ -24,16 +22,14 @@ import cc.co.evenprime.bukkit.nocheat.data.InteractData;
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public class PlayerInteractEventManager extends PlayerListener implements EventManager {
|
||||
public class PlayerInteractEventManager extends PlayerListener implements EventManager {
|
||||
|
||||
private final InteractCheck interactCheck;
|
||||
private final DataManager data;
|
||||
private final ConfigurationManager config;
|
||||
private final NoCheat plugin;
|
||||
private final InteractCheck interactCheck;
|
||||
|
||||
public PlayerInteractEventManager(NoCheat plugin) {
|
||||
|
||||
this.data = plugin.getDataManager();
|
||||
this.config = plugin.getConfigurationManager();
|
||||
this.plugin = plugin;
|
||||
this.interactCheck = new InteractCheck(plugin);
|
||||
|
||||
PluginManager pm = Bukkit.getServer().getPluginManager();
|
||||
@ -49,7 +45,7 @@ public class PlayerInteractEventManager extends PlayerListener implements Event
|
||||
}
|
||||
|
||||
final Player player = event.getPlayer();
|
||||
final ConfigurationCache cc = config.getConfigurationCacheForWorld(player.getWorld().getName());
|
||||
final ConfigurationCache cc = plugin.getConfigurationManager().getConfigurationCacheForWorld(player.getWorld().getName());
|
||||
|
||||
// Find out if checks need to be done for that player
|
||||
if(cc.interact.check && !player.hasPermission(Permissions.INTERACT)) {
|
||||
@ -57,7 +53,7 @@ public class PlayerInteractEventManager extends PlayerListener implements Event
|
||||
boolean cancel = false;
|
||||
|
||||
// Get the player-specific stored data that applies here
|
||||
final InteractData data = this.data.getInteractData(player);
|
||||
final InteractData data = plugin.getDataManager().getInteractData(player);
|
||||
|
||||
cancel = interactCheck.check(player, data, cc);
|
||||
|
||||
@ -65,7 +61,6 @@ public class PlayerInteractEventManager extends PlayerListener implements Event
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,50 +0,0 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.events;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.Event.Priority;
|
||||
import org.bukkit.event.player.PlayerDropItemEvent;
|
||||
import org.bukkit.event.player.PlayerListener;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.NoCheat;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.cache.ConfigurationCache;
|
||||
|
||||
/**
|
||||
*
|
||||
* Temporary, until Bukkit implements a real fix for the problem.
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public class PlayerItemDropEventManager extends PlayerListener implements EventManager {
|
||||
|
||||
public PlayerItemDropEventManager(NoCheat plugin) {
|
||||
|
||||
PluginManager pm = Bukkit.getServer().getPluginManager();
|
||||
|
||||
pm.registerEvent(Event.Type.PLAYER_DROP_ITEM, this, Priority.Lowest, plugin);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerDropItem(PlayerDropItemEvent event) {
|
||||
|
||||
if(!event.getPlayer().isOnline()) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getActiveChecks(ConfigurationCache cc) {
|
||||
return new LinkedList<String>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getInactiveChecks(ConfigurationCache cc) {
|
||||
return new LinkedList<String>();
|
||||
}
|
||||
}
|
@ -15,11 +15,9 @@ import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.NoCheat;
|
||||
import cc.co.evenprime.bukkit.nocheat.Permissions;
|
||||
import cc.co.evenprime.bukkit.nocheat.checks.moving.RunFlyCheck;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.ConfigurationManager;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.Permissions;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.cache.ConfigurationCache;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.DataManager;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.MovingData;
|
||||
|
||||
/**
|
||||
@ -33,15 +31,12 @@ import cc.co.evenprime.bukkit.nocheat.data.MovingData;
|
||||
*/
|
||||
public class PlayerMoveEventManager extends PlayerListener implements EventManager {
|
||||
|
||||
private final RunFlyCheck movingCheck;
|
||||
|
||||
private final ConfigurationManager config;
|
||||
private final DataManager data;
|
||||
private final NoCheat plugin;
|
||||
private final RunFlyCheck movingCheck;
|
||||
|
||||
public PlayerMoveEventManager(NoCheat plugin) {
|
||||
this.config = plugin.getConfigurationManager();
|
||||
this.data = plugin.getDataManager();
|
||||
|
||||
this.plugin = plugin;
|
||||
this.movingCheck = new RunFlyCheck(plugin);
|
||||
|
||||
PluginManager pm = Bukkit.getServer().getPluginManager();
|
||||
@ -59,13 +54,13 @@ public class PlayerMoveEventManager extends PlayerListener implements EventManag
|
||||
|
||||
// Get the world-specific configuration that applies here
|
||||
final Player player = event.getPlayer();
|
||||
final ConfigurationCache cc = config.getConfigurationCacheForWorld(player.getWorld().getName());
|
||||
final ConfigurationCache cc = plugin.getConfigurationManager().getConfigurationCacheForWorld(player.getWorld().getName());
|
||||
|
||||
// Find out if checks need to be done for that player
|
||||
if(cc.moving.check && !player.hasPermission(Permissions.MOVE)) {
|
||||
|
||||
// Get the player-specific stored data that applies here
|
||||
final MovingData data = this.data.getMovingData(player);
|
||||
final MovingData data = plugin.getDataManager().getMovingData(player);
|
||||
|
||||
// Get some data that's needed from this event, to avoid passing the
|
||||
// event itself on to the checks (and risk to
|
||||
@ -101,7 +96,7 @@ public class PlayerMoveEventManager extends PlayerListener implements EventManag
|
||||
if(!event.isCancelled()) {
|
||||
Player player = event.getPlayer();
|
||||
|
||||
MovingData mdata = data.getMovingData(player);
|
||||
MovingData mdata = plugin.getDataManager().getMovingData(player);
|
||||
|
||||
Vector v = event.getVelocity();
|
||||
|
||||
@ -111,7 +106,7 @@ public class PlayerMoveEventManager extends PlayerListener implements EventManag
|
||||
mdata.vertFreedom += mdata.vertVelocity;
|
||||
}
|
||||
|
||||
mdata.vertVelocityCounter = 50;
|
||||
mdata.vertVelocityCounter = 50;
|
||||
|
||||
newVal = Math.sqrt(Math.pow(v.getX(), 2) + Math.pow(v.getZ(), 2));
|
||||
if(newVal > 0.0D) {
|
||||
@ -137,8 +132,6 @@ public class PlayerMoveEventManager extends PlayerListener implements EventManag
|
||||
s.add("moving.nofall");
|
||||
if(cc.moving.check && cc.moving.morePacketsCheck)
|
||||
s.add("moving.morepackets");
|
||||
if(cc.moving.check && cc.moving.noclipCheck)
|
||||
s.add("moving.noclip");
|
||||
|
||||
return s;
|
||||
}
|
||||
@ -159,8 +152,6 @@ public class PlayerMoveEventManager extends PlayerListener implements EventManag
|
||||
s.add("moving.nofall");
|
||||
if(!(cc.moving.check && cc.moving.morePacketsCheck))
|
||||
s.add("moving.morepackets");
|
||||
if(!(cc.moving.check && cc.moving.noclipCheck))
|
||||
s.add("moving.noclip");
|
||||
|
||||
return s;
|
||||
}
|
||||
|
@ -17,7 +17,6 @@ import org.bukkit.plugin.PluginManager;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.NoCheat;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.cache.ConfigurationCache;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.DataManager;
|
||||
import cc.co.evenprime.bukkit.nocheat.data.MovingData;
|
||||
|
||||
/**
|
||||
@ -29,11 +28,11 @@ import cc.co.evenprime.bukkit.nocheat.data.MovingData;
|
||||
*/
|
||||
public class PlayerTeleportEventManager extends PlayerListener implements EventManager {
|
||||
|
||||
private final DataManager data;
|
||||
private final NoCheat plugin;
|
||||
|
||||
public PlayerTeleportEventManager(NoCheat p) {
|
||||
|
||||
public PlayerTeleportEventManager(NoCheat plugin) {
|
||||
|
||||
this.data = plugin.getDataManager();
|
||||
this.plugin = p;
|
||||
|
||||
PluginManager pm = Bukkit.getServer().getPluginManager();
|
||||
|
||||
@ -49,7 +48,7 @@ public class PlayerTeleportEventManager extends PlayerListener implements EventM
|
||||
|
||||
@Override
|
||||
public void onPlayerTeleport(PlayerTeleportEvent event) {
|
||||
final MovingData data2 = data.getMovingData(event.getPlayer());
|
||||
final MovingData data2 = plugin.getDataManager().getMovingData(event.getPlayer());
|
||||
if(event.isCancelled()) {
|
||||
if(data2.teleportTo != null && data2.teleportTo.equals(event.getTo())) {
|
||||
event.setCancelled(false);
|
||||
@ -84,7 +83,7 @@ public class PlayerTeleportEventManager extends PlayerListener implements EventM
|
||||
private void handleTeleportation(Player player, Location newLocation) {
|
||||
|
||||
/********* Moving check ************/
|
||||
final MovingData data = this.data.getMovingData(player);
|
||||
final MovingData data = plugin.getDataManager().getMovingData(player);
|
||||
|
||||
data.runflySetBackPoint = null;
|
||||
data.morePacketsCounter = 0;
|
||||
@ -92,14 +91,6 @@ public class PlayerTeleportEventManager extends PlayerListener implements EventM
|
||||
data.jumpPhase = 0;
|
||||
data.fallDistance = 0F;
|
||||
data.lastAddedFallDistance = 0F;
|
||||
|
||||
if(newLocation != null) {
|
||||
|
||||
data.noclipX = newLocation.getBlockX();
|
||||
data.noclipY = Location.locToBlock(newLocation.getY()+1.1D);
|
||||
data.noclipZ = newLocation.getBlockZ();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,47 +0,0 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.file;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.Explainations;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.ChildOption;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.ConfigurationTree;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.Option;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.ParentOption;
|
||||
|
||||
/**
|
||||
* Create a description file based on a configuration tree (to know what should
|
||||
* be in the description file) and data from "Explainations.java".
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public class DescriptionGenerator {
|
||||
|
||||
public static String treeToDescription(ConfigurationTree tree) {
|
||||
|
||||
ParentOption o = (ParentOption) tree.getOption("");
|
||||
|
||||
String s = "";
|
||||
|
||||
for(Option option : o.getChildOptions()) {
|
||||
s += optionToDescriptionString(option);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
private static String optionToDescriptionString(Option option) {
|
||||
|
||||
String s = "";
|
||||
|
||||
if(option instanceof ParentOption) {
|
||||
for(Option o : ((ParentOption) option).getChildOptions()) {
|
||||
s += optionToDescriptionString(o) + "\r\n";
|
||||
}
|
||||
} else if(option instanceof ChildOption && option.isActive()) {
|
||||
String padding = " ";
|
||||
|
||||
s += option.getFullIdentifier() + "\r\n" + padding + Explainations.get(option.getFullIdentifier()).replace("\n", "\r\n" + padding) + "\r\n";
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.file;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.DefaultConfiguration;
|
||||
import cc.co.evenprime.bukkit.nocheat.actions.ActionManager;
|
||||
|
||||
/**
|
||||
* Parses a action config file that was written in a flat style, one action per
|
||||
* line
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public class FlatActionParser {
|
||||
|
||||
public void read(ActionManager manager, File file) {
|
||||
|
||||
List<String[]> actionLines = readActionLinesFromFile(file, manager.getKnownTypes());
|
||||
|
||||
for(String[] actionLine : actionLines) {
|
||||
manager.createActionFromStrings(actionLine[0], actionLine[1], actionLine[2], actionLine[3], actionLine.length > 4 ? actionLine[4] : null);
|
||||
}
|
||||
}
|
||||
|
||||
private List<String[]> readActionLinesFromFile(File file, String[] knownTypes) {
|
||||
|
||||
List<String[]> lines = new LinkedList<String[]>();
|
||||
|
||||
if(!file.exists()) {
|
||||
DefaultConfiguration.writeActionFile(file);
|
||||
return lines;
|
||||
}
|
||||
|
||||
BufferedReader reader;
|
||||
try {
|
||||
reader = new BufferedReader(new FileReader(file));
|
||||
String line = null;
|
||||
while((line = reader.readLine()) != null) {
|
||||
for(String s : knownTypes) {
|
||||
if(line.startsWith(s)) {
|
||||
// Split at whitespace characters
|
||||
String parts[] = line.split("\\s+", 5);
|
||||
|
||||
if(parts.length < 4) {
|
||||
System.out.println("NoCheat: Incomplete action definition found. Ignoring it: " + line);
|
||||
} else {
|
||||
lines.add(parts);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
reader.close();
|
||||
|
||||
} catch(FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
} catch(IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return lines;
|
||||
|
||||
}
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.file;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.ActionListOption;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.ActionOption;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.ChildOption;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.ConfigurationTree;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.Option;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.ParentOption;
|
||||
|
||||
/**
|
||||
* Create a flat config file based on a ConfigurationTree
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public class FlatConfigGenerator {
|
||||
|
||||
public static String treeToFlatFile(ConfigurationTree tree) {
|
||||
|
||||
ParentOption o = (ParentOption) tree.getOption("");
|
||||
|
||||
String s = "# Want to know what these options do? Read the descriptions.txt file.\r\n\r\n";
|
||||
|
||||
for(Option option : o.getChildOptions()) {
|
||||
s += optionToFlatString(option) + "\r\n";
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
private static String optionToFlatString(Option option) {
|
||||
|
||||
String s = "";
|
||||
|
||||
if(option instanceof ParentOption) {
|
||||
|
||||
for(Option o : ((ParentOption) option).getChildOptions()) {
|
||||
s += optionToFlatString(o);
|
||||
}
|
||||
} else if(option instanceof ActionListOption && option.isActive()) {
|
||||
|
||||
for(ActionOption o : ((ActionListOption) option).getChildOptions()) {
|
||||
s += option.getFullIdentifier() + "." + o.getIdentifier() + " = \"" + o.getStringValue() + "\"\r\n";
|
||||
}
|
||||
} else if(option instanceof ChildOption && option.isActive()) {
|
||||
s += option.getFullIdentifier() + " = \"" + ((ChildOption) option).getStringValue() + "\"\r\n";
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
@ -1,127 +0,0 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.file;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* An extremely simple flat config file parser
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public class FlatConfigParser {
|
||||
|
||||
private final Map<String, Object> root;
|
||||
|
||||
public FlatConfigParser() {
|
||||
|
||||
root = new HashMap<String, Object>();
|
||||
}
|
||||
|
||||
public void read(File file) throws IOException {
|
||||
|
||||
BufferedReader r = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
|
||||
|
||||
LinkedList<String> lines = new LinkedList<String>();
|
||||
|
||||
String line = null;
|
||||
|
||||
while((line = r.readLine()) != null) {
|
||||
lines.add(line);
|
||||
}
|
||||
|
||||
r.close();
|
||||
|
||||
parse(root, lines, "");
|
||||
|
||||
}
|
||||
|
||||
private void parse(Map<String, Object> root, LinkedList<String> lines, String prefix) throws IOException {
|
||||
|
||||
String line = null;
|
||||
|
||||
while(!lines.isEmpty()) {
|
||||
line = lines.getFirst();
|
||||
if(line.trim().startsWith("#")) {
|
||||
lines.removeFirst();
|
||||
} else if(line.trim().isEmpty()) {
|
||||
lines.removeFirst();
|
||||
} else {
|
||||
lines.removeFirst();
|
||||
if(line.contains("=")) {
|
||||
String pair[] = line.split("=", 2);
|
||||
putString(pair[0].trim(), root, removeQuotationMarks(pair[1].trim()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String removeQuotationMarks(String s) {
|
||||
if(s.startsWith("\"") && s.endsWith("\"")) {
|
||||
return s.substring(1, s.length() - 1);
|
||||
} else if(s.startsWith("\'") && s.endsWith("\'")) {
|
||||
return s.substring(1, s.length() - 1);
|
||||
}
|
||||
|
||||
return s;
|
||||
|
||||
}
|
||||
|
||||
/* Convenience methods for retrieving values start here */
|
||||
|
||||
public Object getProperty(String path) {
|
||||
return getProperty(path, root);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static Object getProperty(String path, Map<String, Object> node) {
|
||||
|
||||
if(node == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if(!path.contains(".")) {
|
||||
return node.get(path);
|
||||
} else {
|
||||
String[] parts = path.split("\\.", 2);
|
||||
return getProperty(parts[1], (Map<String, Object>) node.get(parts[0]));
|
||||
}
|
||||
}
|
||||
|
||||
public String getString(String path, String defaultValue) {
|
||||
return getString(path, defaultValue, root);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static void putString(String path, Map<String, Object> node, String property) {
|
||||
String[] pathParts = path.split("\\.");
|
||||
for(int i = 0; i < pathParts.length; i++) {
|
||||
if(i == pathParts.length - 1) { // last in the chain
|
||||
node.put(pathParts[i], property);
|
||||
} else if(node.containsKey(pathParts[i]) && node.get(pathParts[i]) instanceof Map) {
|
||||
node = (Map<String, Object>) node.get(pathParts[i]);
|
||||
} else {
|
||||
HashMap<String, Object> newMap = new HashMap<String, Object>();
|
||||
node.put(pathParts[i], newMap);
|
||||
node = newMap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String getString(String path, String defaultValue, Map<String, Object> node) {
|
||||
try {
|
||||
String result = (String) getProperty(path, node);
|
||||
if(result == null)
|
||||
return defaultValue;
|
||||
return result;
|
||||
} catch(Exception e) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
@ -10,21 +10,17 @@ import java.util.logging.Level;
|
||||
*/
|
||||
public enum LogLevel {
|
||||
|
||||
OFF("off", "never", Level.OFF), LOW("low", "all messages", Level.INFO), MED("med", "important messages", Level.WARNING), HIGH("high", "very important messages", Level.SEVERE);
|
||||
OFF("off", Level.OFF), LOW("low", Level.INFO), MED("med", Level.WARNING), HIGH("high", Level.SEVERE);
|
||||
|
||||
public final String name;
|
||||
private final String description;
|
||||
public final Level level;
|
||||
|
||||
private LogLevel(String name, String description, Level level) {
|
||||
private LogLevel(String name, Level level) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
public static LogLevel getLogLevelFromString(String s) {
|
||||
if(s == null)
|
||||
return OFF;
|
||||
if("off".equals(s))
|
||||
return OFF;
|
||||
else if("low".equals(s))
|
||||
@ -34,11 +30,11 @@ public enum LogLevel {
|
||||
else if("high".equals(s))
|
||||
return HIGH;
|
||||
else
|
||||
return OFF;
|
||||
throw new IllegalArgumentException("Unknown log level "+s);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.name() + ": " + description;
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -6,7 +6,7 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.NoCheat;
|
||||
import cc.co.evenprime.bukkit.nocheat.Permissions;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.Permissions;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.cache.ConfigurationCache;
|
||||
|
||||
/**
|
||||
@ -19,10 +19,10 @@ import cc.co.evenprime.bukkit.nocheat.config.cache.ConfigurationCache;
|
||||
*/
|
||||
public class LogManager {
|
||||
|
||||
private final NoCheat plugin;
|
||||
//private final NoCheat plugin;
|
||||
|
||||
public LogManager(NoCheat plugin) {
|
||||
this.plugin = plugin;
|
||||
//this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,181 +0,0 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.wizard;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.DefaultConfiguration;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.ConfigurationManager;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.ConfigurationTree;
|
||||
import cc.co.evenprime.bukkit.nocheat.wizard.gui.ConfigurationTreeGui;
|
||||
|
||||
/**
|
||||
* The actual GUI for the configuration tool
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public class Wizard extends JFrame {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
Wizard w = new Wizard();
|
||||
w.setVisible(true);
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 8798111079958773207L;
|
||||
|
||||
public static final Color disabled = Color.GRAY;
|
||||
public static final Color enabled = Color.BLACK;
|
||||
|
||||
private class Wizard_JPanel extends JPanel {
|
||||
|
||||
private static final long serialVersionUID = 5748088661296418403L;
|
||||
|
||||
private final JPanel inside;
|
||||
private ConfigurationTree tree;
|
||||
|
||||
/**
|
||||
* Create a complete configuration screen based on a specific
|
||||
* configuration tree
|
||||
*
|
||||
* @param tree
|
||||
*/
|
||||
private Wizard_JPanel(ConfigurationTree tree) {
|
||||
|
||||
JScrollPane scrollPane = new JScrollPane();
|
||||
inside = new JPanel();
|
||||
this.tree = tree;
|
||||
scrollPane.setViewportView(inside);
|
||||
|
||||
this.setLayout(new BorderLayout());
|
||||
|
||||
inside.setLayout(new BoxLayout(inside, BoxLayout.Y_AXIS));
|
||||
|
||||
// Recursively walk through "defaults" tree and move stuff to our
|
||||
// new real config tree, if it is not defined
|
||||
// in our real tree already
|
||||
final ConfigurationTree modelRoot = tree;
|
||||
|
||||
final ConfigurationTreeGui guiRoot = new ConfigurationTreeGui(modelRoot);
|
||||
|
||||
inside.add(guiRoot);
|
||||
this.add(scrollPane, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recreate the whole tree (e.g. in case the underlying model tree
|
||||
* changed
|
||||
*/
|
||||
private void refresh() {
|
||||
this.inside.removeAll();
|
||||
this.inside.add(new ConfigurationTreeGui(tree));
|
||||
}
|
||||
}
|
||||
|
||||
private final JTabbedPane tabs;
|
||||
private final Map<String, File> worldFiles;
|
||||
private final Map<String, ConfigurationTree> worldTrees;
|
||||
|
||||
public Wizard() {
|
||||
|
||||
tabs = new JTabbedPane();
|
||||
worldFiles = ConfigurationManager.getWorldSpecificConfigFiles("NoCheat");
|
||||
worldTrees = new HashMap<String, ConfigurationTree>();
|
||||
|
||||
final File globalConfig = ConfigurationManager.getGlobalConfigFile("NoCheat");
|
||||
ConfigurationTree globalTree;
|
||||
|
||||
try {
|
||||
globalTree = ConfigurationManager.createFullConfigurationTree(DefaultConfiguration.buildDefaultConfigurationTree(), globalConfig);
|
||||
} catch(Exception e) {
|
||||
System.out.println("NoCheat: Couldn't use existing global config file " + globalConfig + ", creating a new file.");
|
||||
globalTree = DefaultConfiguration.buildDefaultConfigurationTree();
|
||||
}
|
||||
|
||||
worldTrees.put(null, globalTree);
|
||||
|
||||
for(String worldName : worldFiles.keySet()) {
|
||||
ConfigurationTree worldTree;
|
||||
try {
|
||||
worldTree = ConfigurationManager.createPartialConfigurationTree(globalTree, worldFiles.get(worldName));
|
||||
worldTrees.put(worldName, worldTree);
|
||||
} catch(Exception e) {
|
||||
System.out.println("NoCheat: Couldn't read existing world-specific config file for world " + worldName);
|
||||
worldFiles.remove(worldName);
|
||||
}
|
||||
}
|
||||
|
||||
worldFiles.put(null, globalConfig);
|
||||
|
||||
setup();
|
||||
}
|
||||
|
||||
private void setup() {
|
||||
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
|
||||
|
||||
this.setLayout(new BorderLayout());
|
||||
|
||||
JButton saveAllButton = new JButton("Save All");
|
||||
|
||||
tabs.addChangeListener(new ChangeListener() {
|
||||
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent arg0) {
|
||||
((Wizard_JPanel) tabs.getSelectedComponent()).refresh();
|
||||
}
|
||||
});
|
||||
|
||||
Wizard_JPanel global = new Wizard_JPanel(worldTrees.get(null));
|
||||
tabs.addTab("Global Settings", null, global, "The settings valid for all worlds, unless a specific setting overrides them.");
|
||||
|
||||
for(String name : worldTrees.keySet()) {
|
||||
if(name != null) {
|
||||
Wizard_JPanel world = new Wizard_JPanel(worldTrees.get(name));
|
||||
tabs.addTab(name + " Settings", null, world, "Some world-specific settings.");
|
||||
}
|
||||
}
|
||||
|
||||
saveAllButton.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
|
||||
for(String worldName : worldTrees.keySet()) {
|
||||
ConfigurationManager.writeConfigFile(worldFiles.get(worldName), worldTrees.get(worldName));
|
||||
}
|
||||
|
||||
ConfigurationManager.writeDescriptionFile(ConfigurationManager.getDescriptionFile("NoCheat"), worldTrees.get(null));
|
||||
|
||||
DefaultConfiguration.writeDefaultActionFile(ConfigurationManager.getDefaultActionFile("NoCheat"));
|
||||
|
||||
DefaultConfiguration.writeActionFile(ConfigurationManager.getActionFile("NoCheat"));
|
||||
|
||||
JOptionPane.showMessageDialog(null, "Saved All");
|
||||
}
|
||||
});
|
||||
|
||||
saveAllButton.setAlignmentY(0.0F);
|
||||
this.add(saveAllButton, BorderLayout.SOUTH);
|
||||
this.pack();
|
||||
this.setSize(1000, 700);
|
||||
this.setTitle("NoCheat configuration utility");
|
||||
|
||||
this.add(tabs, BorderLayout.CENTER);
|
||||
|
||||
}
|
||||
}
|
@ -1,180 +0,0 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.wizard.gui;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.Box;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.ActionListOption;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.ActionOption;
|
||||
import cc.co.evenprime.bukkit.nocheat.wizard.Wizard;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public class ActionListOptionGui extends ChildOptionGui {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 527734534503546802L;
|
||||
|
||||
private final ActionListOption option;
|
||||
private final ActionListOption defaults;
|
||||
|
||||
public ActionListOptionGui(ActionListOption option, ActionListOption defaults) {
|
||||
|
||||
super(option.isActive());
|
||||
|
||||
this.option = option;
|
||||
this.defaults = defaults;
|
||||
|
||||
this.setLayout(new GridBagLayout());
|
||||
recreateContent();
|
||||
}
|
||||
|
||||
private void recreateContent() {
|
||||
|
||||
this.removeAll();
|
||||
|
||||
int line = 0;
|
||||
|
||||
if(this.isActive()) {
|
||||
|
||||
GridBagConstraints c = new GridBagConstraints();
|
||||
c.gridx = 1;
|
||||
c.gridy = line;
|
||||
c.anchor = GridBagConstraints.WEST;
|
||||
c.ipadx = 10;
|
||||
c.weightx = 0;
|
||||
|
||||
this.add(createAddButton(), c);
|
||||
|
||||
for(ActionOption o : option.getChildOptions()) {
|
||||
line++;
|
||||
add(o, line);
|
||||
}
|
||||
} else {
|
||||
for(ActionOption o : defaults.getChildOptions()) {
|
||||
line++;
|
||||
add(o, line);
|
||||
}
|
||||
}
|
||||
|
||||
this.revalidate();
|
||||
}
|
||||
|
||||
private Component createAddButton() {
|
||||
JButton b = new JButton("new Line");
|
||||
b.setToolTipText("Adds a new line to this action list.");
|
||||
|
||||
b.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
String result = JOptionPane.showInputDialog("Please enter a new threshold: ");
|
||||
try {
|
||||
int treshold = Integer.parseInt(result);
|
||||
if(treshold >= 0) {
|
||||
for(ActionOption ao : option.getChildOptions()) {
|
||||
if(ao.getTreshold() == treshold) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
option.add(treshold, "");
|
||||
recreateContent();
|
||||
} catch(Exception e) {}
|
||||
}
|
||||
});
|
||||
return b;
|
||||
}
|
||||
|
||||
private Component createDeleteButton(final ActionOption o) {
|
||||
JButton b = new JButton("remove");
|
||||
b.setToolTipText("Removes this line from the action list.");
|
||||
|
||||
b.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
option.remove(o);
|
||||
recreateContent();
|
||||
}
|
||||
});
|
||||
return b;
|
||||
}
|
||||
|
||||
private void add(final ActionOption child, int line) {
|
||||
|
||||
GridBagConstraints c = new GridBagConstraints();
|
||||
|
||||
c.gridx = 0;
|
||||
c.gridy = line;
|
||||
c.gridwidth = 1;
|
||||
c.anchor = GridBagConstraints.EAST;
|
||||
c.ipadx = 10;
|
||||
c.weightx = 0;
|
||||
|
||||
JLabel l = new JLabel(child.getIdentifier() + " : ");
|
||||
if(!option.isActive()) {
|
||||
l.setForeground(Wizard.disabled);
|
||||
} else {
|
||||
l.setForeground(Wizard.enabled);
|
||||
}
|
||||
|
||||
this.add(l, c);
|
||||
|
||||
c.gridx++;
|
||||
c.gridy = line;
|
||||
c.gridwidth = 1;
|
||||
c.anchor = GridBagConstraints.WEST;
|
||||
c.ipadx = 5;
|
||||
c.weightx = 0;
|
||||
c.fill = GridBagConstraints.HORIZONTAL;
|
||||
|
||||
JComponent tmp = ChildOptionGuiFactory.create(child);
|
||||
|
||||
this.add(tmp, c);
|
||||
|
||||
if(!option.isActive()) {
|
||||
tmp.setEnabled(false);
|
||||
} else {
|
||||
c.gridx++;
|
||||
c.gridy = line;
|
||||
c.gridwidth = 1;
|
||||
c.anchor = GridBagConstraints.WEST;
|
||||
c.ipadx = 1;
|
||||
c.weightx = 0;
|
||||
|
||||
this.add(createDeleteButton(child), c);
|
||||
}
|
||||
|
||||
c.gridx++;
|
||||
c.gridy = line;
|
||||
c.gridwidth = 1;
|
||||
c.anchor = GridBagConstraints.WEST;
|
||||
c.ipadx = 5;
|
||||
c.weightx = 1;
|
||||
|
||||
this.add(Box.createHorizontalGlue(), c);
|
||||
}
|
||||
|
||||
public void setActive(boolean active) {
|
||||
super.setActive(active);
|
||||
option.setActive(active);
|
||||
option.getChildOptions().clear();
|
||||
for(ActionOption ao : defaults.getChildOptions()) {
|
||||
option.getChildOptions().add(ao.clone());
|
||||
}
|
||||
}
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.wizard.gui;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.FlowLayout;
|
||||
import javax.swing.InputVerifier;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.ActionOption;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public class ActionOptionGui extends JPanel {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -3262934728041595488L;
|
||||
|
||||
private final JTextField textField;
|
||||
private final ActionOption option;
|
||||
|
||||
public ActionOptionGui(ActionOption o) {
|
||||
textField = new JTextField();
|
||||
|
||||
this.option = o;
|
||||
|
||||
this.setBorder(new EmptyBorder(0, 0, 0, 0));
|
||||
this.setLayout(new FlowLayout(0, 0, 0));
|
||||
|
||||
textField.setEnabled(option.isActive());
|
||||
|
||||
textField.setText(option.getStringValue());
|
||||
|
||||
textField.setColumns(50);
|
||||
|
||||
textField.setInputVerifier(new InputVerifier() {
|
||||
|
||||
@Override
|
||||
public boolean verify(JComponent arg0) {
|
||||
|
||||
if(option.setStringValue(textField.getText())) {
|
||||
return true;
|
||||
} else {
|
||||
JOptionPane.showMessageDialog(textField, "Illegal value for this field");
|
||||
textField.setText(option.getStringValue());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.add(textField, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean enabled) {
|
||||
super.setEnabled(enabled);
|
||||
textField.setEnabled(enabled);
|
||||
}
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.wizard.gui;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.BooleanOption;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public class BooleanOptionGui extends ChildOptionGui {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 6082180273557581041L;
|
||||
|
||||
private final BooleanOption option;
|
||||
private final BooleanOption defaults;
|
||||
private final ParentOptionGui parentGui;
|
||||
private final JCheckBox checkBox;
|
||||
|
||||
public BooleanOptionGui(BooleanOption o, BooleanOption defaults, ParentOptionGui parent) {
|
||||
|
||||
super(o.isActive());
|
||||
|
||||
checkBox = new JCheckBox();
|
||||
|
||||
this.parentGui = parent;
|
||||
this.option = o;
|
||||
this.defaults = defaults;
|
||||
|
||||
this.setBorder(new EmptyBorder(0, 0, 0, 0));
|
||||
this.setLayout(new FlowLayout(0, 0, 0));
|
||||
|
||||
checkBox.setEnabled(option.isActive());
|
||||
|
||||
if(defaults != null && !option.isActive()) {
|
||||
checkBox.setSelected(defaults.getBooleanValue());
|
||||
} else {
|
||||
checkBox.setSelected(option.getBooleanValue());
|
||||
}
|
||||
|
||||
checkBox.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
option.setBooleanValue(checkBox.isSelected());
|
||||
parentGui.recreateContent();
|
||||
}
|
||||
});
|
||||
|
||||
this.add(checkBox, BorderLayout.CENTER);
|
||||
|
||||
checkBox.setHorizontalTextPosition(SwingConstants.LEADING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActive(boolean active) {
|
||||
super.setActive(active);
|
||||
if(active) {
|
||||
checkBox.setEnabled(true);
|
||||
option.setActive(true);
|
||||
} else {
|
||||
checkBox.setEnabled(false);
|
||||
option.setActive(false);
|
||||
|
||||
}
|
||||
checkBox.setSelected(defaults.getBooleanValue());
|
||||
option.setBooleanValue(defaults.getBooleanValue());
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.wizard.gui;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public abstract class ChildOptionGui extends JPanel {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -8647116398870984111L;
|
||||
|
||||
private boolean active = true;
|
||||
|
||||
public ChildOptionGui(boolean isActive) {
|
||||
this.active = isActive;
|
||||
}
|
||||
|
||||
public void setActive(boolean active) {
|
||||
this.active = active;
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.wizard.gui;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.ActionListOption;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.ActionOption;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.BooleanOption;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.LogLevelOption;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.Option;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.StringOption;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
class ChildOptionGuiFactory {
|
||||
|
||||
protected static ChildOptionGui create(Option option, Option defaults, ParentOptionGui parent) {
|
||||
|
||||
if(option instanceof BooleanOption) {
|
||||
return new BooleanOptionGui((BooleanOption) option, (BooleanOption) defaults, parent);
|
||||
} else if(option instanceof StringOption) {
|
||||
return new StringOptionGui((StringOption) option, (StringOption) defaults);
|
||||
} else if(option instanceof LogLevelOption) {
|
||||
return new LogLevelOptionGui((LogLevelOption) option, (LogLevelOption) defaults);
|
||||
} else if(option instanceof ActionListOption) {
|
||||
return new ActionListOptionGui((ActionListOption) option, (ActionListOption) defaults);
|
||||
}
|
||||
|
||||
throw new RuntimeException("Unknown Option " + option);
|
||||
}
|
||||
|
||||
public static ActionOptionGui create(ActionOption child) {
|
||||
return new ActionOptionGui(child);
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.wizard.gui;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.ConfigurationTree;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.ParentOption;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public class ConfigurationTreeGui extends JPanel {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -3311598864103292261L;
|
||||
|
||||
public ConfigurationTreeGui(ConfigurationTree modelRoot) {
|
||||
|
||||
// If the tree has a parent, use that as the main model and the actual
|
||||
// model only
|
||||
// to supply additional data
|
||||
ConfigurationTree parent = modelRoot.getParent();
|
||||
|
||||
if(parent != null) {
|
||||
this.add(new ParentOptionGui((ParentOption) modelRoot.getOption(""), (ParentOption) parent.getOption("")));
|
||||
} else {
|
||||
this.add(new ParentOptionGui((ParentOption) modelRoot.getOption(""), null));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.wizard.gui;
|
||||
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.LogLevelOption;
|
||||
import cc.co.evenprime.bukkit.nocheat.log.LogLevel;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public class LogLevelOptionGui extends ChildOptionGui {
|
||||
|
||||
private final LogLevelOption option;
|
||||
private final LogLevelOption defaults;
|
||||
private final JComboBox comboBox;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -8285257162704341771L;
|
||||
|
||||
public LogLevelOptionGui(final LogLevelOption o, final LogLevelOption defaults) {
|
||||
|
||||
super(o.isActive());
|
||||
this.option = o;
|
||||
this.defaults = defaults;
|
||||
|
||||
comboBox = new JComboBox();
|
||||
|
||||
for(LogLevel op : LogLevel.values())
|
||||
comboBox.addItem(op);
|
||||
|
||||
comboBox.setEnabled(option.isActive());
|
||||
|
||||
if(defaults != null && !option.isActive()) {
|
||||
comboBox.setSelectedItem(defaults.getLogLevelValue());
|
||||
} else {
|
||||
comboBox.setSelectedItem(option.getLogLevelValue());
|
||||
}
|
||||
|
||||
comboBox.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
option.setLogLevelValue((LogLevel) comboBox.getSelectedItem());
|
||||
}
|
||||
});
|
||||
|
||||
this.setLayout(new FlowLayout(0, 0, 0));
|
||||
this.setBorder(new EmptyBorder(0, 0, 0, 0));
|
||||
|
||||
this.add(comboBox);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActive(boolean active) {
|
||||
super.setActive(active);
|
||||
|
||||
if(active) {
|
||||
comboBox.setEnabled(true);
|
||||
option.setActive(true);
|
||||
} else {
|
||||
comboBox.setEnabled(false);
|
||||
option.setActive(false);
|
||||
}
|
||||
comboBox.setSelectedItem(defaults.getLogLevelValue());
|
||||
option.setLogLevelValue(defaults.getLogLevelValue());
|
||||
}
|
||||
|
||||
}
|
@ -1,193 +0,0 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.wizard.gui;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Insets;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.Box;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.Explainations;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.BooleanOption;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.ChildOption;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.Option;
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.ParentOption;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public class ParentOptionGui extends JPanel {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 5277750257203546802L;
|
||||
|
||||
private final ParentOption option;
|
||||
private final ParentOption defaults;
|
||||
|
||||
public ParentOptionGui(ParentOption option, ParentOption defaults) {
|
||||
this.option = option;
|
||||
this.defaults = defaults;
|
||||
|
||||
recreateContent();
|
||||
}
|
||||
|
||||
void recreateContent() {
|
||||
|
||||
this.removeAll();
|
||||
|
||||
if(option.getIdentifier().length() > 0) {
|
||||
this.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5), BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(BorderFactory.createMatteBorder(2, 2, 2, 2, Color.BLACK), " " + option.getIdentifier() + ": "), BorderFactory.createEmptyBorder(5, 5, 5, 5))));
|
||||
}
|
||||
this.setLayout(new GridBagLayout());
|
||||
|
||||
int line = 0;
|
||||
|
||||
boolean hideNonMasterOptions = false;
|
||||
for(Option o : option.getChildOptions()) {
|
||||
if(o instanceof BooleanOption) {
|
||||
BooleanOption b = (BooleanOption) o;
|
||||
if(b.isMaster() && b.isActive() && !b.getBooleanValue()) {
|
||||
hideNonMasterOptions = true;
|
||||
} else if(b.isMaster() && !b.isActive()) {
|
||||
BooleanOption b2 = (BooleanOption) defaults.getChild(b.getIdentifier());
|
||||
if(b2 != null && !b2.getBooleanValue()) {
|
||||
hideNonMasterOptions = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(Option o : option.getChildOptions()) {
|
||||
if(!hideNonMasterOptions || (o instanceof BooleanOption && ((BooleanOption) o).isMaster())) {
|
||||
if(defaults != null) {
|
||||
add(o, defaults.getChild(o.getIdentifier()), line);
|
||||
line++;
|
||||
} else {
|
||||
add(o, null, line);
|
||||
line++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.revalidate();
|
||||
}
|
||||
|
||||
private void add(final Option child, final Option childDefault, int line) {
|
||||
|
||||
if(child instanceof ParentOption) {
|
||||
GridBagConstraints c = new GridBagConstraints();
|
||||
|
||||
c.gridx = 0;
|
||||
c.gridy = line;
|
||||
|
||||
c.gridwidth = 5;
|
||||
c.anchor = GridBagConstraints.WEST;
|
||||
c.ipadx = 2;
|
||||
c.ipady = 15;
|
||||
c.weightx = 1;
|
||||
c.fill = GridBagConstraints.HORIZONTAL;
|
||||
|
||||
this.add(new ParentOptionGui((ParentOption) child, (ParentOption) childDefault), c);
|
||||
} else if(child instanceof ChildOption) {
|
||||
|
||||
JLabel id = new JLabel(child.getIdentifier() + " : ");
|
||||
ChildOptionGui tmp = ChildOptionGuiFactory.create(child, childDefault, this);
|
||||
JButton defaults = createAddRemoveButton(this, tmp);
|
||||
JButton help = createHelpButton(child.getFullIdentifier());
|
||||
|
||||
if(!tmp.isActive()) {
|
||||
id.setEnabled(false);
|
||||
}
|
||||
|
||||
GridBagConstraints c = new GridBagConstraints();
|
||||
|
||||
c.gridx = 0;
|
||||
c.gridy = line;
|
||||
c.anchor = GridBagConstraints.NORTHWEST;
|
||||
c.ipadx = 2;
|
||||
c.insets = new Insets(0, 1, 0, 1);
|
||||
|
||||
if(childDefault != null) {
|
||||
this.add(defaults, c);
|
||||
c.gridx++;
|
||||
}
|
||||
|
||||
this.add(id, c);
|
||||
c.gridx++;
|
||||
|
||||
this.add(tmp, c);
|
||||
|
||||
c.gridx++;
|
||||
c.ipadx = 2;
|
||||
this.add(help, c);
|
||||
|
||||
c.gridx++;
|
||||
c.gridwidth = 5 - c.gridx + 1;
|
||||
c.weightx = 1;
|
||||
c.fill = GridBagConstraints.HORIZONTAL;
|
||||
|
||||
this.add(Box.createHorizontalGlue(), c);
|
||||
} else {
|
||||
throw new RuntimeException("Unknown Option " + child);
|
||||
}
|
||||
}
|
||||
|
||||
private JButton createAddRemoveButton(final ParentOptionGui container, final ChildOptionGui option) {
|
||||
|
||||
final JButton addRemove = new JButton("+");
|
||||
addRemove.setToolTipText("Allow setting custom options for this world.");
|
||||
|
||||
if(option.isActive()) {
|
||||
addRemove.setText("-");
|
||||
addRemove.setToolTipText("Use global settings instead of these custom options.");
|
||||
}
|
||||
|
||||
addRemove.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
if(addRemove.getText().equals("+")) {
|
||||
option.setActive(true);
|
||||
addRemove.setText("-");
|
||||
addRemove.setToolTipText("Use global settings instead.");
|
||||
} else {
|
||||
option.setActive(false);
|
||||
addRemove.setText("+");
|
||||
addRemove.setToolTipText("Allow setting custom options for this world.");
|
||||
}
|
||||
container.recreateContent();
|
||||
}
|
||||
});
|
||||
|
||||
addRemove.setMargin(new Insets(0, 0, 0, 0));
|
||||
|
||||
return addRemove;
|
||||
}
|
||||
|
||||
private JButton createHelpButton(final String identifier) {
|
||||
JButton help = new JButton("?");
|
||||
help.setToolTipText("Show help. Usually some instructions or further information about this option.");
|
||||
help.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
JOptionPane.showMessageDialog(null, Explainations.get(identifier), "Description of " + identifier, JOptionPane.INFORMATION_MESSAGE);
|
||||
}
|
||||
});
|
||||
|
||||
help.setMargin(new Insets(0, 0, 0, 0));
|
||||
|
||||
return help;
|
||||
}
|
||||
}
|
@ -1,94 +0,0 @@
|
||||
package cc.co.evenprime.bukkit.nocheat.wizard.gui;
|
||||
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.InputVerifier;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
|
||||
import cc.co.evenprime.bukkit.nocheat.config.tree.StringOption;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Evenprime
|
||||
*
|
||||
*/
|
||||
public class StringOptionGui extends ChildOptionGui {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 6082180273557581041L;
|
||||
|
||||
private final StringOption option;
|
||||
private final StringOption defaults;
|
||||
private final JTextField textField;
|
||||
|
||||
public StringOptionGui(StringOption o, StringOption defaults) {
|
||||
|
||||
super(o.isActive());
|
||||
|
||||
textField = new JTextField();
|
||||
this.option = o;
|
||||
this.defaults = defaults;
|
||||
this.setLayout(new FlowLayout(0, 0, 0));
|
||||
this.setBorder(new EmptyBorder(0, 0, 0, 0));
|
||||
|
||||
textField.setEnabled(option.isActive());
|
||||
|
||||
if(defaults != null && !option.isActive()) {
|
||||
textField.setText(defaults.getStringValue());
|
||||
} else {
|
||||
textField.setText(option.getStringValue());
|
||||
}
|
||||
|
||||
if(option.hasPreferredLength()) {
|
||||
textField.setColumns(option.getPreferredLength());
|
||||
}
|
||||
|
||||
textField.setInputVerifier(new InputVerifier() {
|
||||
|
||||
@Override
|
||||
public boolean verify(JComponent arg0) {
|
||||
|
||||
if(option.setStringValue(textField.getText())) {
|
||||
return true;
|
||||
} else {
|
||||
JOptionPane.showMessageDialog(textField, "Illegal value for this field");
|
||||
textField.setText(option.getStringValue());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
textField.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
option.setStringValue(textField.getText());
|
||||
}
|
||||
});
|
||||
|
||||
this.add(textField);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActive(boolean active) {
|
||||
super.setActive(active);
|
||||
if(active) {
|
||||
textField.setEnabled(true);
|
||||
option.setActive(true);
|
||||
textField.setText(defaults.getStringValue());
|
||||
} else {
|
||||
textField.setEnabled(false);
|
||||
option.setActive(false);
|
||||
textField.setText(defaults.getStringValue());
|
||||
}
|
||||
textField.setText(defaults.getStringValue());
|
||||
option.setStringValue(defaults.getStringValue());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user