+ Added NoPwnage to NoCheat+ (checks messages, speed, locations, etc.)

- Removed all the stuff with the plugins list
This commit is contained in:
NeatMonster 2012-04-16 23:11:55 +02:00
parent 82b5dbc5b1
commit 8546a649ed
18 changed files with 794 additions and 353 deletions

View File

@ -267,9 +267,13 @@
----------------------- CHAT Permissions for CHECKS ----------------------------
- nocheatplus.checks.chat.spam
- nocheatplus.checks.chat.nopwnage
Don't limit the number of messages and commands that a player may send in a
short timeframe
short timeframe, the delay allowed to join the server again, etc. in short
everything watched by the NoPwnage check.
- nocheatplus.checks.chat.arrivalslimit
Don't limit the number of new players allowed to join in a short timeframe.
- nocheatplus.checks.chat.color
Don't filter color codes from messages that get sent by players, allowing
@ -940,13 +944,155 @@
Checks that at least technically have to do with chat or commands.
hidenocheatplus:
Setting this to true will hide NoCheatPlus for the /plugins (or /pl) command
of Bukkit (only if typed by a player). This command might be used by some
griefing clients to try to detect and to apply bypasses to NoCheatPlus.
hideCommands:
Enable this if you don't want NoCheat+'s commands to reply to the player if
he doesn't have the permissions to use them.
1) NOPWNAGE:
The instructions for this check comes directly from NoPwnage's instructions
file. You can find the project at http://dev.bukkit.org/server-mods/nopwnage/.
1) COLOR:
warnPlayers:
Should a player that reaches the "warnLevel" get a text message telling
him that he is under suspicion of being a bot.
warnOthers:
Should all players get warned when a player gets banned for spambot-like
activity?
warnLevel:
How much suspicion must a message earn to issue a warning for the player
warnTimeout:
After what time (in ms) should a player be considered "unwarned" again.
banLevel:
How much suspicion must a message earn to execute the "commands" (usually
ban the player). If warnings for players are enabled and the player hasn't
been warned yet, he'll get warned instead.
move.enabled:
move.weightbonus:
move.weightmalus:
move.timeout:
NoPwnage will check if a player moved within the "timeout" timeframe. If
he did move, the suspicion will be reduced by the "weightbonus" value. If
he did not move, the suspicion will be increased by "weightmalus" value.
Only used if "enabled".
messageRepeat.enabled:
messageRepeat.weight:
messageRepeat.timeout:
NoPwnage will check if a player repeats his messages within the "timeout"
timeframe. Even if the message is a bit different, it will be counted as
being a repetition. The suspicion is increased by "weight" and for each
additional repetition by "weight/2". This means that multiple repetitions
will increase suspicion, but not as much as the first repetition.
Only used if "enabled".
messageSpeed.enabled:
messageSpeed.weight:
messageSpeed.timeout:
NoPwnage will check if a player sends messages too fast. If a message is
sent within "timout" ms after the previous message, increase suspicion by
"weight". For each additional message that is sent within "timeout",
the suspicion is increased by "weight/2". This means that multiple
too fast sent messages in a row will increase suspicion, but not as much as
the first.
Only used if "enabled".
messageFirst.enabled:
messageFirst.weight:
messageFirst.timeout:
NoPwnage will check if a player sends his first message within "timeout"
ms after his login. If he does, increase supspicion by "weight".
Only used if "enabled".
globalMessageRepeat.enabled:
globalMessageRepeat.weight:
globalMessageRepeat.timeout:
NoPwnage will check if a player repeats a message that has been sent by
another player just before, within "timeout". If he does, suspicion will
be increased by "weight" and for each additional repetition by "weight/2",
independent of by which player. This means that multiple repetitions will
increase suspicion, but not as much as the first repetition.
Only used if "enabled".
bannedMessageRepeat.enabled:
bannedMessageRepeat.weight:
bannedMessageRepeat.timeout:
NoPwnage will remember the last message that caused someone to get banned.
If a player repeats that message within "timeout" ms, the suspicion will
be increased by "weight".
Only used if "enabled".
relog.enabled:
relog.time:
relog.warnings:
relog.timeout:
NoPwnage will remember the time when a player leaves the server. If he
returns within "time" ms, he will get warned. If he has been warned
"warnings" times already, the "commands" will be executed for him. Warnings
get removed if the time of the last warning was more than "timeout" ms ago.
actions:
NoPwnage allows you to decide what should happen when a player reaches
"banLevel" or relogged too fast. The default is to kick him and ban IP and
name. You'll also get a log message to console stating how exactly he
reached the "banLevel" (how much suspicion was added by each check).
Commands have to be seperated by ";" and the "[player]" and "[ip]"
wildcards will be replaced by the actual data during execution.
captcha.enabled:
Should players that get to "banlevel" be presented with a captcha first
instead of running the commands immediatly?
captcha.question:
How should the question be worded. Use & to create colors. The text
[captcha] will be replaced with the actual captcha.
tries:
How many attempts will a player have to give the correct answer. A failed
attempt will display the question again. Be generous here, as players may
not be fast enough to read the question the first few times or be otherwise
distracted.
length:
How many characters should the captcha have.
characters:
The characters for the captcha are randomly drawn from this string
2) ARRIVALSLIMIT:
This check limits the number of new players joining every X seconds to
prevent the usage of softwares like PWN4G3.
active:
Should players get checked for that kind of spam.
playerslimit:
The number of new players allowed to join during the interval defined
in the configuration.
timeframe:
The interval in milliseconds during which the number of new players
defined in the configuration are allowed to join.
cooldown:
The number of milliseconds during which new players won't be allowed
to join if too many new players have been detected.
newtime:
The time elsaped since the player's first join to be considered as
an old/regular player.
actions:
What should happen if the access is denied to the player.
3) COLOR:
Players may use color-codes to send colored messages. This may be used
to fool other players into believing they are admins or similar.
@ -963,63 +1109,6 @@
each color-code message by 1 and decreases slowly with colorless
messages.
2) SPAM:
Players may send a ton of messages/commands in a short time to cause
lag or even crash a server.
active:
Should player messages get checked for sending of too many messages.
whitelist:
A " " (whitespace) separated list of words. Messages that start with
these sequences will not be counted. This is ideal to exempt commands
from getting filtered, by e.g. adding "/help" to the list.
timeframe:
For how many seconds should messages and commands be counted, before
the counters get reset and counting starts at zero again.
messagelimit:
How many "normal" chat messages may be sent within the timeframe. All
messages that don't start with "/" are considered "normal".
commandlimit:
How many commands may be issued within the timeframe. Some mods (e.g.
TooManyItems) send a command on every mouse-click, which may cause
problems if this is set too low. So choose wisely. Every message that
starts with "/" is considered a command, even if the command doesn't
exist.
actions:
What should happen if players send more messages/commands than declared
by the above limits? Default is to prevent the message/command from
being processed ("cancel" them) and for severe cases where players send
a lot of messages/commands, kick them. The Violation Level (VL) is the
number of messages/commands that were sent beyond the specified limits.
It gets increased for every message/command by 1 and reset to zero when
the "timeframe" has passed.
3) SPAMJOINS:
This check limits the number of new players joining every X seconds to
prevent the usage of softwares like PWN4G3.
active:
Should players get checked for that kind of spam.
playerslimit:
The number of new players allowed to join during the interval defined
in the configuration.
timelimit:
The interval in milliseconds during which the number of new players
defined in the configuration are allowed to join.
cooldown:
The number of milliseconds during which new players won't be allowed
to join if too many new players have been detected.
------------------------------ FIGHT Subsection --------------------------------

View File

