コンテンツにスキップ

ログイン・ログアウト

認証におけるログインは、次の順序で構成されます。

Note
  • SDK 4.7.0未満のバージョンではHelperをサポートしていません。既存のログイン適用方法は[こちら]を参照してください。
  • AuthV4.Helperに関する説明は認証ページを参照してください。

ログイン

認証におけるログインは、次の順序で構成されます。

  1. 自動ログインおよび暗黙的ログイン
  2. 明示的ログイン
  3. デバイスにログインしているIdPアカウントの確認
  4. ゲストログイン

Authv4Helper はログインに関連する一連のプロセスを実行し、応答値に応じて適切な画面に移動するように構成されたクラスです。 ログイン構成時には次の事項を参考にしてください。

Note

AppleはiOSエンタープライズビルドにApple Game Centerとアプリ内購入をサポートしていません。したがって、iOSエンタープライズビルドではApple Game Centerアカウントを利用する暗黙的ログインを使用できず、明示的ログインでもApple Game Centerを利用できません。

Note
Note
  • 中国ではGoogle Playゲームを利用できないため、Androidでの暗黙のログインは使用できません。
  • 中国ではFacebookを利用できないため、IdPリストにFacebookは含まれていません。
  • 中国IPでは実名認証されたユーザーのみが通貨をチャージまたは消費するサービスが可能(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, ...)のコールバック結果がCancelの場合にGame Centerキャンセル案内文を使用してください。

Note

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

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

自動ログインおよび暗黙的ログイン

自動ログイン

インプリシットログインは、ユーザーがログイン手段を選択せず、iOSのApple Game CenterアカウントまたはAndroidのGoogle Play Gamesアカウントに自動的にログインする方法です。自動ログインが失敗した後に実行されるインプリシットログインを実装します。

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

オフラインモード

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

  1. アプリは少なくとも一度オンラインモードで実行され、明示的、暗黙的、ゲスト、またはカスタムログインが成功し、その結果、playerIdplayerTokenが発行される必要があります。
    アプリ開発者の観点からは、オンライン状態でAuthV4.Helper.signInAuthV4.showSignIn、またはAuthV4.signInWithAuthKeyが少なくとも一度成功裏に実行され、コールバックを通じてplayerIdplayerTokenが受信されている必要があります。ユーザーの観点からは、デバイスがネットワークに接続されている間にアプリに少なくとも一度成功裏にログインしている必要があります。ただし、ユーザーのアカウントがオンラインモードでの最後のログイン試行中に停止または制限されていた場合、オフラインモードでログインすることはできません。

  2. Hiveコンソールでオフラインモードを有効にします。アプリセンター > プロジェクト管理 > ゲーム詳細 > Hive製品設定の下で。

Windowsでの自動ログイン

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

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

インプリシットログイン

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

AuthV4.Helper.signInは、PlayerIDの認証トークンキーを使用して自動ログインを試みます。以前のログインから生成されたトークンキーが存在しない場合、ゲームはiOS用のApple Game CenterおよびAndroid用のGoogle Play Gamesに自動的にサインインします。サインインに失敗した場合、レスポンスに応じた適切なログインページを表示します。

Note

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

Note

AuthV4Helperクラスを実装する場合、

  • ユーザーがゲームをロード中にPGSへの暗黙のログインをキャンセルした場合、システムはその状態を記憶し、再度暗黙のログインを試みません。プレイヤーセッションが有効な間に自動ログインが可能であっても、システムは拒否された状態を記憶します。

この内容はGoogle Playゲームサービスガイドに準拠しています。

自動ログインを実行するためのサンプルコードは以下の通りです。

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

// Attempt Hive SDK login (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:
// その他の例外
break;
}
}
});
#include "HiveAuthV4.h"

// 試み Hive SDK ログイン (サインイン)
FHiveAuthV4::Helper::SignIn(FHiveAuthV4HelperDelegate::CreateLambda([this](const FHiveResultAPI& Result, const TOptional<FHivePlayerInfo>& 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 FHiveResultAPI::ECode::AuthV4ConflictPlayer:
                                // アカウントの競合
                                break;
                        case FHiveResultAPI::ECode::AuthV4HelperImplifiedLoginFail:
                                // 暗黙のログイン失敗
                                // 例) AuthV4.showSignIn(...);)
                                break;
                        default:
                                // その他の例外
                                break;
                }
        }
}));

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

