[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,9 @@
namespace PlayFab
{
/// <summary>
/// Base interface of any PlayFab SDK plugin.
/// </summary>
public interface IPlayFabPlugin
{
}
}

View File

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

View File

@@ -0,0 +1,15 @@
namespace PlayFab
{
/// <summary>
/// Interface of any data serializer SDK plugin.
/// </summary>
public interface ISerializerPlugin : IPlayFabPlugin
{
T DeserializeObject<T>(string serialized);
T DeserializeObject<T>(string serialized, object serializerStrategy);
object DeserializeObject(string serialized);
string SerializeObject(object obj);
string SerializeObject(object obj, object serializerStrategy);
}
}

View File

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

View File

@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
namespace PlayFab
{
/// <summary>
/// Interface of any transport SDK plugin.
/// </summary>
public interface ITransportPlugin: IPlayFabPlugin
{
bool IsInitialized { get; }
void Initialize();
// Mirroring MonoBehaviour - Relayed from PlayFabHTTP
void Update();
void OnDestroy();
void SimpleGetCall(string fullUrl, Action<byte[]> successCallback, Action<string> errorCallback);
void SimplePutCall(string fullUrl, byte[] payload, Action<byte[]> successCallback, Action<string> errorCallback);
void SimplePostCall(string fullUrl, byte[] payload, Action<byte[]> successCallback, Action<string> errorCallback);
void MakeApiCall(object reqContainer);
int GetPendingMessages();
}
}

View File

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

View File

@@ -0,0 +1,84 @@
using System.Collections.Generic;
using System;
namespace PlayFab
{
public class PlayFabApiSettings
{
private string _ProductionEnvironmentUrl = PlayFabSettings.DefaultPlayFabApiUrl;
public readonly Dictionary<string, string> _requestGetParams = new Dictionary<string, string> {
{ "sdk", PlayFabSettings.VersionString }
};
public virtual Dictionary<string, string> RequestGetParams { get { return _requestGetParams; } }
/// <summary> This is only for customers running a private cluster. Generally you shouldn't touch this </summary>
public virtual string ProductionEnvironmentUrl { get { return _ProductionEnvironmentUrl; } set { _ProductionEnvironmentUrl = value; } }
/// <summary> You must set this value for PlayFabSdk to work properly (Found in the Game Manager for your title, at the PlayFab Website) </summary>
public virtual string TitleId { get; set; }
/// <summary> The name of a customer vertical. This is only for customers running a private cluster. Generally you shouldn't touch this </summary>
internal virtual string VerticalName { get; set; }
#if ENABLE_PLAYFABSERVER_API || ENABLE_PLAYFABADMIN_API || UNITY_EDITOR || ENABLE_PLAYFAB_SECRETKEY
/// <summary> You must set this value for PlayFabSdk to work properly (Found in the Game Manager for your title, at the PlayFab Website) </summary>
public virtual string DeveloperSecretKey { get; set; }
#endif
/// <summary> Set this to true to prevent hardware information from leaving the device </summary>
public virtual bool DisableDeviceInfo { get; set; }
/// <summary> Set this to true to prevent focus change information from leaving the device </summary>
public virtual bool DisableFocusTimeCollection { get; set; }
public virtual string GetFullUrl(string apiCall, Dictionary<string, string> getParams)
{
return PlayFabSettings.GetFullUrl(apiCall, getParams, this);
}
}
/// <summary>
/// This is only meant for PlayFabSettings to use as a redirect to store values on PlayFabSharedSettings instead of locally
/// </summary>
internal class PlayFabSettingsRedirect : PlayFabApiSettings
{
private readonly Func<PlayFabSharedSettings> GetSO;
public PlayFabSettingsRedirect(Func<PlayFabSharedSettings> getSO) { GetSO = getSO; }
public override string ProductionEnvironmentUrl
{
get { var so = GetSO(); return so == null ? base.ProductionEnvironmentUrl : so.ProductionEnvironmentUrl; }
set { var so = GetSO(); if (so != null) so.ProductionEnvironmentUrl = value; base.ProductionEnvironmentUrl = value; }
}
internal override string VerticalName
{
get { var so = GetSO(); return so == null ? base.VerticalName : so.VerticalName; }
set { var so = GetSO(); if (so != null) so.VerticalName = value; base.VerticalName = value; }
}
#if ENABLE_PLAYFABSERVER_API || ENABLE_PLAYFABADMIN_API || UNITY_EDITOR || ENABLE_PLAYFAB_SECRETKEY
public override string DeveloperSecretKey
{
get { var so = GetSO(); return so == null ? base.DeveloperSecretKey : so.DeveloperSecretKey; }
set { var so = GetSO(); if (so != null) so.DeveloperSecretKey = value; base.DeveloperSecretKey = value; }
}
#endif
public override string TitleId
{
get { var so = GetSO(); return so == null ? base.TitleId : so.TitleId; }
set { var so = GetSO(); if (so != null) so.TitleId = value; base.TitleId = value; }
}
public override bool DisableDeviceInfo
{
get { var so = GetSO(); return so == null ? base.DisableDeviceInfo : so.DisableDeviceInfo; }
set { var so = GetSO(); if (so != null) so.DisableDeviceInfo = value; base.DisableDeviceInfo = value; }
}
public override bool DisableFocusTimeCollection
{
get { var so = GetSO(); return so == null ? base.DisableFocusTimeCollection : so.DisableFocusTimeCollection; }
set { var so = GetSO(); if (so != null) so.DisableFocusTimeCollection = value; base.DisableFocusTimeCollection = value; }
}
}
}

View File

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

View File

@@ -0,0 +1,77 @@
namespace PlayFab
{
public sealed class PlayFabAuthenticationContext
{
public PlayFabAuthenticationContext()
{
}
public PlayFabAuthenticationContext(string clientSessionTicket, string entityToken, string playFabId, string entityId, string entityType) : this()
{
#if !DISABLE_PLAYFABCLIENT_API
ClientSessionTicket = clientSessionTicket;
PlayFabId = playFabId;
#endif
#if !DISABLE_PLAYFABENTITY_API
EntityToken = entityToken;
EntityId = entityId;
EntityType = entityType;
#endif
}
public void CopyFrom(PlayFabAuthenticationContext other)
{
#if !DISABLE_PLAYFABCLIENT_API
ClientSessionTicket = other.ClientSessionTicket;
PlayFabId = other.PlayFabId;
#endif
#if !DISABLE_PLAYFABENTITY_API
EntityToken = other.EntityToken;
EntityId = other.EntityId;
EntityType = other.EntityType;
#endif
}
#if !DISABLE_PLAYFABCLIENT_API
/// <summary> Allows access to the ClientAPI </summary>
public string ClientSessionTicket;
/// <summary> The master player entity Id </summary>
public string PlayFabId;
public bool IsClientLoggedIn()
{
return !string.IsNullOrEmpty(ClientSessionTicket);
}
#endif
#if !DISABLE_PLAYFABENTITY_API
/// <summary> Allows access to most Entity APIs </summary>
public string EntityToken;
/// <summary>
/// Clients: The title player entity Id (unless replaced with a related entity)
/// Servers: The title id (unless replaced with a related entity)
/// </summary>
public string EntityId;
/// <summary>
/// Describes the type of entity identified by EntityId
/// </summary>
public string EntityType;
public bool IsEntityLoggedIn()
{
return !string.IsNullOrEmpty(EntityToken);
}
#endif
public void ForgetAllCredentials()
{
#if !DISABLE_PLAYFABCLIENT_API
PlayFabId = null;
ClientSessionTicket = null;
#endif
#if !DISABLE_PLAYFABENTITY_API
EntityToken = null;
EntityId = null;
EntityType = null;
#endif
}
}
}

View File

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

View File

@@ -0,0 +1,138 @@
using UnityEngine;
using System.Text;
using PlayFab.SharedModels;
using UnityEngine.Rendering;
#if NETFX_CORE
using System.Reflection;
#endif
namespace PlayFab
{
public class PlayFabDataGatherer
{
#if UNITY_5 || UNITY_5_3_OR_NEWER
// UNITY_5 Application info
public string ProductName;
public string ProductBundle;
public string Version;
public string Company;
public RuntimePlatform Platform;
// UNITY_5 Graphics Abilities
public bool GraphicsMultiThreaded;
#else
public enum GraphicsDeviceType
{
OpenGL2 = 0, Direct3D9 = 1, Direct3D11 = 2, PlayStation3 = 3, Null = 4, Xbox360 = 6, OpenGLES2 = 8, OpenGLES3 = 11, PlayStationVita = 12,
PlayStation4 = 13, XboxOne = 14, PlayStationMobile = 15, Metal = 16, OpenGLCore = 17, Direct3D12 = 18, Nintendo3DS = 19
}
// RuntimePlatform Enum info:
// OSXEditor = 0, OSXPlayer = 1, WindowsPlayer = 2, OSXWebPlayer = 3, OSXDashboardPlayer = 4, WindowsWebPlayer = 5, WindowsEditor = 7,
// IPhonePlayer = 8, PS3 = 9, XBOX360 = 10, Android = 11, LinuxPlayer = 13, FlashPlayer = 15, WebGLPlayer = 17, MetroPlayerX86 = 18,
// WSAPlayerX86 = 18, MetroPlayerX64 = 19,WSAPlayerX64 = 19, MetroPlayerARM = 20, WSAPlayerARM = 20, WP8Player = 21,
// EditorBrowsable(EditorBrowsableState.Never)] BB10Player = 22, BlackBerryPlayer = 22, TizenPlayer = 23, PSP2 = 24, PS4 = 25,
// PSM = 26, XboxOne = 27, SamsungTVPlayer = 28, WiiU = 30, tvOS = 31
#endif
#if !UNITY_5_0 && (UNITY_5 || UNITY_5_3_OR_NEWER)
public GraphicsDeviceType GraphicsType;
#endif
// Application info
public string DataPath;
public string PersistentDataPath;
public string StreamingAssetsPath;
public int TargetFrameRate;
public string UnityVersion;
public bool RunInBackground;
//DEVICE & OS
public string DeviceModel;
//public enum DeviceType { Unknown, Handheld, Console, Desktop }
public DeviceType DeviceType;
public string DeviceUniqueId;
public string OperatingSystem;
//GRAPHICS ABILITIES
public int GraphicsDeviceId;
public string GraphicsDeviceName;
public int GraphicsMemorySize;
public int GraphicsShaderLevel;
//SYSTEM INFO
public int SystemMemorySize;
public int ProcessorCount;
public int ProcessorFrequency;
public string ProcessorType;
public bool SupportsAccelerometer;
public bool SupportsGyroscope;
public bool SupportsLocationService;
public PlayFabDataGatherer()
{
#if UNITY_5 || UNITY_5_3_OR_NEWER
// UNITY_5 Application info
ProductName = Application.productName;
Version = Application.version;
Company = Application.companyName;
Platform = Application.platform;
// UNITY_5 Graphics Abilities
GraphicsMultiThreaded = SystemInfo.graphicsMultiThreaded;
#endif
#if !UNITY_5_0 && (UNITY_5 || UNITY_5_3_OR_NEWER)
GraphicsType = SystemInfo.graphicsDeviceType;
#endif
//Only Used on iOS & Android
#if UNITY_5_6_OR_NEWER && (UNITY_ANDROID || UNITY_IOS || UNITY_IPHONE)
ProductBundle = Application.identifier;
#elif UNITY_ANDROID || UNITY_IOS || UNITY_IPHONE
ProductBundle = Application.bundleIdentifier;
#endif
// Application info
DataPath = Application.dataPath;
#if !UNITY_SWITCH
PersistentDataPath = Application.persistentDataPath;
#endif
StreamingAssetsPath = Application.streamingAssetsPath;
TargetFrameRate = Application.targetFrameRate;
UnityVersion = Application.unityVersion;
//DEVICE & OS
DeviceModel = SystemInfo.deviceModel;
DeviceType = SystemInfo.deviceType;
DeviceUniqueId = PlayFabSettings.DeviceUniqueIdentifier;
OperatingSystem = SystemInfo.operatingSystem;
//GRAPHICS ABILITIES
GraphicsDeviceId = SystemInfo.graphicsDeviceID;
GraphicsDeviceName = SystemInfo.graphicsDeviceName;
GraphicsMemorySize = SystemInfo.graphicsMemorySize;
GraphicsShaderLevel = SystemInfo.graphicsShaderLevel;
//SYSTEM INFO
SystemMemorySize = SystemInfo.systemMemorySize;
ProcessorCount = SystemInfo.processorCount;
#if UNITY_5_3_OR_NEWER
ProcessorFrequency = SystemInfo.processorFrequency; // Not Supported in PRE Unity 5_2
#endif
ProcessorType = SystemInfo.processorType;
SupportsAccelerometer = SystemInfo.supportsAccelerometer;
SupportsGyroscope = SystemInfo.supportsGyroscope;
SupportsLocationService = SystemInfo.supportsLocationService;
}
public string GenerateReport()
{
var sb = new StringBuilder();
sb.Append("Logging System Info: ========================================\n");
foreach (var field in GetType().GetTypeInfo().GetFields())
{
var fld = field.GetValue(this).ToString();
sb.AppendFormat("System Info - {0}: {1}\n", field.Name, fld);
}
return sb.ToString();
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 9021fc3e0230b9a4db0f0e1b104b764b
timeCreated: 1464569227
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -0,0 +1,270 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Text;
using System.Threading;
using PlayFab.Internal;
using UnityEngine;
namespace PlayFab.Public
{
#if !UNITY_WSA && !UNITY_WP8 && !NETFX_CORE
public interface IPlayFabLogger
{
IPAddress ip { get; set; }
int port { get; set; }
string url { get; set; }
// Unity MonoBehaviour callbacks
void OnEnable();
void OnDisable();
void OnDestroy();
}
/// <summary>
/// This is some unity-log capturing logic, and threading tools that allow logging to be caught and processed on another thread
/// </summary>
public abstract class PlayFabLoggerBase : IPlayFabLogger
{
private static readonly StringBuilder Sb = new StringBuilder();
private readonly Queue<string> LogMessageQueue = new Queue<string>();
private const int LOG_CACHE_INTERVAL_MS = 10000;
private Thread _writeLogThread;
private readonly object _threadLock = new object();
private static readonly TimeSpan _threadKillTimeout = TimeSpan.FromSeconds(60);
private DateTime _threadKillTime = DateTime.UtcNow + _threadKillTimeout; // Kill the thread after 1 minute of inactivity
private bool _isApplicationPlaying = true;
private int _pendingLogsCount;
public IPAddress ip { get; set; }
public int port { get; set; }
public string url { get; set; }
protected PlayFabLoggerBase()
{
var gatherer = new PlayFabDataGatherer();
var message = gatherer.GenerateReport();
lock (LogMessageQueue)
{
LogMessageQueue.Enqueue(message);
}
}
public virtual void OnEnable()
{
PlayFabHttp.instance.StartCoroutine(RegisterLogger()); // Coroutine helper to set up log-callbacks
}
private IEnumerator RegisterLogger()
{
yield return new WaitForEndOfFrame(); // Effectively just a short wait before activating this registration
if (!string.IsNullOrEmpty(PlayFabSettings.LoggerHost))
{
#if UNITY_5 || UNITY_5_3_OR_NEWER
Application.logMessageReceivedThreaded += HandleUnityLog;
#else
Application.RegisterLogCallback(HandleUnityLog);
#endif
}
}
public virtual void OnDisable()
{
if (!string.IsNullOrEmpty(PlayFabSettings.LoggerHost))
{
#if UNITY_5 || UNITY_5_3_OR_NEWER
Application.logMessageReceivedThreaded -= HandleUnityLog;
#else
Application.RegisterLogCallback(null);
#endif
}
}
public virtual void OnDestroy()
{
_isApplicationPlaying = false;
}
/// <summary>
/// Logs are cached and written in bursts
/// BeginUploadLog is called at the begining of each burst
/// </summary>
protected abstract void BeginUploadLog();
/// <summary>
/// Logs are cached and written in bursts
/// UploadLog is called for each cached log, between BeginUploadLog and EndUploadLog
/// </summary>
protected abstract void UploadLog(string message);
/// <summary>
/// Logs are cached and written in bursts
/// EndUploadLog is called at the end of each burst
/// </summary>
protected abstract void EndUploadLog();
/// <summary>
/// Handler to process Unity logs into our logging system
/// </summary>
/// <param name="message"></param>
/// <param name="stacktrace"></param>
/// <param name="type"></param>
private void HandleUnityLog(string message, string stacktrace, LogType type)
{
if (!PlayFabSettings.EnableRealTimeLogging)
return;
Sb.Length = 0;
if (type == LogType.Log || type == LogType.Warning)
{
Sb.Append(type).Append(": ").Append(message);
message = Sb.ToString();
lock (LogMessageQueue)
{
LogMessageQueue.Enqueue(message);
}
}
else if (type == LogType.Error || type == LogType.Exception)
{
Sb.Append(type).Append(": ").Append(message).Append("\n").Append(stacktrace).Append(StackTraceUtility.ExtractStackTrace());
message = Sb.ToString();
lock (LogMessageQueue)
{
LogMessageQueue.Enqueue(message);
}
}
ActivateThreadWorker();
}
private void ActivateThreadWorker()
{
lock (_threadLock)
{
if (_writeLogThread != null)
{
return;
}
_writeLogThread = new Thread(WriteLogThreadWorker);
_writeLogThread.Start();
}
}
private void WriteLogThreadWorker()
{
try
{
bool active;
lock (_threadLock)
{
// Kill the thread after 1 minute of inactivity
_threadKillTime = DateTime.UtcNow + _threadKillTimeout;
}
var localLogQueue = new Queue<string>();
do
{
lock (LogMessageQueue)
{
_pendingLogsCount = LogMessageQueue.Count;
while (LogMessageQueue.Count > 0) // Transfer the messages to the local queue
localLogQueue.Enqueue(LogMessageQueue.Dequeue());
}
BeginUploadLog();
while (localLogQueue.Count > 0) // Transfer the messages to the local queue
UploadLog(localLogQueue.Dequeue());
EndUploadLog();
#region Expire Thread.
// Check if we've been inactive
lock (_threadLock)
{
var now = DateTime.UtcNow;
if (_pendingLogsCount > 0 && _isApplicationPlaying)
{
// Still active, reset the _threadKillTime
_threadKillTime = now + _threadKillTimeout;
}
// Kill the thread after 1 minute of inactivity
active = now <= _threadKillTime;
if (!active)
{
_writeLogThread = null;
}
// This thread will be stopped, so null this now, inside lock (_threadLock)
}
#endregion
Thread.Sleep(LOG_CACHE_INTERVAL_MS);
} while (active);
}
catch (Exception e)
{
Debug.LogException(e);
_writeLogThread = null;
}
}
}
#else
public interface IPlayFabLogger
{
string ip { get; set; }
int port { get; set; }
string url { get; set; }
// Unity MonoBehaviour callbacks
void OnEnable();
void OnDisable();
void OnDestroy();
}
/// <summary>
/// This is just a placeholder. WP8 doesn't support direct threading, but instead makes you use the await command.
/// </summary>
public abstract class PlayFabLoggerBase : IPlayFabLogger
{
public string ip { get; set; }
public int port { get; set; }
public string url { get; set; }
// Unity MonoBehaviour callbacks
public void OnEnable() { }
public void OnDisable() { }
public void OnDestroy() { }
protected abstract void BeginUploadLog();
protected abstract void UploadLog(string message);
protected abstract void EndUploadLog();
}
#endif
/// <summary>
/// This translates the logs up to the PlayFab service via a PlayFab restful API
/// TODO: PLAYFAB - attach these to the PlayFab API
/// </summary>
public class PlayFabLogger : PlayFabLoggerBase
{
/// <summary>
/// Logs are cached and written in bursts
/// BeginUploadLog is called at the begining of each burst
/// </summary>
protected override void BeginUploadLog()
{
}
/// <summary>
/// Logs are cached and written in bursts
/// UploadLog is called for each cached log, between BeginUploadLog and EndUploadLog
/// </summary>
protected override void UploadLog(string message)
{
}
/// <summary>
/// Logs are cached and written in bursts
/// EndUploadLog is called at the end of each burst
/// </summary>
protected override void EndUploadLog()
{
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 65702fe1cdebb8e4783afb157a614161
timeCreated: 1465847308
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,222 @@
using PlayFab.Internal;
using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
namespace PlayFab
{
public enum WebRequestType
{
#if !UNITY_2018_2_OR_NEWER // Unity has deprecated Www
UnityWww, // High compatability Unity api calls
#endif
UnityWebRequest, // Modern unity HTTP component
HttpWebRequest, // High performance multi-threaded api calls
CustomHttp //If this is used, you must set the Http to an IPlayFabHttp object.
}
[Flags]
public enum PlayFabLogLevel
{
None = 0,
Debug = 1 << 0,
Info = 1 << 1,
Warning = 1 << 2,
Error = 1 << 3,
All = Debug | Info | Warning | Error,
}
public static class PlayFabSettings
{
static PlayFabSettings() { }
private static PlayFabSharedSettings _playFabShared = null;
private static PlayFabSharedSettings PlayFabSharedPrivate { get { if (_playFabShared == null) _playFabShared = GetSharedSettingsObjectPrivate(); return _playFabShared; } }
/// <summary>
/// Global settings used by all static API classes, and as the default for all instance API classes
/// </summary>
public static readonly PlayFabApiSettings staticSettings = new PlayFabSettingsRedirect(() => { return PlayFabSharedPrivate; });
/// <summary>
/// Global user for all static API classes
/// </summary>
public static readonly PlayFabAuthenticationContext staticPlayer = new PlayFabAuthenticationContext();
public const string SdkVersion = "2.167.230529";
public const string BuildIdentifier = "adobuild_unitysdk_167";
public const string VersionString = "UnitySDK-2.167.230529";
public const string DefaultPlayFabApiUrl = "playfabapi.com";
private static PlayFabSharedSettings GetSharedSettingsObjectPrivate()
{
var settingsList = Resources.LoadAll<PlayFabSharedSettings>("PlayFabSharedSettings");
if (settingsList.Length != 1)
{
Debug.LogWarning("The number of PlayFabSharedSettings objects should be 1: " + settingsList.Length);
Debug.LogWarning("If you are upgrading your SDK, you can ignore this warning as PlayFabSharedSettings will be imported soon. If you are not upgrading your SDK and you see this message, you should re-download the latest PlayFab source code.");
}
return settingsList[0];
}
public static string DeviceUniqueIdentifier
{
get
{
var deviceId = "";
#if UNITY_ANDROID && !UNITY_EDITOR
AndroidJavaClass up = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
AndroidJavaObject currentActivity = up.GetStatic<AndroidJavaObject> ("currentActivity");
AndroidJavaObject contentResolver = currentActivity.Call<AndroidJavaObject> ("getContentResolver");
AndroidJavaClass secure = new AndroidJavaClass ("android.provider.Settings$Secure");
deviceId = secure.CallStatic<string> ("getString", contentResolver, "android_id");
#else
deviceId = SystemInfo.deviceUniqueIdentifier;
#endif
return deviceId;
}
}
/// <summary>
/// These are variables which can differ from one PlayFab API Instance to another
/// </summary>
#region staticSettings Redirects
// You must set this value for PlayFabSdk to work properly (Found in the Game Manager for your title, at the PlayFab Website)
public static string TitleId { get { return staticSettings.TitleId; } set { staticSettings.TitleId = value; } }
/// <summary> The name of a customer vertical. This is only for customers running a private cluster. Generally you shouldn't touch this </summary>
internal static string VerticalName { get { return staticSettings.VerticalName; } set { staticSettings.VerticalName = value; } }
#if ENABLE_PLAYFABSERVER_API || ENABLE_PLAYFABADMIN_API || UNITY_EDITOR || ENABLE_PLAYFAB_SECRETKEY
public static string DeveloperSecretKey { get { return staticSettings.DeveloperSecretKey; } set { staticSettings.DeveloperSecretKey = value; } }
#endif
/// <summary> Set this to true to prevent hardware information from leaving the device </summary>
public static bool DisableDeviceInfo { get { return staticSettings.DisableDeviceInfo; } set { staticSettings.DisableDeviceInfo = value; } }
/// <summary> Set this to true to prevent focus change information from leaving the device </summary>
public static bool DisableFocusTimeCollection { get { return staticSettings.DisableFocusTimeCollection; } set { staticSettings.DisableFocusTimeCollection = value; } }
#endregion staticSettings Redirects
/// <summary>
/// These are variables which are always singleton global
/// </summary>
#region PlayFabSharedSettings Redirects
[ObsoleteAttribute("LogLevel has been deprecated, please use UnityEngine.Debug.Log for your logging needs.")]
public static PlayFabLogLevel LogLevel { get { return PlayFabSharedPrivate.LogLevel; } set { PlayFabSharedPrivate.LogLevel = value; } }
public static WebRequestType RequestType { get { return PlayFabSharedPrivate.RequestType; } set { PlayFabSharedPrivate.RequestType = value; } }
public static int RequestTimeout { get { return PlayFabSharedPrivate.RequestTimeout; } set { PlayFabSharedPrivate.RequestTimeout = value; } }
public static bool RequestKeepAlive { get { return PlayFabSharedPrivate.RequestKeepAlive; } set { PlayFabSharedPrivate.RequestKeepAlive = value; } }
public static string LoggerHost { get { return PlayFabSharedPrivate.LoggerHost; } set { PlayFabSharedPrivate.LoggerHost = value; } }
public static int LoggerPort { get { return PlayFabSharedPrivate.LoggerPort; } set { PlayFabSharedPrivate.LoggerPort = value; } }
public static bool EnableRealTimeLogging { get { return PlayFabSharedPrivate.EnableRealTimeLogging; } set { PlayFabSharedPrivate.EnableRealTimeLogging = value; } }
public static int LogCapLimit { get { return PlayFabSharedPrivate.LogCapLimit; } set { PlayFabSharedPrivate.LogCapLimit = value; } }
#endregion PlayFabSharedSettings Redirects
private static string _localApiServer;
public static string LocalApiServer
{
get
{
#if UNITY_2017_1_OR_NEWER
return _localApiServer ?? PlayFabUtil.GetLocalSettingsFileProperty("LocalApiServer");
#else
return _localApiServer;
#endif
}
set
{
_localApiServer = value;
}
}
[ThreadStatic]
private static StringBuilder _cachedStringBuilder;
private static StringBuilder AcquireStringBuilder()
{
if (_cachedStringBuilder == null)
{
_cachedStringBuilder = new StringBuilder(1000);
}
_cachedStringBuilder.Clear();
return _cachedStringBuilder;
}
public static string GetFullUrl(string apiCall, Dictionary<string, string> getParams, PlayFabApiSettings apiSettings = null)
{
StringBuilder sb = AcquireStringBuilder();
string productionEnvironmentUrl = null, verticalName = null, titleId = null;
if (apiSettings != null)
{
if (!string.IsNullOrEmpty(apiSettings.ProductionEnvironmentUrl))
{
productionEnvironmentUrl = apiSettings.ProductionEnvironmentUrl;
}
if (!string.IsNullOrEmpty(apiSettings.VerticalName))
{
verticalName = apiSettings.VerticalName;
}
if (!string.IsNullOrEmpty(apiSettings.TitleId))
{
titleId = apiSettings.TitleId;
}
}
if (productionEnvironmentUrl == null)
{
productionEnvironmentUrl = !string.IsNullOrEmpty(PlayFabSharedPrivate.ProductionEnvironmentUrl) ? PlayFabSharedPrivate.ProductionEnvironmentUrl : DefaultPlayFabApiUrl;
}
if (verticalName == null && apiSettings != null && !string.IsNullOrEmpty(apiSettings.VerticalName))
{
verticalName = apiSettings.VerticalName;
}
if (titleId == null)
{
titleId = PlayFabSharedPrivate.TitleId;
}
var baseUrl = productionEnvironmentUrl;
if (!baseUrl.StartsWith("http"))
{
sb.Append("https://");
if (!string.IsNullOrEmpty(titleId))
{
sb.Append(titleId).Append(".");
}
if (!string.IsNullOrEmpty(verticalName))
{
sb.Append(verticalName).Append(".");
}
}
sb.Append(baseUrl).Append(apiCall);
if (getParams != null)
{
bool firstParam = true;
foreach (var paramPair in getParams)
{
if (firstParam)
{
sb.Append("?");
firstParam = false;
}
else
{
sb.Append("&");
}
sb.Append(paramPair.Key).Append("=").Append(paramPair.Value);
}
}
return sb.ToString();
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: aa223f24327e645d39b48f0ca9615e68
timeCreated: 1462682372
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
namespace PlayFab
{
public enum PluginContract
{
PlayFab_Serializer,
PlayFab_Transport
}
}

View File

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

View File

@@ -0,0 +1,23 @@
using System.Collections.Generic;
namespace PlayFab
{
public struct PluginContractKey
{
public PluginContract _pluginContract;
public string _pluginName;
}
public class PluginContractKeyComparator : EqualityComparer<PluginContractKey>
{
public override bool Equals(PluginContractKey x, PluginContractKey y)
{
return x._pluginContract == y._pluginContract && x._pluginName.Equals(y._pluginName);
}
public override int GetHashCode(PluginContractKey obj)
{
return (int)obj._pluginContract + obj._pluginName.GetHashCode();
}
}
}

View File

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

View File

@@ -0,0 +1,110 @@
using System;
using System.Collections.Concurrent;
using PlayFab.Internal;
namespace PlayFab
{
public class PluginManager
{
private ConcurrentDictionary<PluginContractKey, IPlayFabPlugin> plugins = new ConcurrentDictionary<PluginContractKey, IPlayFabPlugin>(new PluginContractKeyComparator());
/// <summary>
/// The singleton instance of plugin manager.
/// </summary>
private static readonly PluginManager Instance = new PluginManager();
private PluginManager()
{
}
/// <summary>
/// Gets a plugin.
/// If a plugin with specified contract and optional instance name does not exist, it will create a new one.
/// </summary>
/// <param name="contract">The plugin contract.</param>
/// <param name="instanceName">The optional plugin instance name. Instance names allow to have mulptiple plugins with the same contract.</param>
/// <returns>The plugin instance.</returns>
public static T GetPlugin<T>(PluginContract contract, string instanceName = "") where T : IPlayFabPlugin
{
return (T)Instance.GetPluginInternal(contract, instanceName);
}
/// <summary>
/// Sets a custom plugin.
/// If a plugin with specified contract and optional instance name already exists, it will be replaced with specified instance.
/// </summary>
/// <param name="plugin">The plugin instance.</param>
/// <param name="contract">The app contract of plugin.</param>
/// <param name="instanceName">The optional plugin instance name. Instance names allow to have mulptiple plugins with the same contract.</param>
public static void SetPlugin(IPlayFabPlugin plugin, PluginContract contract, string instanceName = "")
{
Instance.SetPluginInternal(plugin, contract, instanceName);
}
private IPlayFabPlugin GetPluginInternal(PluginContract contract, string instanceName)
{
var key = new PluginContractKey { _pluginContract = contract, _pluginName = instanceName };
IPlayFabPlugin plugin;
if (!this.plugins.TryGetValue(key, out plugin))
{
// Requested plugin is not in the cache, create the default one
switch (contract)
{
case PluginContract.PlayFab_Serializer:
plugin = this.CreatePlugin<PlayFab.Json.SimpleJsonInstance>();
break;
case PluginContract.PlayFab_Transport:
plugin = this.CreatePlayFabTransportPlugin();
break;
default:
throw new ArgumentException("This contract is not supported", "contract");
}
this.plugins[key] = plugin;
}
return plugin;
}
private void SetPluginInternal(IPlayFabPlugin plugin, PluginContract contract, string instanceName)
{
if (plugin == null)
{
throw new ArgumentNullException("plugin", "Plugin instance cannot be null");
}
var key = new PluginContractKey { _pluginContract = contract, _pluginName = instanceName };
this.plugins[key] = plugin;
}
private IPlayFabPlugin CreatePlugin<T>() where T : IPlayFabPlugin, new()
{
return (IPlayFabPlugin)System.Activator.CreateInstance(typeof(T));
}
private ITransportPlugin CreatePlayFabTransportPlugin()
{
ITransportPlugin transport = null;
#if !UNITY_WSA && !UNITY_WP8
if (PlayFabSettings.RequestType == WebRequestType.HttpWebRequest)
transport = new PlayFabWebRequest();
#endif
#if UNITY_2018_2_OR_NEWER // PlayFabWww will throw warnings as Unity has deprecated Www
if (transport == null)
transport = new PlayFabUnityHttp();
#elif UNITY_2017_2_OR_NEWER
if (PlayFabSettings.RequestType == WebRequestType.UnityWww)
transport = new PlayFabWww();
if (transport == null)
transport = new PlayFabUnityHttp();
#else
if (transport == null)
transport = new PlayFabWww();
#endif
return transport;
}
}
}

View File

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

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: c770a70afd8f88f40bb0f25e3b0dbb55
folderAsset: yes
timeCreated: 1468086149
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,27 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 093286084a3d1994a9c28281a1c38b1d, type: 3}
m_Name: PlayFabSharedSettings
m_EditorClassIdentifier:
TitleId: 6DC6D
DeveloperSecretKey: P4Y6PXT3ZZTP6N1KPZPSF1DOKJAFYIRK7HMGNZNA687OPKW9Y9
ProductionEnvironmentUrl:
RequestType: 0
DisableDeviceInfo: 0
DisableFocusTimeCollection: 0
RequestTimeout: 8000
RequestKeepAlive: 1
LogLevel: 12
LoggerHost:
LoggerPort: 0
EnableRealTimeLogging: 0
LogCapLimit: 30

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 698b2db098268c640929a7b8090a31eb
timeCreated: 1532637394
licenseType: Pro
NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant: