mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2025-01-01 05:18:00 +01:00
+ Added NoPwnage to NoCheat+ (checks messages, speed, locations, etc.)
- Removed all the stuff with the plugins list
This commit is contained in:
parent
82b5dbc5b1
commit
8546a649ed
219
Instructions.txt
219
Instructions.txt
@ -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 --------------------------------
|
||||
|
||||
|
@ -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:
|
||||
|
2
pom.xml
2
pom.xml
@ -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>
|
||||
|
||||
|
@ -34,4 +34,6 @@ public interface NoCheatPlusPlayer {
|
||||
|
||||
public boolean isSprinting();
|
||||
|
||||
public void sendMessage(String message);
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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())
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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()]);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
299
src/me/neatmonster/nocheatplus/checks/chat/NoPwnageCheck.java
Normal file
299
src/me/neatmonster/nocheatplus/checks/chat/NoPwnageCheck.java
Normal 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.");
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -102,5 +102,6 @@ public class MovingData implements DataItem {
|
||||
fallDistance = 0;
|
||||
lastAddedFallDistance = 0;
|
||||
bunnyhopdelay = 0;
|
||||
fallingSince = 0;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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.";
|
||||
|
@ -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();
|
||||
|
@ -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";
|
||||
|
@ -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"),
|
||||
|
Loading…
Reference in New Issue
Block a user