# EQ2EMu Protocol Structure Report

Overview

The EQ2EMu protocol is a custom UDP-based networking protocol designed for EverQuest II server
emulation. It implements reliability, compression, encryption, and packet fragmentation on top
of UDP.

Core Architecture

1. Protocol Layers

Application Layer

- EQApplicationPacket: High-level game packets containing game logic
- PacketStruct: Dynamic packet structure system using XML definitions
- DataBuffer: Serialization/deserialization buffer management

Protocol Layer

- EQProtocolPacket: Low-level protocol packets with sequencing and reliability
- EQStream: Stream management with connection state, retransmission, and flow control
- EQPacket: Base packet class with common functionality

2. Packet Types

Protocol Control Packets (opcodes.h)

OP_SessionRequest     = 0x01  // Client initiates connection
OP_SessionResponse    = 0x02  // Server accepts connection
OP_Combined          = 0x03  // Multiple packets combined
OP_SessionDisconnect = 0x05  // Connection termination
OP_KeepAlive        = 0x06  // Keep connection alive
OP_ServerKeyRequest  = 0x07  // Request encryption key
OP_SessionStatResponse = 0x08  // Connection statistics
OP_Packet           = 0x09  // Regular data packet
OP_Fragment         = 0x0d  // Fragmented packet piece
OP_OutOfOrderAck    = 0x11  // Acknowledge out-of-order packet
OP_Ack              = 0x15  // Acknowledge packet receipt
OP_AppCombined      = 0x19  // Combined application packets
OP_OutOfSession     = 0x1d  // Out of session notification

3. Connection Flow

1. Session Establishment
  - Client sends OP_SessionRequest with session parameters
  - Server responds with OP_SessionResponse containing session ID and encryption key
  - RC4 encryption initialized using the provided key
2. Data Transfer
  - Packets are sequenced (16-bit sequence numbers)
  - Reliable packets require acknowledgment
  - Retransmission on timeout (default 500ms * 3.0 multiplier)
  - Packet combining for efficiency (max 256 bytes combined)
3. Session Termination
  - Either side sends OP_SessionDisconnect
  - Graceful shutdown with cleanup of pending packets

4. Key Features

Compression

- Uses zlib compression (indicated by 0x5a flag byte)
- Applied after protocol header
- Decompression required before processing

Encryption

- RC4 stream cipher
- Separate keys for client/server directions
- Client uses ~key (bitwise NOT), server uses key directly
- 20 bytes of dummy data prime both ciphers

CRC Validation

- Custom CRC16 implementation
- Applied to entire packet except last 2 bytes
- Session packets exempt from CRC

Fragmentation

- Large packets split into fragments
- Each fragment marked with OP_Fragment
- Reassembly at receiver before processing

5. Packet Structure

Basic Protocol Packet

[1-2 bytes] Opcode (1 byte if < 0xFF, otherwise 2 bytes)
[variable]  Payload
[2 bytes]   CRC16 (if applicable)

Combined Packet Format

[1 byte]    Size of packet 1
[variable]  Packet 1 data
[1 byte]    Size of packet 2
[variable]  Packet 2 data
...

6. Dynamic Packet System

The PacketStruct system allows runtime-defined packet structures:

- XML Configuration: Packet structures defined in XML files
- Version Support: Multiple versions per packet type
- Data Types: int8/16/32/64, float, double, string, array, color, equipment
- Conditional Fields: Fields can be conditional based on other field values
- Oversized Support: Dynamic sizing for variable-length fields

Example structure:
<Struct Name="PlayerUpdate" ClientVersion="1096">
  <Data ElementName="activity" Type="int32"/>
  <Data ElementName="speed" Type="float"/>
  <Data ElementName="x" Type="float"/>
  <Data ElementName="y" Type="float"/>
  <Data ElementName="z" Type="float"/>
</Struct>

7. Opcode Management

- Dynamic Mapping: Runtime opcode mapping via configuration files
- Version Support: Different opcode sets per client version
- Name Resolution: String names mapped to numeric opcodes
- Shared Memory Option: Multi-process opcode sharing support

8. Implementation Considerations for Porting

1. Memory Management
  - Extensive use of dynamic allocation
  - Custom safe_delete macros for cleanup
  - Reference counting for shared packets
2. Threading
  - Mutex protection for all shared resources
  - Separate threads for packet processing
  - Condition variables for synchronization
3. Platform Dependencies
  - POSIX sockets and threading
  - Network byte order conversions
  - Platform-specific timing functions
4. Performance Optimizations
  - Packet combining to reduce overhead
  - Preallocated buffers for common sizes
  - Fast CRC table lookup
5. Error Handling
  - Graceful degradation on errors
  - Extensive logging for debugging
  - Automatic retransmission on failure

9. Critical Classes to Port

