using System.Collections; using System.Collections.Generic; using UltraCombos; using UnityEngine; using UnityEngine.Networking; // Host Migration // https://docs.unity3d.com/Manual/UNetHostMigration.html // Remote Actions // https://docs.unity3d.com/Manual/UNetActions.html public class NetworkManagerControl : NetworkManager { public enum NetworkType { SERVER, HOST, CLIENT, SHADOW } [Header("Manager Control")] public NetworkType networkType; public bool autoConnect = false; public bool netDiscovery = false; public bool netMigration = false; float connect_stamp = 0.0f; bool showGUI = false; protected string module = "Network Manager"; private void Start() { if (Misc.GetCommandLineArgument("-server")) { networkType = NetworkType.SERVER; } else if (Misc.GetCommandLineArgument("-host")) { networkType = NetworkType.HOST; } else if (Misc.GetCommandLineArgument("-client")) { networkType = NetworkType.CLIENT; } else if (Misc.GetCommandLineArgument("-shadow")) { networkType = NetworkType.SHADOW; } string input; if (Misc.GetCommandLineArgument("-id", out input)) { int res; if (int.TryParse(input, out res)) { } } if (Misc.GetCommandLineArgument("-address", out input)) { networkAddress = input; Misc.Verbose(module, string.Format("-address {0}", input)); } else if (networkType == NetworkType.SERVER || networkType == NetworkType.HOST) { networkAddress = GetLocalIPAddress(); Misc.Verbose(module, string.Format("Get Local IP Address: {0}", networkAddress)); } if (netDiscovery) { var discovery_ctrl = gameObject.AddComponent(); discovery_ctrl.broadcastPort = networkPort + 10000; discovery_ctrl.showGUI = false; discovery_ctrl.Initialize(); if (networkType == NetworkType.CLIENT || networkType == NetworkType.SHADOW) discovery_ctrl.StartAsClient(); else if (networkType == NetworkType.SERVER || networkType == NetworkType.HOST) discovery_ctrl.StartAsServer(); } var hud = GetComponent(); if (hud != null) hud.showGUI = showGUI; var nmmc = GetComponent(); if (netMigration) { if (nmmc == null) nmmc = gameObject.AddComponent(); } if (nmmc != null) { nmmc.hostMigration = netMigration; nmmc.showGUI = showGUI; } connect_stamp = -(connectionConfig.ConnectTimeout / 100); } private void Update() { if (Input.GetKeyDown(KeyCode.F2)) { showGUI = !showGUI; var hud = GetComponent(); if (hud != null) hud.showGUI = showGUI; var nmm = GetComponent(); if (nmm != null) nmm.showGUI = showGUI; } if (isNetworkActive == false && autoConnect) { float dt = Time.time - connect_stamp; if (dt > connectionConfig.ConnectTimeout / 100) { ResetConnectStamp(); switch (networkType) { case NetworkType.SERVER: StartServer(); break; case NetworkType.HOST: StartHost(); break; case NetworkType.CLIENT: StartClient(); break; case NetworkType.SHADOW: StartClient(); break; } } } if (NetworkServer.active) { ServerUpdate(); } else if (NetworkClient.active) { ClientUpdate(); } } protected virtual void ServerUpdate() { } protected virtual void ClientUpdate() { } void ResetConnectStamp() { connect_stamp = Time.time; } //------------------------------ Start & Stop callbacks ----------------------------------- // Since there are multiple versions of StartServer, StartClient and StartHost, to reliably customize // their functionality, users would need override all the versions. Instead these callbacks are invoked // from all versions, so users only need to implement this one case. public override void OnStartHost() { Misc.Verbose(module, "OnStartHost"); networkType = NetworkType.HOST; ResetConnectStamp(); } public override void OnStartServer() { Misc.Verbose(module, "OnStartServer"); networkType = NetworkType.SERVER; ResetConnectStamp(); } public override void OnStartClient(NetworkClient client) { Misc.Verbose(module, "OnStartClient"); if (NetworkServer.active) { networkType = NetworkType.HOST; } else { networkType = NetworkType.CLIENT; } ResetConnectStamp(); } public override void OnStopServer() { Misc.Verbose(module, "OnStopServer"); ResetConnectStamp(); } public override void OnStopClient() { Misc.Verbose(module, "OnStopClient"); ResetConnectStamp(); } public override void OnStopHost() { Misc.Verbose(module, "OnStopHost"); ResetConnectStamp(); } private void OnGUI() { if (showGUI == false) return; int xpos = 10; int ypos = 10; int width = 300; int height = 20; const int spacing = 24; string msg = ""; msg = string.Format("Network Type: {0}", networkType); GUI.Label(new Rect(xpos, ypos, width, height), msg); ypos += spacing; msg = string.Format("{0}:{1}", networkAddress, networkPort); GUI.Label(new Rect(xpos, ypos, width, height), msg); ypos += spacing; if (NetworkServer.active) { var connections = NetworkServer.connections; msg = string.Format("NetworkServer.connections: {0}", connections.Count); GUI.Label(new Rect(xpos, ypos, width, height), msg); ypos += spacing; foreach (var conn in connections) { if (conn == null) { msg = string.Format("\tConn: null"); } else { msg = string.Format("\tConn: {0} ({1})", conn.connectionId, conn.address); } GUI.Label(new Rect(xpos, ypos, width, height), msg); ypos += spacing; } msg = string.Format("NetworkServer.objects: {0}", NetworkServer.objects.Count); GUI.Label(new Rect(xpos, ypos, width, height), msg); ypos += spacing; foreach (var id in NetworkServer.objects.Keys) { var identity = NetworkServer.objects[id]; msg = string.Format("\tNetId: {0}", id); GUI.Label(new Rect(xpos, ypos, width, height), msg); ypos += spacing; } } else if (NetworkClient.active) { msg = string.Format("ClientScene.objects: {0}", ClientScene.objects.Count); GUI.Label(new Rect(xpos, ypos, width, height), msg); ypos += spacing; foreach (var id in ClientScene.objects.Keys) { var identity = ClientScene.objects[id]; msg = string.Format("\tNetId: {0}", id); GUI.Label(new Rect(xpos, ypos, width, height), msg); ypos += spacing; } } var hud = GetComponent(); if (hud != null) hud.offsetY = ypos; else { var nmm = GetComponent(); if (nmm != null) nmm.offsetY = ypos; } } protected NetworkIdentity GetLocalPlayer() { #if true var objects = FindObjectsOfType(); foreach (var obj in objects) { if (obj.isLocalPlayer) return obj; } #else Dictionary objects; objects = NetworkServer.active ? NetworkServer.objects : ClientScene.objects; foreach (var id in objects.Keys) { var identity = objects[id]; if (identity.isLocalPlayer) return identity; } #endif return null; } protected string GetLocalIPAddress() { var host = System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName()); foreach (var ip in host.AddressList) { if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) { return ip.ToString(); } } throw new System.Exception("Local IP Address Not Found!"); } }