mirror of
https://github.com/R0m1k3/xtremflow.git
synced 2026-10-21 22:18:04 +02:00
feat: security overhaul (proxy ssrf fix, streaming sanitization, docker optimization)
This commit is contained in:
1 parent
6d87ada2b8
commit
8df9a37baa
810 files changed
+131090
-151
No files matched your search
@@ -0,0 +1,322 @@
|
||||
# Multiplayer Testing Guide
|
||||
|
||||
## Overview
|
||||
|
||||
Multiplayer testing validates network code, synchronization, and the player experience under real-world conditions. Network bugs are notoriously hard to reproduce—systematic testing is essential.
|
||||
|
||||
## Test Categories
|
||||
|
||||
### Synchronization Testing
|
||||
|
||||
| Test Type | Description | Priority |
|
||||
| ------------------- | ---------------------------------------- | -------- |
|
||||
| State sync | All clients see consistent game state | P0 |
|
||||
| Position sync | Character positions match across clients | P0 |
|
||||
| Event ordering | Actions occur in correct sequence | P0 |
|
||||
| Conflict resolution | Simultaneous actions handled correctly | P1 |
|
||||
| Late join | New players sync correctly mid-game | P1 |
|
||||
|
||||
### Network Conditions
|
||||
|
||||
| Condition | Simulation Method | Test Focus |
|
||||
| --------------- | ----------------- | ------------------------ |
|
||||
| High latency | 200-500ms delay | Input responsiveness |
|
||||
| Packet loss | 5-20% drop rate | State recovery |
|
||||
| Jitter | Variable delay | Interpolation smoothness |
|
||||
| Bandwidth limit | Throttle to 1Mbps | Data prioritization |
|
||||
| Disconnection | Kill connection | Reconnection handling |
|
||||
|
||||
## Test Scenarios
|
||||
|
||||
### Basic Multiplayer
|
||||
|
||||
```
|
||||
SCENARIO: Player Join/Leave
|
||||
GIVEN host has started multiplayer session
|
||||
WHEN Player 2 joins
|
||||
THEN Player 2 appears in host's game
|
||||
AND Player 1 appears in Player 2's game
|
||||
AND player counts sync across all clients
|
||||
|
||||
SCENARIO: State Synchronization
|
||||
GIVEN 4 players in match
|
||||
WHEN Player 1 picks up item at position (10, 5)
|
||||
THEN item disappears for all players
|
||||
AND Player 1's inventory updates for all players
|
||||
AND no duplicate pickups possible
|
||||
|
||||
SCENARIO: Combat Synchronization
|
||||
GIVEN Player 1 attacks Player 2
|
||||
WHEN attack hits
|
||||
THEN damage is consistent on all clients
|
||||
AND hit effects play for all players
|
||||
AND health updates sync within 100ms
|
||||
```
|
||||
|
||||
### Network Degradation
|
||||
|
||||
```
|
||||
SCENARIO: High Latency Gameplay
|
||||
GIVEN 200ms latency between players
|
||||
WHEN Player 1 moves forward
|
||||
THEN movement is smooth on Player 1's screen
|
||||
AND other players see interpolated movement
|
||||
AND position converges within 500ms
|
||||
|
||||
SCENARIO: Packet Loss Recovery
|
||||
GIVEN 10% packet loss
|
||||
WHEN important game event occurs (goal, kill, etc.)
|
||||
THEN event is eventually delivered
|
||||
AND game state remains consistent
|
||||
AND no duplicate events processed
|
||||
|
||||
SCENARIO: Player Disconnection
|
||||
GIVEN Player 2 disconnects unexpectedly
|
||||
WHEN 5 seconds pass
|
||||
THEN other players are notified
|
||||
AND Player 2's character handles gracefully (despawn/AI takeover)
|
||||
AND game continues without crash
|
||||
```
|
||||
|
||||
### Edge Cases
|
||||
|
||||
```
|
||||
SCENARIO: Simultaneous Actions
|
||||
GIVEN Player 1 and Player 2 grab same item simultaneously
|
||||
WHEN both inputs arrive at server
|
||||
THEN only one player receives item
|
||||
AND other player sees consistent state
|
||||
AND no item duplication
|
||||
|
||||
SCENARIO: Host Migration
|
||||
GIVEN host disconnects
|
||||
WHEN migration begins
|
||||
THEN new host is selected
|
||||
AND game state transfers correctly
|
||||
AND gameplay resumes within 10 seconds
|
||||
|
||||
SCENARIO: Reconnection
|
||||
GIVEN Player 2 disconnects temporarily
|
||||
WHEN Player 2 reconnects within 60 seconds
|
||||
THEN Player 2 rejoins same session
|
||||
AND state is synchronized
|
||||
AND progress is preserved
|
||||
```
|
||||
|
||||
## Network Simulation Tools
|
||||
|
||||
### Unity
|
||||
|
||||
```csharp
|
||||
// Using Unity Transport with Network Simulator
|
||||
using Unity.Netcode;
|
||||
|
||||
public class NetworkSimulator : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private int latencyMs = 100;
|
||||
[SerializeField] private float packetLossPercent = 5f;
|
||||
[SerializeField] private int jitterMs = 20;
|
||||
|
||||
void Start()
|
||||
{
|
||||
var transport = NetworkManager.Singleton.GetComponent<UnityTransport>();
|
||||
var simulator = transport.GetSimulatorParameters();
|
||||
|
||||
simulator.PacketDelayMS = latencyMs;
|
||||
simulator.PacketDropRate = (int)(packetLossPercent * 100);
|
||||
simulator.PacketJitterMS = jitterMs;
|
||||
}
|
||||
}
|
||||
|
||||
// Test
|
||||
[UnityTest]
|
||||
public IEnumerator Position_UnderLatency_ConvergesWithinThreshold()
|
||||
{
|
||||
EnableNetworkSimulation(latencyMs: 200);
|
||||
|
||||
// Move player
|
||||
player1.Move(Vector3.forward * 10);
|
||||
|
||||
yield return new WaitForSeconds(1f);
|
||||
|
||||
// Check other client's view
|
||||
var player1OnClient2 = client2.GetPlayerPosition(player1.Id);
|
||||
var actualPosition = player1.transform.position;
|
||||
|
||||
Assert.Less(Vector3.Distance(player1OnClient2, actualPosition), 0.5f);
|
||||
}
|
||||
```
|
||||
|
||||
### Unreal
|
||||
|
||||
```cpp
|
||||
// Using Network Emulation
|
||||
void UNetworkTestHelper::EnableLatencySimulation(int32 LatencyMs)
|
||||
{
|
||||
if (UNetDriver* NetDriver = GetWorld()->GetNetDriver())
|
||||
{
|
||||
FPacketSimulationSettings Settings;
|
||||
Settings.PktLag = LatencyMs;
|
||||
Settings.PktLagVariance = LatencyMs / 10;
|
||||
Settings.PktLoss = 0;
|
||||
|
||||
NetDriver->SetPacketSimulationSettings(Settings);
|
||||
}
|
||||
}
|
||||
|
||||
// Functional test for sync
|
||||
void AMultiplayerSyncTest::StartTest()
|
||||
{
|
||||
Super::StartTest();
|
||||
|
||||
// Spawn item on server
|
||||
APickupItem* Item = GetWorld()->SpawnActor<APickupItem>(
|
||||
ItemClass, FVector(0, 0, 100));
|
||||
|
||||
// Wait for replication
|
||||
FTimerHandle TimerHandle;
|
||||
GetWorld()->GetTimerManager().SetTimer(TimerHandle, [this, Item]()
|
||||
{
|
||||
// Verify client has item
|
||||
if (VerifyItemExistsOnAllClients(Item))
|
||||
{
|
||||
FinishTest(EFunctionalTestResult::Succeeded, "Item replicated");
|
||||
}
|
||||
else
|
||||
{
|
||||
FinishTest(EFunctionalTestResult::Failed, "Item not found on clients");
|
||||
}
|
||||
}, 2.0f, false);
|
||||
}
|
||||
```
|
||||
|
||||
### Godot
|
||||
|
||||
```gdscript
|
||||
# Network simulation
|
||||
extends Node
|
||||
|
||||
var simulated_latency_ms := 0
|
||||
var packet_loss_percent := 0.0
|
||||
|
||||
func _ready():
|
||||
# Hook into network to simulate conditions
|
||||
multiplayer.peer_packet_received.connect(_on_packet_received)
|
||||
|
||||
func _on_packet_received(id: int, packet: PackedByteArray):
|
||||
if packet_loss_percent > 0 and randf() < packet_loss_percent / 100:
|
||||
return # Drop packet
|
||||
|
||||
if simulated_latency_ms > 0:
|
||||
await get_tree().create_timer(simulated_latency_ms / 1000.0).timeout
|
||||
|
||||
_process_packet(id, packet)
|
||||
|
||||
# Test
|
||||
func test_position_sync_under_latency():
|
||||
NetworkSimulator.simulated_latency_ms = 200
|
||||
|
||||
# Move player on host
|
||||
host_player.position = Vector3(100, 0, 100)
|
||||
|
||||
await get_tree().create_timer(1.0).timeout
|
||||
|
||||
# Check client view
|
||||
var client_view_position = client.get_remote_player_position(host_player.id)
|
||||
var distance = host_player.position.distance_to(client_view_position)
|
||||
|
||||
assert_lt(distance, 1.0, "Position should converge within 1 unit")
|
||||
```
|
||||
|
||||
## Dedicated Server Testing
|
||||
|
||||
### Test Matrix
|
||||
|
||||
| Scenario | Test Focus |
|
||||
| --------------------- | ------------------------------------ |
|
||||
| Server startup | Clean initialization, port binding |
|
||||
| Client authentication | Login validation, session management |
|
||||
| Server tick rate | Consistent updates under load |
|
||||
| Maximum players | Performance at player cap |
|
||||
| Server crash recovery | State preservation, reconnection |
|
||||
|
||||
### Load Testing
|
||||
|
||||
```
|
||||
SCENARIO: Maximum Players
|
||||
GIVEN server configured for 64 players
|
||||
WHEN 64 players connect
|
||||
THEN all connections succeed
|
||||
AND server tick rate stays above 60Hz
|
||||
AND latency stays below 50ms
|
||||
|
||||
SCENARIO: Stress Test
|
||||
GIVEN 64 players performing actions simultaneously
|
||||
WHEN running for 10 minutes
|
||||
THEN no memory leaks
|
||||
AND no desync events
|
||||
AND server CPU below 80%
|
||||
```
|
||||
|
||||
## Matchmaking Testing
|
||||
|
||||
```
|
||||
SCENARIO: Skill-Based Matching
|
||||
GIVEN players with skill ratings [1000, 1050, 2000, 2100]
|
||||
WHEN matchmaking runs
|
||||
THEN [1000, 1050] are grouped together
|
||||
AND [2000, 2100] are grouped together
|
||||
|
||||
SCENARIO: Region Matching
|
||||
GIVEN players from US-East, US-West, EU
|
||||
WHEN matchmaking runs
|
||||
THEN players prefer same-region matches
|
||||
AND cross-region only when necessary
|
||||
AND latency is acceptable for all players
|
||||
|
||||
SCENARIO: Queue Timeout
|
||||
GIVEN player waiting in queue
|
||||
WHEN 3 minutes pass without match
|
||||
THEN matchmaking expands search criteria
|
||||
AND player is notified of expanded search
|
||||
```
|
||||
|
||||
## Security Testing
|
||||
|
||||
| Vulnerability | Test Method |
|
||||
| ---------------- | --------------------------- |
|
||||
| Speed hacking | Validate movement on server |
|
||||
| Teleportation | Check position delta limits |
|
||||
| Damage hacking | Server-authoritative damage |
|
||||
| Packet injection | Validate packet checksums |
|
||||
| Replay attacks | Use unique session tokens |
|
||||
|
||||
## Performance Metrics
|
||||
|
||||
| Metric | Good | Acceptable | Poor |
|
||||
| --------------------- | --------- | ---------- | ---------- |
|
||||
| Round-trip latency | < 50ms | < 100ms | > 150ms |
|
||||
| Sync delta | < 100ms | < 200ms | > 500ms |
|
||||
| Packet loss tolerance | < 5% | < 10% | > 15% |
|
||||
| Bandwidth per player | < 10 KB/s | < 50 KB/s | > 100 KB/s |
|
||||
| Server tick rate | 60+ Hz | 30+ Hz | < 20 Hz |
|
||||
|
||||
## Best Practices
|
||||
|
||||
### DO
|
||||
|
||||
- Test with real network conditions, not just localhost
|
||||
- Simulate worst-case scenarios (high latency + packet loss)
|
||||
- Use server-authoritative design for competitive games
|
||||
- Implement lag compensation for fast-paced games
|
||||
- Test host migration paths
|
||||
- Log network events for debugging
|
||||
|
||||
### DON'T
|
||||
|
||||
- Trust client data for important game state
|
||||
- Assume stable connections
|
||||
- Skip testing with maximum player counts
|
||||
- Ignore edge cases (simultaneous actions)
|
||||
- Test only in ideal network conditions
|
||||
- Forget to test reconnection flows
|
||||
Reference in new issue
Block a user