0

TrinityCore と呼ばれる WoW エミュレーター用の検閲システムをしばらく作成しようとしています。私が基本的に行っているのは、データベース テーブル (chat_filter) に「悪い言葉」を入力し、起動時にこれらをベクターに入力し、プレイヤーが作成したすべてのチャット ラインで、ベクターの内容と照合してチェックすることです。悪い単語が含まれている場合、これは* *に置き換えられ(一方、* の量はデータベース テーブル (todo) の列からも取得されます)、プレイヤーは罰を受けます (ミュートなど)。

今、私が問題を抱えているのは、適切なフィルターを作成する方法です。現時点では、考えられる単語のすべての可能な組み合わせを追加する必要があります。たとえば、「お尻」は「お尻」とも読む必要がありますが、これを行う方法がわかりません!

現在のコードの重要な部分は次のとおりです。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");
}

前もって感謝します、

碧玉

PS 'GetCensoredWords' はベクトルを返します。

PSS 'msg' is a std::string - プレイヤーが送信した実際のメッセージです。

4

1 に答える 1

1

私は使用しstd::stringないchar*ので、メモリ管理はすべて自動です。これにより、サンプル コードでのメモリ リークの問題が解決されます。Boost.Algorithm は、boost::algorithm::splitよりもはるかに優れた強力な機能を提供しますstrtok

特に入力ごとに単語のセット全体をループする場合は、検閲された単語のすべての可能な順列を保存することは現実的ではありません。「fubar」を検閲したい場合は、「Fubar」と「FUbar」と「FuBaR」と「fub4r」と「FUBAR」と「fubar」などを保存する必要があります。

代わりに、「fubar」などの正規化された形式で、検閲された各単語を一度だけ保存し、入力の各単語を正規化された形式に変換できます。したがって、ユーザーが「FuBaR」と入力すると、それを「fubar」に正規化してから、検閲された単語のセットを簡単に検索できます (関連コンテナーを使用できるため、検索は O(log n) または O(1) になります)。 )

于 2012-05-28T23:15:57.047 に答える