gameserver: consolidate netcode R&D — remove diag spam, document DTLS-PSK wall
Build Game Server / build (push) Successful in 21s

- Keep the R3.5.0 header-bit fix (bunch alignment breakthrough)
- Remove per-packet [HS-RAW]/[HS-HDR]/[HS-BUNCH] diagnostics
- Document the DTLS-PSK encryption wall + packed-binary finding in NETCODE-RND.md
- UWorld NMT_Hello: honest comment on why the connection stops here

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-15 01:13:03 +02:00
co-authored by Claude Opus 4.8
parent ba9976c5b6
commit f0343bc1ea
3 changed files with 112 additions and 30 deletions
+22 -9
View File
@@ -286,15 +286,28 @@ public abstract partial class UWorld : FNetworkNotify, IAsyncDisposable
}
else
{
// The Cycle client offers an EncryptionToken in NMT_Hello. A UE
// connection only switches to AES once the server replies with
// NMT_EncryptionAck — the token is an offer, not a requirement.
// Implementing the full AES-GCM packet handler is a large effort,
// so first proceed WITHOUT encryption: never send the ack and go
// straight to the challenge. If the client keeps talking plaintext
// we're done; if it insists on encryption it will drop here and we
// know AES is mandatory.
Logger.Warning("Client sent EncryptionToken ({Len} chars) — proceeding WITHOUT encryption (no EncryptionAck)", encryptionToken.Length);
// R&D WALL — The Cycle mandates encryption on the game connection.
// The client's NMT_Hello carries EncryptionToken = its PlayFab
// user_id (e.g. "92EBCFE8C3EAF3AC"), and the client PacketHandler
// stack is [DTLSHandlerComponent, StatelessConnectHandlerComponent]
// (confirmed from the client's own logs). Encryption is therefore
// DTLS in PSK mode (the shipping exe bundles ECDHE/DHE-PSK-AES256
// cipher suites + a "DTLS.PreSharedKeys" cvar + DTLSPSK*Callback).
//
// Proceeding to the challenge WITHOUT sending NMT_EncryptionAck does
// NOT work: the client requires encryption and closes the control
// channel immediately after the plaintext challenge.
//
// To finish this we'd need (1) a DTLS-PSK server that matches UE's
// DTLSHandlerComponent framing, and (2) the 32-byte PSK the client
// derives per user_id. The derivation lives in the client's code,
// which cannot be recovered statically: the exe is packed/encrypted
// (.text entropy = 8.0), so Ghidra/radare2 see only ciphertext. The
// only route left is a runtime memory dump of the decrypted image.
//
// For now: log and proceed to the challenge so the flow is visible
// in logs; the client will close afterwards.
Logger.Warning("Client requires DTLS-PSK encryption (EncryptionToken={Token}); server-side DTLS not implemented — connection will be dropped by client", encryptionToken);
connection.SendChallengeControlMessage();
}
}