using System; using System.Linq; using FlaxEditor; using FlaxEngine; using FlaxEngine.Networking; using Console = Game.Console; namespace Game { [AttributeUsage(AttributeTargets.Class)] public class NetworkPredictedAttribute : Attribute { } // TODO: insert code to update variables with this attribute? // rename to NetworkReplicatedAttribute? [AttributeUsage(AttributeTargets.Class)] public class NetworkedAttribute : Attribute { } // NetworkMulticastAttribute: calls methods marked with this in all clients public enum NetworkMessageType : byte { Handshake = 1, Message } public static partial class NetworkManager { public delegate bool OnMessageDecl(ref NetworkEvent networkEvent); private static bool initialized; public static NetworkPeer server; public static NetworkPeer client; private static readonly ushort ServerPort = 59183; private static string ServerAddress; private static readonly ushort MTU = 1500; private static readonly ushort MaximumClients = 32; public static OnMessageDecl OnMessage; public static bool IsServer = false; public static bool IsClient = false; public static bool IsLocalClient = false; // Context dependant, true when message is handled by local client public static void Init() { if (initialized) return; /*if (Engine.CommandLine.Contains("-server")) { StartServer(); ServerAddress = "localhost"; ConnectServer(); } else if (Engine.CommandLine.Contains("-client")) { ServerAddress = "localhost"; ConnectServer(); } //#if FLAX_EDITOR else { StartServer(); ServerAddress = "localhost"; ConnectServer(); }*/ //#endif initialized = true; #if FLAX_EDITOR Editor.Instance.PlayModeEnd += Cleanup; #endif GameModeManager.Init(); // FIXME } public static void Cleanup() { if (server != null) { Scripting.FixedUpdate -= OnServerUpdate; Scripting.Exit -= Cleanup; Level.ActorSpawned -= OnServerActorSpawned; NetworkPeer.ShutdownPeer(server); server = null; } if (client != null) { Scripting.FixedUpdate -= OnClientUpdate; Scripting.Exit -= Cleanup; Level.ActorSpawned -= OnClientActorSpawned; NetworkPeer.ShutdownPeer(client); client = null; } #if FLAX_EDITOR Editor.Instance.PlayModeEnd -= Cleanup; GameModeManager.Cleanup(); // FIXME #endif initialized = false; } private static void OnNetworkMessage(ref NetworkEvent networkEvent) { byte messageTypeByte = networkEvent.Message.ReadByte(); if (!Enum.IsDefined(typeof(NetworkMessageType), messageTypeByte)) { Console.PrintError($"Unsupported message type received from client: {messageTypeByte}"); return; } NetworkMessageType messageType = (NetworkMessageType)messageTypeByte; switch (messageType) { case NetworkMessageType.Handshake: { string message = networkEvent.Message.ReadString(); Console.Print($"Received handshake from {networkEvent.Sender.ConnectionId}, msg: " + message); break; } case NetworkMessageType.Message: { if (OnMessage != null) foreach (OnMessageDecl func in OnMessage.GetInvocationList() .Cast().ToArray()) { bool ret = func.Invoke(ref networkEvent); if (ret) break; } break; } default: Console.PrintError($"Unsupported message type received from client: {messageTypeByte}"); break; } } } }