This commit is contained in:
2024-02-23 15:42:38 +02:00
parent 22391dd2bd
commit ddcf2ff24f
6 changed files with 109 additions and 51 deletions

View File

@@ -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<OnMessageDecl> OnClientMessageDelegates = new(3);
private static List<OnMessageDecl> 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<OnMessageDecl> 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<OnMessageDecl>().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<OnMessageDecl>().ToArray())
foreach (OnMessageDecl func in OnMessageDelegates)
{
bool ret = func.Invoke(ref networkEvent);
if (ret)
break;
}
}*/
break;
}
default:
@@ -151,7 +196,5 @@ namespace Game
break;
}
}
}
}

View File

@@ -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)

View File

@@ -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?
}

View File

@@ -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;

View File

@@ -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<uint,PlayerActor> 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<PlayerMovement>().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<PlayerMovement>().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<PlayerMovement>().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))