明日(10/13 0:00)から、新しいMinecraftサーバー「DebtCraft」を始める。増え続ける日本の借金を、みんなでダイヤを納めて返すサーバー。返済の様子は借金時計で見られる。
荒らし対策として、サバイバルはDiscordサーバーにいる人だけ入れるようにした。ロビーには誰でも入れる。
やりたかったこと
- Discordのボタンからマイクラの名前を登録すると、ホワイトリストに入る
- Discordを抜けたら、ホワイトリストから外してキックする
- 戻ってきて入国審査をやり直したら、ホワイトリストに戻す
仕組み
最初は「マイクラに入ると6桁のコードが出て、それをDiscordに入力する」方式を考えていた。でも、それだとVelocity用のプラグインを1本作る必要がある。
もっと単純に、Discordのbotから、サーバーにRCONでコマンドを送ることにした。
- Discordの 🪪|入国審査 で「入国する」→「Java版で登録」か「統合版で登録」
- 名前を入力すると、botがRCONで
whitelist add 名前(統合版はfwhitelist add 名前)を送る - 誰がどの名前を登録したかは、PostgreSQLのテーブルに保存しておく
- Discordを抜けたら(
on_member_remove)、whitelist removeとkickを送る - botが起動したときは、DBとホワイトリストを照らし合わせて、ずれを直す
botはdiscord.pyで書いた。RCONはライブラリを使わず、struct.pack("<iii", ...) でパケットを組み立てている。ログインとコマンド送信の2種類だけなので、数十行で書けた。
RCONは外に出さない
RCONはサーバーの管理者権限そのものなので、ネットワークに出したくない。
最初はbotを普段のDocker用VMで動かすつもりだった。ただ、その場合はDMZにあるマイクラのVMまでRCONのポートを通す必要があり、ルータのフィルタにも穴を開けることになる。
そこで、botをマイクラと同じVMで動かすことにした。
# サバイバル側:RCONは 127.0.0.1 にだけ公開
ports:
- "127.0.0.1:25575:25575"
# bot側:hostネットワークで動かして 127.0.0.1 につなぐ
network_mode: host
これで、RCONはVMの外からは見えない。ルータの設定も変えなくて済んだ。
ハマったこと①:統合版の登録が「失敗」になる
統合版の人の登録には、Floodgateの fwhitelist を使う。ところが、このコマンドはXboxの名前を調べてから追加するので、結果が非同期で返ってくる。RCONの返事は空になり、登録は成功しているのにbotは失敗と判断してしまう。
対策として、空の返事が来たら少し待ってから whitelist list を送り、.名前(統合版の人は先頭に . が付く)が入っているかを直接確かめるようにした。
ハマったこと②:scpで謎のエラー
botのファイルをPCからVMに送ろうとしたら、こう出た。
scp: Received message too long 1349281121
この数字を16進数にすると 0x506C6561。ASCIIで読むと "Plea" になる。
cloud-initで作ったVMはrootでのログインが禁止されていて、Please login as the user "..." rather than the user "root". と返してくる。scpはこの文章をデータとして読もうとして、壊れていた。普段のユーザーで送って sudo mv すれば済んだ。
開始前の片付け
テスト中にたまった返済や税金の記録は全部消した。ホワイトリストのテーブルだけ残し、ほかは TRUNCATE している。最後に、借金時計の起点を 2026-10-13 00:00:00+09 にした。
いまは開始前なので、借金時計は1,300兆円より少し手前から増えていて、0時ちょうどに1,300兆円になる。
参加はDiscordから:https://discord.gg/FzC4Rp2wG