From 76be3d0818dbc74bcd92e8813d6da15a4efda200 Mon Sep 17 00:00:00 2001 From: MayaTheShy Date: Sun, 9 Nov 2025 02:52:56 -0500 Subject: [PATCH] docs: update protocol implementation details and NLPacket format specifications --- OVERTE_ASSIGNMENT_CLIENT_TASK.md | 79 ++++++++++++++++++++++++-------- 1 file changed, 59 insertions(+), 20 deletions(-) diff --git a/OVERTE_ASSIGNMENT_CLIENT_TASK.md b/OVERTE_ASSIGNMENT_CLIENT_TASK.md index 5c4a1bf..d1c6bb5 100644 --- a/OVERTE_ASSIGNMENT_CLIENT_TASK.md +++ b/OVERTE_ASSIGNMENT_CLIENT_TASK.md @@ -108,31 +108,70 @@ To implement full metaverse authentication: For now, the implementation correctly handles both authenticated and anonymous modes. -## Context +## Protocol Implementation Details -We have successfully implemented the Overte domain connection protocol in `src/OverteClient.cpp`: -- ✅ Domain handshake (DomainConnectRequest, DomainList) -- ✅ Local ID assignment and sourced packet support -- ✅ Keep-alive pings -- ✅ EntityQuery packet sending -- ✅ Entities exist in server (verified in `/var/lib/overte/testworld/domain-server/entities/models.json.gz`) +### NLPacket Format +All Overte network packets use the NLPacket format: +``` +Header (6+ bytes): + [0-3]: Sequence number (uint32 BE) + [4]: Packet type (uint8) + [5]: Version (uint8) + [6+]: Payload (variable length) +``` -However, **EntityData packets are not being received** because we're only connected to the domain server, not the assignment clients. +### DomainConnectRequest Packet (Type 0x1F) +```cpp +// Sent to domain server on UDP port 40104 +225 bytes total: +- NLPacket header (6 bytes) +- 11 fields via QDataStream: + 1. Hardware address (empty QString) + 2. Machine fingerprint (UUID as 16 bytes) + 3. Connect reason (QString, typically empty) + 4. Previous session UUID (16 bytes, null for first connect) + 5. Protocol version signature (16 byte MD5: eb1600e798dc5e03c755a968dc16b7fc) + 6. Local ID (2 bytes, 0 for initial request) + 7. Session local ID (16 bytes, null for first connect) + 8-11. Domain username/password fields (empty for anonymous) +``` -## Problem +### DomainList Reply Packet (Type 0x02) +```cpp +// Received from domain server +Variable length: +- NLPacket header (6 bytes) +- Domain UUID (16 bytes) +- Session UUID (16 bytes) - assigned by domain +- Local ID (2 bytes) - our identifier +- Permissions (4 bytes) +- Timestamps (3x8 bytes = 24 bytes) +- New connection flag (1 byte) +- Assignment client count (variable int) +- For each assignment client: + - Node type (char: 'o'=EntityServer, 'W'=AvatarMixer, 'M'=AudioMixer) + - Node UUID (16 bytes) + - Socket type (int) + - Public address (QHostAddress) + - Public port (uint16) + - Local address (QHostAddress) + - Local port (uint16) + - Permissions (uint32) + - Interest flags (bool) + - Pool/Replicated flags (2 bools) +``` -In Overte's architecture: -1. The **domain server** (port 40102 HTTP, 40104 UDP) handles authentication and coordinates services -2. **Assignment clients** run specialized services on separate UDP ports: - - Entity Server (serves entity data) - - Avatar Mixer (avatar positions/animations) - - Audio Mixer (spatial audio) - - Asset Server (3D models, textures) - - Messages Mixer (chat/messages) +### QDataStream Serialization +Overte uses Qt's QDataStream format (big-endian): +- **QString**: 4-byte length prefix + UTF-16 characters (2 bytes each) +- **UUID**: 16 raw bytes +- **Integers**: Big-endian (use ntohl/be32toh) +- **QHostAddress**: 1 byte protocol + 4 bytes IPv4 or 16 bytes IPv6 -Our current implementation sends EntityQuery to the domain server, but entity data is served by the **Entity Server assignment client** which runs on a different, dynamically-assigned UDP port. - -## Current State +### Implementation Files +- `src/OverteClient.cpp`: Main protocol implementation +- `src/NLPacketCodec.cpp`: Packet encoding/decoding +- `src/QDataStream.cpp`: Qt serialization compatibility ### What Works ```cpp