コンテンツにスキップ

ログイン・ログアウト

認証におけるログインは、以下のステップで構成されています。

Note
  • SDK 4.7.0 未満のバージョンは Helper をサポートしていません。既存のログインアプリケーションメソッドについては、[こちら]を参照してください。
  • AuthV4.Helper の説明については、認証 ページを参照してください。

ログイン

認証におけるログインは、以下のステップで構成されています。

  1. 自動ログインと暗黙のログイン
  2. 明示的ログイン
  3. デバイス上のIdPアカウントのログイン確認
  4. ゲストログイン

Authv4Helperは、ログインに関連する一連のプロセスを実行するクラスであり、応答値に基づいて適切な画面に移動するように設定されています。 ログインを設定する際は、以下のポイントを参照してください。

Note

Appleは、iOSエンタープライズビルドにおいてApple Game Centerおよびアプリ内購入をサポートしていません。したがって、Apple Game Centerアカウントを使用した暗黙的なログインはiOSエンタープライズビルドで使用できず、明示的なログインでもApple Game Centerを使用することはできません。iOSエンタープライズ向けにビルドする際は、コンソールのログインタイプにApple Game Centerを含めてはいけません。

Note
Note
  • 中国では、Google Playゲームは使用できないため、Androidでの暗黙のログインは使用できません。
  • 中国では、Facebookは使用できないため、FacebookはIdPリストに含まれていません。
  • 中国では、実名認証を受けたユーザーのみがサービスをチャージまたは利用できるため(2017年5月1日から有効)、中国のIPからのログインに対するゲストログインはIdPリストに含まれていません。
Note

iOSでは、Apple Game Centerのログインがキャンセルされてもログイン画面は表示されません。したがって、ガイダンスメッセージはSDKがAuthV4HelperクラスのshowGameCenterLoginCancelDialog()メソッドを呼び出すことによって直接表示されるか、ゲームによって表示されることが選択されます。ユーザーにGame Centerアカウントを再接続するためのメッセージを提供したい場合は、AuthV4.signIn(AuthV4.ProviderType.APPLE, ...)およびAuthV4.connect(AuthV4.ProviderType.APPLE, ...)のコールバック結果がキャンセルされたときにGame Centerキャンセルガイダンスメッセージを使用してください。

Note

Apple IDでログインしていないデバイスでユーザーがAppleでログインしようとすると、AuthV4SignInAppleUnknownエラーが発生します。このエラーは、AuthV4Helperクラスのconnect()signIn()メソッドを呼び出す過程で発生します こちら を参照してください。Apple IDログインのガイダンスポップアップが自動的に表示されるため、ゲームスタジオは別途ガイダンスポップアップを表示する必要はありません。

ユーザーがApple IDでログインしようとした際に、デバイスがApple IDでログインしていない場合、AuthV4SignInAppleUnknownエラーがAuthV4Helperクラスのconnect()signIn() メソッドを呼び出す過程で発生します。Apple IDログインのガイダンスポップアップが自動的に表示されるため、ゲームスタジオは別途__ポップアップ__を表示する必要はありません。

Note

PC X IdPログインの場合、Xアカウントでのログインは可能ですが、Xログイン画面でのGoogleおよびAppleアカウント統合によるログインはサポートされていません。 GoogleまたはAppleアカウント統合でXにログインするには、まず外部ブラウザでそれぞれのアカウントにログインし、その後ゲーム内でXログインを進める必要があります。
Steam Deck X IdPログインの場合、Xアカウントでのログインのみがサポートされています。

自動ログインと暗黙のログイン

自動ログイン

これは、ユーザーがログイン方法を選択しない場合のログイン方法を指し、iOSでは自動的にApple Game Centerアカウントにリンクし、AndroidではGoogle Play Gamesアカウントにリンクします。自動ログインを実装し、自動ログインが失敗した場合には暗黙のログインを行います。

iOS環境で自動ログインを使用するには、Game Center Entitlementを追加する必要があります。これは、'Apple GameCenter'依存関係をチェックすると、UnityがUnity PostProcessを通じて自動的に追加します。iOS Nativeでは、XcodeがGame Center Entitlementを自動的に追加します。

オフラインモード

Hive SDK v4 23.1.0 以降では、アプリが起動したときにユーザーのデバイスがネットワークに接続されていなくても、自動ログイン機能(AuthV4.signInProviderType.AUTO を使用、または AuthV4.Helper.signIn)を提供できます。オフラインモードを使用するには、以下の指示に従ってください。

  1. 明示的、暗黙的、ゲスト、またはカスタムログインのために、アプリをオンラインで正常に実行し、playerIdplayerTokenを受け取っている必要があります。

アプリ開発者の視点から見ると、AuthV4.Helper.signInAuthV4.showSignIn、またはAuthV4.signInWithAuthKeyをオンラインで少なくとも一度成功裏に実行する必要があります。そうしないと、コールバックを介してplayerIdplayerTokenを受け取ることができません。ユーザーの視点からすると、ユーザーはデバイスがネットワークに接続されている間にアプリに少なくとも一度成功裏にログインしている必要があります。ただし、ユーザーのアカウントが最後のログイン試行時にオンラインで一時停止または制限されていた場合、ユーザーはオフラインモードでもログインできません。

  1. Hive コンソールでオフラインモードを有効にします App Center > プロジェクト管理 > ゲーム詳細 > Hive 製品設定
Note

オフラインモードのAndroid OSデバイスのユーザーに対して暗黙のGoogleサインインを提供するには、次のリンクを参照してください。

Windows環境での自動ログイン

Windows環境でも自動ログインがサポートされており、Hive コンソールアプリセンターで有効/無効を切り替えることができます。ただし、Windowsでの自動ログインはモバイルとは異なる動作をします。以下は、Windowsでの自動ログインの違いです。

  • モバイルでは、ログイン後、ログイン状態は自動ログインによって常に維持されますが、Windowsでは、ユーザーがログインUIのIdPリストの下部に表示される「ログイン状態を保持する」チェックボックスを有効にした場合のみ維持されます。他の状況では、ログイン状態は維持されません。
  • AuthV4Helper.Connectを実行する際、モバイルでは新しいアカウントに切り替えると、新しいアカウントも自動ログイン状態を維持しますが、Windowsでは新しいアカウントに切り替えると、新しいアカウントは自動ログイン状態を維持しません。

インプリシットログイン

  • インプリシットログインフロー

AuthV4.Helper.signInは、PlayerIDの認証トークンキーを使用して自動的にログインしようとします。既存の認証トークンキーがない場合、iOSではApple Game Center、AndroidではGoogle Play Gamesに自動的にログインします。ログインに失敗した場合、応答値に基づいて適切なログイン画面を設定します。

Note

自動ログインを使用するには、Game Center Entitlementを追加する必要があります。「Apple GameCenter」依存関係をチェックした場合、Unity PostProcessを通じて対応するEntitlementが自動的に追加されます。

Note

AuthV4Helperクラスを使用する際

ゲームを起動したユーザーがPGS中に暗黙のログイン試行を拒否した場合、システムはこれを記憶し、以後は暗黙のログインを試みなくなります。プレイヤーセッションが維持されている間に自動ログインが可能であっても、拒否された暗黙のログインの状態を記憶し続けます。この内容はGoogle Play Games Servicesガイドに基づいています。

自動ログインを行う例のコードは以下の通りです。

APIリファレンス: hive.AuthV4.Helper.signIn

// Hive SDKを使用してサインインを試みる (signIn)
AuthV4.Helper.signIn (delegate (ResultAPI result, AuthV4.PlayerInfo playerInfo) {

    if (result.isSuccess()) {
        // ログイン成功
    } else if (result.needExit()) {
        // TODO: アプリ終了機能を実装する
        // 例) Application.Quit();
    } else {
        switch (result.code) {
            case ResultAPI.Code.AuthV4ConflictPlayer:
                // アカウントの競合
                break;
            case ResultAPI.Code.AuthV4HelperImplifiedLoginFail:
                // 暗黙のログインに失敗しました
                // 例) AuthV4.showSignIn(...);
                break;
            default:
  k              // その他の例外
                break;
        }
    }
});
#include "HiveAuthV4.h"

// Hive SDKにログイン(signIn)を試みる
FHiveAuthV4::Helper::SignIn(FHiveAuthV4HelperDelegate::CreateLambda([this](const FHiveResultAPI& Result, const TOptional<FHivePlayerInfo>& PlayerInfo) {
    if (Result.IsSuccess()) {
        // ログイン成功
    } else if (Result.NeedExit()) {
        // TODO: アプリ終了機能を実装する
        // 例) UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit, false);
    } else {
        switch (Result.Code) {
            case FHiveResultAPI::ECode::AuthV4ConflictPlayer:
                // アカウントの競合
                break;
            case FHiveResultAPI::ECode::AuthV4HelperImplifiedLoginFail:
                // 暗黙のログインに失敗
                // 例) FHiveAuthV4::ShowSigIn()
                break;
            default:
                // その他の例外
                break;
        }
    }
}));

APIリファレンス: Auth4::Helper::signIn

// Hive SDKを使用してサインイン(signIn)を試みる
AuthV4::Helper::signIn([=](ResultAPI const & result, std::shared_ptr playerInfo) {

    if (result.isSuccess()) {
        // ログイン成功
    } else if (result.needExit()) {
        // TODO: アプリ終了機能を実装する
        // Cocos2d-xエンジンユーザー向け
        // 例) exit(0);
        // Unrealエンジンユーザー向け
        // 例) UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit, false);
    } else {
        switch (result.code) {
            case ResultAPI::AuthV4ConflictPlayer:
                // アカウントの競合
                break;
            case ResultAPI::AuthV4HelperImplifiedLoginFail:
                // 暗黙のログインに失敗しました
                // 例) AuthV4.showSignIn(...);
                break;
            default:
                break;
        }
    }
});

APIリファレンス: hive.AuthV4.Helper.signIn

// Hive SDKを使用してサインインを試みる
AuthV4.Helper.signIn(object : AuthV4.Helper.AuthV4HelperListener {
    override fun onAuthV4Helper(result: ResultAPI, playerInfo: AuthV4.PlayerInfo?) {
        if (result.isSuccess) {
            // サインイン成功
        } else if (result.needExit()) {
            // TODO: アプリ終了機能を実装する
            // 例) exitProcess(0)
        } else {
            when (result.code) {
                ResultAPI.Code.AuthV4ConflictPlayer -> {
                    // アカウントの競合
                }
                ResultAPI.Code.AuthV4HelperImplifiedLoginFail -> {
                    // 暗黙のログインに失敗
                    // 例) AuthV4.showSignIn(...)
                }
                else -> {
                    // その他の例外状況
                }
            }
        }
    }
})

APIリファレンス: com.hive.AuthV4.Helper.signIn

// Hive SDK AuthV4 認証 UI リクエスト
AuthV4.Helper.signIn(new AuthV4.Helper.AuthV4HelperListener() {
    @Override
    public void onAuthV4Helper(ResultAPI result, PlayerInfo playerInfo) {

        if (result.isSuccess()) {
            // 認証成功
        } else if (result.needExit()) {
            // TODO: アプリ終了機能を実装する
            // 例) System.exit(0);
        } else {
            switch (result.code) {
                case ResultAPI.Code.AuthV4ConflictPlayer:
                    // アカウントの競合
                    break;
                case ResultAPI.Code.AuthV4HelperImplifiedLoginFail:
                    // 暗黙のログインに失敗しました
                    // 例) AuthV4.showSignIn(...);
                    break;
                default:
                    // その他の例外的な状況
                    break;    
            }
        }
    }
});

APIリファレンス: HIVEAuthV4Helper:signIn

// Hive SDK AuthV4 認証 UI リクエスト
AuthV4Interface.helper().signIn { (result, playerInfo) in

    if result.isSuccess() {
        // 認証成功
    } else if result.needExit() {
        // TODO: アプリ終了機能を実装する
        // 例) exit(0)
    } else {
        switch result.getCode() {
            case .authV4ConflictPlayer:
                // アカウントの競合
                break
            case .authV4HelperImplifiedLoginFail:
                // 暗黙のログインに失敗しました
                // 例) AuthV4.showSignIn(...)
                break
            default:
                // その他の例外状況
                break
            }
        }
    }
}

API リファレンス: HIVEAuthV4:signIn

// Hive SDKにサインイン(signIn)しようとしています    
[[HIVEAuthV4 helper] signIn:^(HIVEResultAPI *result, HIVEPlayerInfo *playerInfo) {

    if (result.isSuccess) {
        // ログイン成功 
    }
    else if (result.needExit) {
        // TODO: アプリ終了機能を実装する
        // ex) exit(0);
    }
    else {
        switch (result.code) {
            case kAuthV4ConflictPlayer:
                // アカウントの競合
                break;    
            case kAuthV4HelperImplifiedLoginFail:
                // 暗黙のログインに失敗しました
                // ex) [HIVEAuthV4 showSignIn:^(HIVEResultAPI *result, HIVEPlayerInfo *playerInfo) {
                // // 何かをする...
                // }];
                break;
            default:
                // その他の例外
                break;   
        }
    }
}];

暗黙のログイン動作: モバイル

モバイルの暗黙のログイン(Hive SDK Unity AndroidなどのAndroid/iOSプラットフォーム)(AuthV4.Helper.signIn)は、初回ログイン後に異なるアカウントでログインするとアカウントの競合状況を引き起こし、AuthV4ConflictPlayerの結果コードを返し、最後にログインしたアカウントでログインするかどうかを尋ねるダイアログをユーザーに表示します(AuthV4.Helper.showConflictの実行)。


ただし、Androidモバイル環境における暗黙のGoogleサインインは、以下のように異なる動作をします。


Androidモバイル環境では、Googleサインインの暗黙のログインは、アカウントの競合を引き起こすことなく(AuthV4ConflictPlayer)、成功または失敗のいずれかを返します。他のモバイル環境とは異なります。上の画像では、レガシーサポートGoogle認証は、Androidモバイル環境におけるGoogleサインインの暗黙のログインを指します。

成功したログインの後、ユーザーがIdP統合を試みたり、Googleの実績とリーダーボードを呼び出したりすると、Googleアカウントを選択するためのUIが表示されます(新しいログインセッションが作成されます)。既にログインしているアカウントのPlayerInfoが確認され、新しく選択されたGoogleアカウントがこの情報と異なる場合、アカウントの競合(AuthV4ConflictPlayer)が発生します。この時点で、アカウント競合の状況を処理すれば、新しく選択されたGoogleアカウントでログインできます。


既存のログインセッションがない状況(例えば、アプリが初めてインストールされて実行されるとき)では、Androidモバイル環境におけるGoogleサインインの暗黙的ログインは、状況に応じて以下のように異なる動作をします。

  1. アプリにログインしているGoogleアカウントがAndroid OSデバイスのアカウント設定に存在する状況(GoogleアカウントがAndroid OSデバイスにログインしている状況)
    • Googleアカウントでログインする
  2. アプリにログインしている2つ以上のGoogleアカウントがAndroid OSデバイスのアカウント設定に存在する状況(特定のGoogleアカウントがAndroid OSデバイスにログインしている状況)
    • ログインしているGoogleアカウントの中から選択できるUIを表示する
    • UIからアカウントを選択した後にログインする
    • ユーザーがGoogleアカウントを選択せずにUIを閉じた場合、Android OSデバイスのアカウント設定に存在するすべてのGoogleアカウントのリストを表示するUIを表示する
    • ユーザーがすべてのGoogleアカウントのUIから希望のGoogleアカウントを選択した場合、そのアカウントでログインする
  3. アプリにログインしているGoogleアカウントがない状況
    • Android OSデバイスのアカウント設定に存在するすべてのGoogleアカウントのリストを表示するUIを表示する
    • ユーザーがすべてのGoogleアカウントのUIから希望のGoogleアカウントを選択した場合、そのアカウントでログインする


下の画像は、上記の3つの状況のUI例を示しています。左から、状況1、2、3に対応しています。

Note

Google 認証に関する詳細は、Google Credential Managerを参照してください。

暗黙のログイン動作: PC

PC(Hive SDK Unity WindowsなどのWindowsプラットフォーム)での暗黙のログイン(AuthV4.Helper.signIn)は、初回ログイン後に異なるアカウントでログインする際に、最後にログインしたアカウントで自動的にログインします。アカウントの競合状況は発生しません。

明示的なログイン

明示的なログインとは、ユーザーが認証のためにIdPを選択するプロセスを指します。自動ログインと暗黙的なログインの両方が失敗した場合、ゲームタイトル画面に移動した後にユーザーがタイトルをクリックしたときに明示的なログインが実行されるように実装します。

明示的なログインUIは、Hive SDKによって提供されるUIを使用するか、Hive SDKの初期化が完了した後に返されるIdPのリストを使用してカスタマイズすることができます。UIをカスタマイズする場合は、明示的ログインのカスタマイズセクションを参照してください。

IdPリストは、各国のポリシーに従ってHiveプラットフォームによって管理され、提供されています。例えば、中国では、Google PlayゲームやFacebookはゲストには利用できません。

明示的なログインのスクリーンショット

SDKによって提供されるIdP選択UI

SDKが提供するUIを使用して実装する場合

SDKが提供するUIを使用して明示的なログインを実装するには、showSignIn()メソッドを呼び出してIdPリストUIを起動するだけです。

