[U] add PlayFab SDK and SNS login improvements

- Add PlayFabSDK as local package dependency
- Add PlayFabTool.cs for PlayFab API integration
- Implement LoginBySns method in TYSdkFacade
- Add Android SNS login support in SDKManager and UnityBridgeFunc
- Add Build Android With Debug menu option
- Improve exception handling and timeout management

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-29 16:12:17 +08:00
parent 638e6a3327
commit aa5ce1ff5a
226 changed files with 64975 additions and 62 deletions

View File

@@ -0,0 +1,104 @@
#if !DISABLE_PLAYFABENTITY_API && !DISABLE_PLAYFAB_STATIC_API
using System;
using System.Collections.Generic;
using PlayFab.AuthenticationModels;
using PlayFab.Internal;
namespace PlayFab
{
/// <summary>
/// The Authentication APIs provide a convenient way to convert classic authentication responses into entity authentication
/// models. These APIs will provide you with the entity authentication token needed for subsequent Entity API calls. Manage
/// API keys for authenticating any entity. The game_server API is designed to create uniquely identifiable game_server
/// entities. The game_server Entity token can be used to call Matchmaking Lobby and Pubsub for server scenarios.
/// </summary>
public static class PlayFabAuthenticationAPI
{
static PlayFabAuthenticationAPI() {}
/// <summary>
/// Verify entity login.
/// </summary>
public static bool IsEntityLoggedIn()
{
return PlayFabSettings.staticPlayer.IsEntityLoggedIn();
}
/// <summary>
/// Clear the Client SessionToken which allows this Client to call API calls requiring login.
/// A new/fresh login will be required after calling this.
/// </summary>
public static void ForgetAllCredentials()
{
PlayFabSettings.staticPlayer.ForgetAllCredentials();
}
/// <summary>
/// Create a game_server entity token and return a new or existing game_server entity.
/// </summary>
public static void AuthenticateGameServerWithCustomId(AuthenticateCustomIdRequest request, Action<AuthenticateCustomIdResult> resultCallback, Action<PlayFabError> errorCallback, object customData = null, Dictionary<string, string> extraHeaders = null)
{
var context = (request == null ? null : request.AuthenticationContext) ?? PlayFabSettings.staticPlayer;
var callSettings = PlayFabSettings.staticSettings;
if (!context.IsEntityLoggedIn()) throw new PlayFabException(PlayFabExceptionCode.NotLoggedIn,"Must be logged in to call this method");
PlayFabHttp.MakeApiCall("/GameServerIdentity/AuthenticateGameServerWithCustomId", request, AuthType.EntityToken, resultCallback, errorCallback, customData, extraHeaders, context, callSettings);
}
/// <summary>
/// Delete a game_server entity.
/// </summary>
public static void Delete(DeleteRequest request, Action<EmptyResponse> resultCallback, Action<PlayFabError> errorCallback, object customData = null, Dictionary<string, string> extraHeaders = null)
{
var context = (request == null ? null : request.AuthenticationContext) ?? PlayFabSettings.staticPlayer;
var callSettings = PlayFabSettings.staticSettings;
if (!context.IsEntityLoggedIn()) throw new PlayFabException(PlayFabExceptionCode.NotLoggedIn,"Must be logged in to call this method");
PlayFabHttp.MakeApiCall("/GameServerIdentity/Delete", request, AuthType.EntityToken, resultCallback, errorCallback, customData, extraHeaders, context, callSettings);
}
/// <summary>
/// Method to exchange a legacy AuthenticationTicket or title SecretKey for an Entity Token or to refresh a still valid
/// Entity Token.
/// </summary>
public static void GetEntityToken(GetEntityTokenRequest request, Action<GetEntityTokenResponse> resultCallback, Action<PlayFabError> errorCallback, object customData = null, Dictionary<string, string> extraHeaders = null)
{
var context = (request == null ? null : request.AuthenticationContext) ?? PlayFabSettings.staticPlayer;
var callSettings = PlayFabSettings.staticSettings;
AuthType authType = AuthType.None;
#if !DISABLE_PLAYFABCLIENT_API
if (context.IsClientLoggedIn()) { authType = AuthType.LoginSession; }
#endif
#if ENABLE_PLAYFABSERVER_API || ENABLE_PLAYFABADMIN_API || ENABLE_PLAYFAB_SECRETKEY
if (callSettings.DeveloperSecretKey != null) { authType = AuthType.DevSecretKey; }
#endif
#if !DISABLE_PLAYFABENTITY_API
if (context.IsEntityLoggedIn()) { authType = AuthType.EntityToken; }
#endif
PlayFabHttp.MakeApiCall("/Authentication/GetEntityToken", request, authType, resultCallback, errorCallback, customData, extraHeaders, context, callSettings);
}
/// <summary>
/// Method for a server to validate a client provided EntityToken. Only callable by the title entity.
/// </summary>
public static void ValidateEntityToken(ValidateEntityTokenRequest request, Action<ValidateEntityTokenResponse> resultCallback, Action<PlayFabError> errorCallback, object customData = null, Dictionary<string, string> extraHeaders = null)
{
var context = (request == null ? null : request.AuthenticationContext) ?? PlayFabSettings.staticPlayer;
var callSettings = PlayFabSettings.staticSettings;
if (!context.IsEntityLoggedIn()) throw new PlayFabException(PlayFabExceptionCode.NotLoggedIn,"Must be logged in to call this method");
PlayFabHttp.MakeApiCall("/Authentication/ValidateEntityToken", request, AuthType.EntityToken, resultCallback, errorCallback, customData, extraHeaders, context, callSettings);
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cf5e0beea20361a45aee9c2329eafd01
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,121 @@
#if !DISABLE_PLAYFABENTITY_API
using System;
using System.Collections.Generic;
using PlayFab.AuthenticationModels;
using PlayFab.Internal;
using PlayFab.SharedModels;
namespace PlayFab
{
/// <summary>
/// The Authentication APIs provide a convenient way to convert classic authentication responses into entity authentication
/// models. These APIs will provide you with the entity authentication token needed for subsequent Entity API calls. Manage
/// API keys for authenticating any entity. The game_server API is designed to create uniquely identifiable game_server
/// entities. The game_server Entity token can be used to call Matchmaking Lobby and Pubsub for server scenarios.
/// </summary>
public class PlayFabAuthenticationInstanceAPI : IPlayFabInstanceApi
{
public readonly PlayFabApiSettings apiSettings = null;
public readonly PlayFabAuthenticationContext authenticationContext = null;
public PlayFabAuthenticationInstanceAPI()
{
authenticationContext = new PlayFabAuthenticationContext();
}
public PlayFabAuthenticationInstanceAPI(PlayFabApiSettings settings)
{
apiSettings = settings;
authenticationContext = new PlayFabAuthenticationContext();
}
public PlayFabAuthenticationInstanceAPI(PlayFabAuthenticationContext context)
{
authenticationContext = context ?? new PlayFabAuthenticationContext();
}
public PlayFabAuthenticationInstanceAPI(PlayFabApiSettings settings, PlayFabAuthenticationContext context)
{
apiSettings = settings;
authenticationContext = context ?? new PlayFabAuthenticationContext();
}
/// <summary>
/// Verify entity login.
/// </summary>
public bool IsEntityLoggedIn()
{
return authenticationContext == null ? false : authenticationContext.IsEntityLoggedIn();
}
/// <summary>
/// Clear the Client SessionToken which allows this Client to call API calls requiring login.
/// A new/fresh login will be required after calling this.
/// </summary>
public void ForgetAllCredentials()
{
if (authenticationContext != null)
{
authenticationContext.ForgetAllCredentials();
}
}
/// <summary>
/// Create a game_server entity token and return a new or existing game_server entity.
/// </summary>
public void AuthenticateGameServerWithCustomId(AuthenticateCustomIdRequest request, Action<AuthenticateCustomIdResult> resultCallback, Action<PlayFabError> errorCallback, object customData = null, Dictionary<string, string> extraHeaders = null)
{
var context = (request == null ? null : request.AuthenticationContext) ?? authenticationContext;
var callSettings = apiSettings ?? PlayFabSettings.staticSettings;
if (!context.IsEntityLoggedIn()) throw new PlayFabException(PlayFabExceptionCode.NotLoggedIn,"Must be logged in to call this method");
PlayFabHttp.MakeApiCall("/GameServerIdentity/AuthenticateGameServerWithCustomId", request, AuthType.EntityToken, resultCallback, errorCallback, customData, extraHeaders, context, callSettings, this);
}
/// <summary>
/// Delete a game_server entity.
/// </summary>
public void Delete(DeleteRequest request, Action<EmptyResponse> resultCallback, Action<PlayFabError> errorCallback, object customData = null, Dictionary<string, string> extraHeaders = null)
{
var context = (request == null ? null : request.AuthenticationContext) ?? authenticationContext;
var callSettings = apiSettings ?? PlayFabSettings.staticSettings;
if (!context.IsEntityLoggedIn()) throw new PlayFabException(PlayFabExceptionCode.NotLoggedIn,"Must be logged in to call this method");
PlayFabHttp.MakeApiCall("/GameServerIdentity/Delete", request, AuthType.EntityToken, resultCallback, errorCallback, customData, extraHeaders, context, callSettings, this);
}
/// <summary>
/// Method to exchange a legacy AuthenticationTicket or title SecretKey for an Entity Token or to refresh a still valid
/// Entity Token.
/// </summary>
public void GetEntityToken(GetEntityTokenRequest request, Action<GetEntityTokenResponse> resultCallback, Action<PlayFabError> errorCallback, object customData = null, Dictionary<string, string> extraHeaders = null)
{
var context = (request == null ? null : request.AuthenticationContext) ?? authenticationContext;
var callSettings = apiSettings ?? PlayFabSettings.staticSettings;
AuthType authType = AuthType.None;
#if !DISABLE_PLAYFABCLIENT_API
if (context.IsClientLoggedIn()) { authType = AuthType.LoginSession; }
#endif
#if ENABLE_PLAYFABSERVER_API || ENABLE_PLAYFABADMIN_API || ENABLE_PLAYFAB_SECRETKEY
if (callSettings.DeveloperSecretKey != null) { authType = AuthType.DevSecretKey; }
#endif
#if !DISABLE_PLAYFABENTITY_API
if (context.IsEntityLoggedIn()) { authType = AuthType.EntityToken; }
#endif
PlayFabHttp.MakeApiCall("/Authentication/GetEntityToken", request, authType, resultCallback, errorCallback, customData, extraHeaders, context, callSettings, this);
}
/// <summary>
/// Method for a server to validate a client provided EntityToken. Only callable by the title entity.
/// </summary>
public void ValidateEntityToken(ValidateEntityTokenRequest request, Action<ValidateEntityTokenResponse> resultCallback, Action<PlayFabError> errorCallback, object customData = null, Dictionary<string, string> extraHeaders = null)
{
var context = (request == null ? null : request.AuthenticationContext) ?? authenticationContext;
var callSettings = apiSettings ?? PlayFabSettings.staticSettings;
if (!context.IsEntityLoggedIn()) throw new PlayFabException(PlayFabExceptionCode.NotLoggedIn,"Must be logged in to call this method");
PlayFabHttp.MakeApiCall("/Authentication/ValidateEntityToken", request, AuthType.EntityToken, resultCallback, errorCallback, customData, extraHeaders, context, callSettings, this);
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ecff04cca276a454aad3baf64c4a2ab4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,233 @@
#if !DISABLE_PLAYFABENTITY_API
using System;
using System.Collections.Generic;
using PlayFab.SharedModels;
namespace PlayFab.AuthenticationModels
{
/// <summary>
/// Create or return a game_server entity token. Caller must be a title entity.
/// </summary>
[Serializable]
public class AuthenticateCustomIdRequest : PlayFabRequestCommon
{
/// <summary>
/// The customId used to create and retrieve game_server entity tokens. This is unique at the title level. CustomId must be
/// between 32 and 100 characters.
/// </summary>
public string CustomId;
/// <summary>
/// The optional custom tags associated with the request (e.g. build number, external trace identifiers, etc.).
/// </summary>
public Dictionary<string,string> CustomTags;
}
[Serializable]
public class AuthenticateCustomIdResult : PlayFabResultCommon
{
/// <summary>
/// The token generated used to set X-EntityToken for game_server calls.
/// </summary>
public EntityTokenResponse EntityToken;
/// <summary>
/// True if the account was newly created on this authentication.
/// </summary>
public bool NewlyCreated;
}
/// <summary>
/// Delete a game_server entity. The caller can be the game_server entity attempting to delete itself. Or a title entity
/// attempting to delete game_server entities for this title.
/// </summary>
[Serializable]
public class DeleteRequest : PlayFabRequestCommon
{
/// <summary>
/// The optional custom tags associated with the request (e.g. build number, external trace identifiers, etc.).
/// </summary>
public Dictionary<string,string> CustomTags;
/// <summary>
/// The game_server entity to be removed.
/// </summary>
public EntityKey Entity;
}
[Serializable]
public class EmptyResponse : PlayFabResultCommon
{
}
/// <summary>
/// Combined entity type and ID structure which uniquely identifies a single entity.
/// </summary>
[Serializable]
public class EntityKey : PlayFabBaseModel
{
/// <summary>
/// Unique ID of the entity.
/// </summary>
public string Id;
/// <summary>
/// Entity type. See https://docs.microsoft.com/gaming/playfab/features/data/entities/available-built-in-entity-types
/// </summary>
public string Type;
}
[Serializable]
public class EntityLineage : PlayFabBaseModel
{
/// <summary>
/// The Character Id of the associated entity.
/// </summary>
public string CharacterId;
/// <summary>
/// The Group Id of the associated entity.
/// </summary>
public string GroupId;
/// <summary>
/// The Master Player Account Id of the associated entity.
/// </summary>
public string MasterPlayerAccountId;
/// <summary>
/// The Namespace Id of the associated entity.
/// </summary>
public string NamespaceId;
/// <summary>
/// The Title Id of the associated entity.
/// </summary>
public string TitleId;
/// <summary>
/// The Title Player Account Id of the associated entity.
/// </summary>
public string TitlePlayerAccountId;
}
[Serializable]
public class EntityTokenResponse : PlayFabBaseModel
{
/// <summary>
/// The entity id and type.
/// </summary>
public EntityKey Entity;
/// <summary>
/// The token used to set X-EntityToken for all entity based API calls.
/// </summary>
public string EntityToken;
/// <summary>
/// The time the token will expire, if it is an expiring token, in UTC.
/// </summary>
public DateTime? TokenExpiration;
}
/// <summary>
/// This API must be called with X-SecretKey, X-Authentication or X-EntityToken headers. An optional EntityKey may be
/// included to attempt to set the resulting EntityToken to a specific entity, however the entity must be a relation of the
/// caller, such as the master_player_account of a character. If sending X-EntityToken the account will be marked as freshly
/// logged in and will issue a new token. If using X-Authentication or X-EntityToken the header must still be valid and
/// cannot be expired or revoked.
/// </summary>
[Serializable]
public class GetEntityTokenRequest : PlayFabRequestCommon
{
/// <summary>
/// The optional custom tags associated with the request (e.g. build number, external trace identifiers, etc.).
/// </summary>
public Dictionary<string,string> CustomTags;
/// <summary>
/// The optional entity to perform this action on. Defaults to the currently logged in entity.
/// </summary>
public EntityKey Entity;
}
[Serializable]
public class GetEntityTokenResponse : PlayFabResultCommon
{
/// <summary>
/// The entity id and type.
/// </summary>
public EntityKey Entity;
/// <summary>
/// The token used to set X-EntityToken for all entity based API calls.
/// </summary>
public string EntityToken;
/// <summary>
/// The time the token will expire, if it is an expiring token, in UTC.
/// </summary>
public DateTime? TokenExpiration;
}
public enum IdentifiedDeviceType
{
Unknown,
XboxOne,
Scarlett
}
public enum LoginIdentityProvider
{
Unknown,
PlayFab,
Custom,
GameCenter,
GooglePlay,
Steam,
XBoxLive,
PSN,
Kongregate,
Facebook,
IOSDevice,
AndroidDevice,
Twitch,
WindowsHello,
GameServer,
CustomServer,
NintendoSwitch,
FacebookInstantGames,
OpenIdConnect,
Apple,
NintendoSwitchAccount,
GooglePlayGames
}
/// <summary>
/// Given an entity token, validates that it hasn't expired or been revoked and will return details of the owner.
/// </summary>
[Serializable]
public class ValidateEntityTokenRequest : PlayFabRequestCommon
{
/// <summary>
/// The optional custom tags associated with the request (e.g. build number, external trace identifiers, etc.).
/// </summary>
public Dictionary<string,string> CustomTags;
/// <summary>
/// Client EntityToken
/// </summary>
public string EntityToken;
}
[Serializable]
public class ValidateEntityTokenResponse : PlayFabResultCommon
{
/// <summary>
/// The entity id and type.
/// </summary>
public EntityKey Entity;
/// <summary>
/// The authenticated device for this entity, for the given login
/// </summary>
public IdentifiedDeviceType? IdentifiedDeviceType;
/// <summary>
/// The identity provider for this entity, for the given login
/// </summary>
public LoginIdentityProvider? IdentityProvider;
/// <summary>
/// The ID issued by the identity provider, e.g. a XUID on Xbox Live
/// </summary>
public string IdentityProviderIssuedId;
/// <summary>
/// The lineage of this profile.
/// </summary>
public EntityLineage Lineage;
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ec656500f922b0b4db8e13c80770e0d5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,18 @@
#if !DISABLE_PLAYFABENTITY_API
using PlayFab.AuthenticationModels;
namespace PlayFab.Events
{
public partial class PlayFabEvents
{
public event PlayFabRequestEvent<AuthenticateCustomIdRequest> OnAuthenticationAuthenticateGameServerWithCustomIdRequestEvent;
public event PlayFabResultEvent<AuthenticateCustomIdResult> OnAuthenticationAuthenticateGameServerWithCustomIdResultEvent;
public event PlayFabRequestEvent<DeleteRequest> OnAuthenticationDeleteRequestEvent;
public event PlayFabResultEvent<EmptyResponse> OnAuthenticationDeleteResultEvent;
public event PlayFabRequestEvent<GetEntityTokenRequest> OnAuthenticationGetEntityTokenRequestEvent;
public event PlayFabResultEvent<GetEntityTokenResponse> OnAuthenticationGetEntityTokenResultEvent;
public event PlayFabRequestEvent<ValidateEntityTokenRequest> OnAuthenticationValidateEntityTokenRequestEvent;
public event PlayFabResultEvent<ValidateEntityTokenResponse> OnAuthenticationValidateEntityTokenResultEvent;
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5c3701fef92515c438633c5d41bf87c8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: