Skip to content
Snippets Groups Projects
CommunicationEvents.cs 11.7 KiB
Newer Older
  • Learn to ignore specific revisions
  • using System.Collections;
    using System.Collections.Generic;
    
    using System.Diagnostics;
    
    using System.Linq;
    
    using UnityEngine;
    using UnityEngine.Events;
    
    using UnityEngine.Networking;
    
    
    public static class CommunicationEvents
    {
    
    ki7077's avatar
    ki7077 committed
        public static UnityEvent<RaycastHit[]> TriggerEvent = new();
    
        public static UnityEvent<RaycastHit[]> TriggerModFireEvent = new();
    
        public static UnityEvent<int> ToolModeChangedEvent = new();
        public static UnityEvent<Fact> AddFactEvent = new();
        public static UnityEvent<Fact> RemoveFactEvent = new();
    
    Richard Marcus's avatar
    Richard Marcus committed
    
    
        public static UnityEvent gameSucceededEvent = new();
        public static UnityEvent gameNotSucceededEvent = new();
    
        public static UnityEvent StartT0Event = new();
    
        /** <summary>Inform ui that it should animate the given fact with the given material.</summary> */
    
        public static UnityEvent<string, FactWrapper.FactMaterials> AnimateExistingFactEvent = new();
    
        /** <summary>Start firework and invoke AnimateExistingFactEvent.</summary> */
    
        public static UnityEvent<Fact, FactWrapper.FactMaterials> AnimateExistingAsSolutionEvent = new();
    
        /** <summary>Show a missing fact for a short time as hint for the user.</summary> */
    
        public static UnityEvent<Fact> AnimateNonExistingFactEvent = new();
    
    John Schihada's avatar
    John Schihada committed
    
        //------------------------------------------------------------------------------------
        //-------------------------------Global Variables-------------------------------------
    
        public static bool ServerAutoStart = true;
    
        public static bool ServerRunning = true;
    
    MaZiFAU's avatar
    MaZiFAU committed
    
    
        //CHANGE HERE PORT OF SERVER
    
        public static readonly string ServerPortDefault = "8085"; //used for Local
        public static readonly string ServerAddressLocal = "localhost:" + ServerPortDefault; // there is currently never a reason to change this.
        public static string ServerAdress = "http://localhost:8085"; //need "http://" //used by displayScrolls.cs //http://10.231.4.95:8085"; //IMPORTANT for MAINMENU
    
        public static Process process_mmt_frameIT_server;
    
    
        public static int ToolID_new;
        public static int ToolID_selected;//Script
    
    MaZiFAU's avatar
    MaZiFAU committed
    
    
        /// <summary>
        /// The Servers stored in NetworkJSON, as an enum to have consistent names.<br/>
        /// Why are <see cref="ServerSlot.last"/>,<see cref="ServerSlot.newIP"/> and 
        /// <see cref="ServerSlot.selecIP"/> in here? Historical Reasons^TM <br/>
        /// If one wants to optimize things, it is likely advisable to make them variables instead. 
        /// But this also requires changing the read/write of NetworkJSON, and likely more ...
        /// </summary>
        [System.Serializable]
        public enum ServerSlot
        {// The numbers are due to legacy code, specifically ServerRunningA indices
    
            last = 1,
            newIP = 2,
            slot1 = 3,
            slot2 = 4,
            slot3 = 5,
            selecIP = 6,
            slot4 = 7,
            slot5 = 8,
            localServer
    
        }
    
        /// <summary>
        /// The status of a <c>ServerSlot</c> in <see cref="ServerSlots"/>
        /// </summary>
        public enum ServerStatus
        {// The numbers are due to legacy code, specifically ServerRunningA values
    
            offline = 0,
            online = 2,
            checking = 1,
            NoNetworkAddress = 3
    
        }
    
        /// <summary>
        /// All data to a Server stored in a Server
        /// </summary>
        public class ServerSlotData
    
    baletiballo's avatar
    baletiballo committed
        {
    
            public string domain;
    
    baletiballo's avatar
    baletiballo committed
            public ServerStatus currentStatus = ServerStatus.offline;
    
            public bool hasBeenChecked = false;
    
    baletiballo's avatar
    baletiballo committed
    
    
            //Define constructor via expression body definition
            public ServerSlotData(string serverURL) => domain = serverURL;
    
    baletiballo's avatar
    baletiballo committed
    
    
            /// <summary>
            /// Ping the server to see if it is online.
            /// Start as a <c>Coroutine</c>, because this involves a <c>WebRequest</c>
            /// </summary>
    
            public IEnumerator UpdateServerStatus(bool skipIfAlreadyChecked = false)
    
    baletiballo's avatar
    baletiballo committed
            {
    
                if (skipIfAlreadyChecked && hasBeenChecked)
    
                    yield break; // Skip, if not neccessary
    
                currentStatus = ServerStatus.checking;
                ServerSlot myKey = ServerSlots.FirstOrDefault(x => x.Value == this).Key;
    
                if (string.IsNullOrEmpty(domain))
    
                    currentStatus = ServerStatus.NoNetworkAddress;
                    UnityEngine.Debug.LogWarning("Server " + myKey.ToString() + " has no network adress.");
    
                    UnityWebRequest request = UnityWebRequest.Get("http://" + domain + "/fact/list");
                    yield return request.SendWebRequest();
    
                    if (request.result == UnityWebRequest.Result.Success)
                    {
                        currentStatus = ServerStatus.online;
                    }
                    else
                    {
                        UnityEngine.Debug.Log("Couldn't connect to Server " + myKey.ToString() + " under " + domain + " : " + request.error + "\n");
                        currentStatus = ServerStatus.offline;
    
                        //try again
                        //request.Dispose();
                        //request = pingMMTServer(NetwAddress);
                        //yield return request.SendWebRequest();
                        //request.Dispose();
    
                    }
                    request.Dispose();
    
                // To keep ServerRunningA updated. Delete if you saved the world from that abomination
    
                ServerRunningA[(int)myKey] = (int)currentStatus;
    
        /// Gather the <see cref="ServerSlotData"/> of all <see cref="ServerSlot"/> in one place, so one can iterate over all of them.<br/>
        /// <remarks><list type="bullet">
        /// <item><seealso cref="LastIP"/>, <seealso cref="SelecIP"/> and alike offer more compact access to the domains.</item>
        /// <item>Accessing other data in this Dict is kind of ugly, but I cannot think of a much better way to implement it, as it shoud be iteratable and indexable.</item>
        /// </list> </remarks> 
    
        /// </summary>
        public static Dictionary<ServerSlot, ServerSlotData> ServerSlots = new()
    
    baletiballo's avatar
    baletiballo committed
        {
    
            { ServerSlot.last, new ServerSlotData("") },
            { ServerSlot.newIP, new ServerSlotData("") },
            { ServerSlot.slot1, new ServerSlotData("- if you can read this") },
            { ServerSlot.slot2, new ServerSlotData("- NetworkConfig") },
            { ServerSlot.slot3, new ServerSlotData("- GO TO -> 'Options'") },
            { ServerSlot.slot4, new ServerSlotData("-   -> 'Reset Options'") },
            { ServerSlot.slot5, new ServerSlotData("-   -> PRESS: 'Reset Configurations'") },
    
            { ServerSlot.selecIP, new ServerSlotData("") },
            { ServerSlot.localServer, new ServerSlotData(ServerAddressLocal) }
    
        /// <summary>
        /// Iterate over all members of <see cref="ServerSlots"/> and have them update their <see cref="ServerSlotData.currentStatus"/><br/>
        /// <br/>
        /// Currently it is not possible to only load the domains via <see cref="StreamingAssetLoader.NetworkJSON_Load_x(string)"/>. If this changes, it might make sense to call the initial loading of the domains from in here. 
        /// </summary>
        public static IEnumerator UpdateAllServers()
        {
            foreach (ServerSlotData server in ServerSlots.Values)
            {
                yield return server.UpdateServerStatus();
            }
        }
    
    
    baletiballo's avatar
    baletiballo committed
    
        //Enum.GetNames(typeof(KnownServers)).Length; //Number of known Server slots, to be able to add more later
    
    
         * will be loaded from other config file,
         * and I am not going to refactor all of this as well, so just an indirection.
         * 
         * LastIP and SelecIP are likely useful shortcuts to the most relevant parts of 'ServerSlots' above, anyway.
    
         * (Also those are domain names (+ port) not IPs)
    
        public static string LastIP { get => ServerSlots[ServerSlot.last].domain; set => ServerSlots[ServerSlot.last].domain = value; }
        public static string NewIP { get => ServerSlots[ServerSlot.newIP].domain; set => ServerSlots[ServerSlot.newIP].domain = value; }
        public static string IPslot1 { get => ServerSlots[ServerSlot.slot1].domain; set => ServerSlots[ServerSlot.slot1].domain = value; }
        public static string IPslot2 { get => ServerSlots[ServerSlot.slot2].domain; set => ServerSlots[ServerSlot.slot2].domain = value; }
        public static string IPslot3 { get => ServerSlots[ServerSlot.slot3].domain; set => ServerSlots[ServerSlot.slot3].domain = value; }
        public static string IPslot4 { get => ServerSlots[ServerSlot.slot4].domain; set => ServerSlots[ServerSlot.slot4].domain = value; }
        public static string IPslot5 { get => ServerSlots[ServerSlot.slot5].domain; set => ServerSlots[ServerSlot.slot5].domain = value; }
        public static string SelecIP { get => ServerSlots[ServerSlot.selecIP].domain; set => ServerSlots[ServerSlot.selecIP].domain = value; }
    
        /// <summary>
        /// IF YOU NEED THIS DATA, USE THE <see cref="ServerSlotData.currentStatus"/> OF THE <see cref="ServerSlots"/> MEMBERS.<br/>
        /// Holds the status of the stored Servers.<br/>
        /// This is acts like a function <see cref="ServerSlot"/> -> <see cref="ServerStatus"/> with a dont-care value at index 0.<br/>
        /// There are so many references to this abomination that I will leave it here and just update it, to be consistent with 
        /// <see cref="ServerSlots"/>.
        /// </summary>
    
        public static int[] ServerRunningA = new int[10] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    
        //other, lastIP, newIP, IP1, IP2, IP3, selecIP, IP4, IP5,...} 
        //0: offline, 1: Checking, 2: online, 3: NoNetworkAddress;
    
        public static bool autoOSrecognition = true;
    
        public static OperationSystem Opsys = OperationSystem.Windows; //Scripts
    
        public enum OperationSystem
        {
    
    MaZiFAU's avatar
    MaZiFAU committed
            Windows = 0,
            Android = 1,
    
            iOS = 2,
    
            WindowsStoreApps = 3,
    
        public static bool CursorVisDefault = true; //Script.
    
        public static bool CursorVisLastUsedIngame = true; //Script.
    
        public static bool GadgetCanBeUsed = false;
    
        // Configs
        public static bool VerboseURI = false;
    
            FactStateMachines,
        }
    
        public static string CreateHierarchiePath(List<Directories> hierarchie, string prefix = "", string postfix = "")
        {
            foreach (var dir in hierarchie)
    
                prefix = Path.Combine(prefix, dir.ToString());
    
            return Path.Combine(prefix, postfix);
    
    
        public static string Get_DataPath()
        {
    
            if (Application.isEditor)
    
                return use_replacementfolder ? Path.Combine(Application.persistentDataPath, "DataPath_writeable") : Path.Combine(Application.dataPath, "StreamingAssets", "StreamToDataPath_withHandler");
    
            return Opsys switch
    
                OperationSystem.Android => Path.Combine(Application.persistentDataPath, "DataPath_writeable"),
    
                OperationSystem.Windows or _ => Application.dataPath,
    
        // TODO! avoid tree traversel with name
    
        public static string CreatePathToFile(out bool file_exists, string name, string format = null, List<Directories> hierarchie = null, bool use_install_folder = false)
    
            if (!string.IsNullOrEmpty(format))
    
                switch (format)
                {
                    case "JSON":
                        ending = ".JSON";
                        break;
                    default:
                        break;
                }
    
    
            string path = use_install_folder
                ? Get_DataPath()
                : Application.persistentDataPath;
    
            if (hierarchie != null)
            {
                path = CreateHierarchiePath(hierarchie, path);
    
                Directory.CreateDirectory(path);
    
            path = Path.Combine(path, name + ending);
            file_exists = File.Exists(path);
    
            return path;