Networking: decode egg-delivery protocol from source; archive console SW

Decoded the console<->pod message layout from the MUNGA framework headers
(the send/recv impl did not survive -- only headers + a test harness):
NetworkPacket = 16B NetworkPacketHeader + a Receiver::Message; the egg is
delivered as ReceiveEggFileMessage chunks (seq/totalLen/thisLen +
notationData[1000]), a full egg packet = 1040B (matches the VPX nb<=1040
cap). Console splits the mission notation file into <=1000B chunks; pod
reassembles + ACKs. Two bytes-on-the-wire details (stream framing +
PPC/x86 endianness) flagged for the first live capture. Full byte tables
in NET-NOTES.md.

Also moves the extracted console software (Console 4.10 PPC app + per-venue
Console.ini + fonts/logs, resource forks preserved) into
410console/4_10-console-extracted/.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-07-04 22:21:06 -05:00
co-authored by Claude Fable 5
parent 5b44ede702
commit e1d44251da
80 changed files with 84 additions and 0 deletions
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+68
View File
@@ -198,6 +198,74 @@ pod "Puck". Remaining protocol unknown is just the on-stream message
framing (NetworkPacketHeader + ReceiveEggFileMessage) — capture it once
the console connects, or read it from network.hpp.
## Egg-delivery protocol — decoded from source (2026-07-04)
Decoded from `CODE/RP/MUNGA/{NETWORK,RECEIVER,HOSTID}.HPP` +
`MUNGA_L4/L4NET.HPP`. The real send/receive *implementation* (framing on
the byte stream) did NOT survive in the archive — only headers + a test
harness (`L4NET.TCP`'s `TestClass`, `#if 0`). So the logical message
layout below is solid; two low-level details (stream framing + endianness)
need a live capture or a binary disasm to pin — see caveats.
**Transport:** console → TCP connect to pod IP : **1501** → the pod
(NetNub `TCP_LISTEN`) accepts. All base types are 32-bit
(`Enumeration=int`, `size_t`, `LWord`, `Time::ticks=long` → 4 bytes each).
**On-wire unit = NetworkPacket = NetworkPacketHeader + a Receiver::Message.**
NetworkPacketHeader (16 bytes):
| off | field | type |
|--|--|--|
| 0 | clientID | ClientID enum (0=NetworkMgr,2=HostMgr,5=Console...) |
| 4 | gameID | Enumeration |
| 8 | fromHost | HostID (Enumeration) |
| 12 | timeStamp | Time (long ticks) |
Receiver::Message header (12 bytes) that every message starts with:
| off | field | type |
|--|--|--|
| 0 | messageLength | size_t (= sizeof the whole message) |
| 4 | messageID | Enumeration (ReceiveEggFileMessageID etc.) |
| 8 | messageFlags | LWord (bit0 ReliableFlag=1) |
**ReceiveEggFileMessage** (the egg carrier; messageLength = 1024):
| off | field | type |
|--|--|--|
| 0 | (Receiver::Message header) | 12 B |
| 12 | sequenceNumber | int (chunk index) |
| 16 | notationFileLength | int (total egg size) |
| 20 | thisMessageLength | int (bytes valid in this chunk, ≤1000) |
| 24 | notationData[1000] | char (the egg chunk) |
So a full egg packet on the wire = **16 (header) + 1024 (message) = 1040
bytes** — matches the `nb≤1040` payload cap seen on the VPX/iserver link.
**Egg-delivery algorithm:** the console splits the mission egg (a text
"notation file", same INI/notation format as Console.ini) into
ceil(len/1000) chunks; sends each as a ReceiveEggFileMessage with
sequenceNumber 0..N, notationFileLength=total, thisMessageLength≤1000. The
pod's `ReceiveEggFileMessageHandler` reassembles into `eggTempBuffer` by
sequence, and when `notationFileLength` bytes have arrived, parses it as
the mission notation file. Pod replies `AcknowledgeEggFileMessage`
("connected, ready, next host"). `messageID` values start at
`NetworkClient::NextMessageID`; ReceiveEggFileMessageID is the first
NetworkManager message ID.
**Caveats to confirm with the first live capture (or a binary disasm of
Console 4.10 send / BTL4OPT receive):**
1. *Stream framing:* whether each 1040-B NetworkPacket is one discrete
NetNub/WATTCP record, or the receiver frames within the TCP stream via
the leading `messageLength`. (NetNub `RECEIVE_PACKET` returns up to
1600 B; MAX aligns with one packet.)
2. *Endianness:* console is **big-endian PPC**, pod is **little-endian
x86** — the multi-byte header/length ints must be byte-swapped by one
side (or sent in network order). `notationData` (egg text) is
endian-agnostic. The capture will show which order the length fields
use; a stand-in sender must match it.
Everything needed to PARSE a capture and BUILD a stand-in egg-sender is
here except those two bytes-on-the-wire details, which the console-connect
milestone resolves immediately.
## Open questions / notes
- Exact TCP listen port(s) — not in the source grep; get from NETNUB.EXE
or a capture at milestone 3.