// Attempt Hive SDK login (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リファレンス: com.hive.Auth4.Helper.signIn

// Attempt Hive SDK login (signIn)
AuthV4.Helper.signIn(object : AuthV4.Helper.AuthV4HelperListener {
    override fun onAuthV4Helper(result: ResultAPI, playerInfo: AuthV4.PlayerInfo?) {
        if (result.isSuccess) {
            // log-in succeed
        } else if (result.needExit()) {
            // TODO: implement app exit functionality
            // ex) exitProcess(0)
        } else {
            when (result.code) {
                ResultAPI.Code.AuthV4ConflictPlayer -> {
                    // account conflict
                }
                ResultAPI.Code.AuthV4HelperImplifiedLoginFail -> {
                    // implicit login failed
                    // ex) AuthV4.showSignIn(...);
                }
                else -> {
                    // other exceptions
                }
            }
        }
    }
})

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

// Attempt Hive SDK login (signIn)
AuthV4.Helper.signIn(new AuthV4.Helper.AuthV4HelperListener() {
    @Override
    public void onAuthV4Helper(ResultAPI result, AuthV4.PlayerInfo playerInfo) {

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

APIリファレンス: AuthV4Interface.signIn

// Attempt Hive SDK ログイン (signIn)
AuthV4Interface.helper().signIn() { (result, playerInfo) in

    if result.isSuccess() {
        // ログイン成功
    }
    else if result.needExit() {
        // TODO: アプリ終了機能を実装
        // ex) exit(0)
    }
    else {
        switch result.getCode() {
        case .authV4ConflictPlayer:
            // アカウントの競合
        case .authV4HelperImplifiedLoginFail:
            // 暗黙のログイン失敗
            // ex) AuthV4Interface.showSignIn() { (result, playerInfo)
            // // 何かをする...
            // }
        default:
            // その他の例外
            break
        }
    }
}

API リファレンス: HIVEAuth4:signIn

// Attempt Hive SDK login (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)がアカウントの競合を引き起こし、初回ログイン後に最後にログインしたアカウントでログインするかどうかを尋ねるダイアログをユーザーに表示します。

暗黙のログイン動作: PC

PCプラットフォーム(Hive SDK Unity Windowsなど、Windows)では、暗黙のログイン(AuthV4.Helper.signIn)が初回ログイン後に最後にログインしたアカウントで自動的にログインし、アカウントの競合を引き起こすことはありません。

明示的なログイン

明示的ログインとは、ユーザーが認証を進めるためにIdPを選択するプロセスを意味します。プレイヤーが自動ログインと暗黙のログインの両方を実行できなかった場合、ゲームを実装してプレイヤーをゲームタイトル画面に移動させ、タイトルをタップしたときに明示的ログインを実行させます。

明示的ログインは、認証に使用されるHive SDKを初期化した後に返されるIdPリストを使用して、Hive SDKによって提供されるUIまたはゲーム内でカスタマイズされたUIで構成されています。UIをカスタマイズする場合は、明示的ログインUIのカスタマイズを参照してください。

Hive プラットフォームは、各国のポリシーに従ってIdPリストを制御および提供します。例えば、Google Play Games、Facebook、ゲストログインは中国では利用できません。

明示的なログインの例画面

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


Hive SDKによって提供されたUIで関数を実装する際

Windows環境での自動ログイン

Windows環境でも自動ログインをサポートしており、Hive コンソールアプリセンターで有効化/無効化できます。ただし、Windowsの自動ログインはモバイルとは異なる動作をします。Windowsでの自動ログインには次のような違いがあります。

  • モバイルではログイン後に必ず自動ログインでログイン状態を維持しますが、Windowsではユーザーがログイン維持チェックボックス(ログインUI上でIdPリストの下に表示)を有効にした場合にのみログインを維持します。それ以外の状況ではログインを維持しません。
  • AuthV4Helper.Connect 実行時にモバイルでは新しいアカウントに切り替える場合、新しいアカウントも自動ログイン状態を維持しますが、Windowsでは新しいアカウントに切り替える場合、新しいアカウントは自動ログイン状態を維持しません。

暗黙のログイン

  • 暗黙のログインフロー

AuthV4.Helper.signInはPlayerIDの認証トークンキーを利用して自動ログインを試みます。既にログインしていた認証トークンキーがない場合、iOSの場合はApple Game Centerに、Androidの場合はGoogle Playゲームに自動的にログインします。ログインに失敗した場合は、応答値に応じて適切なログイン画面を構成します。

Note

自動ログインを使用するには必ずGame Center Entitlementを追加する必要があります。 'Apple GameCenter' Dependencyにチェックを入れた場合、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:    
                // その他の例外状況    
                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:
                                // 暗黙のログインに失敗
                                // ex) FHiveAuthV4::ShowSigIn()
                                break;
                        default:
                                // その他の例外状況
                                break;
                }
        }
}));

