mirror of
https://github.com/MirrorNetworking/Mirror.git
synced 2024-11-17 18:40:33 +00:00
Edgegap Plugin: update to latest version to remove more MIRROR CHANGEs; also supports moving the folder better (#3891)
* Edgegap Plugin: non-breaking updates first * Edgegap Plugin: update to latest version to remove more MIRROR CHANGEs; also supports moving the folder better * 2021+ --------- Co-authored-by: mischa <info@noobtuts.com> Co-authored-by: mischa <16416509+vis2k@users.noreply.github.com>
This commit is contained in:
parent
dd4dd78013
commit
b1cbab8621
@ -1,3 +1,8 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 14024ce6d2e64d5ba58ab20409ac648f
|
guid: 14024ce6d2e64d5ba58ab20409ac648f
|
||||||
timeCreated: 1701785018
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
16
Assets/Mirror/Hosting/Edgegap/Editor/Dockerfile
Normal file
16
Assets/Mirror/Hosting/Edgegap/Editor/Dockerfile
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
FROM ubuntu:22.04
|
||||||
|
|
||||||
|
ARG DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
COPY Builds/EdgegapServer /root/build/
|
||||||
|
|
||||||
|
WORKDIR /root/
|
||||||
|
|
||||||
|
RUN chmod +x /root/build/ServerBuild
|
||||||
|
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y ca-certificates && \
|
||||||
|
apt-get clean && \
|
||||||
|
update-ca-certificates
|
||||||
|
|
||||||
|
ENTRYPOINT [ "/root/build/ServerBuild", "-batchmode", "-nographics"]
|
7
Assets/Mirror/Hosting/Edgegap/Editor/Dockerfile.meta
Normal file
7
Assets/Mirror/Hosting/Edgegap/Editor/Dockerfile.meta
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 74f140c827788b64ebde10a2197d3c0b
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -43,11 +43,11 @@ public static BuildReport BuildServer()
|
|||||||
return BuildPipeline.BuildPlayer(options);
|
return BuildPipeline.BuildPlayer(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<bool> DockerSetupAndInstallationCheck()
|
public static async Task<bool> DockerSetupAndInstallationCheck(string path)
|
||||||
{
|
{
|
||||||
if (!File.Exists("Dockerfile"))
|
if (!File.Exists(path))
|
||||||
{
|
{
|
||||||
File.WriteAllText("Dockerfile", dockerFileText);
|
throw new Exception("Dockerfile not found, please notify plugin maintainer about this issue.");
|
||||||
}
|
}
|
||||||
|
|
||||||
string output = null;
|
string output = null;
|
||||||
@ -77,7 +77,7 @@ static async Task RunCommand_DockerVersion(Action<string> outputReciever = null,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MIRROR CHANGE
|
// MIRROR CHANGE
|
||||||
public static async Task RunCommand_DockerBuild(string registry, string imageRepo, string tag, Action<string> onStatusUpdate)
|
public static async Task RunCommand_DockerBuild(string dockerfilePath, string registry, string imageRepo, string tag, string projectPath, Action<string> onStatusUpdate)
|
||||||
{
|
{
|
||||||
string realErrorMessage = null;
|
string realErrorMessage = null;
|
||||||
|
|
||||||
@ -89,11 +89,11 @@ public static async Task RunCommand_DockerBuild(string registry, string imageRep
|
|||||||
string buildCommand = IsArmCPU() ? "buildx build --platform linux/amd64" : "build";
|
string buildCommand = IsArmCPU() ? "buildx build --platform linux/amd64" : "build";
|
||||||
|
|
||||||
#if UNITY_EDITOR_WIN
|
#if UNITY_EDITOR_WIN
|
||||||
await RunCommand("docker.exe", $"{buildCommand} -t {registry}/{imageRepo}:{tag} .", onStatusUpdate,
|
await RunCommand("docker.exe", $"{buildCommand} -f \"{dockerfilePath}\" -t \"{registry}/{imageRepo}:{tag}\" \"{projectPath}\"", onStatusUpdate,
|
||||||
#elif UNITY_EDITOR_OSX
|
#elif UNITY_EDITOR_OSX
|
||||||
await RunCommand("/bin/bash", $"-c \"docker {buildCommand} -t {registry}/{imageRepo}:{tag} .\"", onStatusUpdate,
|
await RunCommand("/bin/bash", $"-c \"docker {buildCommand} -f {dockerfilePath} -t {registry}/{imageRepo}:{tag} {projectPath}\"", onStatusUpdate,
|
||||||
#elif UNITY_EDITOR_LINUX
|
#elif UNITY_EDITOR_LINUX
|
||||||
await RunCommand("/bin/bash", $"-c \"docker {buildCommand} -t {registry}/{imageRepo}:{tag} .\"", onStatusUpdate,
|
await RunCommand("/bin/bash", $"-c \"docker {buildCommand} -f {dockerfilePath} -t {registry}/{imageRepo}:{tag} {projectPath}\"", onStatusUpdate,
|
||||||
#endif
|
#endif
|
||||||
(msg) =>
|
(msg) =>
|
||||||
{
|
{
|
||||||
@ -220,25 +220,6 @@ public static void UpdateEdgegapAppTag(string tag)
|
|||||||
// throw new NotImplementedException();
|
// throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
// -batchmode -nographics remains for Unity 2019/2020 support pre-dedicated server builds
|
|
||||||
static string dockerFileText = @"FROM ubuntu:bionic
|
|
||||||
|
|
||||||
ARG DEBIAN_FRONTEND=noninteractive
|
|
||||||
|
|
||||||
COPY Builds/EdgegapServer /root/build/
|
|
||||||
|
|
||||||
WORKDIR /root/
|
|
||||||
|
|
||||||
RUN chmod +x /root/build/ServerBuild
|
|
||||||
|
|
||||||
RUN apt-get update && \
|
|
||||||
apt-get install -y ca-certificates && \
|
|
||||||
apt-get clean && \
|
|
||||||
update-ca-certificates
|
|
||||||
|
|
||||||
ENTRYPOINT [ ""/root/build/ServerBuild"", ""-batchmode"", ""-nographics""]
|
|
||||||
";
|
|
||||||
|
|
||||||
/// <summary>Run a Docker cmd with streaming log response. TODO: Plugin to other Docker cmds</summary>
|
/// <summary>Run a Docker cmd with streaming log response. TODO: Plugin to other Docker cmds</summary>
|
||||||
/// <returns>Throws if logs contain "ERROR"</returns>
|
/// <returns>Throws if logs contain "ERROR"</returns>
|
||||||
///
|
///
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
#if UNITY_EDITOR
|
|
||||||
using UnityEditor;
|
|
||||||
using UnityEngine.UIElements;
|
|
||||||
using Edgegap;
|
|
||||||
|
|
||||||
[CustomEditor(typeof(EdgegapToolScript))]
|
|
||||||
public class EdgegapPluginScriptEditor : Editor
|
|
||||||
{
|
|
||||||
VisualElement _serverDataContainer;
|
|
||||||
|
|
||||||
private void OnEnable()
|
|
||||||
{
|
|
||||||
_serverDataContainer = EdgegapServerDataManager.GetServerDataVisualTree();
|
|
||||||
EdgegapServerDataManager.RegisterServerDataContainer(_serverDataContainer);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnDisable()
|
|
||||||
{
|
|
||||||
EdgegapServerDataManager.DeregisterServerDataContainer(_serverDataContainer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override VisualElement CreateInspectorGUI()
|
|
||||||
{
|
|
||||||
return _serverDataContainer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,11 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: c4c676ae6dcca0e458c6a8f06571f8fc
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
@ -4,6 +4,7 @@
|
|||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UIElements;
|
using UnityEngine.UIElements;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
namespace Edgegap
|
namespace Edgegap
|
||||||
{
|
{
|
||||||
@ -88,10 +89,15 @@ public static class EdgegapServerDataManager
|
|||||||
|
|
||||||
public static Status GetServerStatus() => _serverData;
|
public static Status GetServerStatus() => _serverData;
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
internal static string StylesheetPath =>
|
||||||
|
Path.GetDirectoryName(AssetDatabase.GUIDToAssetPath(AssetDatabase.FindAssets($"t:Script {nameof(EdgegapServerDataManager)}")[0]));
|
||||||
|
#endif
|
||||||
|
|
||||||
static EdgegapServerDataManager()
|
static EdgegapServerDataManager()
|
||||||
{
|
{
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
_serverDataStylesheet = AssetDatabase.LoadAssetAtPath<StyleSheet>("Assets/Edgegap/Editor/EdgegapServerData.uss");
|
_serverDataStylesheet = AssetDatabase.LoadAssetAtPath<StyleSheet>($"{StylesheetPath}{Path.DirectorySeparatorChar}EdgegapServerData.uss");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
public static void RegisterServerDataContainer(VisualElement serverDataContainer)
|
public static void RegisterServerDataContainer(VisualElement serverDataContainer)
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
using UnityEngine;
|
|
||||||
using Edgegap;
|
|
||||||
using IO.Swagger.Model;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This script acts as an interface to display and use the necessary variables from the Edgegap tool.
|
|
||||||
/// The server info can be accessed from the tool window, as well as through the public script property.
|
|
||||||
/// </summary>
|
|
||||||
public class EdgegapToolScript : MonoBehaviour
|
|
||||||
{
|
|
||||||
public Status ServerStatus => EdgegapServerDataManager.GetServerStatus();
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 5963202433da25448a22def99f5a598b
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
@ -1,988 +0,0 @@
|
|||||||
// MIRROR CHANGE: disable this completely. otherwise InitUIElements can still throw NRE.
|
|
||||||
/*
|
|
||||||
#if UNITY_EDITOR
|
|
||||||
using UnityEditor;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.UIElements;
|
|
||||||
using UnityEditor.UIElements;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Net.Http.Headers;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using System.Net;
|
|
||||||
using System.Text;
|
|
||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using IO.Swagger.Model;
|
|
||||||
using UnityEditor.Build.Reporting;
|
|
||||||
using Application = UnityEngine.Application;
|
|
||||||
|
|
||||||
namespace Edgegap
|
|
||||||
{
|
|
||||||
public class EdgegapWindow : EditorWindow
|
|
||||||
{
|
|
||||||
// MIRROR CHANGE: create HTTPClient in-place to avoid InvalidOperationExceptions when reusing
|
|
||||||
// static readonly HttpClient _httpClient = new HttpClient();
|
|
||||||
// END MIRROR CHANGE
|
|
||||||
|
|
||||||
const string EditorDataSerializationName = "EdgegapSerializationData";
|
|
||||||
const int ServerStatusCronjobIntervalMs = 10000; // Interval at which the server status is updated
|
|
||||||
|
|
||||||
// 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
|
|
||||||
|
|
||||||
readonly System.Timers.Timer _updateServerStatusCronjob = new System.Timers.Timer(ServerStatusCronjobIntervalMs);
|
|
||||||
|
|
||||||
[SerializeField] string _userExternalIp;
|
|
||||||
[SerializeField] string _apiKey;
|
|
||||||
[SerializeField] ApiEnvironment _apiEnvironment;
|
|
||||||
[SerializeField] string _appName;
|
|
||||||
[SerializeField] string _appVersionName;
|
|
||||||
[SerializeField] string _deploymentRequestId;
|
|
||||||
|
|
||||||
[SerializeField] string _containerRegistry;
|
|
||||||
[SerializeField] string _containerImageRepo;
|
|
||||||
[SerializeField] string _containerImageTag;
|
|
||||||
[SerializeField] bool _autoIncrementTag = true;
|
|
||||||
|
|
||||||
|
|
||||||
VisualTreeAsset _visualTree;
|
|
||||||
bool _shouldUpdateServerStatus = false;
|
|
||||||
|
|
||||||
// Interactable elements
|
|
||||||
EnumField _apiEnvironmentSelect;
|
|
||||||
TextField _apiKeyInput;
|
|
||||||
TextField _appNameInput;
|
|
||||||
TextField _appVersionNameInput;
|
|
||||||
TextField _containerRegistryInput;
|
|
||||||
TextField _containerImageRepoInput;
|
|
||||||
TextField _containerImageTagInput;
|
|
||||||
Toggle _autoIncrementTagInput;
|
|
||||||
Button _connectionButton;
|
|
||||||
Button _serverActionButton;
|
|
||||||
Button _documentationBtn;
|
|
||||||
Button _buildAndPushServerBtn;
|
|
||||||
|
|
||||||
// Readonly elements
|
|
||||||
Label _connectionStatusLabel;
|
|
||||||
VisualElement _serverDataContainer;
|
|
||||||
|
|
||||||
// server data manager
|
|
||||||
StyleSheet _serverDataStylesheet;
|
|
||||||
List<VisualElement> _serverDataContainers = new List<VisualElement>();
|
|
||||||
|
|
||||||
[Obsolete("See EdgegapWindowV2.ShowEdgegapToolWindow()")]
|
|
||||||
// [MenuItem("Edgegap/Server Management")]
|
|
||||||
public static void ShowEdgegapToolWindow()
|
|
||||||
{
|
|
||||||
EdgegapWindow window = GetWindow<EdgegapWindow>();
|
|
||||||
window.titleContent = new GUIContent("Edgegap Hosting"); // MIRROR CHANGE
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void OnEnable()
|
|
||||||
{
|
|
||||||
// Set root VisualElement and style
|
|
||||||
// BEGIN MIRROR CHANGE
|
|
||||||
_visualTree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>($"{StylesheetPath}/EdgegapWindow.uxml");
|
|
||||||
StyleSheet styleSheet = AssetDatabase.LoadAssetAtPath<StyleSheet>($"{StylesheetPath}/EdgegapWindow.uss");
|
|
||||||
_serverDataStylesheet = AssetDatabase.LoadAssetAtPath<StyleSheet>($"{StylesheetPath}/EdgegapServerData.uss");
|
|
||||||
// END MIRROR CHANGE
|
|
||||||
rootVisualElement.styleSheets.Add(styleSheet);
|
|
||||||
|
|
||||||
LoadToolData();
|
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(_userExternalIp))
|
|
||||||
{
|
|
||||||
_userExternalIp = GetExternalIpAddress();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void Update()
|
|
||||||
{
|
|
||||||
if (_shouldUpdateServerStatus)
|
|
||||||
{
|
|
||||||
_shouldUpdateServerStatus = false;
|
|
||||||
UpdateServerStatus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CreateGUI()
|
|
||||||
{
|
|
||||||
rootVisualElement.Clear();
|
|
||||||
_visualTree.CloneTree(rootVisualElement);
|
|
||||||
|
|
||||||
InitUIElements();
|
|
||||||
SyncFormWithObject();
|
|
||||||
|
|
||||||
bool hasActiveDeployment = !string.IsNullOrEmpty(_deploymentRequestId);
|
|
||||||
|
|
||||||
if (hasActiveDeployment)
|
|
||||||
{
|
|
||||||
RestoreActiveDeployment();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DisconnectCallback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void OnDestroy()
|
|
||||||
{
|
|
||||||
bool deploymentActive = !string.IsNullOrEmpty(_deploymentRequestId);
|
|
||||||
|
|
||||||
if (deploymentActive)
|
|
||||||
{
|
|
||||||
EditorUtility.DisplayDialog(
|
|
||||||
"Warning",
|
|
||||||
$"You have an active deployment ({_deploymentRequestId}) that won't be stopped automatically.",
|
|
||||||
"Ok"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void OnDisable()
|
|
||||||
{
|
|
||||||
SyncObjectWithForm();
|
|
||||||
SaveToolData();
|
|
||||||
DeregisterServerDataContainer(_serverDataContainer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 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.
|
|
||||||
/// </summary>
|
|
||||||
void InitUIElements()
|
|
||||||
{
|
|
||||||
_apiEnvironmentSelect = rootVisualElement.Q<EnumField>("environmentSelect");
|
|
||||||
_apiKeyInput = rootVisualElement.Q<TextField>("apiKey");
|
|
||||||
_appNameInput = rootVisualElement.Q<TextField>("appName");
|
|
||||||
_appVersionNameInput = rootVisualElement.Q<TextField>("appVersionName");
|
|
||||||
|
|
||||||
_containerRegistryInput = rootVisualElement.Q<TextField>("containerRegistry");
|
|
||||||
_containerImageRepoInput = rootVisualElement.Q<TextField>("containerImageRepo");
|
|
||||||
_containerImageTagInput = rootVisualElement.Q<TextField>("tag");
|
|
||||||
_autoIncrementTagInput = rootVisualElement.Q<Toggle>("autoIncrementTag");
|
|
||||||
|
|
||||||
_connectionButton = rootVisualElement.Q<Button>("connectionBtn");
|
|
||||||
_serverActionButton = rootVisualElement.Q<Button>("serverActionBtn");
|
|
||||||
_documentationBtn = rootVisualElement.Q<Button>("documentationBtn");
|
|
||||||
_buildAndPushServerBtn = rootVisualElement.Q<Button>("buildAndPushBtn");
|
|
||||||
_buildAndPushServerBtn.clickable.clicked += BuildAndPushServer;
|
|
||||||
|
|
||||||
_connectionStatusLabel = rootVisualElement.Q<Label>("connectionStatusLabel");
|
|
||||||
_serverDataContainer = rootVisualElement.Q<VisualElement>("serverDataContainer");
|
|
||||||
|
|
||||||
// Load initial server data UI element and register for updates.
|
|
||||||
VisualElement serverDataElement = GetServerDataVisualTree();
|
|
||||||
RegisterServerDataContainer(serverDataElement);
|
|
||||||
_serverDataContainer.Clear();
|
|
||||||
_serverDataContainer.Add(serverDataElement);
|
|
||||||
|
|
||||||
_documentationBtn.clickable.clicked += OpenDocumentationCallback;
|
|
||||||
|
|
||||||
// Init the ApiEnvironment dropdown
|
|
||||||
_apiEnvironmentSelect.Init(ApiEnvironment.Console);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// With a call to an external resource, determines the current user's public IP address.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>External IP address</returns>
|
|
||||||
string GetExternalIpAddress()
|
|
||||||
{
|
|
||||||
string externalIpString = new WebClient()
|
|
||||||
.DownloadString("http://icanhazip.com")
|
|
||||||
.Replace("\\r\\n", "")
|
|
||||||
.Replace("\\n", "")
|
|
||||||
.Trim();
|
|
||||||
IPAddress externalIp = IPAddress.Parse(externalIpString);
|
|
||||||
|
|
||||||
return externalIp.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OpenDocumentationCallback()
|
|
||||||
{
|
|
||||||
// MIRROR CHANGE
|
|
||||||
// ApiEnvironment selectedApiEnvironment = (ApiEnvironment)_apiEnvironmentSelect.value;
|
|
||||||
// string documentationUrl = selectedApiEnvironment.GetDocumentationUrl();
|
|
||||||
//
|
|
||||||
// if (!string.IsNullOrEmpty(documentationUrl))
|
|
||||||
// {
|
|
||||||
// UnityEngine.Application.OpenURL(documentationUrl);
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// string apiEnvName = Enum.GetName(typeof(ApiEnvironment), selectedApiEnvironment);
|
|
||||||
// Debug.LogWarning($"Could not open documentation for api environment {apiEnvName}: No documentation URL.");
|
|
||||||
// }
|
|
||||||
|
|
||||||
// link to the easiest documentation
|
|
||||||
Application.OpenURL("https://mirror-networking.gitbook.io/docs/hosting/edgegap-hosting-plugin-guide");
|
|
||||||
// END MIRROR CHANGE
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConnectCallback()
|
|
||||||
{
|
|
||||||
ApiEnvironment selectedApiEnvironment = (ApiEnvironment)_apiEnvironmentSelect.value;
|
|
||||||
string selectedAppName = _appNameInput.value;
|
|
||||||
string selectedVersionName = _appVersionNameInput.value;
|
|
||||||
string selectedApiKey = _apiKeyInput.value;
|
|
||||||
|
|
||||||
bool validAppName = !string.IsNullOrEmpty(selectedAppName) && !string.IsNullOrWhiteSpace(selectedAppName);
|
|
||||||
bool validVersionName = !string.IsNullOrEmpty(selectedVersionName) && !string.IsNullOrWhiteSpace(selectedVersionName);
|
|
||||||
bool validApiKey = selectedApiKey.StartsWith("token ");
|
|
||||||
|
|
||||||
if (validAppName && validVersionName && validApiKey)
|
|
||||||
{
|
|
||||||
string apiKeyValue = selectedApiKey.Substring(6);
|
|
||||||
Connect(selectedApiEnvironment, selectedAppName, selectedVersionName, apiKeyValue);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
EditorUtility.DisplayDialog(
|
|
||||||
"Could not connect - Invalid data",
|
|
||||||
"The data provided is invalid. " +
|
|
||||||
"Make sure every field is filled, and that you provide your complete Edgegap API token " +
|
|
||||||
"(including the \"token\" part).",
|
|
||||||
"Ok"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MIRROR CHANGE: create HTTPClient in-place to avoid InvalidOperationExceptions when reusing
|
|
||||||
HttpClient CreateHttpClient()
|
|
||||||
{
|
|
||||||
HttpClient httpClient = new HttpClient();
|
|
||||||
httpClient.BaseAddress = new Uri(_apiEnvironment.GetApiUrl());
|
|
||||||
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
|
||||||
string token = _apiKeyInput.value.Substring(6);
|
|
||||||
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("token", token);
|
|
||||||
return httpClient;
|
|
||||||
}
|
|
||||||
// END MIRROR CHANGE
|
|
||||||
|
|
||||||
async void Connect(
|
|
||||||
ApiEnvironment selectedApiEnvironment,
|
|
||||||
string selectedAppName,
|
|
||||||
string selectedAppVersionName,
|
|
||||||
string selectedApiTokenValue
|
|
||||||
)
|
|
||||||
{
|
|
||||||
SetToolUIState(ToolState.Connecting);
|
|
||||||
|
|
||||||
// Make HTTP request
|
|
||||||
HttpClient _httpClient = CreateHttpClient(); // MIRROR CHANGE: create HTTPClient in-place to avoid InvalidOperationExceptions when reusing
|
|
||||||
string path = $"/v1/app/{selectedAppName}/version/{selectedAppVersionName}"; // MIRROR CHANGE: use selectedAppName and selectedAppVersionName instead of _appName & _appVersionName
|
|
||||||
HttpResponseMessage response = await _httpClient.GetAsync(path);
|
|
||||||
|
|
||||||
if (response.IsSuccessStatusCode)
|
|
||||||
{
|
|
||||||
SyncObjectWithForm();
|
|
||||||
SetToolUIState(ToolState.Connected);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int status = (int)response.StatusCode;
|
|
||||||
string title;
|
|
||||||
string message;
|
|
||||||
|
|
||||||
if (status == 401)
|
|
||||||
{
|
|
||||||
string apiEnvName = Enum.GetName(typeof(ApiEnvironment), selectedApiEnvironment);
|
|
||||||
title = "Invalid credentials";
|
|
||||||
message = $"Could not find an Edgegap account with this API key for the {apiEnvName} environment.";
|
|
||||||
}
|
|
||||||
else if (status == 404)
|
|
||||||
{
|
|
||||||
title = "App not found";
|
|
||||||
message = $"Could not find app {selectedAppName} with version {selectedAppVersionName}.";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
title = "Oops";
|
|
||||||
message = $"There was an error while connecting you to the Edgegap API. Please try again later.";
|
|
||||||
}
|
|
||||||
|
|
||||||
EditorUtility.DisplayDialog(title, message, "Ok");
|
|
||||||
SetToolUIState(ToolState.Disconnected);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisconnectCallback()
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(_deploymentRequestId))
|
|
||||||
{
|
|
||||||
SetToolUIState(ToolState.Disconnected);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
EditorUtility.DisplayDialog("Cannot disconnect", "Make sure no server is running in the Edgegap tool before disconnecting", "Ok");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
float ProgressCounter = 0;
|
|
||||||
|
|
||||||
// MIRROR CHANGE: added title parameter for more detailed progress while waiting
|
|
||||||
void ShowBuildWorkInProgress(string title, string status)
|
|
||||||
{
|
|
||||||
EditorUtility.DisplayProgressBar(title, status, ProgressCounter++ / 50);
|
|
||||||
}
|
|
||||||
// END MIRROR CHANGE
|
|
||||||
|
|
||||||
async void BuildAndPushServer()
|
|
||||||
{
|
|
||||||
SetToolUIState(ToolState.Building);
|
|
||||||
|
|
||||||
SyncObjectWithForm();
|
|
||||||
ProgressCounter = 0;
|
|
||||||
Action<string> onError = (msg) =>
|
|
||||||
{
|
|
||||||
EditorUtility.DisplayDialog("Error", msg, "Ok");
|
|
||||||
SetToolUIState(ToolState.Connected);
|
|
||||||
};
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// check for installation and setup docker file
|
|
||||||
if (!await EdgegapBuildUtils.DockerSetupAndInstallationCheck())
|
|
||||||
{
|
|
||||||
onError("Docker installation not found. Docker can be downloaded from:\n\nhttps://www.docker.com/");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// MIRROR CHANGE
|
|
||||||
// make sure Linux build target is installed before attemping to build.
|
|
||||||
// if it's not installed, tell the user about it.
|
|
||||||
if (!BuildPipeline.IsBuildTargetSupported(BuildTargetGroup.Standalone, BuildTarget.StandaloneLinux64))
|
|
||||||
{
|
|
||||||
onError($"Linux Build Support is missing.\n\nPlease open Unity Hub -> Installs -> Unity {Application.unityVersion} -> Add Modules -> Linux Build Support (IL2CPP & Mono & Dedicated Server) -> Install\n\nAfterwards restart Unity!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// END MIRROR CHANGE
|
|
||||||
|
|
||||||
// create server build
|
|
||||||
BuildReport buildResult = EdgegapBuildUtils.BuildServer();
|
|
||||||
if (buildResult.summary.result != BuildResult.Succeeded)
|
|
||||||
{
|
|
||||||
onError("Edgegap build failed, please check the Unity console logs.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
string registry = _containerRegistry;
|
|
||||||
string imageName = _containerImageRepo;
|
|
||||||
string tag = _containerImageTag;
|
|
||||||
|
|
||||||
// MIRROR CHANGE ///////////////////////////////////////////////
|
|
||||||
// registry, repository and tag can not contain whitespaces.
|
|
||||||
// otherwise the docker command will throw an error:
|
|
||||||
// "ERROR: "docker buildx build" requires exactly 1 argument."
|
|
||||||
// catch this early and notify the user immediately.
|
|
||||||
if (registry.Contains(" "))
|
|
||||||
{
|
|
||||||
onError($"Container Registry is not allowed to contain whitespace: '{registry}'");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (imageName.Contains(" "))
|
|
||||||
{
|
|
||||||
onError($"Image Repository is not allowed to contain whitespace: '{imageName}'");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tag.Contains(" "))
|
|
||||||
{
|
|
||||||
onError($"Tag is not allowed to contain whitespace: '{tag}'");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// END MIRROR CHANGE ///////////////////////////////////////////
|
|
||||||
|
|
||||||
// increment tag for quicker iteration
|
|
||||||
if (_autoIncrementTag)
|
|
||||||
{
|
|
||||||
tag = EdgegapBuildUtils.IncrementTag(tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
// create docker image
|
|
||||||
await EdgegapBuildUtils.RunCommand_DockerBuild(registry, imageName, tag, status => ShowBuildWorkInProgress("Building Docker Image", status));
|
|
||||||
|
|
||||||
SetToolUIState(ToolState.Pushing);
|
|
||||||
|
|
||||||
// push docker image
|
|
||||||
(bool result, string error) = await EdgegapBuildUtils.RunCommand_DockerPush(registry, imageName, tag, status => ShowBuildWorkInProgress("Uploading Docker Image (this may take a while)", status));
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
// catch common issues with detailed solutions
|
|
||||||
if (error.Contains("Cannot connect to the Docker daemon"))
|
|
||||||
{
|
|
||||||
onError($"{error}\nTo solve this, you can install and run Docker Desktop from:\n\nhttps://www.docker.com/products/docker-desktop");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error.Contains("unauthorized to access repository"))
|
|
||||||
{
|
|
||||||
onError($"Docker authorization failed:\n\n{error}\nTo solve this, you can open a terminal and enter 'docker login {registry}', then enter your credentials.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// project not found?
|
|
||||||
if (Regex.IsMatch(error, @".*project .* not found.*", RegexOptions.IgnoreCase))
|
|
||||||
{
|
|
||||||
onError($"{error}\nTo solve this, make sure that Image Repository is 'project/game' where 'project' is from the Container Registry page on the Edgegap website.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// otherwise show generic error message
|
|
||||||
onError($"Unable to push docker image to registry. Please make sure you're logged in to {registry} and check the following error:\n\n{error}");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// update edgegap server settings for new tag
|
|
||||||
ShowBuildWorkInProgress("Build and Push", "Updating server info on Edgegap");
|
|
||||||
await UpdateAppTagOnEdgegap(tag);
|
|
||||||
|
|
||||||
// cleanup
|
|
||||||
_containerImageTag = tag;
|
|
||||||
SyncFormWithObject();
|
|
||||||
SetToolUIState(ToolState.Connected);
|
|
||||||
|
|
||||||
Debug.Log("Server built and pushed successfully");
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Debug.LogError(ex);
|
|
||||||
onError($"Edgegap build and push failed with Error: {ex}");
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
// MIRROR CHANGE: always clear otherwise it gets stuck there forever!
|
|
||||||
EditorUtility.ClearProgressBar();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async Task UpdateAppTagOnEdgegap(string newTag)
|
|
||||||
{
|
|
||||||
string path = $"/v1/app/{_appName}/version/{_appVersionName}";
|
|
||||||
|
|
||||||
// Setup post data
|
|
||||||
AppVersionUpdatePatchData updatePatchData = new AppVersionUpdatePatchData { DockerImage = _containerImageRepo, DockerRegistry = _containerRegistry, DockerTag = newTag };
|
|
||||||
string json = JsonConvert.SerializeObject(updatePatchData);
|
|
||||||
StringContent patchData = new StringContent(json, Encoding.UTF8, "application/json");
|
|
||||||
|
|
||||||
// Make HTTP request
|
|
||||||
HttpClient _httpClient = CreateHttpClient(); // MIRROR CHANGE: create HTTPClient in-place to avoid InvalidOperationExceptions when reusing
|
|
||||||
HttpRequestMessage request = new HttpRequestMessage(new HttpMethod("PATCH"), path);
|
|
||||||
request.Content = patchData;
|
|
||||||
HttpResponseMessage response = await _httpClient.SendAsync(request);
|
|
||||||
string content = await response.Content.ReadAsStringAsync();
|
|
||||||
|
|
||||||
if (!response.IsSuccessStatusCode)
|
|
||||||
{
|
|
||||||
throw new Exception($"Could not update Edgegap server tag. Got {(int)response.StatusCode} with response:\n{content}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async void StartServerCallback()
|
|
||||||
{
|
|
||||||
SetToolUIState(ToolState.ProcessingDeployment); // Prevents being called multiple times.
|
|
||||||
|
|
||||||
const string path = "/v1/deploy";
|
|
||||||
|
|
||||||
// Setup post data
|
|
||||||
DeployPostData deployPostData = new DeployPostData(_appName, _appVersionName, new List<string> { _userExternalIp });
|
|
||||||
string json = JsonConvert.SerializeObject(deployPostData);
|
|
||||||
StringContent postData = new StringContent(json, Encoding.UTF8, "application/json");
|
|
||||||
|
|
||||||
// Make HTTP request
|
|
||||||
HttpClient _httpClient = CreateHttpClient(); // MIRROR CHANGE: create HTTPClient in-place to avoid InvalidOperationExceptions when reusing
|
|
||||||
HttpResponseMessage response = await _httpClient.PostAsync(path, postData);
|
|
||||||
string content = await response.Content.ReadAsStringAsync();
|
|
||||||
|
|
||||||
if (response.IsSuccessStatusCode)
|
|
||||||
{
|
|
||||||
// Parse response
|
|
||||||
Deployment parsedResponse = JsonConvert.DeserializeObject<Deployment>(content);
|
|
||||||
|
|
||||||
_deploymentRequestId = parsedResponse.RequestId;
|
|
||||||
|
|
||||||
UpdateServerStatus();
|
|
||||||
StartServerStatusCronjob();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Debug.LogError($"Could not start Edgegap server. Got {(int)response.StatusCode} with response:\n{content}");
|
|
||||||
SetToolUIState(ToolState.Connected);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async void StopServerCallback()
|
|
||||||
{
|
|
||||||
string path = $"/v1/stop/{_deploymentRequestId}";
|
|
||||||
|
|
||||||
// Make HTTP request
|
|
||||||
HttpClient _httpClient = CreateHttpClient(); // MIRROR CHANGE: create HTTPClient in-place to avoid InvalidOperationExceptions when reusing
|
|
||||||
HttpResponseMessage response = await _httpClient.DeleteAsync(path);
|
|
||||||
|
|
||||||
if (response.IsSuccessStatusCode)
|
|
||||||
{
|
|
||||||
UpdateServerStatus();
|
|
||||||
SetToolUIState(ToolState.ProcessingDeployment);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Parse response
|
|
||||||
string content = await response.Content.ReadAsStringAsync();
|
|
||||||
|
|
||||||
Debug.LogError($"Could not stop Edgegap server. Got {(int)response.StatusCode} with response:\n{content}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void StartServerStatusCronjob()
|
|
||||||
{
|
|
||||||
_updateServerStatusCronjob.Elapsed += (sourceObject, elaspedEvent) => _shouldUpdateServerStatus = true;
|
|
||||||
_updateServerStatusCronjob.AutoReset = true;
|
|
||||||
_updateServerStatusCronjob.Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void StopServerStatusCronjob() => _updateServerStatusCronjob.Stop();
|
|
||||||
|
|
||||||
async void UpdateServerStatus()
|
|
||||||
{
|
|
||||||
Status serverStatusResponse = await FetchServerStatus();
|
|
||||||
|
|
||||||
ToolState toolState;
|
|
||||||
ServerStatus serverStatus = serverStatusResponse.GetServerStatus();
|
|
||||||
|
|
||||||
if (serverStatus == ServerStatus.Terminated)
|
|
||||||
{
|
|
||||||
SetServerData(null, _apiEnvironment);
|
|
||||||
|
|
||||||
if (_updateServerStatusCronjob.Enabled)
|
|
||||||
{
|
|
||||||
StopServerStatusCronjob();
|
|
||||||
}
|
|
||||||
|
|
||||||
_deploymentRequestId = null;
|
|
||||||
toolState = ToolState.Connected;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SetServerData(serverStatusResponse, _apiEnvironment);
|
|
||||||
|
|
||||||
if (serverStatus == ServerStatus.Ready || serverStatus == ServerStatus.Error)
|
|
||||||
{
|
|
||||||
toolState = ToolState.DeploymentRunning;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
toolState = ToolState.ProcessingDeployment;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SetToolUIState(toolState);
|
|
||||||
}
|
|
||||||
|
|
||||||
async Task<Status> FetchServerStatus()
|
|
||||||
{
|
|
||||||
string path = $"/v1/status/{_deploymentRequestId}";
|
|
||||||
|
|
||||||
// Make HTTP request
|
|
||||||
HttpClient _httpClient = CreateHttpClient(); // MIRROR CHANGE: create HTTPClient in-place to avoid InvalidOperationExceptions when reusing
|
|
||||||
HttpResponseMessage response = await _httpClient.GetAsync(path);
|
|
||||||
|
|
||||||
// Parse response
|
|
||||||
string content = await response.Content.ReadAsStringAsync();
|
|
||||||
|
|
||||||
Status parsedData;
|
|
||||||
|
|
||||||
if (response.IsSuccessStatusCode)
|
|
||||||
{
|
|
||||||
parsedData = JsonConvert.DeserializeObject<Status>(content);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((int)response.StatusCode == 400)
|
|
||||||
{
|
|
||||||
Debug.LogError("The deployment that was active in the tool is now unreachable. Considering it Terminated.");
|
|
||||||
parsedData = new Status() { CurrentStatus = ServerStatus.Terminated.GetLabelText() };
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Debug.LogError(
|
|
||||||
$"Could not fetch status of Edgegap deployment {_deploymentRequestId}. " +
|
|
||||||
$"Got {(int)response.StatusCode} with response:\n{content}"
|
|
||||||
);
|
|
||||||
parsedData = new Status() { CurrentStatus = ServerStatus.NA.GetLabelText() };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return parsedData;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RestoreActiveDeployment()
|
|
||||||
{
|
|
||||||
ConnectCallback();
|
|
||||||
|
|
||||||
_shouldUpdateServerStatus = true;
|
|
||||||
StartServerStatusCronjob();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SyncObjectWithForm()
|
|
||||||
{
|
|
||||||
if (_apiKeyInput == null) return; // MIRROR CHANGE: fix NRE when this is called before UI elements were assgned
|
|
||||||
|
|
||||||
_apiKey = _apiKeyInput.value;
|
|
||||||
_apiEnvironment = (ApiEnvironment)_apiEnvironmentSelect.value;
|
|
||||||
_appName = _appNameInput.value;
|
|
||||||
_appVersionName = _appVersionNameInput.value;
|
|
||||||
|
|
||||||
// MIRROR CHANGE ///////////////////////////////////////////////////
|
|
||||||
// registry, repository and tag can not contain whitespaces.
|
|
||||||
// otherwise it'll throw an error:
|
|
||||||
// "ERROR: "docker buildx build" requires exactly 1 argument."
|
|
||||||
// trim whitespace in case users accidentally added some.
|
|
||||||
_containerRegistry = _containerRegistryInput.value.Trim();
|
|
||||||
_containerImageTag = _containerImageTagInput.value.Trim();
|
|
||||||
_containerImageRepo = _containerImageRepoInput.value.Trim();
|
|
||||||
// END MIRROR CHANGE ///////////////////////////////////////////////
|
|
||||||
|
|
||||||
_autoIncrementTag = _autoIncrementTagInput.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SyncFormWithObject()
|
|
||||||
{
|
|
||||||
_apiKeyInput.value = _apiKey;
|
|
||||||
_apiEnvironmentSelect.value = _apiEnvironment;
|
|
||||||
_appNameInput.value = _appName;
|
|
||||||
_appVersionNameInput.value = _appVersionName;
|
|
||||||
|
|
||||||
_containerRegistryInput.value = _containerRegistry;
|
|
||||||
_containerImageTagInput.value = _containerImageTag;
|
|
||||||
_containerImageRepoInput.value = _containerImageRepo;
|
|
||||||
_autoIncrementTagInput.value = _autoIncrementTag;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetToolUIState(ToolState toolState)
|
|
||||||
{
|
|
||||||
SetConnectionInfoUI(toolState);
|
|
||||||
SetConnectionButtonUI(toolState);
|
|
||||||
SetServerActionUI(toolState);
|
|
||||||
SetDockerRepoInfoUI(toolState);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetDockerRepoInfoUI(ToolState toolState)
|
|
||||||
{
|
|
||||||
bool connected = toolState.CanStartDeployment();
|
|
||||||
_containerRegistryInput.SetEnabled(connected);
|
|
||||||
_autoIncrementTagInput.SetEnabled(connected);
|
|
||||||
_containerImageRepoInput.SetEnabled(connected);
|
|
||||||
_containerImageTagInput.SetEnabled(connected);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetConnectionInfoUI(ToolState toolState)
|
|
||||||
{
|
|
||||||
bool canEditConnectionInfo = toolState.CanEditConnectionInfo();
|
|
||||||
|
|
||||||
_apiKeyInput.SetEnabled(canEditConnectionInfo);
|
|
||||||
_apiEnvironmentSelect.SetEnabled(canEditConnectionInfo);
|
|
||||||
_appNameInput.SetEnabled(canEditConnectionInfo);
|
|
||||||
_appVersionNameInput.SetEnabled(canEditConnectionInfo);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetConnectionButtonUI(ToolState toolState)
|
|
||||||
{
|
|
||||||
bool canConnect = toolState.CanConnect();
|
|
||||||
bool canDisconnect = toolState.CanDisconnect();
|
|
||||||
|
|
||||||
_connectionButton.SetEnabled(canConnect || canDisconnect);
|
|
||||||
|
|
||||||
// A bit dirty, but ensures the callback is not bound multiple times on the button.
|
|
||||||
_connectionButton.clickable.clicked -= ConnectCallback;
|
|
||||||
_connectionButton.clickable.clicked -= DisconnectCallback;
|
|
||||||
|
|
||||||
if (canConnect || toolState == ToolState.Connecting)
|
|
||||||
{
|
|
||||||
_connectionButton.text = "Connect";
|
|
||||||
_connectionStatusLabel.text = "Awaiting connection";
|
|
||||||
_connectionStatusLabel.RemoveFromClassList("text--success");
|
|
||||||
_connectionButton.clickable.clicked += ConnectCallback;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_connectionButton.text = "Disconnect";
|
|
||||||
_connectionStatusLabel.text = "Connected";
|
|
||||||
_connectionStatusLabel.AddToClassList("text--success");
|
|
||||||
_connectionButton.clickable.clicked += DisconnectCallback;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetServerActionUI(ToolState toolState)
|
|
||||||
{
|
|
||||||
bool canStartDeployment = toolState.CanStartDeployment();
|
|
||||||
bool canStopDeployment = toolState.CanStopDeployment();
|
|
||||||
|
|
||||||
// A bit dirty, but ensures the callback is not bound multiple times on the button.
|
|
||||||
_serverActionButton.clickable.clicked -= StartServerCallback;
|
|
||||||
_serverActionButton.clickable.clicked -= StopServerCallback;
|
|
||||||
|
|
||||||
_serverActionButton.SetEnabled(canStartDeployment || canStopDeployment);
|
|
||||||
|
|
||||||
_buildAndPushServerBtn.SetEnabled(canStartDeployment);
|
|
||||||
|
|
||||||
if (canStopDeployment)
|
|
||||||
{
|
|
||||||
_serverActionButton.text = "Stop Server";
|
|
||||||
_serverActionButton.clickable.clicked += StopServerCallback;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_serverActionButton.text = "Start Server";
|
|
||||||
_serverActionButton.clickable.clicked += StartServerCallback;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// server data manager /////////////////////////////////////////////////
|
|
||||||
public void RegisterServerDataContainer(VisualElement serverDataContainer)
|
|
||||||
{
|
|
||||||
_serverDataContainers.Add(serverDataContainer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DeregisterServerDataContainer(VisualElement serverDataContainer)
|
|
||||||
{
|
|
||||||
_serverDataContainers.Remove(serverDataContainer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetServerData(Status serverData, ApiEnvironment apiEnvironment)
|
|
||||||
{
|
|
||||||
EdgegapServerDataManager._serverData = serverData;
|
|
||||||
RefreshServerDataContainers();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Label GetHeader(string text)
|
|
||||||
{
|
|
||||||
Label header = new Label(text);
|
|
||||||
header.AddToClassList("label__header");
|
|
||||||
|
|
||||||
return header;
|
|
||||||
}
|
|
||||||
|
|
||||||
public VisualElement GetHeaderRow()
|
|
||||||
{
|
|
||||||
VisualElement row = new VisualElement();
|
|
||||||
row.AddToClassList("row__port-table");
|
|
||||||
row.AddToClassList("label__header");
|
|
||||||
|
|
||||||
row.Add(new Label("Name"));
|
|
||||||
row.Add(new Label("External"));
|
|
||||||
row.Add(new Label("Internal"));
|
|
||||||
row.Add(new Label("Protocol"));
|
|
||||||
row.Add(new Label("Link"));
|
|
||||||
|
|
||||||
return row;
|
|
||||||
}
|
|
||||||
|
|
||||||
public VisualElement GetRowFromPortResponse(PortMapping port)
|
|
||||||
{
|
|
||||||
VisualElement row = new VisualElement();
|
|
||||||
row.AddToClassList("row__port-table");
|
|
||||||
row.AddToClassList("focusable");
|
|
||||||
|
|
||||||
|
|
||||||
row.Add(new Label(port.Name));
|
|
||||||
row.Add(new Label(port.External.ToString()));
|
|
||||||
row.Add(new Label(port.Internal.ToString()));
|
|
||||||
row.Add(new Label(port.Protocol));
|
|
||||||
row.Add(GetCopyButton("Copy", port.Link));
|
|
||||||
|
|
||||||
return row;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Button GetCopyButton(string btnText, string copiedText)
|
|
||||||
{
|
|
||||||
Button copyBtn = new Button();
|
|
||||||
copyBtn.text = btnText;
|
|
||||||
copyBtn.clickable.clicked += () => GUIUtility.systemCopyBuffer = copiedText;
|
|
||||||
|
|
||||||
return copyBtn;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Button GetLinkButton(string btnText, string targetUrl)
|
|
||||||
{
|
|
||||||
Button copyBtn = new Button();
|
|
||||||
copyBtn.text = btnText;
|
|
||||||
copyBtn.clickable.clicked += () => UnityEngine.Application.OpenURL(targetUrl);
|
|
||||||
|
|
||||||
return copyBtn;
|
|
||||||
}
|
|
||||||
public Label GetInfoText(string innerText)
|
|
||||||
{
|
|
||||||
Label infoText = new Label(innerText);
|
|
||||||
infoText.AddToClassList("label__info-text");
|
|
||||||
|
|
||||||
return infoText;
|
|
||||||
}
|
|
||||||
|
|
||||||
VisualElement GetStatusSection()
|
|
||||||
{
|
|
||||||
ServerStatus serverStatus = EdgegapServerDataManager._serverData.GetServerStatus();
|
|
||||||
string dashboardUrl = _apiEnvironment.GetDashboardUrl();
|
|
||||||
string requestId = EdgegapServerDataManager._serverData.RequestId;
|
|
||||||
string deploymentDashboardUrl = "";
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(requestId) && !string.IsNullOrEmpty(dashboardUrl))
|
|
||||||
{
|
|
||||||
deploymentDashboardUrl = $"{dashboardUrl}/arbitrium/deployment/read/{requestId}/";
|
|
||||||
}
|
|
||||||
|
|
||||||
VisualElement container = new VisualElement();
|
|
||||||
container.AddToClassList("container");
|
|
||||||
|
|
||||||
container.Add(GetHeader("Server Status"));
|
|
||||||
|
|
||||||
VisualElement row = new VisualElement();
|
|
||||||
row.AddToClassList("row__status");
|
|
||||||
|
|
||||||
// Status pill
|
|
||||||
Label statusLabel = new Label(serverStatus.GetLabelText());
|
|
||||||
statusLabel.AddToClassList(serverStatus.GetStatusBgClass());
|
|
||||||
statusLabel.AddToClassList("label__status");
|
|
||||||
row.Add(statusLabel);
|
|
||||||
|
|
||||||
// Link to dashboard
|
|
||||||
if (!string.IsNullOrEmpty(deploymentDashboardUrl))
|
|
||||||
{
|
|
||||||
row.Add(GetLinkButton("See in the dashboard", deploymentDashboardUrl));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
row.Add(new Label("Could not resolve link to this deployment"));
|
|
||||||
}
|
|
||||||
|
|
||||||
container.Add(row);
|
|
||||||
|
|
||||||
return container;
|
|
||||||
}
|
|
||||||
|
|
||||||
VisualElement GetDnsSection()
|
|
||||||
{
|
|
||||||
string serverDns = EdgegapServerDataManager._serverData.Fqdn;
|
|
||||||
|
|
||||||
VisualElement container = new VisualElement();
|
|
||||||
container.AddToClassList("container");
|
|
||||||
|
|
||||||
container.Add(GetHeader("Server DNS"));
|
|
||||||
|
|
||||||
VisualElement row = new VisualElement();
|
|
||||||
row.AddToClassList("row__dns");
|
|
||||||
row.AddToClassList("focusable");
|
|
||||||
|
|
||||||
row.Add(new Label(serverDns));
|
|
||||||
row.Add(GetCopyButton("Copy", serverDns));
|
|
||||||
|
|
||||||
container.Add(row);
|
|
||||||
|
|
||||||
return container;
|
|
||||||
}
|
|
||||||
|
|
||||||
VisualElement GetPortsSection()
|
|
||||||
{
|
|
||||||
List<PortMapping> serverPorts = EdgegapServerDataManager._serverData.Ports.Values.ToList();
|
|
||||||
|
|
||||||
VisualElement container = new VisualElement();
|
|
||||||
container.AddToClassList("container");
|
|
||||||
|
|
||||||
container.Add(GetHeader("Server Ports"));
|
|
||||||
container.Add(GetHeaderRow());
|
|
||||||
|
|
||||||
VisualElement portList = new VisualElement();
|
|
||||||
|
|
||||||
if (serverPorts.Count > 0)
|
|
||||||
{
|
|
||||||
foreach (PortMapping port in serverPorts)
|
|
||||||
{
|
|
||||||
portList.Add(GetRowFromPortResponse(port));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
portList.Add(new Label("No port configured for this app version."));
|
|
||||||
}
|
|
||||||
|
|
||||||
container.Add(portList);
|
|
||||||
|
|
||||||
return container;
|
|
||||||
}
|
|
||||||
|
|
||||||
public VisualElement GetServerDataVisualTree()
|
|
||||||
{
|
|
||||||
VisualElement serverDataTree = new VisualElement();
|
|
||||||
serverDataTree.styleSheets.Add(_serverDataStylesheet);
|
|
||||||
|
|
||||||
bool hasServerData = EdgegapServerDataManager._serverData != null;
|
|
||||||
bool isReady = hasServerData && EdgegapServerDataManager. _serverData.GetServerStatus().IsOneOf(ServerStatus.Ready, ServerStatus.Error);
|
|
||||||
|
|
||||||
if (hasServerData)
|
|
||||||
{
|
|
||||||
serverDataTree.Add(GetStatusSection());
|
|
||||||
|
|
||||||
if (isReady)
|
|
||||||
{
|
|
||||||
serverDataTree.Add(GetDnsSection());
|
|
||||||
serverDataTree.Add(GetPortsSection());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
serverDataTree.Add(GetInfoText("Additional information will be displayed when the server is ready."));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
serverDataTree.Add(GetInfoText("Server data will be displayed here when a server is running."));
|
|
||||||
}
|
|
||||||
|
|
||||||
return serverDataTree;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RefreshServerDataContainers()
|
|
||||||
{
|
|
||||||
foreach (VisualElement serverDataContainer in _serverDataContainers)
|
|
||||||
{
|
|
||||||
serverDataContainer.Clear();
|
|
||||||
serverDataContainer.Add(GetServerDataVisualTree()); // Cannot reuse a same instance of VisualElement
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// save & load /////////////////////////////////////////////////////////
|
|
||||||
/// <summary>
|
|
||||||
/// Save the tool's serializable data to the EditorPrefs to allow persistence across restarts.
|
|
||||||
/// Any field with [SerializeField] will be saved.
|
|
||||||
/// </summary>
|
|
||||||
void SaveToolData()
|
|
||||||
{
|
|
||||||
string data = JsonUtility.ToJson(this, false);
|
|
||||||
EditorPrefs.SetString(EditorDataSerializationName, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Load the tool's serializable data from the EditorPrefs to the object, restoring the tool's state.
|
|
||||||
/// </summary>
|
|
||||||
void LoadToolData()
|
|
||||||
{
|
|
||||||
string data = EditorPrefs.GetString(EditorDataSerializationName, JsonUtility.ToJson(this, false));
|
|
||||||
JsonUtility.FromJsonOverwrite(data, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
*/
|
|
@ -1,11 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 28bfb13cf2845d04eb5cbee51f9353d0
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
@ -15,9 +15,7 @@
|
|||||||
width: 400px;
|
width: 400px;
|
||||||
top: -10px;
|
top: -10px;
|
||||||
right: -150px;
|
right: -150px;
|
||||||
/* MIRROR CHANGE: disable hardcoded image path. this is inserted from the script now.
|
background-image: url('./Images/logo_transparent_400_alpha25.png?fileID=21300000&guid=b7012da4ebf9008458abc3ef9a741f3c&type=3#logo_transparent_400_alpha25');
|
||||||
background-image: url('project://database/Assets/Edgegap/Editor/Images/logo_transparent_400_alpha25.png?fileID=21300000&guid=b7012da4ebf9008458abc3ef9a741f3c&type=3#logo_transparent_400_alpha25');
|
|
||||||
*/
|
|
||||||
-unity-background-scale-mode: scale-and-crop;
|
-unity-background-scale-mode: scale-and-crop;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,7 +26,7 @@
|
|||||||
padding-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
-unity-text-align: middle-center;
|
-unity-text-align: middle-center;
|
||||||
/* MIRROR CHANGE: disable hardcoded font path
|
/* MIRROR CHANGE: disable hardcoded font path
|
||||||
-unity-font: url('project://database/Assets/Edgegap/Editor/Fonts/Src/BaronNeue.otf?fileID=12800000&guid=fb67205c672fbb04d829783b9f771fc9&type=3#BaronNeue');
|
-unity-font: url('./Fonts/Src/BaronNeue.otf?fileID=12800000&guid=fb67205c672fbb04d829783b9f771fc9&type=3#BaronNeue');
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,7 +120,7 @@
|
|||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
color: rgb(222, 222, 222);
|
color: rgb(222, 222, 222);
|
||||||
/* MIRROR CHANGE: disable hardcoded font path
|
/* MIRROR CHANGE: disable hardcoded font path
|
||||||
-unity-font-definition: url('project://database/Assets/Edgegap/Editor/Fonts/Spartan-Regular%20SDF.asset?fileID=11400000&guid=8b0fb2c68be09174f8ea5057b27a545c&type=2#Spartan-Regular SDF');
|
-unity-font-definition: url('./Fonts/Spartan-Regular%20SDF.asset?fileID=11400000&guid=8b0fb2c68be09174f8ea5057b27a545c&type=2#Spartan-Regular SDF');
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,7 +182,7 @@ Toggle > #unity-checkmark {
|
|||||||
.unity-text-field__input > TextElement {
|
.unity-text-field__input > TextElement {
|
||||||
color: rgb(255, 255, 255);
|
color: rgb(255, 255, 255);
|
||||||
/* MIRROR CHANGE: disable hardcoded font path
|
/* MIRROR CHANGE: disable hardcoded font path
|
||||||
-unity-font-definition: url('project://database/Assets/Edgegap/Editor/Fonts/UbuntuMono-R%20SDF.asset?fileID=11400000&guid=2635d61c9807d6c46bcb00a3d8645b37&type=2#UbuntuMono-R SDF');
|
-unity-font-definition: url('./Fonts/UbuntuMono-R%20SDF.asset?fileID=11400000&guid=2635d61c9807d6c46bcb00a3d8645b37&type=2#UbuntuMono-R SDF');
|
||||||
*/
|
*/
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
<Style src="project://database/Assets/Edgegap/Editor/EdgegapWindow.uss?fileID=7433441132597879392&guid=b1a2e4572c5de8840ac8d98377d409ae&type=3#EdgegapWindow" />
|
<Style src="project://database/Assets/Edgegap/Editor/EdgegapWindow.uss?fileID=7433441132597879392&guid=b1a2e4572c5de8840ac8d98377d409ae&type=3#EdgegapWindow" />
|
||||||
<ui:VisualElement class="content" style="padding-top: 0; padding-right: 0; padding-bottom: 0; padding-left: 0;">
|
<ui:VisualElement class="content" style="padding-top: 0; padding-right: 0; padding-bottom: 0; padding-left: 0;">
|
||||||
<ui:VisualElement name="HeaderHorizGroup" style="flex-grow: 1; flex-direction: row; height: 100px; background-color: rgb(37, 37, 37); left: 0;">
|
<ui:VisualElement name="HeaderHorizGroup" style="flex-grow: 1; flex-direction: row; height: 100px; background-color: rgb(37, 37, 37); left: 0;">
|
||||||
<ui:VisualElement name="header-logo-img" style="height: 67px; width: 100px; flex-direction: row; -unity-background-scale-mode: scale-to-fit; -unity-slice-left: 0; -unity-slice-top: 0; -unity-slice-right: 0; -unity-slice-bottom: 0; -unity-background-image-tint-color: rgb(255, 255, 255); -unity-slice-scale: 1px; align-self: center;" />
|
<ui:VisualElement name="header-logo-img" style="height: 67px; width: 100px; flex-direction: row; background-image: url('./Images/logo_transparent_400_alpha25.png?fileID=2800000&guid=b7012da4ebf9008458abc3ef9a741f3c&type=3#logo_transparent_400_alpha25'); -unity-background-scale-mode: scale-to-fit; -unity-slice-left: 0; -unity-slice-top: 0; -unity-slice-right: 0; -unity-slice-bottom: 0; -unity-background-image-tint-color: rgb(255, 255, 255); -unity-slice-scale: 1px; align-self: center;" />
|
||||||
<ui:Label text="EDGEGAP" name="header-logo-txt" class="text__title" style="flex-direction: row; flex-grow: 1; color: rgb(255, 255, 255); font-size: 30px; -unity-text-align: middle-left; -unity-font-style: normal; -unity-font: initial; margin-left: 0; align-items: center; height: 74px;">
|
<ui:Label text="EDGEGAP" name="header-logo-txt" class="text__title" style="flex-direction: row; flex-grow: 1; color: rgb(255, 255, 255); font-size: 30px; -unity-text-align: middle-left; -unity-font-style: normal; -unity-font: initial; -unity-font-definition: url('./Fonts/Spartan-SemiBold%20SDF.asset?fileID=11400000&guid=7b18949555c60224384ab80e57e1fd68&type=2#Spartan-SemiBold SDF'); margin-left: 0; align-items: center; height: 74px;">
|
||||||
<ui:Button text="DEBUG" parse-escape-sequences="true" display-tooltip-when-elided="true" name="DebugBtn" tooltip="Hide me @ EdgegapWindowMetadata.SHOW_DEBUG_BTN" style="-unity-text-align: middle-left; white-space: normal; text-overflow: clip; justify-content: flex-start; align-self: flex-end; position: absolute; right: 0; top: 0; padding-top: 3px;" />
|
<ui:Button text="DEBUG" parse-escape-sequences="true" display-tooltip-when-elided="true" name="DebugBtn" tooltip="Hide me @ EdgegapWindowMetadata.SHOW_DEBUG_BTN" style="-unity-text-align: middle-left; white-space: normal; text-overflow: clip; justify-content: flex-start; align-self: flex-end; position: absolute; right: 0; top: 0; padding-top: 3px;" />
|
||||||
</ui:Label>
|
</ui:Label>
|
||||||
</ui:VisualElement>
|
</ui:VisualElement>
|
||||||
@ -83,7 +83,7 @@
|
|||||||
<ui:Label name="DeploymentsConnectionStatusLabel" text="Unknown" class="text--muted" style="flex-grow: 1; flex-direction: column; -unity-text-align: middle-left; justify-content: flex-start; align-items: center; width: 86px; margin-right: 15px;" />
|
<ui:Label name="DeploymentsConnectionStatusLabel" text="Unknown" class="text--muted" style="flex-grow: 1; flex-direction: column; -unity-text-align: middle-left; justify-content: flex-start; align-items: center; width: 86px; margin-right: 15px;" />
|
||||||
<ui:VisualElement name="DeploymentConnectionUrlHorizGroup" style="flex-grow: 1; flex-direction: row; width: 304px; margin-left: 25px; margin-right: 25px; padding-right: 25px; padding-left: 25px;">
|
<ui:VisualElement name="DeploymentConnectionUrlHorizGroup" style="flex-grow: 1; flex-direction: row; width: 304px; margin-left: 25px; margin-right: 25px; padding-right: 25px; padding-left: 25px;">
|
||||||
<ui:TextField picking-mode="Ignore" name="DeploymentConnectionUrlReadOnlyTxt" readonly="true" tooltip="Selectable" style="padding-left: 0; -unity-text-align: middle-center; width: 297px; align-items: center;">
|
<ui:TextField picking-mode="Ignore" name="DeploymentConnectionUrlReadOnlyTxt" readonly="true" tooltip="Selectable" style="padding-left: 0; -unity-text-align: middle-center; width: 297px; align-items: center;">
|
||||||
<ui:Button name="DeploymentConnectionCopyUrlBtn" tooltip="Copy" class="text-edgegap bg-purple" style="min-width: 15px; visibility: visible; display: flex; overflow: hidden; width: 35px; -unity-background-scale-mode: scale-to-fit; min-height: 25px; background-color: rgb(44, 30, 210); -unity-background-image-tint-color: rgb(224, 224, 224); -unity-slice-left: 1; -unity-slice-top: 1; -unity-slice-right: 1; -unity-slice-bottom: 1; translate: -40px 0;" />
|
<ui:Button name="DeploymentConnectionCopyUrlBtn" tooltip="Copy" class="text-edgegap bg-purple" style="min-width: 15px; visibility: visible; display: flex; overflow: hidden; background-image: url('./Images/clipboard-128.png?fileID=2800000&guid=caa516cdb721dd143bbc8000ca78d50a&type=3#clipboard-128'); width: 35px; -unity-background-scale-mode: scale-to-fit; min-height: 25px; background-color: rgb(44, 30, 210); -unity-background-image-tint-color: rgb(224, 224, 224); -unity-slice-left: 1; -unity-slice-top: 1; -unity-slice-right: 1; -unity-slice-bottom: 1; translate: -40px 0;" />
|
||||||
</ui:TextField>
|
</ui:TextField>
|
||||||
</ui:VisualElement>
|
</ui:VisualElement>
|
||||||
<ui:VisualElement name="DeploymentsConnectionServerStopHorizBtnHorizGroup" style="flex-grow: 1; flex-direction: column; align-items: center; justify-content: center; align-self: auto;">
|
<ui:VisualElement name="DeploymentsConnectionServerStopHorizBtnHorizGroup" style="flex-grow: 1; flex-direction: column; align-items: center; justify-content: center; align-self: auto;">
|
||||||
|
@ -21,20 +21,20 @@ public enum LogLevel
|
|||||||
Debug,
|
Debug,
|
||||||
Error,
|
Error,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set to Debug to show more logs. Default `Error`.
|
/// Set to Debug to show more logs. Default `Error`.
|
||||||
/// - Error level includes "potentially-intentional" (!fatal) errors logged with Debug.Log
|
/// - Error level includes "potentially-intentional" (!fatal) errors logged with Debug.Log
|
||||||
/// - TODO: Move opt to UI?
|
/// - TODO: Move opt to UI?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const LogLevel LOG_LEVEL = LogLevel.Error;
|
public const LogLevel LOG_LEVEL = LogLevel.Error;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set to show a debug button at the top-right for arbitrary testing.
|
/// Set to show a debug button at the top-right for arbitrary testing.
|
||||||
/// Default enables groups. Default `false`.
|
/// Default enables groups. Default `false`.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const bool SHOW_DEBUG_BTN = false;
|
public const bool SHOW_DEBUG_BTN = false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// When running a Docker-based "Build & Push" flow, skip building the Unity server binary
|
/// When running a Docker-based "Build & Push" flow, skip building the Unity server binary
|
||||||
/// (great for testing push flow). Default false.
|
/// (great for testing push flow). Default false.
|
||||||
@ -48,7 +48,7 @@ public enum LogLevel
|
|||||||
public static readonly bool SKIP_DOCKER_IMAGE_BUILD_WHEN_PUSHING = false; // MIRROR CHANGE: 'const' changed to 'static readonly' to avoid 'unreachable code detected' warning
|
public static readonly bool SKIP_DOCKER_IMAGE_BUILD_WHEN_PUSHING = false; // MIRROR CHANGE: 'const' changed to 'static readonly' to avoid 'unreachable code detected' warning
|
||||||
#endregion // Debug
|
#endregion // Debug
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Interval at which the server status is updated</summary>
|
/// <summary>Interval at which the server status is updated</summary>
|
||||||
public const int SERVER_STATUS_CRON_JOB_INTERVAL_MS = 10000;
|
public const int SERVER_STATUS_CRON_JOB_INTERVAL_MS = 10000;
|
||||||
public const int PORT_DEFAULT = 7770;
|
public const int PORT_DEFAULT = 7770;
|
||||||
@ -63,7 +63,7 @@ public enum LogLevel
|
|||||||
public const string EDGEGAP_GET_A_TOKEN_URL = "https://app.edgegap.com/?oneClick=true";
|
public const string EDGEGAP_GET_A_TOKEN_URL = "https://app.edgegap.com/?oneClick=true";
|
||||||
public const string EDGEGAP_ADD_MORE_GAME_SERVERS_URL = "https://edgegap.com/resources/contact";
|
public const string EDGEGAP_ADD_MORE_GAME_SERVERS_URL = "https://edgegap.com/resources/contact";
|
||||||
public const string EDGEGAP_DOC_BTN_HOW_TO_LOGIN_VIA_CLI_URL = "https://docs.edgegap.com/docs/container/edgegap-container-registry/#getting-your-credentials";
|
public const string EDGEGAP_DOC_BTN_HOW_TO_LOGIN_VIA_CLI_URL = "https://docs.edgegap.com/docs/container/edgegap-container-registry/#getting-your-credentials";
|
||||||
private const string DEFAULT_UTM_SOURCE_TAG = "plugin_unity";
|
private const string DEFAULT_UTM_SOURCE_TAG = "partner_mirror_assetstore_unity";
|
||||||
private const string DEFAULT_UTM_MEDIUM_TAG = "servers_quickstart_plugin";
|
private const string DEFAULT_UTM_MEDIUM_TAG = "servers_quickstart_plugin";
|
||||||
private const string DEFAULT_UTM_CONTENT_TAG = "plugin_button";
|
private const string DEFAULT_UTM_CONTENT_TAG = "plugin_button";
|
||||||
public const string DEFAULT_UTM_TAGS = "utm_source=" + DEFAULT_UTM_SOURCE_TAG +
|
public const string DEFAULT_UTM_TAGS = "utm_source=" + DEFAULT_UTM_SOURCE_TAG +
|
||||||
@ -73,14 +73,15 @@ public enum LogLevel
|
|||||||
public const string LOADING_RICH_STR = "<i>Loading...</i>";
|
public const string LOADING_RICH_STR = "<i>Loading...</i>";
|
||||||
public const string PROCESSING_RICH_STR = "<i>Processing...</i>";
|
public const string PROCESSING_RICH_STR = "<i>Processing...</i>";
|
||||||
public const string DEPLOY_REQUEST_RICH_STR = "<i>Requesting Deploy...</i>";
|
public const string DEPLOY_REQUEST_RICH_STR = "<i>Requesting Deploy...</i>";
|
||||||
|
public const string KEY_COMPILER_MACRO = "EDGEGAP_PLUGIN_SERVERS";
|
||||||
|
|
||||||
#region Colors
|
#region Colors
|
||||||
/// <summary>Earthy lime green</summary>
|
/// <summary>Earthy lime green</summary>
|
||||||
public const string SUCCESS_COLOR_HEX = "#8AEE8C";
|
public const string SUCCESS_COLOR_HEX = "#8AEE8C";
|
||||||
|
|
||||||
/// <summary>Calming light orange</summary>
|
/// <summary>Calming light orange</summary>
|
||||||
public const string WARN_COLOR_HEX = "#EEC58A";
|
public const string WARN_COLOR_HEX = "#EEC58A";
|
||||||
|
|
||||||
/// <summary>Vivid blood orange</summary>
|
/// <summary>Vivid blood orange</summary>
|
||||||
public const string FAIL_COLOR_HEX = "#EE9A8A";
|
public const string FAIL_COLOR_HEX = "#EE9A8A";
|
||||||
|
|
||||||
@ -91,17 +92,17 @@ public enum StatusColors
|
|||||||
{
|
{
|
||||||
/// <summary>CornYellow</summary>
|
/// <summary>CornYellow</summary>
|
||||||
Processing,
|
Processing,
|
||||||
|
|
||||||
/// <summary>EarthyLimeGreen</summary>
|
/// <summary>EarthyLimeGreen</summary>
|
||||||
Success,
|
Success,
|
||||||
|
|
||||||
/// <summary>CalmingLightOrange</summary>
|
/// <summary>CalmingLightOrange</summary>
|
||||||
Warn,
|
Warn,
|
||||||
|
|
||||||
/// <summary>VividBloodOrange</summary>
|
/// <summary>VividBloodOrange</summary>
|
||||||
Error,
|
Error,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <returns>Wraps string in color rich text</returns>
|
/// <returns>Wraps string in color rich text</returns>
|
||||||
public static string WrapRichTextInColor(string str, StatusColors statusColor)
|
public static string WrapRichTextInColor(string str, StatusColors statusColor)
|
||||||
{
|
{
|
||||||
@ -120,7 +121,7 @@ public static string WrapRichTextInColor(string str, StatusColors statusColor)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion // Colors
|
#endregion // Colors
|
||||||
|
|
||||||
#region Player Pref Key Ids for persistence
|
#region Player Pref Key Ids for persistence
|
||||||
/// <summary>Cached as base64</summary>
|
/// <summary>Cached as base64</summary>
|
||||||
public const string API_TOKEN_KEY_STR = "ApiToken";
|
public const string API_TOKEN_KEY_STR = "ApiToken";
|
||||||
@ -129,14 +130,14 @@ public static string WrapRichTextInColor(string str, StatusColors statusColor)
|
|||||||
public const string DEPLOYMENT_CONNECTION_STATUS_KEY_STR = "DeploymentsConnectionStatusLabel";
|
public const string DEPLOYMENT_CONNECTION_STATUS_KEY_STR = "DeploymentsConnectionStatusLabel";
|
||||||
public const string CONTAINER_REGISTRY_TRANSPORT_TYPE_ENUM_KEY_STR = "ContainerRegistryProtocolTypeEnum";
|
public const string CONTAINER_REGISTRY_TRANSPORT_TYPE_ENUM_KEY_STR = "ContainerRegistryProtocolTypeEnum";
|
||||||
#endregion // Editor Pref Key Ids for persistence
|
#endregion // Editor Pref Key Ids for persistence
|
||||||
|
|
||||||
#region UI Element Ids
|
#region UI Element Ids
|
||||||
public const string DEBUG_BTN_ID = "DebugBtn";
|
public const string DEBUG_BTN_ID = "DebugBtn";
|
||||||
public const string API_TOKEN_TXT_ID = "ApiTokenMaskedTxt";
|
public const string API_TOKEN_TXT_ID = "ApiTokenMaskedTxt";
|
||||||
public const string API_TOKEN_VERIFY_BTN_ID = "ApiTokenVerifyPurpleBtn";
|
public const string API_TOKEN_VERIFY_BTN_ID = "ApiTokenVerifyPurpleBtn";
|
||||||
public const string API_TOKEN_GET_BTN_ID = "ApiTokenGetBtn";
|
public const string API_TOKEN_GET_BTN_ID = "ApiTokenGetBtn";
|
||||||
public const string POST_AUTH_CONTAINER_ID = "PostAuthContainer";
|
public const string POST_AUTH_CONTAINER_ID = "PostAuthContainer";
|
||||||
|
|
||||||
public const string APP_INFO_FOLDOUT_ID = "ApplicationInfoFoldout";
|
public const string APP_INFO_FOLDOUT_ID = "ApplicationInfoFoldout";
|
||||||
public const string APP_NAME_TXT_ID = "ApplicationNameTxt";
|
public const string APP_NAME_TXT_ID = "ApplicationNameTxt";
|
||||||
public const string APP_LOAD_EXISTING_BTN_ID = "AppLoadExistingBtn";
|
public const string APP_LOAD_EXISTING_BTN_ID = "AppLoadExistingBtn";
|
||||||
@ -156,7 +157,7 @@ public static string WrapRichTextInColor(string str, StatusColors statusColor)
|
|||||||
public const string CONTAINER_TOKEN_TXT_ID = "ContainerTokenTxt";
|
public const string CONTAINER_TOKEN_TXT_ID = "ContainerTokenTxt";
|
||||||
public const string CONTAINER_BUILD_AND_PUSH_BTN_ID = "ContainerBuildAndPushBtn";
|
public const string CONTAINER_BUILD_AND_PUSH_BTN_ID = "ContainerBuildAndPushBtn";
|
||||||
public const string CONTAINER_BUILD_AND_PUSH_RESULT_LABEL_ID = "ContainerBuildAndPushResultLabel";
|
public const string CONTAINER_BUILD_AND_PUSH_RESULT_LABEL_ID = "ContainerBuildAndPushResultLabel";
|
||||||
|
|
||||||
public const string DEPLOYMENTS_FOLDOUT_ID = "DeploymentsFoldout";
|
public const string DEPLOYMENTS_FOLDOUT_ID = "DeploymentsFoldout";
|
||||||
public const string DEPLOYMENTS_REFRESH_BTN_ID = "DeploymentsRefreshBtn";
|
public const string DEPLOYMENTS_REFRESH_BTN_ID = "DeploymentsRefreshBtn";
|
||||||
public const string DEPLOYMENTS_CREATE_BTN_ID = "DeploymentsCreateBtn";
|
public const string DEPLOYMENTS_CREATE_BTN_ID = "DeploymentsCreateBtn";
|
||||||
@ -167,11 +168,11 @@ public static string WrapRichTextInColor(string str, StatusColors statusColor)
|
|||||||
public const string DEPLOYMENTS_CONNECTION_STATUS_LABEL_ID = "DeploymentsConnectionStatusLabel"; // Dynamic
|
public const string DEPLOYMENTS_CONNECTION_STATUS_LABEL_ID = "DeploymentsConnectionStatusLabel"; // Dynamic
|
||||||
public const string DEPLOYMENTS_CONNECTION_SERVER_ACTION_STOP_BTN_ID = "DeploymentsConnectionServerStopBtn";
|
public const string DEPLOYMENTS_CONNECTION_SERVER_ACTION_STOP_BTN_ID = "DeploymentsConnectionServerStopBtn";
|
||||||
public const string DEPLOYMENTS_CONNECTION_CONTAINER_LOGS_BTN_ID = "DeploymentsConnectionContainerLogsBtn";
|
public const string DEPLOYMENTS_CONNECTION_CONTAINER_LOGS_BTN_ID = "DeploymentsConnectionContainerLogsBtn";
|
||||||
|
|
||||||
public const string FOOTER_DOCUMENTATION_BTN_ID = "FooterDocumentationBtn";
|
public const string FOOTER_DOCUMENTATION_BTN_ID = "FooterDocumentationBtn";
|
||||||
public const string FOOTER_NEED_MORE_GAME_SERVERS_BTN_ID = "FooterNeedMoreGameServersBtn";
|
public const string FOOTER_NEED_MORE_GAME_SERVERS_BTN_ID = "FooterNeedMoreGameServersBtn";
|
||||||
#endregion // UI Element Ids
|
#endregion // UI Element Ids
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//[Obsolete("Hard-coded; not from UI. TODO: Get from UI")] // MIRROR CHANGE: comment this out to avoid import warnings
|
//[Obsolete("Hard-coded; not from UI. TODO: Get from UI")] // MIRROR CHANGE: comment this out to avoid import warnings
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
|
#if UNITY_2021_3_OR_NEWER // MIRROR CHANGE
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@ -12,6 +14,7 @@
|
|||||||
using Edgegap.Editor.Api.Models.Requests;
|
using Edgegap.Editor.Api.Models.Requests;
|
||||||
using Edgegap.Editor.Api.Models.Results;
|
using Edgegap.Editor.Api.Models.Results;
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
|
using UnityEditor.Build;
|
||||||
using UnityEditor.Build.Reporting;
|
using UnityEditor.Build.Reporting;
|
||||||
using UnityEditor.UIElements;
|
using UnityEditor.UIElements;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
@ -98,7 +101,7 @@ public class EdgegapWindowV2 : EditorWindow
|
|||||||
|
|
||||||
private Button _footerDocumentationBtn;
|
private Button _footerDocumentationBtn;
|
||||||
private Button _footerNeedMoreGameServersBtn;
|
private Button _footerNeedMoreGameServersBtn;
|
||||||
#endregion // Vars
|
#endregion // Vars\
|
||||||
|
|
||||||
// MIRROR CHANGE
|
// MIRROR CHANGE
|
||||||
// get the path of this .cs file so we don't need to hardcode paths to
|
// get the path of this .cs file so we don't need to hardcode paths to
|
||||||
@ -108,13 +111,10 @@ public class EdgegapWindowV2 : EditorWindow
|
|||||||
internal string StylesheetPath =>
|
internal string StylesheetPath =>
|
||||||
Path.GetDirectoryName(AssetDatabase.GetAssetPath(MonoScript.FromScriptableObject(this)));
|
Path.GetDirectoryName(AssetDatabase.GetAssetPath(MonoScript.FromScriptableObject(this)));
|
||||||
// END MIRROR CHANGE
|
// END MIRROR CHANGE
|
||||||
|
internal string ProjectRootPath => Directory.GetCurrentDirectory();
|
||||||
|
internal string DockerFilePath => $"{Directory.GetParent(Directory.GetFiles(ProjectRootPath, GetType().Name + ".cs", SearchOption.AllDirectories)[0]).FullName}{Path.DirectorySeparatorChar}Dockerfile";
|
||||||
|
|
||||||
// MIRROR CHANGE: images are dragged into the script in inspector and assigned to the UI at runtime. this way we don't need to hardcode it.
|
[MenuItem("Tools/Edgegap Hosting")] // MIRROR CHANGE: more obvious title
|
||||||
public Texture2D LogoImage;
|
|
||||||
public Texture2D ClipboardImage;
|
|
||||||
// END MIRROR CHANGE
|
|
||||||
|
|
||||||
[MenuItem("Edgegap/Edgegap Hosting")] // MIRROR CHANGE: more obvious title
|
|
||||||
public static void ShowEdgegapToolWindow()
|
public static void ShowEdgegapToolWindow()
|
||||||
{
|
{
|
||||||
EdgegapWindowV2 window = GetWindow<EdgegapWindowV2>();
|
EdgegapWindowV2 window = GetWindow<EdgegapWindowV2>();
|
||||||
@ -123,25 +123,52 @@ public static void ShowEdgegapToolWindow()
|
|||||||
window.minSize = window.maxSize;
|
window.minSize = window.maxSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#region Unity Funcs
|
#region Unity Funcs
|
||||||
|
[InitializeOnLoadMethod]
|
||||||
|
public static void AddDefineSymbols()
|
||||||
|
{
|
||||||
|
// check if defined first, otherwise adding the symbol causes an infinite loop of recompilation
|
||||||
|
#if !EDGEGAP_PLUGIN_SERVERS
|
||||||
|
// Get data about current target group
|
||||||
|
bool standaloneAndServer = false;
|
||||||
|
BuildTarget buildTarget = EditorUserBuildSettings.activeBuildTarget;
|
||||||
|
BuildTargetGroup buildTargetGroup = BuildPipeline.GetBuildTargetGroup(buildTarget);
|
||||||
|
if (buildTargetGroup == BuildTargetGroup.Standalone)
|
||||||
|
{
|
||||||
|
StandaloneBuildSubtarget standaloneSubTarget = EditorUserBuildSettings.standaloneBuildSubtarget;
|
||||||
|
if (standaloneSubTarget == StandaloneBuildSubtarget.Server)
|
||||||
|
standaloneAndServer = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare named target, depending on above stuff
|
||||||
|
NamedBuildTarget namedBuildTarget;
|
||||||
|
if (standaloneAndServer)
|
||||||
|
namedBuildTarget = NamedBuildTarget.Server;
|
||||||
|
else
|
||||||
|
namedBuildTarget = NamedBuildTarget.FromBuildTargetGroup(buildTargetGroup);
|
||||||
|
|
||||||
|
// Set universal compiler macro
|
||||||
|
PlayerSettings.SetScriptingDefineSymbols(namedBuildTarget, $"{PlayerSettings.GetScriptingDefineSymbols(namedBuildTarget)};{EdgegapWindowMetadata.KEY_COMPILER_MACRO}");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
protected void OnEnable()
|
protected void OnEnable()
|
||||||
{
|
{
|
||||||
#if UNITY_2021_3_OR_NEWER // MIRROR CHANGE: only load stylesheet in supported Unity versions, otherwise it shows errors in U2020
|
#if UNITY_2021_3_OR_NEWER // only load stylesheet in supported Unity versions, otherwise it shows errors in U2020
|
||||||
// Set root VisualElement and style: V2 still uses EdgegapWindow.[uxml|uss]
|
// Set root VisualElement and style: V2 still uses EdgegapWindow.[uxml|uss]
|
||||||
// BEGIN MIRROR CHANGE
|
// BEGIN MIRROR CHANGE
|
||||||
_visualTree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>($"{StylesheetPath}/EdgegapWindow.uxml");
|
_visualTree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>($"{StylesheetPath}{Path.DirectorySeparatorChar}EdgegapWindow.uxml");
|
||||||
StyleSheet styleSheet = AssetDatabase.LoadAssetAtPath<StyleSheet>($"{StylesheetPath}/EdgegapWindow.uss");
|
StyleSheet styleSheet = AssetDatabase.LoadAssetAtPath<StyleSheet>($"{StylesheetPath}{Path.DirectorySeparatorChar}EdgegapWindow.uss");
|
||||||
// END MIRROR CHANGE
|
// END MIRROR CHANGE
|
||||||
rootVisualElement.styleSheets.Add(styleSheet);
|
rootVisualElement.styleSheets.Add(styleSheet);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma warning disable CS1998 // MIRROR CHANGE: disable async warning in U2020
|
#pragma warning disable CS1998 // disable async warning in U2020
|
||||||
public async void CreateGUI()
|
public async void CreateGUI()
|
||||||
#pragma warning restore CS1998 // END MIRROR CHANGE
|
#pragma warning restore CS1998
|
||||||
{
|
{
|
||||||
// MIRROR CHANGE: the UI requires 'GroupBox', which is not available in Unity 2019/2020.
|
// the UI requires 'GroupBox', which is not available in Unity 2019/2020.
|
||||||
// showing it will break all of Unity's Editor UIs, not just this one.
|
// showing it will break all of Unity's Editor UIs, not just this one.
|
||||||
// instead, show a warning that the Edgegap plugin only works on Unity 2021+
|
// instead, show a warning that the Edgegap plugin only works on Unity 2021+
|
||||||
#if !UNITY_2021_3_OR_NEWER
|
#if !UNITY_2021_3_OR_NEWER
|
||||||
@ -163,10 +190,9 @@ public async void CreateGUI()
|
|||||||
/// <summary>The user closed the window. Save the data.</summary>
|
/// <summary>The user closed the window. Save the data.</summary>
|
||||||
protected void OnDisable()
|
protected void OnDisable()
|
||||||
{
|
{
|
||||||
#if UNITY_2021_3_OR_NEWER // MIRROR CHANGE: only load stylesheet in supported Unity versions, otherwise it shows errors in U2020
|
#if UNITY_2021_3_OR_NEWER // only load stylesheet in supported Unity versions, otherwise it shows errors in U2020
|
||||||
// MIRROR CHANGE: sometimes this is called without having been registered, throwing NRE
|
// sometimes this is called without having been registered, throwing NRE
|
||||||
if (_debugBtn == null) return;
|
if (_debugBtn == null) return;
|
||||||
// END MIRROR CHANGE
|
|
||||||
|
|
||||||
unregisterClickEvents();
|
unregisterClickEvents();
|
||||||
unregisterFieldCallbacks();
|
unregisterFieldCallbacks();
|
||||||
@ -189,7 +215,6 @@ private void InitUIElements()
|
|||||||
registerClickCallbacks();
|
registerClickCallbacks();
|
||||||
registerFieldCallbacks();
|
registerFieldCallbacks();
|
||||||
initToggleDynamicUi();
|
initToggleDynamicUi();
|
||||||
AssignImages(); // MIRROR CHANGE
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void closeDisableGroups()
|
private void closeDisableGroups()
|
||||||
@ -203,20 +228,6 @@ private void closeDisableGroups()
|
|||||||
_deploymentsFoldout.SetEnabled(false);
|
_deploymentsFoldout.SetEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MIRROR CHANGE: assign images to the UI at runtime instead of hardcoding it
|
|
||||||
void AssignImages()
|
|
||||||
{
|
|
||||||
// header logo
|
|
||||||
VisualElement logoElement = rootVisualElement.Q<VisualElement>("header-logo-img");
|
|
||||||
logoElement.style.backgroundImage = LogoImage;
|
|
||||||
|
|
||||||
// clipboard button
|
|
||||||
VisualElement copyElement = rootVisualElement.Q<VisualElement>("DeploymentConnectionCopyUrlBtn");
|
|
||||||
copyElement.style.backgroundImage = ClipboardImage;
|
|
||||||
}
|
|
||||||
|
|
||||||
// END MIRROR CHANGE
|
|
||||||
|
|
||||||
/// <summary>Set fields referencing UI Builder's fields. In order of appearance from top-to-bottom.</summary>
|
/// <summary>Set fields referencing UI Builder's fields. In order of appearance from top-to-bottom.</summary>
|
||||||
private void setVisualElementsToFields()
|
private void setVisualElementsToFields()
|
||||||
{
|
{
|
||||||
@ -633,7 +644,6 @@ private async void onContainerBuildAndPushServerBtnClickAsync()
|
|||||||
#endregion // Init -> /Button Clicks
|
#endregion // Init -> /Button Clicks
|
||||||
#endregion // Init
|
#endregion // Init
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Throw if !appName val</summary>
|
/// <summary>Throw if !appName val</summary>
|
||||||
private void assertAppNameExists() =>
|
private void assertAppNameExists() =>
|
||||||
Assert.IsTrue(!string.IsNullOrEmpty(_appNameInput.value),
|
Assert.IsTrue(!string.IsNullOrEmpty(_appNameInput.value),
|
||||||
@ -1019,7 +1029,7 @@ private void SyncContainerEnablesToState()
|
|||||||
private void openGetApiTokenWebsite()
|
private void openGetApiTokenWebsite()
|
||||||
{
|
{
|
||||||
if (IsLogLevelDebug) Debug.Log("openGetApiTokenWebsite");
|
if (IsLogLevelDebug) Debug.Log("openGetApiTokenWebsite");
|
||||||
Application.OpenURL(EdgegapWindowMetadata.EDGEGAP_GET_A_TOKEN_URL + "&" +
|
Application.OpenURL(EdgegapWindowMetadata.EDGEGAP_GET_A_TOKEN_URL + "&" +
|
||||||
EdgegapWindowMetadata.DEFAULT_UTM_TAGS);
|
EdgegapWindowMetadata.DEFAULT_UTM_TAGS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1139,16 +1149,14 @@ private string getFriendlyCreateAppResultStr(EdgegapHttpResult<GetCreateAppResul
|
|||||||
|
|
||||||
/// <summary>Open contact form in desired locale</summary>
|
/// <summary>Open contact form in desired locale</summary>
|
||||||
private void openNeedMoreGameServersWebsite() =>
|
private void openNeedMoreGameServersWebsite() =>
|
||||||
Application.OpenURL(EdgegapWindowMetadata.EDGEGAP_ADD_MORE_GAME_SERVERS_URL + "?" +
|
Application.OpenURL(EdgegapWindowMetadata.EDGEGAP_ADD_MORE_GAME_SERVERS_URL + "?" +
|
||||||
EdgegapWindowMetadata.DEFAULT_UTM_TAGS);
|
EdgegapWindowMetadata.DEFAULT_UTM_TAGS);
|
||||||
|
|
||||||
private void openDocumentationWebsite()
|
private void openDocumentationWebsite()
|
||||||
{
|
{
|
||||||
string documentationUrl = _apiEnvironment.GetDocumentationUrl() + "?" +
|
string documentationUrl = _apiEnvironment.GetDocumentationUrl() + "?" +
|
||||||
EdgegapWindowMetadata.DEFAULT_UTM_TAGS;
|
EdgegapWindowMetadata.DEFAULT_UTM_TAGS;
|
||||||
|
|
||||||
// BEGIN MIRROR CHANGE
|
|
||||||
/*
|
|
||||||
if (!string.IsNullOrEmpty(documentationUrl))
|
if (!string.IsNullOrEmpty(documentationUrl))
|
||||||
Application.OpenURL(documentationUrl);
|
Application.OpenURL(documentationUrl);
|
||||||
else
|
else
|
||||||
@ -1157,11 +1165,6 @@ private void openDocumentationWebsite()
|
|||||||
Debug.LogWarning($"Could not open documentation for api environment " +
|
Debug.LogWarning($"Could not open documentation for api environment " +
|
||||||
$"{apiEnvName}: No documentation URL.");
|
$"{apiEnvName}: No documentation URL.");
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
// link to our step by step guide
|
|
||||||
Application.OpenURL("https://mirror-networking.gitbook.io/docs/hosting/edgegap-hosting-plugin-guide");
|
|
||||||
// END MIRROR CHANGE
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -1353,10 +1356,7 @@ private void onCreateDeploymentStartServerFail(EdgegapHttpResult<CreateDeploymen
|
|||||||
Debug.Log("(!) Check your deployments here: https://app.edgegap.com/deployment-management/deployments/list");
|
Debug.Log("(!) Check your deployments here: https://app.edgegap.com/deployment-management/deployments/list");
|
||||||
|
|
||||||
// Shake "need more servers" btn on 403
|
// Shake "need more servers" btn on 403
|
||||||
// MIRROR CHANGE: use old C# syntax that is supported in Unity 2019
|
|
||||||
// bool reachedNumDeploymentsHardcap = result is { IsResultCode403: true };
|
|
||||||
bool reachedNumDeploymentsHardcap = result != null && result.IsResultCode403;
|
bool reachedNumDeploymentsHardcap = result != null && result.IsResultCode403;
|
||||||
// END MIRROR CHANGE
|
|
||||||
if (reachedNumDeploymentsHardcap)
|
if (reachedNumDeploymentsHardcap)
|
||||||
shakeNeedMoreGameServersBtn();
|
shakeNeedMoreGameServersBtn();
|
||||||
}
|
}
|
||||||
@ -1519,7 +1519,7 @@ private async Task buildAndPushServerAsync()
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
// check for installation and setup docker file
|
// check for installation and setup docker file
|
||||||
if (!await EdgegapBuildUtils.DockerSetupAndInstallationCheck())
|
if (!await EdgegapBuildUtils.DockerSetupAndInstallationCheck(DockerFilePath))
|
||||||
{
|
{
|
||||||
onBuildPushError("Docker installation not found. " +
|
onBuildPushError("Docker installation not found. " +
|
||||||
"Docker can be downloaded from:\n\nhttps://www.docker.com/");
|
"Docker can be downloaded from:\n\nhttps://www.docker.com/");
|
||||||
@ -1593,7 +1593,7 @@ private async Task buildAndPushServerAsync()
|
|||||||
// tag,
|
// tag,
|
||||||
// ShowBuildWorkInProgress);
|
// ShowBuildWorkInProgress);
|
||||||
|
|
||||||
await EdgegapBuildUtils.RunCommand_DockerBuild(registry, imageName, tag, status => ShowBuildWorkInProgress("Building Docker Image", status));
|
await EdgegapBuildUtils.RunCommand_DockerBuild(DockerFilePath, registry, imageName, tag, ProjectRootPath, status => ShowBuildWorkInProgress("Building Docker Image", status));
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1816,4 +1816,5 @@ private void setMaskedApiTokenFromEditorPrefs()
|
|||||||
#endregion // Persistence Helpers
|
#endregion // Persistence Helpers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
2660
Assets/Mirror/Hosting/Edgegap/Editor/Fonts/BaronNeue SDF.asset
Normal file
2660
Assets/Mirror/Hosting/Edgegap/Editor/Fonts/BaronNeue SDF.asset
Normal file
File diff suppressed because one or more lines are too long
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: af70148bee18c584898036462be91b19
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -1 +0,0 @@
|
|||||||
Removed font files to avoid all kinds of runtime errors.
|
|
2727
Assets/Mirror/Hosting/Edgegap/Editor/Fonts/Spartan-Regular SDF.asset
Normal file
2727
Assets/Mirror/Hosting/Edgegap/Editor/Fonts/Spartan-Regular SDF.asset
Normal file
File diff suppressed because one or more lines are too long
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8b0fb2c68be09174f8ea5057b27a545c
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7b18949555c60224384ab80e57e1fd68
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
8
Assets/Mirror/Hosting/Edgegap/Editor/Fonts/Src.meta
Normal file
8
Assets/Mirror/Hosting/Edgegap/Editor/Fonts/Src.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 96d42e9dd757c494cb7079e8bc71d6d8
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
BIN
Assets/Mirror/Hosting/Edgegap/Editor/Fonts/Src/BaronNeue.otf
Normal file
BIN
Assets/Mirror/Hosting/Edgegap/Editor/Fonts/Src/BaronNeue.otf
Normal file
Binary file not shown.
@ -0,0 +1,21 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: fb67205c672fbb04d829783b9f771fc9
|
||||||
|
TrueTypeFontImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 4
|
||||||
|
fontSize: 16
|
||||||
|
forceTextureCase: -2
|
||||||
|
characterSpacing: 0
|
||||||
|
characterPadding: 1
|
||||||
|
includeFontData: 1
|
||||||
|
fontNames:
|
||||||
|
- Baron Neue
|
||||||
|
fallbackFontReferences: []
|
||||||
|
customCharacters:
|
||||||
|
fontRenderingMode: 0
|
||||||
|
ascentCalculationMode: 1
|
||||||
|
useLegacyBoundsCalculation: 0
|
||||||
|
shouldRoundAdvanceValue: 1
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f18ac4f244549d74aad2ffc298216c48
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
Binary file not shown.
@ -0,0 +1,21 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3445f8970e8fa734c96cef5ab98ddd61
|
||||||
|
TrueTypeFontImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 4
|
||||||
|
fontSize: 16
|
||||||
|
forceTextureCase: -2
|
||||||
|
characterSpacing: 0
|
||||||
|
characterPadding: 1
|
||||||
|
includeFontData: 1
|
||||||
|
fontNames:
|
||||||
|
- Spartan
|
||||||
|
fallbackFontReferences: []
|
||||||
|
customCharacters:
|
||||||
|
fontRenderingMode: 0
|
||||||
|
ascentCalculationMode: 1
|
||||||
|
useLegacyBoundsCalculation: 0
|
||||||
|
shouldRoundAdvanceValue: 1
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
Binary file not shown.
@ -0,0 +1,21 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 52c456e5bd94b2b4b9045a79143694e9
|
||||||
|
TrueTypeFontImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 4
|
||||||
|
fontSize: 16
|
||||||
|
forceTextureCase: -2
|
||||||
|
characterSpacing: 0
|
||||||
|
characterPadding: 1
|
||||||
|
includeFontData: 1
|
||||||
|
fontNames:
|
||||||
|
- Spartan
|
||||||
|
fallbackFontReferences: []
|
||||||
|
customCharacters:
|
||||||
|
fontRenderingMode: 0
|
||||||
|
ascentCalculationMode: 1
|
||||||
|
useLegacyBoundsCalculation: 0
|
||||||
|
shouldRoundAdvanceValue: 1
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
BIN
Assets/Mirror/Hosting/Edgegap/Editor/Fonts/Src/UbuntuMono-R.ttf
Normal file
BIN
Assets/Mirror/Hosting/Edgegap/Editor/Fonts/Src/UbuntuMono-R.ttf
Normal file
Binary file not shown.
@ -0,0 +1,21 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 891349ed6c370194a8c6135995d27d32
|
||||||
|
TrueTypeFontImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 4
|
||||||
|
fontSize: 16
|
||||||
|
forceTextureCase: -2
|
||||||
|
characterSpacing: 0
|
||||||
|
characterPadding: 1
|
||||||
|
includeFontData: 1
|
||||||
|
fontNames:
|
||||||
|
- Ubuntu Mono
|
||||||
|
fallbackFontReferences: []
|
||||||
|
customCharacters:
|
||||||
|
fontRenderingMode: 0
|
||||||
|
ascentCalculationMode: 1
|
||||||
|
useLegacyBoundsCalculation: 0
|
||||||
|
shouldRoundAdvanceValue: 1
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
2723
Assets/Mirror/Hosting/Edgegap/Editor/Fonts/UbuntuMono-R SDF.asset
Normal file
2723
Assets/Mirror/Hosting/Edgegap/Editor/Fonts/UbuntuMono-R SDF.asset
Normal file
File diff suppressed because one or more lines are too long
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2635d61c9807d6c46bcb00a3d8645b37
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) [year] [fullname]
|
Copyright (c) 2024 Edgegap
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -9,17 +9,35 @@ This plugin is intended to help you:
|
|||||||
|
|
||||||
This plugin does not need to be included in your builds, as it's only a development tool and does not have any runtime features.
|
This plugin does not need to be included in your builds, as it's only a development tool and does not have any runtime features.
|
||||||
|
|
||||||
## Install the plugin in Unity
|
## Install using git (recommended)
|
||||||
|
### Benefits
|
||||||
|
- Installing our plugin this way will ensure you get the freshest updates the moment they come out, see [the update guide](#update-the-plugin-in-unity).
|
||||||
|
|
||||||
|
### Caveats
|
||||||
|
- Requirement: functioning git client installed, for example [git-scm](https://git-scm.com/).
|
||||||
|
|
||||||
|
### Instructions
|
||||||
1. Open your Unity project,
|
1. Open your Unity project,
|
||||||
2. Select toolbar option **Window** -> **Package Manager**,
|
2. Select toolbar option **Window** -> **Package Manager**,
|
||||||
3. Click the **+** icon and select **Add package from git URL...**,
|
3. Click the **+** icon and select **Add package from git URL...**,
|
||||||
4. Input the following URL `https://github.com/edgegap/edgegap-unity-plugin.git`,
|
4. Input the following URL `https://github.com/edgegap/edgegap-unity-plugin.git`,
|
||||||
5. Click **Add** and wait for the Unity Package Manager to complete the installation.
|
5. Click **Add** and wait for the Unity Package Manager to complete the installation.
|
||||||
|
|
||||||
Once you have it, check for **Edgegap** -> **Edgegap Hosting** in Unity's top menu.
|
## Install via ZIP archive
|
||||||
|
### Benefits
|
||||||
|
- Slightly easier as no git client is required.
|
||||||
|
|
||||||
From here, we recommend following our [Unity Plugin Guide](https://docs.edgegap.com/docs/tools-and-integrations/unity-plugin-guide) to get your first dedicated server deployed.
|
### Caveats
|
||||||
|
- Installing our plugin this way will require you to manually replace plugin contents if you [wish to update it](#update-the-plugin-in-unity),
|
||||||
|
- The newtonsoft package (dependency) version required may not be compatible with your project if you're already using an older version of this package.
|
||||||
|
|
||||||
|
### Instructions
|
||||||
|
1. Select toolbar option **Window** -> **Package Manager**,
|
||||||
|
2. Click the **+** icon and select **Add package by name...**,
|
||||||
|
3. Input the name `com.unity.nuget.newtonsoft-json` and wait for the Unity Package Manager to complete the installation.,
|
||||||
|
4. Back to this github project - make sure you're on the `main` branch,
|
||||||
|
5. Click **<> Code**, then **Download ZIP**,
|
||||||
|
6. Paste the contents of the unzipped archive in your `Assets` folder within Unity project root.
|
||||||
|
|
||||||
## Other sources
|
## Other sources
|
||||||
|
|
||||||
@ -29,6 +47,14 @@ The only other official distribution channels for this plugin are:
|
|||||||
|
|
||||||
**WARNING!** The [Edgegap plugin published on Unity Asset Store](https://assetstore.unity.com/packages/tools/network/edgegap-game-server-hosting-212563) is outdated and not supported anymore. If you've previously installed our plugin by another method than described above, please remove any Edgegap files or dependencies related before updating your plugin using the git URL.
|
**WARNING!** The [Edgegap plugin published on Unity Asset Store](https://assetstore.unity.com/packages/tools/network/edgegap-game-server-hosting-212563) is outdated and not supported anymore. If you've previously installed our plugin by another method than described above, please remove any Edgegap files or dependencies related before updating your plugin using the git URL.
|
||||||
|
|
||||||
## Update the Plugin in Unity
|
## Next Steps
|
||||||
|
|
||||||
In order to update our plugin, locate it in Unity's **Package Manager** window and click **Update**. Wait for the process to complete and you're good to go!
|
Once you have it, check for **Tools** -> **Edgegap Hosting** in Unity's top menu.
|
||||||
|
|
||||||
|
From here, we recommend following our [Unity Plugin Guide](https://docs.edgegap.com/docs/tools-and-integrations/unity-plugin-guide) to get your first dedicated server deployed.
|
||||||
|
|
||||||
|
### Update the Plugin in Unity
|
||||||
|
|
||||||
|
If you've installed using git, to update our plugin, locate it in Unity's **Package Manager** window and click **Update**. Wait for the process to complete and you're good to go!
|
||||||
|
|
||||||
|
If you've installed by copying, you will have to remove the Edgegap folder and paste the newer copy. Your settings are saved in your Unity version, so they shouldn't be lost in this process.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 34ed2e392924a4517b1410d21bbcdcb7
|
guid: a22cebde73b10534b99d20367fda7b1f
|
||||||
TextScriptImporter:
|
TextScriptImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
userData:
|
userData:
|
||||||
|
6
Assets/Mirror/Hosting/Edgegap/_MIRROR_README.md
Normal file
6
Assets/Mirror/Hosting/Edgegap/_MIRROR_README.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
Notes for Mirror integration:
|
||||||
|
|
||||||
|
-> Plugin needs to be zip drop in instead of package manager dependency:
|
||||||
|
because Asset Store doesn't allow Github dependencies.
|
||||||
|
|
||||||
|
-> We have a few MIRROR CHANGES in the code for fixes / compatibility.
|
@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 57002d60dd8ce46b081a0a0a25e5b52b
|
guid: 3f90e0819d5bc416c8da96885fcc9b72
|
||||||
TextScriptImporter:
|
TextScriptImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
userData:
|
userData:
|
21
Assets/Mirror/Hosting/Edgegap/package.json
Normal file
21
Assets/Mirror/Hosting/Edgegap/package.json
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"name": "com.edgegap.unity-servers-plugin",
|
||||||
|
"version": "1.0.8",
|
||||||
|
"displayName": "Edgegap Servers Quickstart",
|
||||||
|
"description": "Get started quickly with Edgegap Dedicated Server hosting.",
|
||||||
|
"unity": "2021.3",
|
||||||
|
"unityRelease": "0f1",
|
||||||
|
"documentationUrl": "https://docs.edgegap.com/docs/tools-and-integrations/unity-plugin-guide",
|
||||||
|
"changelogUrl": "https://github.com/edgegap/edgegap-unity-plugin/releases",
|
||||||
|
"licensesUrl": "https://choosealicense.com/licenses/mit/",
|
||||||
|
"dependencies": {
|
||||||
|
"com.unity.nuget.newtonsoft-json": "3.2.1",
|
||||||
|
"com.unity.toolchain.win-x86_64-linux-x86_64": "2.0.6",
|
||||||
|
"com.unity.modules.uielements": "1.0.0"
|
||||||
|
},
|
||||||
|
"author": {
|
||||||
|
"name": "Edgegap Technologies",
|
||||||
|
"email": "contact@edgegap.com",
|
||||||
|
"url": "https://www.edgegap.com"
|
||||||
|
}
|
||||||
|
}
|
7
Assets/Mirror/Hosting/Edgegap/package.json.meta
Normal file
7
Assets/Mirror/Hosting/Edgegap/package.json.meta
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 92c00ff489f816847b08e40fa333ae7c
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
Loading…
Reference in New Issue
Block a user