@ -3,7 +3,7 @@ version: ${project.version}
description: ${project.description}
author: NeatMonster
authors: [Evenprime, Juliui, craftingmania]
authors: [Evenprime, Juliui]
website: ${project.url}
main: me.neatmonster.nocheatplus.NoCheatPlus
@ -11,6 +11,7 @@ main: me.neatmonster.nocheatplus.NoCheatPlus
commands:
nocheatplus:
description: NoCheatPlus command(s)
aliases: [ncp]
# permission: nocheatplus.admin.commands
usage: |
/<command> permlist player [permission]: list NoCheatPlus' permissions of player, optionally only if beginning with [permission]
@ -81,8 +82,10 @@ permissions:
nocheatplus.checks.chat:
description: Allow the player to bypass all chat checks
children:
nocheatplus.checks.chat.spam:
description: Allow a player to send an infinite amount of chat messages
nocheatplus.checks.chat.nopwnage:
description: Allow a player to bypass the nopwnage check
nocheatplus.checks.chat.arrivalslimit:
description: Allow a player to bypass the arrivals limit
nocheatplus.checks.chat.color:
description: Allow a player to send colored chat messages
nocheatplus.checks.fight:

View File

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

View File

@ -34,4 +34,6 @@ public interface NoCheatPlusPlayer {
public boolean isSprinting();
public void sendMessage(String message);
}

View File

@ -118,6 +118,11 @@ public class NoCheatPlusPlayerImpl implements NoCheatPlusPlayer {
config = plugin.getConfig(player);
}
@Override
public void sendMessage(final String message) {
player.sendMessage(message);
}
public void setLastUsedTime(final long currentTimeInMilliseconds) {
lastUsedTime = currentTimeInMilliseconds;
}

View File