APIリファレンス: Auth4::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.showSignIn

// Hive SDK ログイン(signIn) 試行    
 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.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:signIn

var email = String()    
    // Hive SDK AuthV4 인증 UI 요청    
    AuthV4Interface.showSignIn { (result, playerInfo) in    

    if result.isSuccess() {    
        // 認証成功    
        // playerInfo: 認証されたユーザー情報    
        // メール情報取得の例    
        if let playerInfo = playerInfo {    
            // providerEmailが存在するproviderInfoを探索 (現在ログイン中のprovider)    
            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:signIn

// Hive SDK ログイン(signIn) 試行    
[[HIVEAuthV4 helper] signIn:^(HIVEResultAPI *result, HIVEPlayerInfo *playerInfo) {

        if (result.isSuccess) {
                // ログイン成功 
        }
        else if (result.needExit) {
                // TODO: アプリ終了機能を実装してください
                // 例) 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)は、最初のログイン後に他のアカウントでログインする場合、アカウントの衝突状況が発生し、最後にログインしたアカウントでログインするかどうかをユーザーに尋ねるウィンドウを表示します。

暗黙のログイン動作: 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: アプリ終了機能を実装してください
        // 例) 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を探索(現在ログイン中のprovider)
                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を探索(現在ログイン中のprovider)
                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);
}
}];

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

明示的なログインのカスタマイズ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.INSTANCE.signIn(AuthV4.ProviderType.GOOGLE, (result, playerInfo) -> {    
        if (result.isSuccess()) {    
            // 呼び出し成功    
            // playerInfo: 認証されたユーザー情報    
            // 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に連携されたアカウントにログインします。この2つの場合、ログインしたPlayerIDのIdPアカウントと実際のデバイスにログインしたIdPアカウント(DevicePlayer)が異なる可能性があります。将来的な実績やリーダーボードの使用に備えて、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:    
                // 正常    
                break;    
            case ResultAPI.Code.AuthV4ConflictPlayer:    
                // アカウントの衝突    
                // ex) Hive UI 使用時     
                // AuthV4.Helper.showConflict(...);    
                // or    
                // ex) 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()
                        // 例) Game 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 -> {    
                    // アカウントの衝突    
                    // ex) Hive UI 使用時    
                    // AuthV4.Helper.showConflict(...);    
                    // or    
                    // ex) GameUI 実装時    
                    // AuthV4.Helper.resolverConflict(...);// 現在のユーザー選択時    
                    // AuthV4.Helper.switchAccount(...);// ユーザー切り替え選択時    
                }    
                else -> {    
                    // その他の例外状況    
                }    
            }    
        }    
})

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

