Torque3D Documentation / _generateds / badWordFilter.cpp

badWordFilter.cpp

Engine/source/app/badWordFilter.cpp

More...

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