Files
GoakeFlax/Source/Game/Network/NetworkManager_Server.cs
2022-05-02 20:34:42 +03:00

134 lines
4.8 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using FlaxEngine;
using FlaxEngine.Networking;
using Console = Cabrito.Console;
using Debug = FlaxEngine.Debug;
namespace Game
{
public static partial class NetworkManager
{
private static List<NetworkConnection> ConnectedClients;
private static List<Type> NetworkedTypes;
public static bool StartServer()
{
ConnectedClients = new List<NetworkConnection>(MaximumClients);
server = NetworkPeer.CreatePeer(new NetworkConfig
{
NetworkDriver = FlaxEngine.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 += Deinitialize;
Level.ActorSpawned += OnClientActorSpawned;
NetworkedTypes = new List<Type>();
AppDomain currentDomain = AppDomain.CurrentDomain;
Assembly[] assemblies = currentDomain.GetAssemblies();
foreach (var assembly in assemblies)
{
// Skip common assemblies
var 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 (var 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 var _ = Utilities.ProfileScope("NetworkManager_OnServerUpdate");
while (server.PopEvent(out NetworkEvent eventData))
{
switch (eventData.EventType)
{
case NetworkEventType.Connected:
{
Console.Print($"Client({eventData.Sender.ConnectionId}) connected!");
ConnectedClients.Add(eventData.Sender);
Console.Print("Connected clients: " + ConnectedClients.Count);
// Send hello message to the client back
{
var sendmessage = server.BeginSendMessage();
sendmessage.WriteString($"Welcome, ({eventData.Sender.ConnectionId})");
server.EndSendMessage(NetworkChannelType.Reliable, sendmessage, eventData.Sender);
}
break;
}
case NetworkEventType.Disconnected:
case NetworkEventType.Timeout:
{
Console.Print($"Client({eventData.Sender.ConnectionId}) disconnected!");
ConnectedClients.Remove(eventData.Sender);
Console.Print("Connected clients: " + ConnectedClients.Count);
break;
}
case NetworkEventType.Message:
{
// Read the message contents
var message = eventData.Message;
var messageData = message.ReadString();
Console.Print($"Received message from Client({eventData.Sender.ConnectionId}): {messageData}");
server.RecycleMessage(message);
break;
}
default:
throw new ArgumentOutOfRangeException();
}
}
}
private static void OnServerActorSpawned(Actor actor)
{
Console.Print($"actor spawned: {actor.Name} ({actor.TypeName})");
}
}
}