wip network refactor

This commit is contained in:
2023-12-31 16:03:26 +02:00
parent dd5a86a8b7
commit 03810705bd
8 changed files with 108 additions and 50 deletions

View File

@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Game;
internal class GameMode
{
}

View File

@@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FlaxEngine.Networking;
using FlaxEngine;
namespace Game;
public struct WelcomePlayerMessage
{
public struct PlayerInfo
{
public uint playerId;
public Float3 playerPosition;
}
public ulong frame;
public float time;
public PlayerInfo[] players;
public static WelcomePlayerMessage Read(ref NetworkMessage networkMessage)
{
WelcomePlayerMessage packet = new WelcomePlayerMessage();
packet.frame = networkMessage.ReadUInt64();
packet.time = networkMessage.ReadSingle();
int numActors = (int)networkMessage.ReadUInt32();
packet.players = new PlayerInfo[numActors];
for (int i = 0; i < numActors; i++)
{
packet.players[i].playerId = networkMessage.ReadUInt32();
packet.players[i].playerPosition.X = networkMessage.ReadSingle();
packet.players[i].playerPosition.Y = networkMessage.ReadSingle();
packet.players[i].playerPosition.Z = networkMessage.ReadSingle();
}
return packet;
}
public void Write(ref NetworkMessage networkMessage)
{
networkMessage.WriteByte((byte)GameModeMessageType.WelcomePlayer);
networkMessage.WriteUInt64(frame);
networkMessage.WriteSingle(time);
networkMessage.WriteUInt32((uint)players.Length);
foreach (PlayerInfo player in players)
{
networkMessage.WriteUInt32(player.playerId);
networkMessage.WriteSingle(player.playerPosition.X);
networkMessage.WriteSingle(player.playerPosition.Y);
networkMessage.WriteSingle(player.playerPosition.Z);
}
}
}

View File

@@ -77,7 +77,7 @@ namespace Game
Editor.Instance.PlayModeEnd += Cleanup; Editor.Instance.PlayModeEnd += Cleanup;
#endif #endif
GameModeManager.Init(); // FIXME WorldStateManager.Init(); // FIXME
} }
public static void Cleanup() public static void Cleanup()
@@ -107,7 +107,7 @@ namespace Game
Editor.Instance.PlayModeEnd -= Cleanup; Editor.Instance.PlayModeEnd -= Cleanup;
//GameModeManager.Cleanup(); // FIXME //GameModeManager.Cleanup(); // FIXME
#endif #endif
GameModeManager.Cleanup(); // FIXME WorldStateManager.Cleanup(); // FIXME
StopRecording(); StopRecording();

View File

@@ -18,7 +18,7 @@ namespace Game
if (!listenServer) if (!listenServer)
{ {
Cleanup(); Cleanup();
GameModeManager.Init(); WorldStateManager.Init();
} }
ServerAddress = serverAddress; ServerAddress = serverAddress;

View File

@@ -38,7 +38,7 @@ namespace Game
{ {
{ {
Cleanup(); Cleanup();
GameModeManager.Init(); WorldStateManager.Init();
} }
if (!ReadDemo(demoName)) if (!ReadDemo(demoName))
@@ -112,7 +112,7 @@ namespace Game
Length = networkEvent.Message.Length, Length = networkEvent.Message.Length,
MessageId = networkEvent.Message.MessageId, MessageId = networkEvent.Message.MessageId,
}; };
MemoryMarshal.Write(bytes, ref header); MemoryMarshal.Write(bytes, header);
demoStream.Write(bytes); demoStream.Write(bytes);
Span<byte> messageBytes = new Span<byte>(networkEvent.Message.Buffer, (int)networkEvent.Message.Length); Span<byte> messageBytes = new Span<byte>(networkEvent.Message.Buffer, (int)networkEvent.Message.Length);

View File

