Files
Campus-25/static/Servers/Tachyon/docs/client-agent-request-3.md
T
2026-10-14 06:59:51 +02:00

74 lines
4.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Request #3: the forked NGO batch/message framing and ConnectionApproved
The LiteNetLib layer is solved and the client now completes the transport handshake against
our server and sends its NGO ConnectionRequest. We decoded it and confirmed the Tachyon JSON
(`AI/AT/VB/CKA/CIA/CPK`). But the fork changed NGO's batch and message framing, so we cannot
send a ConnectionApproved the client will accept without the exact serialization.
## What we already worked out from the wire (for your cross-check)
Decoded from a real 2041-byte ConnectionRequest batch:
```
[0:2] magic u16 = 0x1160
[2:4] count u16 = 0 (stock BatchCount, sent as 0)
[4:8] size u32 = 2041 (total datagram length)
[8:16] hash u64 = 0x3faa53cee8c5e338 (= XXHash64 over bytes [24:2041], VERIFIED)
[16:24] u64 = 1 (fork field; equals message count here)
[24] bitpacked = 1 (message type: ConnectionRequest, client-local idx)
[25:27] bitpacked = 2014 (message size)
[27] 0x81 (version-header preamble byte)
[28:63] 7 × { u32 hash ; 1 byte version=0 }
[63:68] 00 00 00 00 01 (5 bytes, not in stock NGO)
[68:76] u64 ConfigHash
[76:80] u32 = 1961 (ConnData length)
[80:2041] Tachyon JSON
```
So the batch hash covers `[24:end]` (message stream), NOT stock's `[16:alignedLength]`, and
the batch is NOT padded to 8 bytes. Two message-body bytes are unexplained: the `0x81`
preamble, and the `00 00 00 00 01`.
## Questions (in priority order)
**Q1 — forked batch header & hash, in `NetworkMessageManager`.**
Confirm the header layout above. Specifically:
- Is the `u64` at `[16:24]` the message count, a tick, or something else? What writes it?
- Confirm `BatchHash = XXHash64(buffer + 24, size - 24)` (or give the real range/seed).
- **Does the RECEIVER validate `BatchHash` and reject on mismatch, or log-and-continue?**
This decides whether our outbound hash must be exact.
- Does the receiver iterate messages by the `u64` count, by `BatchCount`, or by position?
**Q2 — the version-header preamble.**
In the forked `ConnectionRequestMessage.Serialize` (and the shared version-header code), what
is written before the version table? Stock writes `BytePacker.WriteValueBitPacked(N)` (N=7 ->
`0x39`). We see a single `0x81`. And what is the `00 00 00 00 01` written AFTER the table,
before `ConfigHash`? Give the exact field sequence of the forbidden segment as this build
serializes it.
**Q3 — `ConnectionApprovedMessage` serialization (the thing we must send).**
Full `Serialize` (server→client) for this build. We need every field and its encoding, in
order: the version header (same preamble as Q2?), `OwnerClientId`, `NetworkTick`, any
`ConnectedClientIds`, `sceneObjectCount`, and anything the fork added. Also the message
**type index** the client expects for ConnectionApproved in the pre-approval (local) space,
and how `Deserialize` reads it — because the client's `Deserialize` is what accepts or rejects
our packet.
**Q4 — how the approval reaches Tachyon.**
Earlier finding: `NetworkManager.RecRoom_ConnectionInfo` is a fork addition, hypothesised to
carry the approval JSON (`PMFAAFNFMAL`, the `"Carrot"` / `SessionKeyB` blob). Confirm whether
the approval JSON rides inside `ConnectionApprovedMessage`'s ConnectionData, in
`RecRoom_ConnectionInfo`, or elsewhere — i.e. where in the server→client bytes we must place
`{"DR":"Carrot",...}`.
**Q5 — key-null path for the session.**
Does the client require a non-null `SessionKeyB` to proceed, or will it accept an approval with
`"Carrot"` and no key and stay plaintext (marker `0x11`)? This decides whether we can defer the
RSA keypair patch and run voice unencrypted.
## Output
Decompiled `Serialize`/`Deserialize` bodies where possible, else exact field order + encodings
+ byte offsets. Distinguish read from inferred. If a field genuinely is not present, say so —
do not fill it from stock NGO; the fork has already diverged in three places above.