ICTの水たまり

top > 実験と雑記(ブログ) > 2022/12/04 Minecraftのtext-filtering-configについて

Minecraftのtext-filtering-configについて

記事の目次

この記事は RICORA Advent Calendar 2022の4日目の記事です。

背景

1年ぐらい前に、YouTubeのスパムチャットによるチャンネル凍結(Channel BAN)の事例を知りました。それは コメントを配信画面内に流しているチャンネルを狙い、スパムコメントを投稿してチャンネルを凍結させるものでした。

「もしかして、それはゲーム内チャットでも攻撃として通ってしまうんじゃないか?対策はないのか?」と思い、調べたところ、 Minecraftではその手の設定っぽいものを見つけることができました。今回の「text-filtering-config」です。 しかしながら、技術的解説をしているのは、walshy氏の記事があるのみでした。

この記事では、walshy氏の記事をもとに、いろいろしてみてわかったことをまとめようと思います。

前提

これは公式の情報ではありません。したがって、この記事に書いてある情報が正しいとは限りません。

今回の実験で使用したMinecraftのバージョンは、1.19です。したがって、ゲーム本体的には「Minecraft 1.19が動作すること」となります。 実験自体はに、MinecraftでアカウントBANが実装されたころに行いました。(参考:[2])

text-filtering-configとは

text-filtering-configの設定内容

text-filtering-configは、Minecraft 1.16.4にてしれっと追加された、サーバーの設定項目です。 追加されて以後、使い方が記されていませんでしたが、walshy氏の記事「MC's new secret text filtering!」にて その詳細を知ることができました。

text-filtering-configの設定項目は、次の構造のJSONオブジェクトです。

コード1:text-filtering-configの設定内容
{
    "apiServer": String,
    "apiKey": String,
    "ruleId":Integer,
    "serverId": String,
    "hashesToDrop":Integer,
    "maxConcurrentRequests": Integer
}

具体的な内容は、次のリスト1です。(ref:1:Walshy氏の記事からの情報を含みます。)

リスト1:text-filtering-configの設定内容
apiServer
APIサーバーのアドレス。サーバーのアドレスとポートまで読み込まれる。ここに書かれたURLに、フィルタリングのリクエストが送られる。
apiKey
APIキーとして使う文字列。BASIC認証ヘッダに使用される[1]。
ruleId
ルール識別番号だと思われるが、使い方は不明。
serverId
文字列による、サーバー識別子だと思われる。使い方は不明。
hashesToDrop
メッセージが捨てられるhashの基準値…らしい。
maxConcurrentRequests
処理スレッドプールの数らしい。(=処理スレッドを予約する数。いくつ同時に処理するかの上限だと思ってよさそうである。)

APIエンドポイントに求められるもの

text-filtering-configが正しく設定されていると、apiServerに指定されたサーバーあてに、HTTPでリクエストが送られます。

2022/06/26時点で、わかっているAPIエンドポイントは、リスト2の通りです。
リスト2:APIエンドポイントの一覧

以下に説明を書きます。

POST /v1/chat

/v1/chatは、最も基本となるエンドポイントです。

チャット(say, me), ささやき(msg, tm, w)、看板の書き込み、本への書き込みに対して 使用されるエンドポイントです。tellrawコマンドと、アイテムの名前変更については使用されていません。 また、サーバーコンソールからのチャット・ささやき送信はフィルターされないようです。

看板は、内容編集を終了するとき、各行毎にエンドポイントを呼び出します。

本への書き込みについては、編集後に本を閉じるたびに、ページごとにエンドポイントを呼び出します。

例:Minecraft (Java) IDがPC9801の人が、testとチャットした。

テストプログラムはPHPで作成したため、ヘッダー情報は略します。テキストエンコードはUTF-8です。

{"rule":1,"server":"test","room":"Java:Chat", "player":(player UUID in String type),"player_display_name":"PC9801", "text":"test","language":"*"}
リスト3:リクエストボディの内容
rule
text-filtering-configに書いたルール番号
server
text-filtering-configに書いたサーバー識別子
room
不明。値は1.19では常にJava:Chat
player
発信者のUUID
player_display_name
発信者のMinecraft(Java)ID
text
フィルターを通す文字列です。
language
言語設定を指していると思われますが、不明です。

APIエンドポイントは、リクエストが送られてから2秒未満で反応を返す必要があります。(実験の結果、待ち時間が2秒以上となると無視されました。)

HTTPレスポンスヘッダに、Content-type: application/json;を含む必要があります。

レスポンスボディは、次のようなJSONです。

{"response": true, "hashed": "test", "hashes":[]}
リスト4:レスポンスボディのJSON構造
response
真偽値をとる。trueのとき、文書はフィルターされずに公開される。
hashed
responseがfalseのとき、hashedに書かれたテキストに置き換えられる。看板や本では、「§」文字によるスタイルの変更が効いた。
hashes
リクエストのtextから見つかった、NGワードの配列。この配列の要素数が、text-filtering-configの hashesToDropを超えると、非公開のまま破棄される。

POST /v1/join

何を返すべきか不明。入室通知。未検証。

POST /v1/leave

何を返すべきか不明。退室通知。未検証。

参考文献

  1. MC's new secret text filtering!」 by walshy
  2. Dedicated server text filter does not apply to all text」, (Mojang Studios bug tracking system)

付録

NGワードの集め方

この記事を積極的に、かつ、検索で入り込んできた人にむけて、NGワードの探し方を書いてくことにする。 大人向けだ。というのも、NGワードは結構危ない単語が多い。どうしてNGなのか。使っても問題ない、他の単語は巻き込まないか。 単語を見つけても、考えるべきことは多い。

「Swear words」で検索する

Swear wordsとは、(おおやけ)の場や 子供の前ではふさわしくない単語・表現のこと。「ふさわしくない」どころか、「そもそも使うべきではない悪態」レベルのものもたくさんある。 引っかかる単語はほとんどが英語。

放送禁止用語を調べる

放送禁止用語とは、テレビ局などが、放送しないよう自主規制する対象の言葉。 「諸事情」が特殊な背景のものもあり、「公の放送でなければここまでしなくてもいいのでは?」とおもう単語もあるだろう。 テレビジョン放送局以外にも、インターネット放送やさんのNGワードも参考になる。(ニコニコ生放送の運営NGワードなど)

ゲームのNGワードや、NG推奨ワードを調べてみる

世界中で人気な「ポケットモンスター」には、結構様々なNGワードがある。もちろん「ゲーム中で使ってほしくない単語」の一覧である。 それ以外にも、界隈ごとのNGワードを調べるのはアリ。

インターネットスラングならではの表記

英語では、LEET表記という書き方がある。日本語の場合は「ギャル文字」や「クサチュー語」などが、近い文化かもしれない。 単純に単語を羅列するだけでは、このような特殊な表記法や表記ゆれではスルーされてしまうことがある。

無自覚な荒らし

無自覚な荒らしは(たち)が悪い。自分が無自覚な荒らしになっていないか 自己チェックしない限り気が付けないからである。僕たちは「無自覚な荒らし」をしていないだろうか?君たちは「無自覚な荒らし」をしていないだろうか?

最後に

walshyさんに感謝します。あなたのtext-filtering-configについての記事が、私にとって大きな情報でした。