Note

ユーザーは、SDKによって提供されるIdP選択UIで「X」ボタンを閉じた場合、再度ログインする手段を提供されなければなりません。ユーザーはまだログインしていません。

Note

明示的サインインをカスタマイズするには、以下を参照してください

APIリファレンス: hive.AuthV4.showSignIn

// Hive SDK AuthV4 認証 UI リクエスト
AuthV4.showSignIn((ResultAPI result, AuthV4.PlayerInfo playerInfo)=>{
    if (result.isSuccess()) {
        // 認証成功
        // playerInfo : 認証されたユーザー情報

        // メール情報を取得する例
        foreach (KeyValuePair<AuthV4.ProviderType, AuthV4.ProviderInfo> entry in playerInfo.providerInfoData) {

            AuthV4.ProviderInfo providerInfo = entry.Value;
            if(providerInfo.providerEmail != null && providerInfo.providerEmail != "") {
                string email = providerInfo.providerEmail;
                break;
            }
        }
    }
    else if (result.needExit()) {
        // TODO: アプリの終了機能を実装する
        // e.g.) Application.Quit();
    }
});
#include "HiveAuthV4.h"

// Hive SDK AuthV4 認証 UI リクエスト
FHiveAuthV4::ShowSignIn(FHiveAuthV4OnSignInDelegate::CreateLambda([this](const FHiveResultAPI& Result, const FHivePlayerInfo& PlayerInfo) {
    if (Result.IsSuccess()) {
        // 認証成功 (PlayerInfo: 認証されたユーザー情報) 

        // メール情報を取得する例
        for (const auto& ProviderInfoEntry : PlayerInfo.ProviderInfoData) {
            FHiveProviderInfo ProviderInfo = ProviderInfoEntry.Value;
            FString Email = ProviderInfo.ProviderEmail;
        }
    } else if (Result.NeedExit()) {
        // TODO: アプリの終了機能を実装する
        // 例) UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit, false);
    }
}));

API リファレンス: AuthV4::showSignIn

// Hive SDK AuthV4 認証 UI リクエスト
AuthV4::showSignIn([=](ResultAPI const & result, PlayerInfo const & playerInfo) {
    if (result.isSuccess()) {
        // 認証成功
        // playerInfo: 認証されたユーザー情報

        // メール情報を取得する例
        for(auto it = playerInfo.providerInfoData.begin(); it != playerInfo.providerInfoData.end(); ++it) {
            hive::ProviderInfo providerInfo = it->second;
            if(!providerInfo.providerEmail.empty()) {
                std::string email = providerInfo.providerEmail;
                break;
            }
        }
    }
    else if (result.needExit()) {
        // TODO: アプリ終了機能を実装する
        // Cocos2d-xエンジンユーザー
        // 例) exit(0);
        // Unrealエンジンユーザー
        // 例) UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit, false);
    }
});

APIリファレンス: com.hive.AuthV4.showSignIn

// Hive SDK AuthV4 認証 UI リクエスト
AuthV4.showSignIn(object : AuthV4.AuthV4SignInListener {
    override fun onAuthV4SignIn(result: ResultAPI, playerInfo: AuthV4.PlayerInfo?) {
        if (result.isSuccess) {
            // 認証成功
            // playerInfo: 認証されたユーザー情報

            // メール情報を取得する例
            playerInfo?.let {
                for ((key, value) in it.providerInfoData) {
                    var providerInfo: AuthV4.ProviderInfo = value
                    if(providerInfo.providerEmail.isNotEmpty()) {
                        val email = providerInfo.providerEmail
                        break
                    }
                }
            }
        } else if (result.needExit()) {
            // TODO: アプリ終了機能を実装する
            // 例) exitProcess(0)
        }
    }
})

API リファレンス: com.hive.AuthV4.showSignIn

// Hive SDK AuthV4 認証 UI リクエスト
AuthV4.showSignIn(new AuthV4.AuthV4SignInListener() {
    @Override
    public void onAuthV4SignIn(ResultAPI result, AuthV4.PlayerInfo playerInfo) {

        if (result.isSuccess()) {
            // 認証成功
            // playerInfo: 認証されたユーザー情報

            // メール情報を取得する例
            if(playerInfo != null) {
                for (Map.Entry<AuthV4.ProviderType, AuthV4.ProviderInfo> entry : playerInfo.getProviderInfoData().entrySet()) {
                    AuthV4.ProviderInfo providerInfo = entry.getValue();
                    if (providerInfo.getProviderEmail() != "") {
                        String email = providerInfo.getProviderEmail();
                        break;
                    }
                }
            }
        }
        else if (result.needExit()) {
            // TODO: アプリ終了機能を実装する
            // 例: System.exit(0);
        }
    }
});

APIリファレンス: HIVEAuthV4:showSignIn

var email = String()

// Hive SDK AuthV4 認証 UI リクエスト
AuthV4Interface.showSignIn { (result, playerInfo) in

    if result.isSuccess() {
        // 認証成功
        // playerInfo: 認証されたユーザー情報

        // メール情報を取得する例
        if let playerInfo = playerInfo {
            // providerEmailが存在するproviderInfoを検索する(現在ログインしているプロバイダー)
            for key in playerInfo.providerInfoData.keys {
                if let providerInfo = playerInfo.providerInfoData[key],
                    providerInfo.providerEmail.count > 0 {
                    // providerEmail != ""
                    email = providerInfo.providerEmail
                    break
                }
            }
        }
    } else if result.needExit() {
        // TODO: アプリ終了機能を実装する
        // 例: exit(0)
    }
}

APIリファレンス: HIVEAuthV4:showSignIn

__block NSString* email = @"";

// Hive SDK AuthV4 認証 UI リクエスト
[HIVEAuthV4 showSignIn:^(HIVEResultAPI *result, HIVEPlayerInfo *playerInfo) {

    if([result isSuccess]){
        // 認証成功
        // playerInfo: 認証されたユーザー情報

        // メール情報を取得する例
        if(playerInfo != nil) {
            // 既存のproviderEmail(現在ログインしているプロバイダー)でproviderInfoを検索
            for (NSString* key in playerInfo.providerInfoData.allKeys) {
                HIVEProviderInfo* providerInfo = playerInfo.providerInfoData[key];
                if (providerInfo != nil && providerInfo.providerEmail.length > 0) {
                    // providerEmail != ""
                    email = providerInfo.providerEmail;
                    break;
                }
            }
        }
    } else if ([result needExit]) {
        // TODO: アプリの終了機能を実装
        // 例: exit(0);
    }
}];


既存のログインセッションがない場合(たとえば、アプリがインストールされて初めて実行されるとき)、Androidモバイル環境での明示的なGoogleサインインは、状況に応じて次のように異なる動作をします。

  1. アプリにログインしているGoogleアカウントがAndroid OSデバイスのアカウント設定に存在する状況(GoogleアカウントがAndroid OSデバイスにログインしている状況)
    • 対応するGoogleアカウントでログインする
  2. アプリにログインしている2つ以上のGoogleアカウントがAndroid OSデバイスのアカウント設定に存在する状況(特定のGoogleアカウントがAndroid OSデバイスにログインしている状況)
    • ログインしているGoogleアカウントの中から1つを選択できるUIを表示する
    • UIからアカウントを選択した後にログインする
    • ユーザーがGoogleアカウントを選択せずにUIを閉じた場合、Android OSデバイスのアカウント設定に存在するすべてのGoogleアカウントのリストを表示するUIを表示する
    • ユーザーがすべてのGoogleアカウントのリストUIから希望のGoogleアカウントを選択した場合、そのアカウントでログインする
  3. アプリにログインしているGoogleアカウントがない状況
    • Android OSデバイスのアカウント設定に存在するすべてのGoogleアカウントのリストを表示するUIを表示する
    • ユーザーがすべてのGoogleアカウントのリストUIから希望のGoogleアカウントを選択した場合、そのアカウントでログインする


以下の画像は、上記の3つの状況のUIの例です。左から、それぞれ状況1、2、3に対応しています。

Note

Google 認証に関する詳細情報については、Google Credential Managerを参照してください。

明示的なログインカスタマイズ

明示的なログインのためのカスタマイズ可能なUIは、providerTypeListを使用して実装できます。providerTypeListは、Hive SDKを初期化するためにAuthV4.setup()メソッドを呼び出すときに返されるレスポンスコールバックハンドラーであり、初期化後にAuthV4.Helper.getIDPList()メソッドを呼び出すときにも返されます。この機能は、ゲームUIに応じてログイン画面を表示したり、特定のIdPとの統合を主に公開したりする場合に使用されます。カスタマイズ可能なUIを実装した後は、ユーザーのアクションに基づいて希望するProviderTypeでsignIn()メソッドを呼び出してログインを実装します。