1. EQStream: Core connection management
2. EQPacket/EQProtocolPacket: Packet representation
3. PacketStruct: Dynamic packet structure system
4. DataBuffer: Serialization utilities
5. OpcodeManager: Opcode mapping system
6. Crypto: RC4 encryption wrapper
7. CRC16: Custom CRC implementation

10. Protocol Quirks

- Opcode byte order depends on value (0x00 prefix for opcodes < 0xFF)
- Special handling for session control packets (no CRC)
- 20-byte RC4 priming sequence required
- Custom CRC polynomial (0xEDB88320 reversed)
- Compression flag at variable offset based on opcode size

This protocol is designed for reliability over UDP while maintaining low latency for game
traffic. The dynamic packet structure system allows flexibility in supporting multiple client
versions without recompilation.

# UDP Network Layer Architecture

1. EQStreamFactory - The UDP Socket Manager

- Opens and manages the main UDP socket (line 148: socket(AF_INET, SOCK_DGRAM, 0))
- Binds to a specific port (line 153: bind())
- Sets socket to non-blocking mode (line 159: fcntl(sock, F_SETFL, O_NONBLOCK))
- Runs three main threads:
- ReaderLoop(): Uses recvfrom() to read incoming UDP packets (line 228)
- WriterLoop(): Manages outgoing packet transmission
- CombinePacketLoop(): Combines small packets for efficiency

2. EQStream - Per-Connection Protocol Handler

- Manages individual client connections over the shared UDP socket
- Handles packet serialization/deserialization
- Implements reliability layer (sequencing, acknowledgments, retransmission)
- WritePacket() method uses sendto() for actual UDP transmission (line 1614)

3. Key UDP Operations:

Receiving (EQStreamFactory::ReaderLoop):

recvfrom(sock, buffer, 2048, 0, (struct sockaddr *)&from, (socklen_t *)&socklen)
- Uses select() for non-blocking I/O
- Creates new EQStream instances for new connections (OP_SessionRequest)
- Routes packets to existing streams by IP:port mapping

Sending (EQStream::WritePacket):

sendto(eq_fd,(char *)buffer,length,0,(sockaddr *)&address,sizeof(address))
- Serializes protocol packets to byte arrays
- Applies compression and encryption if enabled
- Adds CRC checksums
- Sends via UDP to specific client address

4. Connection Multiplexing:

- Single UDP socket serves multiple clients
- Stream identification by IP:port combination (sprintf(temp, "%u.%d", 
ntohl(from.sin_addr.s_addr), ntohs(from.sin_port)))
- Thread-safe stream management with mutex protection

So yes, EQStream and EQStreamFactory together provide a complete UDP networking layer that
implements a reliable, connection-oriented protocol on top of unreliable UDP datagrams. The
factory manages the socket and dispatches packets to individual stream instances that handle
the protocol logic for each client connection.

# TCP Usage in EQ2EMu

The TCP implementation serves a completely separate purpose from the main game client
communication:

1. HTTP Web Server (web_server.hpp)

- Purpose: Administrative/monitoring interface
- Features:
  - REST API endpoints (/version, / root)
  - SSL/TLS support with certificate-based encryption
  - HTTP Basic Authentication with session management
  - Database-driven user authentication and authorization levels
  - JSON response formatting for API calls
- Use Cases:
  - Server status monitoring
  - Administrative controls
  - Third-party tool integration
  - Web-based dashboards

2. Server-to-Server Communication (tcp_connection.hpp)

- Purpose: Inter-server communication within EQ2EMu cluster
- Features:
  - Custom packet framing protocol
  - Optional zlib compression for bandwidth efficiency
  - Message relay capabilities between servers
  - Connection state management
- Use Cases:
  - Login server to world server communication
  - Zone server coordination
  - Cross-server messaging
  - Load balancing and failover

Key Differences: UDP vs TCP

| Aspect     | UDP (Game Clients)                         | TCP (Admin/Server)
    |
|------------|--------------------------------------------|------------------------------------
----|
| Protocol   | Custom EQ2 protocol with reliability layer | Standard HTTP/Custom framing
    |
| Encryption | RC4 stream cipher                          | SSL/TLS or none
    |
| Clients    | Game clients (players)                     | Web browsers/Admin tools/Other
servers |
| Port       | 9001 (World), 9100 (Login)                 | Configurable web port
    |
| Threading  | 3 worker threads per factory               | Thread-per-connection
    |

Architecture Summary

Game Clients ←→ [UDP EQStream] ←→ World/Login Servers
                                          ↕
Admin Tools  ←→ [TCP WebServer] ←→ World/Login Servers
                                          ↕
Other Servers ←→ [TCP Connection] ←→ World/Login Servers

The TCP implementation provides out-of-band management and inter-server communication, while
the UDP implementation handles all real-time game traffic. This separation allows for robust
administration without interfering with game performance.