Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ public class GameVariables {
public static String MESSENGER_GREETING;
public static boolean DEBUG_ENABLE = false;
public static int AFK_ROOM_KICK;
public static String CHAT_FILTER_WORDS;
public static String CHAT_FILTER_REPLACEMENT;


public static void setVariables() {
Expand All @@ -33,5 +35,8 @@ public static void setVariables() {
TALK_DISTANCE = Util.getHabboConfig().get("Player", "talking.lookat.distance", Integer.class);
USER_DEFAULT_CREDITS = Util.getHabboConfig().get("Register", "user.default.credits", int.class);
DEBUG_ENABLE = Util.getHabboConfig().get("Debug", "debug.enable", Boolean.class);
CHAT_FILTER_WORDS = Util.getHabboConfig().get("Chat", "filter.words", String.class);
CHAT_FILTER_REPLACEMENT = Util.getHabboConfig().get("Chat", "filter.replacement", String.class);

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.util.Hashtable;
import java.util.Map;
import java.util.Random;
import org.alexdev.roseau.game.GameVariables;

/*
* Written by office.boy (Mike) and Nillus from Blunk v5
Expand Down Expand Up @@ -53,7 +54,27 @@ public static void setupEmotes(boolean classicOnly)

public static String[] filterWords(String[] words)
{
// TODO: crappy word filter for swearwords
String filterList = GameVariables.CHAT_FILTER_WORDS;
String replacement = GameVariables.CHAT_FILTER_REPLACEMENT;

if (filterList == null || filterList.isEmpty() || replacement == null || replacement.isEmpty()) {
return words;
}

String[] bannedWords = filterList.split(",");

for (int i = 0; i < words.length; i++) {
// try to prevent bypasses like f.uck
String normalized = words[i].replaceAll("[^a-zA-Z]", "");

for (String banned : bannedWords) {
if (normalized.equalsIgnoreCase(banned.trim())) {
words[i] = replacement;
break;
}
}
}

return words;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
package org.alexdev.roseau.game.room.entity;

import org.alexdev.roseau.game.GameVariables;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

class ChatUtilityTest {

@BeforeEach
void setUp() {
GameVariables.CHAT_FILTER_WORDS = "fuck,sex,damn";
GameVariables.CHAT_FILTER_REPLACEMENT = "bobba";
}

@Test
void noFilterConfigured_returnsWordsUnchanged() {
GameVariables.CHAT_FILTER_WORDS = null;

String[] input = {"hello", "world"};
String[] result = ChatUtility.filterWords(input);

assertArrayEquals(new String[]{"hello", "world"}, result);
}

@Test
void emptyFilterList_returnsWordsUnchanged() {
GameVariables.CHAT_FILTER_WORDS = "";

String[] input = {"hello", "world"};
String[] result = ChatUtility.filterWords(input);

assertArrayEquals(new String[]{"hello", "world"}, result);
}

@Test
void noReplacementConfigured_returnsWordsUnchanged() {
GameVariables.CHAT_FILTER_REPLACEMENT = null;

String[] input = {"fuck", "world"};
String[] result = ChatUtility.filterWords(input);

assertArrayEquals(new String[]{"fuck", "world"}, result);
}

@Test
void exactMatch_isReplaced() {
String[] input = {"fuck", "hello"};
String[] result = ChatUtility.filterWords(input);

assertArrayEquals(new String[]{"bobba", "hello"}, result);
}

@Test
void caseInsensitiveMatch_isReplaced() {
String[] input = {"FUCK", "Fuck"};
String[] result = ChatUtility.filterWords(input);

assertArrayEquals(new String[]{"bobba", "bobba"}, result);
}

@Test
void dots_areStrippedBeforeMatch() {
String[] input = {"f.uck"};
String[] result = ChatUtility.filterWords(input);

assertArrayEquals(new String[]{"bobba"}, result);
}

@Test
void dashes_areStrippedBeforeMatch() {
String[] input = {"f-u-c-k"};
String[] result = ChatUtility.filterWords(input);

assertArrayEquals(new String[]{"bobba"}, result);
}

@Test
void underscores_areStrippedBeforeMatch() {
String[] input = {"f_u_c_k"};
String[] result = ChatUtility.filterWords(input);

assertArrayEquals(new String[]{"bobba"}, result);
}

@Test
void numbers_areStrippedBeforeMatch() {
String[] input = {"f0uck"};
String[] result = ChatUtility.filterWords(input);

assertArrayEquals(new String[]{"bobba"}, result);
}

@Test
void mixedSeparators_areStrippedBeforeMatch() {
String[] input = {"f...u...c...k"};
String[] result = ChatUtility.filterWords(input);

assertArrayEquals(new String[]{"bobba"}, result);
}

@Test
void multipleSeparatorsTogether_areStrippedBeforeMatch() {
String[] input = {"f.u-c_k"};
String[] result = ChatUtility.filterWords(input);

assertArrayEquals(new String[]{"bobba"}, result);
}

@Test
void nonBannedWord_isUnchanged() {
String[] input = {"hello"};
String[] result = ChatUtility.filterWords(input);

assertArrayEquals(new String[]{"hello"}, result);
}

@Test
void multipleWords_someFiltered() {
String[] input = {"hello", "fuck", "world", "sex"};
String[] result = ChatUtility.filterWords(input);

assertArrayEquals(new String[]{"hello", "bobba", "world", "bobba"}, result);
}

@Test
void multipleBannedWords_allReplaced() {
GameVariables.CHAT_FILTER_WORDS = "fuck,sex,damn";

String[] input = {"fuck", "sex", "damn"};
String[] result = ChatUtility.filterWords(input);

assertArrayEquals(new String[]{"bobba", "bobba", "bobba"}, result);
}

@Test
void whitespaceInFilterList_isTrimmed() {
GameVariables.CHAT_FILTER_WORDS = " fuck , sex ";

String[] input = {"fuck", "sex"};
String[] result = ChatUtility.filterWords(input);

assertArrayEquals(new String[]{"bobba", "bobba"}, result);
}

@Test
void singleBannedWordInMultiWordSentence() {
String[] input = {"this", "is", "a", "fuck", "sentence"};
String[] result = ChatUtility.filterWords(input);

assertArrayEquals(new String[]{"this", "is", "a", "bobba", "sentence"}, result);
}

@Test
void asterisks_areStrippedBeforeMatch() {
String[] input = {"f*ck"};
String[] result = ChatUtility.filterWords(input);

assertArrayEquals(new String[]{"bobba"}, result);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public void handle(Player player, ClientMessage reader) {
}

String talkMessage = Util.filterInput(reader.getMessageBody());
talkMessage = String.join(" ", ChatUtility.filterWords(talkMessage.split(" ")));

if (!reader.getHeader().equals("CHAT") && !reader.getHeader().equals("SHOUT") && !reader.getHeader().equals("WHISPER")) {
return;
Expand Down
4 changes: 4 additions & 0 deletions roseau.properties
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,7 @@ log.errors=true
log.output=true
log.connections=true
log.packets=true

[Chat]
filter.words=fuck,sex,porn
filter.replacement=bobba