0

一段时间以来,我一直在尝试为 WoW 模拟器创建一个名为 TrinityCore 的审查系统。我基本上做的是用“坏词”填充一个数据库表(chat_filter),在启动时用这些填充一个向量,在玩家制作的每条聊天线上,它都会根据我的向量的内容进行检查。如果它包含一个坏词,它会被* * 替换(而 * 的数量也将从数据库表 (todo) 的列中获取)并且玩家会受到惩罚(静音左右)。

现在我遇到的问题是如何制作合适的过滤器。现在你必须添加你能想到的所有可能的单词组合,例如“ass”也应该读作“ass”,我不知道该怎么做!

这是当前代码的重要部分,我省略了数据库拉动,因为它无论如何都没有任何用处(而且它在不同的文件中会使其不太清楚)。

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");
}

提前致谢,

碧玉

PS 'GetCensoredWords' 返回向量。

PSS 'msg' 是一个 std::string - 它是玩家发送的实际消息。

4

1 回答 1

1

我不会使用std::stringchar*所以内存管理是全自动的。这将解决您的示例代码中的内存泄漏问题。Boost.Algorithm 提供了一个boost::algorithm::splitstrtok.

存储被审查词的所有可能排列是不可行的,特别是如果您要为每个输入循环遍历整个词集。如果要审查“fubar”,则必须存储“Fubar”、“FUbar”和“FuBaR”、“fub4r”、“FUBAR”和“fubar”等。

取而代之的是,您可以将每个被审查的词只存储一次,以规范化的形式,例如“fubar”,然后将输入的每个词转换为规范化的形式。因此,如果用户输入“FuBaR”,您将其规范化为“fubar”,那么您可以对一组审查词进行简单查找(可以使用关联容器,因此查找为 O(log n) 甚至 O(1) )

于 2012-05-28T23:15:57.047 回答