我已经尝试为WoW仿真器创建一个称为TrinityCore的审查系统已有一段时间了。基本上,我所做的就是用“坏单词”填充一个数据库表(chat_filter),在启动时用这些单词填充一个向量,并且在播放机创建的每一条聊天线路上,根据我的向量的内容进行检查。如果它包含一个不好的单词,它将被**所取代(而*的数量也将从数据库表(Todo)的列中提取),而玩家将受到惩罚(静默)。
现在我遇到麻烦的是如何做一个合适的过滤器。现在,您必须添加所有可以想到的单词的组合,例如‘a.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‘返回向量。
“msg”是一个std::string --它是播放器发送的实际消息。
发布于 2012-05-28 23:15:57
我会使用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 )甚至O(1))。
https://stackoverflow.com/questions/10790833
复制相似问题