@@ -79,7 +79,7 @@ namespace Game
foreach (Type type in NetworkedTypes) foreach (Type type in NetworkedTypes)
Console.Print("tracking networked type: " + type.Name); Console.Print("tracking networked type: " + type.Name);
#endif #endif
GameModeManager.Init(); WorldStateManager.Init();
if (listenServer) if (listenServer)
return ConnectServer(listenServer: true); return ConnectServer(listenServer: true);
@@ -98,7 +98,6 @@ namespace Game
server.EndSendMessage(channelType, message, connection); server.EndSendMessage(channelType, message, connection);
} }
public static void ServerEndSendMessage(ref NetworkMessage message, NetworkConnection[] connections, NetworkChannelType channelType = NetworkChannelType.Reliable) public static void ServerEndSendMessage(ref NetworkMessage message, NetworkConnection[] connections, NetworkChannelType channelType = NetworkChannelType.Reliable)
{ {
server.EndSendMessage(channelType, message, connections); server.EndSendMessage(channelType, message, connections);
@@ -133,17 +132,16 @@ namespace Game
case NetworkEventType.Connected: case NetworkEventType.Connected:
{ {
Console.Print($"Client({networkEvent.Sender.ConnectionId}) is trying to connect"); Console.Print($"Client({networkEvent.Sender.ConnectionId}) is trying to connect");
try try
{ {
IsServer = true; IsServer = true;
if (GameModeManager.OnClientConnecting(networkEvent.Sender)) if (WorldStateManager.OnClientConnecting(networkEvent.Sender))
{ {
ConnectedClients.Add(networkEvent.Sender); ConnectedClients.Add(networkEvent.Sender);
Console.Print( Console.Print(
$"Client({networkEvent.Sender.ConnectionId}) connected. Total clients: {ConnectedClients.Count}"); $"Client({networkEvent.Sender.ConnectionId}) connected. Total clients: {ConnectedClients.Count}");
GameModeManager.OnClientConnected(networkEvent.Sender); WorldStateManager.OnClientConnected(networkEvent.Sender);
} }
else else
Console.Print($"Client({networkEvent.Sender.ConnectionId}) connection refused"); Console.Print($"Client({networkEvent.Sender.ConnectionId}) connection refused");

View File

@@ -12,7 +12,7 @@ namespace Game
{ {
public enum GameModeMessageType : byte public enum GameModeMessageType : byte
{ {
WelcomePlayer, WelcomePlayer, // WelcomePlayerMessage
SpawnPlayer, SpawnPlayer,
PlayerInput, PlayerInput,
PlayerPosition, // world update PlayerPosition, // world update
@@ -21,7 +21,7 @@ namespace Game
public static class GameModeManager public static class WorldStateManager //FIXME: remove static for better init/cleanup
{ {
private class WorldState private class WorldState
{ {
@@ -51,6 +51,7 @@ namespace Game
private static WorldState serverWorldState; private static WorldState serverWorldState;
private static WorldState clientWorldState; private static WorldState clientWorldState;
private static GameMode gameMode;
private static ulong lastReceivedServerFrame = 0; private static ulong lastReceivedServerFrame = 0;
public static ulong ServerFrame => /*NetworkManager.server != null ? serverWorldState.frame :*/ lastReceivedServerFrame; public static ulong ServerFrame => /*NetworkManager.server != null ? serverWorldState.frame :*/ lastReceivedServerFrame;
@@ -71,6 +72,7 @@ namespace Game
playerLastFrame = new Dictionary<uint, ulong>(); playerLastFrame = new Dictionary<uint, ulong>();
serverWorldState = new WorldState(); serverWorldState = new WorldState();
clientWorldState = new WorldState(); clientWorldState = new WorldState();
gameMode = new GameMode();
NetworkManager.OnMessage += OnMessage; NetworkManager.OnMessage += OnMessage;
Level.SceneLoaded += OnLevelLoaded; Level.SceneLoaded += OnLevelLoaded;
@@ -295,28 +297,21 @@ namespace Game
welcomed = true; welcomed = true;
if (NetworkManager.IsClient || NetworkManager.IsLocalClient) if (NetworkManager.IsClient || NetworkManager.IsLocalClient)
{ {
var serverFrame = networkEvent.Message.ReadUInt64(); WelcomePlayerMessage welcomePlayer = WelcomePlayerMessage.Read(ref networkEvent.Message);
if (!NetworkManager.IsLocalClient) if (!NetworkManager.IsLocalClient)
serverWorldState.frame = serverFrame; serverWorldState.frame = welcomePlayer.frame;
//lastReceivedServerFrame = serverFrame; //lastReceivedServerFrame = welcomePlayer.frame;
clientWorldState.frame += serverFrame; clientWorldState.frame += welcomePlayer.frame;
ClientTime = networkEvent.Message.ReadSingle(); ClientTime = welcomePlayer.time;
int numActors = (int)networkEvent.Message.ReadUInt32(); foreach (var playerInfo in welcomePlayer.players)
for (int i = 0; i < numActors; i++)
{ {
uint playerId = networkEvent.Message.ReadUInt32(); SpawnPlayer(playerInfo.playerId, playerInfo.playerPosition, new Float3(0));
Float3 playerPosition;
playerPosition.X = networkEvent.Message.ReadSingle();
playerPosition.Y = networkEvent.Message.ReadSingle();
playerPosition.Z = networkEvent.Message.ReadSingle();
SpawnPlayer(playerId, playerPosition, new Float3(0));
var playerFrames = new PlayerFrame[120]; var playerFrames = new PlayerFrame[120];
for (int j = 0; j < playerFrames.Length; j++) for (int j = 0; j < playerFrames.Length; j++)
playerFrames[j] = new PlayerFrame(); playerFrames[j] = new PlayerFrame();
clientWorldState.playerFrameHistory.Add(playerId, playerFrames); clientWorldState.playerFrameHistory.Add(playerInfo.playerId, playerFrames);
} }
Console.Print("received welcome: frame " + serverWorldState.frame); Console.Print("received welcome: frame " + serverWorldState.frame);
@@ -324,7 +319,6 @@ namespace Game
if (!players.ContainsKey(NetworkManager.LocalPlayerClientId)) // listen server if (!players.ContainsKey(NetworkManager.LocalPlayerClientId)) // listen server
players.Add(NetworkManager.LocalPlayerClientId, null); players.Add(NetworkManager.LocalPlayerClientId, null);
//playerConnections.Add(NetworkManager.LocalPlayerClientId, connection); //playerConnections.Add(NetworkManager.LocalPlayerClientId, connection);
} }
break; break;
} }
@@ -458,17 +452,17 @@ namespace Game
//if (connection.ConnectionId != NetworkManager.LocalPlayerClientId) //if (connection.ConnectionId != NetworkManager.LocalPlayerClientId)
{ {
Console.Print("sending welcome: frame " + serverWorldState.frame); Console.Print("sending welcome: frame " + serverWorldState.frame);
NetworkMessage message = NetworkManager.ServerBeginSendMessage(); WelcomePlayerMessage welcomeMessage = new WelcomePlayerMessage();
message.WriteByte((byte)GameModeMessageType.WelcomePlayer); welcomeMessage.frame = serverWorldState.frame;
message.WriteUInt64(serverWorldState.frame); welcomeMessage.time = ServerTime;
message.WriteSingle(ServerTime); welcomeMessage.players = new WelcomePlayerMessage.PlayerInfo[serverWorldState.actors.Count];
message.WriteUInt32((uint)serverWorldState.actors.Count);
foreach (PlayerActor playerActor in serverWorldState.actors) for (int i = 0; i < serverWorldState.actors.Count; i++)
{ {
message.WriteUInt32(playerActor.GetScript<PlayerMovement>().PlayerId); PlayerActor playerActor = serverWorldState.actors[i];
message.WriteSingle(playerActor.Position.X); ref WelcomePlayerMessage.PlayerInfo playerInfo = ref welcomeMessage.players[i];
message.WriteSingle(playerActor.Position.Y); playerInfo.playerId = playerActor.GetScript<PlayerMovement>().PlayerId;
message.WriteSingle(playerActor.Position.Z); playerInfo.playerPosition = playerActor.Position;
playerActor.GetScript<PlayerMovement>().input.SetState(serverWorldState.frame, new PlayerInputState(), new PlayerActorState() playerActor.GetScript<PlayerMovement>().input.SetState(serverWorldState.frame, new PlayerInputState(), new PlayerActorState()
{ {
@@ -482,8 +476,9 @@ namespace Game
//onGround = playerActor.GetScript<PlayerMovement>().movementState.onGround, //onGround = playerActor.GetScript<PlayerMovement>().movementState.onGround,
}); });
} }
NetworkMessage message = NetworkManager.ServerBeginSendMessage();
welcomeMessage.Write(ref message);
NetworkManager.ServerEndSendMessage(ref message, connection); NetworkManager.ServerEndSendMessage(ref message, connection);
} }
return true; return true;
} }
@@ -561,7 +556,6 @@ namespace Game
} }
} }
private static void UpdatePlayerInput(uint playerId, PlayerInputState inputState) private static void UpdatePlayerInput(uint playerId, PlayerInputState inputState)
{ {
if (playerId == NetworkManager.LocalPlayerClientId) if (playerId == NetworkManager.LocalPlayerClientId)

View File

@@ -444,10 +444,10 @@ namespace Game
//viewAngles = viewAnglesLastFrame; //viewAngles = viewAnglesLastFrame;
bool canpredict = true; bool canpredict = true;
if (true && input.Predict /*&& !NetworkManager.IsDemoPlaying*/ && GameModeManager.ClientFrame > 0 && GameModeManager.ServerFrame > 0) if (true && input.Predict /*&& !NetworkManager.IsDemoPlaying*/ && WorldStateManager.ClientFrame > 0 && WorldStateManager.ServerFrame > 0)
{ {
ulong currentFrame = GameModeManager.ServerFrame; ulong currentFrame = WorldStateManager.ServerFrame;
for (; currentFrame < GameModeManager.ClientFrame; currentFrame++) for (; currentFrame < WorldStateManager.ClientFrame; currentFrame++)
{ {
if (!input.GetState(currentFrame, out var pastInputState, out var pastActorState)) if (!input.GetState(currentFrame, out var pastInputState, out var pastActorState))
{ {
@@ -469,7 +469,7 @@ namespace Game
predicting = true; predicting = true;
currentFrame = GameModeManager.ServerFrame; currentFrame = WorldStateManager.ServerFrame;
for (; currentFrame < lastFrame; currentFrame++) for (; currentFrame < lastFrame; currentFrame++)
{ {
if (!input.GetState(currentFrame, out var pastInputState, out var pastActorState)) if (!input.GetState(currentFrame, out var pastInputState, out var pastActorState))
@@ -481,7 +481,7 @@ namespace Game
if (currentFrame == inputState.frame) if (currentFrame == inputState.frame)
movementState.jumped = movementState.jumped; movementState.jumped = movementState.jumped;
if (currentFrame == GameModeManager.ServerFrame) if (currentFrame == WorldStateManager.ServerFrame)
{ {
movementState.position = pastActorState.position; movementState.position = pastActorState.position;
movementState.currentVelocity = pastActorState.velocity; movementState.currentVelocity = pastActorState.velocity;
@@ -891,8 +891,8 @@ namespace Game
if (false) if (false)
{ {
if (GameModeManager.ServerFrame > 0 && GameModeManager.ClientFrame > 0) if (WorldStateManager.ServerFrame > 0 && WorldStateManager.ClientFrame > 0)
for (ulong frame = GameModeManager.ServerFrame; frame < GameModeManager.ClientFrame; frame++) for (ulong frame = WorldStateManager.ServerFrame; frame < WorldStateManager.ClientFrame; frame++)
{ {
if (!input.GetState(frame, out var pastInputState, out var pastActorState)) if (!input.GetState(frame, out var pastInputState, out var pastActorState))
continue; continue;
@@ -902,7 +902,7 @@ namespace Game
Float4 color1 = new Float4(Color.Red.R, Color.Red.G, Color.Red.B, Color.Red.A); Float4 color1 = new Float4(Color.Red.R, Color.Red.G, Color.Red.B, Color.Red.A);
Float4 color2 = new Float4(Color.Blue.R, Color.Blue.G, Color.Blue.B, Color.Blue.A); Float4 color2 = new Float4(Color.Blue.R, Color.Blue.G, Color.Blue.B, Color.Blue.A);
Float4 color3 = Float4.Lerp(color1, color2, (float)(frame - GameModeManager.ServerFrame) / (float)(GameModeManager.ClientFrame - GameModeManager.ServerFrame)); Float4 color3 = Float4.Lerp(color1, color2, (float)(frame - WorldStateManager.ServerFrame) / (float)(WorldStateManager.ClientFrame - WorldStateManager.ServerFrame));
Color color = new Color(color3.X, color3.Y, color3.Z, color3.W); Color color = new Color(color3.X, color3.Y, color3.Z, color3.W);
DebugDraw.DrawBox(bbox, color * 1f); DebugDraw.DrawBox(bbox, color * 1f);
} }
@@ -910,7 +910,7 @@ namespace Game
else else
{ {
var serverBbox = boxCollider.OrientedBox.GetBoundingBox(); var serverBbox = boxCollider.OrientedBox.GetBoundingBox();
if (input.GetState(GameModeManager.ServerFrame, out var serverInputState, out var serverActorState)) if (input.GetState(WorldStateManager.ServerFrame, out var serverInputState, out var serverActorState))
serverBbox.Center = serverActorState.position; serverBbox.Center = serverActorState.position;
if (serverBbox.Center == clientBbox.Center) if (serverBbox.Center == clientBbox.Center)
@@ -1159,7 +1159,7 @@ namespace Game
public void SimulatePlayerMovement(PlayerInputState inputState) public void SimulatePlayerMovement(PlayerInputState inputState)
{ {
simulationTime = GameModeManager.ClientTime + (inputState.frame * (1.0f / Time.PhysicsFPS)); simulationTime = WorldStateManager.ClientTime + (inputState.frame * (1.0f / Time.PhysicsFPS));
Vector3 inputDirection = Vector3 inputDirection =
new Float3(inputState.moveRight, 0.0f, inputState.moveForward); new Float3(inputState.moveRight, 0.0f, inputState.moveForward);