Orgnize
This commit is contained in:
parent
3446dcd6f1
commit
a1ede230bb
|
|
@ -5,7 +5,8 @@
|
|||
"Bash(openspec status:*)",
|
||||
"Bash(openspec instructions:*)",
|
||||
"Bash(dotnet build:*)",
|
||||
"Bash(dotnet test:*)"
|
||||
"Bash(dotnet test:*)",
|
||||
"Bash(dotnet Temp/Bin/Debug/Network.EditMode.Tests/Network.EditMode.Tests.dll)"
|
||||
]
|
||||
},
|
||||
"outputStyle": "default"
|
||||
|
|
|
|||
|
|
@ -1,22 +1,60 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Network.Defines;
|
||||
|
||||
namespace Network.NetworkApplication
|
||||
{
|
||||
/// <summary>
|
||||
/// Resolves the delivery policy for each <see cref="MessageType"/>.
|
||||
/// Policies are intentionally explicit here so that adding a new <see cref="MessageType"/>
|
||||
/// requires an intentional decision rather than silently falling through to a default.
|
||||
/// </summary>
|
||||
public sealed class DefaultMessageDeliveryPolicyResolver : IMessageDeliveryPolicyResolver
|
||||
{
|
||||
private static readonly IReadOnlyDictionary<MessageType, DeliveryPolicy> DefaultPolicies =
|
||||
private static readonly IReadOnlyDictionary<MessageType, DeliveryPolicy> Policies =
|
||||
new Dictionary<MessageType, DeliveryPolicy>
|
||||
{
|
||||
// High-frequency sync lane: latest-wins, stale-drop.
|
||||
// These messages are sent every frame and a stale value is never useful.
|
||||
{ MessageType.MoveInput, DeliveryPolicy.HighFrequencySync },
|
||||
{ MessageType.PlayerState, DeliveryPolicy.HighFrequencySync }
|
||||
{ MessageType.PlayerState, DeliveryPolicy.HighFrequencySync },
|
||||
|
||||
// Reliable ordered lane: guaranteed delivery, ordered.
|
||||
// ShootInput carries player intent; losing or reordering it changes gameplay outcomes.
|
||||
{ MessageType.ShootInput, DeliveryPolicy.ReliableOrdered },
|
||||
|
||||
// CombatEvent is a server-authoritative result; clients must receive it reliably
|
||||
// and in order to maintain consistent HP/death state.
|
||||
{ MessageType.CombatEvent, DeliveryPolicy.ReliableOrdered },
|
||||
|
||||
// PlayerJoin carries spawn data that the client needs to instantiate a player.
|
||||
// Reliable ordered ensures the client receives it before gameplay begins.
|
||||
{ MessageType.PlayerJoin, DeliveryPolicy.ReliableOrdered },
|
||||
|
||||
// Login/logout are session-control messages that must not be lost or reordered.
|
||||
{ MessageType.LoginRequest, DeliveryPolicy.ReliableOrdered },
|
||||
{ MessageType.LoginResponse, DeliveryPolicy.ReliableOrdered },
|
||||
{ MessageType.LogoutRequest, DeliveryPolicy.ReliableOrdered },
|
||||
|
||||
// Heartbeat carries server tick used for clock sync; a missing sample is
|
||||
// simply a lost sample — no value in stale delivery.
|
||||
{ MessageType.Heartbeat, DeliveryPolicy.ReliableOrdered },
|
||||
{ MessageType.HeartbeatResponse, DeliveryPolicy.ReliableOrdered },
|
||||
};
|
||||
|
||||
public DeliveryPolicy Resolve(MessageType messageType)
|
||||
{
|
||||
return DefaultPolicies.TryGetValue(messageType, out var policy)
|
||||
? policy
|
||||
: DeliveryPolicy.ReliableOrdered;
|
||||
if (Policies.TryGetValue(messageType, out var policy))
|
||||
{
|
||||
return policy;
|
||||
}
|
||||
|
||||
// A new MessageType was added without an explicit policy decision.
|
||||
// Fail fast so the omission is noticed rather than silently defaulting.
|
||||
throw new System.ArgumentException(
|
||||
$"MessageType '{messageType}' has no assigned {nameof(DeliveryPolicy)}. " +
|
||||
"Add an explicit entry in the policy dictionary.",
|
||||
nameof(messageType));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Network.NetworkHost;
|
||||
using Network.NetworkTransport;
|
||||
|
||||
|
|
@ -63,8 +62,6 @@ namespace Network.NetworkApplication
|
|||
ServerAuthoritativeCombatConfiguration authoritativeCombat = null,
|
||||
IAuthoritativeMovementWorldValidator authoritativeMovementWorldValidator = null)
|
||||
{
|
||||
ValidateDualPortConfiguration(reliablePort, syncPort);
|
||||
|
||||
transportFactory ??= static port => new KcpTransport(port);
|
||||
|
||||
var reliableTransport = transportFactory(reliablePort)
|
||||
|
|
@ -91,11 +88,6 @@ namespace Network.NetworkApplication
|
|||
authoritativeMovementWorldValidator ?? PermissiveAuthoritativeMovementWorldValidator.Instance);
|
||||
}
|
||||
|
||||
public static Task<ServerRuntimeHandle> StartServerRuntimeAsync(ServerRuntimeConfiguration configuration)
|
||||
{
|
||||
return ServerRuntimeEntryPoint.StartAsync(configuration);
|
||||
}
|
||||
|
||||
private static void ValidateDualPortConfiguration(int reliablePort, int? syncPort)
|
||||
{
|
||||
if (reliablePort <= 0)
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ namespace Tests.EditMode.Network
|
|||
TransportFactory = port => CreateTransport(createdTransports, port)
|
||||
};
|
||||
|
||||
using var runtime = NetworkIntegrationFactory.StartServerRuntimeAsync(configuration).GetAwaiter().GetResult();
|
||||
using var runtime = ServerRuntimeEntryPoint.StartAsync(configuration).GetAwaiter().GetResult();
|
||||
|
||||
Assert.That(createdTransports.Keys, Is.EquivalentTo(new[] { 9000 }));
|
||||
Assert.That(runtime.IsRunning, Is.True);
|
||||
|
|
|
|||
Loading…
Reference in New Issue