434 lines
16 KiB
C#
434 lines
16 KiB
C#
|
|
using System;
|
||
|
|
using System.Collections;
|
||
|
|
using System.Collections.Generic;
|
||
|
|
using System.IO;
|
||
|
|
using UnityEditor;
|
||
|
|
using UnityEngine;
|
||
|
|
|
||
|
|
namespace PlayFab.PfEditor
|
||
|
|
{
|
||
|
|
public class PlayFabEditor : UnityEditor.EditorWindow
|
||
|
|
{
|
||
|
|
#if !UNITY_5_3_OR_NEWER
|
||
|
|
public GUIContent titleContent;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#region EdEx Variables
|
||
|
|
// vars for the plugin-wide event system
|
||
|
|
public enum EdExStates { OnLogin, OnLogout, OnMenuItemClicked, OnSubmenuItemClicked, OnHttpReq, OnHttpRes, OnError, OnSuccess, OnWarning }
|
||
|
|
|
||
|
|
public delegate void PlayFabEdExStateHandler(EdExStates state, string status, string misc);
|
||
|
|
public static event PlayFabEdExStateHandler EdExStateUpdate;
|
||
|
|
|
||
|
|
public static Dictionary<string, float> blockingRequests = new Dictionary<string, float>(); // key and blockingRequest start time
|
||
|
|
private static float blockingRequestTimeOut = 10f; // abandon the block after this many seconds.
|
||
|
|
|
||
|
|
public static string latestEdExVersion = string.Empty;
|
||
|
|
|
||
|
|
internal static PlayFabEditor window;
|
||
|
|
#endregion
|
||
|
|
|
||
|
|
#region unity lopps & methods
|
||
|
|
void OnEnable()
|
||
|
|
{
|
||
|
|
if (window == null)
|
||
|
|
{
|
||
|
|
window = this;
|
||
|
|
window.minSize = new Vector2(320, 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!IsEventHandlerRegistered(StateUpdateHandler))
|
||
|
|
{
|
||
|
|
EdExStateUpdate += StateUpdateHandler;
|
||
|
|
}
|
||
|
|
|
||
|
|
PlayFabEditorDataService.RefreshStudiosList(true);
|
||
|
|
GetLatestEdExVersion();
|
||
|
|
}
|
||
|
|
|
||
|
|
void OnDisable()
|
||
|
|
{
|
||
|
|
// clean up objects:
|
||
|
|
PlayFabEditorPrefsSO.Instance.PanelIsShown = false;
|
||
|
|
|
||
|
|
if (IsEventHandlerRegistered(StateUpdateHandler))
|
||
|
|
{
|
||
|
|
EdExStateUpdate -= StateUpdateHandler;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void OnFocus()
|
||
|
|
{
|
||
|
|
OnEnable();
|
||
|
|
}
|
||
|
|
|
||
|
|
[MenuItem("Window/PlayFab/Editor Extensions")]
|
||
|
|
static void PlayFabServices()
|
||
|
|
{
|
||
|
|
var editorAsm = typeof(UnityEditor.Editor).Assembly;
|
||
|
|
var inspWndType = editorAsm.GetType("UnityEditor.SceneHierarchyWindow");
|
||
|
|
|
||
|
|
if (inspWndType == null)
|
||
|
|
{
|
||
|
|
inspWndType = editorAsm.GetType("UnityEditor.InspectorWindow");
|
||
|
|
}
|
||
|
|
|
||
|
|
window = GetWindow<PlayFabEditor>(inspWndType);
|
||
|
|
window.titleContent = new GUIContent("PlayFab EdEx");
|
||
|
|
PlayFabEditorPrefsSO.Instance.PanelIsShown = true;
|
||
|
|
}
|
||
|
|
|
||
|
|
[InitializeOnLoad]
|
||
|
|
public static class Startup
|
||
|
|
{
|
||
|
|
static Startup()
|
||
|
|
{
|
||
|
|
if (PlayFabEditorPrefsSO.Instance.PanelIsShown || !PlayFabEditorSDKTools.IsInstalled)
|
||
|
|
{
|
||
|
|
EditorCoroutine.Start(OpenPlayServices());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
static IEnumerator OpenPlayServices()
|
||
|
|
{
|
||
|
|
yield return new WaitForSeconds(1f);
|
||
|
|
if (!Application.isPlaying)
|
||
|
|
{
|
||
|
|
PlayFabServices();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private void OnGUI()
|
||
|
|
{
|
||
|
|
HideRepaintErrors(OnGuiInternal);
|
||
|
|
}
|
||
|
|
|
||
|
|
private void OnGuiInternal()
|
||
|
|
{
|
||
|
|
GUI.skin = PlayFabEditorHelper.uiStyle;
|
||
|
|
|
||
|
|
using (new UnityVertical())
|
||
|
|
{
|
||
|
|
//Run all updaters prior to drawing;
|
||
|
|
PlayFabEditorHeader.DrawHeader();
|
||
|
|
|
||
|
|
GUI.enabled = blockingRequests.Count == 0 && !EditorApplication.isCompiling;
|
||
|
|
|
||
|
|
if (PlayFabEditorAuthenticate.IsAuthenticated())
|
||
|
|
{
|
||
|
|
PlayFabEditorMenu.DrawMenu();
|
||
|
|
|
||
|
|
switch (PlayFabEditorMenu._menuState)
|
||
|
|
{
|
||
|
|
case PlayFabEditorMenu.MenuStates.Sdks:
|
||
|
|
PlayFabEditorSDKTools.DrawSdkPanel();
|
||
|
|
break;
|
||
|
|
case PlayFabEditorMenu.MenuStates.Settings:
|
||
|
|
PlayFabEditorSettings.DrawSettingsPanel();
|
||
|
|
break;
|
||
|
|
case PlayFabEditorMenu.MenuStates.Help:
|
||
|
|
PlayFabEditorHelpMenu.DrawHelpPanel();
|
||
|
|
break;
|
||
|
|
case PlayFabEditorMenu.MenuStates.Data:
|
||
|
|
PlayFabEditorDataMenu.DrawDataPanel();
|
||
|
|
break;
|
||
|
|
case PlayFabEditorMenu.MenuStates.Tools:
|
||
|
|
PlayFabEditorToolsMenu.DrawToolsPanel();
|
||
|
|
break;
|
||
|
|
case PlayFabEditorMenu.MenuStates.Packages:
|
||
|
|
PlayFabEditorPackages.DrawPackagesMenu();
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
PlayFabEditorAuthenticate.DrawAuthPanels();
|
||
|
|
}
|
||
|
|
|
||
|
|
using (new UnityVertical(PlayFabEditorHelper.uiStyle.GetStyle("gpStyleGray1"), GUILayout.ExpandHeight(true), GUILayout.ExpandWidth(true)))
|
||
|
|
{
|
||
|
|
GUILayout.FlexibleSpace();
|
||
|
|
}
|
||
|
|
|
||
|
|
// help tag at the bottom of the help menu.
|
||
|
|
if (PlayFabEditorMenu._menuState == PlayFabEditorMenu.MenuStates.Help)
|
||
|
|
{
|
||
|
|
DisplayHelpMenu();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
PruneBlockingRequests();
|
||
|
|
|
||
|
|
Repaint();
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void HideRepaintErrors(Action action)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
action();
|
||
|
|
}
|
||
|
|
catch (Exception e)
|
||
|
|
{
|
||
|
|
if (!e.Message.ToLower().Contains("repaint"))
|
||
|
|
throw;
|
||
|
|
// Hide any repaint issues when recompiling
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void DisplayHelpMenu()
|
||
|
|
{
|
||
|
|
using (new UnityVertical(PlayFabEditorHelper.uiStyle.GetStyle("gpStyleGray1")))
|
||
|
|
{
|
||
|
|
using (new UnityHorizontal(PlayFabEditorHelper.uiStyle.GetStyle("gpStyleClear")))
|
||
|
|
{
|
||
|
|
GUILayout.FlexibleSpace();
|
||
|
|
EditorGUILayout.LabelField("PlayFab Editor Extensions: " + PlayFabEditorHelper.EDEX_VERSION, PlayFabEditorHelper.uiStyle.GetStyle("versionText"));
|
||
|
|
GUILayout.FlexibleSpace();
|
||
|
|
}
|
||
|
|
|
||
|
|
//TODO Add plugin upgrade option here (if available);
|
||
|
|
if (ShowEdExUpgrade())
|
||
|
|
{
|
||
|
|
using (new UnityHorizontal())
|
||
|
|
{
|
||
|
|
GUILayout.FlexibleSpace();
|
||
|
|
if (GUILayout.Button("UPGRADE EDEX", PlayFabEditorHelper.uiStyle.GetStyle("textButtonOr")))
|
||
|
|
{
|
||
|
|
UpgradeEdEx();
|
||
|
|
}
|
||
|
|
GUILayout.FlexibleSpace();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
using (new UnityHorizontal())
|
||
|
|
{
|
||
|
|
GUILayout.FlexibleSpace();
|
||
|
|
if (GUILayout.Button("VIEW DOCUMENTATION", PlayFabEditorHelper.uiStyle.GetStyle("textButton")))
|
||
|
|
{
|
||
|
|
Application.OpenURL("https://github.com/PlayFab/UnityEditorExtensions");
|
||
|
|
}
|
||
|
|
GUILayout.FlexibleSpace();
|
||
|
|
}
|
||
|
|
|
||
|
|
using (new UnityHorizontal())
|
||
|
|
{
|
||
|
|
GUILayout.FlexibleSpace();
|
||
|
|
if (GUILayout.Button("REPORT ISSUES", PlayFabEditorHelper.uiStyle.GetStyle("textButton")))
|
||
|
|
{
|
||
|
|
Application.OpenURL("https://github.com/PlayFab/UnityEditorExtensions/issues");
|
||
|
|
}
|
||
|
|
GUILayout.FlexibleSpace();
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!string.IsNullOrEmpty(PlayFabEditorHelper.EDEX_ROOT))
|
||
|
|
{
|
||
|
|
using (new UnityHorizontal())
|
||
|
|
{
|
||
|
|
GUILayout.FlexibleSpace();
|
||
|
|
if (GUILayout.Button("UNINSTALL ", PlayFabEditorHelper.uiStyle.GetStyle("textButton")))
|
||
|
|
{
|
||
|
|
RemoveEdEx();
|
||
|
|
}
|
||
|
|
GUILayout.FlexibleSpace();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
#endregion
|
||
|
|
|
||
|
|
#region menu and helper methods
|
||
|
|
public static void RaiseStateUpdate(EdExStates state, string status = null, string json = null)
|
||
|
|
{
|
||
|
|
if (EdExStateUpdate != null)
|
||
|
|
EdExStateUpdate(state, status, json);
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void PruneBlockingRequests()
|
||
|
|
{
|
||
|
|
List<string> itemsToRemove = new List<string>();
|
||
|
|
foreach (var req in blockingRequests)
|
||
|
|
if (req.Value + blockingRequestTimeOut < (float)EditorApplication.timeSinceStartup)
|
||
|
|
itemsToRemove.Add(req.Key);
|
||
|
|
|
||
|
|
foreach (var item in itemsToRemove)
|
||
|
|
{
|
||
|
|
ClearBlockingRequest(item);
|
||
|
|
RaiseStateUpdate(EdExStates.OnWarning, string.Format(" Request {0} has timed out after {1} seconds.", item, blockingRequestTimeOut));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void AddBlockingRequest(string state)
|
||
|
|
{
|
||
|
|
blockingRequests[state] = (float)EditorApplication.timeSinceStartup;
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void ClearBlockingRequest(string state = null)
|
||
|
|
{
|
||
|
|
if (state == null)
|
||
|
|
{
|
||
|
|
blockingRequests.Clear();
|
||
|
|
}
|
||
|
|
else if (blockingRequests.ContainsKey(state))
|
||
|
|
{
|
||
|
|
blockingRequests.Remove(state);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Handles state updates within the editor extension.
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="state">the state that triggered this event.</param>
|
||
|
|
/// <param name="status">a generic message about the status.</param>
|
||
|
|
/// <param name="json">a generic container for additional JSON encoded info.</param>
|
||
|
|
private void StateUpdateHandler(EdExStates state, string status, string json)
|
||
|
|
{
|
||
|
|
switch (state)
|
||
|
|
{
|
||
|
|
case EdExStates.OnMenuItemClicked:
|
||
|
|
PlayFabEditorPrefsSO.Instance.curSubMenuIdx = 0;
|
||
|
|
break;
|
||
|
|
|
||
|
|
case EdExStates.OnSubmenuItemClicked:
|
||
|
|
int parsed;
|
||
|
|
if (int.TryParse(json, out parsed))
|
||
|
|
PlayFabEditorPrefsSO.Instance.curSubMenuIdx = parsed;
|
||
|
|
break;
|
||
|
|
|
||
|
|
case EdExStates.OnHttpReq:
|
||
|
|
object temp;
|
||
|
|
if (string.IsNullOrEmpty(json) || Json.PlayFabSimpleJson.TryDeserializeObject(json, out temp))
|
||
|
|
break;
|
||
|
|
|
||
|
|
var deserialized = temp as Json.JsonObject;
|
||
|
|
object useSpinner = false;
|
||
|
|
object blockUi = false;
|
||
|
|
|
||
|
|
if (deserialized.TryGetValue("useSpinner", out useSpinner) && bool.Parse(useSpinner.ToString()))
|
||
|
|
{
|
||
|
|
ProgressBar.UpdateState(ProgressBar.ProgressBarStates.spin);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (deserialized.TryGetValue("blockUi", out blockUi) && bool.Parse(blockUi.ToString()))
|
||
|
|
{
|
||
|
|
AddBlockingRequest(status);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
case EdExStates.OnHttpRes:
|
||
|
|
ProgressBar.UpdateState(ProgressBar.ProgressBarStates.off);
|
||
|
|
ProgressBar.UpdateState(ProgressBar.ProgressBarStates.success);
|
||
|
|
ClearBlockingRequest(status);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case EdExStates.OnError:
|
||
|
|
// deserialize and add json details
|
||
|
|
// clear blocking requests
|
||
|
|
ProgressBar.UpdateState(ProgressBar.ProgressBarStates.error);
|
||
|
|
ClearBlockingRequest();
|
||
|
|
Debug.LogError(string.Format("PlayFab EditorExtensions: Caught an error:{0}", status));
|
||
|
|
break;
|
||
|
|
|
||
|
|
case EdExStates.OnWarning:
|
||
|
|
ProgressBar.UpdateState(ProgressBar.ProgressBarStates.warning);
|
||
|
|
ClearBlockingRequest();
|
||
|
|
Debug.LogWarning(string.Format("PlayFab EditorExtensions: {0}", status));
|
||
|
|
break;
|
||
|
|
|
||
|
|
case EdExStates.OnSuccess:
|
||
|
|
ClearBlockingRequest();
|
||
|
|
ProgressBar.UpdateState(ProgressBar.ProgressBarStates.success);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static bool IsEventHandlerRegistered(PlayFabEdExStateHandler prospectiveHandler)
|
||
|
|
{
|
||
|
|
if (EdExStateUpdate == null)
|
||
|
|
return false;
|
||
|
|
|
||
|
|
foreach (PlayFabEdExStateHandler existingHandler in EdExStateUpdate.GetInvocationList())
|
||
|
|
if (existingHandler == prospectiveHandler)
|
||
|
|
return true;
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void GetLatestEdExVersion()
|
||
|
|
{
|
||
|
|
var threshold = PlayFabEditorPrefsSO.Instance.EdSet_lastEdExVersionCheck != DateTime.MinValue ? PlayFabEditorPrefsSO.Instance.EdSet_lastEdExVersionCheck.AddHours(1) : DateTime.MinValue;
|
||
|
|
|
||
|
|
if (DateTime.Today > threshold)
|
||
|
|
{
|
||
|
|
PlayFabEditorHttp.MakeGitHubApiCall("https://api.github.com/repos/PlayFab/UnityEditorExtensions/git/refs/tags", (version) =>
|
||
|
|
{
|
||
|
|
latestEdExVersion = version ?? "Unknown";
|
||
|
|
PlayFabEditorPrefsSO.Instance.EdSet_latestEdExVersion = latestEdExVersion;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
latestEdExVersion = PlayFabEditorPrefsSO.Instance.EdSet_latestEdExVersion;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private static bool ShowEdExUpgrade()
|
||
|
|
{
|
||
|
|
if (string.IsNullOrEmpty(latestEdExVersion) || latestEdExVersion == "Unknown")
|
||
|
|
return false;
|
||
|
|
|
||
|
|
if (string.IsNullOrEmpty(PlayFabEditorHelper.EDEX_VERSION) || PlayFabEditorHelper.EDEX_VERSION == "Unknown")
|
||
|
|
return true;
|
||
|
|
|
||
|
|
string[] currrent = PlayFabEditorHelper.EDEX_VERSION.Split('.');
|
||
|
|
if (currrent.Length != 3)
|
||
|
|
return true;
|
||
|
|
|
||
|
|
string[] latest = latestEdExVersion.Split('.');
|
||
|
|
return latest.Length != 3
|
||
|
|
|| int.Parse(latest[0]) > int.Parse(currrent[0])
|
||
|
|
|| int.Parse(latest[1]) > int.Parse(currrent[1])
|
||
|
|
|| int.Parse(latest[2]) > int.Parse(currrent[2]);
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void RemoveEdEx(bool prompt = true)
|
||
|
|
{
|
||
|
|
if (prompt && !EditorUtility.DisplayDialog("Confirm Editor Extensions Removal", "This action will remove PlayFab Editor Extensions from the current project.", "Confirm", "Cancel"))
|
||
|
|
return;
|
||
|
|
|
||
|
|
try
|
||
|
|
{
|
||
|
|
window.Close();
|
||
|
|
var edExRoot = new DirectoryInfo(PlayFabEditorHelper.EDEX_ROOT);
|
||
|
|
FileUtil.DeleteFileOrDirectory(edExRoot.Parent.FullName);
|
||
|
|
AssetDatabase.Refresh();
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
RaiseStateUpdate(EdExStates.OnError, ex.Message);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void UpgradeEdEx()
|
||
|
|
{
|
||
|
|
if (EditorUtility.DisplayDialog("Confirm EdEx Upgrade", "This action will remove the current PlayFab Editor Extensions and install the lastet version.", "Confirm", "Cancel"))
|
||
|
|
{
|
||
|
|
window.Close();
|
||
|
|
ImportLatestEdEx();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void ImportLatestEdEx()
|
||
|
|
{
|
||
|
|
PlayFabEditorHttp.MakeDownloadCall("https://aka.ms/PlayFabUnityEdEx", (fileName) =>
|
||
|
|
{
|
||
|
|
AssetDatabase.ImportPackage(fileName, false);
|
||
|
|
Debug.Log("PlayFab EdEx Upgrade: Complete");
|
||
|
|
});
|
||
|
|
}
|
||
|
|
#endregion
|
||
|
|
}
|
||
|
|
}
|