mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2025-01-02 13:57:49 +01:00
Bleeding: Split off commands check [unfinished].
This commit is contained in:
parent
b34aec55b4
commit
5d337b2b25
@ -79,7 +79,11 @@ public class ChatConfig extends AsyncCheckConfig {
|
||||
public final boolean colorCheck;
|
||||
public final ActionList colorActions;
|
||||
|
||||
private final boolean commandsCheck;
|
||||
public final boolean commandsCheck;
|
||||
public final double commandsLevel;
|
||||
public final int commandsShortTermTicks;
|
||||
public final double commandsShortTermLevel;
|
||||
public final ActionList commandsActions;
|
||||
|
||||
public final boolean globalChatCheck;
|
||||
public final boolean globalChatGlobalCheck;
|
||||
@ -173,6 +177,11 @@ public class ChatConfig extends AsyncCheckConfig {
|
||||
colorActions = config.getActionList(ConfPaths.CHAT_COLOR_ACTIONS, Permissions.CHAT_COLOR);
|
||||
|
||||
commandsCheck = config.getBoolean(ConfPaths.CHAT_COMMANDS_CHECK);
|
||||
commandsLevel = config.getDouble(ConfPaths.CHAT_COMMANDS_LEVEL);
|
||||
commandsShortTermTicks = config.getInt(ConfPaths.CHAT_COMMANDS_SHORTTERM_TICKS);
|
||||
commandsShortTermLevel = config.getDouble(ConfPaths.CHAT_COMMANDS_SHORTTERM_LEVEL);;
|
||||
commandsActions = config.getActionList(ConfPaths.CHAT_COMMANDS_ACTIONS, Permissions.CHAT_COMMANDS);
|
||||
|
||||
|
||||
globalChatCheck = config.getBoolean(ConfPaths.CHAT_GLOBALCHAT_CHECK);
|
||||
globalChatGlobalCheck = config.getBoolean(ConfPaths.CHAT_GLOBALCHAT_GL_CHECK, true);
|
||||
|
@ -69,6 +69,7 @@ public class ChatData extends AsyncCheckData {
|
||||
// Violation levels.
|
||||
public double captchaVL;
|
||||
public double colorVL;
|
||||
public double commandsVL;
|
||||
public double globalChatVL;
|
||||
public double noPwnageVL;
|
||||
public double relogVL;
|
||||
@ -78,6 +79,11 @@ public class ChatData extends AsyncCheckData {
|
||||
public String captchaGenerated;
|
||||
public boolean captchaStarted;
|
||||
|
||||
/// Commands data.
|
||||
public final ActionFrequency commandsWeights = new ActionFrequency(5, 1000);
|
||||
public long commandsShortTermTick;
|
||||
public double commandsShortTermWeight;
|
||||
|
||||
// Data of the globalchat check.
|
||||
public final ActionFrequency globalChatFrequency = new ActionFrequency(10, 3000);
|
||||
|
||||
|
@ -36,24 +36,31 @@ import fr.neatmonster.nocheatplus.utilities.ds.prefixtree.SimpleCharPrefixTree;
|
||||
* @see ChatEvent
|
||||
*/
|
||||
public class ChatListener implements Listener, INotifyReload {
|
||||
|
||||
/** The color check. */
|
||||
private final Color color = new Color();
|
||||
|
||||
/** The no pwnage check. */
|
||||
private final NoPwnage noPwnage = new NoPwnage();
|
||||
|
||||
// Checks.
|
||||
|
||||
/** Captcha handler. */
|
||||
private final Captcha captcha = new Captcha();
|
||||
|
||||
/** The color check. */
|
||||
private final Color color = new Color();
|
||||
|
||||
/** Global chat check (experiment: alternative / supplement). */
|
||||
private final Commands commands = new Commands();
|
||||
|
||||
/** Global chat check. */
|
||||
private final GlobalChat globalChat = new GlobalChat();
|
||||
|
||||
/** The no pwnage check. */
|
||||
private final NoPwnage noPwnage = new NoPwnage();
|
||||
|
||||
private final Relog relog = new Relog();
|
||||
|
||||
// Auxiliary stuff.
|
||||
|
||||
private final SimpleCharPrefixTree commandExclusions = new SimpleCharPrefixTree();
|
||||
|
||||
private final SimpleCharPrefixTree chatCommands = new SimpleCharPrefixTree();
|
||||
|
||||
private final Relog relog = new Relog();
|
||||
|
||||
public ChatListener(){
|
||||
ConfigFile config = ConfigManager.getConfigFile();
|
||||
@ -63,9 +70,9 @@ public class ChatListener implements Listener, INotifyReload {
|
||||
|
||||
private void initFilters(ConfigFile config) {
|
||||
commandExclusions.clear();
|
||||
commandExclusions.feedAll(config.getStringList(ConfPaths.CHAT_NOPWNAGE_EXCLUSIONS), false, true);
|
||||
commandExclusions.feedAll(config.getStringList(ConfPaths.CHAT_COMMANDS_EXCLUSIONS), false, true);
|
||||
chatCommands.clear();
|
||||
chatCommands.feedAll(config.getStringList(ConfPaths.CHAT_HANDLEASCHAT), false, true);
|
||||
chatCommands.feedAll(config.getStringList(ConfPaths.CHAT_COMMANDS_HANDLEASCHAT), false, true);
|
||||
}
|
||||
|
||||
@EventHandler(priority=EventPriority.MONITOR)
|
||||
@ -100,7 +107,7 @@ public class ChatListener implements Listener, INotifyReload {
|
||||
if (color.isEnabled(player)) event.setMessage(color.check(player, event.getMessage(), false));
|
||||
|
||||
// Then the no pwnage check.
|
||||
if (noPwnage.isEnabled(player) && noPwnage.check(player, event.getMessage(), captcha, false, false))
|
||||
if (noPwnage.isEnabled(player) && noPwnage.check(player, event.getMessage(), captcha, false))
|
||||
event.setCancelled(true);
|
||||
else if (globalChat.isEnabled(player) && globalChat.check(player, event.getMessage(), captcha, false))
|
||||
// Only check those that got through.
|
||||
@ -138,7 +145,7 @@ public class ChatListener implements Listener, INotifyReload {
|
||||
|
||||
// Trim is necessary because the server accepts leading spaces with commands.
|
||||
// TODO: Maybe: only remove the leading whitespace or spaces.
|
||||
final String lcMessage = event.getMessage().trim().toLowerCase();
|
||||
String lcMessage = event.getMessage().trim().toLowerCase();
|
||||
final String command = lcMessage.split(" ")[0].substring(1);
|
||||
|
||||
final ChatConfig cc = ChatConfig.getConfig(player);
|
||||
@ -166,13 +173,24 @@ public class ChatListener implements Listener, INotifyReload {
|
||||
// First the color check.
|
||||
if (color.isEnabled(player)) event.setMessage(color.check(player, event.getMessage(), true));
|
||||
|
||||
// Reset lcMessage (might be canged by color check).
|
||||
lcMessage = event.getMessage().trim().toLowerCase();
|
||||
final boolean handleAsChat = chatCommands.hasPrefixWords(lcMessage);
|
||||
|
||||
// Then the no pwnage check.
|
||||
if (!commandExclusions.hasPrefixWords(lcMessage) && noPwnage.isEnabled(player) && noPwnage.check(player, event.getMessage(), captcha, !handleAsChat, true))
|
||||
event.setCancelled(true);
|
||||
else if (handleAsChat && globalChat.isEnabled(player) && globalChat.check(player, event.getMessage(), captcha, true))
|
||||
event.setCancelled(true);
|
||||
if (handleAsChat){
|
||||
// Treat as chat.
|
||||
if (noPwnage.isEnabled(player) && noPwnage.check(player, event.getMessage(), captcha, true))
|
||||
event.setCancelled(true);
|
||||
else if (globalChat.isEnabled(player) && globalChat.check(player, event.getMessage(), captcha, true))
|
||||
event.setCancelled(true);
|
||||
}
|
||||
else if (!commandExclusions.hasPrefixWords(lcMessage)){
|
||||
// Treat as command.
|
||||
if (commands.isEnabled(player) && commands.check(player, event.getMessage(), captcha))
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,11 +1,55 @@
|
||||
package fr.neatmonster.nocheatplus.checks.chat;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import fr.neatmonster.nocheatplus.checks.Check;
|
||||
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||
import fr.neatmonster.nocheatplus.utilities.TickTask;
|
||||
|
||||
/**
|
||||
* Check only for commands
|
||||
* @author mc_dev
|
||||
*
|
||||
*/
|
||||
public class Commands extends Check {
|
||||
public Commands() {
|
||||
super(CheckType.CHAT_COMMANDS);
|
||||
}
|
||||
|
||||
public boolean check(final Player player, final String message, final Captcha captcha) {
|
||||
|
||||
final long now = System.currentTimeMillis();
|
||||
final int tick = TickTask.getTick();
|
||||
|
||||
final ChatConfig cc = ChatConfig.getConfig(player);
|
||||
final ChatData data = ChatData.getData(player);
|
||||
|
||||
// Weight might later be read from some prefix tree (also known / unknown).
|
||||
final float weight = 1f;
|
||||
|
||||
data.commandsWeights.add(now, weight);
|
||||
if (tick - data.commandsShortTermTick < cc.commandsShortTermTicks){
|
||||
// Add up.
|
||||
data.commandsShortTermWeight += weight;
|
||||
}
|
||||
else{
|
||||
// Reset.
|
||||
data.commandsShortTermTick = tick;
|
||||
data.commandsShortTermWeight = 1.0;
|
||||
}
|
||||
|
||||
final double violation = Math.max(data.commandsWeights.getScore(1f) - cc.commandsLevel, data.commandsShortTermWeight - cc.commandsShortTermLevel);
|
||||
|
||||
if (violation > 0.0){
|
||||
data.commandsVL += violation;
|
||||
if (executeActions(player, data.commandsVL, violation, cc.commandsActions))
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
// TODO: This might need invalidation with time.
|
||||
data.commandsVL *= 0.99;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ public class NoPwnage extends AsyncCheck{
|
||||
* is the thread the main thread
|
||||
* @return If to cancel the event.
|
||||
*/
|
||||
public boolean check(final Player player, final String message, final Captcha captcha, final boolean isCommand,
|
||||
public boolean check(final Player player, final String message, final Captcha captcha,
|
||||
final boolean isMainThread) {
|
||||
|
||||
final ChatConfig cc = ChatConfig.getConfig(player);
|
||||
@ -66,7 +66,7 @@ public class NoPwnage extends AsyncCheck{
|
||||
|
||||
// Keep related to ChatData/NoPwnage/Color used lock.
|
||||
synchronized (data) {
|
||||
return unsafeCheck(player, message, captcha, isCommand, isMainThread, cc, data);
|
||||
return unsafeCheck(player, message, captcha, isMainThread, cc, data);
|
||||
}
|
||||
}
|
||||
|
||||
@ -87,7 +87,7 @@ public class NoPwnage extends AsyncCheck{
|
||||
* the data
|
||||
* @return If to cancel the event.
|
||||
*/
|
||||
private boolean unsafeCheck(final Player player, final String message, final Captcha captcha, final boolean isCommand,
|
||||
private boolean unsafeCheck(final Player player, final String message, final Captcha captcha,
|
||||
final boolean isMainThread, final ChatConfig cc, final ChatData data) {
|
||||
boolean cancel = false;
|
||||
|
||||
@ -104,7 +104,7 @@ public class NoPwnage extends AsyncCheck{
|
||||
int suspicion = 0;
|
||||
// NoPwnage will remember the last message that caused someone to get banned. If a player repeats that
|
||||
// message within "timeout" milliseconds, the suspicion will be increased by "weight".
|
||||
if (!isCommand && cc.noPwnageBannedCheck && now - lastBanCausingMessageTime < cc.noPwnageBannedTimeout
|
||||
if (cc.noPwnageBannedCheck && now - lastBanCausingMessageTime < cc.noPwnageBannedTimeout
|
||||
&& CheckUtils.isSimilar(message, lastBanCausingMessage, 0.8f))
|
||||
suspicion += cc.noPwnageBannedWeight;
|
||||
|
||||
@ -115,7 +115,7 @@ public class NoPwnage extends AsyncCheck{
|
||||
|
||||
// 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".
|
||||
if (!isCommand && cc.noPwnageGlobalCheck && now - lastGlobalMessageTime < cc.noPwnageGlobalTimeout
|
||||
if (cc.noPwnageGlobalCheck && now - lastGlobalMessageTime < cc.noPwnageGlobalTimeout
|
||||
&& CheckUtils.isSimilar(message, lastGlobalMessage, 0.8f))
|
||||
suspicion += cc.noPwnageGlobalWeight;
|
||||
|
||||
@ -134,13 +134,13 @@ public class NoPwnage extends AsyncCheck{
|
||||
|
||||
// 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".
|
||||
if (!isCommand && cc.noPwnageRepeatCheck && now - data.noPwnageLastMessageTime < cc.noPwnageRepeatTimeout
|
||||
if (cc.noPwnageRepeatCheck && now - data.noPwnageLastMessageTime < cc.noPwnageRepeatTimeout
|
||||
&& CheckUtils.isSimilar(message, data.noPwnageLastMessage, 0.8f))
|
||||
suspicion += cc.noPwnageRepeatWeight;
|
||||
|
||||
// NoPwnage will check if a player moved within the "timeout" timeframe. If he did not move, the suspicion will
|
||||
// be increased by "weight" value.
|
||||
if (!isCommand && cc.noPwnageMoveCheck && now - cData.lastMoveTime > cc.noPwnageMoveTimeout)
|
||||
if (cc.noPwnageMoveCheck && now - cData.lastMoveTime > cc.noPwnageMoveTimeout)
|
||||
suspicion += cc.noPwnageMoveWeight;
|
||||
|
||||
// Should a player that reaches the "warnLevel" get a text message telling him that he is under suspicion of
|
||||
|
@ -176,9 +176,6 @@ public abstract class ConfPaths {
|
||||
* "88,d88 888 888 "88 888 888
|
||||
*/
|
||||
private static final String CHAT = CHECKS + "chat.";
|
||||
|
||||
@GlobalConfig
|
||||
public static final String CHAT_HANDLEASCHAT = CHAT + "handleaschat";
|
||||
|
||||
private static final String CHAT_CAPTCHA = CHAT + "captcha.";
|
||||
public static final String CHAT_CAPTCHA_CHECK = CHAT_CAPTCHA + "active";
|
||||
@ -195,6 +192,15 @@ public abstract class ConfPaths {
|
||||
|
||||
private static final String CHAT_COMMANDS = CHAT + "commands.";
|
||||
public static final String CHAT_COMMANDS_CHECK = CHAT_COMMANDS + "active";
|
||||
@GlobalConfig
|
||||
public static final String CHAT_COMMANDS_EXCLUSIONS = CHAT_COMMANDS + "exclusions";
|
||||
@GlobalConfig
|
||||
public static final String CHAT_COMMANDS_HANDLEASCHAT = CHAT_COMMANDS + "handleaschat";
|
||||
public static final String CHAT_COMMANDS_LEVEL = CHAT_COMMANDS + "level";
|
||||
private static final String CHAT_COMMANDS_SHORTTERM = CHAT_COMMANDS + "shortterm.";
|
||||
public static final String CHAT_COMMANDS_SHORTTERM_TICKS = CHAT_COMMANDS_SHORTTERM + "ticks";
|
||||
public static final String CHAT_COMMANDS_SHORTTERM_LEVEL = CHAT_COMMANDS_SHORTTERM + "level";
|
||||
public static final String CHAT_COMMANDS_ACTIONS = CHAT_COMMANDS + "actions";
|
||||
|
||||
// globalchat
|
||||
private static final String CHAT_GLOBALCHAT = CHAT + "globalchat.";
|
||||
@ -235,6 +241,7 @@ public abstract class ConfPaths {
|
||||
// globalchat actions
|
||||
public static final String CHAT_GLOBALCHAT_ACTIONS = CHAT_GLOBALCHAT + "actions";
|
||||
|
||||
// NOT YET IN USE
|
||||
private static final String CHAT_LOGINS = CHAT + "logins.";
|
||||
public static final String CHAT_LOGINS_CHECK = CHAT_LOGINS + "active";
|
||||
|
||||
@ -242,8 +249,6 @@ public abstract class ConfPaths {
|
||||
private static final String CHAT_NOPWNAGE = CHAT + "nopwnage.";
|
||||
public static final String CHAT_NOPWNAGE_CHECK = CHAT_NOPWNAGE + "active";
|
||||
public static final String CHAT_NOPWNAGE_DEBUG = CHAT_NOPWNAGE + "debug";
|
||||
@GlobalConfig
|
||||
public static final String CHAT_NOPWNAGE_EXCLUSIONS = CHAT_NOPWNAGE + "exclusions";
|
||||
public static final String CHAT_NOPWNAGE_LEVEL = CHAT_NOPWNAGE + "level";
|
||||
|
||||
private static final String CHAT_NOPWNAGE_BANNED = CHAT_NOPWNAGE + "banned.";
|
||||
|
@ -148,9 +148,15 @@ public class DefaultConfig extends ConfigFile {
|
||||
set(ConfPaths.CHAT_COLOR_CHECK, true);
|
||||
set(ConfPaths.CHAT_COLOR_ACTIONS, "log:color:0:1:if cancel");
|
||||
|
||||
// Multi purpose.
|
||||
set(ConfPaths.CHAT_HANDLEASCHAT,
|
||||
new LinkedList<String>(Arrays.asList(new String[]{"/me"})));
|
||||
|
||||
set(ConfPaths.CHAT_COMMANDS_CHECK, true);
|
||||
set(ConfPaths.CHAT_COMMANDS_EXCLUSIONS, new ArrayList<String>());
|
||||
set(ConfPaths.CHAT_COMMANDS_HANDLEASCHAT,
|
||||
new LinkedList<String>(Arrays.asList(new String[]{"/me"})));
|
||||
set(ConfPaths.CHAT_COMMANDS_LEVEL, 10);
|
||||
set(ConfPaths.CHAT_COMMANDS_SHORTTERM_TICKS, 18);
|
||||
set(ConfPaths.CHAT_COMMANDS_SHORTTERM_LEVEL, 3);
|
||||
set(ConfPaths.CHAT_COMMANDS_ACTIONS, "log:commands:0:5:cf cancel cmd:kickcommands vl>20 log:commands:0:5:cf cancel cmd:tempkick1");
|
||||
|
||||
// Captcha.
|
||||
set(ConfPaths.CHAT_CAPTCHA_CHECK, false);
|
||||
@ -181,7 +187,6 @@ public class DefaultConfig extends ConfigFile {
|
||||
|
||||
// nopwnage
|
||||
set(ConfPaths.CHAT_NOPWNAGE_CHECK, true);
|
||||
set(ConfPaths.CHAT_NOPWNAGE_EXCLUSIONS, new ArrayList<String>());
|
||||
set(ConfPaths.CHAT_NOPWNAGE_LEVEL, 500);
|
||||
|
||||
set(ConfPaths.CHAT_NOPWNAGE_BANNED_CHECK, true);
|
||||
@ -218,7 +223,7 @@ public class DefaultConfig extends ConfigFile {
|
||||
set(ConfPaths.CHAT_NOPWNAGE_WARN_PLAYER_MESSAGE,
|
||||
"&cPlease don't spam, be careful with what you say. DON'T repeat what you just said either, unless you want to be kicked or even banned.");
|
||||
|
||||
set(ConfPaths.CHAT_NOPWNAGE_ACTIONS, "cancel log:nopwnage:0:5:cf cmd:kicknopwnage vl>150 cancel log:nopwnage:0:5:cf cmd:tempkick5");
|
||||
set(ConfPaths.CHAT_NOPWNAGE_ACTIONS, "cancel log:nopwnage:0:5:cf cmd:kicknopwnage vl>150 log:nopwnage:0:5:cf cancel cmd:tempkick5");
|
||||
|
||||
// Reload
|
||||
set(ConfPaths.CHAT_RELOG_CHECK, true);
|
||||
@ -227,7 +232,7 @@ public class DefaultConfig extends ConfigFile {
|
||||
set(ConfPaths.CHAT_RELOG_WARNING_NUMBER, 1);
|
||||
set(ConfPaths.CHAT_RELOG_KICKMESSAGE, "You've relogged too fast, joining cancelled!");
|
||||
set(ConfPaths.CHAT_RELOG_WARNING_TIMEOUT, 60000L);
|
||||
set(ConfPaths.CHAT_RELOG_ACTIONS, "log:relog:0:10 cancel vl>20 log:relog:0:10 cancel tempkick5");
|
||||
set(ConfPaths.CHAT_RELOG_ACTIONS, "log:relog:0:10:cf cancel vl>20 log:relog:0:10:cf cancel cmd:tempkick5");
|
||||
|
||||
/*
|
||||
* Combined !
|
||||
@ -381,6 +386,7 @@ public class DefaultConfig extends ConfigFile {
|
||||
set(ConfPaths.STRINGS + ".bwrong", start + "broke another block than clicked" + end);
|
||||
set(ConfPaths.STRINGS + ".captcha", "[player] failed captcha repeatedly" + end);
|
||||
set(ConfPaths.STRINGS + ".color", start + "sent colored chat message" + end);
|
||||
set(ConfPaths.STRINGS + ".commands", start + "issued too many commands" + end);
|
||||
set(ConfPaths.STRINGS + ".combspeed", start + "performs different actions at very high speed" + end);
|
||||
set(ConfPaths.STRINGS + ".critical", start + "tried to do a critical hit but wasn't technically jumping" + end);
|
||||
set(ConfPaths.STRINGS + ".drop", start + "tried to drop more items than allowed" + end);
|
||||
@ -401,6 +407,7 @@ public class DefaultConfig extends ConfigFile {
|
||||
set(ConfPaths.STRINGS + ".instanteat", start + "eats food [food] too fast" + end);
|
||||
set(ConfPaths.STRINGS + ".instantheal", start + "tried to regenerate health faster than normal" + end);
|
||||
set(ConfPaths.STRINGS + ".kick", "kick [player]");
|
||||
set(ConfPaths.STRINGS + ".kickcommands", "ncp tempkick [player] 1 You're not allowed to spam commands!");
|
||||
set(ConfPaths.STRINGS + ".kicknopwnage", "ncp tempkick [player] 1 You're not allowed to spam this server!");
|
||||
set(ConfPaths.STRINGS + ".kickcaptcha", "ncp kick [player] Enter the captcha!");
|
||||
set(ConfPaths.STRINGS + ".kickfrequency", "ncp kick [player] How about doing that less often?");
|
||||
|
Loading…
Reference in New Issue
Block a user