first commit
This commit is contained in:
8
Assets/Photon/PhotonRealtime/Code/Unity/Editor.meta
Normal file
8
Assets/Photon/PhotonRealtime/Code/Unity/Editor.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a02814c0303a60f488813e6111993aaa
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
260
Assets/Photon/PhotonRealtime/Code/Unity/Editor/AccountService.cs
Normal file
260
Assets/Photon/PhotonRealtime/Code/Unity/Editor/AccountService.cs
Normal file
@ -0,0 +1,260 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// <copyright file="AccountService.cs" company="Exit Games GmbH">
|
||||
// Photon Cloud Account Service - Copyright (C) 2012 Exit Games GmbH
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// Provides methods to register a new user-account for the Photon Cloud and
|
||||
// get the resulting appId.
|
||||
// </summary>
|
||||
// <author>developer@exitgames.com</author>
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#if UNITY_2017_4_OR_NEWER
|
||||
#define SUPPORTED_UNITY
|
||||
#endif
|
||||
|
||||
|
||||
#if UNITY_EDITOR
|
||||
|
||||
namespace Photon.Realtime
|
||||
{
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
using ExitGames.Client.Photon;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates a instance of the Account Service to register Photon Cloud accounts.
|
||||
/// </summary>
|
||||
public class AccountService
|
||||
{
|
||||
private const string ServiceUrl = "https://partner.photonengine.com/api/{0}/User/RegisterEx";
|
||||
|
||||
private readonly Dictionary<string, string> RequestHeaders = new Dictionary<string, string>
|
||||
{
|
||||
{ "Content-Type", "application/json" },
|
||||
{ "x-functions-key", "" }
|
||||
};
|
||||
|
||||
private const string DefaultContext = "Unity";
|
||||
|
||||
private const string DefaultToken = "VQ920wVUieLHT9c3v1ZCbytaLXpXbktUztKb3iYLCdiRKjUagcl6eg==";
|
||||
|
||||
/// <summary>
|
||||
/// third parties custom context, if null, defaults to DefaultContext property value
|
||||
/// </summary>
|
||||
public string CustomContext = null; // "PartnerCode" on the server
|
||||
|
||||
/// <summary>
|
||||
/// third parties custom token. If null, defaults to DefaultToken property value
|
||||
/// </summary>
|
||||
public string CustomToken = null;
|
||||
|
||||
/// <summary>
|
||||
/// If this AccountService instance is currently waiting for a response. While pending, RegisterByEmail is blocked.
|
||||
/// </summary>
|
||||
public bool RequestPendingResult = false;
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to create a Photon Cloud Account asynchronously. Blocked while RequestPendingResult is true.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Once your callback is called, check ReturnCode, Message and AppId to get the result of this attempt.
|
||||
/// </remarks>
|
||||
/// <param name="email">Email of the account.</param>
|
||||
/// <param name="serviceTypes">Defines which type of Photon-service is being requested.</param>
|
||||
/// <param name="callback">Called when the result is available.</param>
|
||||
/// <param name="errorCallback">Called when the request failed.</param>
|
||||
/// <param name="origin">Can be used to identify the origin of the registration (which package is being used).</param>
|
||||
public bool RegisterByEmail(string email, List<ServiceTypes> serviceTypes, Action<AccountServiceResponse> callback = null, Action<string> errorCallback = null, string origin = null)
|
||||
{
|
||||
if (this.RequestPendingResult)
|
||||
{
|
||||
Debug.LogError("Registration request pending result. Not sending another.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!IsValidEmail(email))
|
||||
{
|
||||
Debug.LogErrorFormat("Email \"{0}\" is not valid", email);
|
||||
return false;
|
||||
}
|
||||
|
||||
string serviceTypeString = GetServiceTypesFromList(serviceTypes);
|
||||
if (string.IsNullOrEmpty(serviceTypeString))
|
||||
{
|
||||
Debug.LogError("serviceTypes string is null or empty");
|
||||
return false;
|
||||
}
|
||||
|
||||
string fullUrl = GetUrlWithQueryStringEscaped(email, serviceTypeString, origin);
|
||||
|
||||
RequestHeaders["x-functions-key"] = string.IsNullOrEmpty(CustomToken) ? DefaultToken : CustomToken;
|
||||
|
||||
|
||||
this.RequestPendingResult = true;
|
||||
|
||||
PhotonEditorUtils.StartCoroutine(
|
||||
PhotonEditorUtils.HttpPost(fullUrl,
|
||||
RequestHeaders,
|
||||
null,
|
||||
s =>
|
||||
{
|
||||
this.RequestPendingResult = false;
|
||||
//Debug.LogWarningFormat("received response {0}", s);
|
||||
if (string.IsNullOrEmpty(s))
|
||||
{
|
||||
if (errorCallback != null)
|
||||
{
|
||||
errorCallback("Server's response was empty. Please register through account website during this service interruption.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AccountServiceResponse ase = this.ParseResult(s);
|
||||
if (ase == null)
|
||||
{
|
||||
if (errorCallback != null)
|
||||
{
|
||||
errorCallback("Error parsing registration response. Please try registering from account website");
|
||||
}
|
||||
}
|
||||
else if (callback != null)
|
||||
{
|
||||
callback(ase);
|
||||
}
|
||||
}
|
||||
},
|
||||
e =>
|
||||
{
|
||||
this.RequestPendingResult = false;
|
||||
if (errorCallback != null)
|
||||
{
|
||||
errorCallback(e);
|
||||
}
|
||||
})
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private string GetUrlWithQueryStringEscaped(string email, string serviceTypes, string originAv)
|
||||
{
|
||||
string emailEscaped = UnityEngine.Networking.UnityWebRequest.EscapeURL(email);
|
||||
string st = UnityEngine.Networking.UnityWebRequest.EscapeURL(serviceTypes);
|
||||
string uv = UnityEngine.Networking.UnityWebRequest.EscapeURL(Application.unityVersion);
|
||||
string serviceUrl = string.Format(ServiceUrl, string.IsNullOrEmpty(CustomContext) ? DefaultContext : CustomContext );
|
||||
|
||||
return string.Format("{0}?email={1}&st={2}&uv={3}&av={4}", serviceUrl, emailEscaped, st, uv, originAv);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the Json response and applies it to local properties.
|
||||
/// </summary>
|
||||
/// <param name="result"></param>
|
||||
private AccountServiceResponse ParseResult(string result)
|
||||
{
|
||||
try
|
||||
{
|
||||
AccountServiceResponse res = JsonUtility.FromJson<AccountServiceResponse>(result);
|
||||
// Unity's JsonUtility does not support deserializing Dictionary, we manually parse it, dirty & ugly af, better then using a 3rd party lib
|
||||
if (res.ReturnCode == AccountServiceReturnCodes.Success)
|
||||
{
|
||||
string[] parts = result.Split(new[] { "\"ApplicationIds\":{" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
parts = parts[1].Split('}');
|
||||
string applicationIds = parts[0];
|
||||
if (!string.IsNullOrEmpty(applicationIds))
|
||||
{
|
||||
parts = applicationIds.Split(new[] { ',', '"', ':' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
res.ApplicationIds = new Dictionary<string, string>(parts.Length / 2);
|
||||
for (int i = 0; i < parts.Length; i = i + 2)
|
||||
{
|
||||
res.ApplicationIds.Add(parts[i], parts[i + 1]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("The server did not return any AppId, ApplicationIds was empty in the response.");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
catch (Exception ex) // probably JSON parsing exception, check if returned string is valid JSON
|
||||
{
|
||||
Debug.LogException(ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Turns the list items to a comma separated string. Returns null if list is null or empty.
|
||||
/// </summary>
|
||||
/// <param name="appTypes">List of service types.</param>
|
||||
/// <returns>Returns null if list is null or empty.</returns>
|
||||
private static string GetServiceTypesFromList(List<ServiceTypes> appTypes)
|
||||
{
|
||||
if (appTypes == null || appTypes.Count <= 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
string serviceTypes = ((int)appTypes[0]).ToString();
|
||||
for (int i = 1; i < appTypes.Count; i++)
|
||||
{
|
||||
int appType = (int)appTypes[i];
|
||||
serviceTypes = string.Format("{0},{1}", serviceTypes, appType);
|
||||
}
|
||||
|
||||
return serviceTypes;
|
||||
}
|
||||
|
||||
// RFC2822 compliant matching 99.9% of all email addresses in actual use today
|
||||
// according to http://www.regular-expressions.info/email.html [22.02.2012]
|
||||
private static Regex reg = new Regex("^((?>[a-zA-Z\\d!#$%&'*+\\-/=?^_{|}~]+\\x20*|\"((?=[\\x01-\\x7f])[^\"\\]|\\[\\x01-\\x7f])*\"\\x20*)*(?<angle><))?((?!\\.)(?>\\.?[a-zA-Z\\d!#$%&'*+\\-/=?^_{|}~]+)+|\"((?=[\\x01-\\x7f])[^\"\\]|\\[\\x01-\\x7f])*\")@(((?!-)[a-zA-Z\\d\\-]+(?<!-)\\.)+[a-zA-Z]{2,}|\\[(((?(?<!\\[)\\.)(25[0-5]|2[0-4]\\d|[01]?\\d?\\d)){4}|[a-zA-Z\\d\\-]*[a-zA-Z\\d]:((?=[\\x01-\\x7f])[^\\\\[\\]]|\\[\\x01-\\x7f])+)\\])(?(angle)>)$",
|
||||
RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
|
||||
public static bool IsValidEmail(string mailAddress)
|
||||
{
|
||||
if (string.IsNullOrEmpty(mailAddress))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var result = reg.Match(mailAddress);
|
||||
return result.Success;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class AccountServiceResponse
|
||||
{
|
||||
public int ReturnCode;
|
||||
public string Message;
|
||||
public Dictionary<string, string> ApplicationIds; // Unity's JsonUtility does not support deserializing Dictionary
|
||||
}
|
||||
|
||||
|
||||
public class AccountServiceReturnCodes
|
||||
{
|
||||
public static int Success = 0;
|
||||
public static int EmailAlreadyRegistered = 8;
|
||||
public static int InvalidParameters = 12;
|
||||
}
|
||||
|
||||
public enum ServiceTypes
|
||||
{
|
||||
Realtime = 0,
|
||||
Turnbased = 1,
|
||||
Chat = 2,
|
||||
Voice = 3,
|
||||
TrueSync = 4,
|
||||
Pun = 5,
|
||||
Thunder = 6,
|
||||
Quantum = 7,
|
||||
Fusion = 8,
|
||||
Bolt = 20
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 166dfe22956ef0341b28e18d0499e363
|
||||
labels:
|
||||
- ExitGames
|
||||
- PUN
|
||||
- Photon
|
||||
- Networking
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
@ -0,0 +1,333 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// <copyright file="PhotonEditorUtils.cs" company="Exit Games GmbH">
|
||||
// PhotonNetwork Framework for Unity - Copyright (C) 2018 Exit Games GmbH
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// Unity Editor Utils
|
||||
// </summary>
|
||||
// <author>developer@exitgames.com</author>
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#pragma warning disable 618 // Deprecation warnings
|
||||
|
||||
|
||||
#if UNITY_2017_4_OR_NEWER
|
||||
#define SUPPORTED_UNITY
|
||||
#endif
|
||||
|
||||
|
||||
#if UNITY_EDITOR
|
||||
|
||||
namespace Photon.Realtime
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
|
||||
[InitializeOnLoad]
|
||||
public static class PhotonEditorUtils
|
||||
{
|
||||
/// <summary>Stores a flag which tells Editor scripts if the PhotonEditor.OnProjectChanged got called since initialization.</summary>
|
||||
/// <remarks>If not, the AssetDatabase is likely not usable yet and instances of ScriptableObject can't be loaded.</remarks>
|
||||
public static bool ProjectChangedWasCalled;
|
||||
|
||||
|
||||
/// <summary>True if the ChatClient of the Photon Chat API is available. If so, the editor may (e.g.) show additional options in settings.</summary>
|
||||
public static bool HasChat;
|
||||
|
||||
/// <summary>True if the VoiceClient of the Photon Voice API is available. If so, the editor may (e.g.) show additional options in settings.</summary>
|
||||
public static bool HasVoice;
|
||||
|
||||
/// <summary>True if PUN is in the project.</summary>
|
||||
public static bool HasPun;
|
||||
|
||||
/// <summary>True if Photon Fusion is available in the project (and enabled).</summary>
|
||||
public static bool HasFusion;
|
||||
|
||||
/// <summary>True if the PhotonEditorUtils checked the available products / APIs. If so, the editor may (e.g.) show additional options in settings.</summary>
|
||||
public static bool HasCheckedProducts;
|
||||
|
||||
static PhotonEditorUtils()
|
||||
{
|
||||
HasVoice = Type.GetType("Photon.Voice.VoiceClient, Assembly-CSharp") != null || Type.GetType("Photon.Voice.VoiceClient, Assembly-CSharp-firstpass") != null || Type.GetType("Photon.Voice.VoiceClient, PhotonVoice.API") != null;
|
||||
HasChat = Type.GetType("Photon.Chat.ChatClient, Assembly-CSharp") != null || Type.GetType("Photon.Chat.ChatClient, Assembly-CSharp-firstpass") != null || Type.GetType("Photon.Chat.ChatClient, PhotonChat") != null;
|
||||
HasPun = Type.GetType("Photon.Pun.PhotonNetwork, Assembly-CSharp") != null || Type.GetType("Photon.Pun.PhotonNetwork, Assembly-CSharp-firstpass") != null || Type.GetType("Photon.Pun.PhotonNetwork, PhotonUnityNetworking") != null;
|
||||
#if FUSION_WEAVER
|
||||
HasFusion = true;
|
||||
#endif
|
||||
PhotonEditorUtils.HasCheckedProducts = true;
|
||||
|
||||
if (EditorPrefs.HasKey("DisablePun") && EditorPrefs.GetBool("DisablePun"))
|
||||
{
|
||||
HasPun = false;
|
||||
}
|
||||
|
||||
if (HasPun)
|
||||
{
|
||||
// MOUNTING SYMBOLS
|
||||
#if !PHOTON_UNITY_NETWORKING
|
||||
AddScriptingDefineSymbolToAllBuildTargetGroups("PHOTON_UNITY_NETWORKING");
|
||||
#endif
|
||||
|
||||
#if !PUN_2_0_OR_NEWER
|
||||
AddScriptingDefineSymbolToAllBuildTargetGroups("PUN_2_0_OR_NEWER");
|
||||
#endif
|
||||
|
||||
#if !PUN_2_OR_NEWER
|
||||
AddScriptingDefineSymbolToAllBuildTargetGroups("PUN_2_OR_NEWER");
|
||||
#endif
|
||||
|
||||
#if !PUN_2_19_OR_NEWER
|
||||
AddScriptingDefineSymbolToAllBuildTargetGroups("PUN_2_19_OR_NEWER");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a given scripting define symbol to all build target groups
|
||||
/// You can see all scripting define symbols ( not the internal ones, only the one for this project), in the PlayerSettings inspector
|
||||
/// </summary>
|
||||
/// <param name="defineSymbol">Define symbol.</param>
|
||||
public static void AddScriptingDefineSymbolToAllBuildTargetGroups(string defineSymbol)
|
||||
{
|
||||
foreach (BuildTarget target in Enum.GetValues(typeof(BuildTarget)))
|
||||
{
|
||||
BuildTargetGroup group = BuildPipeline.GetBuildTargetGroup(target);
|
||||
|
||||
if (group == BuildTargetGroup.Unknown)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var defineSymbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(group).Split(';').Select(d => d.Trim()).ToList();
|
||||
|
||||
if (!defineSymbols.Contains(defineSymbol))
|
||||
{
|
||||
defineSymbols.Add(defineSymbol);
|
||||
|
||||
try
|
||||
{
|
||||
PlayerSettings.SetScriptingDefineSymbolsForGroup(group, string.Join(";", defineSymbols.ToArray()));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Log("Could not set Photon " + defineSymbol + " defines for build target: " + target + " group: " + group + " " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Removes PUN2's Script Define Symbols from project
|
||||
/// </summary>
|
||||
public static void CleanUpPunDefineSymbols()
|
||||
{
|
||||
foreach (BuildTarget target in Enum.GetValues(typeof(BuildTarget)))
|
||||
{
|
||||
BuildTargetGroup group = BuildPipeline.GetBuildTargetGroup(target);
|
||||
|
||||
if (group == BuildTargetGroup.Unknown)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var defineSymbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(group)
|
||||
.Split(';')
|
||||
.Select(d => d.Trim())
|
||||
.ToList();
|
||||
|
||||
List<string> newDefineSymbols = new List<string>();
|
||||
foreach (var symbol in defineSymbols)
|
||||
{
|
||||
if ("PHOTON_UNITY_NETWORKING".Equals(symbol) || symbol.StartsWith("PUN_2_"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
newDefineSymbols.Add(symbol);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
PlayerSettings.SetScriptingDefineSymbolsForGroup(group, string.Join(";", newDefineSymbols.ToArray()));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogErrorFormat("Could not set clean up PUN2's define symbols for build target: {0} group: {1}, {2}", target, group, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parent directory of a path. Recursive Function, will return null if parentName not found
|
||||
/// </summary>
|
||||
/// <returns>The parent directory</returns>
|
||||
/// <param name="path">Path.</param>
|
||||
/// <param name="parentName">Parent name.</param>
|
||||
public static string GetParent(string path, string parentName)
|
||||
{
|
||||
var dir = new DirectoryInfo(path);
|
||||
|
||||
if (dir.Parent == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(parentName))
|
||||
{
|
||||
return dir.Parent.FullName;
|
||||
}
|
||||
|
||||
if (dir.Parent.Name == parentName)
|
||||
{
|
||||
return dir.Parent.FullName;
|
||||
}
|
||||
|
||||
return GetParent(dir.Parent.FullName, parentName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if a GameObject is a prefab asset or part of a prefab asset, as opposed to an instance in the scene hierarchy
|
||||
/// </summary>
|
||||
/// <returns><c>true</c>, if a prefab asset or part of it, <c>false</c> otherwise.</returns>
|
||||
/// <param name="go">The GameObject to check</param>
|
||||
public static bool IsPrefab(GameObject go)
|
||||
{
|
||||
#if UNITY_2021_2_OR_NEWER
|
||||
return UnityEditor.SceneManagement.PrefabStageUtility.GetPrefabStage(go) != null || EditorUtility.IsPersistent(go);
|
||||
#elif UNITY_2018_3_OR_NEWER
|
||||
return UnityEditor.Experimental.SceneManagement.PrefabStageUtility.GetPrefabStage(go) != null || EditorUtility.IsPersistent(go);
|
||||
#else
|
||||
return EditorUtility.IsPersistent(go);
|
||||
#endif
|
||||
}
|
||||
|
||||
//https://forum.unity.com/threads/using-unitywebrequest-in-editor-tools.397466/#post-4485181
|
||||
public static void StartCoroutine(System.Collections.IEnumerator update)
|
||||
{
|
||||
EditorApplication.CallbackFunction closureCallback = null;
|
||||
|
||||
closureCallback = () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
if (update.MoveNext() == false)
|
||||
{
|
||||
EditorApplication.update -= closureCallback;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogException(ex);
|
||||
EditorApplication.update -= closureCallback;
|
||||
}
|
||||
};
|
||||
|
||||
EditorApplication.update += closureCallback;
|
||||
}
|
||||
|
||||
public static System.Collections.IEnumerator HttpPost(string url, Dictionary<string, string> headers, byte[] payload, Action<string> successCallback, Action<string> errorCallback)
|
||||
{
|
||||
using (UnityWebRequest w = new UnityWebRequest(url, "POST"))
|
||||
{
|
||||
if (payload != null)
|
||||
{
|
||||
w.uploadHandler = new UploadHandlerRaw(payload);
|
||||
}
|
||||
w.downloadHandler = new DownloadHandlerBuffer();
|
||||
if (headers != null)
|
||||
{
|
||||
foreach (var header in headers)
|
||||
{
|
||||
w.SetRequestHeader(header.Key, header.Value);
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_2017_2_OR_NEWER
|
||||
yield return w.SendWebRequest();
|
||||
#else
|
||||
yield return w.Send();
|
||||
#endif
|
||||
|
||||
while (w.isDone == false)
|
||||
yield return null;
|
||||
|
||||
#if UNITY_2020_2_OR_NEWER
|
||||
if (w.result == UnityWebRequest.Result.ProtocolError || w.result == UnityWebRequest.Result.ConnectionError || w.result == UnityWebRequest.Result.DataProcessingError)
|
||||
#elif UNITY_2017_1_OR_NEWER
|
||||
if (w.isNetworkError || w.isHttpError)
|
||||
#endif
|
||||
{
|
||||
if (errorCallback != null)
|
||||
{
|
||||
errorCallback(w.error);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (successCallback != null)
|
||||
{
|
||||
successCallback(w.downloadHandler.text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a Foldout using a toggle with (GUIStyle)"Foldout") and a separate label. This is a workaround for 2019.3 foldout arrows not working.
|
||||
/// </summary>
|
||||
/// <param name="isExpanded"></param>
|
||||
/// <param name="label"></param>
|
||||
/// <returns>Returns the new isExpanded value.</returns>
|
||||
public static bool Foldout(this SerializedProperty isExpanded, GUIContent label)
|
||||
{
|
||||
var rect = EditorGUILayout.GetControlRect();
|
||||
bool newvalue = EditorGUI.Toggle(new Rect(rect) { xMin = rect.xMin + 2 }, GUIContent.none, isExpanded.boolValue, (GUIStyle)"Foldout");
|
||||
EditorGUI.LabelField(new Rect(rect) { xMin = rect.xMin + 15 }, label);
|
||||
if (newvalue != isExpanded.boolValue)
|
||||
{
|
||||
isExpanded.boolValue = newvalue;
|
||||
isExpanded.serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
return newvalue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a Foldout using a toggle with (GUIStyle)"Foldout") and a separate label. This is a workaround for 2019.3 foldout arrows not working.
|
||||
/// </summary>
|
||||
/// <param name="isExpanded"></param>
|
||||
/// <param name="label"></param>
|
||||
/// <returns>Returns the new isExpanded value.</returns>
|
||||
public static bool Foldout(this bool isExpanded, GUIContent label)
|
||||
{
|
||||
var rect = EditorGUILayout.GetControlRect();
|
||||
bool newvalue = EditorGUI.Toggle(new Rect(rect) { xMin = rect.xMin + 2 }, GUIContent.none, isExpanded, (GUIStyle)"Foldout");
|
||||
EditorGUI.LabelField(new Rect(rect) { xMin = rect.xMin + 15 }, label);
|
||||
return newvalue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class CleanUpDefinesOnPunDelete : UnityEditor.AssetModificationProcessor
|
||||
{
|
||||
public static AssetDeleteResult OnWillDeleteAsset(string assetPath, RemoveAssetOptions rao)
|
||||
{
|
||||
if ("Assets/Photon/PhotonUnityNetworking".Equals(assetPath))
|
||||
{
|
||||
PhotonEditorUtils.CleanUpPunDefineSymbols();
|
||||
}
|
||||
|
||||
return AssetDeleteResult.DidNotDelete;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 607340ca505d53d4f8e785423fac7964
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
116
Assets/Photon/PhotonRealtime/Code/Unity/PhotonAppSettings.cs
Normal file
116
Assets/Photon/PhotonRealtime/Code/Unity/PhotonAppSettings.cs
Normal file
@ -0,0 +1,116 @@
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="PhotonAppSettings.cs" company="Exit Games GmbH">
|
||||
// </copyright>
|
||||
// <author>developer@photonengine.com</author>
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#if UNITY_2017_4_OR_NEWER
|
||||
#define SUPPORTED_UNITY
|
||||
#endif
|
||||
|
||||
|
||||
#if !PHOTON_UNITY_NETWORKING
|
||||
|
||||
namespace Photon.Realtime
|
||||
{
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
/// <summary>
|
||||
/// Collection of connection-relevant settings, used internally by PhotonNetwork.ConnectUsingSettings.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Includes the AppSettings class from the Realtime APIs plus some other, PUN-relevant, settings.</remarks>
|
||||
[Serializable]
|
||||
[HelpURL("https://doc.photonengine.com/en-us/pun/v2/getting-started/initial-setup")]
|
||||
public class PhotonAppSettings : ScriptableObject
|
||||
{
|
||||
[Tooltip("Core Photon Server/Cloud settings.")]
|
||||
public AppSettings AppSettings;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[HideInInspector]
|
||||
public bool DisableAutoOpenWizard;
|
||||
//public bool ShowSettings;
|
||||
//public bool DevRegionSetOnce;
|
||||
#endif
|
||||
|
||||
private static PhotonAppSettings instance;
|
||||
|
||||
/// <summary>Serialized server settings, written by the Setup Wizard for use in ConnectUsingSettings.</summary>
|
||||
public static PhotonAppSettings Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (instance == null)
|
||||
{
|
||||
LoadOrCreateSettings();
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
private set { instance = value; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void LoadOrCreateSettings()
|
||||
{
|
||||
if (instance != null)
|
||||
{
|
||||
Debug.LogWarning("Instance is not null. Will not LoadOrCreateSettings().");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#if UNITY_EDITOR
|
||||
// let's check if the AssetDatabase finds the file; aimed to avoid multiple files being created, potentially a futile step
|
||||
AssetDatabase.Refresh();
|
||||
#endif
|
||||
|
||||
// try to load the resource / asset (ServerSettings a.k.a. PhotonServerSettings)
|
||||
instance = (PhotonAppSettings)Resources.Load(typeof(PhotonAppSettings).Name, typeof(PhotonAppSettings));
|
||||
if (instance != null)
|
||||
{
|
||||
//Debug.LogWarning("Settings from Resources."); // DEBUG
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// create it if not loaded
|
||||
if (instance == null)
|
||||
{
|
||||
instance = (PhotonAppSettings)CreateInstance(typeof(PhotonAppSettings));
|
||||
if (instance == null)
|
||||
{
|
||||
Debug.LogError("Failed to create ServerSettings. PUN is unable to run this way. If you deleted it from the project, reload the Editor.");
|
||||
return;
|
||||
}
|
||||
|
||||
//Debug.LogWarning("Settings created!"); // DEBUG
|
||||
}
|
||||
|
||||
// in the editor, store the settings file as it's not loaded
|
||||
#if UNITY_EDITOR
|
||||
string punResourcesDirectory = "Assets/Photon/Resources/";
|
||||
string serverSettingsAssetPath = punResourcesDirectory + typeof(PhotonAppSettings).Name + ".asset";
|
||||
string serverSettingsDirectory = Path.GetDirectoryName(serverSettingsAssetPath);
|
||||
|
||||
if (!Directory.Exists(serverSettingsDirectory))
|
||||
{
|
||||
Directory.CreateDirectory(serverSettingsDirectory);
|
||||
AssetDatabase.ImportAsset(serverSettingsDirectory);
|
||||
}
|
||||
|
||||
AssetDatabase.CreateAsset(instance, serverSettingsAssetPath);
|
||||
AssetDatabase.SaveAssets();
|
||||
|
||||
|
||||
//Debug.Log("Settings stored to DB."); // DEBUG
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a389b614f52fbf347a1533dbbf245033
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user