跳轉至

登录注销

在認證中,登錄由以下步驟組成。

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 後處理自動添加該權限。對於 iOS 原生,Xcode 將自動添加 Game Center 權限。

離線模式

Hive SDK v4 23.1.0 及更高版本提供自動登錄功能(AuthV4.signIn 使用 ProviderType.AUTO,或 AuthV4.Helper.signIn),即使用戶的設備未連接到網絡。要使用離線模式,請按照以下說明操作:

  1. 必須至少在在線模式下運行應用程序一次,並成功進行明確、隱式、訪客或自定義登錄,隨後發出playerIdplayerToken
    從應用程序開發者的角度來看,必須至少成功執行過一次AuthV4.Helper.signInAuthV4.showSignInAuthV4.signInWithAuthKey,並在在線狀態下通過回調接收playerIdplayerToken。從用戶的角度來看,他們必須在設備連接到網絡的情況下至少成功登錄過一次應用程序。然而,如果用戶的帳戶在他們上次在線登錄嘗試期間被暫停或限制,他們將無法在離線模式下登錄。

應用中心 > 管理專案 > 遊戲詳情 > 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。如果登錄失敗,則根據響應顯示適當的登錄頁面。

AuthV4.Helper.signIn會利用PlayerID的認證令牌金鑰嘗試自動登錄。如果沒有之前登錄過的認證令牌金鑰,則在iOS的情況下會自動登錄Apple Game Center,在Android的情況下會自動登錄Google Play遊戲。如果登錄失敗,則根據響應值構建適當的登錄畫面。

Note

要使用自動登錄,必須添加Game Center Entitlement。如果勾選了'Apple GameCenter' Dependency,則會通過Unity PostProcess自動添加該Entitlement。

Note

您必須添加遊戲中心權限才能使用自動登錄。如果您已檢查“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"

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

// 嘗試 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 參考: com.hive.Auth4.Helper.signIn

// 嘗試 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: 實作應用程式退出功能
            // ex) exitProcess(0)
        } else {
            when (result.code) {
                ResultAPI.Code.AuthV4ConflictPlayer -> {
                    // 帳戶衝突
                }
                ResultAPI.Code.AuthV4HelperImplifiedLoginFail -> {
                    // 隱式登入失敗
                    // ex) AuthV4.showSignIn(...);
                }
                else -> {
                    // 其他異常
                }
            }
        }
    }
})

API 參考: com.hive.Auth4.signIn

// 嘗試 Hive SDK 登入 (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: 實現應用程式退出功能
            // ex) System.exit(0);
        } else {
            switch(result.code) {
                case AuthV4ConflictPlayer:
                    // 帳戶衝突
                    break;
                case AuthV4HelperImplifiedLoginFail:
                    // 隱式登入失敗
                    // ex) AuthV4.showSignIn(...);
                    break;
                default:
                    // 其他例外
                    break;
            }
        }
    }
});

API 參考: AuthV4Interface.signIn

// 嘗試 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

// 嘗試 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 提供的 UI 或在使用身份提供者 (IdP) 列表初始化 Hive SDK 後在遊戲中自定義的 UI 組成。如果您自定義 UI,請參見 自定義明確登錄 UI

Hive 平台根據各國的政策控制並提供 IdP 列表。例如,Google Play 遊戲、Facebook 和訪客登錄在中國不可用。

一個明確登錄的示例畫面

由 Hive SDK 提供的 IdP 選擇 UI


當使用 Hive SDK 提供的 UI 實現該功能時

要使用 Hive SDK 提供的 UI 實現明確登錄,您可以通過調用 showSignIn() 方法顯示 IdP 列表 UI。

Note

确保在用户点击 SDK 提供的 IdP 选择 UI 中的 X 按钮关闭后,提供再次登录的方法。因为用户尚未登录。

Note

