fix: 修复 spec 与实现的多处差异

- CombatEvent Hit 消息的 Damage 字段改为传递 configuration.DamagePerShot
- SyncSequenceTracker MoveInput streamKey 改为只按 playerId 追踪
- 登录成功后新增 AuthoritativeCombatState bootstrap 逻辑
- 更新 network-gameplay-message-types spec 字段命名以匹配实际 proto 定义
This commit is contained in:
SepComet
2026-04-07 20:42:18 +08:00
parent 2c46012800
commit b7c003f227
4 changed files with 46 additions and 7 deletions
@@ -42,6 +42,29 @@ namespace Network.NetworkHost
}
}
public void BootstrapState(IPEndPoint remoteEndPoint, string playerId, int hp, bool isDead)
{
if (remoteEndPoint == null || string.IsNullOrWhiteSpace(playerId))
{
return;
}
var key = Normalize(remoteEndPoint).ToString();
lock (gate)
{
if (statesByPeer.ContainsKey(key))
{
return;
}
statesByPeer.Add(key, new ServerAuthoritativeCombatState(
Normalize(remoteEndPoint),
playerId,
hp,
isDead));
}
}
public Task HandleShootInputAsync(byte[] payload, IPEndPoint sender)
{
if (payload == null || sender == null)
@@ -95,7 +118,7 @@ namespace Network.NetworkHost
EventType = CombatEventType.Hit,
AttackerId = attackerState.PlayerId,
TargetId = targetState.PlayerId,
Damage = 0,
Damage = configuration.DamagePerShot,
HitPosition = hitPosition
}, MessageType.CombatEvent);
@@ -284,6 +284,7 @@ namespace Network.NetworkHost
RememberPlayerId(remoteEndPoint, playerId);
SessionCoordinator.NotifyLoginSucceeded(remoteEndPoint);
BootstrapAuthoritativeMovementState(remoteEndPoint, speed);
BootstrapAuthoritativeCombatState(remoteEndPoint, playerId);
PublishMetricsSessionSnapshot(remoteEndPoint);
}
@@ -382,6 +383,21 @@ namespace Network.NetworkHost
authoritativeMovementCoordinator.EnsureState(remoteEndPoint, playerId, speed, out _);
}
private void BootstrapAuthoritativeCombatState(IPEndPoint remoteEndPoint, string playerId)
{
if (!TryGetKnownPlayerId(remoteEndPoint, out var resolvedPlayerId))
{
return;
}
if (!authoritativeMovementCoordinator.TryGetState(remoteEndPoint, out var movementState))
{
return;
}
authoritativeCombatCoordinator.BootstrapState(remoteEndPoint, resolvedPlayerId, movementState.Hp, movementState.IsDead);
}
private void RememberPlayerId(IPEndPoint remoteEndPoint, string playerId)
{
if (remoteEndPoint == null || string.IsNullOrWhiteSpace(playerId))