基本的な背景
スプラトゥーン 2 ではGameRandomSeed
という値をゲストに送ることで、ゲーム内容を同期しているということは何度も解説しているのですが、今回もまた大雑把に解説しようと思います。
以下、サーモンランのバイトを開始したときの主なプロトコルの内容です。
- ホストが
GetGameRandomSeed
を実行し、GameRandomSeed
の値を取得する - ホストがバイト開始時に
GameRandomSeed
を含むパラメータをPacketSeqEventCoopSetting()
を呼び出してゲストに送信する - ゲストが
GameRandomSeed
からゲーム内容を計算する - ゲームを開始する
このとき大事なのはホストが送っているデータはstageId
, dangerRate
, GameRandomSeed
, bgmId
, weaponId
, color
の 6 つのパラメータだけだということです。
どんなゲーム内容になるかはGameRandomSeed
から計算するので、送る必要がないということですね。
よって、パッチをあててGameRandomSeed
の値を強制的に変更してゲストに送信することで任意のゲーム内容を再現することができるというわけです。
で、GameRandomSeed
によって計算されるゲーム内容をScenario
と呼ぶことにします。
Scenario
とは
ゲーム内容であるScenario
は以下のデータを含みます。
- バイト種類
- 「いつものバイト」または「プライベート」
- 選択されたブキ
- クマサン印のレアブキ候補
- ステージ ID
- オカシラシャケ ID
- キケン度
- オカシラメーター
- プライベートでは常に 0 が入っています
- ランダムシード
GameRandomSeed
から生成される 4 つのランダムシード
- シナリオコード
- タイムスタンプ
- アプリバージョン
- シーズン ID
- 有効かどうかのチェックフラグ
つまり、前作と同じくシード値が保存されているだけで実際のゲームの内容は保存されていません。よって、ゲームのアップデートでGameRandomSeed
からランダムシードを計算するアルゴリズムまたはランダムシードからScenario
を計算するアルゴリズムに変更があったとしても問題のないようになっています。
現時点ではこれらを計算するアルゴリズムは未解析です
これらのデータはsave.dat
に保存されており、復号することで全ての値を書き換えることが出来ます。
解析することで何ができるか
- キケン度の変更
- 自分が実際に遊びたいキケン度に書き換えることが出来ます
- 選択されたブキの変更
- プライベートバイトの場合はプレイヤーが選択したブキがデフォルト値として入っていますが、これを書き換えることが出来ます。プライベートバイトではデフォルトでブキが選択されていても変更できるので意味がないように思えますが、クマサン印のレアブキに変更することもできると思われます。
- レアブキ枠の変更
- プライベートバイトではレアブキ枠は 0 になっておりクマサン印のブキはランダムで出現しないようになっているのですが、それを書き換えることができます
- ステージの変更
- 好きなステージに変更できます
- オカシラメーターの変更
- プライベートバイトであってもオカシラシャケを出現させられますし、本来オカシラシャケが出現するシナリオコードであっても出現しないように出来ます
- オカシラシャケの変更
- 現在はヨコヅナしか実装されていませんが、将来的に変更することができます
- ランダムシード
- 好きなバイトを発生させられるように変更できます
というわけで、実質的になんでもでき(実行することでゲームが正常に動作するかは別として)るので前作でのシード固定とほぼ同等の汎用性があります。
ちょっと細かい話になるのですが、シード固定では
2^32=4294967296
通りのパターンしか再現できず、今作も同じような仕組みを採用していると思われるのですが、シナリオコードで共有されるのがGameRandomSeed
ではなく 4 つのRandomSeed
のため、実質的に2^(32*4)=340282366920938463463374607431768211456
通りの莫大な組み合わせを表現できる可能性があるのでスプラ 3 の方が自由度は高いかもしれません。
シナリオコード
スプラトゥーン 3 ではシナリオコードと呼ばれるコードを利用することで通常のバイトやプライベートバイトで遊んだ内容を他の人と共有できるシステムが実装されています。
同じゲーム内容を再現できるので、シード値の情報がシナリオコードに含まれていることは明らかなのですが、シナリオコードとは実際に何なのかを解説しようと思います。
シナリオコードの仕様
シナリオコードには実はScenario
に関する情報は全く含まれていません。では、なぜシナリオコードを共有することでScenario
を共有できるのでしょうか?
それは以下に示すように NPLN サーバーと通信することで、サーバーに登録されているScenario
をダウンロードするような仕組みになっているためです。
シナリオ登録
クマサン商会内の端末でシナリオコードを保存するを実行するとnn.npln.toyohr.v1.CoopScenario/RegisterDocument
に対してScenario
を送信します。
受け取ったサーバーはScenario
を保存してランダムに生成されたシナリオコードを返します。
よって、シナリオコードだけではScenario
の中身を計算することは出来ません。
シナリオ取得
クマサン商会内の端末でシナリオコードを入力するとnn.npln.toyohr.v1.CoopScenario/ResolveCoopScenarioCode
にアクセスして、送信されたシナリオコードに対応するScenario
を返します。
データを受け取ったニンテンドースイッチはそのデータをsave.dat
に書き込んで保存します。
よって、適当にシナリオコードを入力しても「そんなコードに対応するScenario
は保存されていない」と返ってきます。誰も登録していないシナリオコードは使えないわけです。その証拠に、ニンテンドーネットワークから隔離されているイカッチャではクマサン商会の端末からシナリオコード取得・登録をすることはできずsave.dat
に保存されているシナリオコードだけが利用可能になっています。
よくある疑問
シナリオコード解析
先述したように、シナリオコードからScenario
を計算することもScenario
からシナリオコードを計算することも出来ません。これらの値はに NPLN サーバーだけが発行して紐付けられる値だからです。
シナリオコード生成
では、任意のScenario
を送信してシナリオコードを発行させることはできるかということになりますが、恐らくできます。ただし、存在しない組み合わせなどをサーバーに送信する行為は威力業務妨害になる恐れがあります。また、NPLN サーバーとの通信では固有 ID を送信する必要があるため、本体の認証情報を使って非正規クライアントでデータを送った時点で本体が BAN されると思われます。
任意のScenario
をサーバーに送ってシナリオコードを取得する方法は現実的に不可能と言って良いでしょう。
利用方法について
シナリオコードを生成することは出来ないので、正規のシナリオコードで取得したScenario
の中身を書き換える方法が考えられます。
ただし、Scenario
はsave.dat
に書き込まれているためオンラインと通信できるニンテンドースイッチでこれを実行するとやはり威力業務妨害になると思われますし、BAN される可能性が非常に高いです。よって、Ryujinx や yuzu などのエミュレータないしはオンラインに繋がらないように対策した EmuMMC 上で実行することになります。
また、save.dat
の書き換えにあたって本体からsave.dat
を抜き出す必要があるので未対策のニンテンドースイッチが必要になります。
改造機でできるようになると思われること
save.dat
書き換え
メリット
- 任意の
Scenario
を無制限にセーブデータに保存できる - 特別なソフトウェアを必要とせず、シナリオコードを切り替えるだけで実質的にシード値を変更できる
save.dat
に書き込まれているので、一度書き込めば CFW で起動する必要がない
デメリット
save.dat
に書き込まれているので、OFW でも実行できてしまう- ニンテンドーネットワークから完全に隔絶させておかないと常に BAN の可能性がある
- 任意の
Scenario
を再現するシード値を計算する Ocean Modifier のような使い方は出来ない - データの追加にはいちいち
save.dat
を書き換える必要がある- そんなに面倒ではないがパッチを単に当てるよりはめんどくさい
パッチ方式
従来と同じように IPSwitch などでバイナリにパッチをあてる方式
メリット
- LFW が有効でないと動作しないので 90DNS が有効な EmuMMC で使えば安全
- SD カード内のテキストファイルを書き換えるだけでデータ追加ができる
デメリット
- Ocean Modifier のようなツールがないと書き換えにいちいち再起動が必要でめんどくさい
非改造機でできるようになると思われること
非改造機では直接バイト内容を書き換えることはできませんが、書き換えられたコードを持っている本体と通信することで同じように遊べると思います。
前作との違い
前作は単にシード値しか保存していなかったのですが、今作は多くのパラメータが保存されているため、追加で以下の機能が使える可能性があります。
- 非改造機でクマサン印のレアブキの使用(デフォルトで選択)
- WAVE3 を通して常に同じブキが支給されます
- 非改造機でクマサン印のレアブキの支給(ランダム枠で支給)
- WAVE ごとにランダムにブキが支給され、レア枠でクマブキが支給されます
ランダムブキが使えたら面白いな、という気はするのですがまだ試せていないのでわかりません。
LanPlay
改造機がホストになる場合、ゲストとして指定されたScenario
で遊ぶことができます。イカッチャで遊んだ内容は保存されないので、そのバイトからシナリオコードを発行することは不可能です。
よって、先述した「存在しないScenario
からシナリオコードを発行して BAN される」可能性はありません。あるとすれば「何らかの痕跡がsava.dat
に保存されている」ということですがそれが本体を改造して書き換えられたものなのか、改造した端末と通信して書き換えられたものかの判断がつかないため、BAN されることはないと思われます。
こちらは完全にローカル環境内で完結しているので任天堂の規約及び法律に反しないと思われます。
save.dat
の書き換え
以下で述べるのは技術的に可能かどうかという内容です。
実際にやると法律に反するものやニンテンドーネットワーク利用規約に違反し、BAN される可能性がある行為が含まれますので絶対に実行しないでください。
非改造機ではsave.dat
の書き換えは出来ませんが、スプラトゥーン 3 はセーブデータがサーバー管理になっているため未対策機で CFW 状態でsave.dat
を書き換えてから OFW に戻してセーブデータのバックアップを取り、非改造機でサーバーから読み込めば書き換えられたシナリオを取得することは可能だと思われます。
とはいえ、流石にアップロードされたデータの整合性チェックなどは行っていると思うのでやると BAN されると思います。
これはニンテンドーネットワークを経由するので絶対に実行しないでください。
最後に
シナリオを完全に書き換えられるので本来はプライベートバイトでシナリオを利用しているのに一見すると通常のバイトのように偽装できたり、とにかくいろいろと何でも出来てしまいます。
不正な使い方をする人がでてくることは容易に想像がつくので、完成してもリリースする予定はありません。
記事は以上。