Files
ClassicAssist.Avalonia/.qoder/repowiki/en/content/Technical Architecture/Technical Architecture.md
T
Beyhan Oğur d5f52cc3d3 first commit
2026-09-03 04:45:36 +03:00

27 KiB
Raw Blame History

Technical Architecture

**Referenced Files in This Document** - [Program.cs](file://ClassicAssist.Avalonia/Program.cs) - [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs) - [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs) - [AvaloniaDispatcher.cs](file://ClassicAssist.Avalonia/AvaloniaDispatcher.cs) - [AvaloniaUIInvoker.cs](file://ClassicAssist.Avalonia/AvaloniaUIInvoker.cs) - [MainWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/MainWindow.axaml.cs) - [Engine.cs](file://ClassicAssist.Shared/Engine.cs) - [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs) - [OutgoingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketHandlers.cs) - [PacketHandler.cs](file://ClassicAssist.Shared/UO/Network/PacketHandler.cs) - [ActionPacketQueue.cs](file://ClassicAssist.Shared/UO/Network/ActionPacketQueue.cs) - [IncomingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketFilters.cs) - [Entity.cs](file://ClassicAssist.Shared/UO/Objects/Entity.cs) - [Mobile.cs](file://ClassicAssist.Shared/UO/Objects/Mobile.cs) - [Item.cs](file://ClassicAssist.Shared/UO/Objects/Item.cs) - [Gump.cs](file://ClassicAssist.Shared/UO/Objects/Gumps/Gump.cs) - [IDispatcher.cs](file://ClassicAssist.Shared/IDispatcher.cs) - [IUIInvoker.cs](file://ClassicAssist.Shared/IUIInvoker.cs) - [BaseViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/BaseViewModel.cs) - [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs) - [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs) - [CommandsManager.cs](file://ClassicAssist.Shared/Data/Commands/CommandsManager.cs) - [ChatManager.cs](file://ClassicAssist.Shared/Data/Chat/ChatManager.cs) - [AutolootManager.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootManager.cs) - [DressManager.cs](file://ClassicAssist.Shared/Data/Dress/DressManager.cs) - [ScavengerManager.cs](file://ClassicAssist.Shared/Data/Scavenger/ScavengerManager.cs) - [OrganizerManager.cs](file://ClassicAssist.Shared/Data/Organizer/OrganizerManager.cs) - [CountersManager.cs](file://ClassicAssist.Shared/Data/Counters/CountersManager.cs) - [TargetManager.cs](file://ClassicAssist.Shared/UO/Network/Targeting/TargetManager.cs) - [PlatformDetector.cs](file://ClassicAssist.Shared/Engine/PlatformDetector.cs)

Table of Contents

  1. Introduction
  2. Project Structure
  3. Core Components
  4. Architecture Overview
  5. Detailed Component Analysis
  6. Dependency Analysis
  7. Performance Considerations
  8. Troubleshooting Guide
  9. Conclusion
  10. Appendices

Introduction

This document describes the technical architecture of ClassicAssist.Avalonia, focusing on layered design, packet processing pipeline, event-driven communication, lifecycle and plugin management, resource strategies, cross-platform considerations for Avalonia and .NET, system boundaries, integration points, scalability, memory management, performance optimization, technology stack decisions, and architectural trade-offs. The goal is to provide a comprehensive yet accessible guide for both developers and advanced users.

Project Structure

The solution is organized into multiple projects with clear separation of concerns:

  • ClassicAssist.Avalonia: Avalonia-based UI application entry point, platform-specific dispatchers, and UI composition.
  • ClassicAssist.Shared: Core engine, game data models, networking, packet handling, agents, macros, hotkeys, commands, chat, and shared UI view models.
  • ClassicAssist.Launcher: WPF-based launcher for shard selection and plugin management.
  • ClassicAssist.Updater: WPF-based updater utility.
  • Tests and tools under dedicated test and tool projects.
graph TB
subgraph "UI Layer (Avalonia)"
A_Program["Program.cs"]
A_App["App.axaml.cs"]
A_Engine["Engine.cs"]
A_Dispatcher["AvaloniaDispatcher.cs"]
A_Invoker["AvaloniaUIInvoker.cs"]
A_MainWindow["MainWindow.axaml.cs"]
end
subgraph "Shared Engine"
S_Engine["Engine.cs"]
S_NetIn["IncomingPacketHandlers.cs"]
S_NetOut["OutgoingPacketHandlers.cs"]
S_PktHdlr["PacketHandler.cs"]
S_Acq["ActionPacketQueue.cs"]
S_IncFilt["IncomingPacketFilters.cs"]
S_Entities["Entity.cs / Mobile.cs / Item.cs"]
S_Gump["Gump.cs"]
S_Hotkeys["HotkeyManager.cs"]
S_Macros["MacroManager.cs"]
S_Commands["CommandsManager.cs"]
S_Chat["ChatManager.cs"]
S_Target["TargetManager.cs"]
S_Platform["PlatformDetector.cs"]
end
A_Program --> A_App
A_App --> A_Engine
A_Engine --> S_Engine
A_Dispatcher --> S_Engine
A_Invoker --> S_Engine
A_MainWindow --> S_Engine
S_Engine --> S_NetIn
S_Engine --> S_NetOut
S_Engine --> S_PktHdlr
S_Engine --> S_Acq
S_Engine --> S_IncFilt
S_Engine --> S_Entities
S_Engine --> S_Gump
S_Engine --> S_Hotkeys
S_Engine --> S_Macros
S_Engine --> S_Commands
S_Engine --> S_Chat
S_Engine --> S_Target
S_Engine --> S_Platform

Diagram sources

Section sources

Core Components

  • Application bootstrap and UI composition: Program initializes the Avalonia app, App configures services and root window, and MainWindow hosts main UI content.
  • Cross-platform dispatcher and UI invoker: AvaloniaDispatcher and AvaloniaUIInvoker implement shared interfaces to marshal work onto the UI thread consistently across platforms.
  • Shared engine: Centralizes lifecycle, subsystem initialization, configuration, and coordination between network, entities, agents, macros, hotkeys, and commands.
  • Networking layer: Packet handlers, filters, queues, and target manager orchestrate incoming/outgoing traffic and maintain game state.
  • Game objects: Entity hierarchy (Entity, Mobile, Item), Gumps, and collections represent world state.
  • Managers: Hotkey, Macro, Commands, Chat, Autoloot, Dress, Scavenger, Organizer, Counters, and Target managers encapsulate domain logic and expose APIs to UI and plugins.

Key responsibilities:

  • UI layer: Rendering, user input, and presentation logic only; delegates to shared engine via dispatchers.
  • Shared engine: Orchestrates subsystems, manages lifecycle, exposes stable APIs, and coordinates events.
  • Network layer: Parses packets, updates entities, enforces filters, and queues actions.
  • Managers: Provide cohesive APIs for features like hotkeys, macros, chat, targeting, and agent behaviors.

Section sources

Architecture Overview

The system follows a layered architecture:

  • Presentation Layer (Avalonia): Views, ViewModels, and controls. Uses MVVM patterns and binds to shared state exposed by the engine.
  • Domain Layer (Shared): Business logic, game rules, managers, and object models.
  • Infrastructure Layer (Networking and Platform Abstractions): Packet I/O, filters, queues, and platform-specific dispatchers.
graph TB
UI["Avalonia UI<br/>Views + ViewModels"] --> Dispatcher["AvaloniaDispatcher<br/>and AvaloniaUIInvoker"]
Dispatcher --> Engine["Shared Engine"]
Engine --> Net["Networking Layer<br/>Packets, Filters, Queues"]
Engine --> Entities["Game Objects<br/>Entity, Mobile, Item, Gump"]
Engine --> Managers["Managers<br/>Hotkeys, Macros, Commands, Chat, Agents, Target"]
Net --> Entities
Managers --> Entities
UI <- --> Managers

Diagram sources

Detailed Component Analysis

Packet Processing Pipeline

End-to-end flow from network I/O to entity updates:

  • Incoming packets are received and routed through filters.
  • Filtered packets are dispatched to registered handlers.
  • Handlers update game objects (entities, gumps).
  • Actions may be queued for later execution or sent back out.
sequenceDiagram
participant Net as "Network I/O"
participant Filters as "IncomingPacketFilters"
participant Handler as "IncomingPacketHandlers"
participant Pkt as "PacketHandler"
participant Queue as "ActionPacketQueue"
participant Entities as "Entity/Mobile/Item/Gump"
Net->>Filters : "Receive raw packet"
Filters-->>Net : "Allow/Deny"
Filters->>Handler : "Dispatch allowed packet"
Handler->>Pkt : "Resolve handler by opcode"
Pkt->>Entities : "Update state"
Pkt->>Queue : "Enqueue action if needed"
Queue-->>Pkt : "Dequeue and execute"
Pkt-->>Net : "Send outgoing packets if required"

Diagram sources

Section sources

Event-Driven Architecture and Message Bus Patterns

  • Managers expose events and publish messages for decoupled communication between components (e.g., chat messages, macro triggers, hotkey activations).
  • UI components subscribe to these events and update bindings accordingly.
  • The shared engine coordinates event publication and subscription lifecycles.
classDiagram
class Engine {
+Initialize()
+PublishEvent(event)
+Subscribe(event, handler)
}
class ChatManager {
+OnMessageReceived()
+SendMessage(text)
}
class HotkeyManager {
+OnHotkeyPressed(key)
+Register(key, command)
}
class MacroManager {
+OnMacroTriggered(name)
+RunMacro(name)
}
class CommandsManager {
+Execute(command)
+Register(alias, handler)
}
class BaseViewModel {
+NotifyPropertyChanged()
+BindTo(event)
}
Engine --> ChatManager : "coordinates"
Engine --> HotkeyManager : "coordinates"
Engine --> MacroManager : "coordinates"
Engine --> CommandsManager : "coordinates"
BaseViewModel --> Engine : "subscribes"

Diagram sources

Section sources

Game Engine Lifecycle Management

Lifecycle phases:

  • Bootstrap: Program creates App, App constructs Engine and UI.
  • Initialization: Engine loads configuration, registers packet handlers, initializes managers, and prepares resources.
  • Runtime: Engine runs message loop, processes network events, handles hotkeys/macros/commands, and updates UI via dispatcher.
  • Shutdown: Engine disposes resources, flushes queues, and releases subscriptions.
flowchart TD
Start(["Application Start"]) --> Boot["Program -> App -> Engine"]
Boot --> Init["Engine.Initialize()<br/>Load config, register handlers, init managers"]
Init --> Run["Engine.Run()<br/>Process network, UI, and subsystem events"]
Run --> Update["Update entities, gumps, and UI state"]
Update --> Run
Run --> Shutdown["Engine.Dispose()<br/>Flush queues, release resources"]
Shutdown --> End(["Exit"])

Diagram sources

Section sources

Plugin Loading Mechanisms

  • The launcher project provides plugin discovery and loading capabilities for external modules.
  • Plugins can extend functionality such as commands, macros, or UI elements.
  • The shared engine integrates with plugin manifests and metadata to load and manage extensions safely.
sequenceDiagram
participant Launcher as "Launcher"
participant Manifest as "Plugin Manifest"
participant Loader as "Plugin Loader"
participant Engine as "Shared Engine"
participant Plugin as "External Plugin"
Launcher->>Manifest : "Read manifest entries"
Manifest-->>Loader : "List of plugins"
Loader->>Engine : "Register plugin capabilities"
Engine->>Plugin : "Invoke extension points"
Plugin-->>Engine : "Provide commands/macro helpers/UI"

Diagram sources

Section sources

Resource Management Strategies

  • Static resources (fonts, icons, themes) are packaged within the Avalonia project and loaded at startup.
  • Data files (JSON configurations, cliloc, tile data) are loaded lazily and cached to minimize I/O overhead.
  • Memory-sensitive structures (entity collections, buffers) use efficient containers and avoid unnecessary allocations.
flowchart TD
LoadStart["Startup"] --> LoadResources["Load static resources<br/>Fonts, Icons, Themes"]
LoadResources --> LoadData["Load data files<br/>JSON configs, Cliloc, TileData"]
LoadData --> Cache["Cache in memory<br/>Lazy reload on change"]
Cache --> Runtime["Runtime access<br/>Fast lookups"]

Diagram sources

Section sources

Cross-Platform Considerations (Avalonia and .NET)

  • Avalonia provides consistent UI across Windows, macOS, and Linux.
  • Platform detection abstracts OS-specific behavior and influences runtime paths and native calls.
  • Dispatchers ensure UI updates occur on the correct thread per platform.
classDiagram
class IDispatcher {
+Invoke(action)
+BeginInvoke(action)
}
class AvaloniaDispatcher {
+Invoke(action)
+BeginInvoke(action)
}
class IUIInvoker {
+ShowDialog(title, content)
+MessageBox(message)
}
class AvaloniaUIInvoker {
+ShowDialog(title, content)
+MessageBox(message)
}
class PlatformDetector {
+GetOS() string
+IsWindows() bool
+IsMacOS() bool
+IsLinux() bool
}
IDispatcher <|.. AvaloniaDispatcher
IUIInvoker <|.. AvaloniaUIInvoker
PlatformDetector ..> AvaloniaDispatcher : "uses"
PlatformDetector ..> AvaloniaUIInvoker : "uses"

Diagram sources

Section sources

System Boundaries and Integration Points

  • External dependencies:
    • Avalonia UI framework for cross-platform rendering.
    • .NET runtime for managed code execution.
    • Optional native libraries for platform-specific features.
  • Integration points:
    • Network socket I/O to Ultima Online servers.
    • File system for configuration and data assets.
    • Plugin loader for extensibility.
graph TB
App["ClassicAssist.Avalonia"] --> Shared["ClassicAssist.Shared"]
App --> Avalonia["Avalonia UI Framework"]
App --> DotNet[".NET Runtime"]
Shared --> UOServer["Ultima Online Server"]
Shared --> FileSystem["File System"]
Shared --> Plugins["Plugin Loader"]

Diagram sources

Section sources

Dependency Analysis

High-level dependency relationships among core components:

graph TB
Engine["Engine.cs"] --> NetIn["IncomingPacketHandlers.cs"]
Engine --> NetOut["OutgoingPacketHandlers.cs"]
Engine --> PktHdlr["PacketHandler.cs"]
Engine --> Acq["ActionPacketQueue.cs"]
Engine --> IncFilt["IncomingPacketFilters.cs"]
Engine --> Ent["Entity.cs / Mobile.cs / Item.cs"]
Engine --> Gump["Gump.cs"]
Engine --> Hotkeys["HotkeyManager.cs"]
Engine --> Macros["MacroManager.cs"]
Engine --> Commands["CommandsManager.cs"]
Engine --> Chat["ChatManager.cs"]
Engine --> Target["TargetManager.cs"]
UI["AvaloniaDispatcher.cs / AvaloniaUIInvoker.cs"] --> Engine

Diagram sources

Section sources

Performance Considerations

  • Packet filtering reduces CPU usage by dropping irrelevant messages early.
  • Action queues batch operations to avoid excessive UI updates and reduce contention.
  • Efficient data structures (collections, caches) minimize allocations and improve lookup times.
  • Lazy loading of heavy resources prevents startup delays.
  • Threading model ensures UI responsiveness by marshalling updates off the UI thread using dispatchers.

[No sources needed since this section provides general guidance]

Troubleshooting Guide

Common issues and diagnostics:

  • Network connectivity problems: Verify server address, firewall settings, and packet filter rules.
  • UI freezes: Ensure all UI updates go through the dispatcher; check for long-running tasks blocking the UI thread.
  • Missing resources: Confirm asset paths and that resources are included in the build output.
  • Plugin failures: Validate plugin manifests and compatibility with the current engine version.

Recommended steps:

  • Enable verbose logging in the engine and review logs for errors.
  • Temporarily disable filters to isolate packet-related issues.
  • Use the launcher’s options to reset configuration and reinitialize resources.

Section sources

Conclusion

ClassicAssist.Avalonia employs a clean layered architecture with a robust shared engine, explicit networking pipeline, and event-driven communication. The Avalonia UI layer remains thin and focused on presentation, while the shared layer encapsulates game logic, state, and integrations. Cross-platform abstractions and careful resource management contribute to stability and performance. Scalability is supported through modular managers, queues, and lazy loading, while plugin mechanisms enable extensibility.

[No sources needed since this section summarizes without analyzing specific files]

Appendices

  • Technology stack decisions:
    • Avalonia for cross-platform UI consistency.
    • .NET runtime for managed performance and ecosystem.
    • JSON-based configuration and data assets for portability.
  • Architectural trade-offs:
    • Separation of UI and engine improves testability but adds indirection.
    • Event-driven design enhances modularity but requires careful lifecycle management.
    • Queued actions balance throughput and UI responsiveness.

[No sources needed since this section provides general guidance]