GS2-Version

バージョンチェック機能

アプリケーションのバージョンや、追加アセットのバージョン、利用規約に同意しているバージョンなどを判定する機能を提供します。

バージョンチェックを通過した際に、新しい一時的なGS2のクライアントID/シークレットを発行できます。

この機能を利用することで、アプリ内に組み込んだGS2のクライアントID/シークレットは、ログインを行いバージョンチェックを行うAPIしか呼び出す権限を持たず、バージョンチェックを通過した後で、実際にゲームをプレイするのに十分な権限のクライアントID/シークレットを受け取れるようにできます。

バージョンモデル

バージョンチェックには複数の項目を設定でき、全てのバージョンチェックが通過した場合にのみ、チェックを通過できます。

バージョンモデルには2種類あり「アプリケーションが送信してきたバージョンを元にバージョン判定をする」「ログイン中のユーザーが過去に同意した規約のバージョンを元にバージョン判定をする」ことができます。
前者を「パッシブバージョンチェック」後者を「アクティブバージョンチェック」と呼びます。

バージョン番号のフォーマット

{major}.{minor}.{micro}
形式のバージョン番号を利用でき、各項目には整数値が指定できます。

パッシブバージョンチェック

ゲームの実行バイナリや、ゲームがダウンロードしたアセットごとのバージョンチェックに利用します。

マスターデータでは、バージョンモデルごとに「警告を発するバージョンの閾値」「エラーとするバージョンの閾値」を設定できます。
警告対象となった場合は、より新しいバージョンがプラットフォーマーが提供するアプリ配信サイトでダウンロードできるが、このままゲームを開始することもできるような状況で利用します。
エラーは文字通り、エラーを発生させバージョンチェックが失敗し、ゲームを開始することはできません。

パッシブバージョンチェックのバージョン番号の設定の例

targetVersionにはアプリのバージョン番号等を設定し、マスターデータ側のwarningVersionとerrorVersionを比較します。

targetVersionerrorVersion判定
1.0.11.0.0通過
1.0.01.0.0エラー
0.9.01.0.0エラー

targetVersion が errorVersionよりも大きければ、通過が可能になります。

targetVersionwarningVersion判定
1.0.11.0.0通過
1.0.01.0.0警告
0.9.01.0.0警告

targetVersion が warningVersionよりも大きければ、そのまま通過、targetVersion が warningVersionと同じか小さければ、バージョンアップを促すが通過が可能なバージョンとして扱うことが可能です。

バージョン署名

ゲームが送信してきたバージョン値は信頼できる情報ではありません。そのため、バージョン番号に署名を付与することができます。
署名はバージョン番号ごとに GS2 の API を通して事前に計算する必要があります。

バージョン番号とともに署名も送信するようにし、バージョンモデルのプロパティに署名を要求するように設定することで署名のないリクエストや、バージョン番号と署名が一致しないリクエストをエラーとすることができます。

アクティブバージョンチェック

利用規約など、プレイヤーが同意した規約のバージョンを記録しておき、現在の利用規約に同意済みかを判定するために利用します。

マスターデータには現在配信中の利用規約のバージョン番号を定義し、プレイヤーが同意APIを呼び出すとその値をデータベースに記録します。
その後バージョンチェック処理では、過去に記録したバージョン情報をデータベースから取り出し、その値とマスターデータで定義された閾値の比較を行います。

アクティブバージョンチェックのバージョン番号の設定の例

マスターデータのcurrentVersionには規約のバージョン番号等を設定し、errorVersionと比較します。

GS2-Versionに記録されている承認バージョン番号errorVersion判定
承認されたバージョン番号なし1.0.0エラー
0.9.0で承認1.0.0エラー
1.0.0で承認1.0.0エラー
1.0.1で承認1.0.0通過

errorVersionに対して currentVersionが大きいバージョン番号に設定されていて、APIを呼び出し承認していれば、通過が可能という判定になります。

実装例

バージョンチェックを実行

    var result = await gs2.Version.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Checker(
    ).CheckVersionAsync(
        targetVersions: new [] {
            new Gs2.Unity.Gs2Version.Model.EzTargetVersion
            {
                VersionName = "app",
                Version = new Gs2.Unity.Gs2Version.Model.EzVersion
                {
                    Major = 1,
                    Minor = 2,
                    Micro = 3,
                },
            },
            new Gs2.Unity.Gs2Version.Model.EzTargetVersion
            {
                VersionName = "asset",
                Version = new Gs2.Unity.Gs2Version.Model.EzVersion
                {
                    Major = 1,
                    Minor = 2,
                    Micro = 3,
                },
            },
        }
    );
    var projectToken = result.ProjectToken;
    var warnings = result.Warnings;
    var errors = result.Errors;
    const auto Future = Gs2->Version->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        AccessToken
    )->Checker(
    )->CheckVersion(
        []
        {
            const auto v = MakeShared<TArray<TSharedPtr<Gs2::Version::Model::FTargetVersion>>>();
            v->Add({'versionName': 'app', 'version': {'major': 1, 'minor': 2, 'micro': 3}});
            v->Add({'versionName': 'asset', 'version': {'major': 1, 'minor': 2, 'micro': 3}});
            return v;
        }() // targetVersions
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError()) return false;
    const auto ProjectToken = Result->ProjectToken;
    const auto Warnings = Result->Warnings;
    const auto Errors = Result->Errors;

アクティブバージョンチェックに同意

    var result = await gs2.Version.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).AcceptVersion(
        versionName: "eula"
    ).AcceptAsync(
    );
    const auto Future = Gs2->Version->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        AccessToken
    )->AcceptVersion(
        "eula" // versionName
    )->Accept(
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError()) return false;

    // obtain changed values / result values
    const auto Future2 = Future->GetTask().Result()->Model();
    Future2->StartSynchronousTask();
    if (Future2->GetTask().IsError()) return false;
    const auto Result = Future2->GetTask().Result();

より実践的な情報

バージョン更新の運用手順

バージョン更新時に、一度プレイ中のプレイヤーを全員追い出して、最新のバージョンでのみ遊べるようにしたいことがあります。
GS2-Version では新規ログインを止めることはできますが、すでにログイン済みのプレイヤーに対してはバージョンチェック後に一時的に発行されるクライアントID/クライアントシークレット の有効期限が切れるまではアクセスし続けることが可能です。

そこで、全てのプレイヤーの GS2-Gateway が提供している通知用の常時接続セッションを切断し、ゲームはセッションの切断をハンドリングすると、バージョンチェック後に再接続処理を行うようにします。
バージョンチェックに失敗した場合は、そのままバージョンアップシーケンスに入ります。

これで、バージョンを更新して全てのプレイ中のプレイヤーにもバージョンチェックを強制することができます。

詳細なリファレンス