/* * Original work: Copyright (c) 2014, Oculus VR, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * RakNet License.txt file in the licenses directory of this source tree. An additional grant * of patent rights can be found in the RakNet Patents.txt file in the same directory. * * * Modified work: Copyright (c) 2016-2018, SLikeSoft UG (haftungsbeschränkt) * * This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style * license found in the license.txt file in the root directory of this source tree. */ #include "ProfanityFilter.h" #include "slikenet/Rand.h" #include "slikenet/assert.h" #include "slikenet/LinuxStrings.h" #include "slikenet/linux_adapter.h" #include "slikenet/osx_adapter.h" #if defined(_WIN32) #include // alloca #elif (defined(__GNUC__) || defined(__GCCXML__)) #include #else #endif using namespace SLNet; char ProfanityFilter::BANCHARS[] = "!@#$%^&*()"; char ProfanityFilter::WORDCHARS[] = "abcdefghijklmnopqrstuvwxyz0123456789"; ProfanityFilter::ProfanityFilter() { } ProfanityFilter::~ProfanityFilter() { } char ProfanityFilter::RandomBanChar() { return BANCHARS[randomMT() % (sizeof(BANCHARS) - 1)]; } bool ProfanityFilter::HasProfanity(const char *str) { return FilterProfanity(str, 0, 0,false) > 0; } int ProfanityFilter::FilterProfanity(const char *input, char *output, bool filter) { if (input == 0 || input[0] == 0) return 0; int count = 0; char* b = (char *)alloca(strlen(input) + 1); strcpy_s(b, strlen(input) + 1, input); _strlwr(b); char *start = b; if (output) strcpy(output, input); start = strpbrk(start, WORDCHARS); while (start != 0) { size_t len = strspn(start, WORDCHARS); if (len > 0) { // we a have a word - let's check if it's a BAAAD one char saveChar = start[len]; start[len] = '\0'; // loop through profanity list for (unsigned int i = 0, size = words.Size(); i < size; i++) { if (_stricmp(start, words[i].C_String()) == 0) { count++; // size_t len = words[i].size(); if (filter && output) { for (unsigned int j = 0; j < len; j++) { output[start + j - b] = RandomBanChar(); } } break; } } start[len] = saveChar; } start += len; start = strpbrk(start, WORDCHARS); } return count; } int ProfanityFilter::FilterProfanity(const char *input, char *output, size_t outputLength, bool filter) { if (input==0 || input[0]==0) return 0; int count = 0; char* b = (char *) alloca(strlen(input) + 1); strcpy_s(b, strlen(input) + 1, input); _strlwr(b); char *start = b; if (output) strcpy_s(output,outputLength,input); start = strpbrk(start, WORDCHARS); while (start != 0) { size_t len = strspn(start, WORDCHARS); if (len > 0) { // we a have a word - let's check if it's a BAAAD one char saveChar = start[len]; start[len] = '\0'; // loop through profanity list for (unsigned int i = 0, size = words.Size(); i < size; i++) { if (_stricmp(start, words[i].C_String()) == 0) { count++; // size_t len = words[i].size(); if (filter && output) { for (unsigned int j = 0; j < len; j++) { output[start + j - b] = RandomBanChar(); } } break; } } start[len] = saveChar; } start += len; start = strpbrk(start, WORDCHARS); } return count; } int ProfanityFilter::Count() { return words.Size(); } void ProfanityFilter::AddWord(SLNet::RakString newWord) { words.Insert(newWord, _FILE_AND_LINE_ ); }