跳轉至

登录注销

登入驗證包括以下步驟。

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 列表中。
  • 由於只有經過實名認證的用戶才能從中國 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, ...) 的回調結果為取消時使用 Game Center 取消指導消息

Note

如果用户尝试使用 Apple 登录,而他们的设备没有使用 Apple ID 登录,AuthV4Helper 类的 connect()signIn() 方法 将触发 AuthV4SignInAppleUnknown 错误。Apple ID 登录指导弹出窗口将自动显示,因此游戏工作室无需显示单独的指导弹出窗口。

如果用户尝试使用 Apple 登录,而他们的设备未使用 Apple ID 登录,则在调用 AuthV4Helper 类的 connect()signIn() 方法的过程中会发生 AuthV4SignInAppleUnknown 错误 这里。Apple ID 登录指导弹出窗口会自动显示,因此游戏工作室无需显示单独的 弹出窗口 进行指导。

自動登入和隱式登入

自動登入

這意味著用戶通過在 iOS 上連結他們的 Apple Game Center 帳戶和在 Android 上連結他們的 Google Play Games 帳戶,自動登錄,而無需選擇登錄方法。它實現了自動登錄,並在自動登錄失敗時執行隱式登錄。

要在 iOS 環境中使用自動登錄,您需要添加 Game Center 權限,Unity 會通過 Unity PostProcess 自動添加該權限,前提是您勾選了「Apple GameCenter」依賴項。在 iOS 原生環境中,Xcode 會自動添加 Game Center 權限。

要在 iOS 環境中使用自動登錄,您需要添加遊戲中心權限。在 Unity 中,如果您已檢查“Apple GameCenter”依賴項,它將通過 Unity 的後處理自動添加該權限。對於 iOS 原生,Xcode 將自動添加遊戲中心權限。

離線模式

在 Hive SDK v4 23.1.0 及以上版本中,即使在應用程式啟動時用戶設備未連接到網絡,也可以提供自動登錄功能(AuthV4.signIn 使用 ProviderType.AUTO,或 AuthV4.Helper.signIn)。要使用離線模式,請遵循以下說明。

  1. 您必須成功在線執行應用程式以進行明確、隱式、來賓或自定義登錄,並獲得 playerIdplayerToken

從應用程式開發者的角度來看,必須至少在線上成功執行過一次 AuthV4.Helper.signInAuthV4.showSignInAuthV4.signInWithAuthKey,並接收到 playerIdplayerToken 作為回調。從使用者的角度來看,使用者必須至少在線上成功登入應用程式一次,並且其設備必須連接到網路。然而,如果使用者的帳戶在他們上次嘗試在線登入時被暫停或限制,即使在離線模式下,使用者也將無法登入。

  1. 在 Hive 控制台中啟用離線模式 應用中心 > 專案管理 > 遊戲詳情 > Hive 產品設定

在 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 權限。如果您已檢查 'Apple GameCenter' 依賴項,它將通過 Unity PostProcess 自動添加相應的權限。

Note

使用 AuthV4Helper 類時

如果正在运行游戏的用户在 PGS 期间拒绝隐式登录尝试,它将记住这一点,并且不再尝试隐式登录。即使在玩家会话保持的情况下可以进行自动登录,它也会继续记住隐式登录被拒绝的状态。此内容基于 Google Play 游戏服务指南。

以下是一個執行自動登錄的示例代碼。

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"

// 嘗試登錄 (signIn) 到 Hive SDK
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::signIn

// Attempt to sign in (signIn) with Hive SDK    
    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 登入
 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 authentication UI request    
    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 authentication UI request    
    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: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) 在登錄不同帳戶時,如果出現帳戶衝突,會提示用戶顯示一個對話框,詢問是否使用上次登錄的帳戶登錄。

隱式登錄行為:PC

在 PC 上的隱式登錄(如 Hive SDK Unity Windows 的 Windows 平台)(AuthV4.Helper.signIn) 在第一次登錄後,當使用不同的帳戶登錄時,會自動使用最後一次登錄的帳戶進行登錄。帳戶衝突不會發生。

明確登入

明確登錄是指用戶選擇身份提供者(IdP)進行身份驗證的過程。如果自動登錄和隱式登錄都失敗,則在用戶移動到遊戲標題屏幕後點擊標題時實施明確登錄。

明確的登錄用戶界面可以使用 Hive SDK 提供的用戶界面,也可以使用 Hive SDK 初始化完成後返回的 IdP 列表進行自定義。如果您正在自定義用戶界面,請參考 明確登錄自定義 部分。