如果您想自定義明確登錄,請參見這裡

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:
                                // 隱式登入失敗
                                // 例如) 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:
                                // 隱式登入失敗
                                // 例如) [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 連結的帳戶。在這兩種情況下,登入的 PlayerID 的 IdP 帳戶和實際設備上登入的 IdP 帳戶 (DevicePlayer) 可能會不同。為了未來使用成就或排行榜,將提供指導語句以統一這兩個帳戶。

  • 確認使用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:
                        // 帐户冲突
                        // ex) 使用 Hive UI 时
                        // FHiveAuthV4::Helper::ShowConflict()
                        // ex) 实现游戏 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:    
            // 帳戶衝突    
            // ex) 使用 Hive UI 時     
            // AuthV4::Helper::showConflict(...);    
            // or    
            // ex) 實現 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(...);    
                    // 或者    
                    // 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(...);    
                // 或者    
                // 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(...);    
            // 或者    
            // 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:    
                // 帳戶衝突    
                // ex) 使用 Hive UI 時     
                // [[HIVEAuthV4 helper] showConflict: ...];    
                // 或者    
                // ex) 實現 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

沒有任何 IdP 認證的訪客狀態的 PlayerID 沒有 playerInfo 的 providerInfoData。

API 參考: hive.AuthV4.signIn

using hive;    
    AuthV4.signIn(AuthV4.ProviderType.GUEST, (ResultAPI result, AuthV4.PlayerInfo playerInfo) => {    
        if (result.isSuccess()) {    
            // 認證成功    
            // playerInfo: 認證的使用者資訊    
        }    
});
#include "HiveAuthV4.h"

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

        if (Result.IsSuccess()) {
                // 呼叫成功 (PlayerInfo: 認證的使用者資訊)
        }
}));

API 參考: Auth4::signIn

#include <HIVE_SDK_Plugin/HIVE_CPP.h>    
    using namespace std;     
    using namespace hive;    
    AuthV4::signIn(ProviderType::GUEST, [=](ResultAPI const & result, PlayerInfo const & playerInfo) {    
        if (result.isSuccess()) {    
            // 認證成功    
            // playerInfo: 認證的使用者資訊    
        }    
});

API 參考: AuthV4.signIn

import com.hive.AuthV4    
    import com.hive.ResultAPI    
    AuthV4.signIn(AuthV4.ProviderType.GUEST, object : AuthV4.AuthV4SignInListener {    
        override fun onAuthV4SignIn(result: ResultAPI, playerInfo: AuthV4.PlayerInfo?) {    
            if (result.isSuccess) {    
                // 認證成功    
                // playerInfo: 認證的用戶信息    
            }    
        }    
})

API 參考: com.hive.Auth4.signIn

import com.hive.AuthV4;    
    import com.hive.ResultAPI;    
    AuthV4.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 數據以確認自定義登錄的用戶信息。 customProviderInfoDataProviderType(enum) 都設置為 CUSTOM,並可以通過 ProviderName(String) 進行詳細區分。

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

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

AuthV4 類的 connect()disconnect() 方法不支持自定義登錄 IdP 的額外連接和解除。使用 connectWithAuthKey()disconnectWithName() 方法支持自定義登錄 IdP 的額外連接和解除。

自訂登錄的範例代碼。

API 參考: hive.AuthV4.signIn

// 在遊戲中實現的 Twitter 登入    
    Game.Login("CUSTOM_TWITTER", (string authKey) => {    
    AuthV4.signInWithAuthKey(authKey, (ResultAPI result, PlayerInfo playerInfo) => {    
        if (result.isSuccess()) {    
            Dictionary<string, ProviderInfo> customProviderInfoData = playerInfo.customProviderInfoData;    
            ProviderInfo providerInfo = customProviderInfoData["CUSTOM_TWITTER"];    
            // 確認以下的用戶連接信息    
            providerInfo.providerType;     // ProviderType.CUSTOM,自定義類型是固定的,需要通過 providerName 來區分    
            providerInfo.providerName;   // "CUSTOM_TWITTER"    
            providerInfo.providerUserId;  // 用於實現的 Twitter 登入的用戶 id    
            return;    
        }    
        else if (result.code == ResultAPI.Code.AuthV4SessionExist) {    
            // 如果已經發放了 playerId 和 playerToken 並需要自動登入    
            // TODO: AuthV4.signIn(ProviderType.AUTO, (ResultAPI _result, PlayerInfo playerInfo) => {});    
        }    
        else if (result.code == ResultAPI.Code.AuthV4NotInitialized) {    
            // TODO: 需要初始化 SDK    
        }    
        else if (result.code == ResultAPI.Code.AuthV4InvalidParam) {    
            // TODO: 確認傳遞的 authKey 值是否為 NULL 或空值    
        }    
        else if (result.needExit()) {    
            // TODO: 實現應用程序退出功能     
            // 例如) Application.Quit();    
        }    
    });    
});
#include "HiveAuthV4.h"

// 在遊戲中以 "CUSTOM_TWITTER" 類型直接實現的推特登錄
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,自定義的類型是固定的,需要通過 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,因為自定義類型是固定的,所以需要用 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

// 在遊戲中實現的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

// 遊戲中直接實現的推特登錄
    [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 連接時僅顯示一次,之後不再顯示。
  • 在訪客登錄時,不會顯示用戶名輸入畫面。

認證令牌密鑰有效性驗證

遊戲伺服器可以利用登錄成功後返回的 Token、playerId 和 DID 資訊來驗證認證令牌密鑰的有效性。Hive 認證允許多設備登錄和重複連接。

如果不允許使用相同帳號重複登入,遊戲伺服器會先在先前登入的設備上顯示提示訊息,然後結束遊戲,並處理以便後來登入的設備可以保持遊戲。在這種情況下,如果在不結束遊戲的情況下重複登入,遊戲的遊玩記錄可能無法正常反映。要實現該功能,需要管理已驗證的令牌金鑰,或管理利用該令牌的遊戲本身的會話金鑰來進行處理。

請參考驗證令牌有效性檢查伺服器 API來實現該功能。

獲取 TalkPlus 登入令牌

通過認證 v4 接口完成 signIn() 後,調用 AuthV4.getHiveTalkPlusLoginToken API 獲取的登入令牌用於 Hive TalkPlus 登入時使用。

Note

相關指南請參考 Hive TalkPlus 登入指南

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 帳戶不同,請在 SDK 初始化後調用 setProviderChangedListener()。調用該 API 後,您可以在遊戲恢復時收到設備上設置的 IdP 帳戶已更改的事件。

iOS 會在 Apple Game Center 及 Android 會在 Google Play 遊戲的帳戶變更時運作,並且只有當當前登錄的 PlayerID 與該 IdP 相關聯時才會傳遞響應。當收到 IdP 帳戶變更事件時,會為用戶構建 UI 以選擇是否使用設備上登錄的 IdP 帳戶。當用戶選擇設備上登錄的 IdP 帳戶時,將調用 signOut 進行登出,然後進行隱式登錄。

Warning

自2021年7月以來安裝的Google Play遊戲的設備,由於Google Play遊戲的運行問題,無法在背景中更改IdP帳戶。

Note

此功能可能會導致遊戲暫停並要求更改帳戶,僅在需要帳戶同步的時刻,例如進入大廳或商店時,才可有限使用。

以下是用户在游戏重新开始时,接收设备上设置的 IdP 账户已更改的事件的示例代码。

API 參考: hive.AuthV4.setProviderChangedListener

using hive;

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

        if (providerInfo != null && providerInfo.providerType == AuthV4.ProviderType.APPLE) {
                // 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 Your login to the Game Center has been canceled.
Log in at [Settings >; Game Center] to sync to the Game Center Account and try again.
Japanese Apple Game Center ログインがキャンセルされました。
Game Center アカウントと連動するには [設定 >; Game Center] にログインした後、再度お試しください。
Chinese (Simplified) Apple Game Center已退出登录。
若想与Game Center账号同步,请在设备[设置 >; Game Center]中重新登录后再试。
Chinese (Traditional) 登入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.
Malay 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 تم إلغاء تسجيل الدخول إلى مركز الألعاب.
سجل الدخول إلى [الإعدادات >; مركز الألعاب] للمزامنة مع حساب مركز الألعاب وحاول مرة أخرى。