一段时间以来,我一直在尝试为名为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) )

09-06 15:39