HN 日本語サマリー

← 一覧へ戻る
プログラミング

Slap ROM Patcher

Slap ROM Patcher (nyuu.page)

19 pointsby apsec1127 コメント

要約

Slapは、ゲームROMファイルにパッチを適用・作成・変換するための、高速で多機能なコマンドラインツールです。HaskellとRustで開発され、クロスプラットフォーム対応、20種類のフォーマットサポート、詳細なエラー報告機能を備えています。特に、パッチの適用における複雑な仕様やエッジケースを正確に処理することに重点を置いています。

全文翻訳

slapコンテキストROMパッチャーは、ゲームファイルを受け取り、それに「パッチ」ファイルを適用します。パッチとは、元のファイルを、翻訳、バグ修正、その他のROMハックのような、それの何らかのバリアントに変えるためのレシピです。慣例として、ゲーム改造の成果物を配布する方法は、元のファイルに適用するためのパッチを作成・配布することです。私はROMパッチャーを作りました。それは良いものです。それは無料/FOSSで、マルチプラットフォーム対応、20のフォーマットをサポートし、キュートで、高速で、小さなパッチを作成します。私はCLIツールが見つからなかったので、Linuxで利用可能で、私が気にかけていた、FXPakを準備するために必要なパッチを適用するのに役立つものが見つからなかったので、それを構築しました。そのため、一部はスクリプトでうまく動作するように構築されています。しかし、それは非常に多弁でもあります。それはあらゆる種類のもののための構造化されたエラー/警告/観察を持っています。それはパッチについて何も仮定しません。無効なものでない限り、何でもうまく処理できると私はかなり確信しています。何かが不正な形式であるか、または一貫性があるが驚くべきことをしようとしている場合、slapは正確に何がどこで起こっているかを伝えます。試してみてください:CLIバージョン、Webバージョン。それはHaskellとRustで書かれており、ブラウザでうまく動作させるのは興味深いことでした。それは6つの動詞を知っています:apply — パッチ + オリジナルROM → 変更されたROM create — 2つのROM → パッチ undo — パッチ + 変更されたROM → オリジナルROM convert — あるフォーマットのパッチ → 別のフォーマットのパッチ explain — パッチ → それが何をするかの人間が読める説明 info — パッチ → そのメタデータ付録の正確性現実的に存在する可能性のあるほぼすべてのパッチについて、「それを適用できる」というのはもちろん当然のことです。しかし、許容されるものの外縁は何でしょうか?各フォーマットについて、「プロパティX」について尋ねる必要がありました:プロパティXは「仕様」のものですか?アプリケーション依存の気まぐれなものですか?ワイヤー機能ですが、「仕様」の一部ではないものですか?いくつか:整形式のIPSパッチとは何ですか?レコードは重複できますか?それらは非単調にできますか?両方の答えが「はい」の場合、これは最初に思われたよりも適用が難しくなります。切り捨てマーカーが、入力ファイルよりも大きいサイズへの「切り捨て」を指示している場合、それを尊重することはどういう意味ですか?IPSは16MiBを超えてアドレス指定できないため、ファイルの先頭のみを変更するという奇妙なエッジケースを考慮しない場合:IPSは16MiBまでのファイルへの変更しか記述できません。おおよそ。それは16MiB先を見ることができませんが、範囲内で始まるがその点を過ぎて、16MiBを超えて書き込むレコードを記述できます。これは一貫性があり、予測可能な結果をもたらし、非常に奇妙です。「仕様内」ですか?もちろん、私たちはこれらを適用しますが、それらを作成することに同意しますか?EBPはJSONメタデータをサポートしており、4つの文字列を格納するために使用します。表現力は、実際に行われていることよりもはるかに大きいです。文字列以外に何か存在するものがすべて間違っている場合、「仕様」とは何ですか?それとも逆ですか:任意の無限ネスト?少なくともUTF-8でなければならないと判断できますか?NINJA2には、入力ROMが「正規形」(インターリーブ解除、ヘッダーなし、N64の場合はz64バイト順など)になっていない場合、パッチャーはその形にするべきであるというクールな「正規化」機能があります。パッチが正規化手順fooを適用するように指示し、パッチャーが手順fooを知らない場合(これは実際にはこじつけではありません)、適用を拒否します。問題は、このフォーマットはチェックサムも格納することです。入力の。チェックサムは、その入力の正規化された形式に対するものです。これはあまりにも保守的だと思います。放棄する前に、入力ファイルが期待される形状になっているかどうかを確認すべきです。私のツールにそれを実行させることができますか、それともそれは私が「抱擁/拡張/消滅」をしていることですか?BPSは「出力の他の部分から何かをコピーする」ことを許可するようです。これは一貫性がありますか、それともありませんか?PPF3はファイルサイズを追跡せず、undoを許可します。ワイヤーは成長を記述できますが、undoが不整合になるような方法です。オリジナルのツールは成長や縮小をブロックすることを意図しているように見えますが、機能しなかったと思われます。ユーザーがundoを搭載したサイズ変更PPF3を作成した場合、どうすればよいですか?ユーザーがPPF3のundo機能を使用したい場合、フォーマット構造上の理由から、ユーザーがundoによる切り捨てを試みていることを検出することは不可能です。そして、など。作成時には、私たちは保守的です:どんなツールでもうまく適用できるものを発行します。適用時には、各フォーマットの「表現範囲」全体をサポートしようとしました。これを行うということは、「線」がどこにあるかを理解することでした。これには、何かがどのように間違っているかを考えることに多くの時間が費やされました。例えば、ワイヤーが一貫性のない指示を表現できることです。その時間の大部分は、パッチが不正な形式になる可能性のあるすべての方法がその名前で呼ばれるようにするために費やされました。興味があれば、私たちが注意していることの種類については、Error.hs、ApplyError.hs、およびVCDIFF.hsを参照してください。テキストエンコーディングの問題一部のフォーマットはテキストメタデータを格納できます。私は、これらの少なくとも一部がASCIIのみであるという証拠を見つけることを期待して入りました。そうではありませんでした!私たちはUTF-8を出力し、それがすべてのケースで「間違っていない」とかなり確信しています。私たちがよく見る2つのことは、「このフォーマットでは、ルールはUTF-8を使用すること」(素晴らしい!)または「このフォーマットでは、ルールは「システムコードページ」を使用すること」(うわー、何?)です。後者はまだUTF-8を許可します:最新のシステムでは、UTF-8はシステムコードページです。読み取り/表示側では、より複雑です。UTF-8がパッチの読み取り方法でない場合に備えて、多くの代替デコードオプションを提供します。デコード/読み取りするものを保護/サニタイズします。いくつかのフォーマットには、任意のデータ用のメタデータフィールドがあります。任意のテキストではなく、任意のデータです。実際には、これらのフィールドが使用されている場合、テキストを格納するために使用されています。そのため、これらのフィールドを通常の表示およびフォーマット変換中の保存メカニズムからファイアウォールするのではなく、疑わしい埋め込みファイルから制御文字の多くを読み取ってから処理したくありません。実際に行っていること:すべて表示し、何も処理しない。印刷不可能なコードポイントはエスケープされて表示され(ビープ音ではなく<U+0007>)、選択したエンコーディングがデコードできないバイトシーケンスはU+FFFDになり、警告が表示されます。ベンチマークを明確にするためにCLIテーブルのすべての数値には、私たちのものを含むプロセスの起動が含まれています。最小のレースは、パッチ適用ではなく、10〜25ミリ秒の実行と実行時間のフロアによって決定されます。いくつかのテーブルがあります。これらはリポジトリのベンチマークから取得されており、あなたは(原則として)自分で実行できます。4MiB GBC ROM、16MiB GBA ROM、64MiB N64 ROM、520MiBディスクイメージの4つの前後ペアがあります。参照ツールをスクリプト化する良い方法がある各フォーマットについて、各ツールは参照ペアからパッチを作成し、各ツールが適用します。これらは時間測定されており、時間はウォームアップ実行の中央値です。すべての出力は、その時間がカウントされる前に、参照ペアに対してバイトごとにチェックされます。各セルには、slap / referenceと表示されます。15秒を超えて実行されたものはすべて15秒+と表示されます。空白のセルは、そのサイズでベンチマークされなかったペアリングです。IPSとEBPは16MiBで上限に達するためです。A — は、実行が行われ、測定するものが何も生成されなかったことを意味します。ppf3は、両側でundoデータオフと比較されます。参照ツールの独自のモードです。作成時間ペアからパッチを作成する時間、slap / referenceフォーマット / reference 4MiB 16MiB 64MiB 520MiB ips / flips 18ms / 12ms 9ms / 21ms ips32 / sips 15ms / 8ms 11ms / 17ms 38ms / 68ms 150ms / 413ms ups / goUps 9ms / 12ms 11ms / 24ms 44ms / 99ms 198ms / 588ms bps / flips 57ms / 327ms 103ms / 1.29s 1.55s / 11.94s 1.88s / 15s+ ppf3 / makeppf3 11ms / 10ms 19ms / 14ms 74ms / 57ms 487ms / 333ms ninja1 / ninjaPhp 17ms / 41ms 45ms / 53ms 130ms / 241ms ninja2 / ninja2Php 19ms / 145ms 50ms / 103ms 204ms / 685ms 1.47s / 1.59s gdiff / javaxdelta 18ms / 136ms 12ms / 249ms 239ms / 1.27s 733ms / 10.76s bsdiff / bsdiff 74ms / 560ms 110ms / 2.65s 682ms / 14.79s 3.57s / 15s+ xdelta1 / xdelta1 44ms / 41ms 45ms / 49ms 386ms / 270ms 1.62s / 1.33s xdelta3 / xdelta3 76ms / 47ms 21ms / 34ms 398ms / 383ms 596ms / 326ms 作成されたパッチ自体、slap / referenceフォーマット / reference 4MiB 16MiB