badWordFilter.cpp
Engine/source/app/badWordFilter.cpp
Public Variables
Public Functions
DefineEngineFunction(addBadWord , bool , (const char *badWord) , "@brief Add <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> string <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the bad word <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">filter\n\n</a>" "The bad word filter is <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> table containing words which will not be " "displayed in chat windows. Instead, <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> designated replacement string will be displayed. " "There are already <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> number of bad words automatically <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">defined.\n\n</a>" " @param badWord Exact text of the word <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">restrict.\n</a>" " @return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> word was successfully added, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the word or <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> subset of it already exists in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">table\n</a>" " @see filterString()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "//In this game, \"Foobar\" is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">banned\n</a>" "% badWord)
DefineEngineFunction(containsBadWords , bool , (const char *text) , "@brief Checks <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> see <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> text is <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> bad <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">word\n\n</a>" "The text is considered <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> bad word <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> it has been added <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the bad word <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">filter.\n\n</a>" "@param text Text <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> scan <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> bad <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">words\n</a>" "@return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the text has bad word, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> it is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">clean\n</a>" " @see addBadWord()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " @see filterString()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "//In this game, \"Foobar\" is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">banned\n</a>" "% badWord)
DefineEngineFunction(filterString , const char * , (const char *baseString, const char *replacementChars) , (nullAsType< const char * >(), nullAsType< const char * >()) , "@brief Replaces the characters in <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> string with designated <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">text\n\n</a>" "Uses the bad word filter <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> determine which characters within the string will be <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">replaced.\n\n</a>" "@param baseString The original string <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">filter.\n</a>" "@param replacementChars A string containing letters you wish <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/mmath__c_8cpp/#mmath__c_8cpp_1a292b2d8e5390b61e7846b81ea2706317">swap</a> in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">baseString.\n</a>" "@return The <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> scrambled string \<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@see addBadWord()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@see containsBadWords()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "// Create the base string, can come from <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">anywhere\n</a>" "% baseString)
Detailed Description
Public Variables
BadWordFilter * gBadWordFilter
MODULE_END
MODULE_INIT
MODULE_SHUTDOWN
Public Functions
DefineEngineFunction(addBadWord , bool , (const char *badWord) , "@brief Add <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> string <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the bad word <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">filter\n\n</a>" "The bad word filter is <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> table containing words which will not be " "displayed in chat windows. Instead, <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> designated replacement string will be displayed. " "There are already <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> number of bad words automatically <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">defined.\n\n</a>" " @param badWord Exact text of the word <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">restrict.\n</a>" " @return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> word was successfully added, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the word or <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> subset of it already exists in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">table\n</a>" " @see filterString()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "//In this game, \"Foobar\" is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">banned\n</a>" "% badWord)
DefineEngineFunction(containsBadWords , bool , (const char *text) , "@brief Checks <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> see <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> text is <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> bad <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">word\n\n</a>" "The text is considered <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> bad word <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> it has been added <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the bad word <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">filter.\n\n</a>" "@param text Text <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> scan <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> bad <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">words\n</a>" "@return True <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> the text has bad word, false <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> it is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">clean\n</a>" " @see addBadWord()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " @see filterString()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "//In this game, \"Foobar\" is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">banned\n</a>" "% badWord)
DefineEngineFunction(filterString , const char * , (const char *baseString, const char *replacementChars) , (nullAsType< const char * >(), nullAsType< const char * >()) , "@brief Replaces the characters in <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> string with designated <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">text\n\n</a>" "Uses the bad word filter <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> determine which characters within the string will be <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">replaced.\n\n</a>" "@param baseString The original string <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">filter.\n</a>" "@param replacementChars A string containing letters you wish <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> <a href="/coding/file/mmath__c_8cpp/#mmath__c_8cpp_1a292b2d8e5390b61e7846b81ea2706317">swap</a> in the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">baseString.\n</a>" "@return The <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> scrambled string \<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@see addBadWord()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@see containsBadWords()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "// Create the base string, can come from <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">anywhere\n</a>" "% baseString)
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "core/strings/stringFunctions.h" 25 26#include "console/consoleTypes.h" 27#include "console/simBase.h" 28#include "console/engineAPI.h" 29#include "app/badWordFilter.h" 30#include "core/module.h" 31 32MODULE_BEGIN( BadWordFilter ) 33 34 MODULE_INIT 35 { 36 BadWordFilter::create(); 37 } 38 39 MODULE_SHUTDOWN 40 { 41 BadWordFilter::destroy(); 42 } 43 44MODULE_END; 45 46 47BadWordFilter *gBadWordFilter = NULL; 48bool BadWordFilter::filteringEnabled = true; 49 50BadWordFilter::BadWordFilter() 51{ 52 VECTOR_SET_ASSOCIATION( filterTables ); 53 54 dStrcpy(defaultReplaceStr, "knqwrtlzs", 32); 55 filterTables.push_back(new FilterTable); 56 curOffset = 0; 57} 58 59BadWordFilter::~BadWordFilter() 60{ 61 for(U32 i = 0; i < filterTables.size(); i++) 62 delete filterTables[i]; 63} 64 65void BadWordFilter::create() 66{ 67 Con::addVariable("pref::enableBadWordFilter", TypeBool, &filteringEnabled, 68 "@brief If true, the bad word filter will be enabled.\n\n" 69 "@ingroup Game"); 70 gBadWordFilter = new BadWordFilter; 71 gBadWordFilter->addBadWord("shit"); 72 gBadWordFilter->addBadWord("fuck"); 73 gBadWordFilter->addBadWord("cock"); 74 gBadWordFilter->addBadWord("bitch"); 75 gBadWordFilter->addBadWord("cunt"); 76 gBadWordFilter->addBadWord("nigger"); 77 gBadWordFilter->addBadWord("bastard"); 78 gBadWordFilter->addBadWord("dick"); 79 gBadWordFilter->addBadWord("whore"); 80 gBadWordFilter->addBadWord("goddamn"); 81 gBadWordFilter->addBadWord("asshole"); 82} 83 84void BadWordFilter::destroy() 85{ 86 delete gBadWordFilter; 87 gBadWordFilter = NULL; 88} 89 90 91U8 BadWordFilter::remapTable[257] = "------------------------------------------------OI---------------ABCDEFGHIJKLMNOPQRSTUVWXYZ------ABCDEFGHIJKLMNOPQRSTUVWXYZ-----C--F--TT--S-C-Z-----------S-C-ZY--CLOY-S-CA---R---UT-UP--IO-----AAAAAAACEEEEIIIIDNOOOOOXOUUUUYDBAAAAAAACEEEEIIIIDNOOOOO-OUUUUYDY"; 92U8 BadWordFilter::randomJunk[MaxBadwordLength+1] = "REMsg rk34n4ksqow;xnskq;KQoaWnZa"; 93 94BadWordFilter::FilterTable::FilterTable() 95{ 96 for(U32 i = 0; i < 26; i++) 97 nextState[i] = TerminateNotFound; 98} 99 100bool BadWordFilter::addBadWord(const char *cword) 101{ 102 FilterTable *curFilterTable = filterTables[0]; 103 // prescan the word to see if it has any skip chars 104 const U8 *word = (const U8 *) cword; 105 const U8 *walk = word; 106 if(dStrlen(cword) > MaxBadwordLength) 107 return false; 108 while(*walk) 109 { 110 if(remapTable[*walk] == '-') 111 return false; 112 walk++; 113 } 114 while(*word) 115 { 116 U8 remap = remapTable[*word] - 'A'; 117 U16 state = curFilterTable->nextState[remap]; 118 119 if(state < TerminateNotFound) 120 { 121 // this character is already in the state table... 122 curFilterTable = filterTables[state]; 123 } 124 else if(state == TerminateFound) 125 { 126 // a subset of this word is already in the table... 127 // exit out. 128 return false; 129 } 130 else if(state == TerminateNotFound) 131 { 132 if(word[1]) 133 { 134 curFilterTable->nextState[remap] = filterTables.size(); 135 filterTables.push_back(new FilterTable); 136 curFilterTable = filterTables[filterTables.size() - 1]; 137 } 138 else 139 curFilterTable->nextState[remap] = TerminateFound; 140 } 141 word++; 142 } 143 return true; 144} 145 146bool BadWordFilter::setDefaultReplaceStr(const char *str) 147{ 148 U32 len = dStrlen(str); 149 if(len < 2 || len >= sizeof(defaultReplaceStr)) 150 return false; 151 dStrcpy(defaultReplaceStr, str, 32); 152 return true; 153} 154 155void BadWordFilter::filterString(char *cstring, const char *replaceStr) 156{ 157 if(!replaceStr) 158 replaceStr = defaultReplaceStr; 159 U8 *string = (U8 *) cstring; 160 U8 *starts[MaxBadwordLength]; 161 U8 *curStart = string; 162 U32 replaceLen = dStrlen(replaceStr); 163 while(*curStart) 164 { 165 FilterTable *curFilterTable = filterTables[0]; 166 S32 index = 0; 167 U8 *walk = curStart; 168 while(*walk) 169 { 170 U8 remap = remapTable[*walk]; 171 if(remap != '-') 172 { 173 starts[index++] = walk; 174 U16 table = curFilterTable->nextState[remap - 'A']; 175 if(table < TerminateNotFound) 176 curFilterTable = filterTables[table]; 177 else if(table == TerminateNotFound) 178 { 179 curStart++; 180 break; 181 } 182 else // terminate found 183 { 184 for(U32 i = 0; i < index; i++) 185 { 186 starts[i][0] = (U8 )replaceStr[curOffset % replaceLen]; 187 curOffset += randomJunk[curOffset & (MaxBadwordLength - 1)]; 188 } 189 curStart = walk + 1; 190 break; 191 } 192 } 193 walk++; 194 } 195 if(!*walk) 196 curStart++; 197 } 198} 199 200bool BadWordFilter::containsBadWords(const char *cstring) 201{ 202 U8 *string = (U8 *) cstring; 203 U8 *curStart = string; 204 while(*curStart) 205 { 206 FilterTable *curFilterTable = filterTables[0]; 207 U8 *walk = curStart; 208 while(*walk) 209 { 210 U8 remap = remapTable[*walk]; 211 if(remap != '-') 212 { 213 U16 table = curFilterTable->nextState[remap - 'A']; 214 if(table < TerminateNotFound) 215 curFilterTable = filterTables[table]; 216 else if(table == TerminateNotFound) 217 { 218 curStart++; 219 break; 220 } 221 else // terminate found 222 return true; 223 } 224 walk++; 225 } 226 if(!*walk) 227 curStart++; 228 } 229 return false; 230} 231 232DefineEngineFunction(addBadWord, bool, (const char* badWord),, 233 "@brief Add a string to the bad word filter\n\n" 234 235 "The bad word filter is a table containing words which will not be " 236 "displayed in chat windows. Instead, a designated replacement string will be displayed. " 237 "There are already a number of bad words automatically defined.\n\n" 238 239 "@param badWord Exact text of the word to restrict.\n" 240 "@return True if word was successfully added, false if the word or a subset of it already exists in the table\n" 241 242 "@see filterString()\n\n" 243 244 "@tsexample\n" 245 "// In this game, \"Foobar\" is banned\n" 246 "%badWord = \"Foobar\";\n\n" 247 "// Returns true, word was successfully added\n" 248 "addBadWord(%badWord);\n\n" 249 "// Returns false, word has already been added\n" 250 "addBadWord(\"Foobar\");" 251 "@endtsexample\n" 252 253 "@ingroup Game") 254{ 255 return gBadWordFilter->addBadWord(badWord); 256} 257 258DefineEngineFunction(filterString, const char *, (const char* baseString, const char* replacementChars), (nullAsType<const char*>(), nullAsType<const char*>()), 259 "@brief Replaces the characters in a string with designated text\n\n" 260 261 "Uses the bad word filter to determine which characters within the string will be replaced.\n\n" 262 263 "@param baseString The original string to filter.\n" 264 "@param replacementChars A string containing letters you wish to swap in the baseString.\n" 265 "@return The new scrambled string \n" 266 267 "@see addBadWord()\n" 268 "@see containsBadWords()\n" 269 270 "@tsexample\n" 271 "// Create the base string, can come from anywhere\n" 272 "%baseString = \"Foobar\";\n\n" 273 "// Create a string of random letters\n" 274 "%replacementChars = \"knqwrtlzs\";\n\n" 275 "// Filter the string\n" 276 "%newString = filterString(%baseString, %replacementChars);\n\n" 277 "// Print the new string to console\n" 278 "echo(%newString);" 279 "@endtsexample\n" 280 281 "@ingroup Game") 282{ 283 const char *replaceStr = NULL; 284 285 if(replacementChars) 286 replaceStr = replacementChars; 287 else 288 replaceStr = gBadWordFilter->getDefaultReplaceStr(); 289 290 dsize_t retLen = dStrlen(baseString) + 1; 291 char *ret = Con::getReturnBuffer(retLen); 292 dStrcpy(ret, baseString, retLen); 293 gBadWordFilter->filterString(ret, replaceStr); 294 return ret; 295} 296 297DefineEngineFunction(containsBadWords, bool, (const char* text),, 298 "@brief Checks to see if text is a bad word\n\n" 299 300 "The text is considered to be a bad word if it has been added to the bad word filter.\n\n" 301 302 "@param text Text to scan for bad words\n" 303 "@return True if the text has bad word(s), false if it is clean\n" 304 305 "@see addBadWord()\n" 306 "@see filterString()\n" 307 308 "@tsexample\n" 309 "// In this game, \"Foobar\" is banned\n" 310 "%badWord = \"Foobar\";\n\n" 311 "// Add a banned word to the bad word filter\n" 312 "addBadWord(%badWord);\n\n" 313 "// Create the base string, can come from anywhere like user chat\n" 314 "%userText = \"Foobar\";\n\n" 315 "// Create a string of random letters\n" 316 "%replacementChars = \"knqwrtlzs\";\n\n" 317 "// If the text contains a bad word, filter it before printing\n" 318 "// Otherwise print the original text\n" 319 "if(containsBadWords(%userText))\n" 320 "{\n" 321 " // Filter the string\n" 322 " %filteredText = filterString(%userText, %replacementChars);\n\n" 323 " // Print filtered text\n" 324 " echo(%filteredText);\n" 325 "}\n" 326 "else\n" 327 " echo(%userText);\n\n" 328 "@endtsexample\n" 329 330 "@ingroup Game") 331{ 332 return gBadWordFilter->containsBadWords(text); 333} 334 335