first commit
This commit is contained in:
+562
@@ -0,0 +1,562 @@
|
||||
# Packet Processing Pipeline
|
||||
|
||||
<cite>
|
||||
**Referenced Files in This Document**
|
||||
- [PacketHandler.cs](file://ClassicAssist.Shared/UO/Network/PacketHandler.cs)
|
||||
- [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs)
|
||||
- [OutgoingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketHandlers.cs)
|
||||
- [IncomingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketFilters.cs)
|
||||
- [OutgoingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketFilters.cs)
|
||||
- [ActionPacketQueue.cs](file://ClassicAssist.Shared/UO/Network/ActionPacketQueue.cs)
|
||||
- [ActionPacketQueueItem.cs](file://ClassicAssist.Shared/UO/Network/ActionPacketQueueItem.cs)
|
||||
- [Compression.cs](file://ClassicAssist.Shared/UO/Compression.cs)
|
||||
- [PacketReader.cs](file://ClassicAssist.Shared/UO/Data/PacketReader.cs)
|
||||
- [PacketWriter.cs](file://ClassicAssist.Shared/UO/Data/PacketWriter.cs)
|
||||
- [BasePacket.cs](file://ClassicAssist.Shared/UO/Network/Packets/BasePacket.cs)
|
||||
- [MobileUpdate.cs](file://ClassicAssist.Shared/UO/Network/Packets/MobileUpdate.cs)
|
||||
- [MobileMoving.cs](file://ClassicAssist.Shared/UO/Network/Packets/MobileMoving.cs)
|
||||
- [Entity.cs](file://ClassicAssist.Shared/UO/Objects/Entity.cs)
|
||||
- [Mobile.cs](file://ClassicAssist.Shared/UO/Objects/Mobile.cs)
|
||||
- [PlayerMobile.cs](file://ClassicAssist.Shared/UO/Objects/PlayerMobile.cs)
|
||||
- [Engine.cs](file://ClassicAssist.Shared/Engine.cs)
|
||||
</cite>
|
||||
|
||||
## Table of Contents
|
||||
1. [Introduction](#introduction)
|
||||
2. [Project Structure](#project-structure)
|
||||
3. [Core Components](#core-components)
|
||||
4. [Architecture Overview](#architecture-overview)
|
||||
5. [Detailed Component Analysis](#detailed-component-analysis)
|
||||
6. [Dependency Analysis](#dependency-analysis)
|
||||
7. [Performance Considerations](#performance-considerations)
|
||||
8. [Troubleshooting Guide](#troubleshooting-guide)
|
||||
9. [Conclusion](#conclusion)
|
||||
10. [Appendices](#appendices)
|
||||
|
||||
## Introduction
|
||||
This document explains the packet processing pipeline in ClassicAssist.Avalonia, focusing on how raw network I/O is transformed into protocol objects and then applied to entities. It covers:
|
||||
- The PacketHandler architecture for incoming/outgoing routing
|
||||
- Compression handling and protocol version detection
|
||||
- Event-driven message bus pattern for packet distribution
|
||||
- Concrete examples of registration, invocation, and error propagation
|
||||
- Performance considerations for high-frequency packets and memory optimization
|
||||
- How to implement custom packet handlers and integrate with the existing pipeline
|
||||
|
||||
## Project Structure
|
||||
The networking stack resides primarily under ClassicAssist.Shared/UO/Network and related data/object layers. Key areas include:
|
||||
- Network core: PacketHandler, Incoming/Outgoing handlers and filters, queues
|
||||
- Data serialization: PacketReader/Writer, BasePacket
|
||||
- Protocol packets: concrete packet types (e.g., MobileUpdate, MobileMoving)
|
||||
- Game objects: Entity, Mobile, PlayerMobile updated by packets
|
||||
- Engine integration: initialization and lifecycle hooks
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "Networking Core"
|
||||
PH["PacketHandler"]
|
||||
INH["IncomingPacketHandlers"]
|
||||
OUTH["OutgoingPacketHandlers"]
|
||||
INF["IncomingPacketFilters"]
|
||||
OUTF["OutgoingPacketFilters"]
|
||||
APQ["ActionPacketQueue"]
|
||||
end
|
||||
subgraph "Serialization"
|
||||
PR["PacketReader"]
|
||||
PW["PacketWriter"]
|
||||
BP["BasePacket"]
|
||||
end
|
||||
subgraph "Packets"
|
||||
MU["MobileUpdate"]
|
||||
MM["MobileMoving"]
|
||||
end
|
||||
subgraph "Game Objects"
|
||||
ENT["Entity"]
|
||||
MOB["Mobile"]
|
||||
PMOB["PlayerMobile"]
|
||||
end
|
||||
subgraph "Engine"
|
||||
ENG["Engine"]
|
||||
end
|
||||
ENG --> PH
|
||||
PH --> INF
|
||||
PH --> INH
|
||||
PH --> APQ
|
||||
PH --> OUTF
|
||||
PH --> OUTH
|
||||
INH --> PR
|
||||
OUTH --> PW
|
||||
INH --> MU
|
||||
INH --> MM
|
||||
MU --> MOB
|
||||
MM --> MOB
|
||||
MOB --> ENT
|
||||
PMOB --> MOB
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [PacketHandler.cs](file://ClassicAssist.Shared/UO/Network/PacketHandler.cs)
|
||||
- [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs)
|
||||
- [OutgoingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketHandlers.cs)
|
||||
- [IncomingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketFilters.cs)
|
||||
- [OutgoingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketFilters.cs)
|
||||
- [ActionPacketQueue.cs](file://ClassicAssist.Shared/UO/Network/ActionPacketQueue.cs)
|
||||
- [PacketReader.cs](file://ClassicAssist.Shared/UO/Data/PacketReader.cs)
|
||||
- [PacketWriter.cs](file://ClassicAssist.Shared/UO/Data/PacketWriter.cs)
|
||||
- [BasePacket.cs](file://ClassicAssist.Shared/UO/Network/Packets/BasePacket.cs)
|
||||
- [MobileUpdate.cs](file://ClassicAssist.Shared/UO/Network/Packets/MobileUpdate.cs)
|
||||
- [MobileMoving.cs](file://ClassicAssist.Shared/UO/Network/Packets/MobileMoving.cs)
|
||||
- [Entity.cs](file://ClassicAssist.Shared/UO/Objects/Entity.cs)
|
||||
- [Mobile.cs](file://ClassicAssist.Shared/UO/Objects/Mobile.cs)
|
||||
- [PlayerMobile.cs](file://ClassicAssist.Shared/UO/Objects/PlayerMobile.cs)
|
||||
- [Engine.cs](file://ClassicAssist.Shared/Engine.cs)
|
||||
|
||||
**Section sources**
|
||||
- [PacketHandler.cs](file://ClassicAssist.Shared/UO/Network/PacketHandler.cs)
|
||||
- [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs)
|
||||
- [OutgoingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketHandlers.cs)
|
||||
- [IncomingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketFilters.cs)
|
||||
- [OutgoingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketFilters.cs)
|
||||
- [ActionPacketQueue.cs](file://ClassicAssist.Shared/UO/Network/ActionPacketQueue.cs)
|
||||
- [PacketReader.cs](file://ClassicAssist.Shared/UO/Data/PacketReader.cs)
|
||||
- [PacketWriter.cs](file://ClassicAssist.Shared/UO/Data/PacketWriter.cs)
|
||||
- [BasePacket.cs](file://ClassicAssist.Shared/UO/Network/Packets/BasePacket.cs)
|
||||
- [MobileUpdate.cs](file://ClassicAssist.Shared/UO/Network/Packets/MobileUpdate.cs)
|
||||
- [MobileMoving.cs](file://ClassicAssist.Shared/UO/Network/Packets/MobileMoving.cs)
|
||||
- [Entity.cs](file://ClassicAssist.Shared/UO/Objects/Entity.cs)
|
||||
- [Mobile.cs](file://ClassicAssist.Shared/UO/Objects/Mobile.cs)
|
||||
- [PlayerMobile.cs](file://ClassicAssist.Shared/UO/Objects/PlayerMobile.cs)
|
||||
- [Engine.cs](file://ClassicAssist.Shared/Engine.cs)
|
||||
|
||||
## Core Components
|
||||
- PacketHandler: Central orchestrator for incoming and outgoing packets; manages filters, compression, dispatching, and queuing.
|
||||
- IncomingPacketHandlers: Registry and dispatcher for inbound packet types to their specific handlers.
|
||||
- OutgoingPacketHandlers: Registry and dispatcher for outbound packet types to their writers.
|
||||
- IncomingPacketFilters / OutgoingPacketFilters: Pluggable filter chain that can inspect, modify, or drop packets.
|
||||
- ActionPacketQueue: Ordered queue for deferring actions across frames or threads.
|
||||
- PacketReader / PacketWriter: Binary readers/writers used by packet implementations.
|
||||
- BasePacket: Common base for all packet types providing shared behavior and metadata.
|
||||
- Protocol Packets: Concrete classes like MobileUpdate and MobileMoving that parse wire format and update game state.
|
||||
- Game Objects: Entity, Mobile, PlayerMobile are mutated by packet handlers to reflect server state.
|
||||
- Engine: Initializes networking components and wires up lifecycle events.
|
||||
|
||||
**Section sources**
|
||||
- [PacketHandler.cs](file://ClassicAssist.Shared/UO/Network/PacketHandler.cs)
|
||||
- [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs)
|
||||
- [OutgoingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketHandlers.cs)
|
||||
- [IncomingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketFilters.cs)
|
||||
- [OutgoingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketFilters.cs)
|
||||
- [ActionPacketQueue.cs](file://ClassicAssist.Shared/UO/Network/ActionPacketQueue.cs)
|
||||
- [PacketReader.cs](file://ClassicAssist.Shared/UO/Data/PacketReader.cs)
|
||||
- [PacketWriter.cs](file://ClassicAssist.Shared/UO/Data/PacketWriter.cs)
|
||||
- [BasePacket.cs](file://ClassicAssist.Shared/UO/Network/Packets/BasePacket.cs)
|
||||
- [MobileUpdate.cs](file://ClassicAssist.Shared/UO/Network/Packets/MobileUpdate.cs)
|
||||
- [MobileMoving.cs](file://ClassicAssist.Shared/UO/Network/Packets/MobileMoving.cs)
|
||||
- [Entity.cs](file://ClassicAssist.Shared/UO/Objects/Entity.cs)
|
||||
- [Mobile.cs](file://ClassicAssist.Shared/UO/Objects/Mobile.cs)
|
||||
- [PlayerMobile.cs](file://ClassicAssist.Shared/UO/Objects/PlayerMobile.cs)
|
||||
- [Engine.cs](file://ClassicAssist.Shared/Engine.cs)
|
||||
|
||||
## Architecture Overview
|
||||
The pipeline follows a layered approach:
|
||||
- Raw bytes arrive from the network socket
|
||||
- Compression is handled before parsing
|
||||
- PacketReader deserializes into typed packet instances
|
||||
- IncomingPacketFilters run first, then IncomingPacketHandlers route to specific logic
|
||||
- Handlers update game objects (e.g., Mobile, PlayerMobile)
|
||||
- Outgoing packets are serialized via PacketWriter, pass through OutgoingPacketFilters, and are sent
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Net as "Network I/O"
|
||||
participant Comp as "Compression"
|
||||
participant PH as "PacketHandler"
|
||||
participant IF as "IncomingPacketFilters"
|
||||
participant IH as "IncomingPacketHandlers"
|
||||
participant PR as "PacketReader"
|
||||
participant Obj as "Game Objects"
|
||||
participant OF as "OutgoingPacketFilters"
|
||||
participant OH as "OutgoingPacketHandlers"
|
||||
participant PW as "PacketWriter"
|
||||
Net->>Comp : "Raw bytes"
|
||||
Comp-->>PH : "Decompressed stream"
|
||||
PH->>PR : "Read next packet"
|
||||
PR-->>PH : "Typed packet instance"
|
||||
PH->>IF : "Run incoming filters"
|
||||
IF-->>PH : "Allow/Drop/Modify"
|
||||
PH->>IH : "Dispatch to handler"
|
||||
IH->>Obj : "Apply updates (e.g., Mobile)"
|
||||
Note over IH,Obj : "Event-driven updates propagate"
|
||||
PH->>OF : "Run outgoing filters"
|
||||
OF-->>PH : "Allow/Drop/Modify"
|
||||
PH->>PW : "Serialize outgoing packet"
|
||||
PW-->>Net : "Compressed bytes"
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [PacketHandler.cs](file://ClassicAssist.Shared/UO/Network/PacketHandler.cs)
|
||||
- [IncomingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketFilters.cs)
|
||||
- [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs)
|
||||
- [OutgoingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketFilters.cs)
|
||||
- [OutgoingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketHandlers.cs)
|
||||
- [PacketReader.cs](file://ClassicAssist.Shared/UO/Data/PacketReader.cs)
|
||||
- [PacketWriter.cs](file://ClassicAssist.Shared/UO/Data/PacketWriter.cs)
|
||||
- [Compression.cs](file://ClassicAssist.Shared/UO/Compression.cs)
|
||||
- [MobileUpdate.cs](file://ClassicAssist.Shared/UO/Network/Packets/MobileUpdate.cs)
|
||||
- [MobileMoving.cs](file://ClassicAssist.Shared/UO/Network/Packets/MobileMoving.cs)
|
||||
- [Mobile.cs](file://ClassicAssist.Shared/UO/Objects/Mobile.cs)
|
||||
- [PlayerMobile.cs](file://ClassicAssist.Shared/UO/Objects/PlayerMobile.cs)
|
||||
|
||||
## Detailed Component Analysis
|
||||
|
||||
### PacketHandler Architecture
|
||||
Responsibilities:
|
||||
- Lifecycle management and initialization
|
||||
- Version negotiation and protocol detection
|
||||
- Compression setup and teardown
|
||||
- Routing incoming packets through filters and handlers
|
||||
- Queuing actions for later execution
|
||||
- Serializing outgoing packets through filters and writers
|
||||
|
||||
Key behaviors:
|
||||
- Incoming path: read -> decompress -> parse -> filter -> dispatch -> apply
|
||||
- Outgoing path: create packet -> serialize -> filter -> compress -> send
|
||||
- Error propagation: exceptions during parsing/handling are captured and surfaced to the engine for logging and recovery
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class PacketHandler {
|
||||
+Initialize()
|
||||
+ProcessIncoming(bytes)
|
||||
+Send(packet)
|
||||
-RunIncomingFilters(packet)
|
||||
-DispatchIncoming(packet)
|
||||
-RunOutgoingFilters(packet)
|
||||
-SerializeOutgoing(packet)
|
||||
}
|
||||
class IncomingPacketHandlers {
|
||||
+Register(type, handler)
|
||||
+Invoke(packet)
|
||||
}
|
||||
class OutgoingPacketHandlers {
|
||||
+Register(type, writer)
|
||||
+Write(packet)
|
||||
}
|
||||
class IncomingPacketFilters {
|
||||
+Add(filter)
|
||||
+Execute(packet) bool
|
||||
}
|
||||
class OutgoingPacketFilters {
|
||||
+Add(filter)
|
||||
+Execute(packet) bool
|
||||
}
|
||||
class ActionPacketQueue {
|
||||
+Enqueue(item)
|
||||
+Drain()
|
||||
}
|
||||
class Compression {
|
||||
+Decompress(input) byte[]
|
||||
+Compress(data) byte[]
|
||||
}
|
||||
PacketHandler --> IncomingPacketHandlers : "dispatches"
|
||||
PacketHandler --> OutgoingPacketHandlers : "serializes"
|
||||
PacketHandler --> IncomingPacketFilters : "filters in"
|
||||
PacketHandler --> OutgoingPacketFilters : "filters out"
|
||||
PacketHandler --> ActionPacketQueue : "queues work"
|
||||
PacketHandler --> Compression : "uses"
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [PacketHandler.cs](file://ClassicAssist.Shared/UO/Network/PacketHandler.cs)
|
||||
- [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs)
|
||||
- [OutgoingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketHandlers.cs)
|
||||
- [IncomingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketFilters.cs)
|
||||
- [OutgoingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketFilters.cs)
|
||||
- [ActionPacketQueue.cs](file://ClassicAssist.Shared/UO/Network/ActionPacketQueue.cs)
|
||||
- [Compression.cs](file://ClassicAssist.Shared/UO/Compression.cs)
|
||||
|
||||
**Section sources**
|
||||
- [PacketHandler.cs](file://ClassicAssist.Shared/UO/Network/PacketHandler.cs)
|
||||
- [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs)
|
||||
- [OutgoingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketHandlers.cs)
|
||||
- [IncomingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketFilters.cs)
|
||||
- [OutgoingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketFilters.cs)
|
||||
- [ActionPacketQueue.cs](file://ClassicAssist.Shared/UO/Network/ActionPacketQueue.cs)
|
||||
- [Compression.cs](file://ClassicAssist.Shared/UO/Compression.cs)
|
||||
|
||||
### Incoming Packet Flow and Event Bus Pattern
|
||||
Flow highlights:
|
||||
- PacketReader reads fields according to the packet’s wire format
|
||||
- IncomingPacketHandlers maps packet type to a handler method
|
||||
- Handlers mutate game objects (e.g., Mobile, PlayerMobile)
|
||||
- Updates may trigger event notifications consumed by UI or subsystems
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant PH as "PacketHandler"
|
||||
participant PR as "PacketReader"
|
||||
participant IH as "IncomingPacketHandlers"
|
||||
participant MU as "MobileUpdate"
|
||||
participant MOB as "Mobile"
|
||||
participant PMOB as "PlayerMobile"
|
||||
PH->>PR : "Read packet header/type"
|
||||
PR-->>PH : "Instance of MobileUpdate"
|
||||
PH->>IH : "Invoke handler for MobileUpdate"
|
||||
IH->>MU : "Parse fields"
|
||||
MU->>MOB : "Update position/status"
|
||||
MOB->>PMOB : "Notify player-specific changes"
|
||||
Note over PH,IH : "Event-driven updates propagate to subscribers"
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [PacketHandler.cs](file://ClassicAssist.Shared/UO/Network/PacketHandler.cs)
|
||||
- [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs)
|
||||
- [PacketReader.cs](file://ClassicAssist.Shared/UO/Data/PacketReader.cs)
|
||||
- [MobileUpdate.cs](file://ClassicAssist.Shared/UO/Network/Packets/MobileUpdate.cs)
|
||||
- [Mobile.cs](file://ClassicAssist.Shared/UO/Objects/Mobile.cs)
|
||||
- [PlayerMobile.cs](file://ClassicAssist.Shared/UO/Objects/PlayerMobile.cs)
|
||||
|
||||
**Section sources**
|
||||
- [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs)
|
||||
- [PacketReader.cs](file://ClassicAssist.Shared/UO/Data/PacketReader.cs)
|
||||
- [MobileUpdate.cs](file://ClassicAssist.Shared/UO/Network/Packets/MobileUpdate.cs)
|
||||
- [Mobile.cs](file://ClassicAssist.Shared/UO/Objects/Mobile.cs)
|
||||
- [PlayerMobile.cs](file://ClassicAssist.Shared/UO/Objects/PlayerMobile.cs)
|
||||
|
||||
### Outgoing Packet Flow
|
||||
Flow highlights:
|
||||
- Create a typed packet object
|
||||
- OutgoingPacketHandlers serializes it using PacketWriter
|
||||
- OutgoingPacketFilters can inspect/modify/drop
|
||||
- Compression is applied before sending
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant App as "Application Code"
|
||||
participant OH as "OutgoingPacketHandlers"
|
||||
participant PW as "PacketWriter"
|
||||
participant OF as "OutgoingPacketFilters"
|
||||
participant PH as "PacketHandler"
|
||||
participant Net as "Network I/O"
|
||||
App->>OH : "Create and enqueue packet"
|
||||
OH->>PW : "Serialize packet"
|
||||
PW-->>OH : "Byte buffer"
|
||||
OH->>OF : "Run outgoing filters"
|
||||
OF-->>OH : "Allow/Drop/Modify"
|
||||
OH->>PH : "Return processed buffer"
|
||||
PH->>Net : "Send compressed bytes"
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [OutgoingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketHandlers.cs)
|
||||
- [PacketWriter.cs](file://ClassicAssist.Shared/UO/Data/PacketWriter.cs)
|
||||
- [OutgoingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketFilters.cs)
|
||||
- [PacketHandler.cs](file://ClassicAssist.Shared/UO/Network/PacketHandler.cs)
|
||||
|
||||
**Section sources**
|
||||
- [OutgoingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketHandlers.cs)
|
||||
- [PacketWriter.cs](file://ClassicAssist.Shared/UO/Data/PacketWriter.cs)
|
||||
- [OutgoingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketFilters.cs)
|
||||
- [PacketHandler.cs](file://ClassicAssist.Shared/UO/Network/PacketHandler.cs)
|
||||
|
||||
### Compression Handling and Protocol Version Detection
|
||||
- Compression: Decompression occurs before parsing; compression is applied after filtering and before transmission.
|
||||
- Protocol version detection: Handled during initialization and handshake; influences which packet formats and handlers are active.
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start(["Start"]) --> Detect["Detect protocol version"]
|
||||
Detect --> InitComp["Initialize compression context"]
|
||||
InitComp --> ReadLoop["Read loop"]
|
||||
ReadLoop --> InFilter{"Incoming filters allow?"}
|
||||
InFilter --> |No| DropIn["Drop packet"]
|
||||
InFilter --> |Yes| Parse["Parse packet"]
|
||||
Parse --> Dispatch["Dispatch to handler"]
|
||||
Dispatch --> Update["Update game objects"]
|
||||
Update --> ReadLoop
|
||||
DropIn --> ReadLoop
|
||||
ReadLoop --> End(["Stop"])
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [Compression.cs](file://ClassicAssist.Shared/UO/Compression.cs)
|
||||
- [PacketHandler.cs](file://ClassicAssist.Shared/UO/Network/PacketHandler.cs)
|
||||
- [IncomingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketFilters.cs)
|
||||
|
||||
**Section sources**
|
||||
- [Compression.cs](file://ClassicAssist.Shared/UO/Compression.cs)
|
||||
- [PacketHandler.cs](file://ClassicAssist.Shared/UO/Network/PacketHandler.cs)
|
||||
- [IncomingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketFilters.cs)
|
||||
|
||||
### Error Propagation and Recovery
|
||||
- Parsing errors: Invalid headers or truncated packets raise exceptions; these are caught by the handler layer and logged.
|
||||
- Handler errors: Exceptions thrown inside handlers are wrapped and propagated to the engine for centralized handling.
|
||||
- Filter errors: Filters must not throw; they should return a decision (allow/drop) and log issues internally.
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Entry(["Incoming packet"]) --> TryParse["Try parse"]
|
||||
TryParse --> Ok{"Parsed OK?"}
|
||||
Ok --> |No| LogErr["Log parse error"]
|
||||
LogErr --> Next["Next packet"]
|
||||
Ok --> RunFilters["Run incoming filters"]
|
||||
RunFilters --> Allow{"Allowed?"}
|
||||
Allow --> |No| Drop["Drop packet"]
|
||||
Allow --> |Yes| InvokeHandler["Invoke handler"]
|
||||
InvokeHandler --> HOk{"Handler OK?"}
|
||||
HOk --> |No| WrapErr["Wrap and propagate error"]
|
||||
HOk --> |Yes| Apply["Apply updates"]
|
||||
Apply --> Next
|
||||
Drop --> Next
|
||||
Next --> Exit(["Exit"])
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [PacketHandler.cs](file://ClassicAssist.Shared/UO/Network/PacketHandler.cs)
|
||||
- [IncomingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketFilters.cs)
|
||||
- [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs)
|
||||
|
||||
**Section sources**
|
||||
- [PacketHandler.cs](file://ClassicAssist.Shared/UO/Network/PacketHandler.cs)
|
||||
- [IncomingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketFilters.cs)
|
||||
- [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs)
|
||||
|
||||
### Concrete Examples
|
||||
|
||||
#### Registering an Incoming Packet Handler
|
||||
- Use the incoming registry to map a packet type to a handler method.
|
||||
- Ensure the handler accepts the correct packet type and updates game objects safely.
|
||||
|
||||
**Section sources**
|
||||
- [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs)
|
||||
- [BasePacket.cs](file://ClassicAssist.Shared/UO/Network/Packets/BasePacket.cs)
|
||||
|
||||
#### Invoking a Handler and Updating Entities
|
||||
- A MobileUpdate packet parses fields and applies changes to Mobile/PlayerMobile.
|
||||
- Subscribers receive updates via events or property change notifications.
|
||||
|
||||
**Section sources**
|
||||
- [MobileUpdate.cs](file://ClassicAssist.Shared/UO/Network/Packets/MobileUpdate.cs)
|
||||
- [Mobile.cs](file://ClassicAssist.Shared/UO/Objects/Mobile.cs)
|
||||
- [PlayerMobile.cs](file://ClassicAssist.Shared/UO/Objects/PlayerMobile.cs)
|
||||
|
||||
#### Sending an Outgoing Packet
|
||||
- Construct a typed packet, enqueue it, and let OutgoingPacketHandlers serialize it.
|
||||
- Filters can intercept to log or modify content before compression and send.
|
||||
|
||||
**Section sources**
|
||||
- [OutgoingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketHandlers.cs)
|
||||
- [OutgoingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketFilters.cs)
|
||||
- [PacketWriter.cs](file://ClassicAssist.Shared/UO/Data/PacketWriter.cs)
|
||||
|
||||
#### Implementing a Custom Packet Handler
|
||||
Steps:
|
||||
1. Define a new packet class derived from BasePacket if needed.
|
||||
2. Register an incoming handler mapping your packet type to a method.
|
||||
3. In the handler, use PacketReader to parse fields and update relevant objects.
|
||||
4. If you need to defer work, enqueue items via ActionPacketQueue.
|
||||
|
||||
**Section sources**
|
||||
- [BasePacket.cs](file://ClassicAssist.Shared/UO/Network/Packets/BasePacket.cs)
|
||||
- [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs)
|
||||
- [PacketReader.cs](file://ClassicAssist.Shared/UO/Data/PacketReader.cs)
|
||||
- [ActionPacketQueue.cs](file://ClassicAssist.Shared/UO/Network/ActionPacketQueue.cs)
|
||||
|
||||
## Dependency Analysis
|
||||
High-level dependencies between networking components and game objects:
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
PH["PacketHandler"] --> INH["IncomingPacketHandlers"]
|
||||
PH --> OUTH["OutgoingPacketHandlers"]
|
||||
PH --> INF["IncomingPacketFilters"]
|
||||
PH --> OUTF["OutgoingPacketFilters"]
|
||||
PH --> APQ["ActionPacketQueue"]
|
||||
INH --> PR["PacketReader"]
|
||||
OUTH --> PW["PacketWriter"]
|
||||
INH --> MU["MobileUpdate"]
|
||||
INH --> MM["MobileMoving"]
|
||||
MU --> MOB["Mobile"]
|
||||
MM --> MOB
|
||||
MOB --> ENT["Entity"]
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [PacketHandler.cs](file://ClassicAssist.Shared/UO/Network/PacketHandler.cs)
|
||||
- [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs)
|
||||
- [OutgoingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketHandlers.cs)
|
||||
- [IncomingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketFilters.cs)
|
||||
- [OutgoingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketFilters.cs)
|
||||
- [ActionPacketQueue.cs](file://ClassicAssist.Shared/UO/Network/ActionPacketQueue.cs)
|
||||
- [PacketReader.cs](file://ClassicAssist.Shared/UO/Data/PacketReader.cs)
|
||||
- [PacketWriter.cs](file://ClassicAssist.Shared/UO/Data/PacketWriter.cs)
|
||||
- [MobileUpdate.cs](file://ClassicAssist.Shared/UO/Network/Packets/MobileUpdate.cs)
|
||||
- [MobileMoving.cs](file://ClassicAssist.Shared/UO/Network/Packets/MobileMoving.cs)
|
||||
- [Mobile.cs](file://ClassicAssist.Shared/UO/Objects/Mobile.cs)
|
||||
- [Entity.cs](file://ClassicAssist.Shared/UO/Objects/Entity.cs)
|
||||
|
||||
**Section sources**
|
||||
- [PacketHandler.cs](file://ClassicAssist.Shared/UO/Network/PacketHandler.cs)
|
||||
- [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs)
|
||||
- [OutgoingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketHandlers.cs)
|
||||
- [IncomingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketFilters.cs)
|
||||
- [OutgoingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketFilters.cs)
|
||||
- [ActionPacketQueue.cs](file://ClassicAssist.Shared/UO/Network/ActionPacketQueue.cs)
|
||||
- [PacketReader.cs](file://ClassicAssist.Shared/UO/Data/PacketReader.cs)
|
||||
- [PacketWriter.cs](file://ClassicAssist.Shared/UO/Data/PacketWriter.cs)
|
||||
- [MobileUpdate.cs](file://ClassicAssist.Shared/UO/Network/Packets/MobileUpdate.cs)
|
||||
- [MobileMoving.cs](file://ClassicAssist.Shared/UO/Network/Packets/MobileMoving.cs)
|
||||
- [Mobile.cs](file://ClassicAssist.Shared/UO/Objects/Mobile.cs)
|
||||
- [Entity.cs](file://ClassicAssist.Shared/UO/Objects/Entity.cs)
|
||||
|
||||
## Performance Considerations
|
||||
- Minimize allocations in hot paths:
|
||||
- Reuse buffers where possible in PacketReader/Writer.
|
||||
- Avoid per-packet object creation when simple primitives suffice.
|
||||
- Keep handlers fast:
|
||||
- Do heavy work off the main thread; enqueue via ActionPacketQueue.
|
||||
- Batch updates to reduce UI churn.
|
||||
- Filtering efficiency:
|
||||
- Place cheap checks early in filter chains.
|
||||
- Avoid expensive string operations in tight loops.
|
||||
- Compression overhead:
|
||||
- Tune compression settings based on bandwidth vs CPU trade-offs.
|
||||
- Threading model:
|
||||
- Ensure thread-safe access to shared game objects.
|
||||
- Use queues to decouple network I/O from game logic.
|
||||
|
||||
[No sources needed since this section provides general guidance]
|
||||
|
||||
## Troubleshooting Guide
|
||||
Common issues and remedies:
|
||||
- Parse failures: Check packet length and version compatibility; verify PacketReader usage matches wire format.
|
||||
- Missing handlers: Confirm registration of incoming handlers for expected packet types.
|
||||
- Dropped packets: Inspect incoming/outgoing filters to ensure they are not inadvertently dropping traffic.
|
||||
- High CPU usage: Profile handlers and filters; move heavy work to background queues.
|
||||
- Memory pressure: Monitor allocations in hot paths; consider pooling strategies.
|
||||
|
||||
**Section sources**
|
||||
- [PacketHandler.cs](file://ClassicAssist.Shared/UO/Network/PacketHandler.cs)
|
||||
- [IncomingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketFilters.cs)
|
||||
- [OutgoingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketFilters.cs)
|
||||
- [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs)
|
||||
- [OutgoingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketHandlers.cs)
|
||||
|
||||
## Conclusion
|
||||
The ClassicAssist.Avalonia packet pipeline cleanly separates concerns across parsing, filtering, dispatch, and application updates. By leveraging typed packets, a central PacketHandler, and pluggable filters, the system remains extensible and maintainable. Following the performance and troubleshooting recommendations ensures robust operation under high-frequency network loads.
|
||||
|
||||
[No sources needed since this section summarizes without analyzing specific files]
|
||||
|
||||
## Appendices
|
||||
|
||||
### Quick Reference: Typical Registration and Usage Paths
|
||||
- Incoming registration: Map packet type to handler in IncomingPacketHandlers.
|
||||
- Outgoing usage: Create packet, enqueue, and rely on OutgoingPacketHandlers to serialize.
|
||||
- Custom filters: Add to IncomingPacketFilters or OutgoingPacketFilters for inspection/modification.
|
||||
- Deferring work: Enqueue tasks via ActionPacketQueue for later processing.
|
||||
|
||||
**Section sources**
|
||||
- [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs)
|
||||
- [OutgoingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketHandlers.cs)
|
||||
- [IncomingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketFilters.cs)
|
||||
- [OutgoingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketFilters.cs)
|
||||
- [ActionPacketQueue.cs](file://ClassicAssist.Shared/UO/Network/ActionPacketQueue.cs)
|
||||
Reference in New Issue
Block a user