wip network refactor
This commit is contained in:
12
Source/Game/GameMode/GameMode.cs
Normal file
12
Source/Game/GameMode/GameMode.cs
Normal 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
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
54
Source/Game/GameMode/Messages/WelcomePlayerMessage.cs
Normal file
54
Source/Game/GameMode/Messages/WelcomePlayerMessage.cs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace Game
|
|||||||
if (!listenServer)
|
if (!listenServer)
|
||||||
{
|
{
|
||||||
Cleanup();
|
Cleanup();
|
||||||
GameModeManager.Init();
|
WorldStateManager.Init();
|
||||||
}
|
}
|
||||||
ServerAddress = serverAddress;
|
ServerAddress = serverAddress;
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
@@ -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)
|
||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user