#if UNITY_EDITOR using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Http; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using Edgegap.Editor.Api; using Edgegap.Editor.Api.Models; using Edgegap.Editor.Api.Models.Requests; using Edgegap.Editor.Api.Models.Results; using UnityEditor; using UnityEditor.Build.Reporting; using UnityEditor.UIElements; using UnityEngine; using UnityEngine.Assertions; using UnityEngine.UIElements; using Application = UnityEngine.Application; namespace Edgegap.Editor { /// /// Editor logic event handler for "UI Builder" EdgegapWindow.uxml, superceding` EdgegapWindow.cs`. /// public class EdgegapWindowV2 : EditorWindow { #region Vars public static bool IsLogLevelDebug => EdgegapWindowMetadata.LOG_LEVEL == EdgegapWindowMetadata.LogLevel.Debug; private bool IsInitd; private VisualTreeAsset _visualTree; private bool _isApiTokenVerified; // Toggles the rest of the UI private bool _isContainerRegistryReady; private Sprite _appIconSpriteObj; private string _appIconBase64Str; private ApiEnvironment _apiEnvironment; // TODO: Swap out hard-coding with UI element? private GetRegistryCredentialsResult _credentials; private static readonly Regex _appNameAllowedCharsRegex = new Regex(@"^[a-zA-Z0-9_\-+\.]*$"); // MIRROR CHANGE: 'new()' not supported in Unity 2020 private GetCreateAppResult _loadedApp; /// TODO: Make this a list private GetDeploymentStatusResult _lastKnownDeployment; private string _deploymentRequestId; private string _userExternalIp; private bool _isAwaitingDeploymentReadyStatus; private bool _registered; #endregion // Vars #region Vars -> Interactable Elements private Button _debugBtn; /// (!) This is saved manually to EditorPrefs via Base64 instead of via UiBuilder private TextField _apiTokenInput; private Button _apiTokenVerifyBtn; private Button _apiTokenGetBtn; private VisualElement _postAuthContainer; private Foldout _appInfoFoldout; private Button _appLoadExistingBtn; private TextField _appNameInput; /// `Sprite` type private ObjectField _appIconSpriteObjInput; private Button _appCreateBtn; private Label _appCreateResultLabel; private Foldout _containerRegistryFoldout; private TextField _containerNewTagVersionInput; private TextField _containerPortNumInput; // MIRROR CHANGE: EnumField Port type fails to resolve unless in Assembly-CSharp-Editor.dll. replace with regular Dropdown instead. /// `ProtocolType` type // private EnumField _containerTransportTypeEnumInput; private PopupField _containerTransportTypeEnumInput; // END MIRROR CHANGE private Toggle _containerUseCustomRegistryToggle; private VisualElement _containerCustomRegistryWrapper; private TextField _containerRegistryUrlInput; private TextField _containerImageRepositoryInput; private TextField _containerUsernameInput; private TextField _containerTokenInput; private Button _containerBuildAndPushServerBtn; private Label _containerBuildAndPushResultLabel; private Foldout _deploymentsFoldout; private Button _deploymentsRefreshBtn; private Button _deploymentsCreateBtn; /// display:none (since it's on its own line), rather than !visible. private Label _deploymentsStatusLabel; private VisualElement _deploymentsServerDataContainer; private Button _deploymentConnectionCopyUrlBtn; private TextField _deploymentsConnectionUrlReadonlyInput; private Label _deploymentsConnectionStatusLabel; private Button _deploymentsConnectionStopBtn; private Button _deploymentsConnectionContainerLogsBtn; private Button _footerDocumentationBtn; private Button _footerNeedMoreGameServersBtn; #endregion // Vars // MIRROR CHANGE // get the path of this .cs file so we don't need to hardcode paths to // the .uxml and .uss files: // https://forum.unity.com/threads/too-many-hard-coded-paths-in-the-templates-and-documentation.728138/ // this way users can move this folder without breaking UIToolkit paths. internal string StylesheetPath => Path.GetDirectoryName(AssetDatabase.GetAssetPath(MonoScript.FromScriptableObject(this))); // END MIRROR CHANGE [MenuItem("Edgegap/Edgegap Hosting")] // MIRROR CHANGE: more obvious title public static void ShowEdgegapToolWindow() { EdgegapWindowV2 window = GetWindow(); window.titleContent = new GUIContent("Edgegap Hosting"); // MIRROR CHANGE: 'Edgegap Server Management' is too long for the tab space window.maxSize = new Vector2(635, 900); window.minSize = window.maxSize; } #region Unity Funcs protected void OnEnable() { // Set root VisualElement and style: V2 still uses EdgegapWindow.[uxml|uss] // BEGIN MIRROR CHANGE _visualTree = AssetDatabase.LoadAssetAtPath($"{StylesheetPath}/EdgegapWindow.uxml"); StyleSheet styleSheet = AssetDatabase.LoadAssetAtPath($"{StylesheetPath}/EdgegapWindow.uss"); // END MIRROR CHANGE rootVisualElement.styleSheets.Add(styleSheet); } public async void CreateGUI() { // Get UI elements from UI Builder rootVisualElement.Clear(); _visualTree.CloneTree(rootVisualElement); // Register callbacks and sync UI builder elements to fields here InitUIElements(); syncFormWithObjectStatic(); await syncFormWithObjectDynamicAsync(); // API calls IsInitd = true; } /// The user closed the window. Save the data. protected void OnDisable() { unregisterClickEvents(); unregisterFieldCallbacks(); SyncObjectWithForm(); _registered = false; } #endregion // Unity Funcs #region Init /// /// Binds the form inputs to the associated variables and initializes the inputs as required. /// Requires the VisualElements to be loaded before this call. Otherwise, the elements cannot be found. /// private void InitUIElements() { _registered = true; setVisualElementsToFields(); assertVisualElementKeys(); closeDisableGroups(); registerClickCallbacks(); registerFieldCallbacks(); initToggleDynamicUi(); } private void closeDisableGroups() { _appInfoFoldout.value = false; _containerRegistryFoldout.value = false; _deploymentsFoldout.value = false; _appInfoFoldout.SetEnabled(false); _containerRegistryFoldout.SetEnabled(false); _deploymentsFoldout.SetEnabled(false); } /// Set fields referencing UI Builder's fields. In order of appearance from top-to-bottom. private void setVisualElementsToFields() { _debugBtn = rootVisualElement.Q