Quantumleap
3211 words
16 minutes
スプラトゥーン3におけるシナリオプロトコル解説

基本的な背景#

スプラトゥーン 2 ではGameRandomSeedという値をゲストに送ることで、ゲーム内容を同期しているということは何度も解説しているのですが、今回もまた大雑把に解説しようと思います。

以下、サーモンランのバイトを開始したときの主なプロトコルの内容です。

  1. ホストがGetGameRandomSeedを実行し、GameRandomSeedの値を取得する
  2. ホストがバイト開始時にGameRandomSeedを含むパラメータをPacketSeqEventCoopSetting()を呼び出してゲストに送信する
  3. ゲストがGameRandomSeedからゲーム内容を計算する
  4. ゲームを開始する

このとき大事なのはホストが送っているデータは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の中身を書き換える方法が考えられます。

ただし、Scenariosave.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 されると思います。

これはニンテンドーネットワークを経由するので絶対に実行しないでください。

最後に#

シナリオを完全に書き換えられるので本来はプライベートバイトでシナリオを利用しているのに一見すると通常のバイトのように偽装できたり、とにかくいろいろと何でも出来てしまいます。

不正な使い方をする人がでてくることは容易に想像がつくので、完成してもリリースする予定はありません。

記事は以上。

スプラトゥーン3におけるシナリオプロトコル解説
https://fuwari.vercel.app/posts/2023/02/scenario/
Author
tkgling
Published at
2023-02-04