using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using FlaxEngine; using FlaxEngine.Networking; using Console = Cabrito.Console; using Object = FlaxEngine.Object; namespace Game { public static partial class NetworkManager { private static List ConnectedClients; private static List NetworkedTypes; public static bool StartServer() { ConnectedClients = new List(MaximumClients); server = NetworkPeer.CreatePeer(new NetworkConfig { NetworkDriver = Object.New(typeof(ENetDriver)), ConnectionsLimit = MaximumClients, MessagePoolSize = 2048, MessageSize = MTU, Address = "any", Port = ServerPort }); if (!server.Listen()) { Console.PrintError("Failed to start the server."); return false; } Scripting.FixedUpdate += OnServerUpdate; Scripting.Exit += Cleanup; Level.ActorSpawned += OnServerActorSpawned; NetworkedTypes = new List(); AppDomain currentDomain = AppDomain.CurrentDomain; var assemblies = currentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { // Skip common assemblies string assemblyName = assembly.GetName().Name; if (assemblyName == "System" || assemblyName.StartsWith("System.") || assemblyName.StartsWith("Mono.") || assemblyName == "mscorlib" || assemblyName == "Newtonsoft.Json" || assemblyName.StartsWith("FlaxEngine.") || assemblyName.StartsWith("JetBrains.") || assemblyName.StartsWith("Microsoft.") || assemblyName.StartsWith("nunit.")) continue; foreach (Type type in assembly.GetTypes()) if (type.GetCustomAttributes().Any(x => x is NetworkedAttribute)) NetworkedTypes.Add(type); } foreach (Type type in NetworkedTypes) Console.Print("tracking networked type: " + type.Name); return true; } private static void OnServerUpdate() { using Utilities.ScopeProfiler _ = Utilities.ProfileScope("NetworkManager_OnServerUpdate"); while (server.PopEvent(out NetworkEvent networkEvent)) switch (networkEvent.EventType) { case NetworkEventType.Connected: { Console.Print($"Client({networkEvent.Sender.ConnectionId}) connected!"); ConnectedClients.Add(networkEvent.Sender); Console.Print("Connected clients: " + ConnectedClients.Count); // Send hello message to the client back { NetworkMessage sendmessage = server.BeginSendMessage(); sendmessage.WriteByte((byte)NetworkMessageType.Message); //sendmessage.WriteString($"Welcome, ({networkEvent.Sender.ConnectionId})"); server.EndSendMessage(NetworkChannelType.Reliable, sendmessage, networkEvent.Sender); } break; } case NetworkEventType.Disconnected: case NetworkEventType.Timeout: { Console.Print($"Client({networkEvent.Sender.ConnectionId}) disconnected!"); ConnectedClients.Remove(networkEvent.Sender); Console.Print("Connected clients: " + ConnectedClients.Count); break; } case NetworkEventType.Message: { OnNetworkMessage(networkEvent); server.RecycleMessage(networkEvent.Message); break; } default: throw new ArgumentOutOfRangeException(); } } private static void OnServerActorSpawned(Actor actor) { //Console.Print($"actor spawned: {actor.Name} ({actor.TypeName})"); } } }