はじめに
③の続きです
リプレイファイルの解析
リプレイファイルを上げただけでそのプレイ内容を理解するにはリプレイファイルの構造を理解し解析出来なければならない。
旧ロイヤルフレアは alcoscore.cgi
で全てを賄っていたと先に話したが、 alcoscore.cgi
はリプレイを解析するための ALCOReplay.py
というPythonファイルをimportし、そのファイル内で実装されている解析クラスを呼び出すことでリプレイ解析を行っていた。
今回の開発にて旧ロイヤルフレアの解析クラスはとても参考になった。しかしそのまま移植しようにもPythonの記法が古く、バリデーションもせず全てを受け入れる1ものであった。
そのため旧ロイヤルフレアのコードを参考にしつつも、どのような構成のファイルをどのように解析しているのか理解してから、モダンに書き換えるため手を加えようと挑んだ。
東方関連のリプレイファイル構成
東方のリプレイファイルは自機の操作シーケンスや乱数のシード値、そしてプレイのメタデータが入っている。
具体的にどのような構成になっているかというと以下の通りである。2
伝家の宝刀stirlingバイナリエディタを使用して解析する。
左側がバイナリデータで右側がそのバイナリデータをShift-JISデコードした結果である。
最初の4バイトはいわゆるマジックナンバーである。黄昏酒場なら al1r
が入る
飛んで 000C
番地 から2バイトを使って 66 9C
と書かれている。これはリトルエンディアンで 9C66
という値を示していてメタデータが 9C66
番地から始まることを表している。
スクロールして実際に 9C66
へ行ってみるとここから USER
という読める文字が書かれていることが分かる。
0D 0A
が CRLF
でいわゆる改行を表すということを抑えたうえで 9C66
から1行分読んでみると USER{なんか空白}リプレイファイル情報
となる。これは黄昏酒場なので何も書かれていないがその他東方作品では作品名が書かれていることがある。
東方風神録と入っていたり弾幕アマノジャクと入っていたりする。ダブルスポイラーが文花帖と書いてあってth095の文花帖と区別がつかない…
その後はキーバリュー形式でデータが入っている。キーとバリューはスペース(20
)で区切られている。バリューの末尾に CRLF
で改行が入っていて、一行ごとにキーバリューがある。
ここで特筆すべきは日付の年が下二桁表記で入っている3ことである。うーんこの。
これさえ分かればサクサク組める。パース時にpydanticのBaseModelを使用してバリデーションを行い、不適切なデータならエラーを返すようにした。
ただしこのメタデータはあくまでIT意識の高いプレイヤーのために作成しているものであって、このメタデータを変更しても別の領域に東方が読む用のメタデータが保存されているらしく、ゲーム画面上では変更されない。
マジックナンバー
普通の人間は拡張子を使って、『最後に.pngってついてるということは画像ファイルだな!』と判断しているが、実はファイルの中にも先頭にファイルフォーマットが書かれていることがある。例えば png
ならUTF-8デコードするとバイナリデータの先頭に .PNG
と書かれている。
同様に東方のリプレイファイルでもマジックナンバーが設定されており黄昏酒場のリプレイファイルなら必ず先頭に al1r
と書かれている。
このマジックナンバーには規則性があり、th095の文花帖以降では東方の t
とナンバリング、そして製品版か体験版かの情報が入る。4
例えば東方風神録製品版であればth10なので t10r
と入る。製品版、つまり release
版なので末尾は r
である。
対して東方虹龍洞体験版なら trial
なので t18t
となる。5
次回
リプレイ解析以外の内部処理を作成していく。
おまけ 花映塚以前のリプレイファイル
th09花映塚以前のマジックナンバーは T9RP
などの T
,ナンバリング, RP
6 で表される。
th09花映塚はキーバリュー形式で保管されているが区切り文字が 09 09
の水平タブ2文字である。
それより前の永夜抄以前はマジックナンバーこそ同じだが解読できる形式ではなくよくわからなかった。
いつか3部作のリプレイを収集するときに頑張ることにする。
参考文献
-
旧ロイヤルフレアのリプレイアップローダを昔使用した事がある人なら分かるかもしれないが、東方新作が出た直後にリプレイを上げると作品名こそでないもののスコア等の記録が解析出来た状態で上がっていたのを覚えていないだろうか?
あれはこの後説明するマジックナンバーの解析に失敗してもパースを続行しメタデータを取得していたからである。
幻想郷は全てを受け入れるのである。それはそれは残酷な話なのである。 ↩ -
黄昏酒場823万円(全国1位)のリプレイファイルを参照した。 ↩
-
つまり2100年に作成されたリプレイは2000年に作成されたプレイと判別がつかないということである。
ZUNは2000年問題から何を学んだんだ…?
と思ったが親切心からリプレイファイルのデータ量を2バイト分圧縮していただいているということである。ZUNに感謝、アーメン。 ↩ -
つまり
al1r
はalcostg
の1
作目のrelease
版ってこと…?
2作目期待していいんですか…?? ↩ -
この流れで行くと東方天空璋体験版は
t16t
となりそうだが、実際にはt16r
となっている。ただしメタデータ開始行にUSER{空白}東方天星璋
と書かれるので多分天空璋体験版自体が全体的に手抜きだったからだと思われる。ZUNは2014年に第一子出産で天空璋は2016年の作品なので子育てに忙しすぎたのかもしれない。 ↩ -
RePlay
のRP
? ↩