@ -20,7 +20,9 @@ public enum ParameterName {
BLOCK_TYPE("blocktype"),
LIMIT("limit"),
FOOD("food"),
SERVERS("servers");
SERVERS("servers"),
REASON("reason"),
IP("ip");
public static final ParameterName get(final String s) {
for (final ParameterName c : ParameterName.values())

View File

@ -5,7 +5,7 @@ import java.util.Arrays;
import me.neatmonster.nocheatplus.NoCheatPlus;
import me.neatmonster.nocheatplus.NoCheatPlusPlayer;
public class SpamJoinsCheck extends ChatCheck {
public class ArrivalsLimitCheck extends ChatCheck {
// Used to know if the cooldown is enabled and since when
private boolean cooldown = false;
@ -15,22 +15,22 @@ public class SpamJoinsCheck extends ChatCheck {
private long[] joinsTimes = null;
private String[] joinsPlayers = null;
public SpamJoinsCheck(final NoCheatPlus plugin) {
super(plugin, "chat.spamjoins");
public ArrivalsLimitCheck(final NoCheatPlus plugin) {
super(plugin, "chat.arrivalslimit");
}
public boolean check(final NoCheatPlusPlayer player, final ChatData data, final ChatConfig cc) {
// Initialize the joins array
if (joinsTimes == null)
joinsTimes = new long[cc.spamJoinsPlayersLimit];
joinsTimes = new long[cc.arrivalsLimitPlayersLimit];
if (joinsPlayers == null)
joinsPlayers = new String[cc.spamJoinsPlayersLimit];
joinsPlayers = new String[cc.arrivalsLimitPlayersLimit];
boolean kick = false;
boolean cancel = false;
// If the new players cooldown is over
if (cooldown && System.currentTimeMillis() - cooldownStartTime > cc.spamJoinsCooldown) {
if (cooldown && System.currentTimeMillis() - cooldownStartTime > cc.arrivalsLimitCooldownDelay) {
// Stop the new players cooldown
cooldown = false;
cooldownStartTime = 0L;
@ -39,27 +39,27 @@ public class SpamJoinsCheck extends ChatCheck {
// If the new players cooldown is active
else if (cooldown)
// Kick the player who joined
kick = true;
cancel = executeActions(player, cc.arrivalsLimitActions, 0);
// If more than limit new players have joined in less than limit time
else if (System.currentTimeMillis() - joinsTimes[0] < cc.spamJoinsTimeLimit) {
else if (System.currentTimeMillis() - joinsTimes[0] < cc.arrivalsLimitTimeframe) {
// Enable the new players cooldown
cooldown = true;
cooldownStartTime = System.currentTimeMillis();
// Kick the player who joined
kick = true;
cancel = executeActions(player, cc.arrivalsLimitActions, 0);
}
// Fill the joining times array
if (!Arrays.asList(joinsPlayers).contains(player.getName())) {
for (int i = 0; i < cc.spamJoinsPlayersLimit - 1; i++) {
for (int i = 0; i < cc.arrivalsLimitPlayersLimit - 1; i++) {
joinsTimes[i] = joinsTimes[i + 1];
joinsPlayers[i] = joinsPlayers[i + 1];
}
joinsTimes[cc.spamJoinsPlayersLimit - 1] = System.currentTimeMillis();
joinsPlayers[cc.spamJoinsPlayersLimit - 1] = player.getName();
joinsTimes[cc.arrivalsLimitPlayersLimit - 1] = System.currentTimeMillis();
joinsPlayers[cc.arrivalsLimitPlayersLimit - 1] = player.getName();
}
return kick;
return cancel;
}
}

View File

@ -1,5 +1,6 @@
package me.neatmonster.nocheatplus.checks.chat;
import java.lang.management.ManagementFactory;
import java.util.LinkedList;
import java.util.List;
@ -9,16 +10,14 @@ import me.neatmonster.nocheatplus.NoCheatPlusPlayer;
import me.neatmonster.nocheatplus.config.ConfigurationCacheStore;
import me.neatmonster.nocheatplus.config.Permissions;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerChatEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerLoginEvent.Result;
import org.bukkit.plugin.Plugin;
/**
* Central location to listen to events that are
@ -27,19 +26,20 @@ import org.bukkit.plugin.Plugin;
*/
public class ChatCheckListener implements Listener, EventManager {
private final SpamCheck spamCheck;
private final SpamJoinsCheck spamJoinsCheck;
private final ColorCheck colorCheck;
private final NoPwnageCheck noPwnageCheck;
private final ArrivalsLimitCheck arrivalsLimitCheck;
private final ColorCheck colorCheck;
private final NoCheatPlus plugin;
private final NoCheatPlus plugin;
public ChatCheckListener(final NoCheatPlus plugin) {
this.plugin = plugin;
spamCheck = new SpamCheck(plugin);
spamJoinsCheck = new SpamJoinsCheck(plugin);
noPwnageCheck = new NoPwnageCheck(plugin);
arrivalsLimitCheck = new ArrivalsLimitCheck(plugin);
colorCheck = new ColorCheck(plugin);
}
/**
@ -61,11 +61,17 @@ public class ChatCheckListener implements Listener, EventManager {
// Remember the original message
data.message = event.getMessage();
// Remember if it is a command or not
if (event instanceof PlayerCommandPreprocessEvent)
data.isCommand = true;
else
data.isCommand = false;
// Now do the actual checks
// First the spam check
if (cc.spamCheck && !player.hasPermission(Permissions.CHAT_SPAM))
cancelled = spamCheck.check(player, data, cc);
// First the nopwnage check
if (cc.noPwnageCheck && !player.hasPermission(Permissions.CHAT_NOPWNAGE))
cancelled = noPwnageCheck.check(player, data, cc);
// Second the color check
if (!cancelled && cc.colorCheck && !player.hasPermission(Permissions.CHAT_COLOR))
@ -90,50 +96,6 @@ public class ChatCheckListener implements Listener, EventManager {
@EventHandler(
priority = EventPriority.LOWEST)
public void commandPreprocess(final PlayerCommandPreprocessEvent event) {
final NoCheatPlusPlayer player = plugin.getPlayer(event.getPlayer());
final ChatConfig cc = ChatCheck.getConfig(player);
// If the command is /plugins or /pl
if ((event.getMessage().equalsIgnoreCase("/plugins")
|| event.getMessage().toLowerCase().startsWith("/plugins ")
|| event.getMessage().equalsIgnoreCase("/pl") || event.getMessage().toLowerCase().startsWith("/pl "))
// Exception for 'PluginList'...
&& Bukkit.getPluginManager().getPlugin("PluginList") == null
// ...and CommandHelper
&& Bukkit.getPluginManager().getPlugin("CommandHelper") == null && cc.hideNoCheatPlus) {
// If the player isn't allowed to use this command
if (!event.getPlayer().hasPermission("bukkit.command.plugins"))
// Fake the permissions error message
event.getPlayer().sendMessage(
ChatColor.RED + "I'm sorry, but you do not have permission to perform this command. "
+ "Please contact the server administrators if you believe that this is in error.");
else {
// Fake the plugins list
final StringBuilder pluginList = new StringBuilder();
final Plugin[] plugins = Bukkit.getPluginManager().getPlugins();
for (final Plugin plugin : plugins) {
// But make sure to hide NoCheatPlus from the plugins list
if (plugin.getName().equals("NoCheatPlus"))
continue;
if (pluginList.length() > 0) {
pluginList.append(ChatColor.WHITE);
pluginList.append(", ");
}
pluginList.append(plugin.isEnabled() ? ChatColor.GREEN : ChatColor.RED);
pluginList.append(plugin.getDescription().getName());
}
// Of course decrease the number of plugins
event.getPlayer().sendMessage("Plugins (" + (plugins.length - 1) + "): " + pluginList.toString());
}
// Cancel the event, we have already replied to the player
event.setCancelled(true);
}
// This type of event is derived from PlayerChatEvent, therefore
// just treat it like that
chat(event);
@ -144,29 +106,46 @@ public class ChatCheckListener implements Listener, EventManager {
final LinkedList<String> s = new LinkedList<String>();
final ChatConfig c = ChatCheck.getConfig(cc);
if (c.spamCheck)
s.add("chat.spam");
if (c.spamJoinsCheck)
s.add("chat.spamjoins");
if (c.noPwnageCheck)
s.add("chat.nopwnage");
if (c.arrivalsLimitCheck)
s.add("chat.arrivalscheck");
if (c.colorCheck)
s.add("chat.color");
return s;
}
@EventHandler(
priority = EventPriority.LOWEST)
public void join(final PlayerJoinEvent event) {
final NoCheatPlusPlayer player = plugin.getPlayer(event.getPlayer());
final ChatConfig cc = ChatCheck.getConfig(player);
final ChatData data = ChatCheck.getData(player);
// Check if the join is valid
if (cc.noPwnageCheck && !player.hasPermission(Permissions.CHAT_NOPWNAGE))
noPwnageCheck.handleJoin(player, data, cc);
}
@EventHandler(
ignoreCancelled = true, priority = EventPriority.LOWEST)
public void login(final PlayerLoginEvent event) {
// Only check new players (who has joined less than 10 minutes ago)
if (System.currentTimeMillis() - event.getPlayer().getFirstPlayed() > 600000D)
// Do not check the players if the server has just restarted
if (System.currentTimeMillis() - ManagementFactory.getRuntimeMXBean().getStartTime() < 120000L)
return;
final NoCheatPlusPlayer player = plugin.getPlayer(event.getPlayer());
final ChatConfig cc = ChatCheck.getConfig(player);
final ChatData data = ChatCheck.getData(player);
if (cc.spamJoinsCheck && spamJoinsCheck.check(player, data, cc))
// Only check new players, not the regular players
if (System.currentTimeMillis() - event.getPlayer().getFirstPlayed() > cc.arrivalsLimitNewTime)
return;
if (cc.arrivalsLimitCheck && arrivalsLimitCheck.check(player, data, cc))
// If the player failed the check, disallow the login
event.disallow(Result.KICK_OTHER, cc.spamJoinsKickMessage);
event.disallow(Result.KICK_OTHER, cc.arrivalsLimitKickMessage);
}
}

View File

@ -1,8 +1,5 @@
package me.neatmonster.nocheatplus.checks.chat;
import java.util.LinkedList;
import java.util.List;
import me.neatmonster.nocheatplus.ConfigItem;
import me.neatmonster.nocheatplus.actions.types.ActionList;
import me.neatmonster.nocheatplus.config.ConfPaths;
@ -17,59 +14,118 @@ import me.neatmonster.nocheatplus.config.Permissions;
*/
public class ChatConfig implements ConfigItem {
public final boolean hideNoCheatPlus;
public final boolean hideCommands;
public final boolean spamCheck;
public final String[] spamWhitelist;
public final long spamTimeframe;
public final int spamMessageLimit;
public final int spamCommandLimit;
public final ActionList spamActions;
public final boolean noPwnageCheck;
public final boolean noPwnageWarnPlayers;
public final boolean noPwnageWarnOthers;
public final int noPwnageWarnLevel;
public final long noPwnageWarnTimeout;
public final int noPwnageBanLevel;
public final ActionList noPwnageActions;
public final boolean spamJoinsCheck;
public final int spamJoinsPlayersLimit;
public final int spamJoinsTimeLimit;
public final int spamJoinsCooldown;
public final String spamJoinsKickMessage;
public final boolean noPwnageMoveCheck;
public final int noPwnageMoveWeightBonus;
public final int noPwnageMoveWeightMalus;
public final long noPwnageMoveTimeout;
public final boolean noPwnageSpeedCheck;
public final int noPwnageSpeedWeight;
public final long noPwnageSpeedTimeout;
public final boolean noPwnageFirstCheck;
public final int noPwnageFirstWeight;
public final long noPwnageFirstTimeout;
public final boolean noPwnageRepeatCheck;
public final int noPwnageRepeatWeight;
public final long noPwnageRepeatTimeout;
public final boolean noPwnageGlobalCheck;
public final int noPwnageGlobalWeight;
public final long noPwnageGlobalTimeout;
public final boolean noPwnageBannedCheck;
public final int noPwnageBannedWeight;
public final long noPwnageBannedTimeout;
public final boolean noPwnageRelogCheck;
public final long noPwnageRelogTime;
public final int noPwnageRelogWarnings;
public final long noPwnageRelogTimeout;
public final boolean noPwnageCaptchaCheck;
public final int noPwnageCaptchaLength;
public final String noPwnageCaptchaCharacters;
public final int noPwnageCaptchaTries;
public final boolean arrivalsLimitCheck;
public final int arrivalsLimitPlayersLimit;
public final long arrivalsLimitTimeframe;
public final long arrivalsLimitCooldownDelay;
public final long arrivalsLimitNewTime;
public final String arrivalsLimitKickMessage;
public final ActionList arrivalsLimitActions;
public final boolean colorCheck;
public final ActionList colorActions;
public ChatConfig(final NoCheatPlusConfiguration data) {
hideNoCheatPlus = data.getBoolean(ConfPaths.CHAT_HIDENOCHEATPLUS);
spamCheck = data.getBoolean(ConfPaths.CHAT_SPAM_CHECK);
spamWhitelist = splitWhitelist(data.getString(ConfPaths.CHAT_SPAM_WHITELIST));
spamTimeframe = data.getInt(ConfPaths.CHAT_SPAM_TIMEFRAME) * 1000L;
spamMessageLimit = data.getInt(ConfPaths.CHAT_SPAM_MESSAGELIMIT);
spamCommandLimit = data.getInt(ConfPaths.CHAT_SPAM_COMMANDLIMIT);
spamActions = data.getActionList(ConfPaths.CHAT_SPAM_ACTIONS, Permissions.CHAT_SPAM);
spamJoinsCheck = data.getBoolean(ConfPaths.CHAT_SPAMJOINS_CHECK);
spamJoinsPlayersLimit = data.getInt(ConfPaths.CHAT_SPAMJOINS_PLAYERSLIMIT);
spamJoinsTimeLimit = data.getInt(ConfPaths.CHAT_SPAMJOINS_TIMELIMIT);
spamJoinsCooldown = data.getInt(ConfPaths.CHAT_SPAMJOINS_COOLDOWN);
spamJoinsKickMessage = data.getString(ConfPaths.CHAT_SPAMJOINS_KICKMESSAGE);
hideCommands = data.getBoolean(ConfPaths.CHAT_HIDECOMMANDS);
noPwnageCheck = data.getBoolean(ConfPaths.CHAT_NOPWNAGE_CHECK);
noPwnageWarnPlayers = data.getBoolean(ConfPaths.CHAT_NOPWNAGE_WARNPLAYERS);
noPwnageWarnOthers = data.getBoolean(ConfPaths.CHAT_NOPWNAGE_WARNOTHERS);
noPwnageWarnLevel = data.getInt(ConfPaths.CHAT_NOPWNAGE_WARNLEVEL);
noPwnageWarnTimeout = data.getLong(ConfPaths.CHAT_NOPWNAGE_WARNTIMEOUT);
noPwnageBanLevel = data.getInt(ConfPaths.CHAT_NOPWNAGE_BANLEVEL);
noPwnageActions = data.getActionList(ConfPaths.CHAT_NOPWNAGE_ACTIONS, Permissions.CHAT_NOPWNAGE);
noPwnageMoveCheck = data.getBoolean(ConfPaths.CHAT_NOPWNAGE_MOVE_CHECK);
noPwnageMoveWeightBonus = data.getInt(ConfPaths.CHAT_NOPWNAGE_MOVE_WEIGHTBONUS);
noPwnageMoveWeightMalus = data.getInt(ConfPaths.CHAT_NOPWNAGE_MOVE_WEIGHTMALUS);
noPwnageMoveTimeout = data.getLong(ConfPaths.CHAT_NOPWNAGE_MOVE_TIMEOUT);
noPwnageSpeedCheck = data.getBoolean(ConfPaths.CHAT_NOPWNAGE_SPEED_CHECK);
noPwnageSpeedWeight = data.getInt(ConfPaths.CHAT_NOPWNAGE_SPEED_WEIGHT);
noPwnageSpeedTimeout = data.getLong(ConfPaths.CHAT_NOPWNAGE_SPEED_TIMEOUT);
noPwnageFirstCheck = data.getBoolean(ConfPaths.CHAT_NOPWNAGE_FIRST_CHECK);
noPwnageFirstWeight = data.getInt(ConfPaths.CHAT_NOPWNAGE_FIRST_WEIGHT);
noPwnageFirstTimeout = data.getLong(ConfPaths.CHAT_NOPWNAGE_FIRST_TIMEOUT);
noPwnageRepeatCheck = data.getBoolean(ConfPaths.CHAT_NOPWNAGE_REPEAT_CHECK);
noPwnageRepeatWeight = data.getInt(ConfPaths.CHAT_NOPWNAGE_REPEAT_WEIGHT);
noPwnageRepeatTimeout = data.getInt(ConfPaths.CHAT_NOPWNAGE_REPEAT_TIMEOUT);
noPwnageGlobalCheck = data.getBoolean(ConfPaths.CHAT_NOPWNAGE_GLOBAL_CHECK);
noPwnageGlobalWeight = data.getInt(ConfPaths.CHAT_NOPWNAGE_GLOBAL_WEIGHT);
noPwnageGlobalTimeout = data.getLong(ConfPaths.CHAT_NOPWNAGE_GLOBAL_TIMEOUT);
noPwnageBannedCheck = data.getBoolean(ConfPaths.CHAT_NOPWNAGE_BANNED_CHECK);
noPwnageBannedWeight = data.getInt(ConfPaths.CHAT_NOPWNAGE_BANNED_WEIGHT);
noPwnageBannedTimeout = data.getLong(ConfPaths.CHAT_NOPWNAGE_BANNED_TIMEOUT);
noPwnageRelogCheck = data.getBoolean(ConfPaths.CHAT_NOPWNAGE_RELOG_CHECK);
noPwnageRelogTime = data.getLong(ConfPaths.CHAT_NOPWNAGE_RELOG_TIME);
noPwnageRelogWarnings = data.getInt(ConfPaths.CHAT_NOPWNAGE_RELOG_WARNINGS);
noPwnageRelogTimeout = data.getLong(ConfPaths.CHAT_NOPWNAGE_RELOG_TIMEOUT);
noPwnageCaptchaCheck = data.getBoolean(ConfPaths.CHAT_NOPWNAGE_CAPTCHA_CHECK);
noPwnageCaptchaLength = data.getInt(ConfPaths.CHAT_NOPWNAGE_CAPTCHA_LENGTH);
noPwnageCaptchaCharacters = data.getString(ConfPaths.CHAT_NOPWNAGE_CAPTCHA_CHARACTERS);
noPwnageCaptchaTries = data.getInt(ConfPaths.CHAT_NOPWNAGE_CAPTCHA_TRIES);
arrivalsLimitCheck = data.getBoolean(ConfPaths.CHAT_ARRIVALSLIMIT_CHECK);
arrivalsLimitPlayersLimit = data.getInt(ConfPaths.CHAT_ARRIVALSLIMIT_PLAYERSLIMIT);
arrivalsLimitTimeframe = data.getLong(ConfPaths.CHAT_ARRIVALSLIMIT_TIMEFRAME);
arrivalsLimitCooldownDelay = data.getLong(ConfPaths.CHAT_ARRIVALSLIMIT_COOLDOWNDELAY);
arrivalsLimitNewTime = data.getLong(ConfPaths.CHAT_ARRIVALSLIMIT_NEWTIME);
arrivalsLimitKickMessage = data.getString(ConfPaths.CHAT_ARRIVALSLIMIT_KICKMESSAGE);
arrivalsLimitActions = data.getActionList(ConfPaths.CHAT_ARRIVALSLIMIT_ACTIONS, Permissions.CHAT_ARRIVALSLIMIT);
colorCheck = data.getBoolean(ConfPaths.CHAT_COLOR_CHECK);
colorActions = data.getActionList(ConfPaths.CHAT_COLOR_ACTIONS, Permissions.CHAT_COLOR);
}
/**
* Convenience method to split a string into an array on every occurance of
* the "," character, removing all whitespaces before and after it too.
*
* @param string
* The string containing text seperated by ","
* @return An array of the seperate texts
*/
private String[] splitWhitelist(String string) {
final List<String> strings = new LinkedList<String>();
string = string.trim();
for (final String s : string.split(","))
if (s != null && s.trim().length() > 0)
strings.add(s.trim());
return strings.toArray(new String[strings.size()]);
}
}

View File

@ -1,13 +1,7 @@
package me.neatmonster.nocheatplus.checks.chat;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import me.neatmonster.nocheatplus.DataItem;
import me.neatmonster.nocheatplus.data.SimpleLocation;
/**
* Player specific data for the chat checks
@ -15,53 +9,55 @@ import me.neatmonster.nocheatplus.DataItem;
*/
public class ChatData implements DataItem {
// Keep track of the violation levels for the two checks
public int spamVL;
public int spamJoinsVL;
public int colorVL;
// Keep track of the violation levels for the check
public int colorVL;
// Count messages and commands
public int messageCount = 0;
public int commandCount = 0;
// Remember when the last check time period started
public long spamLastTime = 0;
// Remember the player's location
public final SimpleLocation location = new SimpleLocation();
// Remember the last chat message or command for logging purposes
public String message = "";
public String message = "";
public String lastMessage = "";
public long lastMessageTime;
// Remember the question
private String[] question = null;
// Remember if the message is a command or not
public boolean isCommand = false;
public String[] getQuestion() {
if (question != null)
return question;
try {
// The URL of the .txt file containing the questions and the hashed answers
final URL dropBox = new URL("http://dl.dropbox.com/u/34835222/NoCheatPlus_Questions.txt");
// Remember some other time informations about the player
public long joinTime;
public long leaveTime;
public long lastWarningTime;
public long lastRelogWarningTime;
public long lastMovedTime;
// Reading the file
String line;
final List<String> lines = new ArrayList<String>();
final BufferedReader reader = new BufferedReader(new InputStreamReader(dropBox.openStream()));
while ((line = reader.readLine()) != null)
lines.add(line);
reader.close();
// Remember how many time the player has repeated the same message
public int messageRepeated;
// Choosing a random question and answer
final Random random = new Random();
line = lines.get(random.nextInt(lines.size()));
final String question = line.split("--")[0];
final String answer = line.split("--")[1];
// Remember some warning levels
public int relogWarnings;
public int speedRepeated;
// Save the question
this.question = new String[] {question, answer};
// Remember some data about captcha
public String captchaAnswer = "";
public String captchaQuestion = "";
public boolean captchaDone = false;
public boolean captchaStarted = false;
public int captchaTries;
// Returning the selected question and answer
return this.question;
} catch (final Exception e) {
e.printStackTrace();
}
return null;
// Remember if commands have been run by the player
public boolean commandsHaveBeenRun = false;
// Remember reason and player's IP
public String reason = "";
public String ip = "";
public boolean compareLocation(final SimpleLocation l) {
return location != null && location.x == l.x && location.y == l.y && location.z == l.z;
}
public void setLocation(final SimpleLocation l) {
location.x = l.x;
location.y = l.y;
location.z = l.z;
}
}

View File

@ -0,0 +1,299 @@
package me.neatmonster.nocheatplus.checks.chat;
import java.util.Locale;
import java.util.Random;
import me.neatmonster.nocheatplus.NoCheatPlus;
import me.neatmonster.nocheatplus.NoCheatPlusPlayer;
import me.neatmonster.nocheatplus.actions.ParameterName;
import me.neatmonster.nocheatplus.config.ConfPaths;
import me.neatmonster.nocheatplus.data.SimpleLocation;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
public class NoPwnageCheck extends ChatCheck {
private String lastBanCausingMessage;
private long lastBanCausingMessageTime;
private String lastGlobalMessage;
private long lastGlobalMessageTime;
private int globalRepeated;
private final Random random = new Random();
public NoPwnageCheck(final NoCheatPlus plugin) {
super(plugin, "chat.nopwnage");
// Store the players' location
for (final Player player : Bukkit.getOnlinePlayers()) {
final ChatData data = ChatCheck.getData(plugin.getPlayer(player));
data.location.setLocation(player.getLocation());
}
}
public boolean check(final NoCheatPlusPlayer player, final ChatData data, final ChatConfig cc) {
boolean cancel = false;
if (data.commandsHaveBeenRun || !player.getPlayer().isOnline())
return false;
// Player is supposed to fill out a captcha
if (cc.noPwnageCaptchaCheck && data.captchaDone)
// His reply was valid, he isn't a spambot
return false;
if (cc.noPwnageCaptchaCheck && data.captchaStarted) {
// Correct answer?
if (data.message.equals(data.captchaAnswer))
data.captchaDone = true;
else {
// Display the question again
player.sendMessage(data.captchaQuestion);
// He failed too much times
if (data.captchaTries > cc.noPwnageCaptchaTries)
if (player.getPlayer().isOnline())
// Execute the commands, it's a spambot
runCommands(player, "failed captcha", data, cc);
// Increment the number of times he replied
data.captchaTries++;
}
return true;
}
// Do some pre-testing for the next check
final long now = System.currentTimeMillis();
final SimpleLocation location = new SimpleLocation();
location.setLocation(player.getPlayer().getLocation());
double suspicion = 0;
if (data.location == null)
data.setLocation(location);
else if (!data.compareLocation(location)) {
data.setLocation(location);
data.lastMovedTime = now;
}
// Banned check (cf. documentation)
if (!data.isCommand && cc.noPwnageBannedCheck && now - lastBanCausingMessageTime < cc.noPwnageBannedTimeout
&& similar(data.message, lastBanCausingMessage))
suspicion += cc.noPwnageBannedWeight;
// First check (cf. documentation)
if (cc.noPwnageFirstCheck && now - data.joinTime <= cc.noPwnageFirstTimeout)
suspicion += cc.noPwnageFirstWeight;
// Global check (cf. documentation)
if (!data.isCommand && cc.noPwnageGlobalCheck && now - lastGlobalMessageTime < cc.noPwnageGlobalTimeout
&& similar(data.message, lastGlobalMessage)) {
final int added = (globalRepeated + 2) * cc.noPwnageGlobalWeight / 2;
globalRepeated++;
suspicion += added;
} else
globalRepeated = 0;
// Speed check (cf. documentation)
if (cc.noPwnageSpeedCheck && now - data.lastMessageTime <= cc.noPwnageSpeedTimeout) {
int added = (data.speedRepeated + 2) * cc.noPwnageSpeedWeight / 2;
data.speedRepeated++;
if (data.isCommand)
added /= 4;
suspicion += added;
} else
data.speedRepeated = 0;
// Repeat check (cf. documentation)
if (!data.isCommand && cc.noPwnageRepeatCheck && now - data.lastMessageTime <= cc.noPwnageRepeatTimeout
&& similar(data.message, data.lastMessage)) {
final int added = (data.messageRepeated + 2) * cc.noPwnageRepeatWeight / 2;
data.messageRepeated++;
suspicion += added;
} else
data.messageRepeated = 0;
boolean warned = false;
if (cc.noPwnageWarnPlayers && now - data.lastWarningTime <= cc.noPwnageWarnTimeout) {
suspicion += 100;
warned = true;
}
// Move checks (cf. documentation)
if (cc.noPwnageMoveCheck && now - data.lastMovedTime <= cc.noPwnageMoveTimeout)
suspicion -= cc.noPwnageMoveWeightBonus;
else
suspicion += cc.noPwnageMoveWeightMalus;
// Warn player
if (cc.noPwnageWarnPlayers && suspicion >= cc.noPwnageWarnLevel && !warned) {
data.lastWarningTime = now;
warnPlayer(player);
} else if (suspicion >= cc.noPwnageBanLevel)
if (cc.noPwnageCaptchaCheck && !data.captchaStarted) {
// Display the captcha to the player
data.captchaStarted = true;
final String captcha = generateCaptcha(cc);
data.captchaAnswer = captcha;
data.captchaQuestion = ChatColor.RED + "Please type '" + ChatColor.GOLD + captcha + ChatColor.RED
+ "' to continue sending messages/commands.";
cancel = true;
player.sendMessage(data.captchaQuestion);
} else if (player.getPlayer().isOnline()) {
// Execute the commands, it's a spambot
lastBanCausingMessage = data.message;
lastBanCausingMessageTime = now;
data.lastWarningTime = now;
if (cc.noPwnageWarnOthers)
warnOthers(player);
runCommands(player, "spambotlike behaviour", data, cc);
return true;
}
// Remember his message and some other data
data.lastMessage = data.message;
data.lastMessageTime = now;
lastGlobalMessage = data.message;
lastGlobalMessageTime = now;
return cancel;
}
private String generateCaptcha(final ChatConfig cc) {
final StringBuilder b = new StringBuilder();
for (int i = 0; i < cc.noPwnageCaptchaLength; i++)
b.append(cc.noPwnageCaptchaCharacters.charAt(random.nextInt(cc.noPwnageCaptchaCharacters.length())));
return b.toString();
}
@Override
public String getParameter(final ParameterName wildcard, final NoCheatPlusPlayer player) {
if (wildcard == ParameterName.REASON)
return String.format(Locale.US, "%d", getData(player).reason);
else if (wildcard == ParameterName.IP)
return String.format(Locale.US, "%d", getData(player).ip);
else
return super.getParameter(wildcard, player);
}
public void handleJoin(final NoCheatPlusPlayer player, final ChatData data, final ChatConfig cc) {
final long now = System.currentTimeMillis();
// Relog check (cf. documentation)
if (cc.noPwnageRelogCheck && now - data.leaveTime <= cc.noPwnageRelogTime) {
if (now - data.lastRelogWarningTime >= cc.noPwnageRelogTimeout)
data.relogWarnings = 0;
if (data.relogWarnings < cc.noPwnageRelogWarnings) {
player.sendMessage(player.getConfigurationStore().getConfiguration()
.getString(ConfPaths.LOGGING_PREFIX)
+ ChatColor.DARK_RED
+ "You relogged really fast! If you keep doing that, you're going to be banned.");
data.lastRelogWarningTime = now;
data.relogWarnings++;
} else if (now - data.lastRelogWarningTime < cc.noPwnageRelogTimeout)
// Run the commands, it's a spambot
runCommands(player, "relogged too fast", data, cc);
}
// Remember his location
final SimpleLocation location = new SimpleLocation();
location.setLocation(player.getPlayer().getLocation());
data.setLocation(location);
data.joinTime = now;
data.commandsHaveBeenRun = false;
}
private int minimum(final int a, final int b, final int c) {
int mi;
mi = a;
if (b < mi)
mi = b;
if (c < mi)
mi = c;
return mi;
}
private void runCommands(final NoCheatPlusPlayer player, final String reason, final ChatData data,
final ChatConfig cc) {
data.reason = reason;
data.ip = player.getPlayer().getAddress().toString().substring(1).split(":")[0];
if (player.getPlayer().isOnline()) {
data.commandsHaveBeenRun = true;
executeActions(player, cc.noPwnageActions, 0);
}
}
private boolean similar(final String message1, final String message2) {
return message1 != null && message2 != null
&& stringDifference(message1, message2) < 1 + message1.length() / 10;
}
private int stringDifference(final String s, final String t) {
int d[][];
int n;
int m;
int i;
int j;
char s_i;
char t_j;
int cost;
n = s.length();
m = t.length();
if (n == 0)
return m;
if (m == 0)
return n;
d = new int[n + 1][m + 1];
for (i = 0; i <= n; i++)
d[i][0] = i;
for (j = 0; j <= m; j++)
d[0][j] = j;
for (i = 1; i <= n; i++) {
s_i = s.charAt(i - 1);
for (j = 1; j <= m; j++) {
t_j = t.charAt(j - 1);
if (s_i == t_j)
cost = 0;
else
cost = 1;
d[i][j] = minimum(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost);
}
}
return d[n][m];
}
private void warnOthers(final NoCheatPlusPlayer player) {
plugin.getServer().broadcastMessage(
ChatColor.YELLOW + player.getName() + ChatColor.DARK_RED + " has set off the autoban!");
plugin.getServer().broadcastMessage(
ChatColor.DARK_RED + " Please do not say anything similar to what the user said!");
}
private void warnPlayer(final NoCheatPlusPlayer player) {
player.sendMessage(player.getConfigurationStore().getConfiguration().getString(ConfPaths.LOGGING_PREFIX)
+ ChatColor.DARK_RED + "Our system has detected unusual bot activities coming from you.");
player.sendMessage(ChatColor.DARK_RED
+ "Please be careful with what you say. DON'T repeat what you just said either, unless you want to be banned.");
}
}

View File

@ -1,78 +0,0 @@
package me.neatmonster.nocheatplus.checks.chat;
import java.util.Locale;
import me.neatmonster.nocheatplus.NoCheatPlus;
import me.neatmonster.nocheatplus.NoCheatPlusPlayer;
import me.neatmonster.nocheatplus.actions.ParameterName;
import me.neatmonster.nocheatplus.data.Statistics.Id;
/**
* The SpamCheck will count messages and commands over a short timeframe to
* see if the player tried to send too many of them
*
*/
public class SpamCheck extends ChatCheck {
public SpamCheck(final NoCheatPlus plugin) {
super(plugin, "chat.spam");
}
public boolean check(final NoCheatPlusPlayer player, final ChatData data, final ChatConfig cc) {
boolean cancel = false;
// Maybe it's a command and on the whitelist
for (final String s : cc.spamWhitelist)
if (data.message.startsWith(s))
// It is
return false;
final int commandLimit = cc.spamCommandLimit;
final int messageLimit = cc.spamMessageLimit;
final long timeframe = cc.spamTimeframe;
final long time = System.currentTimeMillis();
// Has enough time passed? Then reset the counters
if (data.spamLastTime + timeframe <= time) {
data.spamLastTime = time;
data.messageCount = 0;
data.commandCount = 0;
}
// Security check, if the system time changes
else if (data.spamLastTime > time)
data.spamLastTime = Integer.MIN_VALUE;
// Increment appropriate counter
if (data.message.startsWith("/"))
data.commandCount++;
else
data.messageCount++;
// Did the player go over the limit on at least one of the counters?
if (data.messageCount > messageLimit || data.commandCount > commandLimit) {
// Set the vl as the number of messages above the limit and
// increment statistics
data.spamVL = Math.max(0, data.messageCount - messageLimit);
data.spamVL += Math.max(0, data.commandCount - commandLimit);
incrementStatistics(player, Id.CHAT_SPAM, 1);
// Execute whatever actions are associated with this check and the
// violation level and find out if we should cancel the event
cancel = executeActions(player, cc.spamActions, data.spamVL);
}
return cancel;
}
@Override
public String getParameter(final ParameterName wildcard, final NoCheatPlusPlayer player) {
if (wildcard == ParameterName.VIOLATIONS)
return String.format(Locale.US, "%d", getData(player).spamVL);
else
return super.getParameter(wildcard, player);
}
}

View File

@ -102,5 +102,6 @@ public class MovingData implements DataItem {
fallDistance = 0;
lastAddedFallDistance = 0;
bunnyhopdelay = 0;
fallingSince = 0;
}
}

View File

@ -71,7 +71,7 @@ public class CommandHandler {
final ChatConfig cc = ChatCheck.getConfig(player);
// Hide NoCheatPlus's commands if the player doesn't have the required permission
if (!sender.hasPermission("nocheatplus.admin.commands") && cc.hideNoCheatPlus) {
if (cc.hideCommands && !sender.hasPermission("nocheatplus.admin.commands")) {
sender.sendMessage("Unknown command. Type \"help\" for help.");
return true;
}

View File

@ -131,27 +131,73 @@ public abstract class ConfPaths {
private final static String CHAT = CHECKS + "chat.";
public final static String CHAT_HIDENOCHEATPLUS = CHAT + "hidenocheatplus";
public final static String CHAT_HIDECOMMANDS = CHAT + "hidecommands";
private final static String CHAT_NOPWNAGE = CHAT + "nopwnage.";
public final static String CHAT_NOPWNAGE_CHECK = CHAT_NOPWNAGE + "active";
public final static String CHAT_NOPWNAGE_WARNPLAYERS = CHAT_NOPWNAGE + "warnplayers";
public final static String CHAT_NOPWNAGE_WARNOTHERS = CHAT_NOPWNAGE + "warnothers";
public final static String CHAT_NOPWNAGE_WARNLEVEL = CHAT_NOPWNAGE + "warnlevel";
public final static String CHAT_NOPWNAGE_WARNTIMEOUT = CHAT_NOPWNAGE + "warntimeout";
public final static String CHAT_NOPWNAGE_BANLEVEL = CHAT_NOPWNAGE + "banlevel";
public final static String CHAT_NOPWNAGE_ACTIONS = CHAT_NOPWNAGE + "actions";
private final static String CHAT_NOPWNAGE_MOVE = CHAT_NOPWNAGE + "move.";
public final static String CHAT_NOPWNAGE_MOVE_CHECK = CHAT_NOPWNAGE_MOVE + "active";
public final static String CHAT_NOPWNAGE_MOVE_WEIGHTBONUS = CHAT_NOPWNAGE_MOVE + "weightbonus";
public final static String CHAT_NOPWNAGE_MOVE_WEIGHTMALUS = CHAT_NOPWNAGE_MOVE + "weightmalus";
public final static String CHAT_NOPWNAGE_MOVE_TIMEOUT = CHAT_NOPWNAGE_MOVE + "timeout";
private final static String CHAT_NOPWNAGE_REPEAT = CHAT_NOPWNAGE + "repeat.";
public final static String CHAT_NOPWNAGE_REPEAT_CHECK = CHAT_NOPWNAGE_REPEAT + "active";
public final static String CHAT_NOPWNAGE_REPEAT_WEIGHT = CHAT_NOPWNAGE_REPEAT + "weight";
public final static String CHAT_NOPWNAGE_REPEAT_TIMEOUT = CHAT_NOPWNAGE_REPEAT + "timeout";
private final static String CHAT_NOPWNAGE_SPEED = CHAT_NOPWNAGE + "speed.";
public final static String CHAT_NOPWNAGE_SPEED_CHECK = CHAT_NOPWNAGE_SPEED + "active";
public final static String CHAT_NOPWNAGE_SPEED_WEIGHT = CHAT_NOPWNAGE_SPEED + "weight";
public final static String CHAT_NOPWNAGE_SPEED_TIMEOUT = CHAT_NOPWNAGE_SPEED + "timeout";
private final static String CHAT_NOPWNAGE_FIRST = CHAT_NOPWNAGE + "first.";
public final static String CHAT_NOPWNAGE_FIRST_CHECK = CHAT_NOPWNAGE_FIRST + "active";
public final static String CHAT_NOPWNAGE_FIRST_WEIGHT = CHAT_NOPWNAGE_FIRST + "weight";
public final static String CHAT_NOPWNAGE_FIRST_TIMEOUT = CHAT_NOPWNAGE_FIRST + "timeout";
private final static String CHAT_NOPWNAGE_GLOBAL = CHAT_NOPWNAGE + "global.";
public final static String CHAT_NOPWNAGE_GLOBAL_CHECK = CHAT_NOPWNAGE_GLOBAL + "active";
public final static String CHAT_NOPWNAGE_GLOBAL_WEIGHT = CHAT_NOPWNAGE_GLOBAL + "weight";
public final static String CHAT_NOPWNAGE_GLOBAL_TIMEOUT = CHAT_NOPWNAGE_GLOBAL + "timeout";
private final static String CHAT_NOPWNAGE_BANNED = CHAT_NOPWNAGE + "banned.";
public final static String CHAT_NOPWNAGE_BANNED_CHECK = CHAT_NOPWNAGE_BANNED + "active";
public final static String CHAT_NOPWNAGE_BANNED_WEIGHT = CHAT_NOPWNAGE_BANNED + "weight";
public final static String CHAT_NOPWNAGE_BANNED_TIMEOUT = CHAT_NOPWNAGE_BANNED + "timeout";
private final static String CHAT_NOPWNAGE_RELOG = CHAT_NOPWNAGE + "relog.";
public final static String CHAT_NOPWNAGE_RELOG_CHECK = CHAT_NOPWNAGE_RELOG + "active";
public final static String CHAT_NOPWNAGE_RELOG_TIME = CHAT_NOPWNAGE_RELOG + "time";
public final static String CHAT_NOPWNAGE_RELOG_WARNINGS = CHAT_NOPWNAGE_RELOG + "warnings";
public final static String CHAT_NOPWNAGE_RELOG_TIMEOUT = CHAT_NOPWNAGE_RELOG + "timeout";
private final static String CHAT_NOPWNAGE_CAPTCHA = CHAT_NOPWNAGE + "captcha.";
public final static String CHAT_NOPWNAGE_CAPTCHA_CHECK = CHAT_NOPWNAGE_CAPTCHA + "active";
public final static String CHAT_NOPWNAGE_CAPTCHA_TRIES = CHAT_NOPWNAGE_CAPTCHA + "tries";
public final static String CHAT_NOPWNAGE_CAPTCHA_LENGTH = CHAT_NOPWNAGE_CAPTCHA + "length";
public final static String CHAT_NOPWNAGE_CAPTCHA_CHARACTERS = CHAT_NOPWNAGE_CAPTCHA + "characters";
private final static String CHAT_ARRIVALSLIMIT = CHAT + "arrivalslimit.";
public final static String CHAT_ARRIVALSLIMIT_CHECK = CHAT_ARRIVALSLIMIT + "active";
public final static String CHAT_ARRIVALSLIMIT_PLAYERSLIMIT = CHAT_ARRIVALSLIMIT + "playerslimit";
public final static String CHAT_ARRIVALSLIMIT_TIMEFRAME = CHAT_ARRIVALSLIMIT + "timeframe";
public final static String CHAT_ARRIVALSLIMIT_COOLDOWNDELAY = CHAT_ARRIVALSLIMIT + "cooldowndelay";
public final static String CHAT_ARRIVALSLIMIT_KICKMESSAGE = CHAT_ARRIVALSLIMIT + "kickmessage";
public final static String CHAT_ARRIVALSLIMIT_NEWTIME = CHAT_ARRIVALSLIMIT + "newtime";
public final static String CHAT_ARRIVALSLIMIT_ACTIONS = CHAT_ARRIVALSLIMIT + "actions";
private final static String CHAT_COLOR = CHAT + "color.";
public final static String CHAT_COLOR_CHECK = CHAT_COLOR + "active";
public final static String CHAT_COLOR_ACTIONS = CHAT_COLOR + "actions";
private final static String CHAT_SPAM = CHAT + "spam.";
public final static String CHAT_SPAM_CHECK = CHAT_SPAM + "active";
public final static String CHAT_SPAM_WHITELIST = CHAT_SPAM + "whitelist";
public final static String CHAT_SPAM_TIMEFRAME = CHAT_SPAM + "timeframe";
public final static String CHAT_SPAM_MESSAGELIMIT = CHAT_SPAM + "messagelimit";
public final static String CHAT_SPAM_COMMANDLIMIT = CHAT_SPAM + "commandlimit";
public final static String CHAT_SPAM_ACTIONS = CHAT_SPAM + "actions";
private final static String CHAT_SPAMJOINS = CHAT + "spamjoins.";
public final static String CHAT_SPAMJOINS_CHECK = CHAT_SPAMJOINS + "active";
public final static String CHAT_SPAMJOINS_PLAYERSLIMIT = CHAT_SPAMJOINS + "playerslimit";
public final static String CHAT_SPAMJOINS_TIMELIMIT = CHAT_SPAMJOINS + "timelimit";
public final static String CHAT_SPAMJOINS_COOLDOWN = CHAT_SPAMJOINS + "cooldown";
public final static String CHAT_SPAMJOINS_KICKMESSAGE = CHAT_SPAMJOINS + "kickmessage";
private final static String FIGHT = CHECKS + "fight.";
private final static String FIGHT_DIRECTION = FIGHT + "direction.";

View File

@ -116,24 +116,63 @@ public class DefaultConfiguration extends NoCheatPlusConfiguration {
/*** CHAT ***/
set(ConfPaths.CHAT_HIDENOCHEATPLUS, true);
set(ConfPaths.CHAT_HIDECOMMANDS, false);
set(ConfPaths.CHAT_NOPWNAGE_CHECK, true);
set(ConfPaths.CHAT_NOPWNAGE_WARNPLAYERS, false);
set(ConfPaths.CHAT_NOPWNAGE_WARNOTHERS, false);
set(ConfPaths.CHAT_NOPWNAGE_WARNLEVEL, 400);
set(ConfPaths.CHAT_NOPWNAGE_WARNTIMEOUT, 30000);
set(ConfPaths.CHAT_NOPWNAGE_BANLEVEL, 800);
set(ConfPaths.CHAT_NOPWNAGE_ACTIONS, "log:nopwnage:2:5:cf cmd:kick cmd:ban cmd:ban-ip");
set(ConfPaths.CHAT_NOPWNAGE_MOVE_CHECK, true);
set(ConfPaths.CHAT_NOPWNAGE_MOVE_WEIGHTBONUS, 200);
set(ConfPaths.CHAT_NOPWNAGE_MOVE_WEIGHTMALUS, 200);
set(ConfPaths.CHAT_NOPWNAGE_MOVE_TIMEOUT, 30000);
set(ConfPaths.CHAT_NOPWNAGE_REPEAT_CHECK, true);
set(ConfPaths.CHAT_NOPWNAGE_REPEAT_WEIGHT, 150);
set(ConfPaths.CHAT_NOPWNAGE_REPEAT_TIMEOUT, 5000);
set(ConfPaths.CHAT_NOPWNAGE_SPEED_CHECK, true);
set(ConfPaths.CHAT_NOPWNAGE_SPEED_WEIGHT, 200);
set(ConfPaths.CHAT_NOPWNAGE_SPEED_TIMEOUT, 500);
set(ConfPaths.CHAT_NOPWNAGE_FIRST_CHECK, true);
set(ConfPaths.CHAT_NOPWNAGE_FIRST_WEIGHT, 200);
set(ConfPaths.CHAT_NOPWNAGE_FIRST_TIMEOUT, 3000);
set(ConfPaths.CHAT_NOPWNAGE_GLOBAL_CHECK, true);
set(ConfPaths.CHAT_NOPWNAGE_GLOBAL_WEIGHT, 100);
set(ConfPaths.CHAT_NOPWNAGE_GLOBAL_TIMEOUT, 5000);
set(ConfPaths.CHAT_NOPWNAGE_BANNED_CHECK, true);
set(ConfPaths.CHAT_NOPWNAGE_BANNED_WEIGHT, 200);
set(ConfPaths.CHAT_NOPWNAGE_BANNED_TIMEOUT, 2000);
set(ConfPaths.CHAT_NOPWNAGE_RELOG_CHECK, true);
set(ConfPaths.CHAT_NOPWNAGE_RELOG_TIME, 1500);
set(ConfPaths.CHAT_NOPWNAGE_RELOG_WARNINGS, 1);
set(ConfPaths.CHAT_NOPWNAGE_RELOG_TIMEOUT, 60000);
set(ConfPaths.CHAT_NOPWNAGE_CAPTCHA_CHECK, true);
set(ConfPaths.CHAT_NOPWNAGE_CAPTCHA_TRIES, 20);
set(ConfPaths.CHAT_NOPWNAGE_CAPTCHA_LENGTH, 4);
set(ConfPaths.CHAT_NOPWNAGE_CAPTCHA_CHARACTERS,
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890");
set(ConfPaths.CHAT_ARRIVALSLIMIT_CHECK, false);
set(ConfPaths.CHAT_ARRIVALSLIMIT_PLAYERSLIMIT, 3);
set(ConfPaths.CHAT_ARRIVALSLIMIT_TIMEFRAME, 5000);
set(ConfPaths.CHAT_ARRIVALSLIMIT_COOLDOWNDELAY, 5000);
set(ConfPaths.CHAT_ARRIVALSLIMIT_NEWTIME, 600000);
set(ConfPaths.CHAT_ARRIVALSLIMIT_KICKMESSAGE, "Please try again later!");
set(ConfPaths.CHAT_ARRIVALSLIMIT_ACTIONS, "cancel");
set(ConfPaths.CHAT_COLOR_CHECK, true);
set(ConfPaths.CHAT_COLOR_ACTIONS, "log:color:0:1:if cancel");
set(ConfPaths.CHAT_SPAM_CHECK, true);
set(ConfPaths.CHAT_SPAM_WHITELIST, "");
set(ConfPaths.CHAT_SPAM_TIMEFRAME, 3);
set(ConfPaths.CHAT_SPAM_MESSAGELIMIT, 3);
set(ConfPaths.CHAT_SPAM_COMMANDLIMIT, 12);
set(ConfPaths.CHAT_SPAM_ACTIONS, "log:spam:0:3:if cancel vl>30 log:spam:0:3:cif cancel cmd:kick");
set(ConfPaths.CHAT_SPAMJOINS_CHECK, true);
set(ConfPaths.CHAT_SPAMJOINS_PLAYERSLIMIT, 3);
set(ConfPaths.CHAT_SPAMJOINS_TIMELIMIT, 5000);
set(ConfPaths.CHAT_SPAMJOINS_COOLDOWN, 5000);
set(ConfPaths.CHAT_SPAMJOINS_KICKMESSAGE, "SpamBot?!");
/*** FIGHT ***/
set(ConfPaths.FIGHT_DIRECTION_CHECK, true);
@ -186,9 +225,9 @@ public class DefaultConfiguration extends NoCheatPlusConfiguration {
"[player] failed [check]: tried to interact with a block out of line of sight. VL [violations]");
set(ConfPaths.STRINGS + ".bpprojectile",
"[player] failed [check]: tried to throw items too quicly. VL [violations]");
set(ConfPaths.STRINGS + ".nopwnage", "Commands run for [player] ([ip]): [reason]!");
set(ConfPaths.STRINGS + ".color",
"[player] failed [check]: Sent colored chat message '[text]'. VL [violations]");
set(ConfPaths.STRINGS + ".spam", "[player] failed [check]: Last sent message '[text]'. VL [violations]");
set(ConfPaths.STRINGS + ".fdirection",
"[player] failed [check]: tried to interact with a block out of line of sight. VL [violations]");
set(ConfPaths.STRINGS + ".freach",
@ -202,6 +241,8 @@ public class DefaultConfiguration extends NoCheatPlusConfiguration {
set(ConfPaths.STRINGS + ".ibow", "[player] failed [check]: Fires bow to fast. VL [violations]");
set(ConfPaths.STRINGS + ".ieat", "[player] failed [check]: Eats food [food] too fast. VL [violations]");
set(ConfPaths.STRINGS + ".kick", "kick [player]");
set(ConfPaths.STRINGS + ".ban", "ban [player]");
set(ConfPaths.STRINGS + ".ban-ip", "ban-ip [ip]");
// Update internal factory based on all the new entries to the "actions" section
regenerateActionLists();

View File

@ -31,7 +31,8 @@ public class Permissions {
public static final String BLOCKPLACE_AUTOSIGN = BLOCKPLACE + ".autosign";
private static final String CHAT = CHECKS + ".chat";
public static final String CHAT_SPAM = CHAT + ".spam";
public static final String CHAT_NOPWNAGE = CHAT + ".nopwnage";
public static final String CHAT_ARRIVALSLIMIT = CHAT + ".arrivalslimit";
public static final String CHAT_COLOR = CHAT + ".color";
private static final String FIGHT = CHECKS + ".fight";

View File

@ -18,7 +18,6 @@ public class Statistics {
BP_REACH("blockplace.reach"),
BP_PROJECTILE("blockplace.projectile"),
CHAT_COLOR("chat.color"),
CHAT_SPAM("chat.spam"),
FI_DIRECTION("fight.direction"),
FI_NOSWING("fight.noswing"),
FI_REACH("fight.reach"),