Note
  • ログイン画面に表示されるFacebook統合ボタンのみを示すUI例のスクリーンショット

以下は、ユーザーがカスタマイズされた明示的なログインUIでGoogleログインを選択する状況を想定した例のソースコードです。

APIリファレンス: hive.AuthV4.signIn

using hive;

AuthV4.signIn(AuthV4.ProviderType.GOOGLE, (ResultAPI result, AuthV4.PlayerInfo playerInfo) => {
    if (result.isSuccess()) {
        // 呼び出し成功
        // playerInfo : 認証されたユーザー情報。
        // ProviderType.GOOGLEのメール情報を取得する例
        Dictionary<AuthV4.ProviderType, AuthV4.ProviderInfo> providerInfoData = playerInfo.providerInfoData;
        AuthV4.ProviderInfo providerInfo = providerInfoData[AuthV4.ProviderType.GOOGLE];
        string email = providerInfo.providerEmail;
    }
});
#include "HiveAuthV4.h"

FHiveAuthV4::SignIn(EHiveProviderType::GOOGLE,
                    FHiveAuthV4OnSignInDelegate::CreateLambda([this](const FHiveResultAPI& Result, const FHivePlayerInfo& PlayerInfo) {

    if (Result.IsSuccess()) {
        // 呼び出し成功 (PlayerInfo: 認証されたユーザー情報) 

        // EHiveProviderType::GOOGLEのためのメール情報を取得する例
        TMap<EHiveProviderType, FHiveProviderInfo> ProviderInfoData = PlayerInfo.ProviderInfoData;
        if (const FHiveProviderInfo* ProviderInfo = ProviderInfoData.Find(EHiveProviderType::GOOGLE)) {
                FString Email = ProviderInfo->ProviderEmail;
        }
    }
}));

APIリファレンス: Auth4::signIn

#include <HIVE_SDK_Plugin/HIVE_CPP.h>

AuthV4::signIn(ProviderType::GOOGLE, [=](ResultAPI const & result, PlayerInfo const & playerInfo) {
    if (result.isSuccess()) {
        // 成功した呼び出し
        // playerInfo : 認証されたユーザー情報。

        // ProviderType::GOOGLEのためのメール情報を取得する例
        map<ProviderType, ProviderInfo> providerInfoData = playerInfo.providerInfoData;
        ProviderInfo providerInfo = providerInfoData[ProviderType::GOOGLE];
        string email = providerInfo.providerEmail;
    }
});

APIリファレンス: AuthV4.signIn

import com.hive.AuthV4
import com.hive.ResultAPI

AuthV4.signIn(AuthV4.ProviderType.GOOGLE, object : AuthV4.AuthV4SignInListener {
    override fun onAuthV4SignIn(result: ResultAPI, playerInfo: AuthV4.PlayerInfo?) {
        if (result.isSuccess) {
            // 呼び出し成功
            // playerInfo: 認証されたユーザー情報
            // ProviderType.GOOGLEのメール情報を取得する例
            if (playerInfo != null) {
                val providerInfoData = playerInfo.providerInfoData
                val providerInfo = providerInfoData[AuthV4.ProviderType.GOOGLE]
                if (providerInfo != null) {
                    val email = providerInfo.providerEmail
                }
            }
        }
    }
})

APIリファレンス: com.hive.Auth4.signIn

import com.hive.AuthV4;
import com.hive.ResultAPI;

AuthV4.signIn(AuthV4.ProviderType.GOOGLE, (result, playerInfo) -> {
    if (result.isSuccess()) {
        // Call successful
        // playerInfo: authenticated user information
        // Example of retrieving email information for ProviderType.GOOGLE
        if (playerInfo != null) {
            HashMap<AuthV4.ProviderType, AuthV4.ProviderInfo> providerInfoData = playerInfo.getProviderInfoData();
            AuthV4.ProviderInfo providerInfo = providerInfoData.get(AuthV4.ProviderType.GOOGLE);
            if (providerInfo != null) {
                String email = providerInfo.getProviderEmail();
            }
        }
    }
});

APIリファレンス: AuthV4Interface.signIn

import HIVEService

AuthV4Interface.signIn(.Google) { result, playerInfo in    
    if result.isSuccess() {
        // 成功した呼び出し
        // playerInfo: 認証されたユーザー情報。

        // Googleのメール情報を取得する例
        if 
            let playerInfo = playerInfo,  
            let providerInfo = playerInfo.providerInfoData["GOOGLE"] {
                let email = providerInfo.providerEmail
        }
    }
}

APIリファレンス: HIVEAuth4:signIn

#import <HIVEService/HIVEService-Swift.h>

[HIVEAuthV4 signIn:HIVEProviderTypeGoogle handler:^(HIVEResultAPI *result, HIVEPlayerInfo *playerInfo) {
    if ([result isSuccess]){
        // 呼び出し成功
        // playerInfo: 認証されたユーザー情報。

        // HIVEProviderTypeGoogleのメール情報を取得する例
        if(playerInfo != nil) {
            HIVEProviderInfo *providerInfo = playerInfo.providerInfoData[@"GOOGLE"];
            if(providerInfo != nil){
                NSString *email = providerInfo.providerEmail;
            }
        }
    }
}];

デバイス上のIdPアカウントのログイン確認

自動ログインは、保存されたPlayerIDの認証トークンキーを使用してログインしますが、明示的なログインは複数のIdPにリンクされたアカウントにログインします。いずれの場合も、ログインしているPlayerIDのIdPアカウントは、実際のデバイス(DevicePlayer)にログインしているIdPアカウントと異なる場合があります。将来の成果やリーダーボードの使用に備えて、2つのアカウントを統一するためのガイダンスが提供されます。

  • SDKによって提供されたDevicePlayerのUIを確認してください

以下はIdP情報を確認するための例コードです。

API リファレンス: AuthV4.Helper.syncAccount

using hive;

AuthV4.ProviderType providerType = AuthV4.ProviderType.GOOGLE;
AuthV4.Helper.syncAccount (providerType, delegate (ResultAPI result, AuthV4.PlayerInfo playerInfo) {

    switch (result.code) {
        case ResultAPI.Code.Success:
            // Normal
            break;   
        case ResultAPI.Code.AuthV4ConflictPlayer:
            // アカウントの競合
            // 例) Hive UIを使用しているとき
            // AuthV4.Helper.showConflict(...);
            // または
            // 例) GameUIを実装しているとき
            // AuthV4.Helper.resolverConflict(...);// 現在のユーザーを選択するとき
            // AuthV4.Helper.switchAccount(...);// ユーザー切り替えを選択するとき 
            break;
        default:  
            // その他の例外
            break;
    }
});
#include "HiveAuthV4.h"

FHiveAuthV4::Helper::SyncAccount(ProviderType, 
                                 FHiveAuthV4HelperDelegate::CreateLambda([this](const FHiveResultAPI& Result, 
                                                                                const TOptional<FHivePlayerInfo>& PlayerInfo) {

    switch (Result.Code) {
        case FHiveResultAPI::ECode::Success:
            // 通常の応答
            break;
        case FHiveResultAPI::ECode::AuthV4ConflictPlayer:
            // アカウントの競合
            // 例) Hive UIを使用しているとき
            // FHiveAuthV4::Helper::ShowConflict()
            // 例) ゲームUIを実装しているとき
            // FHiveAuthV4::Helper::ResolveConflict() // 現在のユーザー選択
            // FHiveAuthV4::Helper::SwitchAccount() // ユーザー切り替え選択
            break;
        default:
            // その他の例外的な状況
            break;
    }
}));

APIリファレンス: AuthV4::Helper::syncAccount

#include <HIVE_SDK_Plugin/HIVE_CPP.h>
using namespace std;
using namespace hive;

ProviderType providerType = ProviderType::GOOGLE;
AuthV4::Helper::syncAccount(providerType, [=](ResultAPI const & result, shared_ptr<PlayerInfo> playerInfo) {

    switch (result.code) {
        case ResultAPI::Success:
            // 通常
            break;   
        case ResultAPI::AuthV4ConflictPlayer:
            // アカウントの競合
            // 例) Hive UIを使用しているとき
            // AuthV4::Helper::showConflict(...);
            // または
            // 例) GameUIを実装しているとき
            // AuthV4::Helper::resolverConflict(...);// 現在のユーザーを選択するとき
            // AuthV4::Helper::switchAccount(...);// ユーザーを切り替えるとき 
            break;
        default:  
            // その他の例外状況
            break;
    }
});

APIリファレンス: AuthV4.Helper.syncAccount

import com.hive.AuthV4
import com.hive.ResultAPI

