Bleeding: Split off commands check [unfinished].

This commit is contained in:
asofold 2012-10-01 22:40:56 +02:00
parent b34aec55b4
commit 5d337b2b25
7 changed files with 124 additions and 35 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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);
}
}
/**

View File

@ -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;
}
}

View File

@ -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

View File

@ -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.";

View File

@ -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?");