IdP 列表由 Hive 平台根據各國的政策進行控制和提供。例如,在中國,不提供 Google Play 遊戲和 Facebook,以及客人。

明確的登錄截圖

由 SDK 提供的 IdP 選擇 UI

當使用SDK提供的UI進行實作時

要使用 SDK 提供的 UI 實現明確登錄,您可以簡單地調用 showSignIn() 方法來調用 IdP 列表 UI。

Note

如果用户通过按下“X”按钮关闭SDK提供的IdP选择UI,则必须提供再次登录的方式。用户仍然没有登录。

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: Implement the app exit feature
        // 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 authentication UI request
AuthV4::showSignIn([=](ResultAPI const & result, PlayerInfo const & playerInfo) {
if (result.isSuccess()) {
        // Authentication successful
        // playerInfo: Authenticated user information

        // 獲取電子郵件信息的示例
        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 authentication UI request
AuthV4.showSignIn(object : AuthV4.AuthV4SignInListener {
override fun onAuthV4SignIn(result: ResultAPI, playerInfo: AuthV4.PlayerInfo?) {
        if (result.isSuccess) {
                // Authentication successful
                // playerInfo: Authenticated user information

                // 獲取電子郵件信息的示例
                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: 實現應用程序退出功能
                // e.g.) exitProcess(0)
        }
}
})

API 參考: com.hive.AuthV4.showSignIn

// Hive SDK AuthV4 authentication UI request
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);
}
}];

明確的登入自訂

可自訂的明確登錄 UI 可以使用 providerTypeList 實現。當調用 AuthV4.setup() 方法以初始化 Hive SDK,或在初始化後調用 AuthV4.Helper.getIDPList() 方法時,providerTypeList 是返回的響應回調處理程序。當您希望根據遊戲 UI 顯示登錄屏幕或主要暴露與特定 IdP 的集成時,會使用此功能。在實現可自訂的 UI 後,根據用戶的操作調用 signIn() 方法,並使用所需的 ProviderType 來實現登錄。

Note
  • UI範例截圖顯示登錄屏幕上的Facebook整合按鈕

以下是一段示範源代碼,假設用戶在自定義的明確登錄用戶界面中選擇了 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()) {
                // Call succeeded (PlayerInfo: authenticated user information)

                // 取得 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 相關聯的帳戶。在這兩種情況下,登錄的 PlayerID 的 IdP 帳戶可能與實際設備(DevicePlayer)上登錄的 IdP 帳戶不同。將提供指導以統一這兩個帳戶,以便為未來的成就或排行榜使用做好準備。

  • 檢查由 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:    
                // 帳戶衝突    
                // 例如) 當使用 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.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:    
                // 帳戶衝突    
                // 例如) 當使用 Hive UI    
                // AuthV4.Helper.INSTANCE.showConflict(...);    
                // 或    
                // 例如) 當實作 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:    
            // 帳戶衝突    
            // 例如) 使用 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 列表中。

要執行訪客登錄,請調用 signIn() 方法,並將 ProviderType.GUEST 作為參數。
這裡是執行訪客登錄的示例代碼。

Note

The 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()) {    
            // Authentication successful    
            // playerInfo: Authenticated user information    
        }    
});

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: 已验证用户信息    
        }    
}];

自訂登入

自訂登入是一項功能,允許您實現與遊戲本身整合的身份提供者(IdP)進行登入,除了Hive提供的IdP之外。請嘗試創建一個身份驗證密鑰(authKey),以便在根據Authenticate v4 Custom Authentication調用自訂登入API時使用。

在调用自定义登录 API 后,您可以通过作为回调接收到的 PlayerInfo 类的实例访问 customProviderInfoData 数据,以检查自定义登录用户的信息。 customProviderInfoDataProviderType (枚举) 统一设置为 CUSTOM,并且可以通过 ProviderName (字符串) 进行详细区分。

在遊戲中實現自定義登錄的 IdP 的信息不包含在調用 AuthV4 類的 setup()showSignIn() 方法的結果中。

如果您在第一次執行自定義登錄後收到了 playerIdplayerToken,則在重新調用自定義登錄 API 時,authV4SessionExist(code) 的結果 API 將作為回調傳遞。在這種情況下,您應該使用 ProviderType.Auto 作為參數調用 signIn(),以便使用已登錄的帳戶進行自動登錄。請參考下面的示例代碼。

AuthV4 類的 connect()disconnect() 方法不支持自定義登錄 IdP 的額外集成和斷開。自定義登錄 IdP 的額外集成和斷開由 connectWithAuthKey()disconnectWithName() 方法支持。

