一段时间以来,我一直在尝试为名为TrinityCore的WoW模拟器创建一个检查系统。我基本上要做的是在数据库表(chat_filter)中填入“坏词”,在启动时以及在玩家进行的每条聊天行中用这些词填充一个向量,然后根据向量的内容对其进行检查。如果它包含一个坏词,则将其替换为**(而*的数量也将从数据库表中的一列中提取)(待办事项),并且玩家将受到惩罚(将其静音)。
现在,我遇到的问题是如何制作适当的过滤器。现在,您必须添加可能想到的单词的所有可能组合,例如“ a.s.s.”应该也读作“屁股”,我也不知道该怎么做!
这是当前代码的重要部分,我遗漏了DB的拉动,因为它无论如何都没有用(而且由于它在不同的文件中,因此它变得不太清楚)。
char* msg3 = strdup(msg.c_str());
char* words = strtok(msg3, " ,.-()&^%$#@!{}'<>/?|\\=+-_1234567890"); // This splits the sentence in seperated words and removes the symbols
ObjectMgr::ChatFilterContainer const& censoredWords = sObjectMgr->GetCensoredWords();
while (words != NULL && !censoredWords.empty())
{
for (uint32 i = 0; i < censoredWords.size(); ++i)
{
if (!stricmp(censoredWords[i].c_str(), words))
{
sLog->outString("%s", words);
//msg.replace(msg.begin(), msg.end(), msg.c_str(), "***");
msg.replace(msg.begin(), msg.end(), censoredWords[i].c_str(), '*');
}
//msg.replace(msg.begin(), msg.end(), censoredWords[i].c_str(), /*replacement*/ "***");
//msg.replace(msg.find(censoredWords[i].c_str()), censoredWords.size(),
}
words = strtok(NULL, " ,.-()&^%$#@!{}'<>/?|\=+-_1234567890");
}
提前致谢,
碧玉
附言'GetCensoredWords'返回向量。
P.S.S. “ msg”是std :: string-这是播放器发送的实际消息。
最佳答案
我会使用std::string
而不是char*
,因此内存管理是自动的。那将解决示例代码中内存泄漏的问题。 Boost.Algorithm提供了强大的boost::algorithm::split
函数,该函数比strtok
更好。
存储被检查单词的所有可能排列是不可行的,尤其是如果您要为每个输入循环遍历整个单词集时,尤其如此。如果要审查“ fubar”,则必须存储“ Fubar”,“ FUbar”和“ FuBaR”,“ fub4r”,“ F.U.B.A.R”和“ f.u.b.a.r”等。
取而代之的是,您只能以规范化形式(例如, “ fubar”,然后将输入的每个单词转换为规范化形式。因此,如果用户输入“ FuBaR”,则将其归一化为“ fubar”,则可以对被检查词集进行简单查找(可以使用关联容器,因此查找为O(log n)甚至O(1) )