mirror of
https://github.com/tribes2/engine.git
synced 2026-01-20 19:54:46 +00:00
218 lines
5.9 KiB
C++
218 lines
5.9 KiB
C++
//-----------------------------------------------------------------------------
|
|
// V12 Engine
|
|
//
|
|
// Copyright (c) 2001 GarageGames.Com
|
|
// Portions Copyright (c) 2001 by Sierra Online, Inc.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#include "platform/platform.h"
|
|
#include "console/console.h"
|
|
#include "console/consoleTypes.h"
|
|
#include "game/badWordFilter.h"
|
|
|
|
BadWordFilter *gBadWordFilter = NULL;
|
|
bool BadWordFilter::filteringEnabled = true;
|
|
|
|
BadWordFilter::BadWordFilter()
|
|
{
|
|
dStrcpy(defaultReplaceStr, "knqwrtlzs");
|
|
filterTables.push_back(new FilterTable);
|
|
curOffset = 0;
|
|
}
|
|
|
|
BadWordFilter::~BadWordFilter()
|
|
{
|
|
for(U32 i = 0; i < filterTables.size(); i++)
|
|
delete filterTables[i];
|
|
}
|
|
|
|
void BadWordFilter::create()
|
|
{
|
|
Con::addVariable("pref::enableBadWordFilter", TypeBool, &filteringEnabled);
|
|
gBadWordFilter = new BadWordFilter;
|
|
gBadWordFilter->addBadWord("shit");
|
|
gBadWordFilter->addBadWord("fuck");
|
|
gBadWordFilter->addBadWord("cock");
|
|
gBadWordFilter->addBadWord("bitch");
|
|
gBadWordFilter->addBadWord("cunt");
|
|
gBadWordFilter->addBadWord("nigger");
|
|
gBadWordFilter->addBadWord("bastard");
|
|
gBadWordFilter->addBadWord("dick");
|
|
gBadWordFilter->addBadWord("whore");
|
|
gBadWordFilter->addBadWord("goddamn");
|
|
gBadWordFilter->addBadWord("asshole");
|
|
}
|
|
|
|
void BadWordFilter::destroy()
|
|
{
|
|
delete gBadWordFilter;
|
|
gBadWordFilter = NULL;
|
|
}
|
|
|
|
|
|
U8 BadWordFilter::remapTable[257] = "------------------------------------------------OI---------------ABCDEFGHIJKLMNOPQRSTUVWXYZ------ABCDEFGHIJKLMNOPQRSTUVWXYZ-----C--F--TT--S-C-Z-----------S-C-ZY--CLOY-S-CA---R---UT-UP--IO-----AAAAAAACEEEEIIIIDNOOOOOXOUUUUYDBAAAAAAACEEEEIIIIDNOOOOO-OUUUUYDY";
|
|
U8 BadWordFilter::randomJunk[MaxBadwordLength+1] = "REMsg rk34n4ksqow;xnskq;KQoaWnZa";
|
|
|
|
BadWordFilter::FilterTable::FilterTable()
|
|
{
|
|
for(U32 i = 0; i < 26; i++)
|
|
nextState[i] = TerminateNotFound;
|
|
}
|
|
|
|
bool BadWordFilter::addBadWord(const char *cword)
|
|
{
|
|
FilterTable *curFilterTable = filterTables[0];
|
|
// prescan the word to see if it has any skip chars
|
|
const U8 *word = (const U8 *) cword;
|
|
const U8 *walk = word;
|
|
if(dStrlen(cword) > MaxBadwordLength)
|
|
return false;
|
|
while(*walk)
|
|
{
|
|
if(remapTable[*walk] == '-')
|
|
return false;
|
|
walk++;
|
|
}
|
|
while(*word)
|
|
{
|
|
U8 remap = remapTable[*word] - 'A';
|
|
U16 state = curFilterTable->nextState[remap];
|
|
|
|
if(state < TerminateNotFound)
|
|
{
|
|
// this character is already in the state table...
|
|
curFilterTable = filterTables[state];
|
|
}
|
|
else if(state == TerminateFound)
|
|
{
|
|
// a subset of this word is already in the table...
|
|
// exit out.
|
|
return false;
|
|
}
|
|
else if(state == TerminateNotFound)
|
|
{
|
|
if(word[1])
|
|
{
|
|
curFilterTable->nextState[remap] = filterTables.size();
|
|
filterTables.push_back(new FilterTable);
|
|
curFilterTable = filterTables[filterTables.size() - 1];
|
|
}
|
|
else
|
|
curFilterTable->nextState[remap] = TerminateFound;
|
|
}
|
|
word++;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool BadWordFilter::setDefaultReplaceStr(const char *str)
|
|
{
|
|
U32 len = dStrlen(str);
|
|
if(len < 2 || len >= sizeof(defaultReplaceStr))
|
|
return false;
|
|
dStrcpy(defaultReplaceStr, str);
|
|
return true;
|
|
}
|
|
|
|
void BadWordFilter::filterString(char *cstring, const char *replaceStr)
|
|
{
|
|
if(!replaceStr)
|
|
replaceStr = defaultReplaceStr;
|
|
U8 *string = (U8 *) cstring;
|
|
U8 *starts[MaxBadwordLength];
|
|
U8 *curStart = string;
|
|
U32 replaceLen = dStrlen(replaceStr);
|
|
while(*curStart)
|
|
{
|
|
FilterTable *curFilterTable = filterTables[0];
|
|
S32 index = 0;
|
|
U8 *walk = curStart;
|
|
while(*walk)
|
|
{
|
|
U8 remap = remapTable[*walk];
|
|
if(remap != '-')
|
|
{
|
|
starts[index++] = walk;
|
|
U16 table = curFilterTable->nextState[remap - 'A'];
|
|
if(table < TerminateNotFound)
|
|
curFilterTable = filterTables[table];
|
|
else if(table == TerminateNotFound)
|
|
{
|
|
curStart++;
|
|
break;
|
|
}
|
|
else // terminate found
|
|
{
|
|
for(U32 i = 0; i < index; i++)
|
|
{
|
|
starts[i][0] = (U8 )replaceStr[curOffset % replaceLen];
|
|
curOffset += randomJunk[curOffset & (MaxBadwordLength - 1)];
|
|
}
|
|
curStart = walk + 1;
|
|
break;
|
|
}
|
|
}
|
|
walk++;
|
|
}
|
|
if(!*walk)
|
|
curStart++;
|
|
}
|
|
}
|
|
|
|
bool BadWordFilter::containsBadWords(const char *cstring)
|
|
{
|
|
U8 *string = (U8 *) cstring;
|
|
U8 *curStart = string;
|
|
while(*curStart)
|
|
{
|
|
FilterTable *curFilterTable = filterTables[0];
|
|
S32 index = 0;
|
|
U8 *walk = curStart;
|
|
while(*walk)
|
|
{
|
|
U8 remap = remapTable[*walk];
|
|
if(remap != '-')
|
|
{
|
|
U16 table = curFilterTable->nextState[remap - 'A'];
|
|
if(table < TerminateNotFound)
|
|
curFilterTable = filterTables[table];
|
|
else if(table == TerminateNotFound)
|
|
{
|
|
curStart++;
|
|
break;
|
|
}
|
|
else // terminate found
|
|
return true;
|
|
}
|
|
walk++;
|
|
}
|
|
if(!*walk)
|
|
curStart++;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
ConsoleFunction(addBadWord, bool, 2, 2, "addBadWord(someReallyNastyWord);")
|
|
{
|
|
argc;
|
|
return gBadWordFilter->addBadWord(argv[1]);
|
|
}
|
|
|
|
ConsoleFunction(filterString, const char *, 2, 3, "filterString(baseString,replacementChars);")
|
|
{
|
|
const char *replaceStr = NULL;
|
|
if(argc == 3)
|
|
replaceStr = argv[2];
|
|
|
|
char *ret = Con::getReturnBuffer(dStrlen(argv[1]) + 1);
|
|
dStrcpy(ret, argv[1]);
|
|
gBadWordFilter->filterString(ret, replaceStr);
|
|
return ret;
|
|
}
|
|
|
|
ConsoleFunction(containsBadWords, bool, 2, 2, "containsBadWords(text);")
|
|
{
|
|
argc;
|
|
return gBadWordFilter->containsBadWords(argv[1]);
|
|
}
|