Add repeated words filtering to chat filter.

This commit is contained in:
Andy Janata 2018-04-01 19:46:26 -07:00
parent 43f9b70d54
commit 1c07624a5c
7 changed files with 27 additions and 2 deletions

View File

@ -130,6 +130,7 @@ cah.$.ErrorCode.TOO_MANY_USERS = "tmu";
cah.$.ErrorCode.NOT_GAME_HOST = "ngh";
cah.$.ErrorCode.MESSAGE_TOO_LONG = "mtl";
cah.$.ErrorCode.NO_NICK_SPECIFIED = "nns";
cah.$.ErrorCode.REPEATED_WORDS = "rW";
cah.$.ErrorCode.BANNED = "B&";
cah.$.ErrorCode.WRONG_PASSWORD = "wp";
cah.$.ErrorCode.RESERVED_NICK = "rn";
@ -200,6 +201,7 @@ cah.$.ErrorCode_msg['cjag'] = "You cannot join another game.";
cah.$.ErrorCode_msg['B&'] = "Banned.";
cah.$.ErrorCode_msg['mtl'] = "Messages cannot be longer than 200 characters.";
cah.$.ErrorCode_msg['in'] = "Nickname must contain only upper and lower case letters, numbers, or underscores, must be 3 to 30 characters long, and must not start with a number.";
cah.$.ErrorCode_msg['rW'] = "You must use more unique words in your message.";
cah.$.ErrorCode_msg['serr'] = "An error occured on the server.";
cah.$.ErrorCode_msg['CL'] = "Try turning caps lock off.";
cah.$.ErrorCode_msg['dnhc'] = "You don't have that card.";

View File

@ -43,6 +43,10 @@ pyx.global.spaces_min_count=4
pyx.global.flood_count=3
# seconds
pyx.global.flood_time=25
# Messages with more than repeated_words_min_count words must have at least
# repeated_words_unique_ratio unique words in them.
pyx.global.repeated_words_min_count=10
pyx.global.repeated_words_unique_ratio=.5
# Settings for game chat protection. If it isn't listed here, it isn't supported.
# same but for game chats

View File

@ -16,6 +16,8 @@ pyx.chat.global.spaces_min_len=${pyx.global.spaces_min_len}
pyx.chat.global.spaces_min_count=${pyx.global.spaces_min_count}
pyx.chat.global.capslock_min_len=${pyx.global.capslock_min_len}
pyx.chat.global.capslock_ratio=${pyx.global.capslock_ratio}
pyx.chat.global.repeated_words_min_count=${pyx.global.repeated_words_min_count}
pyx.chat.global.repeated_words_unique_ratio=${pyx.global.repeated_words_unique_ratio}
pyx.chat.game.flood_count=${pyx.game.flood_count}
pyx.chat.game.flood_time=${pyx.game.flood_time}
pyx.build=${buildNumber}

View File

@ -399,6 +399,7 @@ public class Constants {
RESERVED_NICK("rn", "That nick is reserved."),
REPEAT_MESSAGE("rm",
"You can't repeat the same message multiple times in a row."),
REPEATED_WORDS("rW", "You must use more unique words in your message."),
SERVER_ERROR("serr", "An error occured on the server."),
SESSION_EXPIRED("se", "Your session has expired. Refresh the page."),
TOO_FAST("tf", "You are chatting too fast. Wait a few seconds and try again."),

View File

@ -110,6 +110,8 @@ public class ChatHandler extends Handler {
break;
case REPEAT:
return error(ErrorCode.REPEAT_MESSAGE);
case REPEAT_WORDS:
return error(ErrorCode.REPEATED_WORDS);
case TOO_FAST:
return error(ErrorCode.TOO_FAST);
case TOO_LONG:

View File

@ -99,6 +99,8 @@ public class GameChatHandler extends GameWithPlayerHandler {
break;
case REPEAT:
return error(ErrorCode.REPEAT_MESSAGE);
case REPEAT_WORDS:
return error(ErrorCode.REPEATED_WORDS);
case TOO_FAST:
return error(ErrorCode.TOO_FAST);
case TOO_LONG:

View File

@ -37,6 +37,7 @@ import java.util.regex.Pattern;
import org.apache.log4j.Logger;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
@ -60,6 +61,8 @@ public class ChatFilter {
private static final int DEFAULT_SPACES_REQUIRED = 3;
private static final int DEFAULT_CAPSLOCK_MIN_MSG_LENGTH = 50;
private static final double DEFAULT_CAPSLOCK_RATIO = .5;
private static final int DEFAULT_REPEATED_WORDS_MIN_COUNT = 10;
private static final double DEFAULT_REPEATED_WORDS_UNIQUE_RATIO = .5;
public static final String DEFAULT_SHADOWBAN_PROVIDER = DefaultShadowBannedStringsProvider.class
.getCanonicalName();
@ -70,7 +73,7 @@ public class ChatFilter {
private final Map<User, FilterData> filterData = Collections.synchronizedMap(new WeakHashMap<>());
public enum Result {
CAPSLOCK, DROP_MESSAGE, NO_MESSAGE, NOT_ENOUGH_SPACES, OK, REPEAT, TOO_FAST, TOO_LONG, TOO_MANY_SPECIALS
CAPSLOCK, DROP_MESSAGE, NO_MESSAGE, NOT_ENOUGH_SPACES, OK, REPEAT, REPEAT_WORDS, TOO_FAST, TOO_LONG, TOO_MANY_SPECIALS
}
private enum Scope {
@ -102,12 +105,21 @@ public class ChatFilter {
}
}
final int spaces = message.split("\\s+").length + 1;
final String[] words = message.toLowerCase(Locale.ENGLISH).split("\\s+");
final int spaces = words.length + 1;
if (total >= getIntParameter(Scope.global, "spaces_min_len", DEFAULT_SPACES_MIN_MSG_LENGTH)
&& spaces < getIntParameter(Scope.global, "spaces_min_count", DEFAULT_SPACES_REQUIRED)) {
return Result.NOT_ENOUGH_SPACES;
}
final Set<String> uniqueWords = ImmutableSet.copyOf(words);
if (words.length >= getIntParameter(Scope.global, "repeated_words_min_count",
DEFAULT_REPEATED_WORDS_MIN_COUNT)
&& ((double) uniqueWords.size()) / words.length < getDoubleParameter(Scope.global,
"repeated_words_unique_ratio", DEFAULT_REPEATED_WORDS_UNIQUE_RATIO)) {
return Result.REPEAT_WORDS;
}
final long caps = message.codePoints().filter(c -> Character.isUpperCase(c)).count();
if (total >= getIntParameter(Scope.global, "capslock_min_len", DEFAULT_CAPSLOCK_MIN_MSG_LENGTH)
&& ((double) caps) / total > getDoubleParameter(Scope.global, "capslock_ratio",