val providerType = AuthV4.ProviderType.GOOGLE
AuthV4.Helper.syncAccount(providerType, object : AuthV4.Helper.AuthV4HelperListener {
    override fun onAuthV4Helper(result: ResultAPI, playerInfo: AuthV4.PlayerInfo?) {    
        when (result.code) {
            ResultAPI.Code.Success -> {
                // 通常
            }
            ResultAPI.Code.AuthV4ConflictPlayer -> {
                // アカウントの競合
                // 例) Hive UIを使用しているとき
                // AuthV4.Helper.showConflict(...);
                // または
                // 例) GameUIを実装しているとき
                // AuthV4.Helper.resolverConflict(...);// 現在のユーザーを選択するとき
                // AuthV4.Helper.switchAccount(...);// ユーザー切り替えを選択するとき 
            }
            else -> {
                // その他の例外的な状況
            }
        }
    }
})

APIリファレンス: AuthV4.Helper.syncAccount

import com.hive.AuthV4;
import com.hive.ResultAPI;

AuthV4.ProviderType providerType = AuthV4.ProviderType.GOOGLE;
AuthV4.Helper.syncAccount(providerType, (result, playerInfo) -> {
    switch (result.getCode()) {
        case Success:
            // 通常  
        case AuthV4ConflictPlayer:    
            break;   
            // アカウントの競合
            // 例) Hive UIを使用しているとき
            // AuthV4.Helper.showConflict(...);
            // または
            // 例) GameUIを実装しているとき
            // AuthV4.Helper.resolverConflict(...);// 現在のユーザーを選択する時
            // AuthV4.Helper.switchAccount(...);// ユーザー切り替えを選択する時 
            break;
        default:  
            // その他の例外
            break;
    }
});

API リファレンス: AuthV4Interface.helper().syncAccount

import HIVEService
let providerType: ProviderType = .Google

AuthV4Interface.helper().syncAccount(providerType) { result, playerInfo in
    switch result.getCode() {
        case .success:
        // 通常
        case .authV4ConflictPlayer:
        // アカウントの競合
        // 例) Hive UIを使用しているとき
        // AuthV4Interface.helper().showConflict(...);
        // または
        // 例) GameUIを実装しているとき
        // AuthV4Interface.helper().resolverConflict(...);// 現在のユーザーが選択されているとき
        // AuthV4Interface.helper().switchAccount(...);// ユーザー切り替えが選択されているとき 
        default:
        // その他の例外的な状況
        break
    }
}

APIリファレンス: [HIVEAuthV4 helper] syncAccount

#import <HIVEService/HIVEService-Swift.h>

HIVEProviderType providerType = HIVEProviderTypeGoogle
[[HIVEAuthV4 helper] syncAccount: providerType handler: ^(HIVEResultAPI *result, HIVEPlayerInfo *playerInfo) {
    switch ([result getCode]) {
        case HIVEResultAPICodeSuccess:
            // 通常
            break;    
        case HIVEResultAPICodeAuthV4ConflictPlayer:
            // アカウントの競合
            // 例) Hive UIを使用しているとき
            // [[HIVEAuthV4 helper] showConflict: ...];
            // または
            // 例) GameUIを実装しているとき
            // [[HIVEAuthV4 helper] resolverConflict:...];// 現在のユーザーが選択されているとき
            // [[HIVEAuthV4 helper] switchAccount:...];// ユーザー切り替えが選択されているとき  
            break;
        default:  
            // その他の例外
            break;
    }
}];

ゲストログイン

ゲストログイン機能を使用すると、ユーザーはIdPを選択せずにゲストモードでゲームをプレイできます。Hive SDKが提供する明示的なログインUIからゲストログインを選択するか、ゲーム内でカスタマイズしている場合は直接ゲストログインを実装できます。Windows環境ではゲストログインはサポートされていません。

ゲストとしてログインする際は、以下のポリシーに従う必要があります。

ゲストログインポリシー

  • IdP認証されたユーザーとゲストユーザーの両方が同じようにゲームを利用できるように実装してください。 Hiveプラットフォームのほとんどの機能は、ゲストとしてログインしている場合でも使用できます。したがって、ゲストとしてログインしているユーザーがIdPリンクされたユーザーと同じようにゲームを利用できるようにゲームを実装してください。たとえば、ゲストユーザーもアイテムを購入したり、ゲーム内で支払いを行ったりできる必要があります。
    • ゲストユーザーにログアウト機能を提供しないでください。 ゲストとしてログインした後にユーザーがログアウトすると、同じPlayerIDで再度ログインできなくなります。したがって、ゲストとしてログインしているときにユーザーがログアウトできないように、ログアウトボタンを提供しないでください。
    • 中国のゲストログイン禁止ポリシー 中国のIPを使用している場合、実名確認を受けたユーザーのみがリチャージやリソースの消費を行うことができます(2017年5月1日から有効)。したがって、ゲストログインは中国のIPでログインできるIdPのリストには含まれていません。

ゲストログインを行うには、ProviderType.GUESTをパラメータとしてsignIn()メソッドを呼び出します。 ゲストログインを行うための例コードは以下の通りです。

Note

ゲスト状態でIdP認証なしのPlayerIDのplayerInfoにはproviderInfoDataがありません。

APIリファレンス: hive.AuthV4.signIn

using hive;

AuthV4.signIn(AuthV4.ProviderType.GUEST, (ResultAPI result, AuthV4.PlayerInfo playerInfo) => {
    if (result.isSuccess()) {
        // 認証成功
        // playerInfo: 認証されたユーザー情報
    }
});
#include "HiveAuthV4.h"

FHiveAuthV4::SignIn(EHiveProviderType::GUEST, 
                    FHiveAuthV4OnSignInDelegate::CreateLambda([this](const FHiveResultAPI& Result, const FHivePlayerInfo& PlayerInfo) {

    if (Result.IsSuccess()) {
            // 呼び出し成功 (PlayerInfo: 認証されたユーザー情報)
    }
}));

APIリファレンス: Auth4::signIn

#include <HIVE_SDK_Plugin/HIVE_CPP.h>

using namespace std;
using namespace hive;
AuthV4::signIn(ProviderType::GUEST, [=](ResultAPI const & result, PlayerInfo const & playerInfo) {
    if (result.isSuccess()) {
        // 認証成功
        // playerInfo: 認証されたユーザー情報
    }
});

APIリファレンス: AuthV4.signIn

import com.hive.AuthV4
import com.hive.ResultAPI

AuthV4.signIn(AuthV4.ProviderType.GUEST, object : AuthV4.AuthV4SignInListener {
    override fun onAuthV4SignIn(result: ResultAPI, playerInfo: AuthV4.PlayerInfo?) {
        if (result.isSuccess) {
            // 認証成功
            // playerInfo: 認証されたユーザー情報
        }
    }
})

APIリファレンス: com.hive.Auth4.signIn

import com.hive.AuthV4;
import com.hive.ResultAPI;

AuthV4.signIn(AuthV4.ProviderType.GUEST, (result, playerInfo) -> {
    if (result.isSuccess()) {
        // 認証成功
        // playerInfo: 認証されたユーザー情報
    }
});

APIリファレンス: AuthV4Interface.signIn

import HIVEService

AuthV4Interface.signIn(.Guest) { result, playerInfo in
    if result.isSuccess() {
        // 認証成功
        // playerInfo: 認証されたユーザー情報
    }
}

APIリファレンス: HIVEAuth4:signIn

#import <HIVEService/HIVEService-Swift.h>

[HIVEAuthV4 サインイン: HIVEProviderTypeGuest ハンドラー: ^(ResultAPI *result, HIVEPlayerInfo *playerInfo) {
    if ([result isSuccess]) {
        // 認証成功
        // playerInfo: 認証されたユーザー情報
    }
}];

カスタムログイン

カスタムログインカスタマイズされたログインのための機能で、Hiveが提供するIdPに加えて、ゲーム自体と統合されたIdPを通じてログインを実装することを可能にします。カスタムログインAPIを呼び出す際に使用する認証キー(authKey)を生成してみてください。これはAuthenticate v4 Custom Authenticationに従って行います。

カスタムログインAPIを呼び出した後、コールバックとして受け取ったPlayerInfoクラスのインスタンスを通じて、customProviderInfoDataデータにアクセスしてカスタムでログインしたユーザーの情報を確認できます。customProviderInfoDataProviderType (enum)は一律にCUSTOMに設定されており、ProviderName (String)によって詳細に区別できます。

ゲームでカスタムログインを実装したIdPの情報は、AuthV4クラスのsetup()およびshowSignIn()メソッド呼び出しの結果には含まれていません。

カスタムログインの最初の実行後にplayerIdとplayerTokenを受け取った場合、カスタムログインAPIが再呼び出しされると、authV4SessionExist(code)の結果APIがコールバックとして配信されます。この場合、既にログインしているアカウントを使用して自動ログインを進めるために、ProviderType.AutoをパラメータとしてsignIn()を呼び出す必要があります。以下の例コードを参照してください。

