Add config flag to allow preventing vl reset in chat.text.

This might be temporary, the resetting could get removed completely,
or it might be fixed/altered.
This commit is contained in:
asofold 2014-05-11 22:59:37 +02:00
parent 4f224eefee
commit 0024e16112
4 changed files with 41 additions and 31 deletions

View File

@ -105,7 +105,8 @@ public class ChatConfig extends AsyncCheckConfig {
public final float textMessageNoLetter; public final float textMessageNoLetter;
public final float textGlobalWeight; public final float textGlobalWeight;
public final float textPlayerWeight; public final float textPlayerWeight;
public boolean textEngineMaximum; public final boolean textEngineMaximum;
public final boolean textAllowVLReset;
public final boolean textDebug; public final boolean textDebug;
public final boolean chatWarningCheck; public final boolean chatWarningCheck;
@ -194,6 +195,7 @@ public class ChatConfig extends AsyncCheckConfig {
textEngineMaximum = config.getBoolean(ConfPaths.CHAT_TEXT_ENGINE_MAXIMUM, true); textEngineMaximum = config.getBoolean(ConfPaths.CHAT_TEXT_ENGINE_MAXIMUM, true);
textDebug = config.getBoolean(ConfPaths.CHAT_TEXT_DEBUG, false); textDebug = config.getBoolean(ConfPaths.CHAT_TEXT_DEBUG, false);
textFreqNormActions = config.getOptimizedActionList(ConfPaths.CHAT_TEXT_FREQ_NORM_ACTIONS, Permissions.CHAT_TEXT); textFreqNormActions = config.getOptimizedActionList(ConfPaths.CHAT_TEXT_FREQ_NORM_ACTIONS, Permissions.CHAT_TEXT);
textAllowVLReset = config.getBoolean(ConfPaths.CHAT_TEXT_ALLOWVLRESET);
chatWarningCheck = config.getBoolean(ConfPaths.CHAT_WARNING_CHECK); chatWarningCheck = config.getBoolean(ConfPaths.CHAT_WARNING_CHECK);
chatWarningLevel = (float) config.getDouble(ConfPaths.CHAT_WARNING_LEVEL); chatWarningLevel = (float) config.getDouble(ConfPaths.CHAT_WARNING_LEVEL);

View File

@ -70,7 +70,7 @@ public class Text extends AsyncCheck implements INotifyReload{
// Set some things from the global config. // Set some things from the global config.
final ConfigFile config = ConfigManager.getConfigFile(); final ConfigFile config = ConfigManager.getConfigFile();
final NoCheatPlusAPI api = NCPAPIProvider.getNoCheatPlusAPI(); final NoCheatPlusAPI api = NCPAPIProvider.getNoCheatPlusAPI();
if (engine != null){ if (engine != null) {
engine.clear(); engine.clear();
api.removeComponent(engine); api.removeComponent(engine);
} }
@ -80,7 +80,7 @@ public class Text extends AsyncCheck implements INotifyReload{
@Override @Override
public void onReload() { public void onReload() {
synchronized(engine){ synchronized(engine) {
engine.clear(); engine.clear();
} }
init(); init();
@ -120,7 +120,7 @@ public class Text extends AsyncCheck implements INotifyReload{
boolean debug = cc.textDebug || cc.debug; boolean debug = cc.textDebug || cc.debug;
final List<String> debugParts; final List<String> debugParts;
if (debug){ if (debug) {
debugParts = new LinkedList<String>(); debugParts = new LinkedList<String>();
debugParts.add("[NoCheatPlus][chat.text] Message ("+player.getName()+"/"+message.length()+"): "); debugParts.add("[NoCheatPlus][chat.text] Message ("+player.getName()+"/"+message.length()+"): ");
} }
@ -143,13 +143,13 @@ public class Text extends AsyncCheck implements INotifyReload{
// Full message processing. ------------ // Full message processing. ------------
// Upper case. // Upper case.
if (letterCounts.fullCount.upperCase > msgLen / 3){ if (letterCounts.fullCount.upperCase > msgLen / 3) {
final float wUpperCase = 0.6f * letterCounts.fullCount.getUpperCaseRatio(); final float wUpperCase = 0.6f * letterCounts.fullCount.getUpperCaseRatio();
score += wUpperCase * cc.textMessageUpperCase; score += wUpperCase * cc.textMessageUpperCase;
} }
// Letters vs. word length. // Letters vs. word length.
if (msgLen > 4){ if (msgLen > 4) {
final float fullRep = letterCounts.fullCount.getLetterCountRatio(); final float fullRep = letterCounts.fullCount.getLetterCountRatio();
// Long messages: very small and very big are bad ! // Long messages: very small and very big are bad !
final float wRepetition = (float) msgLen / 15.0f * Math.abs(0.5f - fullRep); final float wRepetition = (float) msgLen / 15.0f * Math.abs(0.5f - fullRep);
@ -157,7 +157,7 @@ public class Text extends AsyncCheck implements INotifyReload{
// Number of words vs. length of message // Number of words vs. length of message
final float fnWords = (float) letterCounts.words.length / (float) msgLen; final float fnWords = (float) letterCounts.words.length / (float) msgLen;
if (fnWords > 0.75f){ // TODO: balance or configure or remove ? if (fnWords > 0.75f) { // TODO: balance or configure or remove ?
score += fnWords * cc.textMessagePartition; score += fnWords * cc.textMessagePartition;
} }
} }
@ -165,40 +165,40 @@ public class Text extends AsyncCheck implements INotifyReload{
final CombinedData cData = CombinedData.getData(player); final CombinedData cData = CombinedData.getData(player);
final long timeout = 8000; // TODO: maybe set dynamically in data. final long timeout = 8000; // TODO: maybe set dynamically in data.
// Repetition of last message. // Repetition of last message.
if (cc.textMsgRepeatSelf != 0f && time - data.chatLastTime < timeout){ if (cc.textMsgRepeatSelf != 0f && time - data.chatLastTime < timeout) {
if (StringUtil.isSimilar(lcMessage, data.chatLastMessage, 0.8f)){ if (StringUtil.isSimilar(lcMessage, data.chatLastMessage, 0.8f)) {
final float timeWeight = (float) (timeout - (time - data.chatLastTime)) / (float) timeout; final float timeWeight = (float) (timeout - (time - data.chatLastTime)) / (float) timeout;
score += cc.textMsgRepeatSelf * timeWeight; score += cc.textMsgRepeatSelf * timeWeight;
} }
} }
// Repetition of last global message. // Repetition of last global message.
if (cc.textMsgRepeatGlobal != 0f && time - lastGlobalTime < timeout){ if (cc.textMsgRepeatGlobal != 0f && time - lastGlobalTime < timeout) {
if (StringUtil.isSimilar(lcMessage, lastGlobalMessage, 0.8f)){ if (StringUtil.isSimilar(lcMessage, lastGlobalMessage, 0.8f)) {
final float timeWeight = (float) (timeout - (time - lastGlobalTime)) / (float) timeout; final float timeWeight = (float) (timeout - (time - lastGlobalTime)) / (float) timeout;
score += cc.textMsgRepeatGlobal * timeWeight; score += cc.textMsgRepeatGlobal * timeWeight;
} }
} }
// Repetition of last cancelled message. // Repetition of last cancelled message.
if (cc.textMsgRepeatCancel != 0f && time - lastCancelledTime < timeout){ if (cc.textMsgRepeatCancel != 0f && time - lastCancelledTime < timeout) {
if (StringUtil.isSimilar(lcMessage, lastCancelledMessage, 0.8f)){ if (StringUtil.isSimilar(lcMessage, lastCancelledMessage, 0.8f)) {
final float timeWeight = (float) (timeout - (time - lastCancelledTime)) / (float) timeout; final float timeWeight = (float) (timeout - (time - lastCancelledTime)) / (float) timeout;
score += cc.textMsgRepeatCancel * timeWeight; score += cc.textMsgRepeatCancel * timeWeight;
} }
} }
// Chat quickly after join. // Chat quickly after join.
if (cc.textMsgAfterJoin != 0f && time - cData.lastJoinTime < timeout){ if (cc.textMsgAfterJoin != 0f && time - cData.lastJoinTime < timeout) {
final float timeWeight = (float) (timeout - (time - cData.lastJoinTime)) / (float) timeout; final float timeWeight = (float) (timeout - (time - cData.lastJoinTime)) / (float) timeout;
score += cc.textMsgAfterJoin * timeWeight; score += cc.textMsgAfterJoin * timeWeight;
} }
// Chat without moving. // Chat without moving.
if (cc.textMsgNoMoving != 0f && time - cData.lastMoveTime > timeout){ if (cc.textMsgNoMoving != 0f && time - cData.lastMoveTime > timeout) {
score += cc.textMsgNoMoving; score += cc.textMsgNoMoving;
} }
// Per word checks. ------------------- // Per word checks. -------------------
float wWords = 0.0f; float wWords = 0.0f;
final float avwLen = (float) msgLen / (float) letterCounts.words.length; final float avwLen = (float) msgLen / (float) letterCounts.words.length;
for (final WordLetterCount word: letterCounts.words){ for (final WordLetterCount word: letterCounts.words) {
float wWord = 0.0f; float wWord = 0.0f;
final int wLen = word.word.length(); final int wLen = word.word.length();
// TODO: ? used letters vs. word length. // TODO: ? used letters vs. word length.
@ -232,7 +232,7 @@ public class Text extends AsyncCheck implements INotifyReload{
engMap = engine.process(letterCounts, player.getName(), cc, data); engMap = engine.process(letterCounts, player.getName(), cc, data);
// TODO: more fine grained sync !s // TODO: more fine grained sync !s
// TODO: different methods (add or max or add+max or something else). // TODO: different methods (add or max or add+max or something else).
for (final Float res : engMap.values()){ for (final Float res : engMap.values()) {
if (cc.textEngineMaximum) wEngine = Math.max(wEngine, res.floatValue()); if (cc.textEngineMaximum) wEngine = Math.max(wEngine, res.floatValue());
else wEngine += res.floatValue(); else wEngine += res.floatValue();
} }
@ -252,40 +252,46 @@ public class Text extends AsyncCheck implements INotifyReload{
final float shortTermAccumulated = cc.textFreqShortTermWeight * data.chatShortTermFrequency.score(cc.textFreqShortTermFactor); final float shortTermAccumulated = cc.textFreqShortTermWeight * data.chatShortTermFrequency.score(cc.textFreqShortTermFactor);
final boolean shortTermViolation = shortTermAccumulated > cc.textFreqShortTermLevel; final boolean shortTermViolation = shortTermAccumulated > cc.textFreqShortTermLevel;
if (normalViolation || shortTermViolation){ if (normalViolation || shortTermViolation) {
lastCancelledMessage = lcMessage; lastCancelledMessage = lcMessage;
lastCancelledTime = time; lastCancelledTime = time;
final double added; final double added;
if (shortTermViolation) added = (shortTermAccumulated - cc.textFreqShortTermLevel)/ 3.0; if (shortTermViolation) {
else added = (accumulated - cc.textFreqNormLevel) / 10.0; added = (shortTermAccumulated - cc.textFreqShortTermLevel)/ 3.0;
data.textVL += added; } else {
added = (accumulated - cc.textFreqNormLevel) / 10.0;
}
data.textVL += added;
if (captcha.shouldStartCaptcha(cc, data)){ if (captcha.shouldStartCaptcha(cc, data)) {
captcha.sendNewCaptcha(player, cc, data); captcha.sendNewCaptcha(player, cc, data);
cancel = true; cancel = true;
} }
else{ else{
if (shortTermViolation){ if (shortTermViolation) {
if (executeActions(player, data.textVL, added, cc.textFreqShortTermActions, isMainThread)) if (executeActions(player, data.textVL, added, cc.textFreqShortTermActions, isMainThread)) {
cancel = true; cancel = true;
}
} }
else if (normalViolation){ else if (normalViolation) {
if (executeActions(player, data.textVL, added, cc.textFreqNormActions, isMainThread)) if (executeActions(player, data.textVL, added, cc.textFreqNormActions, isMainThread)) {
cancel = true; cancel = true;
}
} }
} }
} }
else if (cc.chatWarningCheck && time - data.chatWarningTime > cc.chatWarningTimeout && (100f * accumulated / cc.textFreqNormLevel > cc.chatWarningLevel || 100f * shortTermAccumulated / cc.textFreqShortTermLevel > cc.chatWarningLevel)){ else if (cc.chatWarningCheck && time - data.chatWarningTime > cc.chatWarningTimeout && (100f * accumulated / cc.textFreqNormLevel > cc.chatWarningLevel || 100f * shortTermAccumulated / cc.textFreqShortTermLevel > cc.chatWarningLevel)) {
NCPAPIProvider.getNoCheatPlusAPI().sendMessageOnTick(player.getName(), ColorUtil.replaceColors(cc.chatWarningMessage)); NCPAPIProvider.getNoCheatPlusAPI().sendMessageOnTick(player.getName(), ColorUtil.replaceColors(cc.chatWarningMessage));
data.chatWarningTime = time; data.chatWarningTime = time;
} }
else { else {
data.textVL *= 0.95; data.textVL *= 0.95;
if (normalScore < 2.0f * cc.textFreqNormWeight && shortTermScore < 2.0f * cc.textFreqShortTermWeight) if (cc.textAllowVLReset && normalScore < 2.0f * cc.textFreqNormWeight && shortTermScore < 2.0f * cc.textFreqShortTermWeight) {
// Reset the VL. // Reset the VL.
// TODO: maybe elaborate on resetting conditions (after some timeout just divide by two or so?). // TODO: maybe elaborate on resetting conditions (after some timeout just divide by two or so?).
data.textVL = 0.0; data.textVL = 0.0;
}
} }
if (debug) { if (debug) {

View File

@ -244,6 +244,7 @@ public abstract class ConfPaths {
public static final String CHAT_TEXT_CHECK = CHAT_TEXT + "active"; public static final String CHAT_TEXT_CHECK = CHAT_TEXT + "active";
public static final String CHAT_TEXT_DEBUG = CHAT_TEXT + "debug"; public static final String CHAT_TEXT_DEBUG = CHAT_TEXT + "debug";
public static final String CHAT_TEXT_ENGINE_MAXIMUM = CHAT_TEXT + "maximum"; public static final String CHAT_TEXT_ENGINE_MAXIMUM = CHAT_TEXT + "maximum";
public static final String CHAT_TEXT_ALLOWVLRESET = CHAT_TEXT + "allowvlreset";
public static final String CHAT_TEXT_FREQ = CHAT_TEXT + "frequency."; public static final String CHAT_TEXT_FREQ = CHAT_TEXT + "frequency.";
public static final String CHAT_TEXT_FREQ_NORM = CHAT_TEXT_FREQ + "normal."; public static final String CHAT_TEXT_FREQ_NORM = CHAT_TEXT_FREQ + "normal.";
public static final String CHAT_TEXT_FREQ_NORM_FACTOR = CHAT_TEXT_FREQ_NORM + "factor"; public static final String CHAT_TEXT_FREQ_NORM_FACTOR = CHAT_TEXT_FREQ_NORM + "factor";

View File

@ -168,6 +168,7 @@ public class DefaultConfig extends ConfigFile {
// Text (ordering on purpose). // Text (ordering on purpose).
set(ConfPaths.CHAT_TEXT_CHECK, true); set(ConfPaths.CHAT_TEXT_CHECK, true);
set(ConfPaths.CHAT_TEXT_ALLOWVLRESET, false);
set(ConfPaths.CHAT_TEXT_FREQ_NORM_MIN, 0.0); set(ConfPaths.CHAT_TEXT_FREQ_NORM_MIN, 0.0);
set(ConfPaths.CHAT_TEXT_FREQ_NORM_FACTOR, 0.9D); set(ConfPaths.CHAT_TEXT_FREQ_NORM_FACTOR, 0.9D);
set(ConfPaths.CHAT_TEXT_FREQ_NORM_WEIGHT, 6); set(ConfPaths.CHAT_TEXT_FREQ_NORM_WEIGHT, 6);