登录注销
登录认证包括以下步骤。
Note
- SDK 4.7.0 以下的版本不支持 Helper。请参考 [以下内容] 了解现有的登录应用程序方法。
- 有关 AuthV4.Helper 的描述,请参考 身份验证 页面。
登录¶
登录认证包括以下步骤。
Authv4Helper 是一个执行与登录相关的一系列过程的类,并根据响应值配置为导航到适当的屏幕。 配置登录时,请参考以下几点。
Note
苹果不支持在 iOS 企业构建中使用 Apple Game Center 和应用内购买。因此,在 iOS 企业构建中无法使用 Apple Game Center 账户的隐式登录,显式登录也无法使用 Apple Game Center。在为 iOS 企业构建时,控制台中的 登录类型 不能包含 Apple Game Center。
Note
- 如果游戏主要针对13岁以下的儿童,则无法应用Google Play游戏服务,并且在Google构建中无法使用隐式登录。有关更多信息,请参阅Google Play游戏服务的质量检查清单。
- Google Play游戏的隐式登录应仅在初始登录期间尝试。有关更多信息,请参阅Google开发者指南1.5 记住如果玩家拒绝登录。
Note
- 在中国,无法使用Google Play游戏,因此在Android上无法使用隐式登录。
- 在中国,无法使用Facebook,因此Facebook未包含在IdP列表中。
- 在中国,只有经过实名认证的用户才能充值或消费服务(自2017年5月1日起生效),因此来自中国IP的登录未在IdP列表中包含游客登录。
Note
iOS即使在取消Apple Game Center登录的情况下也不会显示登录屏幕。因此,指导消息可以通过SDK调用AuthV4Helper
类的showGameCenterLoginCancelDialog()
方法直接显示,或者由游戏选择显示。如果您想为用户提供重新连接其Game Center帐户的消息,请在AuthV4.signIn(AuthV4.ProviderType.APPLE, ...)
和AuthV4.connect(AuthV4.ProviderType.APPLE, ...)
的回调结果为取消时使用Game Center取消指导消息。
Note
如果用户在其设备未使用 Apple ID 登录时尝试使用 Apple 登录,则在调用 AuthV4Helper 类的 connect()
、signIn()
方法的过程中会发生 AuthV4SignInAppleUnknown 错误 这里。Apple ID 登录指导弹出窗口会自动显示,因此游戏工作室无需显示单独的指导弹出窗口。
如果用户尝试使用 Apple 登录,而他们的设备没有登录 Apple ID,则在调用 AuthV4Helper 类的 connect()
、signIn()
方法 的过程中会发生 AuthV4SignInAppleUnknown 错误。Apple ID 登录指导弹出窗口会自动显示,因此游戏工作室无需显示单独的 弹出窗口 进行指导。
Note
对于 PC X IdP 登录,可以使用 X 账户登录,但在 X 登录屏幕上不支持使用 Google 和 Apple 账户集成登录。 要使用 Google 或 Apple 账户集成登录 X,您必须先在外部浏览器中使用相应的账户登录,然后在游戏中继续进行 X 登录。
对于 Steam Deck X IdP 登录,仅支持使用 X 账户登录。
自动登录和隐式登录¶
自动登录¶
这指的是一种登录方法,用户不选择登录方式,在iOS上,它会自动链接到Apple Game Center账户,而在Android上,它链接到Google Play Games账户。它实现了自动登录,并在自动登录失败的情况下执行隐式登录。
在iOS环境中使用自动登录,您需要添加Game Center权限,如果您勾选了“Apple GameCenter”依赖项,Unity会通过Unity PostProcess自动添加。在iOS Native中,Xcode会自动添加Game Center权限。
离线模式¶
在 Hive SDK v4 23.1.0 及以上版本中,即使用户设备在应用启动时未连接到网络,也可以提供自动登录功能(AuthV4.signIn
使用 ProviderType.AUTO
,或 AuthV4.Helper.signIn
)。要使用离线模式,请按照以下说明进行操作。
- 您必须成功在线执行应用程序以进行显式、隐式、访客或自定义登录,并接收到
playerId
和playerToken
。
从应用开发者的角度来看,必须至少在线成功执行过一次 AuthV4.Helper.signIn
、AuthV4.showSignIn
或 AuthV4.signInWithAuthKey
,才能通过回调接收 playerId
和 playerToken
。从用户的角度来看,用户必须在设备连接到网络时至少成功登录过一次应用程序。然而,如果用户的账户在上次在线登录尝试时被暂停或限制,用户即使在离线模式下也无法登录。
- 在 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:
k // 其他异常
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::Helper::signIn
// 尝试使用 Hive SDK 登录 (signIn)
AuthV4::Helper::signIn([=](ResultAPI const & result, std::shared_ptr playerInfo) {
if (result.isSuccess()) {
// 登录成功
} else if (result.needExit()) {
// TODO: 实现应用退出功能
// 对于 Cocos2d-x 引擎用户
// 例如: exit(0);
// 对于 Unreal 引擎用户
// 例如: UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit, false);
} else {
switch (result.code) {
case ResultAPI::AuthV4ConflictPlayer:
// 账户冲突
break;
case ResultAPI::AuthV4HelperImplifiedLoginFail:
// 隐式登录失败
// 例如) AuthV4.showSignIn(...);
break;
default:
break;
}
}
});
API 参考: hive.AuthV4.Helper.signIn
// 尝试使用 Hive SDK 登录
AuthV4.Helper.signIn(object : AuthV4.Helper.AuthV4HelperListener {
override fun onAuthV4Helper(result: ResultAPI, playerInfo: AuthV4.PlayerInfo?) {
if (result.isSuccess) {
// 登录成功
} else if (result.needExit()) {
// TODO: 实现应用退出功能
// e.g.) exitProcess(0)
} else {
when (result.code) {
ResultAPI.Code.AuthV4ConflictPlayer -> {
// 账户冲突
}
ResultAPI.Code.AuthV4HelperImplifiedLoginFail -> {
// 隐式登录失败
// e.g.) AuthV4.showSignIn(...)
}
else -> {
// 其他异常情况
}
}
}
}
})
API 参考: com.hive.AuthV4.Helper.signIn
// Hive SDK AuthV4 认证 UI 请求
AuthV4.Helper.signIn(new AuthV4.Helper.AuthV4HelperListener() {
@Override
public void onAuthV4Helper(ResultAPI result, PlayerInfo playerInfo) {
if (result.isSuccess()) {
// 认证成功
} else if (result.needExit()) {
// TODO: 实现应用退出功能
// e.g.) System.exit(0);
} else {
switch (result.code) {
case ResultAPI.Code.AuthV4ConflictPlayer:
// 账户冲突
break;
case ResultAPI.Code.AuthV4HelperImplifiedLoginFail:
// 隐式登录失败
// ex) AuthV4.showSignIn(...);
break;
default:
// 其他异常情况
break;
}
}
}
});
API 参考: HIVEAuthV4Helper:signIn
// Hive SDK AuthV4 authentication UI request
AuthV4Interface.helper().signIn { (result, playerInfo) in
if result.isSuccess() {
// 认证成功
} else if result.needExit() {
// TODO: 实现应用退出功能
// 例如)exit(0)
} else {
switch result.getCode() {
case .authV4ConflictPlayer:
// 账户冲突
break
case .authV4HelperImplifiedLoginFail:
// 隐式登录失败
// 例如)AuthV4.showSignIn(...)
break
default:
// 其他异常情况
break
}
}
}
}
API 参考: HIVEAuthV4:signIn
// 尝试登录 (signIn) 到 Hive SDK
[[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提供的UI进行实现时¶
要使用SDK提供的UI实现显式登录,您只需调用showSignIn()
方法以调用IdP列表UI。
Note
用户必须提供一种方式以便在关闭SDK提供的IdP选择UI中的“X”按钮后再次登录。用户仍未登录。
Note
要自定义显式登录,请参考以下内容。
API 参考: hive.AuthV4.showSignIn
// Hive SDK AuthV4 认证 UI 请求
AuthV4.showSignIn((ResultAPI result, AuthV4.PlayerInfo playerInfo)=>{
if (result.isSuccess()) {
// 认证成功
// playerInfo : 认证用户信息
// 获取电子邮件信息的示例
foreach (KeyValuePair<AuthV4.ProviderType, AuthV4.ProviderInfo> entry in playerInfo.providerInfoData) {
AuthV4.ProviderInfo providerInfo = entry.Value;
if(providerInfo.providerEmail != null && providerInfo.providerEmail != "") {
string email = providerInfo.providerEmail;
break;
}
}
}
else if (result.needExit()) {
// TODO: 实现应用程序退出功能
// e.g.) Application.Quit();
}
});
#include "HiveAuthV4.h"
// Hive SDK AuthV4 认证 UI 请求
FHiveAuthV4::ShowSignIn(FHiveAuthV4OnSignInDelegate::CreateLambda([this](const FHiveResultAPI& Result, const FHivePlayerInfo& PlayerInfo) {
if (Result.IsSuccess()) {
// 认证成功 (PlayerInfo: 经过认证的用户信息)
// 获取电子邮件信息的示例
for (const auto& ProviderInfoEntry : PlayerInfo.ProviderInfoData) {
FHiveProviderInfo ProviderInfo = ProviderInfoEntry.Value;
FString Email = ProviderInfo.ProviderEmail;
}
} else if (Result.NeedExit()) {
// TODO: 实现应用程序退出功能
// 示例) UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit, false);
}
}));
API 参考: AuthV4::showSignIn
// Hive SDK AuthV4 认证 UI 请求
AuthV4::showSignIn([=](ResultAPI const & result, PlayerInfo const & playerInfo) {
if (result.isSuccess()) {
// 认证成功
// playerInfo: 认证用户信息
// 获取电子邮件信息的示例
for(auto it = playerInfo.providerInfoData.begin(); it != playerInfo.providerInfoData.end(); ++it) {
hive::ProviderInfo providerInfo = it->second;
if(!providerInfo.providerEmail.empty()) {
std::string email = providerInfo.providerEmail;
break;
}
}
}
else if (result.needExit()) {
// TODO: 实现应用退出功能
// Cocos2d-x 引擎用户
// 示例) exit(0);
// Unreal 引擎用户
// 示例) UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit, false);
}
});
API 参考: com.hive.AuthV4.showSignIn
// Hive SDK AuthV4 认证 UI 请求
AuthV4.showSignIn(object : AuthV4.AuthV4SignInListener {
override fun onAuthV4SignIn(result: ResultAPI, playerInfo: AuthV4.PlayerInfo?) {
if (result.isSuccess) {
// 认证成功
// playerInfo: 认证用户信息
// 获取电子邮件信息的示例
playerInfo?.let {
for ((key, value) in it.providerInfoData) {
var providerInfo: AuthV4.ProviderInfo = value
if(providerInfo.providerEmail.isNotEmpty()) {
val email = providerInfo.providerEmail
break
}
}
}
} else if (result.needExit()) {
// TODO: 实现应用程序退出功能
// e.g.) 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: 实现应用退出功能
// e.g. 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 {
// 搜索 providerInfo,其中 providerEmail 存在(当前登录的提供者)
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
实现。providerTypeList
是在调用 AuthV4.setup()
方法初始化 Hive SDK 时返回的响应回调处理程序,或者在初始化后调用 AuthV4.Helper.getIDPList()
方法时返回的。此功能用于根据游戏 UI 显示登录屏幕,或主要暴露与特定 IdP 的集成。在实现可自定义的 UI 后,根据用户的操作调用 signIn()
方法,并使用所需的 ProviderType 来实现登录。
Note
- 创建登录按钮时,应参考每个 IdP 提供的设计指南。
- 游戏中心:没有具体规定
- Google Play 游戏:品牌指南
- Google:品牌指南
- Hive 会员:Hive BI 指南
- Facebook:品牌资源中心
- QQ:政策和规定
- 微信:主要品牌和指南
- VK:VK 品牌手册
- 苹果:人机界面指南
- LINE:LINE 登录按钮设计指南
- 华为:HUAWEI ID 图标规范
- Steam:Steam 品牌指南
- X:X 品牌工具包
- Telegram:Telegram 徽标和应用截图
- 遵守 Google Featured 的 Google 登录按钮指南非常重要。
- 有关应用于 Hive 身份验证的多语言登录按钮名称,请参考这里。
- 仅在登录屏幕上显示 Facebook 集成按钮的 UI 示例截图
以下是一个示例源代码,假设用户在自定义显式登录 UI 中选择 Google 登录的情况。
API 参考: hive.AuthV4.signIn
using hive;
AuthV4.signIn(AuthV4.ProviderType.GOOGLE, (ResultAPI result, AuthV4.PlayerInfo playerInfo) => {
if (result.isSuccess()) {
// 调用成功
// playerInfo : 认证用户信息。
// 获取ProviderType.GOOGLE的电子邮件信息示例
Dictionary<AuthV4.ProviderType, AuthV4.ProviderInfo> providerInfoData = playerInfo.providerInfoData;
AuthV4.ProviderInfo providerInfo = providerInfoData[AuthV4.ProviderType.GOOGLE];
string email = providerInfo.providerEmail;
}
});
#include "HiveAuthV4.h"
FHiveAuthV4::SignIn(EHiveProviderType::GOOGLE,
FHiveAuthV4OnSignInDelegate::CreateLambda([this](const FHiveResultAPI& Result, const FHivePlayerInfo& PlayerInfo) {
if (Result.IsSuccess()) {
// 调用成功 (PlayerInfo: 经过身份验证的用户信息)
// 示例:检索EHiveProviderType::GOOGLE的电子邮件信息
TMap<EHiveProviderType, FHiveProviderInfo> ProviderInfoData = PlayerInfo.ProviderInfoData;
if (const FHiveProviderInfo* ProviderInfo = ProviderInfoData.Find(EHiveProviderType::GOOGLE)) {
FString Email = ProviderInfo->ProviderEmail;
}
}
}));
API 参考: Auth4::signIn
#include <HIVE_SDK_Plugin/HIVE_CPP.h>
AuthV4::signIn(ProviderType::GOOGLE, [=](ResultAPI const & result, PlayerInfo const & playerInfo) {
if (result.isSuccess()) {
// 调用成功
// playerInfo : 认证用户信息。
// 示例:检索 ProviderType::GOOGLE 的电子邮件信息
map<ProviderType, ProviderInfo> providerInfoData = playerInfo.providerInfoData;
ProviderInfo providerInfo = providerInfoData[ProviderType::GOOGLE];
string email = providerInfo.providerEmail;
}
});
API 参考: AuthV4.signIn
import com.hive.AuthV4
import com.hive.ResultAPI
AuthV4.signIn(AuthV4.ProviderType.GOOGLE, object : AuthV4.AuthV4SignInListener {
override fun onAuthV4SignIn(result: ResultAPI, playerInfo: AuthV4.PlayerInfo?) {
if (result.isSuccess) {
// 调用成功
// playerInfo: 经过身份验证的用户信息
// 获取ProviderType.GOOGLE的电子邮件信息示例
if (playerInfo != null) {
val providerInfoData = playerInfo.providerInfoData
val providerInfo = providerInfoData[AuthV4.ProviderType.GOOGLE]
if (providerInfo != null) {
val email = providerInfo.providerEmail
}
}
}
}
})
API 参考: com.hive.Auth4.signIn
import com.hive.AuthV4;
import com.hive.ResultAPI;
AuthV4.signIn(AuthV4.ProviderType.GOOGLE, (result, playerInfo) -> {
if (result.isSuccess()) {
// 调用成功
// 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
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 账户不同。将提供指导以统一这两个账户,以便为未来的成就或排行榜使用做好准备。
以下是检查 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.syncAccount
import com.hive.AuthV4;
import com.hive.ResultAPI;
AuthV4.ProviderType providerType = AuthV4.ProviderType.GOOGLE;
AuthV4.Helper.syncAccount(providerType, (result, playerInfo) -> {
switch (result.getCode()) {
case Success:
// 正常
case AuthV4ConflictPlayer:
break;
// 账户冲突
// 例如) 使用 Hive UI 时
// AuthV4.Helper.showConflict(...);
// 或
// 例如) 实现 GameUI 时
// AuthV4.Helper.resolverConflict(...);// 选择当前用户时
// AuthV4.Helper.switchAccount(...);// 选择用户切换时
break;
default:
// 其他异常
break;
}
});
API 参考: AuthV4Interface.helper().syncAccount
import HIVEService
let providerType: ProviderType = .Google
AuthV4Interface.helper().syncAccount(providerType) { result, playerInfo in
switch result.getCode() {
case .success:
// 正常
case .authV4ConflictPlayer:
// 账户冲突
// 例如) 使用 Hive UI 时
// AuthV4Interface.helper().showConflict(...);
// 或
// 例如) 实现 GameUI 时
// AuthV4Interface.helper().resolverConflict(...);// 当当前用户被选中时
// AuthV4Interface.helper().switchAccount(...);// 当用户切换被选中时
default:
// 其他异常情况
break
}
}
API 参考: [HIVEAuthV4 helper] syncAccount
#import <HIVEService/HIVEService-Swift.h>
HIVEProviderType providerType = HIVEProviderTypeGoogle
[[HIVEAuthV4 helper] syncAccount: providerType handler: ^(HIVEResultAPI *result, HIVEPlayerInfo *playerInfo) {
switch ([result getCode]) {
case HIVEResultAPICodeSuccess:
// 正常
break;
case HIVEResultAPICodeAuthV4ConflictPlayer:
// 账户冲突
// 例如) 使用 Hive UI 时
// [[HIVEAuthV4 helper] showConflict: ...];
// 或
// 例如) 实现 GameUI 时
// [[HIVEAuthV4 helper] resolverConflict:...];// 当选择当前用户时
// [[HIVEAuthV4 helper] switchAccount:...];// 当选择用户切换时
break;
default:
// 其他异常
break;
}
}];
游客登录¶
游客登录功能允许用户在不选择身份提供者(IdP)的情况下以游客模式玩游戏。您可以从 Hive SDK 提供的显式登录用户界面中选择游客登录,或者如果您在游戏中自定义它,可以直接实现游客登录。Windows 环境不支持游客登录。
作为访客登录时,您必须遵守以下政策。
客户登录政策¶
- 实现游戏,使得 IdP 认证用户和访客用户可以以相同的方式使用它。 大多数 Hive 平台的功能即使在以访客身份登录时也可以使用。因此,请实现您的游戏,使得以访客身份登录的用户可以与 IdP 关联用户以相同的方式使用游戏。例如,访客用户也应该能够在游戏中购买物品和进行支付。
- 不为访客用户提供注销功能。 如果用户在以访客身份登录后注销,他们将无法使用相同的 PlayerID 重新登录。因此,不要提供注销按钮,以便用户在以访客身份登录时无法注销。
- 中国访客登录禁令政策 如果使用中国 IP,只有经过实名认证的用户才能充值和消费资源(自 2017 年 5 月 1 日起生效),因此访客登录不包括在可以使用中国 IP 登录的 IdP 列表中。
要执行访客登录,请调用signIn()
方法,并将ProviderType.GUEST
作为参数。
这是执行访客登录的示例代码。
Note
在没有任何 IdP 认证的访客状态下,PlayerID 的 playerInfo 中没有 providerInfoData。
API 参考: hive.AuthV4.signIn
API 参考: Auth4::signIn
API 参考: AuthV4.signIn
API 参考: com.hive.Auth4.signIn
API 参考: AuthV4Interface.signIn
API 参考: HIVEAuth4:signIn
自定义登录¶
**自定义登录**是一个用于自定义登录的功能,允许您通过与游戏本身集成的身份提供者(IdP)实现登录,此外还可以使用Hive提供的IdP。尝试生成一个身份验证密钥(authKey),以便在调用自定义登录API时使用,具体请参见Authenticate v4 Custom Authentication。
在调用自定义登录 API 后,您可以通过作为回调接收到的 PlayerInfo 类实例访问 customProviderInfoData
数据,以检查自定义登录用户的信息。customProviderInfoData
的 ProviderType (enum) 统一设置为 CUSTOM
,并且可以通过 ProviderName (String) 进行详细区分。
在游戏中实现自定义登录的 IdP 的信息不包括在 AuthV4
类的 setup()
和 showSignIn()
方法调用的结果中。
如果您在第一次执行自定义登录后收到了 playerId 和 playerToken,当自定义登录 API 被重新调用时,authV4SessionExist(code)
的结果 API 将作为回调返回。在这种情况下,您应该使用 ProviderType.Auto
作为参数调用 signIn()
,以便使用已登录的帐户进行自动登录。请参阅下面的示例代码。
AuthV4
类的 connect()
和 disconnect()
方法不支持自定义登录 IdP 的额外集成和断开连接。connectWithAuthKey()
和 disconnectWithName()
方法支持自定义登录 IdP 的额外集成和断开连接。
这是一个实现自定义登录的示例代码。
API 参考: hive.AuthV4.signIn
// Twitter 登录直接在游戏中实现
Game.Login("CUSTOM_TWITTER", (string authKey) => {
AuthV4.signInWithAuthKey(authKey, (ResultAPI result, PlayerInfo playerInfo) => {
if (result.isSuccess()) {
Dictionary<string, ProviderInfo> customProviderInfoData = playerInfo.customProviderInfoData;
ProviderInfo providerInfo = customProviderInfoData["CUSTOM_TWITTER"];
// 检查以下用户链接信息
providerInfo.providerType; // ProviderType.CUSTOM,自定义类型是固定的,因此需要通过 providerName 区分
providerInfo.providerName; // "CUSTOM_TWITTER"
providerInfo.providerUserId; // 用于自定义 Twitter 登录的用户 ID
return;
}
else if (result.code == ResultAPI.Code.AuthV4SessionExist) {
// 如果 playerId 和 playerToken 已经被发放并且需要自动登录
// TODO: AuthV4.signIn(ProviderType.AUTO, (ResultAPI _result, PlayerInfo playerInfo) => {});
}
else if (result.code == ResultAPI.Code.AuthV4NotInitialized) {
// TODO: 需要 SDK 初始化
}
else if (result.code == ResultAPI.Code.AuthV4InvalidParam) {
// TODO: 检查提供的 authKey 的值是否为 NULL 或空
}
else if (result.needExit()) {
// TODO: 实现应用退出功能
// 示例) Application.Quit();
}
});
});
#include "HiveAuthV4.h"
// 在游戏中直接实现了“CUSTOM_TWITTER”类型的Twitter登录
void GameLogin(const FString& AuthKey)
{
FHiveAuthV4::SignInWithAuthKey(AuthKey, FHiveAuthV4OnSignInDelegate::CreateLambda([this](const FHiveResultAPI& Result, const FHivePlayerInfo& PlayerInfo) {
if (Result.IsSuccess()) {
TMap<FString, FHiveProviderInfo> CustomProviderInfoData = PlayerInfo.CustomProviderInfoData;
if (const FHiveProviderInfo* ProviderInfo = CustomProviderInfoData.Find(TEXT("CUSTOM_TWITTER"))) {
EHiveProviderType ProviderType = ProviderInfo->ProviderType; // EHiveProviderType::CUSTOM, custom types are fixed
FString ProviderName = ProviderInfo->ProviderName; // Need to distinguish by ProviderName
FString ProviderUserId = ProviderInfo->ProviderUserId; // User id used in the custom Twitter login
}
} else if (Result.NeedExit()) {
// TODO: 实现应用退出功能
// e.g.) UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit, false);
} else if (Result.Code == FHiveResultAPI::ECode::AuthV4SessionExist) {
// 如果 playerId 和 playerToken 已经被发放并且需要自动登录
// TODO: FHiveAuthV4.SignIn(EHiveProviderType::GUEST, Delegate);
} else if (Result.Code == FHiveResultAPI::ECode::AuthV4NotInitialized) {
// TODO: 需要 SDK 初始化
} else if (Result.Code == FHiveResultAPI::ECode::AuthV4InvalidParam) {
// TODO: 检查提供的 authKey 的值是否为空
}
}));
}
API 参考: Auth4::signIn
using namespace std;
using namespace hive;
// Twitter 登录直接在游戏中实现
Game::Login("CUSTOM_TWITTER", [=](string authKey) {
AuthV4::signInWithAuthKey(authKey, [=](ResultAPI const & result, PlayerInfo const & playerInfo) {
if (result.isSuccess()) {
map<string, ProviderInfo> customProviderInfoData = playerInfo.customProviderInfoData;
ProviderInfo providerInfo = customProviderInfoData["CUSTOM_TWITTER"];
// 检查以下用户链接信息
providerInfo.providerType; // ProviderType::CUSTOM,因为自定义类型是固定的,需要通过 providerName 区分
providerInfo.providerName; // "CUSTOM_TWITTER"
providerInfo.providerUserId; // 用于自定义 Twitter 登录的用户 ID
return;
}
else if (result.code == ResultAPI::Code::AuthV4SessionExist) {
// 如果 playerId 和 playerToken 已经被发放并且需要自动登录
// TODO: AuthV4.signIn(ProviderType::AUTO, [=](ResultAPI const & _result, PlayerInfo const & playerInfo) {});
}
else if (result.code == ResultAPI::Code::AuthV4NotInitialized) {
// TODO: 需要 SDK 初始化
}
else if (result.code == ResultAPI::Code::AuthV4InvalidParam) {
// TODO: 检查提供的 authKey 的值是否为 NULL 或空
}
else if (result.needExit()) {
// TODO: 实现应用退出功能
// 对于 Cocos2d-x 引擎用户
// 示例) exit(0);
// 对于 Unreal 引擎用户
// 示例) UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit, false);
}
});
});
API 参考: com.hive.Auth4.signIn
// 在游戏中直接实现Twitter登录
Game.Login("CUSTOM_TWITTER") { authKey: String ->
AuthV4.signInWithAuthKey(authKey, object : AuthV4.AuthV4SignInListener {
override fun onAuthV4SignIn(result: ResultAPI, playerInfo: AuthV4.PlayerInfo?) {
if (result.isSuccess && playerInfo != null) {
playerInfo.customProviderInfoData["CUSTOM_TWITTER"]?.let { providerInfo ->
providerInfo.providerType // ProviderType.CUSTOM, custom types are fixed, so need to distinguish by providerName
providerInfo.providerName // "CUSTOM_TWITTER"
providerInfo.providerUserId // User id used for the custom Twitter login
}
}
else if (result.needExit()) {
// TODO: 实现应用程序退出功能
// e.g.) exitProcess(0)
}
else if (result.code == ResultAPI.Code.AuthV4SessionExist) {
// 如果 playerId 和 playerToken 已经发放并且需要自动登录
// TODO: AuthV4.signIn(AuthV4.ProviderType.AUTO, authV4SignInListener)
}
else if (result.code == ResultAPI.Code.AuthV4NotInitialized) {
// TODO: 需要 SDK 初始化
}
else if (result.code == ResultAPI.Code.AuthV4InvalidParam) {
// TODO: 检查提供的 authKey 的值是否为 NULL 或空
}
}
})
}
API 参考: com.hive.Auth4.signIn
// 在游戏中直接实现Twitter登录
Game.Login("CUSTOM_TWITTER") { authKey: String ->
AuthV4.signInWithAuthKey(authKey, new AuthV4.AuthV4SignInListener() {
@Override
public void onAuthV4SignIn(@NonNull ResultAPI result, @Nullable AuthV4.PlayerInfo playerInfo) {
if(result.isSuccess() && playerInfo != null) {
HashMap<String, AuthV4.ProviderInfo> customProviderInfoData = playerInfo.getCustomProviderInfoData();
AuthV4.ProviderInfo providerInfo = customProviderInfoData.get("CUSTOM_TWITTER");
// 检查以下用户链接信息
if (providerInfo != null){
providerInfo.getProviderType(); // AuthV4.ProviderType.CUSTOM,因为自定义类型是固定的,需要通过providerName区分
providerInfo.getProviderName(); // "CUSTOM_TWITTER"
providerInfo.getProviderUserId(); // 用于直接实现的自定义Twitter登录的用户ID
}
} else if (result.needExit()) {
// TODO: 实现应用退出功能
// 例如)System.exit(0);
} else if (result.getCode() == ResultAPI.Code.AuthV4SessionExist) {
// 如果playerId和playerToken已经被发放并且需要自动登录
// TODO: AuthV4.signIn(AuthV4.ProviderType.AUTO, authV4SignInListener)
} else if (result.getCode() == ResultAPI.Code.AuthV4NotInitialized) {
// TODO: 需要SDK初始化
} else if (result.getCode() == ResultAPI.Code.AuthV4InvalidParam) {
// TODO: 检查提供的authKey的值是否为NULL或空
}
}
});
}
API 参考: HIVEAuth4:signIn
// 在游戏中直接实现Twitter登录
Game.login("CUSTOM_TWITTER") { (authKey) in
AuthV4Interface.signInWithAuthKey(authKey) { (result, playerInfo) in
if result.isSuccess() {
let customProviderInfoData = playerInfo?.customProviderInfoData;
let providerInfo = customProviderInfoData?["CUSTOM_TWITTER"]
// 检查以下用户链接信息
providerInfo?.providerType; // AuthProviderType,自定义类型是固定的,因此需要通过providerName区分
providerInfo?.providerName; // "CUSTOM_TWITTER"
providerInfo?.providerUserId; // 用于自定义Twitter登录的用户ID
return
}
else if result.getCode() == .authV4SessionExist {
// 如果playerId和playerToken已经被发放,并且需要自动登录
// TODO: AuthV4Interface.signIn(.auto) { (result, playerInfo) in }
}
else if result.getCode() == .authV4NotInitialized {
// TODO: 需要SDK初始化
}
else if result.getCode() == .authV4invalidParam {
// TODO: 检查提供的authKey的值是否为nil或空
}
else if result.needExit() {
// TODO: 实现应用退出功能。
// 例如: exit(0)
}
}
}
API 参考: HIVEAuth4:signIn
// 游戏中直接实现的Twitter登录
[Game login:@"CUSTOM_TWITTER" handler:^(NSString* authKey) {
[HIVEAuthV4 signInWithAuthKey:authKey handler:^(HIVEResultAPI* result, HIVEPlayerInfo* playerInfo) {
if (result.isSuccess) {
NSDictionary<NSString*, HIVEProviderInfo*>* customProviderInfoData = playerInfo.customProviderInfoData;
ProviderInfo* providerInfo = [customProviderInfoData objectForKey:@"CUSTOM_TWITTER"];
// 检查以下用户链接信息
providerInfo.providerType; // HIVEProviderTypeCustom,自定义类型是固定的,因此需要通过providerName区分
providerInfo.providerName; // "CUSTOM_TWITTER"
providerInfo.providerUserId; // 在自定义Twitter登录中使用的用户ID
return;
}
else if (result.getCode == HIVEResultAPICodeAuthV4SessionExist) {
// 如果playerId和playerToken已经被发放并且需要自动登录
// TODO: [HIVEAuthV4 signIn:HIVEProviderTypeAuto, handler:^(HIVEResultAPI* _result, HIVEPlayerInfo* playerInfo) {}];
}
else if (result.getCode == HIVEResultAPICodeAuthV4NotInitialized) {
// TODO: 需要SDK初始化
}
else if (result.getCode == HIVEResultAPICodeAuthV4InvalidParam) {
// TODO: 检查提供的authKey的值是否为NULL或空
}
else if (result.needExit) {
// TODO: 实现应用退出功能。
// 例如) exit(0);
}
}];
}];
用户名¶
由于美国的COPPA等问题,当用户从美国及其领土访问并以IdP身份登录时,必须输入用户名以便进行额外的用户身份验证处理。作为参考,包含在美国领土中的国家有美属萨摩亚(AS)、关岛(GU)、北马里亚纳群岛(MP)、波多黎各(PR)、美国小离岛(UM)和美属维尔京群岛(VI)。输入用户名以进行用户身份识别的屏幕如下。
- 用户名输入屏幕仅用于用户识别目的,因此它只在初始 IdP 集成期间显示一次,之后将不再显示。
- 在访客登录期间不会显示用户名输入屏幕。
验证身份验证令牌密钥¶
游戏服务器可以使用成功登录后返回的令牌、playerId 和 DID 信息来验证令牌密钥的真实性。Hive 身份验证允许多设备登录和并发访问。
如果不允许同一账户重复访问,游戏服务器将在首次连接的设备上显示通知消息,然后退出游戏,允许后连接的设备继续游戏。如果您在未退出的情况下尝试再次访问游戏,您的游戏记录可能无法正确反映。要实现此功能,您需要管理一个经过验证的令牌密钥或游戏本身的会话密钥。
通过参考身份验证令牌密钥验证服务器 API来实现此功能。
在后台检测 IdP 账户更改¶
用户可以在游戏过程中导航到设备设置,以更改他们的 Apple Game Center 或 Google Play Games 账户。如果您需要检查游戏过程中 IdP 账户是否与当前 PlayerID 的 IdP 账户不同,请在初始化 SDK 后调用 setProviderChangedListener()
。通过调用此 API,您可以在游戏恢复时接收到一个事件,指示设备上设置的 IdP 账户已更改。
iOS与Apple Game Center配合使用,而Android与Google Play游戏配合使用,当帐户更改时,只有当前登录的PlayerID与相应的IdP关联时,才会发送响应。当接收到IdP帐户更改事件时,UI被配置为允许用户选择是否使用已登录到设备的IdP帐户。如果用户选择了已登录到设备的IdP帐户,则调用signOut
进行注销,然后执行隐式登录。
Warning
由于Google Play游戏的操作问题,2021年7月之后发布的安装了Google Play游戏的设备无法在后台更改IdP帐户。
Note
此功能可能会导致游戏暂停并请求更改账户,仅在需要账户同步的情况下(例如进入大厅或商店时)限制使用。
以下是一个示例代码,用于在用户重新启动游戏并且设备上设置的 IdP 账户发生更改时接收事件。
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 游戏服务帐户
}
}
})
游戏数据初始化¶
在初始化游戏数据时,请勿调用注销。由于 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
#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
API 参考: AuthV4.Helper.signOut
API 参考: AuthV4.Helper.signOut
API 参考: [HIVEAuthV4 helper] 登出
游戏中心取消通知文本¶
语言 | 短语 |
---|---|
韩语 | Apple Game Center 登录已被取消。 请在 [设置 > Game Center] 登录以与您的 Game Center 帐户同步并重试。 |
英语 | 您对 Game Center 的登录已被取消。 在 [设置> Game Center] 登录以与 Game Center 帐户同步并重试。 |
日语 | Apple Game Center 登录已被取消。 请在 [设置 > Game Center] 登录以在与您的 Game Center 帐户同步后重试。 |
简体中文 | Apple Game Center 已注销。 如果您想与 Game Center 帐户同步,请在 [设置> Game Center] 中重新登录并重试。 |
繁体中文 | Apple Game Center 登录已被取消。 如果您想链接到 Game Center 帐户,请在 [设置 > Game Center] 登录并重试。 |
法语 | 您与 Game Center 的连接已被取消。 在 [设置 > Game Center] 登录以同步您的 Game Center 帐户并重试。 |
德语 | Apple Game Center 的登录已被取消。 通过在 [设置 > Game Center] 登录与 Game Center 帐户同步并重试。 |
俄语 | 您对 Game Center 的登录已被取消。 通过 [设置 > Game Center] 登录到 Game Center 并重试。 |
西班牙语 | 您对 Game Center 的登录已被取消。 在 [设置> Game Center] 登录以与 Game Center 帐户同步并重试。 |
葡萄牙语 | 您对 Game Center 的登录已被取消。 在 [设置> Game Center] 登录以与 Game Center 帐户同步并重试。 |
印度尼西亚语 | Apple Game Center 登录已被取消。 通过在 [设置 > Game Center] 登录连接您的 Game Center 帐户并重试。 |
马来语 | 您对 Game Center 的登录已被取消。 在 [设置> Game Center] 登录以与 Game Center 帐户同步并重试。 |
越南语 | Apple Game Center 登录已被取消。 在 [设置 > Game Center] 登录以与您的 Game Center 帐户同步并重试。 |
泰语 | 您对 Game Center 的登录已被取消。 在 [设置> Game Center] 登录以连接到您的 Game Center 帐户并重试。 |
意大利语 | 您对 Apple Game Center 的访问已被取消。 在 [设置 > Game Center] 登录以与 Game Center 同步您的帐户并重试。 |
土耳其语 | 您对 Apple Game Center 的登录已被取消。 在 [设置> Game Center] 登录以访问 Game Center 帐户并重试。 |
阿拉伯语 | 您对 Game Center 的登录已被取消。 在 [设置> Game Center] 登录以与您的 Game Center 帐户同步并重试。 |