import com.hive.AuthV4;    
    import com.hive.ResultAPI;    
    AuthV4.ProviderType providerType = AuthV4.ProviderType.GOOGLE;    
    AuthV4.Helper.INSTANCE.syncAccount(providerType, (result, playerInfo) -> {    
        switch (result.getCode()) {    
            case Success:    
                // 正常    
                break;    
            case AuthV4ConflictPlayer:    
                // アカウントの衝突    
                // ex) Hive UI 使用時    
                // AuthV4.Helper.INSTANCE.showConflict(...);    
                // or    
                // ex) GameUI 実装時    
                // AuthV4.Helper.INSTANCE.resolverConflict(...);// 現在のユーザー選択時    
                // AuthV4.Helper.INSTANCE.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:    
            // アカウントの衝突    
            // ex) Hive UI 使用時     
            // AuthV4Interface.helper().showConflict(...);    
            // or    
            // ex) 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を使用する場合、実名認証されたユーザーのみが資金を充電・消費するサービスが可能(17. 5. 1施行)であるため、中国IPでログインできるIdPリストにはゲストログインが含まれていません。

ゲストログインを実行するには、ProviderType.GUESTをパラメータとしてsignIn()メソッドを呼び出してください。 次はゲストログインを実行する例のコードです。

Note

ゲスト状態のPlayerIDには、どのIdP認証もないため、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.INSTANCE.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 signIn: HIVEProviderTypeGuest handler: ^(ResultAPI *result, HIVEPlayerInfo *playerInfo) {    
        if ([result isSuccess]) {    
            // 認証成功    
            // playerInfo: 認証されたユーザー情報    
        }    
}];

カスタムログイン

カスタムログインカスタマイズされたログイン 機能で、Hiveが提供するIdP以外にゲーム自体で連携するIdPでログインを実装できます。 認証 v4 カスタム認証する に従ってカスタムログインAPI呼び出し時に使用する認証キー(authKey)を生成してみてください。

カスタムログインAPIを呼び出した後、コールバックで渡される**PlayerInfo**クラスのインスタンスを使用して、customProviderInfoDataデータにアクセスし、カスタムログインされたユーザー情報を確認できます。customProviderInfoDataの**ProviderType(enum)**はすべてCUSTOMとして同じに設定され、**ProviderName(String)**で詳細に区別できます。

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

カスタムログインを初めて実行した後にplayerId>とplayerTokenを発行された場合、カスタムログインAPIを再呼び出しする際にauthV4SessionExist(code)のResult 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, カスタムはTypeが固定されているため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」タイプとして直接実装したツイッターログイン
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, カスタムはタイプが固定
                                FString ProviderName = ProviderInfo->ProviderName; // ProviderNameで区別する必要がある
                                FString ProviderUserId = ProviderInfo->ProviderUserId; // 実装したTwitterログインに使用されたユーザーID
                        }
                } else if (Result.NeedExit()) {
                        // TODO: アプリ終了機能を実装してください
                        // 例) 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, カスタムはTypeが固定なので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

// ゲームで直接実装したツイッターログイン
    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, カスタムはTypeが固定されているため、providerNameで区別する必要があります
                                    providerInfo.providerName   // "CUSTOM_TWITTER"
                                    providerInfo.providerUserId // 自分で実装したTwitterログインに使用されたユーザーid
                            }
                    }
                    else if (result.needExit()) {
                            // TODO: アプリ終了機能を実装してください
                            // 例) 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

// ゲームで直接実装したツイッターログイン
    Game.Login("CUSTOM_TWITTER") { authKey: String ->
            AuthV4.INSTANCE.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, カスタムはTypeが固定されているので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、カスタムはTypeが固定なので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

// ゲームで直接実装したツイッターログイン
    [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, カスタムはTypeが固定されているため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連携時に1回のみ表示され、それ以外では表示されません。
  • ゲストログイン時にはユーザー名入力画面は表示されません。

認証トークンキーの有効性検証

ゲームサーバーでは、ログイン成功後に返されたToken、playerId、DID情報を利用して認証トークンキーの有効性を検証できます。Hive認証ではマルチデバイスログインと重複接続を許可しています。

同じアカウントでの重複接続を許可しない場合、ゲームサーバーは最初に接続したデバイスに案内メッセージを表示した後、ゲームを終了し、後から接続したデバイスでゲームが維持されるように処理します。この時、ゲームを終了せずに重複接続した場合、ゲームプレイ記録が正常に反映されない可能性があります。この機能を実装するには、検証を完了したトークンキーを管理するか、これを利用したゲーム自体のセッションキーを管理して処理する必要があります。

その機能は認証トークンキーの有効性検証Server APIを参考にして実装してください。

トークプラスログイントークン取得

認証 v4 インターフェースを通じて signIn() 完了後 AuthV4.getHiveTalkPlusLoginToken APIを呼び出して取得したログイントークンを Hive トークプラスログイン時に使用します。

Note

関連ガイドとしてHive トークプラスログインガイドを参照してください。

AuthV4.getHiveTalkPlusLoginToken((ResultAPI result, String loginToken) =&gt; {
if (result.isSuccess()) {
    // SUCCESS
    // TODO: 전달받은 loginToken 값 확인 후 HiveTalkPlus 로그인 진행
}
});
// Kotlin
AuthV4.getHiveTalkPlusLoginToken(object : AuthV4.AuthV4GetHiveTalkPlusLoginTokenListener {
        override fun onAuthV4GetHiveTalkPlusLoginToken(resultApi: ResultAPI, loginToken: String?) {
                if (resultApi.isSuccess) {
                        // SUCCESS
                }
        }
}
// Java
com.hive.AuthV4.INSTANCE.getHiveTalkPlusLoginToken(new com.hive.AuthV4.AuthV4GetHiveTalkPlusLoginTokenListener() {
        @Override
        public void onAuthV4GetHiveTalkPlusLoginToken(@NotNull ResultAPI result, @Nullable String loginToken) {
if (result.isSuccess()) {
// SUCCESS
}
        }
});
// Swift
AuthV4Interface.getHiveTalkPlusLoginToken { result, loginToken in
        if (result.isSuccess()) {
                // SUCCESS
        }
}
// Objective-c
[HIVEAuthV4 getHiveTalkplusLoginToken:^(HIVEResultAPI* result, NSString* loginToken) {
        if ([result isSuccess]) {
                // SUCCESS
        }
}];

IdPアカウント変更の検出

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

iOSはApple Game Center、AndroidはGoogle Playゲームのアカウントが変更された場合に動作し、現在ログインしているPlayerIDが該当するIdPに連携されている場合にのみ応答が伝達されます。IdPアカウント変更イベントを受け取った場合、ユーザーにデバイスにログインしているIdPアカウントを使用するかどうかを選択できるようにUIを構成します。ユーザーがデバイスにログインしている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) {
                // GameCenter ユーザー情報変更
        }
});
#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.INSTANCE.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 {
        // GameCenter ユーザー情報変更
    }
}

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
  • Logout動作時に認証情報である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:
                        // ログアウト成功
                        break;
                default:
                        // その他の例外状況
                        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.INSTANCE.signOut

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

