This commit is contained in:
SepComet
2026-04-06 11:58:36 +08:00
parent b1b38b485e
commit aebc4011c7
84 changed files with 5796 additions and 238 deletions
@@ -8,6 +8,8 @@ namespace Network.NetworkHost
public float TurnSpeedDegreesPerSecond { get; set; } = 180f;
public TimeSpan SimulationInterval { get; set; } = TimeSpan.FromMilliseconds(50);
public TimeSpan BroadcastInterval { get; set; } = TimeSpan.FromMilliseconds(50);
public int DefaultHp { get; set; } = 100;
@@ -24,6 +26,11 @@ namespace Network.NetworkHost
throw new ArgumentOutOfRangeException(nameof(TurnSpeedDegreesPerSecond), "Turn speed must be finite and non-negative.");
}
if (SimulationInterval <= TimeSpan.Zero)
{
throw new ArgumentOutOfRangeException(nameof(SimulationInterval), "Simulation interval must be positive.");
}
if (BroadcastInterval <= TimeSpan.Zero)
{
throw new ArgumentOutOfRangeException(nameof(BroadcastInterval), "Broadcast interval must be positive.");
@@ -17,6 +17,7 @@ namespace Network.NetworkHost
private readonly IAuthoritativeMovementWorldValidator worldValidator;
private readonly Dictionary<string, ServerAuthoritativeMovementState> statesByPeer = new();
private long nextBroadcastTick = 1;
private TimeSpan accumulatedSimulationTime;
private TimeSpan accumulatedBroadcastTime;
public ServerAuthoritativeMovementCoordinator(
@@ -31,6 +32,8 @@ namespace Network.NetworkHost
this.worldValidator = worldValidator ?? throw new ArgumentNullException(nameof(worldValidator));
}
public TimeSpan SimulationInterval => configuration.SimulationInterval;
public IReadOnlyList<ServerAuthoritativeMovementState> States
{
get
@@ -153,25 +156,30 @@ namespace Network.NetworkHost
lock (gate)
{
foreach (var state in statesByPeer.Values)
accumulatedSimulationTime += elapsed;
while (accumulatedSimulationTime >= configuration.SimulationInterval)
{
IntegrateState(state, elapsed);
}
accumulatedBroadcastTime += elapsed;
while (accumulatedBroadcastTime >= configuration.BroadcastInterval)
{
accumulatedBroadcastTime -= configuration.BroadcastInterval;
pendingBroadcasts ??= new List<PendingBroadcast>();
accumulatedSimulationTime -= configuration.SimulationInterval;
foreach (var state in statesByPeer.Values)
{
state.LastBroadcastTick = nextBroadcastTick;
pendingBroadcasts.Add(new PendingBroadcast(
state.RemoteEndPoint,
BuildPlayerState(state, nextBroadcastTick)));
IntegrateState(state, configuration.SimulationInterval);
}
nextBroadcastTick++;
accumulatedBroadcastTime += configuration.SimulationInterval;
while (accumulatedBroadcastTime >= configuration.BroadcastInterval)
{
accumulatedBroadcastTime -= configuration.BroadcastInterval;
pendingBroadcasts ??= new List<PendingBroadcast>();
foreach (var state in statesByPeer.Values)
{
state.LastBroadcastTick = nextBroadcastTick;
pendingBroadcasts.Add(new PendingBroadcast(
state.RemoteEndPoint,
BuildPlayerState(state, nextBroadcastTick)));
}
nextBroadcastTick++;
}
}
}
@@ -299,6 +307,7 @@ namespace Network.NetworkHost
lock (gate)
{
statesByPeer.Clear();
accumulatedSimulationTime = TimeSpan.Zero;
accumulatedBroadcastTime = TimeSpan.Zero;
}
}
@@ -460,7 +469,8 @@ namespace Network.NetworkHost
Z = state.VelocityZ
},
Rotation = state.Rotation,
Hp = state.Hp
Hp = state.Hp,
AcknowledgedMoveTick = state.LastAcceptedMoveTick
};
}
@@ -71,6 +71,8 @@ namespace Network.NetworkHost
public MultiSessionManager SessionCoordinator { get; }
public TimeSpan AuthoritativeMovementCadence => authoritativeMovementCoordinator.SimulationInterval;
public IReadOnlyList<ManagedNetworkSession> ManagedSessions => SessionCoordinator.Sessions;
public IReadOnlyList<ServerAuthoritativeMovementState> AuthoritativeMovementStates => authoritativeMovementCoordinator.States;
@@ -21,6 +21,8 @@ namespace Network.NetworkHost
public bool IsRunning { get; private set; }
public TimeSpan AuthoritativeMovementCadence => host.AuthoritativeMovementCadence;
public IReadOnlyList<ManagedNetworkSession> ManagedSessions => host.ManagedSessions;
public IReadOnlyList<ServerAuthoritativeMovementState> AuthoritativeMovementStates => host.AuthoritativeMovementStates;