mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2025-01-21 06:51:26 +01:00
Add commands to check like chat to globalchat, add experimental counts.
This commit is contained in:
parent
c58c086e39
commit
87d2894fcf
@ -1,8 +1,10 @@
|
||||
package fr.neatmonster.nocheatplus.checks.chat;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@ -71,6 +73,7 @@ public class ChatConfig implements CheckConfig {
|
||||
public final ActionList colorActions;
|
||||
|
||||
public final boolean globalChatCheck;
|
||||
public final Set<String> globalChatCommands;
|
||||
public final float globalChatFrequencyFactor;
|
||||
public final float globalChatFrequencyWeight;
|
||||
public final double globalChatLevel;
|
||||
@ -143,6 +146,13 @@ public class ChatConfig implements CheckConfig {
|
||||
colorActions = data.getActionList(ConfPaths.CHAT_COLOR_ACTIONS, Permissions.CHAT_COLOR);
|
||||
|
||||
globalChatCheck = data.getBoolean(ConfPaths.CHAT_GLOBALCHAT_CHECK);
|
||||
final List<String> commands = data.getStringList(ConfPaths.CHAT_GLOBALCHAT_COMMANDS);
|
||||
globalChatCommands = new HashSet<String>();
|
||||
if (commands != null){
|
||||
for (String cmd : commands){
|
||||
globalChatCommands.add(cmd.trim().toLowerCase());
|
||||
}
|
||||
}
|
||||
globalChatFrequencyFactor = (float) data.getDouble(ConfPaths.CHAT_GLOBALCHAT_FREQUENCY_FACTOR);
|
||||
globalChatFrequencyWeight = (float) data.getDouble(ConfPaths.CHAT_GLOBALCHAT_FREQUENCY_WEIGHT);
|
||||
globalChatLevel = data.getDouble(ConfPaths.CHAT_GLOBALCHAT_LEVEL);
|
||||
|
@ -63,7 +63,7 @@ public class ChatListener implements Listener {
|
||||
// Then the no pwnage check.
|
||||
if (noPwnage.check(player, event.getMessage(), false))
|
||||
event.setCancelled(true);
|
||||
else if (globalChat.check(player, event.getMessage(), (ICaptcha) noPwnage))
|
||||
else if (globalChat.check(player, event.getMessage(), (ICaptcha) noPwnage, false))
|
||||
// Only check those that got through.
|
||||
// (ICaptcha to start captcha if desired.)
|
||||
event.setCancelled(true);
|
||||
@ -93,10 +93,12 @@ public class ChatListener implements Listener {
|
||||
* |_|
|
||||
*/
|
||||
final Player player = event.getPlayer();
|
||||
final String command = event.getMessage().split(" ")[0].substring(1).toLowerCase();
|
||||
final String command = event.getMessage().trim().split(" ")[0].substring(1).toLowerCase();
|
||||
|
||||
final ChatConfig cc = ChatConfig.getConfig(player);
|
||||
|
||||
// Protect some commands to prevent players for seeing which plugins are installed.
|
||||
if (ChatConfig.getConfig(player).protectPlugins)
|
||||
if (cc.protectPlugins)
|
||||
if ((command.equalsIgnoreCase("plugins") || command.equalsIgnoreCase("pl")
|
||||
|| command.equalsIgnoreCase("version") || command.equalsIgnoreCase("ver"))
|
||||
&& !player.hasPermission(Permissions.ADMINISTRATION_PLUGINS)) {
|
||||
@ -108,7 +110,7 @@ public class ChatListener implements Listener {
|
||||
}
|
||||
|
||||
// Prevent /op and /deop commands from being used in chat.
|
||||
if (ChatConfig.getConfig(player).opInConsoleOnly && (command.equals("op") || command.equals("deop"))) {
|
||||
if (cc.opInConsoleOnly && (command.equals("op") || command.equals("deop"))) {
|
||||
event.getPlayer().sendMessage(
|
||||
ChatColor.RED + "I'm sorry, but this command can't be executed in chat. Use the console instead!");
|
||||
event.setCancelled(true);
|
||||
@ -121,6 +123,8 @@ public class ChatListener implements Listener {
|
||||
// Then the no pwnage check.
|
||||
if (noPwnage.check(player, event.getMessage(), true))
|
||||
event.setCancelled(true);
|
||||
else if ((cc.globalChatCommands.contains(command) || cc.globalChatCommands.contains("/"+command)) && globalChat.check(player, event.getMessage(), noPwnage, true))
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5,7 +5,6 @@ import org.bukkit.entity.Player;
|
||||
import fr.neatmonster.nocheatplus.checks.Check;
|
||||
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||
import fr.neatmonster.nocheatplus.hooks.NCPExemptionManager;
|
||||
import fr.neatmonster.nocheatplus.players.Permissions;
|
||||
|
||||
/**
|
||||
* Some alternative more or less advanced analysis methods.
|
||||
@ -28,18 +27,18 @@ public class GlobalChat extends Check{
|
||||
* Used for starting captcha on failure, if configured so.
|
||||
* @return
|
||||
*/
|
||||
public boolean check(final Player player, final String message, final ICaptcha captcha) {
|
||||
public boolean check(final Player player, final String message, final ICaptcha captcha, boolean isMainThread) {
|
||||
|
||||
final ChatConfig cc = ChatConfig.getConfig(player);
|
||||
|
||||
// Checking the player, actually.
|
||||
if (!cc.isEnabled(type) || NCPExemptionManager.isExempted(player, type))
|
||||
if (isMainThread && !isEnabled(player)) return false;
|
||||
if (!isMainThread && (!cc.isEnabled(type) || NCPExemptionManager.isExempted(player, type)))
|
||||
return false;
|
||||
|
||||
|
||||
final ChatData data = ChatData.getData(player);
|
||||
|
||||
synchronized (data) {
|
||||
return unsafeCheck(player, message, captcha, cc, data);
|
||||
return unsafeCheck(player, message, captcha, cc, data, isMainThread);
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,10 +49,11 @@ public class GlobalChat extends Check{
|
||||
* @param captcha
|
||||
* @param cc
|
||||
* @param data
|
||||
* @param isMainThread
|
||||
* @return
|
||||
*/
|
||||
private boolean unsafeCheck(final Player player, final String message, final ICaptcha captcha,
|
||||
final ChatConfig cc, final ChatData data) {
|
||||
final ChatConfig cc, final ChatData data, boolean isMainThread) {
|
||||
// Take time once:
|
||||
final long time = System.currentTimeMillis();
|
||||
|
||||
@ -68,6 +68,23 @@ public class GlobalChat extends Check{
|
||||
|
||||
// Weight of this chat message.
|
||||
float weight = 1.0f;
|
||||
|
||||
final MessageLetterCount letterCounts = new MessageLetterCount(message);
|
||||
|
||||
final int length = message.length();
|
||||
// Upper case.
|
||||
if (length > 8 && letterCounts.fullCount.upperCase > length / 4){
|
||||
weight += 0.6 * letterCounts.fullCount.getUpperCaseRatio();
|
||||
}
|
||||
|
||||
// ? for words individually ?
|
||||
|
||||
// Repetition of characters.
|
||||
if (length > 4){
|
||||
final float fullRep = letterCounts.fullCount.getLetterRatio();
|
||||
score += (float) length / 15.0 * Math.abs(0.5 - fullRep); // Very small and very big are bad !
|
||||
}
|
||||
|
||||
// TODO Core checks....
|
||||
|
||||
// Add weight to frequency counts.
|
||||
@ -81,13 +98,14 @@ public class GlobalChat extends Check{
|
||||
}
|
||||
else{
|
||||
data.globalChatVL += score / 10.0;
|
||||
if (executeActionsThreadSafe(player, data.globalChatVL, score, cc.globalChatActions, Permissions.CHAT_GLOBALCHAT))
|
||||
if (executeActionsThreadSafe(player, data.globalChatVL, score, cc.globalChatActions, isMainThread))
|
||||
cancel = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
data.globalChatVL *= 0.95;
|
||||
|
||||
|
||||
return cancel;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,96 @@
|
||||
package fr.neatmonster.nocheatplus.checks.chat;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Letter count for a message and sub words, including upper case count.<br>
|
||||
* NOTE: this is a pretty heavy implementation for testing purposes.
|
||||
* @author mc_dev
|
||||
*
|
||||
*/
|
||||
public class MessageLetterCount {
|
||||
/**
|
||||
* Letter count for a word.
|
||||
* @author mc_dev
|
||||
*
|
||||
*/
|
||||
public static final class WordLetterCount{
|
||||
public final String word;
|
||||
public final Map<Character, Integer> counts;
|
||||
public final int upperCase;
|
||||
public WordLetterCount(final String word){
|
||||
this.word = word;
|
||||
char[] a = word.toCharArray();
|
||||
// Preserve insertion order.
|
||||
counts = new LinkedHashMap<Character, Integer>(a.length);
|
||||
int upperCase = 0;
|
||||
for (int i = 0; i < a.length; i++){
|
||||
final char c = a[i];
|
||||
final Character key;
|
||||
if (Character.isUpperCase(c)){
|
||||
upperCase ++;
|
||||
key = Character.toLowerCase(c);
|
||||
}
|
||||
else key = c;
|
||||
final Integer count = counts.remove(key);
|
||||
if (count == null) counts.put(key, 1);
|
||||
else counts.put(key, count.intValue() + 1);
|
||||
|
||||
}
|
||||
this.upperCase = upperCase;
|
||||
}
|
||||
|
||||
public float getLetterRatio(){
|
||||
return (float) counts.size() / (float) word.length();
|
||||
}
|
||||
|
||||
public float getUpperCaseRatio(){
|
||||
return (float) upperCase / (float) word.length();
|
||||
}
|
||||
}
|
||||
|
||||
public final String message;
|
||||
|
||||
public final String split;
|
||||
|
||||
public final WordLetterCount[] words;
|
||||
|
||||
public final WordLetterCount fullCount;
|
||||
|
||||
/**
|
||||
* Constructor for splitting by a space.
|
||||
* @param message
|
||||
*/
|
||||
public MessageLetterCount(final String message){
|
||||
this(message, " ");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param message
|
||||
* @param split
|
||||
*/
|
||||
public MessageLetterCount(final String message, final String split){
|
||||
this.message = message;
|
||||
this.split = split;
|
||||
|
||||
final String[] parts = message.split(split);
|
||||
words = new WordLetterCount[parts.length];
|
||||
|
||||
fullCount = new WordLetterCount(message);
|
||||
// (Do not store 60 times "a".)
|
||||
final Map<String, WordLetterCount> done = new HashMap<String, MessageLetterCount.WordLetterCount>(words.length);
|
||||
for (int i = 0; i < parts.length; i++){
|
||||
final String word = parts[i];
|
||||
if (done.containsKey(word)){
|
||||
words[i] = done.get(word);
|
||||
continue;
|
||||
}
|
||||
done.put(word, words[i] = new WordLetterCount(word));
|
||||
}
|
||||
done.clear();
|
||||
}
|
||||
|
||||
}
|
@ -141,6 +141,7 @@ public abstract class ConfPaths {
|
||||
|
||||
public static final String CHAT_GLOBALCHAT = CHAT + "globalchat.";
|
||||
public static final String CHAT_GLOBALCHAT_CHECK = CHAT_GLOBALCHAT + "active";
|
||||
public static final String CHAT_GLOBALCHAT_COMMANDS = CHAT_GLOBALCHAT + "commands";
|
||||
public static final String CHAT_GLOBALCHAT_FREQUENCY = CHAT_GLOBALCHAT + "frequency.";
|
||||
public static final String CHAT_GLOBALCHAT_FREQUENCY_WEIGHT = CHAT_GLOBALCHAT_FREQUENCY + "weight";
|
||||
public static final String CHAT_GLOBALCHAT_FREQUENCY_FACTOR = CHAT_GLOBALCHAT_FREQUENCY + "factor";
|
||||
|
@ -1,6 +1,8 @@
|
||||
package fr.neatmonster.nocheatplus.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
|
||||
/*
|
||||
* M""""""'YMM .8888b dP dP MM'""""'YMM .8888b oo
|
||||
@ -126,6 +128,8 @@ public class DefaultConfig extends ConfigFile {
|
||||
set(ConfPaths.CHAT_COLOR_ACTIONS, "log:color:0:1:if cancel");
|
||||
|
||||
set(ConfPaths.CHAT_GLOBALCHAT_CHECK, true);
|
||||
set(ConfPaths.CHAT_GLOBALCHAT_COMMANDS, new LinkedList<String>(Arrays.asList(
|
||||
new String[]{"/me"})));
|
||||
set(ConfPaths.CHAT_GLOBALCHAT_FREQUENCY_FACTOR, 0.8D);
|
||||
set(ConfPaths.CHAT_GLOBALCHAT_FREQUENCY_WEIGHT, 6.0D);
|
||||
set(ConfPaths.CHAT_GLOBALCHAT_LEVEL, 30D);
|
||||
|
Loading…
Reference in New Issue
Block a user