AuthV4クラスのconnect()およびdisconnect()メソッドは、カスタムログインIdPの追加統合および切断をサポートしていません。connectWithAuthKey()およびdisconnectWithName()メソッドは、カスタムログインIdPの追加統合および切断をサポートしています。

これはカスタムログインを実装するための例のコードです。

APIリファレンス: hive.AuthV4.signIn

// ゲーム内で直接実装されたTwitterログイン
Game.Login("CUSTOM_TWITTER", (string authKey) => {
    AuthV4.signInWithAuthKey(authKey, (ResultAPI result, PlayerInfo playerInfo) => {
        if (result.isSuccess()) {
            Dictionary<string, ProviderInfo> customProviderInfoData = playerInfo.customProviderInfoData;
            ProviderInfo providerInfo = customProviderInfoData["CUSTOM_TWITTER"];
            // 次のユーザーリンク情報を確認します
            providerInfo.providerType;     // ProviderType.CUSTOM、カスタムタイプは固定されているため、providerNameで区別する必要があります
            providerInfo.providerName;   // "CUSTOM_TWITTER"
            providerInfo.providerUserId;  // カスタムTwitterログインに使用されるユーザーID
            return;
        }
        else if (result.code == ResultAPI.Code.AuthV4SessionExist) {
            // playerIdとplayerTokenがすでに発行されていて、自動ログインが必要な場合
            // TODO: AuthV4.signIn(ProviderType.AUTO, (ResultAPI _result, PlayerInfo playerInfo) => {});
        }
        else if (result.code == ResultAPI.Code.AuthV4NotInitialized) {
            // TODO: SDKの初期化が必要です
        }
        else if (result.code == ResultAPI.Code.AuthV4InvalidParam) {
            // TODO: 提供されたauthKeyの値がNULLまたは空でないか確認します
        }
        else if (result.needExit()) {
            // TODO: アプリの終了機能を実装します
            // 例) Application.Quit();
        }
    });  
});
#include "HiveAuthV4.h"

// ゲーム内で「CUSTOM_TWITTER」タイプのTwitterログインを直接実装しました
void GameLogin(const FString& AuthKey)
{
    FHiveAuthV4::SignInWithAuthKey(AuthKey, FHiveAuthV4OnSignInDelegate::CreateLambda([this](const FHiveResultAPI& Result, const FHivePlayerInfo& PlayerInfo) {

        if (Result.IsSuccess()) {
            TMap<FString, FHiveProviderInfo> CustomProviderInfoData = PlayerInfo.CustomProviderInfoData;
            if (const FHiveProviderInfo* ProviderInfo = CustomProviderInfoData.Find(TEXT("CUSTOM_TWITTER"))) {
                    EHiveProviderType ProviderType = ProviderInfo->ProviderType; // EHiveProviderType::CUSTOM, custom types are fixed
                    FString ProviderName = ProviderInfo->ProviderName; // Need to distinguish by ProviderName
                    FString ProviderUserId = ProviderInfo->ProviderUserId; // User id used in the custom Twitter login
            }
        } else if (Result.NeedExit()) {
            // TODO: アプリ終了機能を実装する
            // e.g.) UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit, false);
        } else if (Result.Code == FHiveResultAPI::ECode::AuthV4SessionExist) {
            // もしplayerIdとplayerTokenがすでに発行されていて、自動ログインが必要な場合
            // TODO: FHiveAuthV4.SignIn(EHiveProviderType::GUEST, Delegate);
        } else if (Result.Code == FHiveResultAPI::ECode::AuthV4NotInitialized) {
            // TODO: SDKの初期化が必要
        } else if (Result.Code == FHiveResultAPI::ECode::AuthV4InvalidParam) {
            // TODO: 提供されたauthKeyの値が空でないか確認する
        }
    }));
}

API リファレンス: Auth4::signIn

using namespace std;
using namespace hive;

// ゲーム内で直接実装されたTwitterログイン
Game::Login("CUSTOM_TWITTER", [=](string authKey) {
    AuthV4::signInWithAuthKey(authKey, [=](ResultAPI const & result, PlayerInfo const & playerInfo) {
        if (result.isSuccess()) {
            map<string, ProviderInfo> customProviderInfoData = playerInfo.customProviderInfoData;
            ProviderInfo providerInfo = customProviderInfoData["CUSTOM_TWITTER"];
            // 以下のユーザーリンク情報を確認
            providerInfo.providerType; // ProviderType::CUSTOM、カスタムタイプは固定されているため、providerNameで区別する必要があります
            providerInfo.providerName; // "CUSTOM_TWITTER"
            providerInfo.providerUserId; // カスタムTwitterログインに使用されるユーザーID
            return;
        }
        else if (result.code == ResultAPI::Code::AuthV4SessionExist) {
            // playerIdとplayerTokenがすでに発行されており、自動ログインが必要な場合
            // TODO: AuthV4.signIn(ProviderType::AUTO, [=](ResultAPI const & _result, PlayerInfo const & playerInfo) {});
        }
        else if (result.code == ResultAPI::Code::AuthV4NotInitialized) {
            // TODO: SDKの初期化が必要
        }
        else if (result.code == ResultAPI::Code::AuthV4InvalidParam) {
            // TODO: 提供されたauthKeyの値がNULLまたは空であるか確認
        }
        else if (result.needExit()) {
            // TODO: アプリ終了機能を実装
            // Cocos2d-xエンジンユーザー向け
            // 例) exit(0);
            // Unrealエンジンユーザー向け
            // 例) UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit, false);
        }
    });  
});

APIリファレンス: com.hive.Auth4.signIn

// ゲーム内で直接実装されたTwitterログイン
Game.Login("CUSTOM_TWITTER") { authKey: String ->

    AuthV4.signInWithAuthKey(authKey, object : AuthV4.AuthV4SignInListener {
        override fun onAuthV4SignIn(result: ResultAPI, playerInfo: AuthV4.PlayerInfo?) {

            if (result.isSuccess && playerInfo != null) {
                playerInfo.customProviderInfoData["CUSTOM_TWITTER"]?.let { providerInfo ->
                    providerInfo.providerType   // ProviderType.CUSTOM, custom types are fixed, so need to distinguish by providerName
                    providerInfo.providerName   // "CUSTOM_TWITTER"
                    providerInfo.providerUserId // User id used for the custom Twitter login
                }
            }
            else if (result.needExit()) {
                // TODO: アプリ終了機能を実装する
                // e.g.) exitProcess(0)
            }
            else if (result.code == ResultAPI.Code.AuthV4SessionExist) {
                // playerIdとplayerTokenがすでに発行されていて、自動ログインが必要な場合
                // TODO: AuthV4.signIn(AuthV4.ProviderType.AUTO, authV4SignInListener)
            }
            else if (result.code == ResultAPI.Code.AuthV4NotInitialized) {
                // TODO: SDKの初期化が必要
            }
            else if (result.code == ResultAPI.Code.AuthV4InvalidParam) {
                // TODO: 提供されたauthKeyの値がNULLまたは空であるか確認する
            }
        }
    })
}

APIリファレンス: com.hive.Auth4.signIn

// ゲーム内で直接実装されたTwitterログイン
Game.Login("CUSTOM_TWITTER") { authKey: String ->
    AuthV4.signInWithAuthKey(authKey, new AuthV4.AuthV4SignInListener() {
        @Override
        public void onAuthV4SignIn(@NonNull ResultAPI result, @Nullable AuthV4.PlayerInfo playerInfo) {

            if(result.isSuccess() && playerInfo != null) {
                HashMap<String, AuthV4.ProviderInfo> customProviderInfoData = playerInfo.getCustomProviderInfoData();
                AuthV4.ProviderInfo providerInfo = customProviderInfoData.get("CUSTOM_TWITTER");
                // 次のユーザーリンク情報を確認します
                if (providerInfo != null){
                    providerInfo.getProviderType(); // AuthV4.ProviderType.CUSTOM、カスタムタイプは固定されているため、providerNameで区別する必要があります
                    providerInfo.getProviderName(); // "CUSTOM_TWITTER"
                    providerInfo.getProviderUserId(); // 直接実装されたカスタムTwitterログインに使用されるユーザーID
                }
            } else if (result.needExit()) {
                // TODO: アプリ終了機能を実装する
                // 例) System.exit(0);
            } else if (result.getCode() == ResultAPI.Code.AuthV4SessionExist) {
                // playerIdとplayerTokenがすでに発行され、自動ログインが必要な場合
                // TODO: AuthV4.signIn(AuthV4.ProviderType.AUTO, authV4SignInListener)
            } else if (result.getCode() == ResultAPI.Code.AuthV4NotInitialized) {
                // TODO: SDKの初期化が必要です
            } else if (result.getCode() == ResultAPI.Code.AuthV4InvalidParam) {
                // TODO: 提供されたauthKeyの値がNULLまたは空であるか確認する
            }
        }
    });
}

