381 lines
14 KiB
C#
381 lines
14 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
|
|
namespace AppCenterEditor
|
|
{
|
|
public class AppCenterEditor : EditorWindow
|
|
{
|
|
private Vector2 scrollPosition = Vector2.zero;
|
|
private const string EditorExtensionsDownloadFormat = "https://github.com/Microsoft/AppCenter-SDK-Unity-Extension/releases/download/{0}/AppCenterEditorExtensions-v{0}.unitypackage";
|
|
public enum EdExStates { OnMenuItemClicked, OnHttpReq, OnHttpRes, OnError, OnSuccess, OnWarning }
|
|
|
|
public delegate void AppCenterEdExStateHandler(EdExStates state, string status, string misc);
|
|
public static event AppCenterEdExStateHandler 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;
|
|
|
|
private static Rect scrollInnerContainer;
|
|
public static float InnerContainerWidth
|
|
{
|
|
get
|
|
{
|
|
return scrollInnerContainer.width;
|
|
}
|
|
}
|
|
|
|
internal static AppCenterEditor window;
|
|
|
|
void OnEnable()
|
|
{
|
|
if (window == null)
|
|
{
|
|
window = this;
|
|
window.minSize = new Vector2(320, 0);
|
|
}
|
|
|
|
if (!IsEventHandlerRegistered(StateUpdateHandler))
|
|
{
|
|
EdExStateUpdate += StateUpdateHandler;
|
|
}
|
|
|
|
GetLatestEdExVersion();
|
|
}
|
|
|
|
void OnDisable()
|
|
{
|
|
AppCenterEditorPrefsSO.Instance.PanelIsShown = false;
|
|
|
|
if (IsEventHandlerRegistered(StateUpdateHandler))
|
|
{
|
|
EdExStateUpdate -= StateUpdateHandler;
|
|
}
|
|
}
|
|
|
|
void OnFocus()
|
|
{
|
|
OnEnable();
|
|
}
|
|
|
|
[MenuItem("Window/App Center/Editor Extensions")]
|
|
static void AppCenterServices()
|
|
{
|
|
var editorAsm = typeof(Editor).Assembly;
|
|
var inspWndType = editorAsm.GetType("UnityEditor.SceneHierarchyWindow");
|
|
|
|
if (inspWndType == null)
|
|
{
|
|
inspWndType = editorAsm.GetType("UnityEditor.InspectorWindow");
|
|
}
|
|
|
|
window = GetWindow<AppCenterEditor>(inspWndType);
|
|
window.titleContent = new GUIContent("App Center");
|
|
AppCenterEditorPrefsSO.Instance.PanelIsShown = true;
|
|
}
|
|
|
|
[InitializeOnLoad]
|
|
public class Startup
|
|
{
|
|
static Startup()
|
|
{
|
|
if (AppCenterEditorPrefsSO.Instance.PanelIsShown || !AppCenterEditorSDKTools.IsInstalled)
|
|
{
|
|
Coroutiner.StartCoroutine(OpenAppCenterServices());
|
|
}
|
|
}
|
|
}
|
|
|
|
static IEnumerator OpenAppCenterServices()
|
|
{
|
|
yield return new WaitForSeconds(1f);
|
|
if (!Application.isPlaying)
|
|
{
|
|
AppCenterServices();
|
|
}
|
|
}
|
|
|
|
private void OnGUI()
|
|
{
|
|
HideRepaintErrors(OnGuiInternal);
|
|
}
|
|
|
|
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 void OnGuiInternal()
|
|
{
|
|
GUI.skin = AppCenterEditorHelper.uiStyle;
|
|
scrollPosition = GUILayout.BeginScrollView(scrollPosition, false, false, GUILayout.Width(window.position.width), GUILayout.Height(window.position.height));
|
|
// Gets a rectangle with size of inner scroll area.
|
|
scrollInnerContainer = EditorGUILayout.BeginHorizontal(GUILayout.ExpandHeight(true), GUILayout.ExpandWidth(true));
|
|
using (new AppCenterGuiFieldHelper.UnityVertical(
|
|
GUILayout.Width(scrollInnerContainer.width),
|
|
GUILayout.MaxWidth(scrollInnerContainer.width),
|
|
GUILayout.Height(scrollInnerContainer.height)))
|
|
{
|
|
GUI.enabled = IsGUIEnabled();
|
|
AppCenterEditorHeader.DrawHeader();
|
|
AppCenterEditorMenu.DrawMenu();
|
|
AppCenterEditorSDKTools.DrawSdkPanel();
|
|
foreach (var package in AppCenterSDKPackage.SupportedPackages)
|
|
{
|
|
AppCenterEditorSDKTools.DisplayPackagePanel(package);
|
|
}
|
|
AppCenterEditorSDKTools.SDKState state = AppCenterEditorSDKTools.GetSDKState();
|
|
if (state == AppCenterEditorSDKTools.SDKState.SDKIsFull || state == AppCenterEditorSDKTools.SDKState.SDKNotFull)
|
|
{
|
|
AppCenterEditorSDKTools.ShowUpgradePanel();
|
|
}
|
|
DisplayEditorExtensionHelpMenu();
|
|
}
|
|
EditorGUILayout.EndHorizontal();
|
|
GUILayout.EndScrollView();
|
|
PruneBlockingRequests();
|
|
Repaint();
|
|
}
|
|
|
|
public static bool IsGUIEnabled()
|
|
{
|
|
if (blockingRequests.Count > 0 || EditorApplication.isCompiling)
|
|
{
|
|
return false;
|
|
}
|
|
AppCenterEditorSDKTools.SDKState state = AppCenterEditorSDKTools.GetSDKState();
|
|
return
|
|
!AppCenterEditorSDKTools.IsUpgrading &&
|
|
state != AppCenterEditorSDKTools.SDKState.SDKNotFullAndInstalling &&
|
|
state != AppCenterEditorSDKTools.SDKState.SDKNotInstalledAndInstalling;
|
|
}
|
|
|
|
private static void DisplayEditorExtensionHelpMenu()
|
|
{
|
|
using (new AppCenterGuiFieldHelper.UnityVertical(AppCenterEditorHelper.uiStyle.GetStyle("gpStyleGray1")))
|
|
{
|
|
using (new AppCenterGuiFieldHelper.UnityHorizontal(AppCenterEditorHelper.uiStyle.GetStyle("gpStyleClear")))
|
|
{
|
|
GUILayout.FlexibleSpace();
|
|
EditorGUILayout.LabelField("App Center Editor Extensions: " + AppCenterEditorHelper.EDEX_VERSION, AppCenterEditorHelper.uiStyle.GetStyle("versionText"));
|
|
GUILayout.FlexibleSpace();
|
|
}
|
|
|
|
if (ShowEdExUpgrade())
|
|
{
|
|
using (new AppCenterGuiFieldHelper.UnityHorizontal())
|
|
{
|
|
GUILayout.FlexibleSpace();
|
|
if (GUILayout.Button("UPGRADE EDITOR EXTENSION", AppCenterEditorHelper.uiStyle.GetStyle("textButtonMagenta")))
|
|
{
|
|
UpgradeEdEx();
|
|
}
|
|
GUILayout.FlexibleSpace();
|
|
}
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(AppCenterEditorHelper.EDEX_ROOT))
|
|
{
|
|
using (new AppCenterGuiFieldHelper.UnityHorizontal())
|
|
{
|
|
GUILayout.FlexibleSpace();
|
|
if (GUILayout.Button("UNINSTALL EDITOR EXTENSION", AppCenterEditorHelper.uiStyle.GetStyle("textButton")))
|
|
{
|
|
RemoveEdEx();
|
|
}
|
|
GUILayout.FlexibleSpace();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#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:
|
|
break;
|
|
|
|
case EdExStates.OnHttpReq:
|
|
break;
|
|
|
|
case EdExStates.OnHttpRes:
|
|
break;
|
|
|
|
case EdExStates.OnError:
|
|
ProgressBar.UpdateState(ProgressBar.ProgressBarStates.error);
|
|
EdExLogger.LoggerInstance.LogError(string.Format("App Center Editor Extensions: {0}", status));
|
|
break;
|
|
|
|
case EdExStates.OnWarning:
|
|
ProgressBar.UpdateState(ProgressBar.ProgressBarStates.warning);
|
|
EdExLogger.LoggerInstance.LogWarning(string.Format("App Center Editor Extensions: {0}", status));
|
|
break;
|
|
|
|
case EdExStates.OnSuccess:
|
|
ProgressBar.UpdateState(ProgressBar.ProgressBarStates.success);
|
|
break;
|
|
}
|
|
}
|
|
|
|
public static bool IsEventHandlerRegistered(AppCenterEdExStateHandler prospectiveHandler)
|
|
{
|
|
if (EdExStateUpdate == null)
|
|
return false;
|
|
|
|
foreach (AppCenterEdExStateHandler existingHandler in EdExStateUpdate.GetInvocationList())
|
|
if (existingHandler == prospectiveHandler)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
#endregion
|
|
|
|
private static void GetLatestEdExVersion()
|
|
{
|
|
var threshold = AppCenterEditorPrefsSO.Instance.EdSet_lastEdExVersionCheck != DateTime.MinValue ? AppCenterEditorPrefsSO.Instance.EdSet_lastEdExVersionCheck.AddHours(1) : DateTime.MinValue;
|
|
|
|
if (DateTime.Today > threshold)
|
|
{
|
|
AppCenterEditorHttp.MakeGitHubApiCall("https://api.github.com/repos/Microsoft/AppCenter-SDK-Unity-Extension/git/refs/tags", (version) =>
|
|
{
|
|
latestEdExVersion = version ?? Constants.UnknownVersion;
|
|
AppCenterEditorPrefsSO.Instance.EdSet_latestEdExVersion = latestEdExVersion;
|
|
});
|
|
}
|
|
else
|
|
{
|
|
latestEdExVersion = AppCenterEditorPrefsSO.Instance.EdSet_latestEdExVersion;
|
|
}
|
|
}
|
|
|
|
private static bool ShowEdExUpgrade()
|
|
{
|
|
if (string.IsNullOrEmpty(latestEdExVersion) || latestEdExVersion == Constants.UnknownVersion)
|
|
return false;
|
|
|
|
if (string.IsNullOrEmpty(AppCenterEditorHelper.EDEX_VERSION) || AppCenterEditorHelper.EDEX_VERSION == Constants.UnknownVersion)
|
|
return true;
|
|
|
|
string[] currrent = AppCenterEditorHelper.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 App Center Editor Extensions from the current project.", "Confirm", "Cancel"))
|
|
return;
|
|
|
|
try
|
|
{
|
|
window.Close();
|
|
var edExDirectory = new DirectoryInfo(AppCenterEditorHelper.EDEX_ROOT).Parent.FullName;
|
|
EdExLogger.LoggerInstance.LogWithTimeStamp("Deleting directory: " + edExDirectory);
|
|
FileUtil.DeleteFileOrDirectory(edExDirectory);
|
|
var edExDirectoryMeta = edExDirectory + ".meta";
|
|
EdExLogger.LoggerInstance.LogWithTimeStamp("Deleting file: " + edExDirectoryMeta);
|
|
FileUtil.DeleteFileOrDirectory(edExDirectoryMeta);
|
|
if (prompt)
|
|
{
|
|
AssetDatabase.Refresh();
|
|
}
|
|
PlayerPrefs.DeleteKey(AppCenterEditorPrefsSO.SdkLastCheckDateKey);
|
|
PlayerPrefs.DeleteKey(AppCenterEditorPrefsSO.EdExLastCheckDateKey);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
EdExLogger.LoggerInstance.LogError("Failed to remove App Center Editor Extensions: " + ex);
|
|
}
|
|
}
|
|
|
|
private static void UpgradeEdEx()
|
|
{
|
|
if (EditorUtility.DisplayDialog("Confirm EdEx Upgrade", "This action will remove the current App Center Editor Extensions and install the lastet version.", "Confirm", "Cancel"))
|
|
{
|
|
RemoveEdEx(false);
|
|
ImportLatestEdEx();
|
|
}
|
|
}
|
|
|
|
private static void ImportLatestEdEx()
|
|
{
|
|
var downloadUrl = string.Format(EditorExtensionsDownloadFormat, latestEdExVersion);
|
|
AppCenterEditorHttp.MakeDownloadCall(downloadUrl, file =>
|
|
{
|
|
EdExLogger.LoggerInstance.LogWithTimeStamp("Importing package: " + file);
|
|
AssetDatabase.ImportPackage(file, false);
|
|
EdExLogger.LoggerInstance.LogWithTimeStamp("Deleteing file: " + file);
|
|
FileUtil.DeleteFileOrDirectory(file);
|
|
EdExLogger.LoggerInstance.LogWithTimeStamp("App Center Editor Extensions upgrade complete");
|
|
});
|
|
}
|
|
}
|
|
} |