# Advanced Features **Referenced Files in This Document** - [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs) - [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs) - [Program.cs](file://ClassicAssist.Avalonia/Program.cs) - [AvaloniaDispatcher.cs](file://ClassicAssist.Avalonia/AvaloniaDispatcher.cs) - [AvaloniaUIInvoker.cs](file://ClassicAssist.Avalonia/AvaloniaUIInvoker.cs) - [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.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) - [PacketFilter.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilter.cs) - [PacketFilterInfo.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterInfo.cs) - [PacketFilterCondition.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterCondition.cs) - [PacketFilterConditions.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterConditions.cs) - [PacketWaitEntry.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketWaitEntry.cs) - [PacketWaitEntries.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketWaitEntries.cs) - [BasePacket.cs](file://ClassicAssist.Shared/UO/Network/Packets/BasePacket.cs) - [ActionPacketQueue.cs](file://ClassicAssist.Shared/UO/Network/ActionPacketQueue.cs) - [ThreadQueue.cs](file://ClassicAssist.Shared/Misc/ThreadQueue.cs) - [ThreadPriorityQueue.cs](file://ClassicAssist.Shared/Misc/ThreadPriorityQueue.cs) - [OffsetStopwatch.cs](file://ClassicAssist.Shared/Misc/OffsetStopwatch.cs) - [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs) - [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs) - [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs) - [CommandsManager.cs](file://ClassicAssist.Shared/Data/Commands/CommandsManager.cs) - [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.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) - [VendorBuyAgentEntry.cs](file://ClassicAssist.Shared/Data/Vendors/VendorBuyAgentEntry.cs) - [VendorSellAgentEntry.cs](file://ClassicAssist.Shared/Data/Vendors/VendorSellAgentEntry.cs) - [ClilocFilter.cs](file://ClassicAssist.Shared/Data/Filters/ClilocFilter.cs) - [RepeatedMessagesFilter.cs](file://ClassicAssist.Shared/Data/Filters/RepeatedMessagesFilter.cs) - [LightLevelFilter.cs](file://ClassicAssist.Shared/Data/Filters/LightLevelFilter.cs) - [SeasonFilter.cs](file://ClassicAssist.Shared/Data/Filters/SeasonFilter.cs) - [WeatherFilter.cs](file://ClassicAssist.Shared/Data/Filters/WeatherFilter.cs) - [BardsMusicFilter.cs](file://ClassicAssist.Shared/Data/Filters/BardsMusicFilter.cs) - [DynamicFilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/DynamicFilterEntry.cs) - [FilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/FilterEntry.cs) - [IConfigurableFilter.cs](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.cs) - [FilterOptionsAttribute.cs](file://ClassicAssist.Shared/Data/Filters/FilterOptionsAttribute.cs) - [EntityCollectionViewerViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/EntityCollectionViewerViewModel.cs) - [ChatViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/ChatViewModel.cs) - [AgentsTabControl.axaml.cs](file://ClassicAssist.Avalonia/Views/Agents/AgentsTabControl.axaml.cs) ## 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) ## Introduction This document explains the advanced features and extension points of ClassicAssist.Avalonia with a focus on: - Agent framework for custom automation agents integrated with the rule engine - Filter system for message processing, including custom filters and performance considerations - Plugin architecture, extension points, loading mechanisms, and distribution strategies - Reflection-based command discovery and dynamic assembly loading - Event hooks and inter-component communication patterns - Advanced networking features such as packet manipulation and protocol extensions - Threading models, concurrency patterns, and performance optimization techniques The goal is to provide both high-level understanding and code-level guidance for extending and optimizing the application. ## Project Structure ClassicAssist.Avalonia is organized into layered modules: - UI layer (Avalonia): Views, ViewModels, controls, and platform-specific dispatchers - Shared core: Networking, data models, macro system, hotkeys, commands, filters, and utilities - Agents: Feature-specific managers implementing agent behaviors (autoloot, dress, scavenger, vendors) - Filters: Built-in filters and filter configuration infrastructure - Networking: Packet handlers, filters, queues, and wait entries for request/response flows ```mermaid graph TB subgraph "Avalonia UI" A_App["App.axaml.cs"] A_Program["Program.cs"] A_Engine["Engine.cs"] A_Dispatcher["AvaloniaDispatcher.cs"] A_Invoker["AvaloniaUIInvoker.cs"] A_VM_Entity["EntityCollectionViewerViewModel.cs"] A_VM_Chat["ChatViewModel.cs"] end subgraph "Shared Core" S_Filters["Filters.cs"] S_Hotkeys["HotkeyManager.cs"] S_Macros["MacroManager.cs"] S_Commands["CommandsManager.cs"] S_Reflection["Reflection.cs"] S_ThreadQ["ThreadQueue.cs"] S_PrioQ["ThreadPriorityQueue.cs"] S_Stopwatch["OffsetStopwatch.cs"] end subgraph "Networking" N_InHandlers["IncomingPacketHandlers.cs"] N_OutHandlers["OutgoingPacketHandlers.cs"] N_InFilters["IncomingPacketFilters.cs"] N_OutFilters["OutgoingPacketFilters.cs"] N_Filter["PacketFilter.cs"] N_FilterInfo["PacketFilterInfo.cs"] N_FilterCond["PacketFilterCondition.cs"] N_FilterConds["PacketFilterConditions.cs"] N_WaitEntry["PacketWaitEntry.cs"] N_WaitEntries["PacketWaitEntries.cs"] N_BasePkt["BasePacket.cs"] N_ActionQ["ActionPacketQueue.cs"] end subgraph "Agents" G_Auto["AutolootManager.cs"] G_Dress["DressManager.cs"] G_Scav["ScavengerManager.cs"] G_VBuy["VendorBuyAgentEntry.cs"] G_VSell["VendorSellAgentEntry.cs"] end subgraph "Filters" F_Cliloc["ClilocFilter.cs"] F_Repeat["RepeatedMessagesFilter.cs"] F_Light["LightLevelFilter.cs"] F_Season["SeasonFilter.cs"] F_Weather["WeatherFilter.cs"] F_Bard["BardsMusicFilter.cs"] F_Dyn["DynamicFilterEntry.cs"] F_Entry["FilterEntry.cs"] F_Config["IConfigurableFilter.cs"] F_Options["FilterOptionsAttribute.cs"] end A_App --> A_Engine A_Program --> A_App A_Engine --> S_Filters A_Engine --> N_InHandlers A_Engine --> N_OutHandlers A_Engine --> N_InFilters A_Engine --> N_OutFilters A_VM_Entity --> S_Filters A_VM_Chat --> S_Filters N_InHandlers --> N_Filter N_OutHandlers --> N_Filter N_Filter --> N_FilterInfo N_Filter --> N_FilterCond N_Filter --> N_FilterConds N_InHandlers --> N_WaitEntries N_OutHandlers --> N_WaitEntries N_InHandlers --> N_ActionQ N_OutHandlers --> N_ActionQ S_Macros --> S_Commands S_Macros --> S_Reflection S_Hotkeys --> S_Commands G_Auto --> S_Filters G_Dress --> S_Filters G_Scav --> S_Filters G_VBuy --> S_Filters G_VSell --> S_Filters S_Filters --> F_Entry S_Filters --> F_Dyn S_Filters --> F_Config S_Filters --> F_Options S_Filters --> F_Cliloc S_Filters --> F_Repeat S_Filters --> F_Light S_Filters --> F_Season S_Filters --> F_Weather S_Filters --> F_Bard S_ThreadQ --> N_ActionQ S_PrioQ --> N_ActionQ S_Stopwatch --> N_InHandlers S_Stopwatch --> N_OutHandlers ``` **Diagram sources** - [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs) - [Program.cs](file://ClassicAssist.Avalonia/Program.cs) - [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs) - [AvaloniaDispatcher.cs](file://ClassicAssist.Avalonia/AvaloniaDispatcher.cs) - [AvaloniaUIInvoker.cs](file://ClassicAssist.Avalonia/AvaloniaUIInvoker.cs) - [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.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) - [PacketFilter.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilter.cs) - [PacketFilterInfo.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterInfo.cs) - [PacketFilterCondition.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterCondition.cs) - [PacketFilterConditions.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterConditions.cs) - [PacketWaitEntry.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketWaitEntry.cs) - [PacketWaitEntries.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketWaitEntries.cs) - [BasePacket.cs](file://ClassicAssist.Shared/UO/Network/Packets/BasePacket.cs) - [ActionPacketQueue.cs](file://ClassicAssist.Shared/UO/Network/ActionPacketQueue.cs) - [ThreadQueue.cs](file://ClassicAssist.Shared/Misc/ThreadQueue.cs) - [ThreadPriorityQueue.cs](file://ClassicAssist.Shared/Misc/ThreadPriorityQueue.cs) - [OffsetStopwatch.cs](file://ClassicAssist.Shared/Misc/OffsetStopwatch.cs) - [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs) - [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs) - [CommandsManager.cs](file://ClassicAssist.Shared/Data/Commands/CommandsManager.cs) - [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.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) - [VendorBuyAgentEntry.cs](file://ClassicAssist.Shared/Data/Vendors/VendorBuyAgentEntry.cs) - [VendorSellAgentEntry.cs](file://ClassicAssist.Shared/Data/Vendors/VendorSellAgentEntry.cs) - [ClilocFilter.cs](file://ClassicAssist.Shared/Data/Filters/ClilocFilter.cs) - [RepeatedMessagesFilter.cs](file://ClassicAssist.Shared/Data/Filters/RepeatedMessagesFilter.cs) - [LightLevelFilter.cs](file://ClassicAssist.Shared/Data/Filters/LightLevelFilter.cs) - [SeasonFilter.cs](file://ClassicAssist.Shared/Data/Filters/SeasonFilter.cs) - [WeatherFilter.cs](file://ClassicAssist.Shared/Data/Filters/WeatherFilter.cs) - [BardsMusicFilter.cs](file://ClassicAssist.Shared/Data/Filters/BardsMusicFilter.cs) - [DynamicFilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/DynamicFilterEntry.cs) - [FilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/FilterEntry.cs) - [IConfigurableFilter.cs](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.cs) - [FilterOptionsAttribute.cs](file://ClassicAssist.Shared/Data/Filters/FilterOptionsAttribute.cs) - [EntityCollectionViewerViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/EntityCollectionViewerViewModel.cs) - [ChatViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/ChatViewModel.cs) **Section sources** - [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs) - [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs) - [Program.cs](file://ClassicAssist.Avalonia/Program.cs) - [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.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) - [PacketFilter.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilter.cs) - [PacketFilterInfo.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterInfo.cs) - [PacketFilterCondition.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterCondition.cs) - [PacketFilterConditions.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterConditions.cs) - [PacketWaitEntry.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketWaitEntry.cs) - [PacketWaitEntries.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketWaitEntries.cs) - [BasePacket.cs](file://ClassicAssist.Shared/UO/Network/Packets/BasePacket.cs) - [ActionPacketQueue.cs](file://ClassicAssist.Shared/UO/Network/ActionPacketQueue.cs) - [ThreadQueue.cs](file://ClassicAssist.Shared/Misc/ThreadQueue.cs) - [ThreadPriorityQueue.cs](file://ClassicAssist.Shared/Misc/ThreadPriorityQueue.cs) - [OffsetStopwatch.cs](file://ClassicAssist.Shared/Misc/OffsetStopwatch.cs) - [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs) - [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs) - [CommandsManager.cs](file://ClassicAssist.Shared/Data/Commands/CommandsManager.cs) - [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.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) - [VendorBuyAgentEntry.cs](file://ClassicAssist.Shared/Data/Vendors/VendorBuyAgentEntry.cs) - [VendorSellAgentEntry.cs](file://ClassicAssist.Shared/Data/Vendors/VendorSellAgentEntry.cs) - [ClilocFilter.cs](file://ClassicAssist.Shared/Data/Filters/ClilocFilter.cs) - [RepeatedMessagesFilter.cs](file://ClassicAssist.Shared/Data/Filters/RepeatedMessagesFilter.cs) - [LightLevelFilter.cs](file://ClassicAssist.Shared/Data/Filters/LightLevelFilter.cs) - [SeasonFilter.cs](file://ClassicAssist.Shared/Data/Filters/SeasonFilter.cs) - [WeatherFilter.cs](file://ClassicAssist.Shared/Data/Filters/WeatherFilter.cs) - [BardsMusicFilter.cs](file://ClassicAssist.Shared/Data/Filters/BardsMusicFilter.cs) - [DynamicFilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/DynamicFilterEntry.cs) - [FilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/FilterEntry.cs) - [IConfigurableFilter.cs](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.cs) - [FilterOptionsAttribute.cs](file://ClassicAssist.Shared/Data/Filters/FilterOptionsAttribute.cs) - [EntityCollectionViewerViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/EntityCollectionViewerViewModel.cs) - [ChatViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/ChatViewModel.cs) ## Core Components - Engine initialization and lifecycle: The Avalonia entry point wires up the engine, dispatcher, and UI invoker, then starts subsystems like macros, hotkeys, and networking. - Dispatcher and UI invoker: Platform abstraction over UI thread marshaling ensures safe updates from background threads. - Filters pipeline: Centralized filter registry and evaluation used by UI components and agents. - Networking stack: Incoming/outgoing packet handlers and filters, action queue, and wait entries for request-response synchronization. - Macro and command systems: Reflection-driven command discovery and execution, hotkey integration. - Agent managers: Feature-specific automation logic that integrates with filters and events. Key responsibilities: - Engine orchestrates startup and shutdown, registers services, and coordinates subsystems. - Dispatcher/Invoker abstract UI threading to keep UI responsive during heavy operations. - Filters provide declarative and programmatic filtering for messages and entities. - Networking handles low-level packet I/O, filtering, and queuing actions safely across threads. - Macros and commands expose extensibility via attributes and reflection. - Agents encapsulate domain automation rules and integrate with filters and events. **Section sources** - [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs) - [AvaloniaDispatcher.cs](file://ClassicAssist.Avalonia/AvaloniaDispatcher.cs) - [AvaloniaUIInvoker.cs](file://ClassicAssist.Avalonia/AvaloniaUIInvoker.cs) - [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.cs) - [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs) - [OutgoingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketHandlers.cs) - [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs) - [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs) - [CommandsManager.cs](file://ClassicAssist.Shared/Data/Commands/CommandsManager.cs) - [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.cs) ## Architecture Overview The system follows a layered architecture with clear separation between UI, core services, networking, and feature agents. Extension points are exposed through interfaces, attributes, and manager classes. ```mermaid sequenceDiagram participant App as "App.axaml.cs" participant Program as "Program.cs" participant Engine as "Engine.cs" participant Dispatcher as "AvaloniaDispatcher.cs" participant Invoker as "AvaloniaUIInvoker.cs" participant NetIn as "IncomingPacketHandlers.cs" participant NetOut as "OutgoingPacketHandlers.cs" participant Filters as "Filters.cs" participant VM as "EntityCollectionViewerViewModel.cs" Program->>App : Initialize App->>Engine : Start() Engine->>Dispatcher : Configure UI thread context Engine->>Invoker : Register UI invoker Engine->>NetIn : Register incoming handlers Engine->>NetOut : Register outgoing handlers Engine->>Filters : Build filter registry VM->>Filters : Query/filter entities or messages NetIn-->>VM : Update UI via Dispatcher/Invoker NetOut-->>NetIn : Action queue items processed ``` **Diagram sources** - [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs) - [Program.cs](file://ClassicAssist.Avalonia/Program.cs) - [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs) - [AvaloniaDispatcher.cs](file://ClassicAssist.Avalonia/AvaloniaDispatcher.cs) - [AvaloniaUIInvoker.cs](file://ClassicAssist.Avalonia/AvaloniaUIInvoker.cs) - [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs) - [OutgoingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketHandlers.cs) - [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.cs) - [EntityCollectionViewerViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/EntityCollectionViewerViewModel.cs) ## Detailed Component Analysis ### Agent Framework and Rule Engine Integration Agents implement domain-specific automation (e.g., autoloot, dressing, scavenging, vendor buying/selling). They integrate with the filter system and event hooks to react to game state changes and user actions. - Autoloot: Evaluates item properties against configured rules and performs pick-up actions. - Dress: Manages outfit definitions and equips items based on criteria. - Scavenger: Automates gathering tasks using region and property constraints. - Vendor Buy/Sell: Automates transactions based on lists and conditions. ```mermaid classDiagram class AutolootManager { +Evaluate(item) bool +ExecuteActions(item) void } class DressManager { +LoadOutfit(name) void +EquipOutfit() void } class ScavengerManager { +PlanRoute() void +GatherItems() void } class VendorBuyAgentEntry { +AddItem(entry) void +BuySelected() void } class VendorSellAgentEntry { +AddItem(entry) void +SellSelected() void } class Filters { +Register(filter) void +Apply(entity) bool } AutolootManager --> Filters : "uses" DressManager --> Filters : "uses" ScavengerManager --> Filters : "uses" VendorBuyAgentEntry --> Filters : "uses" VendorSellAgentEntry --> Filters : "uses" ``` **Diagram sources** - [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) - [VendorBuyAgentEntry.cs](file://ClassicAssist.Shared/Data/Vendors/VendorBuyAgentEntry.cs) - [VendorSellAgentEntry.cs](file://ClassicAssist.Shared/Data/Vendors/VendorSellAgentEntry.cs) - [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.cs) **Section sources** - [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) - [VendorBuyAgentEntry.cs](file://ClassicAssist.Shared/Data/Vendors/VendorBuyAgentEntry.cs) - [VendorSellAgentEntry.cs](file://ClassicAssist.Shared/Data/Vendors/VendorSellAgentEntry.cs) - [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.cs) ### Filter System for Message Processing The filter system provides a centralized registry and evaluation pipeline for messages and entities. It supports built-in filters and allows custom filters to be registered and composed. - Built-in filters include cliloc text matching, repeated message detection, light level, season, weather, and bard music. - Dynamic filter entries enable runtime composition and configuration. - Configurable filters expose options via attributes for UI binding. ```mermaid flowchart TD Start(["Message/Entity Received"]) --> ApplyFilters["Apply Registered Filters"] ApplyFilters --> CheckCustom{"Custom Filter?"} CheckCustom --> |Yes| CustomLogic["Run Custom Filter Logic"] CheckCustom --> |No| SkipCustom["Skip Custom Filter"] CustomLogic --> EvaluateBuiltins["Evaluate Built-in Filters"] SkipCustom --> EvaluateBuiltins EvaluateBuiltins --> Result{"All Conditions Met?"} Result --> |Yes| Pass["Pass to Consumer"] Result --> |No| Drop["Drop/Ignore"] Pass --> End(["Done"]) Drop --> End ``` **Diagram sources** - [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.cs) - [ClilocFilter.cs](file://ClassicAssist.Shared/Data/Filters/ClilocFilter.cs) - [RepeatedMessagesFilter.cs](file://ClassicAssist.Shared/Data/Filters/RepeatedMessagesFilter.cs) - [LightLevelFilter.cs](file://ClassicAssist.Shared/Data/Filters/LightLevelFilter.cs) - [SeasonFilter.cs](file://ClassicAssist.Shared/Data/Filters/SeasonFilter.cs) - [WeatherFilter.cs](file://ClassicAssist.Shared/Data/Filters/WeatherFilter.cs) - [BardsMusicFilter.cs](file://ClassicAssist.Shared/Data/Filters/BardsMusicFilter.cs) - [DynamicFilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/DynamicFilterEntry.cs) - [FilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/FilterEntry.cs) - [IConfigurableFilter.cs](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.cs) - [FilterOptionsAttribute.cs](file://ClassicAssist.Shared/Data/Filters/FilterOptionsAttribute.cs) **Section sources** - [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.cs) - [ClilocFilter.cs](file://ClassicAssist.Shared/Data/Filters/ClilocFilter.cs) - [RepeatedMessagesFilter.cs](file://ClassicAssist.Shared/Data/Filters/RepeatedMessagesFilter.cs) - [LightLevelFilter.cs](file://ClassicAssist.Shared/Data/Filters/LightLevelFilter.cs) - [SeasonFilter.cs](file://ClassicAssist.Shared/Data/Filters/SeasonFilter.cs) - [WeatherFilter.cs](file://ClassicAssist.Shared/Data/Filters/WeatherFilter.cs) - [BardsMusicFilter.cs](file://ClassicAssist.Shared/Data/Filters/BardsMusicFilter.cs) - [DynamicFilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/DynamicFilterEntry.cs) - [FilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/FilterEntry.cs) - [IConfigurableFilter.cs](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.cs) - [FilterOptionsAttribute.cs](file://ClassicAssist.Shared/Data/Filters/FilterOptionsAttribute.cs) ### Plugin Architecture and Extension Points Extension points are provided through: - Manager classes (macros, hotkeys, commands) that discover and register components - Attributes for metadata and display hints - Reflection helpers for dynamic loading and invocation Key extension points: - Macro commands: Discovered via attributes and reflection, invoked dynamically - Hotkey commands: Bound to key combinations and executed through the command system - Commands: Centralized registration and consumption - Filters: Pluggable filter implementations with configurable options Distribution strategies: - Separate assemblies can be loaded at runtime if referenced by the host - Managers scan loaded types for specific attributes and interfaces - Configuration files define plugin manifests and dependencies **Section sources** - [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs) - [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs) - [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs) - [CommandsManager.cs](file://ClassicAssist.Shared/Data/Commands/CommandsManager.cs) - [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.cs) ### Reflection-Based Command Discovery and Dynamic Assembly Loading Command discovery leverages attributes and reflection to locate and invoke methods without hard-coded references. - Commands are annotated with metadata for display and grouping - Reflection scans assemblies for decorated types/methods - Invoker resolves parameters and executes commands safely ```mermaid sequenceDiagram participant Loader as "Reflection.cs" participant CmdMgr as "CommandsManager.cs" participant MacroMgr as "MacroManager.cs" participant Invoker as "MacroInvoker.cs" Loader->>CmdMgr : Scan assemblies for command attributes CmdMgr->>MacroMgr : Register discovered commands MacroMgr->>Invoker : Resolve method and parameters Invoker-->>MacroMgr : Execute result MacroMgr-->>CmdMgr : Notify completion ``` **Diagram sources** - [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.cs) - [CommandsManager.cs](file://ClassicAssist.Shared/Data/Commands/CommandsManager.cs) - [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs) - [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs) **Section sources** - [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.cs) - [CommandsManager.cs](file://ClassicAssist.Shared/Data/Commands/CommandsManager.cs) - [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs) - [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs) ### Event Hooks and Inter-Component Communication Inter-component communication relies on: - Centralized managers exposing registration APIs - UI view models subscribing to core services - Dispatchers ensuring cross-thread safety Patterns: - Publish-subscribe via managers (e.g., chat, entity collections) - ViewModel bindings to observable collections updated by core services - UI invoker marshaling updates to the UI thread **Section sources** - [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.cs) - [EntityCollectionViewerViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/EntityCollectionViewerViewModel.cs) - [ChatViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/ChatViewModel.cs) - [AvaloniaDispatcher.cs](file://ClassicAssist.Avalonia/AvaloniaDispatcher.cs) - [AvaloniaUIInvoker.cs](file://ClassicAssist.Avalonia/AvaloniaUIInvoker.cs) ### Advanced Networking Features: Packet Manipulation and Protocol Extensions The networking layer provides robust packet handling, filtering, and synchronization primitives. - Incoming/outgoing handlers register per-packet-type callbacks - Packet filters allow conditional routing and transformation - Wait entries support request-response synchronization - Action queues serialize network-bound actions to prevent contention ```mermaid sequenceDiagram participant Client as "Game Client" participant NetIn as "IncomingPacketHandlers.cs" participant NetOut as "OutgoingPacketHandlers.cs" participant PktFilt as "PacketFilter.cs" participant Wait as "PacketWaitEntries.cs" participant ActQ as "ActionPacketQueue.cs" Client->>NetIn : Receive packet NetIn->>PktFilt : Apply incoming filters PktFilt-->>NetIn : Allow/Deny NetIn->>Wait : Match wait entry if any Wait-->>NetIn : Signal completion NetIn->>ActQ : Enqueue action if needed Client->>NetOut : Send packet NetOut->>PktFilt : Apply outgoing filters PktFilt-->>NetOut : Allow/Deny NetOut->>ActQ : Enqueue outgoing action ``` **Diagram sources** - [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs) - [OutgoingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketHandlers.cs) - [PacketFilter.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilter.cs) - [PacketFilterInfo.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterInfo.cs) - [PacketFilterCondition.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterCondition.cs) - [PacketFilterConditions.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterConditions.cs) - [PacketWaitEntry.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketWaitEntry.cs) - [PacketWaitEntries.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketWaitEntries.cs) - [ActionPacketQueue.cs](file://ClassicAssist.Shared/UO/Network/ActionPacketQueue.cs) - [BasePacket.cs](file://ClassicAssist.Shared/UO/Network/Packets/BasePacket.cs) **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) - [PacketFilter.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilter.cs) - [PacketFilterInfo.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterInfo.cs) - [PacketFilterCondition.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterCondition.cs) - [PacketFilterConditions.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterConditions.cs) - [PacketWaitEntry.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketWaitEntry.cs) - [PacketWaitEntries.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketWaitEntries.cs) - [ActionPacketQueue.cs](file://ClassicAssist.Shared/UO/Network/ActionPacketQueue.cs) - [BasePacket.cs](file://ClassicAssist.Shared/UO/Network/Packets/BasePacket.cs) ### Threading Models, Concurrency Patterns, and Performance Optimization Threading model: - UI updates are marshaled via AvaloniaDispatcher and UI invoker - Background threads process networking and agent logic - Queues serialize access to shared resources Concurrency patterns: - Thread-safe queues for actions and packets - Priority queues for time-sensitive operations - Stopwatch instrumentation for performance measurement Optimization techniques: - Batch updates to reduce UI churn - Early exits in filters to minimize work - Reuse compiled regex patterns where applicable - Avoid allocations in hot paths **Section sources** - [AvaloniaDispatcher.cs](file://ClassicAssist.Avalonia/AvaloniaDispatcher.cs) - [AvaloniaUIInvoker.cs](file://ClassicAssist.Avalonia/AvaloniaUIInvoker.cs) - [ThreadQueue.cs](file://ClassicAssist.Shared/Misc/ThreadQueue.cs) - [ThreadPriorityQueue.cs](file://ClassicAssist.Shared/Misc/ThreadPriorityQueue.cs) - [OffsetStopwatch.cs](file://ClassicAssist.Shared/Misc/OffsetStopwatch.cs) - [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs) - [OutgoingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketHandlers.cs) ## Dependency Analysis High-level dependency relationships among core modules: ```mermaid graph LR Engine["Engine.cs"] --> Filters["Filters.cs"] Engine --> InHandlers["IncomingPacketHandlers.cs"] Engine --> OutHandlers["OutgoingPacketHandlers.cs"] InHandlers --> PktFilter["PacketFilter.cs"] OutHandlers --> PktFilter InHandlers --> WaitEntries["PacketWaitEntries.cs"] OutHandlers --> WaitEntries InHandlers --> ActionQ["ActionPacketQueue.cs"] OutHandlers --> ActionQ MacroMgr["MacroManager.cs"] --> Commands["CommandsManager.cs"] MacroMgr --> Reflection["Reflection.cs"] Hotkeys["HotkeyManager.cs"] --> Commands Agents["Autoloot/Dress/Scavenger/Vendor"] --> Filters ``` **Diagram sources** - [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs) - [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.cs) - [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs) - [OutgoingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketHandlers.cs) - [PacketFilter.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilter.cs) - [PacketWaitEntries.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketWaitEntries.cs) - [ActionPacketQueue.cs](file://ClassicAssist.Shared/UO/Network/ActionPacketQueue.cs) - [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs) - [CommandsManager.cs](file://ClassicAssist.Shared/Data/Commands/CommandsManager.cs) - [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.cs) - [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.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) - [VendorBuyAgentEntry.cs](file://ClassicAssist.Shared/Data/Vendors/VendorBuyAgentEntry.cs) - [VendorSellAgentEntry.cs](file://ClassicAssist.Shared/Data/Vendors/VendorSellAgentEntry.cs) **Section sources** - [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs) - [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.cs) - [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs) - [OutgoingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketHandlers.cs) - [PacketFilter.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilter.cs) - [PacketWaitEntries.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketWaitEntries.cs) - [ActionPacketQueue.cs](file://ClassicAssist.Shared/UO/Network/ActionPacketQueue.cs) - [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs) - [CommandsManager.cs](file://ClassicAssist.Shared/Data/Commands/CommandsManager.cs) - [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.cs) - [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.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) - [VendorBuyAgentEntry.cs](file://ClassicAssist.Shared/Data/Vendors/VendorBuyAgentEntry.cs) - [VendorSellAgentEntry.cs](file://ClassicAssist.Shared/Data/Vendors/VendorSellAgentEntry.cs) ## Performance Considerations - Use early-exit conditions in filters to avoid unnecessary processing - Prefer immutable data structures for frequently accessed entities - Batch UI updates to reduce layout passes - Leverage priority queues for time-critical actions - Instrument hot paths with stopwatch measurements to identify bottlenecks - Minimize allocations in tight loops; reuse buffers where possible [No sources needed since this section provides general guidance] ## Troubleshooting Guide Common issues and resolutions: - UI not updating: Ensure updates are dispatched via AvaloniaDispatcher/UI invoker - Filters not triggering: Verify registration order and condition precedence - Network timeouts: Check wait entries and ensure responses match expected packet types - Command not found: Confirm attribute decoration and assembly scanning - Deadlocks: Review queue usage and avoid holding locks while invoking UI **Section sources** - [AvaloniaDispatcher.cs](file://ClassicAssist.Avalonia/AvaloniaDispatcher.cs) - [AvaloniaUIInvoker.cs](file://ClassicAssist.Avalonia/AvaloniaUIInvoker.cs) - [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.cs) - [PacketWaitEntries.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketWaitEntries.cs) - [CommandsManager.cs](file://ClassicAssist.Shared/Data/Commands/CommandsManager.cs) ## Conclusion ClassicAssist.Avalonia exposes powerful extension points for building custom agents, filters, and plugins. Its layered architecture, robust networking stack, and reflection-driven command system enable flexible automation and customization. By following the threading and performance guidelines outlined here, developers can create efficient, responsive extensions that integrate seamlessly with the core system.