From ddcf2ff24f78ef4a8ff5c3b09c1887660b83ddec Mon Sep 17 00:00:00 2001 From: Ari Vuollet Date: Fri, 23 Feb 2024 15:42:38 +0200 Subject: [PATCH] _wip net --- .../EngineSettings/GraphicsSettings.json | 11 +-- Source/Game/GameMode/NetworkManager.cs | 67 +++++++++++++++---- Source/Game/GameMode/NetworkManager_Client.cs | 13 ++-- Source/Game/GameMode/NetworkManager_Demo.cs | 8 +-- Source/Game/GameMode/NetworkManager_Server.cs | 11 +-- Source/Game/GameMode/WorldStateManager.cs | 50 ++++++++------ 6 files changed, 109 insertions(+), 51 deletions(-) diff --git a/Content/Settings/EngineSettings/GraphicsSettings.json b/Content/Settings/EngineSettings/GraphicsSettings.json index a4965d6..dee610e 100644 --- a/Content/Settings/EngineSettings/GraphicsSettings.json +++ b/Content/Settings/EngineSettings/GraphicsSettings.json @@ -1,7 +1,7 @@ { "ID": "f94d5aae457aeba67033a8a4ca753214", "TypeName": "FlaxEditor.Content.Settings.GraphicsSettings", - "EngineBuild": 6340, + "EngineBuild": 6407, "Data": { "UseVSync": false, "AAQuality": 3, @@ -31,11 +31,11 @@ }, "GI": { "OverrideFlags": 63, - "Mode": 1, + "Mode": 0, "Intensity": 1.0, "BounceIntensity": 1.0, - "TemporalResponse": 0.9, - "Distance": 20000.0, + "TemporalResponse": 0.0, + "Distance": 4000.0, "FallbackIrradiance": { "R": 1.0, "G": 0.0, @@ -287,6 +287,7 @@ "PostFxMaterials": { "Materials": null } - } + }, + "FallbackFonts": null } } \ No newline at end of file diff --git a/Source/Game/GameMode/NetworkManager.cs b/Source/Game/GameMode/NetworkManager.cs index d2d82f1..351c12b 100644 --- a/Source/Game/GameMode/NetworkManager.cs +++ b/Source/Game/GameMode/NetworkManager.cs @@ -1,7 +1,9 @@ using System; +using System.Collections.Generic; using System.Linq; using FlaxEditor; using FlaxEngine; +using FlaxEngine.Assertions; using FlaxEngine.Networking; using Console = Game.Console; @@ -41,11 +43,37 @@ namespace Game 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 + private static List OnClientMessageDelegates = new(3); + private static List OnServerMessageDelegates = new(3); + + public static void RegisterClientMessageCallback(OnMessageDecl deleg) + { + Assert.IsTrue(!OnClientMessageDelegates.Contains(deleg)); + OnClientMessageDelegates.Add(deleg); + } + public static void UnregisterClientMessageCallback(OnMessageDecl deleg) + { + Assert.IsTrue(OnClientMessageDelegates.Contains(deleg)); + OnClientMessageDelegates.Remove(deleg); + } + + public static void RegisterServerMessageCallback(OnMessageDecl deleg) + { + Assert.IsTrue(!OnServerMessageDelegates.Contains(deleg)); + OnServerMessageDelegates.Add(deleg); + } + public static void UnregisterServerMessageCallback(OnMessageDecl deleg) + { + Assert.IsTrue(OnServerMessageDelegates.Contains(deleg)); + OnServerMessageDelegates.Remove(deleg); + } + + public static string DebugLastHandledMessage = ""; + + //public static bool IsServer = false; + //public static bool IsClient = false; + // static bool IsLocalClient = false; // Context dependant, true when message is handled by local client public static void Init() { @@ -107,14 +135,18 @@ namespace Game Editor.Instance.PlayModeEnd -= Cleanup; //GameModeManager.Cleanup(); // FIXME #endif - //WorldStateManager.Cleanup(); // FIXME + if (clientWorldStateManager != null) + { + clientWorldStateManager.Cleanup(); + clientWorldStateManager = null; + } StopRecording(); initialized = false; } - private static void OnNetworkMessage(ref NetworkEvent networkEvent) + private static void OnNetworkMessage(ref NetworkEvent networkEvent, Span funcs) { byte messageTypeByte = networkEvent.Message.ReadByte(); if (!Enum.IsDefined(typeof(NetworkMessageType), messageTypeByte)) @@ -135,15 +167,28 @@ namespace Game } case NetworkMessageType.Message: { - if (OnMessage != null) - foreach (OnMessageDecl func in OnMessage.GetInvocationList() - .Cast().ToArray()) + var messageStartPosition = networkEvent.Message.Position; + foreach (var func in funcs) + { + networkEvent.Message.Position = messageStartPosition; + bool handled = func(ref networkEvent); + if (handled) + break; + } + + //if (OnMessage != null) + /*{ + // GetInvocationList() allocates, use allocation-free but unsafe way to iterate + // + //foreach (OnMessageDecl func in OnMessage.GetInvocationList() + // .Cast().ToArray()) + foreach (OnMessageDecl func in OnMessageDelegates) { bool ret = func.Invoke(ref networkEvent); if (ret) break; } - + }*/ break; } default: @@ -151,7 +196,5 @@ namespace Game break; } } - - } } \ No newline at end of file diff --git a/Source/Game/GameMode/NetworkManager_Client.cs b/Source/Game/GameMode/NetworkManager_Client.cs index cae1e04..2938874 100644 --- a/Source/Game/GameMode/NetworkManager_Client.cs +++ b/Source/Game/GameMode/NetworkManager_Client.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Runtime.InteropServices; using FlaxEngine; using FlaxEngine.Networking; using Console = Game.Console; @@ -79,14 +80,14 @@ namespace Game try { - IsLocalClient = server != null; - IsClient = true; + //IsLocalClient = server != null; + //IsClient = true; OnClientReadMessage(ref networkEvent); } finally { - IsLocalClient = false; - IsClient = false; + //IsLocalClient = false; + //IsClient = false; if (networkEvent.EventType == NetworkEventType.Message) client.RecycleMessage(networkEvent.Message); } @@ -120,7 +121,7 @@ namespace Game } case NetworkEventType.Message: { - OnNetworkMessage(ref networkEvent); + OnNetworkMessage(ref networkEvent, CollectionsMarshal.AsSpan(OnClientMessageDelegates)); if (networkEvent.Message.Position > 0 && networkEvent.Message.Position < networkEvent.Message.Length) @@ -146,6 +147,8 @@ namespace Game default: throw new ArgumentOutOfRangeException(); } + + DebugLastHandledMessage = ""; } private static void OnClientActorSpawned(Actor actor) diff --git a/Source/Game/GameMode/NetworkManager_Demo.cs b/Source/Game/GameMode/NetworkManager_Demo.cs index 3099829..25f6ebc 100644 --- a/Source/Game/GameMode/NetworkManager_Demo.cs +++ b/Source/Game/GameMode/NetworkManager_Demo.cs @@ -261,14 +261,14 @@ namespace Game // TODO: change/randomize Sender.ConnectionId? try { - IsLocalClient = server != null; - IsClient = true; + //IsLocalClient = server != null; + //IsClient = true; OnClientReadMessage(ref demoEvent); } finally { - IsLocalClient = false; - IsClient = false; + //IsLocalClient = false; + //IsClient = false; //TODO: recycle event? } diff --git a/Source/Game/GameMode/NetworkManager_Server.cs b/Source/Game/GameMode/NetworkManager_Server.cs index 9197c5b..4bc34c7 100644 --- a/Source/Game/GameMode/NetworkManager_Server.cs +++ b/Source/Game/GameMode/NetworkManager_Server.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; +using System.Runtime.InteropServices; using FlaxEngine; using FlaxEngine.Networking; using Console = Game.Console; @@ -137,7 +138,7 @@ namespace Game Console.Print($"Client({networkEvent.Sender.ConnectionId}) is trying to connect"); try { - IsServer = true; + //IsServer = true; if (serverWorldStateManager.OnClientConnecting(networkEvent.Sender)) { ConnectedClients.Add(networkEvent.Sender); @@ -151,7 +152,7 @@ namespace Game } finally { - IsServer = false; + //IsServer = false; } break; @@ -169,8 +170,8 @@ namespace Game { try { - IsServer = true; - OnNetworkMessage(ref networkEvent); + //IsServer = true; + OnNetworkMessage(ref networkEvent, CollectionsMarshal.AsSpan(OnServerMessageDelegates)); if (networkEvent.Message.Position > 0 && networkEvent.Message.Position < networkEvent.Message.Length) @@ -194,7 +195,7 @@ namespace Game } finally { - IsServer = false; + //IsServer = false; server.RecycleMessage(networkEvent.Message); } break; diff --git a/Source/Game/GameMode/WorldStateManager.cs b/Source/Game/GameMode/WorldStateManager.cs index ab05f38..3f1ed6e 100644 --- a/Source/Game/GameMode/WorldStateManager.cs +++ b/Source/Game/GameMode/WorldStateManager.cs @@ -17,6 +17,8 @@ namespace Game PlayerInput, PlayerPosition, // world update PlayerSnapshot, // send world state delta to client since last client's acknowledged frame + + LastMessageType = 128, } @@ -88,7 +90,10 @@ namespace Game clientWorldState = new WorldState(); gameMode = new GameMode(); - NetworkManager.OnMessage += OnMessage; + if (IsServer) + NetworkManager.RegisterServerMessageCallback(OnMessage); + else + NetworkManager.RegisterClientMessageCallback(OnMessage); Level.SceneLoaded += OnLevelLoaded; //Scripting.LateUpdate += OnLateUpdatePre; Scripting.LateFixedUpdate += OnLateUpdatePre; @@ -96,7 +101,11 @@ namespace Game public void Cleanup() { - NetworkManager.OnMessage -= OnMessage; + if (IsServer) + NetworkManager.UnregisterServerMessageCallback(OnMessage); + else + NetworkManager.UnregisterClientMessageCallback(OnMessage); + Level.SceneLoaded -= OnLevelLoaded; //Scripting.LateUpdate -= OnLateUpdatePre; Scripting.LateFixedUpdate -= OnLateUpdatePre; @@ -129,22 +138,22 @@ namespace Game { try { - NetworkManager.IsServer = NetworkManager.server != null; - NetworkManager.IsClient = (NetworkManager.client != null || NetworkManager.IsDemoPlaying) && NetworkManager.server == null; - NetworkManager.IsLocalClient = (NetworkManager.client != null || NetworkManager.IsDemoPlaying) && NetworkManager.server != null; + //NetworkManager.IsServer = NetworkManager.server != null; + //NetworkManager.IsClient = (NetworkManager.client != null || NetworkManager.IsDemoPlaying) && NetworkManager.server == null; + //NetworkManager.IsLocalClient = (NetworkManager.client != null || NetworkManager.IsDemoPlaying) && NetworkManager.server != null; OnLateUpdate(); } finally { - NetworkManager.IsServer = false; - NetworkManager.IsClient = false; - NetworkManager.IsLocalClient = false; + //NetworkManager.IsServer = false; + //NetworkManager.IsClient = false; + //NetworkManager.IsLocalClient = false; } } public void OnLateUpdate() { - if (NetworkManager.IsServer) + if (IsServer) { foreach (KeyValuePair kv in players) { @@ -217,7 +226,7 @@ namespace Game } } - if (NetworkManager.IsClient || NetworkManager.IsLocalClient) + if (IsClient || IsLocalClient) { //if (!welcomed) // return; @@ -264,7 +273,7 @@ namespace Game NetworkManager.ClientEndSendMessage(ref message); }*/ } - else if (NetworkManager.IsLocalClient) + else if (IsLocalClient) { } @@ -312,6 +321,7 @@ namespace Game } GameModeMessageType messageType = (GameModeMessageType)messageTypeByte; + NetworkManager.DebugLastHandledMessage = messageType.ToString(); //Console.Print($"GameModeManager: {messageType}"); switch (messageType) @@ -319,10 +329,10 @@ namespace Game case GameModeMessageType.WelcomePlayer: { welcomed = true; - if (NetworkManager.IsClient || NetworkManager.IsLocalClient) + if (IsClient || IsLocalClient) { WelcomePlayerMessage welcomePlayer = WelcomePlayerMessage.Read(ref networkEvent.Message); - if (!NetworkManager.IsLocalClient) + if (!IsLocalClient) serverWorldState.frame = welcomePlayer.frame; //lastReceivedServerFrame = welcomePlayer.frame; clientWorldState.frame += welcomePlayer.frame; @@ -429,7 +439,7 @@ namespace Game break; } - if (NetworkManager.IsClient) + if (IsClient) { if (reportedPlayerId == NetworkManager.LocalPlayerClientId) lastReceivedServerFrame = reportedFrame; @@ -443,12 +453,12 @@ namespace Game { PlayerInput playerInput = playerActor.GetScript().input; - if (NetworkManager.IsLocalClient && reportedPlayerId == NetworkManager.LocalPlayerClientId) + if (IsLocalClient && reportedPlayerId == NetworkManager.LocalPlayerClientId) { } else playerInput.SetState(reportedFrame, inputState, actorState); - if (!NetworkManager.IsLocalClient && playerInput is PlayerInputNetwork) + if (!IsLocalClient && playerInput is PlayerInputNetwork) { playerActor.Position = actorState.position; playerActor.GetScript().movementState.currentVelocity = actorState.velocity; @@ -550,10 +560,10 @@ namespace Game private void SpawnPlayer(uint playerId, Float3 position, Vector3 eulerAngles) { - if (NetworkManager.IsServer && !playerLastFrame.ContainsKey(playerId)) + if (IsServer && !playerLastFrame.ContainsKey(playerId)) playerLastFrame.Add(playerId, serverWorldState.frame); - if (NetworkManager.IsLocalClient && playerId == NetworkManager.LocalPlayerClientId) + if (IsLocalClient && playerId == NetworkManager.LocalPlayerClientId) return; // Handled by listenserver //spawned = true; @@ -571,8 +581,8 @@ namespace Game players.Add(playerId, null); players[playerId] = playerActor; PlayerInput playerInput = playerActor.GetScript().input; - playerInput.frame = (NetworkManager.IsServer) ? serverWorldState.frame : ClientFrame; - if (NetworkManager.IsServer) + playerInput.frame = IsServer ? serverWorldState.frame : ClientFrame; + if (IsServer) { serverWorldState.actors.Add(playerActor); if (!playerLastReceivedFrames.ContainsKey(playerId))