這是一個實現自定義登錄的示例代碼。

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 have fixed Type
                                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: Implement app exit functionality
                        // e.g.) UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit, false);
                } else if (Result.Code == FHiveResultAPI::ECode::AuthV4SessionExist) {
                        // If playerId and playerToken have already been issued and automatic login is needed
                        // TODO: FHiveAuthV4.SignIn(EHiveProviderType::GUEST, Delegate);
                } else if (Result.Code == FHiveResultAPI::ECode::AuthV4NotInitialized) {
                        // TODO: SDK initialization needed
                } else if (Result.Code == FHiveResultAPI::ECode::AuthV4InvalidParam) {
                        // TODO: Check if the value of the provided authKey is empty
                }
        }));
}

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: Implement app exit functionality
                            // e.g.) exitProcess(0)
                    }
                    else if (result.code == ResultAPI.Code.AuthV4SessionExist) {
                            // If playerId and playerToken have already been issued and automatic login is needed
                            // TODO: AuthV4.signIn(AuthV4.ProviderType.AUTO, authV4SignInListener)
                    }
                    else if (result.code == ResultAPI.Code.AuthV4NotInitialized) {
                            // TODO: SDK initialization required
                    }
                    else if (result.code == ResultAPI.Code.AuthV4InvalidParam) {
                            // TODO: Check if the value of the provided authKey is NULL or empty
                    }
            }
    })

    }

API 參考: com.hive.Auth4.signIn

// Twitter 登入直接在遊戲中實現
    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,自定義類型由類型固定,因此需要通過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 遊戲帳戶。如果您需要檢查遊戲過程中的 IdP 帳戶是否與當前 PlayerID 相關聯的 IdP 帳戶不同,請在初始化 SDK 後調用 setProviderChangedListener()。通過調用此 API,當遊戲恢復時,您將收到一個事件,指示設備上設置的 IdP 帳戶已更改。

當Apple Game Center帳戶更改時,iOS會運作;當Google Play Games帳戶更改時,Android會運作,並且僅當當前登錄的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) {
                // 更改 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 游戏服务帐户
    }
});

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 游戏服务帐户
                }
        }
})

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 遊戲服務帳戶
        }
});

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
  • 登出時,身份驗證信息 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 helper] 登出

#import <HIVEService/HIVEService-Swift.h> 

[[HIVEAuthV4 helper] signOut: ^(HIVEResultAPI *result, HIVEPlayerInfo *playerInfo) {
        switch ([result getCode]) {
                case HIVEResultAPICodeSuccess:
                        // 登录成功
                        break;
                default:
                        // 其他异常
                        break;
        }
}];

遊戲中心取消通知文本

語言 短語
Korean Apple Game Center 登入已取消。
請在 [設定 > Game Center] 登入以同步您的 Game Center 帳戶,然後再試一次。
English 您的 Game Center 登入已取消。
請在 [設定 > Game Center] 登入以同步到 Game Center 帳戶,然後再試一次。
Japanese Apple Game Center ログインがキャンセルされました。
Game Center アカウントと連動するには [設定 > Game Center] にログインした後、再度お試しください。
Simplified Chinese Apple Game Center 已登出。
如果您想與 Game Center 帳戶同步,請在設備的 [設定 > Game Center] 中再次登入,然後再試一次。
Traditional Chinese 登入Apple Game Center已取消。
若想連動Game Center帳號,請至[設定 > Game Center]登入後,再試一次。
French 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.
German 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.
Russian Ваш авторизация в Game Center была отменена.
Авторизуйтесь в Game Center через [Настройки > Game Center] и повторите попытку.
Spanish 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.
Portuguese 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.
Indonesian Login ke Apple Game Center telah dibatalkan.
Hubungkan akun Game Center dengan login di [Pengaturan > Game Center] dan coba lagi.
Malaysian Log masuk ke Game Center anda telah dibatalkan.
Log masuk di [Tetapan>Game Center] untuk disegerakkan ke Akaun Game Center dan cuba lagi.
Vietnamese Đã 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.
Thai การล็อกอินเข้า Game Center ของคุณถูกยกเลิก
ล็อกอินที่ [การตั้งค่า>Game Center] เพื่อเชื่อมต่อบัญชี Game Center และโปรดลองอีกครั้ง
Italian 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.
Turkish 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.
Arabic تم إلغاء تسجيل الدخول إلى مركز الألعاب.
سجل الدخول إلى [الإعدادات> مركز الألعاب] للمزامنة مع حساب مركز الألعاب وحاول مرة أخرى。