APIリファレンス: HIVEAuth4:signIn

// ゲーム内で直接実装されたTwitterログイン
Game.login("CUSTOM_TWITTER") { (authKey) in
    AuthV4Interface.signInWithAuthKey(authKey) { (result, playerInfo) in
        if result.isSuccess() {
            let customProviderInfoData = playerInfo?.customProviderInfoData;
            let providerInfo = customProviderInfoData?["CUSTOM_TWITTER"]
            // 次のユーザーリンク情報を確認
            providerInfo?.providerType;     // AuthProviderType、カスタムタイプは固定されているため、providerNameで区別する必要があります
            providerInfo?.providerName;     // "CUSTOM_TWITTER"
            providerInfo?.providerUserId;   // カスタムTwitterログインに使用されるユーザーID
            return
        }
        else if result.getCode() == .authV4SessionExist {
            // playerIdとplayerTokenがすでに発行されていて、自動ログインが必要な場合
            // TODO: AuthV4Interface.signIn(.auto) { (result, playerInfo) in }
        }
        else if result.getCode() == .authV4NotInitialized {
            // TODO: SDKの初期化が必要です
        }
        else if result.getCode() == .authV4invalidParam {
            // TODO: 提供されたauthKeyの値がnilまたは空であるか確認してください
        }
        else if result.needExit() {
            // TODO: アプリの終了機能を実装します。
            // 例: exit(0)
        }
    }
}

APIリファレンス: HIVEAuth4:signIn

// ゲーム内で直接実装されたTwitterログイン
[Game login:@"CUSTOM_TWITTER" handler:^(NSString* authKey) {

    [HIVEAuthV4 signInWithAuthKey:authKey handler:^(HIVEResultAPI* result, HIVEPlayerInfo* playerInfo) {
        if (result.isSuccess) {
            NSDictionary<NSString*, HIVEProviderInfo*>* customProviderInfoData = playerInfo.customProviderInfoData;
            ProviderInfo* providerInfo = [customProviderInfoData objectForKey:@"CUSTOM_TWITTER"];
            // 次のユーザーリンク情報を確認します
            providerInfo.providerType;     // HIVEProviderTypeCustom、カスタムタイプは固定されているため、providerNameで区別する必要があります
            providerInfo.providerName;   // "CUSTOM_TWITTER"
            providerInfo.providerUserId;  // カスタムTwitterログインで使用されるユーザーID
            return;
        }
        else if (result.getCode == HIVEResultAPICodeAuthV4SessionExist) {
            // playerIdとplayerTokenがすでに発行されていて、オートログインが必要な場合
            // TODO: [HIVEAuthV4 signIn:HIVEProviderTypeAuto, handler:^(HIVEResultAPI* _result, HIVEPlayerInfo* playerInfo) {}];
        }
        else if (result.getCode == HIVEResultAPICodeAuthV4NotInitialized) {
            // TODO: SDKの初期化が必要です
        }
        else if (result.getCode == HIVEResultAPICodeAuthV4InvalidParam) {
            // TODO: 提供されたauthKeyの値がNULLまたは空であるか確認します
        }
        else if (result.needExit) {
            // TODO: アプリの終了機能を実装します。
            // 例) exit(0);
        }
    }];   
}];

ユーザー名

アメリカ合衆国におけるCOPPAなどの問題により、アメリカ合衆国およびその領土からIdPにアクセスしログインする際、ユーザーは追加のユーザー識別認証処理を促進するためにユーザー名を入力する必要があります。参考までに、アメリカ領土に含まれる国は、アメリカ領サモア(AS)、グアム(GU)、北マリアナ諸島(MP)、プエルトリコ(PR)、アメリカ合衆国小離島(UM)、およびアメリカ領ヴァージン諸島(VI)です。ユーザー識別のためのユーザー名を入力する画面は以下の通りです。

  • ユーザー名入力画面はユーザー識別の目的のみで使用されるため、初回のIdP統合時にのみ表示され、その後は表示されません。
  • ゲストログイン中にはユーザー名入力画面は表示されません。

認証トークンキーの検証

ゲームサーバーは、成功したログイン後に返されるトークン、playerId、およびDID情報を使用してトークンキーの真偽を検証できます。Hive認証は、マルチデバイスログインと同時アクセスを許可します。

同じアカウントでの重複アクセスが許可されていない場合、ゲームサーバーは最初に接続したデバイスに通知メッセージを表示し、その後ゲームを終了します。これにより、後から接続したデバイスでゲームを続行できるようになります。ゲームを終了せずに再度アクセスを試みると、ゲームプレイの記録が正しく反映されない可能性があります。この機能を実装するには、検証済みのトークンキーまたはゲーム自体のセッションキーを管理する必要があります。

この機能は、認証トークンキー検証サーバーAPIを参照して実装してください。

バックグラウンドでのIdPアカウント変更の検出

ユーザーは、ゲームプレイ中にデバイスの設定に移動して、Apple Game CenterまたはGoogle Play Gamesアカウントを変更できます。ゲームプレイ中のIdPアカウントが現在のPlayerIDのIdPアカウントと異なるかどうかを確認する必要がある場合は、SDKを初期化した後にsetProviderChangedListener()を呼び出してください。このAPIを呼び出すことで、ゲームが再開されたときにデバイスに設定されたIdPアカウントが変更されたことを示すイベントを受け取ることができます。

iOSはApple Game Centerと連携し、Androidはアカウントが変更されるとGoogle Playゲームと連携します。応答は、現在ログインしているPlayerIDが対応するIdPにリンクされている場合にのみ配信されます。IdPアカウント変更イベントを受信すると、UIはユーザーがデバイスにログインしているIdPアカウントを使用するかどうかを選択できるように構成されます。ユーザーがデバイスにログインしているIdPアカウントを選択すると、signOutが呼び出されてログアウトし、その後、暗黙のログインが行われます。

Warning

2021年7月以降にリリースされたGoogle Playゲームをインストールしたデバイスは、Google Playゲームの運用上の問題により、バックグラウンドでIdPアカウントを変更できません。

Note

この機能はゲームプレイを一時停止させ、アカウントの変更を要求する可能性があり、ロビーやショップに入るなど、アカウントの同期が必要な時に制限的にのみ使用できます。

以下は、ユーザーがゲームを再起動し、デバイスに設定されたIdPアカウントが変更されたときにイベントを受信するための設定を行う例のコードです。

APIリファレンス: hive.AuthV4.setProviderChangedListener

using hive;

AuthV4.setProviderChangedListener((ResultAPI result, AuthV4.ProviderInfo providerInfo) => {
    if (!result.isSuccess()) {
        return;
    }

    if (providerInfo != null && providerInfo.providerType == AuthV4.ProviderType.APPLE) {
        // ゲームセンターのユーザー情報を変更する
    }
});
#include "HiveAuthV4.h"

FHiveAuthV4::SetProviderChangedListener(FHiveAuthV4OnCheckProviderDelegate::CreateLambda([this](const FHiveResultAPI& Result, const FHiveProviderInfo& ProviderInfo) {
    if (Result.IsSuccess()) {
            // 呼び出しが成功しました。ProviderInfoオブジェクトを通じて変更されたユーザー情報を確認してください
    }
}));

API リファレンス: AuthV4::setProviderChangedListener

#include <HIVE_SDK_Plugin/HIVE_CPP.h>
using namespace std;
using namespace hive;

AuthV4::setProviderChangedListener([=](ResultAPI const & result, ProviderInfo const & providerInfo) {
    if (!result.isSuccess()) {
        return;
    }

    if (providerInfo != null && providerInfo.providerType == ProviderType::GOOGLE) {
        // Google Play Game Serviceアカウントを変更する
    }
});

APIリファレンス: AuthV4.setProviderChangedListener

import com.hive.AuthV4
import com.hive.ResultAPI

AuthV4.setProviderChangedListener(object : AuthV4.AuthV4CheckProviderListener {
    override fun onDeviceProviderInfo(result: ResultAPI, providerInfo: AuthV4.ProviderInfo?) {
        if (!result.isSuccess) {
            return
        }

        if (providerInfo != null && providerInfo.providerType == AuthV4.ProviderType.GOOGLE) {
            // Google Play Game Serviceアカウントを変更
        }
    }
})

APIリファレンス: com.hive.AuthV4.setProviderChangedListener

import com.hive.AuthV4;
import com.hive.ResultAPI;

AuthV4.setProviderChangedListener((result, providerInfo) -> {
    if (!result.isSuccess()) {
        return;
    }

    if (providerInfo != null && providerInfo.getProviderType() == AuthV4.ProviderType.GOOGLE) {
        // Google Play Game Serviceアカウントを変更する
    }
});