AuthV4.Helper.INSTANCE.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]登入後,再試一次。
フランス語 Ta connexion au Game Center a été annulée.
Connecte-toi dans [Réglages >; Game Center] pour synchroniser ton compte Game Center et essaie de nouveau.
ドイツ語 Das Einloggen ins Apple Game Center wurde abgebrochen.
Die Synchronisation mit dem Game Center-Konto läuft über [Einstellungen >; Game Center]. Logge dich ein und versuche es erneut.
ロシア語 Ваш авторизация в Game Center была отменена.
Авторизуйтесь в Game Center через [Настройки >; Game Center] и повторите попытку.
スペイン語 Tu Inicio de Sesión en Game Center ha sido cancelado.
Inicia Sesión en [Configuración >; Game Center] para sincronizar a la Cuenta de Game Center, e inténtalo de nuevo.
ポルトガル語 O seu login no Game Center foi cancelado.
Faça o login em [Configurações >; Game Center] para sincronizar com a Conta do Game Center e tente novamente.
インドネシア語 Login ke Apple Game Center telah dibatalkan.
Hubungkan akun Game Center dengan login di [Pengaturan >; Game Center] dan coba lagi.
マレー語 Log masuk ke Game Center anda telah dibatalkan.
Log masuk di [Tetapan >; Game Center] untuk disegerakkan ke Akaun Game Center dan cuba lagi.
ベトナム語 Đã hủy bỏ đăng nhập vào Apple Game Center.
Đăng nhập tại [Cài đặt >; Game Center] để đồng bộ với tài khoản Game Center và thử lại.
タイ語 การล็อกอินเข้า Game Center ของคุณถูกยกเลิก
ล็อกอินที่ [การตั้งค่า >; Game Center] เพื่อเชื่อมต่อบัญชี Game Center และโปรดลองอีกครั้ง
イタリア語 L'accesso all'Apple Game Center è stato annullato.
Fai log-in su [Impostazioni >; Game Center] per sincronizzare il tuo account con il Game Center e riprova.
トルコ語 Apple Oyun Merkezine girişiniz iptal edilmiştir.
Oyun Merkezi Hesabına ulaşmak için [Ayarlar >; Oyun Merkezi]'nden giriş yapın ve tekrar deneyin.
アラビア語 تم إلغاء تسجيل الدخول إلى مركز الألعاب.
سجل الدخول إلى [الإعدادات >; مركز الألعاب] للمزامنة مع حساب مركز الألعاب وحاول مرة أخرى。