API リファレンス: AuthV4Interface.setProviderChangedListener

import HIVEService

AuthV4Interface.setProviderChangedListener() { result, providerInfo in 
    if !result.isSuccess() {
        return
    }

    if let providerInfo = providerInfo, providerInfo.providerType == .Apple {
        // ゲームセンターのユーザー情報を変更します
    }
}

API リファレンス: HIVEAuthV4:setProviderChangedListener

#import <HIVEService/HIVEService-Swift.h> 

[HIVEAuthV4 setProviderChangedListener: ^(HIVEResultAPI *result, ProviderInfo *providerInfo) {
    if (![result isSuccess]) {
        return;
    }

    if (providerInfo != nil && providerInfo.providerType == HIVEProviderTypeApple) {
        // GameCenter ユーザー情報の変更
    }
}];

ゲームデータの初期化

ゲームデータを初期化する際にログアウトを呼び出さないでください。PlayerIDは削除されないため、アカウント間での競合が発生する可能性があります。ユーザーが現在ログインしているアカウントでプレイを続けられるように実装し、ユーザーが明示的に要求するまでログアウトを呼び出さないようにしてください。

ログアウト

Warning
  • ログアウト操作中に、認証情報のPlayerIdおよびセッション情報のPlayerToken、ならびにすべてのIDPのセッション情報が削除されます。
  • setで始まるすべてのAPIによって設定された値は初期化されず、削除されません。
    • Configuration、Auth、Auth v4、Promotion、Pushクラスのsetで始まるすべてのメソッド
    • 以下は代表的な例です。ex> Configuration.setServer、Configuration.setUseLog、Configuration.setGameLanguage、Configuration.setHiveCertificationKey、Auth.setEmergencyMode、AuthV4.setProviderChangedListener、Promotion.setUserEngagementReady、Promotion.setAddtionalInfo、Push.setRemotePush、Push.setForegroundPushなど。setで始まるすべてのメソッドはこのカテゴリに該当します。
    • Hive SDK v4 24.3.0以降、ゲストユーザーがログアウトするとエラーコードが返されます。その後、クライアントとサーバーのセッションは維持されます。
  • SDK内のsetで始まるメソッドを通じて設定された値の有効範囲は、ログインまたはログアウトの状態に関係なく、アプリのライフサイクル内で維持されます。

Hiveにログインしている場合、PlayerIDと認証トークンキーが発行されています。ログアウトはPlayerIDと認証トークンキーを初期化する機能を果たします。signOut()メソッドを呼び出してログアウトを完了すると、ゲームタイトルにリダイレクトされ、タイトルをクリックすると明示的なログインが行われます。

Note
  • ゲストログイン状態でログアウトすると、同じPlayerIDは見つからなくなるため、ゲスト状態ではログアウトが提供されないように実装してください。
  • PlayerIDのIdP連携状態は、ログアウト後も変更されません。
  • ログアウトが完了すると、ゲームタイトルに移動し、タイトルをクリックすると明示的なログインが行われます。
  • ログアウト後、アプリが再起動されると、最初に暗黙的なログインが行われます。

ログアウトを実行する例のコードがあります。

APIリファレンス: hive.AuthV4.signOut

using hive;    

AuthV4.Helper.signOut (delegate (ResultAPI result, AuthV4.PlayerInfo playerInfo) {    
    switch(result.code) {    
        case ResultAPI.Code.Success:    
            // ログアウト成功    
            break;    
        default:    
            // その他の例外    
            break;    
    }    
});
#include "HiveAuthV4.h"

FHiveAuthV4::Helper::SignOut(FHiveAuthV4HelperDelegate::CreateLambda([this](const FHiveResultAPI& Result, const TOptional<FHivePlayerInfo>& PlayerInfo) {
    AHIVESDKV4TesterGameMode::getGameModeInstance()->appendLogString(ELogType::AuthV4Helper ,TEXT("Helper::SignOut Result = %s"), *(Result.ToString()));
    switch (Result.Code) {
        case FHiveResultAPI::ECode::Success:
            // Logout successful
            break;
        default:
            // Other exceptions
            break;
    }
}));

APIリファレンス: AuthV4::signOut

#include <HIVE_SDK_Plugin/HIVE_CPP.h>    
using namespace std;    
using namespace hive;    

AuthV4::Helper::signOut([=](ResultAPI const & result, shared_ptr playerInfo) {    
    switch (result.code) {    
        case ResultAPI::Success:    
            // ログアウト成功    
            break;    
        default:    
            // その他の例外    
            break;    
    }    
});

APIリファレンス: AuthV4.Helper.signOut

import com.hive.AuthV4
import com.hive.ResultAPI

AuthV4.Helper.signOut(object : AuthV4.Helper.AuthV4HelperListener {
    override fun onAuthV4Helper(result: ResultAPI, playerInfo: AuthV4.PlayerInfo?) {
        when (result.code) {
            ResultAPI.Code.Success -> {
                // ログアウト成功
            }
            else -> {
                // その他の例外的な状況
            }
        }
    }
})

APIリファレンス: AuthV4.Helper.signOut

import com.hive.AuthV4;
import com.hive.ResultAPI;

AuthV4.Helper.signOut((result, playerInfo) -> {
    switch (result.getCode()) {
        case Success:
            // ログアウト成功
            break;
        default:
            // その他の例外
            break;
    }
});

APIリファレンス: AuthV4Interface.helper().signOut()

import HIVEService

AuthV4Interface.helper().signOut() { result, playerInfo in
    switch result.getCode() {
        case .success:
            // ログアウト成功
        default:
            // その他の例外
            break
    }}

APIリファレンス: [HIVEAuthV4ヘルパー] サインアウト

#import <HIVEService/HIVEService-Swift.h>

[[HIVEAuthV4 ヘルパー] signOut: ^(HIVEResultAPI *result, HIVEPlayerInfo *playerInfo) {
    switch ([result getCode]) {
        case HIVEResultAPICodeSuccess:
            // ログイン成功
            break;
        default:
            // その他の例外
            break;
    }
}];

ゲームセンターキャンセル通知テキスト

言語 フレーズ
韓国語 Apple Game Centerのログインがキャンセルされました。
[設定 > Game Center]でログインして、Game Centerアカウントと同期し、再試行してください。
英語 Game Centerへのログインがキャンセルされました。
[設定> Game Center]でログインして、Game Centerアカウントと同期し、再試行してください。
日本語 Apple Game Centerのログインがキャンセルされました。
[設定 > Game Center]でログインして、Game Centerアカウントと同期した後、再試行してください。
簡体字中国語 Apple Game Centerからログアウトしました。
Game Centerアカウントと同期したい場合は、[設定> Game Center]で再度ログインして、再試行してください。
繁体字中国語 Apple Game Centerへのログインがキャンセルされました。
Game Centerアカウントにリンクしたい場合は、[設定 > Game Center]でログインして、再試行してください。
フランス語 Game Centerへの接続がキャンセルされました。
[設定 > Game Center]でログインして、Game Centerアカウントと同期し、再試行してください。
ドイツ語 Apple Game Centerへのログインがキャンセルされました。
[設定 > Game Center]でログインして、Game Centerアカウントと同期し、再試行してください。
ロシア語 Game Centerへのログインがキャンセルされました。
[設定 > Game Center]からGame Centerにログインして、再試行してください。
スペイン語 Game Centerへのログインがキャンセルされました。
[設定> Game Center]でログインして、Game Centerアカウントと同期し、再試行してください。
ポルトガル語 Game Centerへのログインがキャンセルされました。
[設定> Game Center]でログインして、Game Centerアカウントと同期し、再試行してください。
インドネシア語 Apple Game Centerへのログインがキャンセルされました。
[設定 > Game Center]でログインして、Game Centerアカウントを接続し、再試行してください。
マレー語 Game Centerへのログインがキャンセルされました。
[設定> Game Center]でログインして、Game Centerアカウントと同期し、再試行してください。
ベトナム語 Apple Game Centerへのログインがキャンセルされました。
[設定 > Game Center]でログインして、Game Centerアカウントと同期し、再試行してください。
タイ語 Game Centerへのログインがキャンセルされました。
[設定> Game Center]でログインして、Game Centerアカウントに接続し、再試行してください。
イタリア語 Apple Game Centerへのアクセスがキャンセルされました。
[設定 > Game Center]でログインして、アカウントをGame Centerと同期し、再試行してください。
トルコ語 Apple Game Centerへのログインがキャンセルされました。
[設定> Game Center]でログインして、Game Centerアカウントにアクセスし、再試行してください。
アラビア語 Game Centerへのログインがキャンセルされました。
[設定> Game Center]でログインして、Game Centerアカウントと同期し、再試行してください。