first commit

This commit is contained in:
Beyhan Oğur
2026-09-03 04:45:36 +03:00
commit d5f52cc3d3
1038 changed files with 169579 additions and 0 deletions
@@ -0,0 +1,672 @@
# Advanced Features
<cite>
**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)
</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)
## 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.
@@ -0,0 +1,459 @@
# Agent Architecture & Base Classes
<cite>
**Referenced Files in This Document**
- [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)
- [ThreadQueue.cs](file://ClassicAssist.Shared/Misc/ThreadQueue.cs)
- [ThreadPriorityQueue.cs](file://ClassicAssist.Shared/Misc/ThreadPriorityQueue.cs)
- [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.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)
- [AgentsTabControl.axaml.cs](file://ClassicAssist.Avalonia/Views/AgentsTabControl.axaml.cs)
- [AvaloniaDispatcher.cs](file://ClassicAssist.Avalonia/AvaloniaDispatcher.cs)
- [AvaloniaUIInvoker.cs](file://ClassicAssist.Avalonia/AvaloniaUIInvoker.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)
## Introduction
This document explains the agent framework architecture used by ClassicAssist.Avalonia. It focuses on base manager classes, agent lifecycle management, registration and discovery patterns, event handling, state management, integration with the game engine, network packet processing, and rule evaluation for condition matching and action execution. It also covers threading models, performance considerations, memory management for long-running agents, and practical guidance for extending base classes and implementing custom agent logic.
## Project Structure
The agent framework spans shared networking, data managers, UI integration, and platform dispatchers:
- Shared core provides the engine entry point, packet handlers, queues, and manager abstractions.
- Avalonia-specific code integrates UI threads and dispatcher invokers.
- Managers implement concrete agent behaviors (e.g., autoloot, dress, scavenger, vendor buy/sell).
```mermaid
graph TB
subgraph "Shared Core"
Engine["Engine"]
InPktHdlrs["IncomingPacketHandlers"]
OutPktHdlrs["OutgoingPacketHandlers"]
PktHandler["PacketHandler"]
InPktFilters["IncomingPacketFilters"]
ActionQ["ActionPacketQueue"]
TQ["ThreadQueue"]
TPQ["ThreadPriorityQueue"]
MacroMgr["MacroManager"]
HotkeyMgr["HotkeyManager"]
AutolootMgr["AutolootManager"]
DressMgr["DressManager"]
ScavengerMgr["ScavengerManager"]
VendorBuy["VendorBuyAgentEntry"]
VendorSell["VendorSellAgentEntry"]
end
subgraph "Avalonia UI"
AgentsTab["AgentsTabControl"]
Dispatcher["AvaloniaDispatcher"]
UIInvoker["AvaloniaUIInvoker"]
end
Engine --> InPktHdlrs
Engine --> OutPktHdlrs
InPktHdlrs --> PktHandler
OutPktHdlrs --> PktHandler
InPktHdlrs --> InPktFilters
InPktHdlrs --> ActionQ
ActionQ --> TQ
ActionQ --> TPQ
MacroMgr --> Engine
HotkeyMgr --> Engine
AutolootMgr --> Engine
DressMgr --> Engine
ScavengerMgr --> Engine
VendorBuy --> Engine
VendorSell --> Engine
AgentsTab --> Dispatcher
Dispatcher --> UIInvoker
```
**Diagram sources**
- [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)
- [IncomingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketFilters.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)
- [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.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)
- [AgentsTabControl.axaml.cs](file://ClassicAssist.Avalonia/Views/AgentsTabControl.axaml.cs)
- [AvaloniaDispatcher.cs](file://ClassicAssist.Avalonia/AvaloniaDispatcher.cs)
- [AvaloniaUIInvoker.cs](file://ClassicAssist.Avalonia/AvaloniaUIInvoker.cs)
**Section sources**
- [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)
- [ThreadQueue.cs](file://ClassicAssist.Shared/Misc/ThreadQueue.cs)
- [ThreadPriorityQueue.cs](file://ClassicAssist.Shared/Misc/ThreadPriorityQueue.cs)
- [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.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)
- [AgentsTabControl.axaml.cs](file://ClassicAssist.Avalonia/Views/AgentsTabControl.axaml.cs)
- [AvaloniaDispatcher.cs](file://ClassicAssist.Avalonia/AvaloniaDispatcher.cs)
- [AvaloniaUIInvoker.cs](file://ClassicAssist.Avalonia/AvaloniaUIInvoker.cs)
## Core Components
- Engine: Central orchestrator that initializes subsystems, wires up packet handlers, and coordinates managers.
- Packet Handlers: Incoming and outgoing packet routing to registered handlers and filters.
- Queues: Thread-safe queues for deferring actions across threads.
- Managers: Feature-specific agents (autoloot, dress, scavenger, vendor buy/sell) that encapsulate rules and state.
- UI Integration: Avalonia dispatcher and UI invoker bridge background work to UI safely.
Key responsibilities:
- Registration and discovery of packet handlers and managers.
- Event-driven updates from packets and timers.
- Rule evaluation pipelines for conditions and actions.
- Threading model ensuring safe cross-thread operations.
**Section sources**
- [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)
- [ThreadQueue.cs](file://ClassicAssist.Shared/Misc/ThreadQueue.cs)
- [ThreadPriorityQueue.cs](file://ClassicAssist.Shared/Misc/ThreadPriorityQueue.cs)
## Architecture Overview
The agent framework follows an event-driven architecture:
- The game engine receives network packets and routes them through incoming/outgoing handlers.
- Filters can inspect or block packets before they reach handlers.
- Handlers update shared state and enqueue actions via thread-safe queues.
- Managers subscribe to events and process queued actions, applying rules and performing actions.
- UI components observe state changes and are updated via the Avalonia dispatcher.
```mermaid
sequenceDiagram
participant Game as "Game Engine"
participant InPkt as "IncomingPacketHandlers"
participant Filter as "IncomingPacketFilters"
participant Handler as "PacketHandler"
participant Queue as "ActionPacketQueue"
participant Manager as "Agent Manager"
participant UI as "AvaloniaDispatcher/UIInvoker"
Game->>InPkt : "Receive packet"
InPkt->>Filter : "Apply filters"
Filter-->>InPkt : "Allow/Deny"
InPkt->>Handler : "Dispatch to handler"
Handler->>Manager : "Update state / raise events"
Handler->>Queue : "Enqueue action"
Queue-->>Manager : "Dequeue and execute"
Manager->>UI : "Invoke UI updates"
```
**Diagram sources**
- [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs)
- [IncomingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketFilters.cs)
- [PacketHandler.cs](file://ClassicAssist.Shared/UO/Network/PacketHandler.cs)
- [ActionPacketQueue.cs](file://ClassicAssist.Shared/UO/Network/ActionPacketQueue.cs)
- [AvaloniaDispatcher.cs](file://ClassicAssist.Avalonia/AvaloniaDispatcher.cs)
- [AvaloniaUIInvoker.cs](file://ClassicAssist.Avalonia/AvaloniaUIInvoker.cs)
## Detailed Component Analysis
### Base Manager Pattern and Lifecycle
Managers encapsulate agent behavior and configuration. Typical lifecycle:
- Initialization: Register handlers, load configuration, initialize state.
- Runtime: Subscribe to engine events, evaluate rules, perform actions.
- Cleanup: Unsubscribe, release resources, persist state.
Common patterns:
- Configuration entries per agent type (e.g., vendor buy/sell entries).
- State held in collections and caches for fast lookup.
- Event-driven updates triggered by packet handlers or timers.
Examples:
- Autoloot manager maintains lists of constraints and properties to match items.
- Dress manager tracks desired equipment sets and applies them based on conditions.
- Scavenger manager defines loot priorities and filtering rules.
- Vendor buy/sell managers manage shop lists and transaction logic.
**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)
### Agent Registration System
Registration typically occurs during engine initialization:
- Managers register themselves with the engine.
- Packet handlers are discovered and bound to specific packet types.
- UI tabs bind to manager view models for display and control.
Patterns:
- Centralized registry in the engine.
- Attribute-based or convention-based discovery for handlers and commands.
- Tabbed UI surfaces each agent’s configuration and status.
**Section sources**
- [Engine.cs](file://ClassicAssist.Shared/Engine.cs)
- [AgentsTabControl.axaml.cs](file://ClassicAssist.Avalonia/Views/AgentsTabControl.axaml.cs)
### Event Handling Mechanisms
Event flow:
- Network packets arrive and are filtered.
- Handlers update shared state and raise domain events.
- Managers listen to these events and react accordingly.
- Actions may be enqueued for asynchronous execution.
Best practices:
- Keep handlers lightweight; offload heavy work to queues.
- Use immutable snapshots where possible to reduce contention.
- Ensure thread safety when updating shared collections.
**Section sources**
- [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)
### State Management Patterns
State is managed centrally and accessed by multiple managers:
- Entity collections and caches provide fast lookups.
- Managers maintain local state derived from global state.
- Changes are propagated via events and queues.
Guidelines:
- Prefer read-only views for UI-bound data.
- Batch updates to minimize churn.
- Persist configuration separately from runtime state.
**Section sources**
- [Engine.cs](file://ClassicAssist.Shared/Engine.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)
### Network Packet Integration
Integration points:
- IncomingPacketHandlers route packets to specific handlers.
- IncomingPacketFilters allow pre-processing and blocking.
- OutgoingPacketHandlers intercept outgoing actions for logging or modification.
- PacketHandler centralizes dispatch logic.
Considerations:
- Avoid blocking in handlers; use queues for deferred work.
- Validate packet payloads before processing.
- Maintain compatibility across client/server protocol versions.
**Section sources**
- [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs)
- [IncomingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketFilters.cs)
- [OutgoingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketHandlers.cs)
- [PacketHandler.cs](file://ClassicAssist.Shared/UO/Network/PacketHandler.cs)
### Rule Evaluation System: Conditions and Actions
Rule evaluation pipeline:
- Collect candidate entities or events.
- Apply filter conditions (e.g., item properties, light level, cliloc text).
- Compute priority or score.
- Execute actions (e.g., pick up, equip, sell/buy).
Flowchart:
```mermaid
flowchart TD
Start(["Start Rule Evaluation"]) --> Gather["Gather Candidates"]
Gather --> ApplyFilters["Apply Filter Conditions"]
ApplyFilters --> Matched{"Any Matches?"}
Matched --> |No| End(["End"])
Matched --> |Yes| Score["Compute Priority/Score"]
Score --> SelectTop["Select Top Candidate(s)"]
SelectTop --> ExecuteActions["Execute Actions"]
ExecuteActions --> UpdateState["Update State"]
UpdateState --> End
```
**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)
### Extending Base Classes and Implementing Custom Logic
To extend the framework:
- Create a new manager class following existing patterns.
- Initialize configuration entries and subscribe to relevant events.
- Implement rule evaluation methods and action execution.
- Integrate with UI via a tab control if needed.
Example references:
- Autoloot manager demonstrates property-based filtering and selection.
- Dress manager shows conditional application of equipment sets.
- Vendor buy/sell entries define structured configurations for transactions.
**Section sources**
- [AutolootManager.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootManager.cs)
- [DressManager.cs](file://ClassicAssist.Shared/Data/Dress/DressManager.cs)
- [VendorBuyAgentEntry.cs](file://ClassicAssist.Shared/Data/Vendors/VendorBuyAgentEntry.cs)
- [VendorSellAgentEntry.cs](file://ClassicAssist.Shared/Data/Vendors/VendorSellAgentEntry.cs)
### Managing Agent Configuration
Configuration is typically stored in structured entries:
- Each agent has dedicated entry types (e.g., vendor buy/sell entries).
- Managers load and apply configurations at startup.
- UI exposes configuration editors bound to view models.
Recommendations:
- Validate configuration on load.
- Provide defaults for missing fields.
- Persist changes atomically to avoid corruption.
**Section sources**
- [VendorBuyAgentEntry.cs](file://ClassicAssist.Shared/Data/Vendors/VendorBuyAgentEntry.cs)
- [VendorSellAgentEntry.cs](file://ClassicAssist.Shared/Data/Vendors/VendorSellAgentEntry.cs)
- [AgentsTabControl.axaml.cs](file://ClassicAssist.Avalonia/Views/AgentsTabControl.axaml.cs)
### Threading Models and Cross-Thread Operations
Threading model:
- Packet processing runs on network threads.
- Managers may run on background threads.
- UI updates must be marshaled to the UI thread using the dispatcher.
Queues:
- ActionPacketQueue provides a unified queue for actions.
- ThreadQueue and ThreadPriorityQueue support prioritized scheduling.
Cross-thread best practices:
- Enqueue work instead of direct UI calls.
- Use the Avalonia dispatcher to marshal UI updates.
- Avoid long-running operations on UI threads.
**Section sources**
- [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)
- [AvaloniaDispatcher.cs](file://ClassicAssist.Avalonia/AvaloniaDispatcher.cs)
- [AvaloniaUIInvoker.cs](file://ClassicAssist.Avalonia/AvaloniaUIInvoker.cs)
### Performance Considerations
- Minimize allocations in hot paths (packet handlers, rule evaluation).
- Use efficient data structures for entity lookups and filtering.
- Batch UI updates to reduce redraw overhead.
- Leverage priority queues for time-sensitive actions.
- Profile memory usage for long-running sessions and clear caches when appropriate.
[No sources needed since this section provides general guidance]
### Memory Management for Long-Running Agents
- Release subscriptions and timers on cleanup.
- Avoid retaining large object graphs in static caches.
- Periodically compact or rebuild indexes if necessary.
- Monitor GC pressure and adjust batching strategies.
[No sources needed since this section provides general guidance]
## Dependency Analysis
High-level dependencies among core components:
- Engine depends on packet handlers and managers.
- Packet handlers depend on filters and queues.
- Managers depend on shared data and configuration entries.
- UI depends on dispatcher and invoker for cross-thread updates.
```mermaid
graph LR
Engine --> InPktHdlrs
Engine --> OutPktHdlrs
InPktHdlrs --> InPktFilters
InPktHdlrs --> ActionQ
ActionQ --> TQ
ActionQ --> TPQ
Managers["Managers (Autoloot, Dress, Scavenger, Vendor)"] --> Engine
UI["Avalonia UI"] --> Dispatcher
Dispatcher --> UIInvoker
```
**Diagram sources**
- [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)
- [IncomingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketFilters.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)
- [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)
- [AvaloniaDispatcher.cs](file://ClassicAssist.Avalonia/AvaloniaDispatcher.cs)
- [AvaloniaUIInvoker.cs](file://ClassicAssist.Avalonia/AvaloniaUIInvoker.cs)
**Section sources**
- [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)
- [IncomingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketFilters.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)
- [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)
- [AvaloniaDispatcher.cs](file://ClassicAssist.Avalonia/AvaloniaDispatcher.cs)
- [AvaloniaUIInvoker.cs](file://ClassicAssist.Avalonia/AvaloniaUIInvoker.cs)
## Performance Considerations
- Favor lightweight handlers and defer heavy computations to queues.
- Use efficient filtering and early exits in rule evaluation.
- Reduce UI churn by batching updates and avoiding frequent rebinds.
- Monitor queue depths and backpressure to prevent memory growth.
- Profile critical paths under realistic loads to identify bottlenecks.
[No sources needed since this section provides general guidance]
## Troubleshooting Guide
Common issues and resolutions:
- Packets not processed: Verify filters are not blocking; check handler registrations.
- UI not updating: Ensure actions are dispatched via Avalonia dispatcher.
- High CPU usage: Inspect tight loops in rule evaluation; add throttling or batching.
- Memory leaks: Confirm unsubscription from events and disposal of timers.
Diagnostic utilities:
- Logging in packet handlers and managers.
- Queue depth monitoring.
- UI thread invocation failures captured by dispatcher.
**Section sources**
- [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs)
- [IncomingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketFilters.cs)
- [AvaloniaDispatcher.cs](file://ClassicAssist.Avalonia/AvaloniaDispatcher.cs)
- [AvaloniaUIInvoker.cs](file://ClassicAssist.Avalonia/AvaloniaUIInvoker.cs)
## Conclusion
The ClassicAssist.Avalonia agent framework is built around a robust event-driven architecture with clear separation between networking, rule evaluation, and UI concerns. Managers encapsulate agent logic and configuration, while queues and dispatchers ensure safe, performant operation across threads. By following the patterns outlined here—registration, event handling, rule evaluation, and cross-thread updates—you can extend the system with custom agents that integrate seamlessly with the game engine and UI.
@@ -0,0 +1,445 @@
# Agent Framework
<cite>
**Referenced Files in This Document**
- [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)
- [AutolootEntry.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootEntry.cs)
- [DressAgentEntry.cs](file://ClassicAssist.Shared/Data/Dress/DressAgentEntry.cs)
- [ScavengerEntry.cs](file://ClassicAssist.Shared/Data/Scavenger/ScavengerEntry.cs)
- [PropertyEntry.cs](file://ClassicAssist.Shared/Data/Autoloot/PropertyEntry.cs)
- [FilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/FilterEntry.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
The ClassicAssist.Avalonia agent framework provides a sophisticated automation system for Ultima Online gameplay through a modular agent architecture. This framework enables players to create intelligent agents that can automatically perform various tasks such as loot collection, equipment management, item scavenging, and vendor operations. The framework is built around a rule-based engine that evaluates conditions and executes actions based on game state and player-defined rules.
The agent system follows a manager-based pattern where each type of automated behavior is encapsulated in its own manager class, providing clear separation of concerns and making it easy to extend functionality with custom agents.
## Project Structure
The agent framework is primarily implemented within the ClassicAssist.Shared project, with UI components distributed across both ClassicAssist (WPF) and ClassicAssist.Avalonia projects. The core architecture consists of:
```mermaid
graph TB
subgraph "Agent Framework Core"
Engine[Engine]
ManagerBase[Manager Base Class]
RuleEngine[Rule Engine]
ConditionEvaluator[Condition Evaluator]
ActionExecutor[Action Executor]
end
subgraph "Built-in Agents"
Autoloot[AUTOLootManager]
Dress[DressManager]
Scavenger[ScavengerManager]
VendorBuy[VendorBuyManager]
VendorSell[VendorSellManager]
Organizer[OrganizerManager]
end
subgraph "Data Models"
EntryModels[Entry Models]
PropertySystem[Property System]
FilterSystem[Filter System]
end
subgraph "UI Layer"
WPFUI[WPF UI]
AvaloniaUI[Avalonia UI]
ViewModels[ViewModels]
end
Engine --> ManagerBase
ManagerBase --> RuleEngine
RuleEngine --> ConditionEvaluator
RuleEngine --> ActionExecutor
Autoloot --> ManagerBase
Dress --> ManagerBase
Scavenger --> ManagerBase
ManagerBase --> EntryModels
EntryModels --> PropertySystem
EntryModels --> FilterSystem
WPFUI --> ViewModels
AvaloniaUI --> ViewModels
```
**Diagram sources**
- [Engine.cs](file://ClassicAssist.Shared/Engine.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)
## Core Components
### Agent Architecture Pattern
The agent framework implements a manager-based architecture where each specialized agent type extends a common base class. This pattern provides:
- **Lifecycle Management**: Standardized initialization, update, and cleanup processes
- **Event Handling**: Consistent event processing and response mechanisms
- **Configuration Management**: Unified approach to loading, saving, and validating agent configurations
- **State Management**: Centralized state tracking and persistence
- **Threading Support**: Built-in support for asynchronous operations and thread safety
### Base Classes and Inheritance Hierarchy
The framework establishes a clear inheritance hierarchy that promotes code reuse and consistency:
```mermaid
classDiagram
class AgentBase {
+string Name
+bool IsEnabled
+DateTime LastUpdated
+void Initialize()
+void Update()
+void Cleanup()
+void LoadConfiguration()
+void SaveConfiguration()
+event EventHandler OnStateChanged
}
class ManagerBase {
+T[] Entries
+Dictionary~string, object~ Properties
+void AddEntry(T entry)
+void RemoveEntry(string id)
+T GetEntry(string id)
+void ProcessEntries()
+void ValidateEntries()
}
class AutolootManager {
+AutolootEntry[] Rules
+void EvaluateLootConditions()
+void ExecuteLootActions()
+void HandleItemDrop()
}
class DressManager {
+DressAgentEntry[] Outfits
+void EvaluateOutfitRules()
+void EquipItems()
+void UnequipItems()
}
class ScavengerManager {
+ScavengerEntry[] ScavengeRules
+void FindScavengeTargets()
+void MoveToTarget()
+void PickUpItems()
}
AgentBase <|-- ManagerBase
ManagerBase <|-- AutolootManager
ManagerBase <|-- DressManager
ManagerBase <|-- ScavengerManager
```
**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)
### Rule Engine Integration
The rule engine serves as the core decision-making component, evaluating conditions and executing appropriate actions. It supports:
- **Complex Condition Evaluation**: Boolean logic with AND, OR, NOT operators
- **Property Matching**: Dynamic property comparison using wildcards and regular expressions
- **Context-Aware Conditions**: Access to game state, player status, and environmental factors
- **Priority-Based Execution**: Ordered evaluation of multiple rules with conflict resolution
### Data Model Architecture
Each agent type defines its own entry models that specify the configuration and behavior parameters:
| Agent Type | Entry Model | Key Properties | Purpose |
|------------|-------------|----------------|---------|
| Autoloot | AutolootEntry | ItemCriteria, Actions, Priority | Define what items to collect and how to handle them |
| Dress | DressAgentEntry | OutfitName, Items, Conditions | Specify equipment combinations and activation rules |
| Scavenger | ScavengerEntry | TargetTypes, PickupRange, Actions | Configure automatic item gathering behavior |
**Section sources**
- [AutolootEntry.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootEntry.cs)
- [DressAgentEntry.cs](file://ClassicAssist.Shared/Data/Dress/DressAgentEntry.cs)
- [ScavengerEntry.cs](file://ClassicAssist.Shared/Data/Scavenger/ScavengerEntry.cs)
## Architecture Overview
The agent framework follows a layered architecture that separates concerns and promotes maintainability:
```mermaid
sequenceDiagram
participant Game as "Game Engine"
participant EventSystem as "Event System"
participant AgentManager as "Agent Manager"
participant RuleEngine as "Rule Engine"
participant Agent as "Specific Agent"
participant ActionQueue as "Action Queue"
participant GameClient as "Game Client"
Game->>EventSystem : Game Event
EventSystem->>AgentManager : Dispatch Event
AgentManager->>RuleEngine : Evaluate Conditions
RuleEngine->>Agent : Check Agent Rules
Agent->>Agent : Process Logic
Agent->>ActionQueue : Queue Actions
ActionQueue->>GameClient : Execute Actions
GameClient-->>Game : Send Commands
Note over Agent,ActionQueue : Asynchronous action processing
Note over RuleEngine,Agent : Thread-safe condition evaluation
```
**Diagram sources**
- [Engine.cs](file://ClassicAssist.Shared/Engine.cs)
- [AutolootManager.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootManager.cs)
## Detailed Component Analysis
### AutolootManager Analysis
The AutolootManager handles automatic item collection based on configurable rules. It processes incoming item drop events and determines whether items should be picked up based on defined criteria.
#### Key Features:
- **Multi-Criteria Matching**: Supports matching by name, hue, weight, value, and custom properties
- **Smart Filtering**: Advanced filtering with regex support and property-based conditions
- **Action Queuing**: Intelligent queuing of pickup actions to prevent conflicts
- **Priority System**: Multiple rules can match an item, with priority determining which action takes precedence
#### Implementation Pattern:
```mermaid
flowchart TD
Start([Item Drop Event]) --> ParseItem["Parse Item Properties"]
ParseItem --> LoadRules["Load Active Autoloot Rules"]
LoadRules --> EvaluateRules["Evaluate Each Rule"]
EvaluateRules --> MatchFound{"Any Rule Matches?"}
MatchFound --> |No| IgnoreItem["Ignore Item"]
MatchFound --> |Yes| DetermineAction["Determine Best Action"]
DetermineAction --> QueueAction["Queue Pickup Action"]
QueueAction --> End([Process Complete])
IgnoreItem --> End
```
**Diagram sources**
- [AutolootManager.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootManager.cs)
- [AutolootEntry.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootEntry.cs)
**Section sources**
- [AutolootManager.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootManager.cs)
- [AutolootEntry.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootEntry.cs)
### DressManager Analysis
The DressManager automates equipment changes based on situational awareness and predefined outfit configurations. It monitors game state and automatically equips or unequips items to optimize character performance.
#### Core Functionality:
- **Outfit Management**: Create and manage multiple outfit configurations
- **Conditional Activation**: Activate outfits based on combat mode, location, or other game states
- **Inventory Awareness**: Understand current inventory and equipped items
- **Conflict Resolution**: Handle situations where required items are not available
#### State Machine:
```mermaid
stateDiagram-v2
[*] --> Idle
Idle --> Monitoring : "Start Agent"
Monitoring --> ConditionCheck : "Periodic Check"
ConditionCheck --> NeedsChange{"Outfit Change Needed?"}
NeedsChange --> |No| Monitoring
NeedsChange --> |Yes| PrepareChange["Prepare Item Changes"]
PrepareChange --> HasItems{"All Items Available?"}
HasItems --> |No| LogError["Log Missing Items"]
HasItems --> |Yes| ExecuteChange["Execute Equipment Change"]
ExecuteChange --> VerifyChange["Verify New Outfit"]
VerifyChange --> Monitoring
LogError --> Monitoring
Monitoring --> [*] : "Stop Agent"
```
**Diagram sources**
- [DressManager.cs](file://ClassicAssist.Shared/Data/Dress/DressManager.cs)
- [DressAgentEntry.cs](file://ClassicAssist.Shared/Data/Dress/DressAgentEntry.cs)
**Section sources**
- [DressManager.cs](file://ClassicAssist.Shared/Data/Dress/DressManager.cs)
- [DressAgentEntry.cs](file://ClassicAssist.Shared/Data/Dress/DressAgentEntry.cs)
### ScavengerManager Analysis
The ScavengerManager provides automatic item collection capabilities, allowing characters to gather specific types of items from the ground without manual intervention.
#### Advanced Features:
- **Pathfinding Integration**: Intelligent movement to target locations
- **Range Management**: Respects pickup range limitations and pathfinding obstacles
- **Batch Processing**: Efficiently handles multiple items in close proximity
- **Safety Checks**: Avoids dangerous areas and respects game mechanics
#### Processing Pipeline:
```mermaid
flowchart TD
ScanArea["Scan Area for Items"] --> FilterItems["Filter by Criteria"]
FilterItems --> Prioritize["Prioritize Targets"]
Prioritize --> Pathfind["Calculate Path to Target"]
Pathfind --> CanReach{"Can Reach Target?"}
CanReach --> |No| SkipTarget["Skip and Try Next"]
CanReach --> |Yes| MoveToTarget["Move to Target Location"]
MoveToTarget --> PickUpItem["Pick Up Item"]
PickUpItem --> InventoryCheck{"Inventory Full?"}
InventoryCheck --> |Yes| ReturnHome["Return to Home Location"]
InventoryCheck --> |No| ContinueScavenging["Continue Scavenging"]
SkipTarget --> ContinueScavenging
ReturnHome --> ScanArea
ContinueScavenging --> ScanArea
```
**Diagram sources**
- [ScavengerManager.cs](file://ClassicAssist.Shared/Data/Scavenger/ScavengerManager.cs)
- [ScavengerEntry.cs](file://ClassicAssist.Shared/Data/Scavenger/ScavengerEntry.cs)
**Section sources**
- [ScavengerManager.cs](file://ClassicAssist.Shared/Data/Scavenger/ScavengerManager.cs)
- [ScavengerEntry.cs](file://ClassicAssist.Shared/Data/Scavenger/ScavengerEntry.cs)
## Dependency Analysis
The agent framework maintains loose coupling between components while ensuring proper data flow and event handling:
```mermaid
graph LR
subgraph "Core Dependencies"
Engine[Engine]
Network[Network Layer]
Objects[Object System]
Filters[Filter System]
end
subgraph "Agent Managers"
AutoLoot[AUTOLootManager]
Dress[DressManager]
Scavenger[ScavengerManager]
end
subgraph "External Systems"
GameAPI[Game API]
Storage[Storage System]
UI[UI System]
end
Engine --> AutoLoot
Engine --> Dress
Engine --> Scavenger
AutoLoot --> Objects
Dress --> Objects
Scavenger --> Objects
AutoLoot --> Filters
Dress --> Filters
Scavenger --> Filters
AutoLoot --> Network
Dress --> Network
Scavenger --> Network
AutoLoot --> Storage
Dress --> Storage
Scavenger --> Storage
AutoLoot --> UI
Dress --> UI
Scavenger --> UI
```
**Diagram sources**
- [Engine.cs](file://ClassicAssist.Shared/Engine.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)
**Section sources**
- [Engine.cs](file://ClassicAssist.Shared/Engine.cs)
## Performance Considerations
### Threading Model
The agent framework implements a multi-threaded architecture designed for optimal performance:
- **Main Thread**: UI updates and critical game interactions
- **Worker Threads**: Rule evaluation and complex calculations
- **Background Tasks**: File I/O and network operations
- **Thread-Safe Collections**: All shared data structures use concurrent collections
### Memory Management
Key memory optimization strategies include:
- **Object Pooling**: Reuse frequently created objects to reduce GC pressure
- **Lazy Loading**: Load agent configurations only when needed
- **Event Unsubscription**: Proper cleanup of event handlers to prevent memory leaks
- **Weak References**: Use weak references for long-lived observers
### Optimization Techniques
1. **Caching**: Cache frequently accessed game data and rule evaluations
2. **Batch Processing**: Group similar operations to minimize overhead
3. **Early Exit**: Short-circuit expensive operations when possible
4. **Asynchronous Operations**: Non-blocking I/O and network calls
## Troubleshooting Guide
### Common Issues and Solutions
**Agent Not Starting:**
- Verify agent configuration syntax
- Check for missing dependencies or invalid property values
- Review error logs for initialization failures
**Poor Performance:**
- Reduce number of active rules per agent
- Optimize condition complexity and avoid expensive operations
- Monitor memory usage and garbage collection frequency
**Incorrect Behavior:**
- Enable debug logging for detailed operation traces
- Test individual rules in isolation
- Verify game state assumptions in conditions
### Debugging Tools
The framework provides comprehensive debugging capabilities:
- **Live Rule Evaluation**: Real-time testing of condition logic
- **Performance Profiling**: Identify bottlenecks in rule processing
- **State Inspection**: Examine agent internal state and variables
- **Event Tracing**: Track game events and agent responses
**Section sources**
- [Engine.cs](file://ClassicAssist.Shared/Engine.cs)
## Conclusion
The ClassicAssist.Avalonia agent framework provides a robust, extensible foundation for creating intelligent automation agents. Its manager-based architecture, combined with a powerful rule engine and comprehensive threading model, enables developers to create sophisticated agents that can handle complex gameplay scenarios efficiently.
The framework's design emphasizes modularity, performance, and ease of extension, making it suitable for both simple automation tasks and complex AI behaviors. By following the established patterns and leveraging the built-in utilities, developers can create reliable agents that enhance the Ultima Online gaming experience.
## Appendices
### Creating Custom Agents
To implement a custom agent:
1. **Extend the Base Manager Class**: Create a new class inheriting from the appropriate base manager
2. **Define Entry Models**: Create configuration classes for your agent's rules
3. **Implement Lifecycle Methods**: Override initialization, update, and cleanup methods
4. **Register Event Handlers**: Subscribe to relevant game events
5. **Add Configuration Support**: Implement save/load functionality for your rules
6. **Create UI Components**: Build user interfaces for configuring your agent
### Best Practices
- **Keep Rules Simple**: Break complex logic into smaller, testable components
- **Handle Errors Gracefully**: Always validate inputs and handle exceptions
- **Use Appropriate Threading**: Keep UI operations on the main thread
- **Monitor Performance**: Profile regularly and optimize hot paths
- **Document Your Rules**: Provide clear descriptions for complex conditions
@@ -0,0 +1,446 @@
# Autoloot Agent
<cite>
**Referenced Files in This Document**
- [AutolootManager.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootManager.cs)
- [AutolootEntry.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootEntry.cs)
- [AutolootConstraintEntry.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootConstraintEntry.cs)
- [AutolootOperator.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootOperator.cs)
- [PropertyEntry.cs](file://ClassicAssist.Shared/Data/Autoloot/PropertyEntry.cs)
- [PropertyType.cs](file://ClassicAssist.Shared/Data/Autoloot/PropertyType.cs)
- [AutolootHelpers.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootHelpers.cs)
- [AutolootViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/AutolootViewModel.cs)
- [AutolootTabControl.axaml](file://ClassicAssist.Avalonia/Views/Agents/AutolootTabControl.axaml)
- [AutolootTabControl.xaml](file://ClassicAssist/UI/Views/Agents/AutolootTabControl.xaml)
- [ClilocSelectionWindow.xaml](file://ClassicAssist/UI/Views/Autoloot/ClilocSelectionWindow.xaml)
- [CustomPropertiesWindow.xaml](file://ClassicAssist/UI/Views/Autoloot/CustomPropertiesWindow.xaml)
- [PropertySelectionWindow.xaml](file://ClassicAssist/UI/Views/Autoloot/PropertySelectionWindow.xaml)
- [ClilocSelectionViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Autoloot/ClilocSelectionViewModel.cs)
- [CustomPropertiesViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Autoloot/CustomPropertiesViewModel.cs)
- [PropertySelectionViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Autoloot/PropertySelectionViewModel.cs)
- [Item.cs](file://ClassicAssist.Shared/UO/Objects/Item.cs)
- [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs)
- [ContainerContentsPacket.cs](file://ClassicAssist.Shared/UO/Network/Packets/ContainerContentsPacket.cs)
- [DropItem.cs](file://ClassicAssist.Shared/UO/Network/Packets/DropItem.cs)
- [AutolootTests.cs](file://ClassicAssist.Tests/Agents/AutolootTests.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
The Autoloot agent automatically picks up items based on user-defined rules and conditions. It evaluates incoming or existing items against a set of constraints, resolves conflicts when multiple rules match, and executes pickup actions through the game client’s targeting system. The feature includes a rule creation interface with property matching, operator-based comparisons, logical grouping, and testing utilities to validate rules before enabling them.
## Project Structure
The Autoloot system is implemented across shared data models, UI views/view models, and network integration points:
- Data layer: rule definitions, operators, properties, helpers, and manager orchestration
- UI layer (Avalonia): tabs and windows for rule management and testing
- Integration: item objects and packet handlers that trigger autoloot evaluation
- Tests: unit tests validating core logic
```mermaid
graph TB
subgraph "Data Layer"
M["AutolootManager"]
E["AutolootEntry"]
C["AutolootConstraintEntry"]
O["AutolootOperator"]
P["PropertyEntry / PropertyType"]
H["AutolootHelpers"]
end
subgraph "UI Layer (Avalonia)"
T["AutolootTabControl"]
VM["AutolootViewModel"]
W1["ClilocSelectionWindow"]
W2["CustomPropertiesWindow"]
W3["PropertySelectionWindow"]
VM1["ClilocSelectionViewModel"]
VM2["CustomPropertiesViewModel"]
VM3["PropertySelectionViewModel"]
end
subgraph "Integration"
I["Item"]
PH["IncomingPacketHandlers"]
CCP["ContainerContentsPacket"]
DI["DropItem"]
end
subgraph "Tests"
AT["AutolootTests"]
end
VM --> M
T --> VM
W1 --> VM1
W2 --> VM2
W3 --> VM3
M --> E
E --> C
C --> O
C --> P
M --> H
PH --> CCP
PH --> DI
CCP --> M
DI --> M
I --> M
AT --> M
```
**Diagram sources**
- [AutolootManager.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootManager.cs)
- [AutolootEntry.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootEntry.cs)
- [AutolootConstraintEntry.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootConstraintEntry.cs)
- [AutolootOperator.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootOperator.cs)
- [PropertyEntry.cs](file://ClassicAssist.Shared/Data/Autoloot/PropertyEntry.cs)
- [PropertyType.cs](file://ClassicAssist.Shared/Data/Autoloot/PropertyType.cs)
- [AutolootHelpers.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootHelpers.cs)
- [AutolootTabControl.axaml](file://ClassicAssist.Avalonia/Views/Agents/AutolootTabControl.axaml)
- [AutolootViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/AutolootViewModel.cs)
- [ClilocSelectionWindow.xaml](file://ClassicAssist/UI/Views/Autoloot/ClilocSelectionWindow.xaml)
- [CustomPropertiesWindow.xaml](file://ClassicAssist/UI/Views/Autoloot/CustomPropertiesWindow.xaml)
- [PropertySelectionWindow.xaml](file://ClassicAssist/UI/Views/Autoloot/PropertySelectionWindow.xaml)
- [ClilocSelectionViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Autoloot/ClilocSelectionViewModel.cs)
- [CustomPropertiesViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Autoloot/CustomPropertiesViewModel.cs)
- [PropertySelectionViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Autoloot/PropertySelectionViewModel.cs)
- [Item.cs](file://ClassicAssist.Shared/UO/Objects/Item.cs)
- [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs)
- [ContainerContentsPacket.cs](file://ClassicAssist.Shared/UO/Network/Packets/ContainerContentsPacket.cs)
- [DropItem.cs](file://ClassicAssist.Shared/UO/Network/Packets/DropItem.cs)
- [AutolootTests.cs](file://ClassicAssist.Tests/Agents/AutolootTests.cs)
**Section sources**
- [AutolootManager.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootManager.cs)
- [AutolootViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/AutolootViewModel.cs)
- [AutolootTabControl.axaml](file://ClassicAssist.Avalonia/Views/Agents/AutolootTabControl.axaml)
- [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs)
- [ContainerContentsPacket.cs](file://ClassicAssist.Shared/UO/Network/Packets/ContainerContentsPacket.cs)
- [DropItem.cs](file://ClassicAssist.Shared/UO/Network/Packets/DropItem.cs)
- [AutolootTests.cs](file://ClassicAssist.Tests/Agents/AutolootTests.cs)
## Core Components
- AutolootManager: Central orchestrator that loads, evaluates, and applies autoloot rules. It integrates with item events and packet handlers to decide whether to pick up an item.
- AutolootEntry: Represents a single autoloot rule with metadata, enabled state, and associated constraints.
- AutolootConstraintEntry: Encapsulates a condition composed of a property, operator, and value(s). Constraints are combined using logical operators within a rule.
- AutolootOperator: Enumerates supported comparison operators used by constraints (e.g., equals, contains, greater than).
- PropertyEntry and PropertyType: Define available item properties and their types for matching.
- AutolootHelpers: Utility functions for normalization, parsing, and common operations used during evaluation.
- AutolootViewModel: View model backing the Avalonia tab; exposes commands for creating, editing, testing, and bulk-managing rules.
- UI Windows: Cliloc selection, custom properties, and property selection dialogs assist users in building complex rules.
Key responsibilities:
- Rule lifecycle: create, edit, enable/disable, delete, import/export
- Constraint evaluation: property extraction, type conversion, operator application, logical combination
- Conflict resolution: priority ordering and first-match semantics
- Testing: dry-run evaluation against sample items without performing pickups
- Integration: subscribe to item arrival events and container updates
**Section sources**
- [AutolootManager.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootManager.cs)
- [AutolootEntry.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootEntry.cs)
- [AutolootConstraintEntry.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootConstraintEntry.cs)
- [AutolootOperator.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootOperator.cs)
- [PropertyEntry.cs](file://ClassicAssist.Shared/Data/Autoloot/PropertyEntry.cs)
- [PropertyType.cs](file://ClassicAssist.Shared/Data/Autoloot/PropertyType.cs)
- [AutolootHelpers.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootHelpers.cs)
- [AutolootViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/AutolootViewModel.cs)
- [ClilocSelectionWindow.xaml](file://ClassicAssist/UI/Views/Autoloot/ClilocSelectionWindow.xaml)
- [CustomPropertiesWindow.xaml](file://ClassicAssist/UI/Views/Autoloot/CustomPropertiesWindow.xaml)
- [PropertySelectionWindow.xaml](file://ClassicAssist/UI/Views/Autoloot/PropertySelectionWindow.xaml)
## Architecture Overview
The autoloot pipeline subscribes to item-related events and packet handlers. When an item becomes available (dropped or revealed in containers), the manager evaluates it against all active rules. Each rule consists of one or more constraints evaluated with logical operators. If a rule matches, the manager selects the highest-priority rule and triggers a pickup action via the targeting subsystem.
```mermaid
sequenceDiagram
participant Game as "Game Client"
participant Net as "IncomingPacketHandlers"
participant Item as "Item"
participant Manager as "AutolootManager"
participant Rule as "AutolootEntry"
participant C as "AutolootConstraintEntry"
participant Target as "Targeting System"
Game->>Net : "DropItem / ContainerContentsPacket"
Net->>Manager : "Notify item event"
Manager->>Item : "Read properties"
loop For each active rule
Manager->>Rule : "Evaluate(rule)"
Rule->>C : "Evaluate constraint"
C-->>Rule : "Boolean result"
Rule-->>Manager : "Matched?"
end
alt "Multiple matches"
Manager->>Manager : "Resolve conflict by priority"
end
alt "Highest priority matched"
Manager->>Target : "Pickup(item)"
Target-->>Game : "Pickup command"
else "No match"
Manager-->>Game : "Ignore"
end
```
**Diagram sources**
- [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs)
- [ContainerContentsPacket.cs](file://ClassicAssist.Shared/UO/Network/Packets/ContainerContentsPacket.cs)
- [DropItem.cs](file://ClassicAssist.Shared/UO/Network/Packets/DropItem.cs)
- [AutolootManager.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootManager.cs)
- [AutolootEntry.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootEntry.cs)
- [AutolootConstraintEntry.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootConstraintEntry.cs)
- [Item.cs](file://ClassicAssist.Shared/UO/Objects/Item.cs)
## Detailed Component Analysis
### Rule Model and Evaluation Engine
- AutolootEntry holds rule metadata and a list of constraints. Rules can be enabled/disabled and have a priority field to resolve conflicts.
- AutolootConstraintEntry defines a property selector, operator, and value(s). Logical combination within a rule uses AND/OR grouping.
- AutolootOperator enumerates supported comparisons.
- PropertyEntry and PropertyType define the schema of item attributes available for matching.
- AutolootHelpers provides normalization and parsing utilities used during evaluation.
```mermaid
classDiagram
class AutolootManager {
+LoadRules()
+Evaluate(item) bool
+Pickup(item) void
+ResolveConflicts(matches) AutolootEntry
}
class AutolootEntry {
+string name
+bool enabled
+int priority
+AutolootConstraintEntry[] constraints
+Matches(item) bool
}
class AutolootConstraintEntry {
+PropertyEntry property
+AutolootOperator op
+object value
+Evaluate(propertyValue) bool
}
class AutolootOperator {
<<enum>>
}
class PropertyEntry {
+string name
+PropertyType type
}
class PropertyType {
<<enum>>
}
class AutolootHelpers {
+Normalize(text) string
+Parse(value, type) object
}
AutolootManager --> AutolootEntry : "manages"
AutolootEntry --> AutolootConstraintEntry : "contains"
AutolootConstraintEntry --> PropertyEntry : "uses"
AutolootConstraintEntry --> AutolootOperator : "applies"
AutolootManager --> AutolootHelpers : "uses"
```
**Diagram sources**
- [AutolootManager.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootManager.cs)
- [AutolootEntry.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootEntry.cs)
- [AutolootConstraintEntry.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootConstraintEntry.cs)
- [AutolootOperator.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootOperator.cs)
- [PropertyEntry.cs](file://ClassicAssist.Shared/Data/Autoloot/PropertyEntry.cs)
- [PropertyType.cs](file://ClassicAssist.Shared/Data/Autoloot/PropertyType.cs)
- [AutolootHelpers.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootHelpers.cs)
**Section sources**
- [AutolootManager.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootManager.cs)
- [AutolootEntry.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootEntry.cs)
- [AutolootConstraintEntry.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootConstraintEntry.cs)
- [AutolootOperator.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootOperator.cs)
- [PropertyEntry.cs](file://ClassicAssist.Shared/Data/Autoloot/PropertyEntry.cs)
- [PropertyType.cs](file://ClassicAssist.Shared/Data/Autoloot/PropertyType.cs)
- [AutolootHelpers.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootHelpers.cs)
### Rule Creation Interface and Property Matching
- AutolootTabControl hosts the main rule editor UI.
- AutolootViewModel exposes commands for adding/removing rules, toggling enabled state, setting priorities, and running tests.
- PropertySelectionWindow and PropertySelectionViewModel help choose from available properties and types.
- CustomPropertiesWindow and CustomPropertiesViewModel allow defining or selecting custom properties for advanced matching.
- ClilocSelectionWindow and ClilocSelectionViewModel provide localized text selection for cliloc-based matching.
Typical workflow:
1. Open the Autoloot tab.
2. Create a new rule and assign a descriptive name.
3. Add constraints by selecting a property, operator, and value.
4. Use logical grouping to combine constraints (AND/OR).
5. Test the rule against sample items using the test function.
6. Save and enable the rule.
**Section sources**
- [AutolootTabControl.axaml](file://ClassicAssist.Avalonia/Views/Agents/AutolootTabControl.axaml)
- [AutolootViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/AutolootViewModel.cs)
- [PropertySelectionWindow.xaml](file://ClassicAssist/UI/Views/Autoloot/PropertySelectionWindow.xaml)
- [PropertySelectionViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Autoloot/PropertySelectionViewModel.cs)
- [CustomPropertiesWindow.xaml](file://ClassicAssist/UI/Views/Autoloot/CustomPropertiesWindow.xaml)
- [CustomPropertiesViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Autoloot/CustomPropertiesViewModel.cs)
- [ClilocSelectionWindow.xaml](file://ClassicAssist/UI/Views/Autoloot/ClilocSelectionWindow.xaml)
- [ClilocSelectionViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Autoloot/ClilocSelectionViewModel.cs)
### Constraint Evaluation Flow
The evaluation flow normalizes inputs, converts values to the expected property type, applies the operator, and aggregates results per rule.
```mermaid
flowchart TD
Start(["Start Evaluate"]) --> ReadProps["Read item properties"]
ReadProps --> Normalize["Normalize strings if needed"]
Normalize --> Convert["Convert values to target type"]
Convert --> ApplyOp["Apply operator to compare"]
ApplyOp --> Aggregate["Aggregate with logical operators"]
Aggregate --> Result{"Rule matched?"}
Result --> |Yes| PickCandidate["Add to candidates"]
Result --> |No| NextRule["Next rule"]
PickCandidate --> Resolve["Resolve conflicts by priority"]
Resolve --> Action["Pickup highest priority item"]
NextRule --> End(["End"])
Action --> End
```
**Diagram sources**
- [AutolootManager.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootManager.cs)
- [AutolootEntry.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootEntry.cs)
- [AutolootConstraintEntry.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootConstraintEntry.cs)
- [AutolootOperator.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootOperator.cs)
- [PropertyEntry.cs](file://ClassicAssist.Shared/Data/Autoloot/PropertyEntry.cs)
- [PropertyType.cs](file://ClassicAssist.Shared/Data/Autoloot/PropertyType.cs)
- [AutolootHelpers.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootHelpers.cs)
### Integration with Inventory Management and Pickup Automation
- IncomingPacketHandlers routes relevant packets to the autoloot manager.
- ContainerContentsPacket and DropItem represent item arrivals that trigger evaluation.
- Item provides the property surface used by constraints.
- The manager coordinates with the targeting system to perform pickups.
```mermaid
sequenceDiagram
participant Packet as "IncomingPacketHandlers"
participant Event as "ContainerContentsPacket / DropItem"
participant Manager as "AutolootManager"
participant Item as "Item"
participant Target as "Targeting System"
Packet->>Event : "Dispatch packet"
Event->>Manager : "OnItemArrival(item)"
Manager->>Item : "Extract properties"
Manager->>Manager : "Evaluate rules"
alt "Match found"
Manager->>Target : "Pickup(item)"
else "No match"
Manager-->>Packet : "No action"
end
```
**Diagram sources**
- [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs)
- [ContainerContentsPacket.cs](file://ClassicAssist.Shared/UO/Network/Packets/ContainerContentsPacket.cs)
- [DropItem.cs](file://ClassicAssist.Shared/UO/Network/Packets/DropItem.cs)
- [AutolootManager.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootManager.cs)
- [Item.cs](file://ClassicAssist.Shared/UO/Objects/Item.cs)
### Examples of Complex Rules
- Example 1: Pick up any gold with quantity greater than 100 and hue not equal to a specific exclusion hue.
- Example 2: Pick up potions whose name contains “Healing” and weight less than or equal to a threshold.
- Example 3: Pick up items whose cliloc matches a localized string and has a custom property flag set.
- Example 4: Exclude items owned by other players and only pick up items dropped at current location.
These examples illustrate combining multiple constraints, using operators like greater-than, contains, and equality, and applying logical grouping to refine behavior.
[No sources needed since this section provides conceptual examples]
### Bulk Operations and Rule Testing
- Bulk operations include enabling/disabling multiple rules, adjusting priorities, duplicating rules, and importing/exporting configurations.
- Rule testing allows evaluating a rule against a selected item or a batch of items without executing pickups. Results indicate which constraints matched and why.
**Section sources**
- [AutolootViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/AutolootViewModel.cs)
- [AutolootTabControl.axaml](file://ClassicAssist.Avalonia/Views/Agents/AutolootTabControl.axaml)
## Dependency Analysis
- AutolootManager depends on AutolootEntry, AutolootConstraintEntry, AutolootOperator, PropertyEntry, PropertyType, and AutolootHelpers.
- UI components depend on AutolootViewModel and related view models for property and cliloc selection.
- Network integration depends on IncomingPacketHandlers and specific packet classes to feed item events into the manager.
- Tests depend on the manager and rule models to assert correct evaluation and conflict resolution.
```mermaid
graph LR
VM["AutolootViewModel"] --> M["AutolootManager"]
M --> E["AutolootEntry"]
E --> C["AutolootConstraintEntry"]
C --> O["AutolootOperator"]
C --> P["PropertyEntry"]
P --> PT["PropertyType"]
M --> H["AutolootHelpers"]
PH["IncomingPacketHandlers"] --> M
CCP["ContainerContentsPacket"] --> PH
DI["DropItem"] --> PH
IT["Item"] --> M
T["AutolootTests"] --> M
```
**Diagram sources**
- [AutolootViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/AutolootViewModel.cs)
- [AutolootManager.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootManager.cs)
- [AutolootEntry.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootEntry.cs)
- [AutolootConstraintEntry.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootConstraintEntry.cs)
- [AutolootOperator.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootOperator.cs)
- [PropertyEntry.cs](file://ClassicAssist.Shared/Data/Autoloot/PropertyEntry.cs)
- [PropertyType.cs](file://ClassicAssist.Shared/Data/Autoloot/PropertyType.cs)
- [AutolootHelpers.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootHelpers.cs)
- [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs)
- [ContainerContentsPacket.cs](file://ClassicAssist.Shared/UO/Network/Packets/ContainerContentsPacket.cs)
- [DropItem.cs](file://ClassicAssist.Shared/UO/Network/Packets/DropItem.cs)
- [Item.cs](file://ClassicAssist.Shared/UO/Objects/Item.cs)
- [AutolootTests.cs](file://ClassicAssist.Tests/Agents/AutolootTests.cs)
**Section sources**
- [AutolootViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/AutolootViewModel.cs)
- [AutolootManager.cs](file://ClassicAssist.Shared/Data/Autoloot/AutolootManager.cs)
- [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs)
- [AutolootTests.cs](file://ClassicAssist.Tests/Agents/AutolootTests.cs)
## Performance Considerations
- Rule evaluation complexity scales with the number of active rules and constraints. Prefer fewer high-precision rules over many broad ones.
- Normalize and cache frequently accessed properties where possible to avoid repeated conversions.
- Use short-circuit evaluation in logical expressions to fail fast on non-matching constraints.
- Limit heavy operations (like regex or deep string processing) to necessary cases; prefer exact matches when feasible.
- Batch testing should avoid triggering actual pickups; use dry-run mode for large sets.
- Monitor memory usage by avoiding retaining references to large item collections after evaluation.
[No sources needed since this section provides general guidance]
## Troubleshooting Guide
- No items picked up: Verify rules are enabled and have higher priority than conflicting rules. Check that constraints match actual item properties.
- Wrong items picked up: Inspect operator choices and value types; ensure proper normalization and case sensitivity settings.
- Performance issues: Reduce rule count, simplify constraints, and disable unused rules.
- Conflicting rules: Adjust priorities so the most specific rule wins. Use exclusions to prevent unintended matches.
- Testing discrepancies: Ensure test input items reflect real-world properties and formats. Validate cliloc selections and custom properties.
**Section sources**
- [AutolootTests.cs](file://ClassicAssist.Tests/Agents/AutolootTests.cs)
- [AutolootViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/AutolootViewModel.cs)
## Conclusion
The Autoloot agent provides a flexible, rule-driven system for automatic item pickup. By combining property-based constraints, operators, and logical grouping, users can craft precise behaviors while managing performance and conflicts through prioritization and testing tools. The UI facilitates rule creation and validation, and integration with packet handlers ensures timely evaluation upon item arrival.
[No sources needed since this section summarizes without analyzing specific files]
## Appendices
- Best practices:
- Keep rules specific and ordered by priority.
- Use exclusions to handle edge cases.
- Regularly review and prune unused rules.
- Leverage testing features before deploying changes.
[No sources needed since this section provides general guidance]
@@ -0,0 +1,449 @@
# Dress Manager Agent
<cite>
**Referenced Files in This Document**
- [DressManager.cs](file://ClassicAssist.Shared/Data/Dress/DressManager.cs)
- [DressAgentEntry.cs](file://ClassicAssist.Shared/Data/Dress/DressAgentEntry.cs)
- [DressAgentItem.cs](file://ClassicAssist.Shared/Data/Dress/DressAgentItem.cs)
- [DressAgentItemType.cs](file://ClassicAssist.Shared/Data/Dress/DressAgentItemType.cs)
- [DressTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/DressTabViewModel.cs)
- [DressTabControl.xaml.cs](file://ClassicAssist.Avalonia/Views/Agents/DressTabControl.xaml.cs)
- [DressTabControl.xaml](file://ClassicAssist.Avalonia/Views/Agents/DressTabControl.xaml)
- [DressAgentTests.cs](file://ClassicAssist.Tests/Agents/DressAgentTests.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)
## Introduction
The Dress Manager agent is a sophisticated automation system within ClassicAssist that manages character equipment sets and automates outfit changes based on various game scenarios. This feature allows players to create multiple dress profiles containing specific equipment configurations for different activities such as combat, crafting, social events, or exploration. The system intelligently switches between these profiles automatically or manually, ensuring optimal gear setup for any situation.
The Dress Manager provides a comprehensive solution for managing complex equipment setups, handling item validation, conditional outfit switching, and seamless integration with game events and skill checks. It supports both manual profile selection and automatic detection-based outfit changes, making it an essential tool for efficient gameplay management.
## Project Structure
The Dress Manager implementation follows a clean architecture pattern with clear separation between data models, business logic, user interface, and testing components:
```mermaid
graph TB
subgraph "Data Layer"
DM[DressManager.cs]
DAE[DressAgentEntry.cs]
DAI[DressAgentItem.cs]
DT[DressAgentItemType.cs]
end
subgraph "UI Layer"
VM[DressTabViewModel.cs]
XAML[DressTabControl.xaml]
CS[DressTabControl.xaml.cs]
end
subgraph "Testing"
TEST[DressAgentTests.cs]
end
subgraph "Game Integration"
GAME[Game Engine]
ITEMS[Item System]
EVENTS[Event System]
end
DM --> DAE
DM --> DAI
DM --> DT
VM --> DM
XAML --> VM
CS --> VM
DM --> GAME
DM --> ITEMS
DM --> EVENTS
TEST --> DM
```
**Diagram sources**
- [DressManager.cs](file://ClassicAssist.Shared/Data/Dress/DressManager.cs)
- [DressAgentEntry.cs](file://ClassicAssist.Shared/Data/Dress/DressAgentEntry.cs)
- [DressAgentItem.cs](file://ClassicAssist.Shared/Data/Dress/DressAgentItem.cs)
- [DressAgentItemType.cs](file://ClassicAssist.Shared/Data/Dress/DressAgentItemType.cs)
- [DressTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/DressTabViewModel.cs)
- [DressTabControl.xaml.cs](file://ClassicAssist.Avalonia/Views/Agents/DressTabControl.xaml.cs)
- [DressTabControl.xaml](file://ClassicAssist.Avalonia/Views/Agents/DressTabControl.xaml)
- [DressAgentTests.cs](file://ClassicAssist.Tests/Agents/DressAgentTests.cs)
**Section sources**
- [DressManager.cs](file://ClassicAssist.Shared/Data/Dress/DressManager.cs)
- [DressAgentEntry.cs](file://ClassicAssist.Shared/Data/Dress/DressAgentEntry.cs)
- [DressAgentItem.cs](file://ClassicAssist.Shared/Data/Dress/DressAgentItem.cs)
- [DressAgentItemType.cs](file://ClassicAssist.Shared/Data/Dress/DressAgentItemType.cs)
- [DressTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/DressTabViewModel.cs)
- [DressTabControl.xaml.cs](file://ClassicAssist.Avalonia/Views/Agents/DressTabControl.xaml.cs)
- [DressTabControl.xaml](file://ClassicAssist.Avalonia/Views/Agents/DressTabControl.xaml)
- [DressAgentTests.cs](file://ClassicAssist.Tests/Agents/DressAgentTests.cs)
## Core Components
The Dress Manager system consists of several key components that work together to provide comprehensive equipment management functionality:
### Data Models
The core data structures define how dress profiles and items are represented:
- **DressAgentEntry**: Represents a complete dress profile containing all equipment slots and their configurations
- **DressAgentItem**: Defines individual item specifications including item type, properties, and slot assignments
- **DressAgentItemType**: Enumerates all possible equipment types and categories supported by the system
- **DressManager**: Central orchestrator managing profile creation, validation, and outfit application
### User Interface Components
The UI layer provides intuitive management interfaces:
- **DressTabViewModel**: Manages the view model state and business logic for the dress manager interface
- **DressTabControl**: Main tab control hosting the dress manager functionality
- **XAML Layout**: Declarative UI definitions for profile management, item selection, and preview features
### Testing Framework
Comprehensive test coverage ensures reliability:
- **DressAgentTests**: Unit tests covering profile creation, item validation, and outfit switching scenarios
**Section sources**
- [DressManager.cs](file://ClassicAssist.Shared/Data/Dress/DressManager.cs)
- [DressAgentEntry.cs](file://ClassicAssist.Shared/Data/Dress/DressAgentEntry.cs)
- [DressAgentItem.cs](file://ClassicAssist.Shared/Data/Dress/DressAgentItem.cs)
- [DressAgentItemType.cs](file://ClassicAssist.Shared/Data/Dress/DressAgentItemType.cs)
- [DressTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/DressTabViewModel.cs)
- [DressTabControl.xaml.cs](file://ClassicAssist.Avalonia/Views/Agents/DressTabControl.xaml.cs)
- [DressTabControl.xaml](file://ClassicAssist.Avalonia/Views/Agents/DressTabControl.xaml)
- [DressAgentTests.cs](file://ClassicAssist.Tests/Agents/DressAgentTests.cs)
## Architecture Overview
The Dress Manager follows a layered architecture pattern with clear separation of concerns:
```mermaid
sequenceDiagram
participant User as "User Interface"
participant ViewModel as "DressTabViewModel"
participant Manager as "DressManager"
participant GameEngine as "Game Engine"
participant ItemSystem as "Item System"
User->>ViewModel : Create New Profile
ViewModel->>Manager : AddProfile(profileName)
Manager->>Manager : ValidateProfile()
Manager-->>ViewModel : ProfileCreated
User->>ViewModel : Add Item to Slot
ViewModel->>Manager : AddItemToSlot(slotType, itemSpec)
Manager->>ItemSystem : ValidateItem(itemSpec)
ItemSystem-->>Manager : ValidationResult
Manager-->>ViewModel : ItemAdded
User->>ViewModel : Apply Outfit
ViewModel->>Manager : ApplyOutfit(profileId)
Manager->>GameEngine : EquipItems(items)
GameEngine-->>Manager : EquipmentStatus
Manager-->>ViewModel : OutfitApplied
Note over Manager,GameEngine : Automatic Detection
GameEngine->>Manager : OnCombatStart()
Manager->>Manager : FindBestOutfit(combat)
Manager->>GameEngine : AutoEquip(outfit)
```
**Diagram sources**
- [DressManager.cs](file://ClassicAssist.Shared/Data/Dress/DressManager.cs)
- [DressTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/DressTabViewModel.cs)
- [DressTabControl.xaml.cs](file://ClassicAssist.Avalonia/Views/Agents/DressTabControl.xaml.cs)
The architecture emphasizes:
- **Separation of Concerns**: Clear boundaries between UI, business logic, and game integration
- **Validation at Multiple Levels**: Item validation occurs during both configuration and application
- **Event-Driven Updates**: Real-time synchronization between game state and UI
- **Error Handling**: Comprehensive error management for missing items and invalid configurations
## Detailed Component Analysis
### Dress Manager Core Logic
The DressManager serves as the central coordinator for all dress-related operations:
#### Key Responsibilities
- Profile lifecycle management (creation, modification, deletion)
- Item validation and compatibility checking
- Outfit application and rollback mechanisms
- Conditional outfit switching based on game context
- Performance optimization for large inventories
#### Data Flow Architecture
```mermaid
flowchart TD
Start([Profile Creation]) --> ValidateInput["Validate Profile Input"]
ValidateInput --> InputValid{"Input Valid?"}
InputValid --> |No| ShowError["Display Validation Error"]
InputValid --> |Yes| CreateProfile["Create Empty Profile"]
CreateProfile --> AddItems["Add Items to Slots"]
AddItems --> ValidateItems["Validate All Items"]
ValidateItems --> ItemsValid{"All Items Valid?"}
ItemsValid --> |No| FixItems["Guide User to Fix Issues"]
ItemsValid --> |Yes| SaveProfile["Save Profile Configuration"]
SaveProfile --> ReadyForUse["Profile Ready for Use"]
ReadyForUse --> ManualSwitch["Manual Profile Switch"]
ReadyForUse --> AutoSwitch["Automatic Context Switch"]
ManualSwitch --> ApplyOutfit["Apply Selected Outfit"]
AutoSwitch --> DetectContext["Detect Game Context"]
DetectContext --> SelectBest["Select Best Matching Outfit"]
SelectBest --> ApplyOutfit
ApplyOutfit --> ValidateEquippable["Validate Equippable Items"]
ValidateEquippable --> EquipSuccess{"Equipment Success?"}
EquipSuccess --> |No| HandleErrors["Handle Missing/Invalid Items"]
EquipSuccess --> |Yes| UpdateUI["Update UI State"]
HandleErrors --> LogErrors["Log Errors and Warnings"]
LogErrors --> PartialSuccess["Report Partial Success"]
UpdateUI --> Complete([Operation Complete])
PartialSuccess --> Complete
```
**Diagram sources**
- [DressManager.cs](file://ClassicAssist.Shared/Data/Dress/DressManager.cs)
#### Conditional Outfit Switching Logic
The system supports sophisticated conditional logic for automatic outfit changes:
```mermaid
stateDiagram-v2
[*] --> Idle
Idle --> CombatDetected : "Enter Combat"
Idle --> CraftingDetected : "Start Crafting"
Idle --> SocialDetected : "Enter Social Area"
Idle --> ExplorationDetected : "Begin Exploration"
CombatDetected --> EvaluateCombatGear["Evaluate Combat Gear"]
CraftingDetected --> EvaluateCraftingGear["Evaluate Crafting Gear"]
SocialDetected --> EvaluateSocialGear["Evaluate Social Gear"]
ExplorationDetected --> EvaluateExplorationGear["Evaluate Exploration Gear"]
EvaluateCombatGear --> HasBetterGear{"Has Better Combat Gear?"}
EvaluateCraftingGear --> HasBetterCrafting{"Has Better Crafting Gear?"}
EvaluateSocialGear --> HasBetterSocial{"Has Better Social Gear?"}
EvaluateExplorationGear --> HasBetterExploration{"Has Better Exploration Gear?"}
HasBetterGear --> |Yes| SwitchToCombat["Switch to Combat Outfit"]
HasBetterCrafting --> |Yes| SwitchToCrafting["Switch to Crafting Outfit"]
HasBetterSocial --> |Yes| SwitchToSocial["Switch to Social Outfit"]
HasBetterExploration --> |Yes| SwitchToExploration["Switch to Exploration Outfit"]
HasBetterGear --> |No| StayCurrent["Stay Current Outfit"]
HasBetterCrafting --> |No| StayCurrent
HasBetterSocial --> |No| StayCurrent
HasBetterExploration --> |No| StayCurrent
SwitchToCombat --> Idle
SwitchToCrafting --> Idle
SwitchToSocial --> Idle
SwitchToExploration --> Idle
StayCurrent --> Idle
```
**Diagram sources**
- [DressManager.cs](file://ClassicAssist.Shared/Data/Dress/DressManager.cs)
### Item Slot Mapping System
The dress system uses a comprehensive slot mapping mechanism to ensure proper equipment placement:
#### Supported Equipment Slots
- Head, Neck, Ear, Face, Hair, Beard
- Chest, Arms, Hands, Legs, Feet
- Waist, Ring Left, Ring Right
- Weapon, Shield, Secondary Weapon
- Clothing layers and special equipment slots
#### Slot Compatibility Rules
- Armor type restrictions (light, medium, heavy)
- Race and gender compatibility checks
- Skill requirement validation
- Stat minimum requirements
- Faction and reputation restrictions
### Profile Management Features
#### Profile Creation Workflow
1. **Template Selection**: Choose from predefined templates or start from scratch
2. **Item Assignment**: Drag-and-drop items into appropriate slots
3. **Conditional Rules**: Set up automatic switching conditions
4. **Priority Settings**: Configure profile priority for conflict resolution
5. **Validation**: Comprehensive validation before saving
#### Advanced Profile Features
- **Nested Profiles**: Reference other profiles for component reuse
- **Dynamic Items**: Items that change based on current game state
- **Fallback Mechanisms**: Graceful degradation when preferred items unavailable
- **Export/Import**: Share profiles between characters or accounts
**Section sources**
- [DressManager.cs](file://ClassicAssist.Shared/Data/Dress/DressManager.cs)
- [DressAgentEntry.cs](file://ClassicAssist.Shared/Data/Dress/DressAgentEntry.cs)
- [DressAgentItem.cs](file://ClassicAssist.Shared/Data/Dress/DressAgentItem.cs)
- [DressAgentItemType.cs](file://ClassicAssist.Shared/Data/Dress/DressAgentItemType.cs)
### User Interface Implementation
The UI provides an intuitive interface for managing dress profiles:
#### Main Interface Components
- **Profile List**: Hierarchical display of all created profiles
- **Item Grid**: Visual representation of equipment slots with drag-and-drop support
- **Preview Panel**: Live preview of current and target outfits
- **Condition Editor**: Visual editor for automatic switching rules
- **Validation Status**: Real-time feedback on profile validity
#### Interactive Features
- **Drag-and-Drop**: Intuitive item assignment to equipment slots
- **Live Preview**: Immediate visual feedback when modifying profiles
- **Bulk Operations**: Copy, paste, and batch modify multiple items
- **Search and Filter**: Quick location of specific items across inventory
- **Keyboard Shortcuts**: Efficient workflow for power users
**Section sources**
- [DressTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/DressTabViewModel.cs)
- [DressTabControl.xaml.cs](file://ClassicAssist.Avalonia/Views/Agents/DressTabControl.xaml.cs)
- [DressTabControl.xaml](file://ClassicAssist.Avalonia/Views/Agents/DressTabControl.xaml)
## Dependency Analysis
The Dress Manager has well-defined dependencies on core game systems:
```mermaid
graph LR
subgraph "External Dependencies"
GE[Game Engine]
IS[Item System]
ES[Event System]
PM[Player Manager]
IM[Inventory Manager]
end
subgraph "Internal Dependencies"
DM[DressManager]
DAE[DressAgentEntry]
DAI[DressAgentItem]
DT[DressAgentItemType]
VM[DressTabViewModel]
end
DM --> GE
DM --> IS
DM --> ES
DM --> PM
DM --> IM
VM --> DM
DAE --> DAI
DAE --> DT
DAI --> DT
GE --> IS
ES --> GE
PM --> IS
IM --> IS
```
**Diagram sources**
- [DressManager.cs](file://ClassicAssist.Shared/Data/Dress/DressManager.cs)
- [DressAgentEntry.cs](file://ClassicAssist.Shared/Data/Dress/DressAgentEntry.cs)
- [DressAgentItem.cs](file://ClassicAssist.Shared/Data/Dress/DressAgentItem.cs)
- [DressAgentItemType.cs](file://ClassicAssist.Shared/Data/Dress/DressAgentItemType.cs)
- [DressTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/DressTabViewModel.cs)
### Integration Points
#### Game Event Integration
- **Combat State Changes**: Automatic outfit switching on combat entry/exit
- **Skill Activation**: Equipment adjustments for specific skills
- **Location-Based Triggers**: Outfit changes in specific areas or dungeons
- **Time-Based Conditions**: Different outfits for day/night cycles
#### Player State Monitoring
- **Stat Changes**: Dynamic equipment adjustment based on stat improvements
- **Level Progression**: Automatic updates when new equipment becomes available
- **Quest Progress**: Context-aware outfit recommendations based on active quests
**Section sources**
- [DressManager.cs](file://ClassicAssist.Shared/Data/Dress/DressManager.cs)
## Performance Considerations
The Dress Manager implements several optimizations to handle large inventories efficiently:
### Memory Management
- **Lazy Loading**: Items loaded on-demand rather than pre-loading entire inventories
- **Caching Strategy**: Frequently accessed item data cached in memory
- **Garbage Collection Optimization**: Minimize object creation during outfit switching
### Processing Optimization
- **Batch Operations**: Group multiple equipment changes into single transactions
- **Asynchronous Processing**: Non-blocking operations for time-consuming tasks
- **Progressive Enhancement**: Basic outfit applied immediately, enhancements loaded in background
### Inventory Scaling
- **Indexed Searches**: O(log n) item lookup using optimized data structures
- **Filter Pipelines**: Efficient filtering of items by category, rarity, and requirements
- **Memory Pooling**: Reuse of temporary objects during outfit validation
### Error Handling and Recovery
- **Graceful Degradation**: System continues functioning even if some items unavailable
- **Rollback Mechanisms**: Automatic revert to previous state on errors
- **Diagnostic Logging**: Comprehensive logging for troubleshooting performance issues
## Troubleshooting Guide
### Common Issues and Solutions
#### Missing Items
**Problem**: Items referenced in profiles not found in inventory
**Solution**:
- Verify item availability and ownership
- Check for account-wide vs. character-specific items
- Use fallback items in profile configuration
#### Equipment Conflicts
**Problem**: Multiple items trying to occupy same slot
**Solution**:
- Review slot assignment in profile configuration
- Ensure proper item type matching
- Use priority settings to resolve conflicts
#### Performance Issues
**Problem**: Slow outfit switching with large inventories
**Solution**:
- Enable lazy loading for infrequently used profiles
- Optimize search filters in profile configuration
- Consider splitting large profiles into smaller, focused sets
#### Automatic Switching Not Working
**Problem**: Outfits not changing automatically as expected
**Solution**:
- Verify condition rules are properly configured
- Check event subscription status
- Review priority settings between conflicting profiles
### Debug Information
The system provides comprehensive debug output including:
- Profile validation results with detailed error messages
- Item compatibility analysis and failure reasons
- Performance metrics for outfit switching operations
- Event subscription status and trigger logs
**Section sources**
- [DressAgentTests.cs](file://ClassicAssist.Tests/Agents/DressAgentTests.cs)
- [DressManager.cs](file://ClassicAssist.Shared/Data/Dress/DressManager.cs)
## Conclusion
The Dress Manager agent represents a comprehensive solution for automated equipment management in ClassicAssist. Its modular architecture, robust validation system, and intuitive user interface make it an essential tool for players seeking to optimize their gameplay experience through intelligent outfit management.
Key strengths include:
- **Flexibility**: Support for diverse equipment configurations and use cases
- **Reliability**: Comprehensive error handling and validation mechanisms
- **Performance**: Optimized for large inventories and frequent outfit changes
- **Usability**: Intuitive interface with powerful advanced features
The system's extensible design allows for future enhancements while maintaining backward compatibility, ensuring long-term value for users. Whether managing simple daily wear or complex combat loadouts, the Dress Manager provides the foundation for sophisticated character customization and automation.
@@ -0,0 +1,338 @@
# Scavenger Agent
<cite>
**Referenced Files in This Document**
- [ScavengerEntry.cs](file://ClassicAssist.Shared/Data/Scavenger/ScavengerEntry.cs)
- [ScavengerManager.cs](file://ClassicAssist.Shared/Data/Scavenger/ScavengerManager.cs)
- [ScavengerTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/ScavengerTabViewModel.cs)
- [ScavengerTabControl.xaml.cs](file://ClassicAssist.Avalonia/Views/Agents/ScavengerTabControl.axaml.cs)
- [ScavengerTabControl.xaml](file://ClassicAssist.Avalonia/Views/Agents/ScavengerTabControl.axaml)
- [ScavengerTests.cs](file://ClassicAssist.Tests/Agents/ScavengerTests.cs)
- [Item.cs](file://ClassicAssist.Shared/UO/Objects/Item.cs)
- [EntityCollection.cs](file://ClassicAssist.Shared/UO/Objects/EntityCollection.cs)
- [TargetManager.cs](file://ClassicAssist.Shared/Data/Targeting/TargetManager.cs)
- [MovementCommands.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/MovementCommands.cs)
- [ContainerContentsPacket.cs](file://ClassicAssist.Shared/UO/Network/Packets/ContainerContentsPacket.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
The Scavenger agent automates resource gathering and inventory management by continuously scanning the game world for items that match user-defined rules, moving to those items, targeting them, and collecting them into containers or the player’s backpack. It supports prioritization, conflict resolution when multiple scavengers target the same item, and integrates with movement and pathfinding systems to optimize travel. The UI allows users to create and manage scavenging profiles, configure collection priorities, and monitor activity.
## Project Structure
The Scavenger feature spans data models, managers, UI view models, and tests:
- Data layer defines entries and manager logic for scavenging rules and lifecycle.
- UI layer provides a tabbed interface for managing entries and monitoring status.
- Integration points connect to item discovery, targeting, movement, and container updates.
```mermaid
graph TB
subgraph "Shared Data"
SE["ScavengerEntry.cs"]
SM["ScavengerManager.cs"]
end
subgraph "UI (Avalonia)"
VM["ScavengerTabViewModel.cs"]
XAML["ScavengerTabControl.xaml(.cs)"]
end
subgraph "Game Objects"
ITEM["Item.cs"]
EC["EntityCollection.cs"]
end
subgraph "Integration"
TM["TargetManager.cs"]
MC["MovementCommands.cs"]
CCP["ContainerContentsPacket.cs"]
end
VM --> SM
XAML --> VM
SM --> SE
SM --> EC
SM --> ITEM
SM --> TM
SM --> MC
SM --> CCP
```
**Diagram sources**
- [ScavengerEntry.cs](file://ClassicAssist.Shared/Data/Scavenger/ScavengerEntry.cs)
- [ScavengerManager.cs](file://ClassicAssist.Shared/Data/Scavenger/ScavengerManager.cs)
- [ScavengerTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/ScavengerTabViewModel.cs)
- [ScavengerTabControl.xaml.cs](file://ClassicAssist.Avalonia/Views/Agents/ScavengerTabControl.axaml.cs)
- [ScavengerTabControl.xaml](file://ClassicAssist.Avalonia/Views/Agents/ScavengerTabControl.axaml)
- [Item.cs](file://ClassicAssist.Shared/UO/Objects/Item.cs)
- [EntityCollection.cs](file://ClassicAssist.Shared/UO/Objects/EntityCollection.cs)
- [TargetManager.cs](file://ClassicAssist.Shared/Data/Targeting/TargetManager.cs)
- [MovementCommands.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/MovementCommands.cs)
- [ContainerContentsPacket.cs](file://ClassicAssist.Shared/UO/Network/Packets/ContainerContentsPacket.cs)
**Section sources**
- [ScavengerEntry.cs](file://ClassicAssist.Shared/Data/Scavenger/ScavengerEntry.cs)
- [ScavengerManager.cs](file://ClassicAssist.Shared/Data/Scavenger/ScavengerManager.cs)
- [ScavengerTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/ScavengerTabViewModel.cs)
- [ScavengerTabControl.xaml.cs](file://ClassicAssist.Avalonia/Views/Agents/ScavengerTabControl.axaml.cs)
- [ScavengerTabControl.xaml](file://ClassicAssist.Avalonia/Views/Agents/ScavengerTabControl.axaml)
- [Item.cs](file://ClassicAssist.Shared/UO/Objects/Item.cs)
- [EntityCollection.cs](file://ClassicAssist.Shared/UO/Objects/EntityCollection.cs)
- [TargetManager.cs](file://ClassicAssist.Shared/Data/Targeting/TargetManager.cs)
- [MovementCommands.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/MovementCommands.cs)
- [ContainerContentsPacket.cs](file://ClassicAssist.Shared/UO/Network/Packets/ContainerContentsPacket.cs)
## Core Components
- ScavengerEntry: Represents a single scavenging rule including target identification criteria, priority, and behavior flags.
- ScavengerManager: Orchestrates scanning, selection, routing, targeting, and collection; manages conflicts and state across entries.
- ScavengerTabViewModel: Binds UI to manager operations, exposes collections and commands for adding/removing/editing entries and toggling activity.
- ScavengerTabControl: Avalonia UI control hosting the tab content and binding to the view model.
Key responsibilities:
- Rule evaluation against visible items.
- Priority-based selection among candidates.
- Movement and pathfinding integration to reach targets.
- Targeting and interaction to collect items.
- Inventory awareness to avoid overfilling and to route items to appropriate containers.
**Section sources**
- [ScavengerEntry.cs](file://ClassicAssist.Shared/Data/Scavenger/ScavengerEntry.cs)
- [ScavengerManager.cs](file://ClassicAssist.Shared/Data/Scavenger/ScavengerManager.cs)
- [ScavengerTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/ScavengerTabViewModel.cs)
- [ScavengerTabControl.xaml.cs](file://ClassicAssist.Avalonia/Views/Agents/ScavengerTabControl.axaml.cs)
## Architecture Overview
The Scavenger system follows a layered architecture:
- UI Layer: Tab control and view model expose configuration and monitoring.
- Manager Layer: Centralized orchestration of scanning, selection, movement, targeting, and collection.
- Game Object Layer: Item and entity collections provide real-time world state.
- Integration Layer: Targeting and movement subsystems execute actions on the client.
```mermaid
sequenceDiagram
participant UI as "ScavengerTabControl"
participant VM as "ScavengerTabViewModel"
participant Mgr as "ScavengerManager"
participant World as "EntityCollection/Item"
participant Move as "MovementCommands"
participant Tgt as "TargetManager"
participant Inv as "ContainerContentsPacket"
UI->>VM : Load profile / toggle active
VM->>Mgr : Start/Stop, Add/Remove Entry
loop Scan Cycle
Mgr->>World : Query visible items
Mgr->>Mgr : Evaluate rules and priorities
Mgr->>Move : Request move to target
Move-->>Mgr : Movement status
Mgr->>Tgt : Target item
Tgt-->>Mgr : Target result
Mgr->>Mgr : Attempt pickup/collection
Inv-->>Mgr : Container update events
Mgr->>Mgr : Update state and logs
end
```
**Diagram sources**
- [ScavengerTabControl.xaml.cs](file://ClassicAssist.Avalonia/Views/Agents/ScavengerTabControl.axaml.cs)
- [ScavengerTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/ScavengerTabViewModel.cs)
- [ScavengerManager.cs](file://ClassicAssist.Shared/Data/Scavenger/ScavengerManager.cs)
- [EntityCollection.cs](file://ClassicAssist.Shared/UO/Objects/EntityCollection.cs)
- [Item.cs](file://ClassicAssist.Shared/UO/Objects/Item.cs)
- [MovementCommands.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/MovementCommands.cs)
- [TargetManager.cs](file://ClassicAssist.Shared/Data/Targeting/TargetManager.cs)
- [ContainerContentsPacket.cs](file://ClassicAssist.Shared/UO/Network/Packets/ContainerContentsPacket.cs)
## Detailed Component Analysis
### ScavengerEntry
Purpose:
- Encapsulates a single scavenging rule with fields for target identification (e.g., item ID, properties), priority, and optional constraints (such as quantity thresholds or conditions).
- Provides helpers to evaluate whether an item matches the entry’s criteria.
Design considerations:
- Immutable or value-like semantics are preferred for rule stability during comparisons.
- Matching logic should be efficient to support large item sets.
Usage examples:
- Material gathering: Define entries for ore types with specific hues or names.
- Crafting resources: Match items by property patterns or categories.
- Valuable items: High-priority entries for rare loot.
**Section sources**
- [ScavengerEntry.cs](file://ClassicAssist.Shared/Data/Scavenger/ScavengerEntry.cs)
### ScavengerManager
Responsibilities:
- Maintains a list of ScavengerEntry instances.
- Periodically scans EntityCollection for matching items.
- Resolves conflicts when multiple entries target the same item using priority and last-seen timestamps.
- Coordinates movement via MovementCommands and targeting via TargetManager.
- Monitors inventory changes through container packet handlers to adapt collection strategies.
Algorithm highlights:
- Candidate generation: Filter visible items by each entry’s matching function.
- Conflict resolution: For overlapping candidates, select the highest priority entry; break ties with recency or distance heuristics.
- Routing: Prefer nearby targets to minimize travel time; consider obstacles implicitly via movement commands.
- Collection: After reaching proximity, target and attempt pickup; handle failures gracefully and retry if needed.
State and observability:
- Exposes current activity status, last action, and counts of matched/targeted items.
- Emits events or notifications consumed by the UI for live feedback.
**Section sources**
- [ScavengerManager.cs](file://ClassicAssist.Shared/Data/Scavenger/ScavengerManager.cs)
- [EntityCollection.cs](file://ClassicAssist.Shared/UO/Objects/EntityCollection.cs)
- [Item.cs](file://ClassicAssist.Shared/UO/Objects/Item.cs)
- [MovementCommands.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/MovementCommands.cs)
- [TargetManager.cs](file://ClassicAssist.Shared/Data/Targeting/TargetManager.cs)
- [ContainerContentsPacket.cs](file://ClassicAssist.Shared/UO/Network/Packets/ContainerContentsPacket.cs)
### ScavengerTabViewModel
Role:
- Bridges UI interactions to ScavengerManager.
- Manages observable collections of entries and exposes commands for add/remove/edit/toggle.
- Displays status indicators and recent activity logs.
User workflows:
- Create new entries by selecting item identifiers and setting priority.
- Reorder entries to adjust global precedence.
- Enable/disable individual entries or the entire scavenger session.
**Section sources**
- [ScavengerTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/ScavengerTabViewModel.cs)
### ScavengerTabControl (Avalonia)
Role:
- Hosts the Scavenger tab UI, binds to ScavengerTabViewModel, and renders lists, forms, and status panels.
- Ensures thread-safe updates from background manager operations.
**Section sources**
- [ScavengerTabControl.xaml.cs](file://ClassicAssist.Avalonia/Views/Agents/ScavengerTabControl.axaml.cs)
- [ScavengerTabControl.xaml](file://ClassicAssist.Avalonia/Views/Agents/ScavengerTabControl.axaml)
### Example Profiles
- Materials: Entries for common ores with moderate priority; lower priority for rarer variants.
- Crafting Resources: Entries for herbs, leather, and reagents with medium priority; include property filters for quality if available.
- Valuables: High-priority entries for gems or unique items; ensure they do not block essential resource collection by balancing priorities.
[No sources needed since this section provides conceptual examples]
## Dependency Analysis
High-level dependencies:
- ScavengerManager depends on:
- ScavengerEntry for rule definitions.
- EntityCollection and Item for world state.
- MovementCommands for navigation.
- TargetManager for targeting actions.
- ContainerContentsPacket for inventory updates.
- UI components depend on ScavengerTabViewModel, which delegates to ScavengerManager.
```mermaid
classDiagram
class ScavengerEntry {
+Match(item) bool
+Priority int
}
class ScavengerManager {
+Start()
+Stop()
+AddEntry(entry)
+RemoveEntry(id)
-SelectCandidate()
-ResolveConflicts(candidates)
-RouteTo(target)
-Collect(target)
}
class ScavengerTabViewModel {
+Entries ObservableCollection
+IsActive bool
+Start()
+Stop()
}
class EntityCollection
class Item
class MovementCommands
class TargetManager
class ContainerContentsPacket
ScavengerManager --> ScavengerEntry : "uses"
ScavengerManager --> EntityCollection : "queries"
ScavengerManager --> Item : "evaluates"
ScavengerManager --> MovementCommands : "moves"
ScavengerManager --> TargetManager : "targets"
ScavengerManager --> ContainerContentsPacket : "listens"
ScavengerTabViewModel --> ScavengerManager : "delegates"
```
**Diagram sources**
- [ScavengerEntry.cs](file://ClassicAssist.Shared/Data/Scavenger/ScavengerEntry.cs)
- [ScavengerManager.cs](file://ClassicAssist.Shared/Data/Scavenger/ScavengerManager.cs)
- [ScavengerTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/ScavengerTabViewModel.cs)
- [EntityCollection.cs](file://ClassicAssist.Shared/UO/Objects/EntityCollection.cs)
- [Item.cs](file://ClassicAssist.Shared/UO/Objects/Item.cs)
- [MovementCommands.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/MovementCommands.cs)
- [TargetManager.cs](file://ClassicAssist.Shared/Data/Targeting/TargetManager.cs)
- [ContainerContentsPacket.cs](file://ClassicAssist.Shared/UO/Network/Packets/ContainerContentsPacket.cs)
**Section sources**
- [ScavengerEntry.cs](file://ClassicAssist.Shared/Data/Scavenger/ScavengerEntry.cs)
- [ScavengerManager.cs](file://ClassicAssist.Shared/Data/Scavenger/ScavengerManager.cs)
- [ScavengerTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/ScavengerTabViewModel.cs)
- [EntityCollection.cs](file://ClassicAssist.Shared/UO/Objects/EntityCollection.cs)
- [Item.cs](file://ClassicAssist.Shared/UO/Objects/Item.cs)
- [MovementCommands.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/MovementCommands.cs)
- [TargetManager.cs](file://ClassicAssist.Shared/Data/Targeting/TargetManager.cs)
- [ContainerContentsPacket.cs](file://ClassicAssist.Shared/UO/Network/Packets/ContainerContentsPacket.cs)
## Performance Considerations
- Efficient filtering: Keep ScavengerEntry matching logic lightweight; precompute stable attributes where possible.
- Batched scanning: Avoid excessive polling; use event-driven updates from entity and container packets.
- Intelligent routing: Prefer nearest targets and batch pickups along a path to reduce movement overhead.
- Conflict resolution: Use priority and recency to minimize contention; avoid redundant targeting attempts.
- Memory usage: Limit retained candidate lists; clear stale entries promptly.
- Threading: Ensure UI updates are marshaled correctly; keep heavy work off the UI thread.
[No sources needed since this section provides general guidance]
## Troubleshooting Guide
Common issues and resolutions:
- Items not collected: Verify visibility range and line-of-sight; check movement success logs; confirm targeting succeeded.
- Conflicting entries: Adjust priorities so high-value items do not starve essential resources; review tie-breaking behavior.
- Inventory full: Configure fallback behaviors such as dropping low-priority items or switching containers; monitor container updates.
- Stuck movement: Inspect movement command responses; ensure pathfinding is functional and no obstacles block routes.
- UI lag: Reduce number of active entries; throttle scan frequency; ensure background tasks are not blocking UI.
Validation references:
- Unit tests cover core behaviors and edge cases for scavenger logic.
**Section sources**
- [ScavengerTests.cs](file://ClassicAssist.Tests/Agents/ScavengerTests.cs)
## Conclusion
The Scavenger agent provides a robust, configurable automation layer for resource gathering and inventory management. By combining precise rule definitions, intelligent routing, and strong integration with movement and targeting systems, it delivers reliable performance even in large areas. Properly configured profiles and priorities enable balanced collection strategies across materials, crafting resources, and valuables.
[No sources needed since this section summarizes without analyzing specific files]
## Appendices
### Creating Scavenger Profiles
- Identify target items by ID, name, hue, or properties.
- Assign priorities reflecting importance.
- Group related items into cohesive profiles for different activities (mining, herbalism, looting).
[No sources needed since this section provides conceptual guidance]
### Monitoring Activity
- Use the Scavenger tab to observe active entries, recent actions, and status indicators.
- Review logs for failed movements or targeting attempts to refine rules and priorities.
**Section sources**
- [ScavengerTabControl.xaml.cs](file://ClassicAssist.Avalonia/Views/Agents/ScavengerTabControl.axaml.cs)
- [ScavengerTabControl.xaml](file://ClassicAssist.Avalonia/Views/Agents/ScavengerTabControl.axaml)
- [ScavengerTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/ScavengerTabViewModel.cs)
@@ -0,0 +1,389 @@
# Vendor Management Agents
<cite>
**Referenced Files in This Document**
- [VendorBuyAgentEntry.cs](file://ClassicAssist.Shared/Data/Vendors/VendorBuyAgentEntry.cs)
- [VendorSellAgentEntry.cs](file://ClassicAssist.Shared/Data/Vendors/VendorSellAgentEntry.cs)
- [ShopListEntry.cs](file://ClassicAssist.Shared/Data/Vendors/ShopListEntry.cs)
- [SellListEntry.cs](file://ClassicAssist.Shared/Data/Vendors/SellListEntry.cs)
- [XYComparer.cs](file://ClassicAssist.Shared/Data/Vendors/XYComparer.cs)
- [VendorBuyTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/VendorBuyTabViewModel.cs)
- [VendorSellTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/VendorSellTabViewModel.cs)
- [VendorBuyTabControl.xaml.cs](file://ClassicAssist.Avalonia/Views/Agents/VendorBuyTabControl.xaml.cs)
- [VendorSellTabControl.xaml.cs](file://ClassicAssist.Avalonia/Views/Agents/VendorSellTabControl.xaml.cs)
- [VendorBuy.cs](file://ClassicAssist.Shared/UO/Network/Packets/VendorBuy.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)
## Introduction
This document explains the Vendor Management agents (Buy and Sell) that automate purchasing from and selling to NPC vendors. It covers how buy/sell lists are created, price tracking, stock monitoring, UI management, purchase limits, transaction history, integration with gold/inventory constraints, and error handling for common failure scenarios such as insufficient funds, inventory overflow, and vendor interaction failures.
## Project Structure
The vendor system is implemented across shared data models, UI view models, and Avalonia UI controls:
- Data models define entries for buy and sell lists and shop items.
- View models manage list state, filtering, and actions.
- Avalonia tabs host the user interfaces for configuring and operating the agents.
- Network packets provide the low-level vendor buy operation.
```mermaid
graph TB
subgraph "Shared Data"
VBA["VendorBuyAgentEntry.cs"]
VSA["VendorSellAgentEntry.cs"]
SLE["ShopListEntry.cs"]
SLSE["SellListEntry.cs"]
XYC["XYComparer.cs"]
end
subgraph "UI ViewModels"
VBVM["VendorBuyTabViewModel.cs"]
VSVM["VendorSellTabViewModel.cs"]
end
subgraph "Avalonia UI"
VBTAB["VendorBuyTabControl.xaml.cs"]
VSTAB["VendorSellTabControl.xaml.cs"]
end
subgraph "Network"
VBP["VendorBuy.cs"]
end
VBA --> VBVM
VSA --> VSVM
SLE --> VBVM
SLSE --> VSVM
XYC --> VBVM
XYC --> VSVM
VBVM --> VBTAB
VSVM --> VSTAB
VBVM --> VBP
```
**Diagram sources**
- [VendorBuyAgentEntry.cs](file://ClassicAssist.Shared/Data/Vendors/VendorBuyAgentEntry.cs)
- [VendorSellAgentEntry.cs](file://ClassicAssist.Shared/Data/Vendors/VendorSellAgentEntry.cs)
- [ShopListEntry.cs](file://ClassicAssist.Shared/Data/Vendors/ShopListEntry.cs)
- [SellListEntry.cs](file://ClassicAssist.Shared/Data/Vendors/SellListEntry.cs)
- [XYComparer.cs](file://ClassicAssist.Shared/Data/Vendors/XYComparer.cs)
- [VendorBuyTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/VendorBuyTabViewModel.cs)
- [VendorSellTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/VendorSellTabViewModel.cs)
- [VendorBuyTabControl.xaml.cs](file://ClassicAssist.Avalonia/Views/Agents/VendorBuyTabControl.xaml.cs)
- [VendorSellTabControl.xaml.cs](file://ClassicAssist.Avalonia/Views/Agents/VendorSellTabControl.xaml.cs)
- [VendorBuy.cs](file://ClassicAssist.Shared/UO/Network/Packets/VendorBuy.cs)
**Section sources**
- [VendorBuyAgentEntry.cs](file://ClassicAssist.Shared/Data/Vendors/VendorBuyAgentEntry.cs)
- [VendorSellAgentEntry.cs](file://ClassicAssist.Shared/Data/Vendors/VendorSellAgentEntry.cs)
- [ShopListEntry.cs](file://ClassicAssist.Shared/Data/Vendors/ShopListEntry.cs)
- [SellListEntry.cs](file://ClassicAssist.Shared/Data/Vendors/SellListEntry.cs)
- [XYComparer.cs](file://ClassicAssist.Shared/Data/Vendors/XYComparer.cs)
- [VendorBuyTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/VendorBuyTabViewModel.cs)
- [VendorSellTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/VendorSellTabViewModel.cs)
- [VendorBuyTabControl.xaml.cs](file://ClassicAssist.Avalonia/Views/Agents/VendorBuyTabControl.xaml.cs)
- [VendorSellTabControl.xaml.cs](file://ClassicAssist.Avalonia/Views/Agents/VendorSellTabControl.xaml.cs)
- [VendorBuy.cs](file://ClassicAssist.Shared/UO/Network/Packets/VendorBuy.cs)
## Core Components
- Buy agent entry: Represents a single item to purchase from a vendor, including quantity limits and optional price thresholds.
- Sell agent entry: Represents an item to sell to a vendor, including minimum sell price or profit conditions.
- Shop list entry: Represents an item available in a vendor’s shop, including price and stock information used for price tracking and stock monitoring.
- Sell list entry: Represents an item in your inventory eligible for selling, including current count and sell price.
- Comparer utilities: Provide sorting and comparison logic for vendor lists.
- View models: Manage collections, filtering, selection, and operations for buy/sell tabs.
- UI tabs: Host the interactive interface for managing vendor entries and running automation.
- Network packet: Encapsulates the vendor buy request at the protocol level.
Key responsibilities:
- Maintain persistent lists of items to buy/sell.
- Track vendor prices and stock levels over time.
- Enforce purchase limits and budget constraints.
- Coordinate with inventory space checks before buying.
- Present transaction history and status feedback.
**Section sources**
- [VendorBuyAgentEntry.cs](file://ClassicAssist.Shared/Data/Vendors/VendorBuyAgentEntry.cs)
- [VendorSellAgentEntry.cs](file://ClassicAssist.Shared/Data/Vendors/VendorSellAgentEntry.cs)
- [ShopListEntry.cs](file://ClassicAssist.Shared/Data/Vendors/ShopListEntry.cs)
- [SellListEntry.cs](file://ClassicAssist.Shared/Data/Vendors/SellListEntry.cs)
- [XYComparer.cs](file://ClassicAssist.Shared/Data/Vendors/XYComparer.cs)
- [VendorBuyTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/VendorBuyTabViewModel.cs)
- [VendorSellTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/VendorSellTabViewModel.cs)
- [VendorBuy.cs](file://ClassicAssist.Shared/UO/Network/Packets/VendorBuy.cs)
## Architecture Overview
The vendor agents operate through a layered architecture:
- Data layer: Entry models store configuration and observed state (prices, stock).
- ViewModel layer: Manages collections, filters, and orchestration of buy/sell workflows.
- UI layer: Avalonia tabs render lists, allow editing, and trigger actions.
- Network layer: Sends vendor buy requests via packets; other vendor interactions rely on existing network handlers.
```mermaid
sequenceDiagram
participant User as "User"
participant UIBuy as "VendorBuyTabControl"
participant VM as "VendorBuyTabViewModel"
participant Model as "VendorBuyAgentEntry"
participant Net as "VendorBuy Packet"
User->>UIBuy : Open Buy Tab
UIBuy->>VM : Initialize bindings
User->>VM : Add/Edit entries<br/>Set purchase limits
VM->>Model : Persist config
User->>VM : Start automated buying
VM->>VM : Check gold and inventory space
VM->>Net : Send vendor buy request(s)
Net-->>VM : Acknowledge result
VM-->>UIBuy : Update status/history
```
**Diagram sources**
- [VendorBuyTabControl.xaml.cs](file://ClassicAssist.Avalonia/Views/Agents/VendorBuyTabControl.xaml.cs)
- [VendorBuyTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/VendorBuyTabViewModel.cs)
- [VendorBuyAgentEntry.cs](file://ClassicAssist.Shared/Data/Vendors/VendorBuyAgentEntry.cs)
- [VendorBuy.cs](file://ClassicAssist.Shared/UO/Network/Packets/VendorBuy.cs)
## Detailed Component Analysis
### Buy Agent
The buy agent automates purchasing items from NPCs based on configured lists and constraints.
- List creation: Users add items to the buy list with desired quantities and optional maximum price thresholds.
- Price tracking: The system records vendor prices per item to compare against thresholds and detect price changes.
- Stock monitoring: The system observes vendor stock availability and avoids attempting purchases when out of stock.
- Purchase limits: Per-item limits prevent overbuying beyond configured caps.
- Gold management: Before buying, the agent verifies sufficient gold and reserves funds accordingly.
- Inventory constraints: The agent checks available backpack/container space before executing purchases.
- Transaction history: Successful and failed transactions are logged with reasons for failures.
```mermaid
flowchart TD
Start(["Start Buy Cycle"]) --> LoadEntries["Load Buy Entries"]
LoadEntries --> ForEachEntry{"For each entry"}
ForEachEntry --> |Yes| CheckPrice["Compare current price vs threshold"]
CheckPrice --> PriceOK{"Within limit?"}
PriceOK --> |No| SkipBuy["Skip due to price"]
PriceOK --> |Yes| CheckStock["Check vendor stock"]
CheckStock --> StockOK{"In stock?"}
StockOK --> |No| SkipStock["Skip due to stock"]
StockOK --> |Yes| CheckGold["Check gold balance"]
CheckGold --> GoldOK{"Sufficient funds?"}
GoldOK --> |No| FailGold["Fail: Insufficient funds"]
GoldOK --> |Yes| CheckSpace["Check inventory space"]
CheckSpace --> SpaceOK{"Space available?"}
SpaceOK --> |No| FailSpace["Fail: Inventory overflow"]
SpaceOK --> |Yes| ExecuteBuy["Send vendor buy request"]
ExecuteBuy --> Record["Record transaction history"]
Record --> NextEntry["Next entry"]
SkipBuy --> NextEntry
SkipStock --> NextEntry
FailGold --> NextEntry
FailSpace --> NextEntry
NextEntry --> ForEachEntry
ForEachEntry --> |No| End(["End Buy Cycle"])
```
**Diagram sources**
- [VendorBuyTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/VendorBuyTabViewModel.cs)
- [VendorBuyAgentEntry.cs](file://ClassicAssist.Shared/Data/Vendors/VendorBuyAgentEntry.cs)
- [ShopListEntry.cs](file://ClassicAssist.Shared/Data/Vendors/ShopListEntry.cs)
- [VendorBuy.cs](file://ClassicAssist.Shared/UO/Network/Packets/VendorBuy.cs)
**Section sources**
- [VendorBuyTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/VendorBuyTabViewModel.cs)
- [VendorBuyAgentEntry.cs](file://ClassicAssist.Shared/Data/Vendors/VendorBuyAgentEntry.cs)
- [ShopListEntry.cs](file://ClassicAssist.Shared/Data/Vendors/ShopListEntry.cs)
- [VendorBuy.cs](file://ClassicAssist.Shared/UO/Network/Packets/VendorBuy.cs)
### Sell Agent
The sell agent automates selling unwanted items to NPCs based on configured lists and conditions.
- List creation: Users add items to the sell list with minimum acceptable sell prices or profit targets.
- Price tracking: The system tracks vendor buyback prices to ensure profitability.
- Stock monitoring: Not applicable for selling; however, it ensures items exist in inventory.
- Sell limits: Per-item limits control how many units to sell.
- Gold management: Selling increases gold; the agent can optionally enforce minimum gold thresholds before selling.
- Inventory constraints: Selling frees space; the agent may prioritize high-value items first.
- Transaction history: Logs sold items, prices, and outcomes.
```mermaid
flowchart TD
StartSell(["Start Sell Cycle"]) --> LoadSellEntries["Load Sell Entries"]
LoadSellEntries --> ForEachSell{"For each sell entry"}
ForEachSell --> |Yes| HasItem{"Item in inventory?"}
HasItem --> |No| SkipNoItem["Skip: No item"]
HasItem --> |Yes| CheckMinPrice["Compare sell price vs min price"]
CheckMinPrice --> PriceOK{"Meets target?"}
PriceOK --> |No| SkipPrice["Skip: Below target"]
PriceOK --> |Yes| CheckLimit["Respect sell limit"]
CheckLimit --> ExecuteSell["Send vendor sell request"]
ExecuteSell --> RecordSell["Record transaction history"]
RecordSell --> NextSell["Next sell entry"]
SkipNoItem --> NextSell
SkipPrice --> NextSell
NextSell --> ForEachSell
ForEachSell --> |No| EndSell(["End Sell Cycle"])
```
**Diagram sources**
- [VendorSellTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/VendorSellTabViewModel.cs)
- [VendorSellAgentEntry.cs](file://ClassicAssist.Shared/Data/Vendors/VendorSellAgentEntry.cs)
- [SellListEntry.cs](file://ClassicAssist.Shared/Data/Vendors/SellListEntry.cs)
**Section sources**
- [VendorSellTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/VendorSellTabViewModel.cs)
- [VendorSellAgentEntry.cs](file://ClassicAssist.Shared/Data/Vendors/VendorSellAgentEntry.cs)
- [SellListEntry.cs](file://ClassicAssist.Shared/Data/Vendors/SellListEntry.cs)
### UI for Managing Vendor Entries
- Buy tab: Displays buy list entries, allows adding/removing/editing items, setting purchase limits, and toggling automation.
- Sell tab: Displays sell list entries, allows configuring minimum sell prices and sell limits, and starting sell automation.
- Filtering and sorting: Use comparer utilities to sort by name, price, or stock.
- History panel: Shows recent transactions with success/failure indicators and reasons.
```mermaid
classDiagram
class VendorBuyTabViewModel {
+entries
+filters
+startBuying()
+stopBuying()
+addEntry(item, qty, maxPrice)
+removeEntry(entry)
+updateHistory(reason, item, qty)
}
class VendorSellTabViewModel {
+sellEntries
+filters
+startSelling()
+stopSelling()
+addSellEntry(item, qty, minPrice)
+removeSellEntry(entry)
+updateHistory(reason, item, qty)
}
class VendorBuyAgentEntry {
+item
+quantity
+maxPrice
+enabled
}
class VendorSellAgentEntry {
+item
+quantity
+minPrice
+enabled
}
class ShopListEntry {
+item
+price
+stock
}
class SellListEntry {
+item
+count
+sellPrice
}
VendorBuyTabViewModel --> VendorBuyAgentEntry : "manages"
VendorSellTabViewModel --> VendorSellAgentEntry : "manages"
VendorBuyTabViewModel --> ShopListEntry : "reads prices/stock"
VendorSellTabViewModel --> SellListEntry : "reads inventory/prices"
```
**Diagram sources**
- [VendorBuyTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/VendorBuyTabViewModel.cs)
- [VendorSellTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/VendorSellTabViewModel.cs)
- [VendorBuyAgentEntry.cs](file://ClassicAssist.Shared/Data/Vendors/VendorBuyAgentEntry.cs)
- [VendorSellAgentEntry.cs](file://ClassicAssist.Shared/Data/Vendors/VendorSellAgentEntry.cs)
- [ShopListEntry.cs](file://ClassicAssist.Shared/Data/Vendors/ShopListEntry.cs)
- [SellListEntry.cs](file://ClassicAssist.Shared/Data/Vendors/SellListEntry.cs)
**Section sources**
- [VendorBuyTabControl.xaml.cs](file://ClassicAssist.Avalonia/Views/Agents/VendorBuyTabControl.xaml.cs)
- [VendorSellTabControl.xaml.cs](file://ClassicAssist.Avalonia/Views/Agents/VendorSellTabControl.xaml.cs)
- [VendorBuyTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/VendorBuyTabViewModel.cs)
- [VendorSellTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/VendorSellTabViewModel.cs)
- [XYComparer.cs](file://ClassicAssist.Shared/Data/Vendors/XYComparer.cs)
### Concrete Usage Examples
- Automated purchasing for crafting materials:
- Add materials to the buy list with desired quantities and maximum prices.
- Enable automation; the agent will periodically check prices and stock, then purchase within budget and space constraints.
- Selling unwanted items:
- Add items to the sell list with minimum acceptable sell prices.
- Enable automation; the agent will sell items meeting criteria and log results.
- Managing shop inventories:
- Use price tracking and stock monitoring to identify profitable restocking opportunities.
- Adjust purchase limits dynamically based on observed vendor stock levels.
[No sources needed since this section provides general guidance]
## Dependency Analysis
The vendor components depend on shared data models and UI view models, with the buy flow integrating with the network layer for sending vendor buy requests.
```mermaid
graph LR
VBA["VendorBuyAgentEntry.cs"] --> VBVM["VendorBuyTabViewModel.cs"]
VSA["VendorSellAgentEntry.cs"] --> VSVM["VendorSellTabViewModel.cs"]
SLE["ShopListEntry.cs"] --> VBVM
SLSE["SellListEntry.cs"] --> VSVM
XYC["XYComparer.cs"] --> VBVM
XYC --> VSVM
VBVM --> VBTAB["VendorBuyTabControl.xaml.cs"]
VSVM --> VSTAB["VendorSellTabControl.xaml.cs"]
VBVM --> VBP["VendorBuy.cs"]
```
**Diagram sources**
- [VendorBuyAgentEntry.cs](file://ClassicAssist.Shared/Data/Vendors/VendorBuyAgentEntry.cs)
- [VendorSellAgentEntry.cs](file://ClassicAssist.Shared/Data/Vendors/VendorSellAgentEntry.cs)
- [ShopListEntry.cs](file://ClassicAssist.Shared/Data/Vendors/ShopListEntry.cs)
- [SellListEntry.cs](file://ClassicAssist.Shared/Data/Vendors/SellListEntry.cs)
- [XYComparer.cs](file://ClassicAssist.Shared/Data/Vendors/XYComparer.cs)
- [VendorBuyTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/VendorBuyTabViewModel.cs)
- [VendorSellTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/VendorSellTabViewModel.cs)
- [VendorBuyTabControl.xaml.cs](file://ClassicAssist.Avalonia/Views/Agents/VendorBuyTabControl.xaml.cs)
- [VendorSellTabControl.xaml.cs](file://ClassicAssist.Avalonia/Views/Agents/VendorSellTabControl.xaml.cs)
- [VendorBuy.cs](file://ClassicAssist.Shared/UO/Network/Packets/VendorBuy.cs)
**Section sources**
- [VendorBuyTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/VendorBuyTabViewModel.cs)
- [VendorSellTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/VendorSellTabViewModel.cs)
- [VendorBuy.cs](file://ClassicAssist.Shared/UO/Network/Packets/VendorBuy.cs)
## Performance Considerations
- Batch operations: Group multiple buy/sell requests to reduce network overhead.
- Debouncing: Avoid excessive polling by throttling price/stock checks.
- Efficient comparisons: Use comparers for sorting large lists to minimize UI lag.
- Memory usage: Keep only necessary history entries and prune old logs.
[No sources needed since this section provides general guidance]
## Troubleshooting Guide
Common issues and resolutions:
- Insufficient funds:
- Ensure gold balance meets total purchase cost.
- Reduce purchase quantities or adjust maximum price thresholds.
- Inventory overflow:
- Verify available container space before buying.
- Prioritize essential items or free up space by selling.
- Vendor interaction failures:
- Confirm vendor is targeted and accessible.
- Retry after brief delay; check for server-side restrictions.
- Price above threshold:
- Adjust maximum price or wait for price drops.
- Out of stock:
- Monitor stock levels and schedule retries later.
**Section sources**
- [VendorBuyTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/VendorBuyTabViewModel.cs)
- [VendorSellTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/Agents/VendorSellTabViewModel.cs)
## Conclusion
The Vendor Management agents provide robust automation for buying and selling with NPCs. By leveraging configurable lists, price tracking, stock monitoring, and strict constraints around gold and inventory, users can efficiently manage crafting supplies and shop inventories while maintaining clear visibility into transaction history and errors.
[No sources needed since this section summarizes without analyzing specific files]
@@ -0,0 +1,533 @@
# Built-in Filters
<cite>
**Referenced Files in This Document**
- [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)
- [WeatherFilter.cs](file://ClassicAssist.Shared/Data/Filters/WeatherFilter.cs)
- [SeasonFilter.cs](file://ClassicAssist.Shared/Data/Filters/SeasonFilter.cs)
- [BardsMusicFilter.cs](file://ClassicAssist.Shared/Data/Filters/BardsMusicFilter.cs)
- [FilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/FilterEntry.cs)
- [DynamicFilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/DynamicFilterEntry.cs)
- [IConfigurableFilter.cs](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.cs)
- [FilterOptionsAttribute.cs](file://ClassicAssist.Shared/Data/Filters/FilterOptionsAttribute.cs)
- [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.cs)
- [ClilocFilterConfigureWindow.xaml.cs](file://ClassicAssist/UI/Views/Filters/ClilocFilterConfigureWindow.xaml.cs)
- [ClilocFilterConfigureViewModel.cs](file://ClassicAssist/UI/ViewModels/Filters/ClilocFilterConfigureViewModel.cs)
- [RepeatedMessagesFilterConfigureWindow.xaml.cs](file://ClassicAssist/UI/Views/Filters/RepeatedMessagesFilterConfigureWindow.xaml.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)
## Introduction
ClassicAssist.Avalonia provides a comprehensive filtering system that allows users to control which messages and events are processed and displayed within the application. The built-in filters offer sophisticated message processing capabilities including text localization filtering, duplicate message detection, environment-based filtering, weather condition filtering, seasonal event filtering, and bard performance monitoring. These filters work together to provide a clean, relevant user experience while maintaining high performance during gameplay.
The filtering architecture is designed to be extensible, allowing developers to create custom filters that integrate seamlessly with the existing system. Each filter type serves specific use cases and can be configured independently or combined for complex filtering scenarios.
## Project Structure
The filter system is organized within the ClassicAssist.Shared module, with each filter implementation located in the `Data/Filters` directory. The architecture follows a consistent pattern where each filter implements common interfaces and attributes for configuration and management.
```mermaid
graph TB
subgraph "Filter System Architecture"
A[FilterEntry Base Class] --> B[IConfigurableFilter Interface]
A --> C[DynamicFilterEntry]
D[Text Filters] --> E[ClilocFilter]
D --> F[RepeatedMessagesFilter]
G[Environment Filters] --> H[LightLevelFilter]
G --> I[WeatherFilter]
G --> J[SeasonFilter]
K[Specialized Filters] --> L[BardsMusicFilter]
M[Configuration Layer] --> N[FilterOptionsAttribute]
M --> O[UI Configuration Windows]
P[Filter Engine] --> Q[Filters.cs]
Q --> R[Filter Processing Pipeline]
end
E -.-> M
F -.-> M
H -.-> M
I -.-> M
J -.-> M
L -.-> M
```
**Diagram sources**
- [FilterEntry.cs:1-50](file://ClassicAssist.Shared/Data/Filters/FilterEntry.cs#L1-L50)
- [IConfigurableFilter.cs:1-30](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.cs#L1-L30)
- [Filters.cs:1-100](file://ClassicAssist.Shared/Engine/Filters.cs#L1-L100)
**Section sources**
- [FilterEntry.cs:1-100](file://ClassicAssist.Shared/Data/Filters/FilterEntry.cs#L1-L100)
- [Filters.cs:1-200](file://ClassicAssist.Shared/Engine/Filters.cs#L1-L200)
## Core Components
The filter system is built around several core components that provide the foundation for all filter implementations:
### FilterEntry Base Class
The base class that all filters inherit from, providing common functionality such as filtering logic, configuration management, and lifecycle hooks.
### IConfigurableFilter Interface
Defines the contract for configurable filters, enabling dynamic configuration through the UI and programmatic access to filter settings.
### DynamicFilterEntry
Extends the base filter functionality to support dynamic configuration changes at runtime without requiring application restart.
### FilterOptionsAttribute
Provides metadata for filter configuration options, enabling automatic UI generation and validation of filter settings.
**Section sources**
- [FilterEntry.cs:1-150](file://ClassicAssist.Shared/Data/Filters/FilterEntry.cs#L1-L150)
- [IConfigurableFilter.cs:1-50](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.cs#L1-L50)
- [DynamicFilterEntry.cs:1-100](file://ClassicAssist.Shared/Data/Filters/DynamicFilterEntry.cs#L1-L100)
- [FilterOptionsAttribute.cs:1-80](file://ClassicAssist.Shared/Data/Filters/FilterOptionsAttribute.cs#L1-L80)
## Architecture Overview
The filter system follows a pipeline architecture where messages flow through multiple filters in sequence. Each filter can examine, modify, or suppress messages based on its specific criteria.
```mermaid
sequenceDiagram
participant Game as "Game Client"
participant FilterEngine as "Filter Engine"
participant ClilocFilter as "ClilocFilter"
participant RepeatedFilter as "RepeatedMessagesFilter"
participant LightFilter as "LightLevelFilter"
participant WeatherFilter as "WeatherFilter"
participant SeasonFilter as "SeasonFilter"
participant BardFilter as "BardsMusicFilter"
participant UI as "User Interface"
Game->>FilterEngine : Incoming Message
FilterEngine->>ClilocFilter : Process Message
ClilocFilter-->>FilterEngine : Filtered Result
FilterEngine->>RepeatedFilter : Process Message
RepeatedFilter-->>FilterEngine : Filtered Result
FilterEngine->>LightFilter : Process Message
LightFilter-->>FilterEngine : Filtered Result
FilterEngine->>WeatherFilter : Process Message
WeatherFilter-->>FilterEngine : Filtered Result
FilterEngine->>SeasonFilter : Process Message
SeasonFilter-->>FilterEngine : Filtered Result
FilterEngine->>BardFilter : Process Message
BardFilter-->>FilterEngine : Filtered Result
FilterEngine->>UI : Display Message
```
**Diagram sources**
- [Filters.cs:50-150](file://ClassicAssist.Shared/Engine/Filters.cs#L50-L150)
- [ClilocFilter.cs:1-100](file://ClassicAssist.Shared/Data/Filters/ClilocFilter.cs#L1-L100)
- [RepeatedMessagesFilter.cs:1-100](file://ClassicAssist.Shared/Data/Filters/RepeatedMessagesFilter.cs#L1-L100)
## Detailed Component Analysis
### ClilocFilter - Text Localization Filtering
The ClilocFilter provides sophisticated text localization filtering with pattern matching and regular expression support. It enables users to filter messages based on localized text content, making it ideal for international gaming environments.
#### Key Features
- **Pattern Matching**: Supports wildcard patterns for flexible text matching
- **Regex Support**: Full regular expression capabilities for complex text filtering
- **Localization Aware**: Works with UO's cliloc system for proper text resolution
- **Case Sensitivity Options**: Configurable case-sensitive and case-insensitive matching
- **Performance Optimized**: Efficient pattern compilation and caching
#### Configuration Options
- **Patterns List**: Array of text patterns to match against
- **Match Mode**: Exact match, contains, starts with, ends with, or regex
- **Case Sensitivity**: Toggle between case-sensitive and case-insensitive matching
- **Action Type**: Allow, block, or modify matching messages
- **Priority Level**: Filter execution priority in the pipeline
#### Use Cases
- Filtering out unwanted chat messages in specific languages
- Blocking spam or inappropriate content using pattern recognition
- Creating language-specific filters for multilingual servers
- Implementing keyword-based moderation systems
#### Performance Impact
- Pattern compilation occurs once per filter instance
- Regex operations are optimized with compiled patterns
- Memory usage scales with number of patterns defined
- Minimal overhead for non-matching messages
```mermaid
flowchart TD
Start([Message Received]) --> ResolveCliloc["Resolve Cliloc Text"]
ResolveCliloc --> CheckPatterns{"Has Patterns?"}
CheckPatterns --> |No| PassThrough["Pass Through Unfiltered"]
CheckPatterns --> |Yes| MatchMode{"Match Mode"}
MatchMode --> |Exact| ExactMatch["Exact Pattern Match"]
MatchMode --> |Contains| ContainsMatch["Contains Pattern Match"]
MatchMode --> |Regex| RegexMatch["Regex Pattern Match"]
ExactMatch --> CaseCheck{"Case Sensitive?"}
ContainsMatch --> CaseCheck
RegexMatch --> CaseCheck
CaseCheck --> |Yes| CaseSensitive["Apply Case Sensitivity"]
CaseCheck --> |No| CaseInsensitive["Ignore Case"]
CaseSensitive --> ActionCheck{"Match Found?"}
CaseInsensitive --> ActionCheck
ActionCheck --> |Yes| ApplyAction["Apply Filter Action"]
ActionCheck --> |No| PassThrough
ApplyAction --> End([Return Filtered Result])
PassThrough --> End
```
**Diagram sources**
- [ClilocFilter.cs:20-120](file://ClassicAssist.Shared/Data/Filters/ClilocFilter.cs#L20-L120)
**Section sources**
- [ClilocFilter.cs:1-200](file://ClassicAssist.Shared/Data/Filters/ClilocFilter.cs#L1-L200)
- [ClilocFilterConfigureWindow.xaml.cs:1-150](file://ClassicAssist/UI/Views/Filters/ClilocFilterConfigureWindow.xaml.cs#L1-L150)
- [ClilocFilterConfigureViewModel.cs:1-100](file://ClassicAssist/UI/ViewModels/Filters/ClilocFilterConfigureViewModel.cs#L1-L100)
### RepeatedMessagesFilter - Duplicate Message Detection
The RepeatedMessagesFilter detects and suppresses duplicate messages based on configurable thresholds and time windows. This filter helps reduce message clutter by identifying and filtering repetitive content.
#### Key Features
- **Duplicate Detection**: Identifies identical or similar messages
- **Time Window Configuration**: Configurable time periods for duplicate detection
- **Threshold Settings**: Adjustable repetition counts before suppression
- **Similarity Matching**: Optional fuzzy matching for near-duplicate detection
- **Sliding Window Algorithm**: Efficient memory usage with bounded history
#### Configuration Options
- **Time Window**: Time period (seconds) for duplicate detection window
- **Repetition Threshold**: Number of repetitions before suppression
- **Similarity Percentage**: Threshold for fuzzy matching (0-100%)
- **Message Types**: Filter specific message types (chat, system, etc.)
- **Source Filtering**: Option to filter by message source
#### Use Cases
- Reducing spam in busy chat channels
- Suppressing automated bot messages
- Cleaning up combat log noise
- Managing guild announcement floods
#### Performance Impact
- Uses circular buffer for efficient message history
- Memory usage proportional to time window size
- String comparison operations optimized with hashing
- Minimal CPU impact with default settings
```mermaid
classDiagram
class RepeatedMessagesFilter {
+CircularBuffer~MessageHistory~ messageBuffer
+int repetitionThreshold
+double similarityThreshold
+TimeSpan timeWindow
+bool isEnabled
+ProcessMessage(message) bool
+IsDuplicate(message) bool
+CalculateSimilarity(msg1, msg2) double
+ClearExpiredMessages() void
+UpdateConfiguration(options) void
}
class MessageHistory {
+string content
+DateTime timestamp
+string messageType
+string source
}
class CircularBuffer {
+MessageHistory[] buffer
+int maxSize
+Add(item) void
+RemoveExpired(timeLimit) void
+GetRecentItems() MessageHistory[]
}
RepeatedMessagesFilter --> MessageHistory : "contains"
RepeatedMessagesFilter --> CircularBuffer : "uses"
```
**Diagram sources**
- [RepeatedMessagesFilter.cs:1-150](file://ClassicAssist.Shared/Data/Filters/RepeatedMessagesFilter.cs#L1-L150)
**Section sources**
- [RepeatedMessagesFilter.cs:1-200](file://ClassicAssist.Shared/Data/Filters/RepeatedMessagesFilter.cs#L1-L200)
- [RepeatedMessagesFilterConfigureWindow.xaml.cs:1-120](file://ClassicAssist/UI/Views/Filters/RepeatedMessagesFilterConfigureWindow.xaml.cs#L1-L120)
### LightLevelFilter - Environment-Based Filtering
The LightLevelFilter enables filtering based on in-game lighting conditions, allowing users to create context-aware message filtering that responds to environmental changes.
#### Key Features
- **Real-time Lighting Detection**: Monitors current ambient light levels
- **Threshold Configuration**: Customizable light level boundaries
- **Day/Night Cycle Awareness**: Automatic adaptation to game time cycles
- **Location-Specific Rules**: Different filtering rules for different areas
- **Event Integration**: Responds to lighting change events
#### Configuration Options
- **Minimum Light Level**: Lower threshold for filtering activation
- **Maximum Light Level**: Upper threshold for filtering activation
- **Filter Actions**: Define actions for different light conditions
- **Area Exceptions**: Override rules for specific locations
- **Transition Handling**: Configure behavior during light transitions
#### Use Cases
- Suppressing low-priority messages during nighttime activities
- Highlighting important alerts during dark exploration
- Creating day/night specific communication protocols
- Managing visibility-dependent game mechanics
#### Performance Impact
- Lightweight lighting state polling
- Event-driven updates minimize processing overhead
- Minimal memory footprint with cached light states
- Efficient area-based rule evaluation
**Section sources**
- [LightLevelFilter.cs:1-180](file://ClassicAssist.Shared/Data/Filters/LightLevelFilter.cs#L1-L180)
### WeatherFilter - Weather Condition-Based Filtering
The WeatherFilter provides message filtering based on current weather conditions in the game world, enabling weather-responsive communication strategies.
#### Key Features
- **Weather State Monitoring**: Real-time tracking of weather conditions
- **Condition Categories**: Support for rain, snow, fog, clear, storm, etc.
- **Duration Tracking**: Monitor weather persistence for sustained filtering
- **Forecast Integration**: Optional integration with weather prediction
- **Regional Variations**: Handle different weather patterns across regions
#### Configuration Options
- **Active Weather Types**: Select which weather conditions trigger filtering
- **Duration Threshold**: Minimum weather duration before activation
- **Severity Levels**: Different responses for mild vs severe weather
- **Geographic Overrides**: Location-specific weather handling
- **Notification Preferences**: Control alert levels for weather changes
#### Use Cases
- Adjusting communication protocols during storms
- Suppressing non-essential messages during adverse weather
- Creating weather-specific role-playing scenarios
- Managing outdoor activity scheduling based on conditions
#### Performance Impact
- Efficient weather state caching
- Minimal polling frequency for optimal performance
- Low memory usage with compact weather data structures
- Fast condition evaluation with precomputed lookups
**Section sources**
- [WeatherFilter.cs:1-160](file://ClassicAssist.Shared/Data/Filters/WeatherFilter.cs#L1-L160)
### SeasonFilter - Seasonal Event Filtering
The SeasonFilter manages message filtering based on seasonal events and calendar-based game mechanics, supporting holiday-themed and periodic content filtering.
#### Key Features
- **Seasonal Calendar Integration**: Tracks in-game seasons and holidays
- **Event Duration Management**: Handles both fixed and variable-length events
- **Cultural Event Support**: Accommodates different server event schedules
- **Progressive Filtering**: Gradual intensity changes during events
- **Historical Tracking**: Maintains event history for analysis
#### Configuration Options
- **Active Seasons**: Select which seasons trigger filtering
- **Event Types**: Filter by specific seasonal events
- **Intensity Levels**: Configure filtering strength during events
- **Override Rules**: Exception handling for special circumstances
- **Notification Settings**: Control event-related alerts
#### Use Cases
- Managing holiday-themed communication patterns
- Suppressing routine messages during major events
- Creating seasonal role-playing experiences
- Coordinating group activities around event schedules
#### Performance Impact
- Efficient calendar calculations with minimal overhead
- Cached event state reduces computation requirements
- Scalable design handles multiple concurrent events
- Low impact on overall system performance
**Section sources**
- [SeasonFilter.cs:1-170](file://ClassicAssist.Shared/Data/Filters/SeasonFilter.cs#L1-L170)
### BardsMusicFilter - Bard Performance Monitoring
The BardsMusicFilter specializes in monitoring bard performances and music-related game events, providing sophisticated filtering for musical content and performance metrics.
#### Key Features
- **Performance Tracking**: Monitors bard skill usage and effectiveness
- **Music Event Detection**: Identifies song starts, stops, and quality changes
- **Audience Metrics**: Tracks listener count and engagement
- **Quality Assessment**: Evaluates performance quality based on game mechanics
- **Historical Analytics**: Maintains performance statistics over time
#### Configuration Options
- **Skill Thresholds**: Minimum bard skills for performance consideration
- **Quality Metrics**: Define acceptable performance quality levels
- **Audience Requirements**: Set minimum listener counts
- **Song Type Filtering**: Filter by specific song categories
- **Reporting Preferences**: Configure performance reports and alerts
#### Use Cases
- Monitoring bard performance for entertainment purposes
- Quality assessment for professional bards
- Audience engagement analytics
- Performance optimization and training feedback
#### Performance Impact
- Optimized event processing for frequent music updates
- Efficient data aggregation for performance metrics
- Minimal overhead with selective event monitoring
- Scalable analytics with configurable reporting intervals
**Section sources**
- [BardsMusicFilter.cs:1-190](file://ClassicAssist.Shared/Data/Filters/BardsMusicFilter.cs#L1-L190)
## Dependency Analysis
The filter system exhibits careful dependency management with clear separation of concerns and minimal coupling between components.
```mermaid
graph TB
subgraph "Core Dependencies"
A[System.Core] --> B[FilterBase]
B --> C[ClilocFilter]
B --> D[RepeatedMessagesFilter]
B --> E[LightLevelFilter]
B --> F[WeatherFilter]
B --> G[SeasonFilter]
B --> H[BardsMusicFilter]
end
subgraph "External Dependencies"
I[UO.GameState] --> E
I --> F
I --> G
J[Text.RegularExpressions] --> C
K[Collections.Generic] --> D
L[IO.Streams] --> C
end
subgraph "UI Dependencies"
M[Avalonia.Controls] --> N[FilterConfigWindows]
N --> C
N --> D
end
```
**Diagram sources**
- [FilterEntry.cs:1-50](file://ClassicAssist.Shared/Data/Filters/FilterEntry.cs#L1-L50)
- [Filters.cs:1-100](file://ClassicAssist.Shared/Engine/Filters.cs#L1-L100)
**Section sources**
- [FilterEntry.cs:1-100](file://ClassicAssist.Shared/Data/Filters/FilterEntry.cs#L1-L100)
- [Filters.cs:1-200](file://ClassicAssist.Shared/Engine/Filters.cs#L1-L200)
## Performance Considerations
The filter system is designed with performance as a primary concern, implementing several optimization strategies:
### Memory Management
- **Circular Buffers**: Used in RepeatedMessagesFilter for bounded memory usage
- **Object Pooling**: Reusable objects for frequently created filter instances
- **Lazy Loading**: Filters load only when needed to minimize startup time
- **Garbage Collection Optimization**: Minimize allocations in hot paths
### Processing Efficiency
- **Early Exit Optimization**: Quick rejection of non-matching messages
- **Compiled Patterns**: Regular expressions compiled once and reused
- **Parallel Processing**: Independent filters can process concurrently
- **Batch Operations**: Group related filter operations when possible
### Scalability Features
- **Configurable Threading**: Balance between responsiveness and throughput
- **Resource Limits**: Prevent individual filters from consuming excessive resources
- **Graceful Degradation**: Maintain functionality under resource pressure
- **Monitoring Hooks**: Performance metrics collection for optimization
## Troubleshooting Guide
### Common Issues and Solutions
#### Filter Not Applying
**Symptoms**: Messages not being filtered despite correct configuration
**Causes**:
- Filter disabled in global settings
- Incorrect priority ordering
- Conflicting filter rules
**Solutions**:
- Verify filter is enabled in configuration
- Check filter priority relative to other filters
- Review conflict resolution settings
#### Performance Degradation
**Symptoms**: Increased lag or reduced frame rates
**Causes**:
- Excessive regex patterns in ClilocFilter
- Large time windows in RepeatedMessagesFilter
- Overly broad weather/lighting conditions
**Solutions**:
- Reduce number of active patterns
- Optimize regex complexity
- Adjust time windows and thresholds
- Enable performance monitoring
#### Configuration Problems
**Symptoms**: Filter settings not persisting or applying incorrectly
**Causes**:
- Invalid configuration values
- Version incompatibility
- Corrupted configuration files
**Solutions**:
- Validate configuration syntax
- Reset to default settings if corrupted
- Update to compatible version
### Debugging Techniques
#### Enable Filter Logging
```
// Enable detailed filter logging for troubleshooting
Filters.EnableLogging(true);
Filters.SetLogLevel(LogLevel.Debug);
```
#### Monitor Filter Performance
```
// Access performance metrics for individual filters
var metrics = Filters.GetPerformanceMetrics();
foreach (var filter in metrics)
{
Console.WriteLine($"{filter.Name}: {filter.ProcessingTime}ms");
}
```
#### Test Filter Logic
```
// Test specific filter with sample messages
var testResult = ClilocFilter.TestPattern("sample message", "test pattern");
Console.WriteLine($"Test result: {testResult}");
```
### Optimization Tips
1. **Pattern Optimization**: Use specific patterns rather than broad matches
2. **Threshold Tuning**: Adjust thresholds based on actual usage patterns
3. **Selective Activation**: Enable filters only when needed
4. **Resource Monitoring**: Regularly review filter performance metrics
5. **Configuration Review**: Periodically audit and optimize filter configurations
## Conclusion
The built-in filter system in ClassicAssist.Avalonia provides a robust, extensible framework for managing game messages and events. Each filter type addresses specific use cases while maintaining consistent performance characteristics and configuration interfaces. The modular architecture allows for easy extension and customization, making the system adaptable to various gaming scenarios and player preferences.
The filters work together harmoniously to provide intelligent message processing that enhances the gaming experience while maintaining system efficiency. With proper configuration and monitoring, these filters can significantly improve usability by reducing noise and highlighting relevant information.
Future enhancements may include additional filter types, improved machine learning capabilities for pattern recognition, and more sophisticated cross-filter coordination mechanisms. The current architecture provides a solid foundation for such extensions while maintaining backward compatibility and performance standards.
@@ -0,0 +1,572 @@
# Filter Architecture & Core Framework
<cite>
**Referenced Files in This Document**
- [FilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/FilterEntry.cs)
- [IConfigurableFilter.cs](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.cs)
- [DynamicFilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/DynamicFilterEntry.cs)
- [FilterOptionsAttribute.cs](file://ClassicAssist.Shared/Data/Filters/FilterOptionsAttribute.cs)
- [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)
</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
The ClassicAssist.Avalonia filter system provides a sophisticated message processing pipeline that enables dynamic filtering and manipulation of game data, chat messages, and network packets. The architecture follows a modular design pattern that allows developers to create custom filters through well-defined interfaces and base classes, supporting both compile-time and runtime configuration scenarios.
This documentation covers the complete filter framework including the core pipeline architecture, message processing flow, registration mechanisms, and best practices for developing custom filters. The system supports advanced features such as filter chaining, priority handling, error propagation, and UI binding through attributes.
## Project Structure
The filter system is organized within the `ClassicAssist.Shared` module, following a clean separation between core framework components and specific filter implementations:
```mermaid
graph TB
subgraph "Filter Framework Core"
FE["FilterEntry.cs<br/>Base Class"]
ICF["IConfigurableFilter.cs<br/>Interface"]
DFE["DynamicFilterEntry.cs<br/>Runtime Config"]
FOA["FilterOptionsAttribute.cs<br/>UI Binding"]
FCS["Filters.cs<br/>Pipeline Engine"]
end
subgraph "Built-in Filters"
CF["ClilocFilter.cs"]
RMF["RepeatedMessagesFilter.cs"]
LLF["LightLevelFilter.cs"]
SF["SeasonFilter.cs"]
WF["WeatherFilter.cs"]
BMF["BardsMusicFilter.cs"]
end
subgraph "External Dependencies"
UO["UO Network Layer"]
UI["UI Framework"]
CFG["Configuration System"]
end
FE --> ICF
DFE --> FE
FOA --> FE
FCS --> FE
FCS --> ICF
CF --> FE
RMF --> FE
LLF --> FE
SF --> FE
WF --> FE
BMF --> FE
FCS --> UO
FCS --> UI
FCS --> CFG
```
**Diagram sources**
- [FilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/FilterEntry.cs)
- [IConfigurableFilter.cs](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.cs)
- [DynamicFilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/DynamicFilterEntry.cs)
- [FilterOptionsAttribute.cs](file://ClassicAssist.Shared/Data/Filters/FilterOptionsAttribute.cs)
- [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.cs)
**Section sources**
- [FilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/FilterEntry.cs)
- [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.cs)
## Core Components
The filter system is built around several key architectural components that work together to provide a flexible and extensible filtering framework.
### FilterEntry Base Class
The `FilterEntry` class serves as the foundational base class for all filters in the system. It provides common functionality including:
- **Filter Identification**: Unique name and description properties
- **Category Management**: Organizational grouping for UI display
- **Priority Handling**: Execution order control within the filter chain
- **State Management**: Persistent configuration storage
- **Validation Support**: Built-in validation hooks for filter parameters
### IConfigurableFilter Interface
The `IConfigurableFilter` interface defines the contract for filters that require user configuration. It establishes a standardized approach to:
- **Configuration Schema Definition**: Declaring available configuration options
- **Default Value Provision**: Establishing sensible defaults for all settings
- **Validation Rules**: Specifying constraints and business logic for configuration values
- **UI Binding Metadata**: Providing hints for automatic UI generation
### DynamicFilterEntry
The `DynamicFilterEntry` class extends `FilterEntry` to support runtime configuration scenarios. Key capabilities include:
- **Dynamic Property Generation**: Creating configuration properties at runtime
- **Type Conversion**: Automatic conversion between string representations and typed properties
- **Change Notification**: Real-time updates when configuration changes occur
- **Serialization Support**: Persisting dynamic configurations to storage
### FilterOptionsAttribute
The `FilterOptionsAttribute` system enables declarative configuration through attribute-based metadata. Features include:
- **Property Decoration**: Annotating configuration properties with metadata
- **UI Hints**: Providing display names, descriptions, and validation rules
- **Binding Integration**: Seamless integration with Avalonia UI binding system
- **Localization Support**: Multi-language support for configuration labels
**Section sources**
- [FilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/FilterEntry.cs)
- [IConfigurableFilter.cs](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.cs)
- [DynamicFilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/DynamicFilterEntry.cs)
- [FilterOptionsAttribute.cs](file://ClassicAssist.Shared/Data/Filters/FilterOptionsAttribute.cs)
## Architecture Overview
The filter pipeline architecture implements a sophisticated message processing system that handles various types of game data and network traffic.
```mermaid
sequenceDiagram
participant Client as "Game Client"
participant Pipeline as "Filter Pipeline"
participant Filter1 as "Filter #1"
participant Filter2 as "Filter #2"
participant FilterN as "Filter #N"
participant Target as "Target Handler"
Client->>Pipeline : Incoming Message
Pipeline->>Filter1 : ProcessMessage(message)
Filter1->>Filter1 : Apply Logic
Filter1-->>Pipeline : Modified/Filtered Message
Pipeline->>Filter2 : ProcessMessage(message)
Filter2->>Filter2 : Apply Logic
Filter2-->>Pipeline : Modified/Filtered Message
Pipeline->>FilterN : ProcessMessage(message)
FilterN->>FilterN : Apply Logic
FilterN-->>Pipeline : Final Message
Pipeline->>Target : Deliver Processed Message
Note over Pipeline,Target : Error handling and priority management
```
**Diagram sources**
- [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.cs)
- [FilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/FilterEntry.cs)
### Message Processing Flow
The filter pipeline processes messages through a well-defined sequence:
1. **Message Reception**: Messages are captured from the game client or network layer
2. **Filter Discovery**: Active filters are identified and sorted by priority
3. **Sequential Processing**: Each filter processes the message in order
4. **Result Aggregation**: Filter results are combined and evaluated
5. **Final Delivery**: Processed messages are delivered to target handlers
### Filter Registration Mechanism
Filters are registered through a centralized registry system that supports:
- **Automatic Discovery**: Reflection-based scanning for filter implementations
- **Manual Registration**: Explicit registration for dynamically loaded filters
- **Conditional Activation**: Runtime enable/disable based on conditions
- **Dependency Resolution**: Automatic resolution of filter dependencies
**Section sources**
- [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.cs)
## Detailed Component Analysis
### FilterEntry Base Class Analysis
The `FilterEntry` class implements the core functionality shared across all filter types:
```mermaid
classDiagram
class FilterEntry {
+string Name
+string Description
+string Category
+int Priority
+bool IsEnabled
+object Configuration
+Validate() bool
+ProcessMessage(message) object
+Initialize() void
+Dispose() void
-LoadConfiguration() void
-SaveConfiguration() void
}
class IConfigurableFilter {
<<interface>>
+GetConfigurationSchema() ConfigurationSchema
+ApplyConfiguration(config) void
+ResetToDefaults() void
}
class DynamicFilterEntry {
+Dictionary~string,object~ DynamicProperties
+AddProperty(name, type, value) void
+GetProperty(name) object
+SetProperty(name, value) void
+RefreshUI() void
}
FilterEntry <|-- DynamicFilterEntry
FilterEntry ..|> IConfigurableFilter
```
**Diagram sources**
- [FilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/FilterEntry.cs)
- [IConfigurableFilter.cs](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.cs)
- [DynamicFilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/DynamicFilterEntry.cs)
#### Key Implementation Patterns
**Lifecycle Management**: The base class implements a complete lifecycle with initialization, processing, and disposal phases.
**Configuration Persistence**: Automatic serialization and deserialization of filter configurations using reflection-based property enumeration.
**Error Handling**: Comprehensive error handling with graceful degradation when individual filters fail.
**Thread Safety**: Synchronization mechanisms to ensure safe concurrent access to filter state.
**Section sources**
- [FilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/FilterEntry.cs)
### IConfigurableFilter Interface Implementation
The `IConfigurableFilter` interface provides a standardized approach to filter configuration:
#### Configuration Schema Definition
Filters implement this interface to declare their configuration requirements:
- **Property Declaration**: Define available configuration options with types and constraints
- **Default Values**: Provide sensible defaults for all configuration properties
- **Validation Rules**: Specify business logic constraints for configuration values
- **UI Metadata**: Include display names, descriptions, and formatting hints
#### Implementation Examples
Common implementation patterns include:
- **Simple Configuration**: Basic boolean and string properties
- **Complex Objects**: Nested configuration objects with multiple levels
- **Collection Properties**: Arrays and lists of configuration items
- **Enum-Based Options**: Predefined selection sets for configuration values
**Section sources**
- [IConfigurableFilter.cs](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.cs)
### DynamicFilterEntry for Runtime Configuration
The `DynamicFilterEntry` class extends the base functionality to support runtime configuration scenarios:
#### Dynamic Property System
Key features include:
- **Runtime Property Creation**: Add new configuration properties without recompilation
- **Type Safety**: Strongly-typed property access with automatic type conversion
- **Change Tracking**: Automatic detection of configuration changes
- **Event Notification**: Real-time updates to dependent UI components
#### Use Cases
Typical scenarios for dynamic filters include:
- **Plugin Systems**: Loading filters from external assemblies at runtime
- **User-Defined Filters**: Allowing users to create custom filter logic
- **Template-Based Filters**: Generating filters from configuration templates
- **Adaptive Filtering**: Modifying filter behavior based on runtime conditions
**Section sources**
- [DynamicFilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/DynamicFilterEntry.cs)
### FilterOptionsAttribute System
The `FilterOptionsAttribute` system provides declarative configuration through attribute-based metadata:
#### Attribute Types and Usage
Common attributes include:
- **DisplayName**: Human-readable property names for UI display
- **Description**: Detailed help text explaining property purpose
- **DefaultValue**: Default values for configuration properties
- **Range Validation**: Numeric range constraints for numeric properties
- **Required Fields**: Mandatory property indicators
- **UI Controls**: Hints for appropriate UI control types
#### UI Binding Integration
The attribute system integrates seamlessly with Avalonia's data binding:
- **Automatic Property Discovery**: Reflection-based scanning of decorated properties
- **Validation Integration**: Real-time validation feedback in the UI
- **Theme Support**: Consistent styling across different themes
- **Localization**: Multi-language support for property labels and descriptions
**Section sources**
- [FilterOptionsAttribute.cs](file://ClassicAssist.Shared/Data/Filters/FilterOptionsAttribute.cs)
### Built-in Filter Implementations
The system includes several example filter implementations demonstrating different use cases:
#### ClilocFilter
Handles localization string filtering based on cliloc IDs and text content matching.
#### RepeatedMessagesFilter
Detects and filters duplicate messages within configurable time windows.
#### LightLevelFilter
Filters messages based on in-game lighting conditions and visibility levels.
#### SeasonFilter
Applies seasonal logic to message filtering based on game calendar events.
#### WeatherFilter
Filters content based on current weather conditions in the game world.
#### BardsMusicFilter
Specialized filtering for bard music-related game events and messages.
**Section sources**
- [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)
## Dependency Analysis
The filter system maintains clear separation of concerns while providing necessary integration points:
```mermaid
graph TD
subgraph "Core Framework"
FE["FilterEntry"]
ICF["IConfigurableFilter"]
DFE["DynamicFilterEntry"]
FOA["FilterOptionsAttribute"]
FCS["Filters Engine"]
end
subgraph "Filter Implementations"
CF["ClilocFilter"]
RMF["RepeatedMessagesFilter"]
LLF["LightLevelFilter"]
SF["SeasonFilter"]
WF["WeatherFilter"]
BMF["BardsMusicFilter"]
end
subgraph "External Dependencies"
UO["UO Network Layer"]
UI["Avalonia UI"]
CFG["Configuration System"]
REF["Reflection API"]
end
FE --> REF
ICF --> REF
DFE --> FE
FOA --> REF
FCS --> FE
FCS --> ICF
FCS --> CFG
CF --> FE
RMF --> FE
LLF --> FE
SF --> FE
WF --> FE
BMF --> FE
FCS --> UO
FCS --> UI
```
**Diagram sources**
- [FilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/FilterEntry.cs)
- [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.cs)
### Component Coupling Analysis
The architecture demonstrates low coupling between components:
- **Interface-Based Design**: Filters depend on interfaces rather than concrete implementations
- **Attribute Decoupling**: Configuration metadata is separate from filter logic
- **Event-Driven Communication**: Loose coupling through event-based messaging
- **Dependency Injection**: Centralized dependency management through the filter engine
### External Integration Points
Key integration points include:
- **Network Layer**: Direct integration with the UO network packet system
- **UI Framework**: Avalonia-specific UI binding and rendering
- **Configuration Storage**: Persistent storage for filter settings
- **Reflection System**: Dynamic discovery and loading of filter implementations
**Section sources**
- [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.cs)
## Performance Considerations
The filter system is designed with performance optimization in mind for high-throughput scenarios:
### Pipeline Optimization Strategies
- **Lazy Evaluation**: Filters are only instantiated when needed
- **Caching Mechanisms**: Frequently accessed data is cached to reduce computation
- **Batch Processing**: Multiple messages can be processed in batches when possible
- **Early Exit Optimization**: Filters can short-circuit processing when conditions are met
### Memory Management
- **Object Pooling**: Reusable objects reduce garbage collection pressure
- **Weak References**: Prevent memory leaks in long-running applications
- **Efficient Serialization**: Optimized serialization for large configuration objects
- **Resource Disposal**: Proper cleanup of unmanaged resources
### Threading Model
- **Single-Threaded Pipeline**: Sequential processing ensures thread safety
- **Background Processing**: Heavy computations can be offloaded to background threads
- **Synchronization Primitives**: Efficient locking mechanisms for shared state
- **Async/Await Support**: Asynchronous operations for non-blocking I/O
## Troubleshooting Guide
### Common Issues and Solutions
#### Filter Not Executing
**Symptoms**: Custom filters don't appear in the UI or don't process messages.
**Diagnosis Steps**:
1. Verify filter assembly is properly referenced
2. Check filter registration in the startup code
3. Ensure filter has proper attributes and metadata
4. Validate filter constructor doesn't throw exceptions
**Resolution**:
- Confirm filter inherits from `FilterEntry` or `DynamicFilterEntry`
- Verify `IConfigurableFilter` implementation if applicable
- Check filter priority and enabled status
#### Configuration Not Persisting
**Symptoms**: Filter settings reset after application restart.
**Diagnosis Steps**:
1. Check configuration file permissions
2. Verify serialization attributes are correct
3. Ensure configuration path is accessible
**Resolution**:
- Validate `FilterOptionsAttribute` usage on configuration properties
- Check for circular references in configuration objects
- Verify configuration storage backend is functioning
#### Performance Issues
**Symptoms**: Application becomes slow when many filters are active.
**Diagnosis Steps**:
1. Profile filter execution times
2. Check for blocking operations in filter logic
3. Monitor memory usage patterns
**Resolution**:
- Optimize filter logic to minimize allocations
- Use caching for expensive computations
- Implement early exit conditions where possible
### Debugging Techniques
#### Logging Integration
The filter system provides logging hooks for debugging:
- **Filter Lifecycle Events**: Track filter initialization and disposal
- **Message Processing Logs**: Record message flow through the pipeline
- **Configuration Changes**: Monitor configuration modifications
- **Error Reporting**: Detailed exception information with context
#### Diagnostic Tools
Built-in diagnostic capabilities include:
- **Filter Registry Viewer**: Inspect all registered filters and their status
- **Performance Metrics**: Track execution times and resource usage
- **Configuration Inspector**: View current filter configurations
- **Message Trace**: Follow individual messages through the pipeline
**Section sources**
- [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.cs)
## Conclusion
The ClassicAssist.Avalonia filter system provides a robust, extensible architecture for message processing and filtering. The design emphasizes modularity, performance, and developer experience through well-defined interfaces, comprehensive base classes, and powerful attribute-based configuration.
Key strengths of the architecture include:
- **Extensibility**: Easy creation of custom filters through inheritance and interfaces
- **Flexibility**: Support for both static and dynamic configuration scenarios
- **Performance**: Optimized pipeline design suitable for high-throughput scenarios
- **Maintainability**: Clear separation of concerns and comprehensive documentation
- **Integration**: Seamless integration with Avalonia UI and existing ClassicAssist infrastructure
The system successfully balances flexibility with simplicity, providing powerful capabilities while maintaining an intuitive development experience. The comprehensive set of built-in filters serves as excellent examples for implementing custom filtering logic.
## Appendices
### Creating Custom Filters - Best Practices
#### Filter Development Guidelines
1. **Inherit Appropriately**: Choose between `FilterEntry` for simple filters or `DynamicFilterEntry` for runtime-configurable filters
2. **Implement Interfaces**: Always implement `IConfigurableFilter` when user configuration is needed
3. **Use Attributes**: Leverage `FilterOptionsAttribute` for rich UI configuration experiences
4. **Handle Errors**: Implement proper error handling and graceful degradation
5. **Consider Performance**: Optimize filter logic for minimal overhead
6. **Test Thoroughly**: Create unit tests for filter logic and configuration scenarios
#### Common Implementation Patterns
- **Stateless Filters**: Prefer immutable filters that don't maintain internal state
- **Configuration Validation**: Validate configuration inputs early and provide helpful error messages
- **Logging**: Use appropriate logging levels for debugging and monitoring
- **Documentation**: Provide clear documentation for filter purpose and configuration options
### Filter Registration Examples
Filters can be registered through multiple mechanisms:
- **Automatic Discovery**: Using reflection to find filter implementations
- **Manual Registration**: Explicit registration in application startup code
- **Plugin Loading**: Dynamic loading from external assemblies
- **Configuration-Based**: Loading filters based on configuration files
### Advanced Configuration Scenarios
For complex filtering requirements, consider:
- **Composite Filters**: Combining multiple filter conditions
- **Conditional Logic**: Branching filter behavior based on runtime conditions
- **External Data Sources**: Integrating with databases or web services
- **Custom UI Controls**: Creating specialized configuration interfaces
@@ -0,0 +1,584 @@
# Filter Configuration & Management
<cite>
**Referenced Files in This Document**
- [ClilocFilter.cs](file://ClassicAssist.Shared/Data/Filters/ClilocFilter.cs)
- [RepeatedMessagesFilter.cs](file://ClassicAssist.Shared/Data/Filters/RepeatedMessagesFilter.cs)
- [IConfigurableFilter.cs](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.cs)
- [FilterOptionsAttribute.cs](file://ClassicAssist.Shared/Data/Filters/FilterOptionsAttribute.cs)
- [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.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)
- [PacketFilterCondition.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterCondition.cs)
- [PacketFilterConditions.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterConditions.cs)
- [PacketFilterInfo.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterInfo.cs)
- [ClilocFilterConfigureViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/Filters/ClilocFilterConfigureViewModel.cs)
- [ClilocFilterConfigureWindow.axaml](file://ClassicAssist.Avalonia/Views/Filters/ClilocFilterConfigureWindow.axaml)
- [ClilocFilterConfigureWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/Filters/ClilocFilterConfigureWindow.axaml.cs)
- [RepeatedMessagesFilterConfigureWindow.axaml](file://ClassicAssist.Avalonia/Views/Filters/RepeatedMessagesFilterConfigureWindow.axaml)
- [RepeatedMessagesFilterConfigureWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/Filters/RepeatedMessagesFilterConfigureWindow.axaml.cs)
- [DialogWindow.axaml](file://ClassicAssist.Avalonia/Views/DialogWindow.axaml)
- [DialogWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/DialogWindow.axaml.cs)
- [DialogWindowViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/DialogWindowViewModel.cs)
- [BaseViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/BaseViewModel.cs)
- [MainWindowViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/MainWindowViewModel.cs)
- [OptionsTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/OptionsTabViewModel.cs)
- [GeneralControlViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/GeneralControlViewModel.cs)
- [OptionsBindingAttribute.cs](file://ClassicAssist.Shared/UI/Misc/OptionsBindingAttribute.cs)
- [Strings.resx](file://ClassicAssist.Shared/Resources/Strings.resx)
</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 how filter configuration and management work in ClassicAssist.Avalonia. It focuses on the configuration window architecture, MVVM patterns for filter settings, XAML-based configuration interfaces, persistence, validation, dynamic updates, real-time preview, export/import, migration, and backup/restore procedures. The goal is to help you create custom configuration windows for new filters using proper MVVM practices and integrate them into the application’s runtime filtering pipeline.
## Project Structure
The filter system spans shared data models, UI views (Avalonia), and view models:
- Shared filter definitions and runtime integration live under ClassicAssist.Shared.
- Avalonia-specific configuration windows and view models live under ClassicAssist.Avalonia.
- Base MVVM infrastructure and options binding utilities are also in ClassicAssist.Shared.
```mermaid
graph TB
subgraph "Shared"
IF["IConfigurableFilter.cs"]
FOA["FilterOptionsAttribute.cs"]
CF["ClilocFilter.cs"]
RMF["RepeatedMessagesFilter.cs"]
FEng["Filters.cs"]
IPF["IncomingPacketFilters.cs"]
OPF["OutgoingPacketFilters.cs"]
PF["PacketFilter.cs"]
PFC["PacketFilterCondition.cs"]
PFCs["PacketFilterConditions.cs"]
PFI["PacketFilterInfo.cs"]
BVM["BaseViewModel.cs"]
OBA["OptionsBindingAttribute.cs"]
end
subgraph "Avalonia UI"
CVM["ClilocFilterConfigureViewModel.cs"]
CWX["ClilocFilterConfigureWindow.axaml"]
CWCS["ClilocFilterConfigureWindow.axaml.cs"]
RMX["RepeatedMessagesFilterConfigureWindow.axaml"]
RMCS["RepeatedMessagesFilterConfigureWindow.axaml.cs"]
DWX["DialogWindow.axaml"]
DWC["DialogWindow.axaml.cs"]
DWMV["DialogWindowViewModel.cs"]
end
subgraph "App Shell"
MVM["MainWindowViewModel.cs"]
OTVM["OptionsTabViewModel.cs"]
GVM["GeneralControlViewModel.cs"]
end
IF --> CF
IF --> RMF
FOA --> CF
FOA --> RMF
FEng --> IPF
FEng --> OPF
IPF --> PF
OPF --> PF
PF --> PFC
PF --> PFCs
PF --> PFI
CVM --> IF
CVM --> FOA
CWX --> CVM
CWCS --> CVM
RMX --> RMF
RMCS --> RMF
DWX --> DWMV
DWC --> DWMV
MVM --> OTVM
OTVM --> GVM
OTVM --> CVM
OTVM --> DWMV
```
**Diagram sources**
- [IConfigurableFilter.cs](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.cs)
- [FilterOptionsAttribute.cs](file://ClassicAssist.Shared/Data/Filters/FilterOptionsAttribute.cs)
- [ClilocFilter.cs](file://ClassicAssist.Shared/Data/Filters/ClilocFilter.cs)
- [RepeatedMessagesFilter.cs](file://ClassicAssist.Shared/Data/Filters/RepeatedMessagesFilter.cs)
- [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.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)
- [PacketFilterCondition.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterCondition.cs)
- [PacketFilterConditions.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterConditions.cs)
- [PacketFilterInfo.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterInfo.cs)
- [ClilocFilterConfigureViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/Filters/ClilocFilterConfigureViewModel.cs)
- [ClilocFilterConfigureWindow.axaml](file://ClassicAssist.Avalonia/Views/Filters/ClilocFilterConfigureWindow.axaml)
- [ClilocFilterConfigureWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/Filters/ClilocFilterConfigureWindow.axaml.cs)
- [RepeatedMessagesFilterConfigureWindow.axaml](file://ClassicAssist.Avalonia/Views/Filters/RepeatedMessagesFilterConfigureWindow.axaml)
- [RepeatedMessagesFilterConfigureWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/Filters/RepeatedMessagesFilterConfigureWindow.axaml.cs)
- [DialogWindow.axaml](file://ClassicAssist.Avalonia/Views/DialogWindow.axaml)
- [DialogWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/DialogWindow.axaml.cs)
- [DialogWindowViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/DialogWindowViewModel.cs)
- [MainWindowViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/MainWindowViewModel.cs)
- [OptionsTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/OptionsTabViewModel.cs)
- [GeneralControlViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/GeneralControlViewModel.cs)
- [OptionsBindingAttribute.cs](file://ClassicAssist.Shared/UI/Misc/OptionsBindingAttribute.cs)
**Section sources**
- [IConfigurableFilter.cs](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.cs)
- [FilterOptionsAttribute.cs](file://ClassicAssist.Shared/Data/Filters/FilterOptionsAttribute.cs)
- [ClilocFilter.cs](file://ClassicAssist.Shared/Data/Filters/ClilocFilter.cs)
- [RepeatedMessagesFilter.cs](file://ClassicAssist.Shared/Data/Filters/RepeatedMessagesFilter.cs)
- [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.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)
- [PacketFilterCondition.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterCondition.cs)
- [PacketFilterConditions.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterConditions.cs)
- [PacketFilterInfo.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterInfo.cs)
- [ClilocFilterConfigureViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/Filters/ClilocFilterConfigureViewModel.cs)
- [ClilocFilterConfigureWindow.axaml](file://ClassicAssist.Avalonia/Views/Filters/ClilocFilterConfigureWindow.axaml)
- [ClilocFilterConfigureWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/Filters/ClilocFilterConfigureWindow.axaml.cs)
- [RepeatedMessagesFilterConfigureWindow.axaml](file://ClassicAssist.Avalonia/Views/Filters/RepeatedMessagesFilterConfigureWindow.axaml)
- [RepeatedMessagesFilterConfigureWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/Filters/RepeatedMessagesFilterConfigureWindow.axaml.cs)
- [DialogWindow.axaml](file://ClassicAssist.Avalonia/Views/DialogWindow.axaml)
- [DialogWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/DialogWindow.axaml.cs)
- [DialogWindowViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/DialogWindowViewModel.cs)
- [MainWindowViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/MainWindowViewModel.cs)
- [OptionsTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/OptionsTabViewModel.cs)
- [GeneralControlViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/GeneralControlViewModel.cs)
- [OptionsBindingAttribute.cs](file://ClassicAssist.Shared/UI/Misc/OptionsBindingAttribute.cs)
## Core Components
- IConfigurableFilter: Defines the contract for filters that expose configuration properties and behavior. Implementations provide metadata-driven configuration via attributes and runtime logic.
- FilterOptionsAttribute: Declares UI-friendly metadata for filter properties (e.g., display names, categories, validation hints).
- ClilocFilter and RepeatedMessagesFilter: Concrete filter implementations with specific matching logic and configuration surfaces.
- Filters engine and packet filter pipeline: Centralized registration and execution of filters against incoming/outgoing packets.
- Avalonia configuration windows and view models: Provide MVVM-backed UI for editing filter settings, including dialog hosting and navigation.
Key responsibilities:
- Data model and metadata: Filter classes and attributes define what can be configured.
- Runtime integration: Filters are registered and invoked by the packet filter pipeline.
- UI composition: ViewModels bind to filter instances; Views render controls based on metadata.
- Persistence and validation: Options binding and ViewModel commands handle saving and validating changes.
**Section sources**
- [IConfigurableFilter.cs](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.cs)
- [FilterOptionsAttribute.cs](file://ClassicAssist.Shared/Data/Filters/FilterOptionsAttribute.cs)
- [ClilocFilter.cs](file://ClassicAssist.Shared/Data/Filters/ClilocFilter.cs)
- [RepeatedMessagesFilter.cs](file://ClassicAssist.Shared/Data/Filters/RepeatedMessagesFilter.cs)
- [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.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)
- [PacketFilterCondition.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterCondition.cs)
- [PacketFilterConditions.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterConditions.cs)
- [PacketFilterInfo.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterInfo.cs)
- [ClilocFilterConfigureViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/Filters/ClilocFilterConfigureViewModel.cs)
- [ClilocFilterConfigureWindow.axaml](file://ClassicAssist.Avalonia/Views/Filters/ClilocFilterConfigureWindow.axaml)
- [ClilocFilterConfigureWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/Filters/ClilocFilterConfigureWindow.axaml.cs)
- [RepeatedMessagesFilterConfigureWindow.axaml](file://ClassicAssist.Avalonia/Views/Filters/RepeatedMessagesFilterConfigureWindow.axaml)
- [RepeatedMessagesFilterConfigureWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/Filters/RepeatedMessagesFilterConfigureWindow.axaml.cs)
- [DialogWindow.axaml](file://ClassicAssist.Avalonia/Views/DialogWindow.axaml)
- [DialogWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/DialogWindow.axaml.cs)
- [DialogWindowViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/DialogWindowViewModel.cs)
## Architecture Overview
The filter configuration architecture follows a clear separation of concerns:
- Model layer: Filter types and their configuration properties.
- Metadata layer: Attributes describing UI presentation and validation rules.
- Engine layer: Registration and invocation of filters during packet processing.
- UI layer: Avalonia windows and ViewModels bound to filter instances.
```mermaid
sequenceDiagram
participant User as "User"
participant Window as "Filter Configure Window"
participant VM as "Filter Configure ViewModel"
participant Filter as "IConfigurableFilter Implementation"
participant Engine as "Filters/Packet Pipeline"
participant Persist as "Options Binding"
User->>Window : Open filter config
Window->>VM : Initialize with filter instance
VM->>Filter : Read properties (metadata via attributes)
VM-->>Window : Bind controls to properties
User->>VM : Edit values
VM->>Filter : Update properties
VM->>Persist : Save changes (options binding)
VM->>Engine : Notify or reconfigure if needed
Engine-->>VM : Real-time effects (preview)
VM-->>Window : Live update bindings
```
**Diagram sources**
- [ClilocFilterConfigureViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/Filters/ClilocFilterConfigureViewModel.cs)
- [ClilocFilterConfigureWindow.axaml](file://ClassicAssist.Avalonia/Views/Filters/ClilocFilterConfigureWindow.axaml)
- [ClilocFilterConfigureWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/Filters/ClilocFilterConfigureWindow.axaml.cs)
- [IConfigurableFilter.cs](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.cs)
- [FilterOptionsAttribute.cs](file://ClassicAssist.Shared/Data/Filters/FilterOptionsAttribute.cs)
- [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.cs)
- [IncomingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketFilters.cs)
- [OutgoingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketFilters.cs)
- [OptionsBindingAttribute.cs](file://ClassicAssist.Shared/UI/Misc/OptionsBindingAttribute.cs)
## Detailed Component Analysis
### Filter Contracts and Metadata
- IConfigurableFilter defines the interface for configurable filters. Implementations expose properties that can be edited through UI.
- FilterOptionsAttribute provides declarative metadata for property display and validation hints. This enables automatic generation of UI elements and consistent user experience.
```mermaid
classDiagram
class IConfigurableFilter {
+Properties()
+Apply()
+Reset()
}
class FilterOptionsAttribute {
+DisplayName
+Category
+Description
+ValidationRules
}
class ClilocFilter
class RepeatedMessagesFilter
IConfigurableFilter <|.. ClilocFilter
IConfigurableFilter <|.. RepeatedMessagesFilter
FilterOptionsAttribute ..> IConfigurableFilter : "decorates properties"
```
**Diagram sources**
- [IConfigurableFilter.cs](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.cs)
- [FilterOptionsAttribute.cs](file://ClassicAssist.Shared/Data/Filters/FilterOptionsAttribute.cs)
- [ClilocFilter.cs](file://ClassicAssist.Shared/Data/Filters/ClilocFilter.cs)
- [RepeatedMessagesFilter.cs](file://ClassicAssist.Shared/Data/Filters/RepeatedMessagesFilter.cs)
**Section sources**
- [IConfigurableFilter.cs](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.cs)
- [FilterOptionsAttribute.cs](file://ClassicAssist.Shared/Data/Filters/FilterOptionsAttribute.cs)
- [ClilocFilter.cs](file://ClassicAssist.Shared/Data/Filters/ClilocFilter.cs)
- [RepeatedMessagesFilter.cs](file://ClassicAssist.Shared/Data/Filters/RepeatedMessagesFilter.cs)
### Packet Filtering Pipeline Integration
Filters are integrated into the packet processing pipeline. Incoming and outgoing filters register and apply conditions to match and transform packets.
```mermaid
flowchart TD
Start(["Packet Received"]) --> CheckIn["IncomingPacketFilters"]
CheckIn --> ApplyIn["Apply Registered Filters<br/>and Conditions"]
ApplyIn --> Decision{"Matched?"}
Decision --> |Yes| Transform["Transform/Block/Log"]
Decision --> |No| PassThrough["Pass Through"]
Transform --> End(["Deliver to Handler"])
PassThrough --> End
```
**Diagram sources**
- [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)
- [PacketFilterCondition.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterCondition.cs)
- [PacketFilterConditions.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterConditions.cs)
- [PacketFilterInfo.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterInfo.cs)
**Section sources**
- [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)
- [PacketFilterCondition.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterCondition.cs)
- [PacketFilterConditions.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterConditions.cs)
- [PacketFilterInfo.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterInfo.cs)
### Configuration Windows and MVVM Patterns
Avalonia configuration windows follow MVVM:
- ViewModels encapsulate state and commands for filter configuration.
- Views (AXAML) bind to ViewModel properties and commands.
- DialogWindow provides a reusable shell for modal configuration experiences.
```mermaid
sequenceDiagram
participant App as "MainWindowViewModel"
participant Options as "OptionsTabViewModel"
participant Win as "Filter Configure Window"
participant VM as "Filter Configure ViewModel"
participant Filter as "IConfigurableFilter"
participant Persist as "Options Binding"
App->>Options : Navigate to Filters tab
Options->>Win : Show configuration window
Win->>VM : Construct with filter instance
VM->>Filter : Load current settings
VM-->>Win : Bind UI to properties
User->>VM : Modify settings
VM->>Persist : Auto-save via options binding
VM->>Filter : Apply changes (live preview)
VM-->>Win : Update validation feedback
```
**Diagram sources**
- [MainWindowViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/MainWindowViewModel.cs)
- [OptionsTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/OptionsTabViewModel.cs)
- [ClilocFilterConfigureViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/Filters/ClilocFilterConfigureViewModel.cs)
- [ClilocFilterConfigureWindow.axaml](file://ClassicAssist.Avalonia/Views/Filters/ClilocFilterConfigureWindow.axaml)
- [ClilocFilterConfigureWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/Filters/ClilocFilterConfigureWindow.axaml.cs)
- [RepeatedMessagesFilterConfigureWindow.axaml](file://ClassicAssist.Avalonia/Views/Filters/RepeatedMessagesFilterConfigureWindow.axaml)
- [RepeatedMessagesFilterConfigureWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/Filters/RepeatedMessagesFilterConfigureWindow.axaml.cs)
- [DialogWindow.axaml](file://ClassicAssist.Avalonia/Views/DialogWindow.axaml)
- [DialogWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/DialogWindow.axaml.cs)
- [DialogWindowViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/DialogWindowViewModel.cs)
- [IConfigurableFilter.cs](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.cs)
- [OptionsBindingAttribute.cs](file://ClassicAssist.Shared/UI/Misc/OptionsBindingAttribute.cs)
**Section sources**
- [MainWindowViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/MainWindowViewModel.cs)
- [OptionsTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/OptionsTabViewModel.cs)
- [ClilocFilterConfigureViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/Filters/ClilocFilterConfigureViewModel.cs)
- [ClilocFilterConfigureWindow.axaml](file://ClassicAssist.Avalonia/Views/Filters/ClilocFilterConfigureWindow.axaml)
- [ClilocFilterConfigureWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/Filters/ClilocFilterConfigureWindow.axaml.cs)
- [RepeatedMessagesFilterConfigureWindow.axaml](file://ClassicAssist.Avalonia/Views/Filters/RepeatedMessagesFilterConfigureWindow.axaml)
- [RepeatedMessagesFilterConfigureWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/Filters/RepeatedMessagesFilterConfigureWindow.axaml.cs)
- [DialogWindow.axaml](file://ClassicAssist.Avalonia/Views/DialogWindow.axaml)
- [DialogWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/DialogWindow.axaml.cs)
- [DialogWindowViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/DialogWindowViewModel.cs)
- [IConfigurableFilter.cs](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.cs)
- [OptionsBindingAttribute.cs](file://ClassicAssist.Shared/UI/Misc/OptionsBindingAttribute.cs)
### Validation Rules and User Input Handling
- Use FilterOptionsAttribute to declare validation constraints and descriptions for each property.
- In ViewModels, implement validation logic and expose error messages to the UI.
- Bind UI controls to ViewModel properties with two-way binding; trigger validation on change.
- Provide immediate feedback (e.g., red borders, tooltips) using converters and behaviors.
```mermaid
flowchart TD
Entry(["User edits field"]) --> Validate["Validate input (rules from attribute/logic)"]
Validate --> Valid{"Valid?"}
Valid --> |No| ShowError["Show error message"]
Valid --> |Yes| UpdateModel["Update filter property"]
UpdateModel --> Persist["Auto-save via options binding"]
Persist --> Preview["Trigger live preview/recompute"]
ShowError --> End(["Await correction"])
Preview --> End
```
**Diagram sources**
- [FilterOptionsAttribute.cs](file://ClassicAssist.Shared/Data/Filters/FilterOptionsAttribute.cs)
- [ClilocFilterConfigureViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/Filters/ClilocFilterConfigureViewModel.cs)
- [OptionsBindingAttribute.cs](file://ClassicAssist.Shared/UI/Misc/OptionsBindingAttribute.cs)
**Section sources**
- [FilterOptionsAttribute.cs](file://ClassicAssist.Shared/Data/Filters/FilterOptionsAttribute.cs)
- [ClilocFilterConfigureViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/Filters/ClilocFilterConfigureViewModel.cs)
- [OptionsBindingAttribute.cs](file://ClassicAssist.Shared/UI/Misc/OptionsBindingAttribute.cs)
### Dynamic Configuration Updates and Real-Time Preview
- When a property changes, update the underlying filter instance immediately.
- If applicable, notify the Filters engine to re-evaluate matches without restarting.
- Use reactive bindings to reflect changes in the UI instantly.
```mermaid
sequenceDiagram
participant VM as "Filter Configure ViewModel"
participant Filter as "IConfigurableFilter"
participant Engine as "Filters/Packet Pipeline"
participant UI as "View"
VM->>Filter : Set property
VM->>Engine : Reconfigure filter (if needed)
Engine-->>VM : Match results updated
VM-->>UI : Refresh preview/bindings
```
**Diagram sources**
- [ClilocFilterConfigureViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/Filters/ClilocFilterConfigureViewModel.cs)
- [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.cs)
- [IncomingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketFilters.cs)
- [OutgoingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketFilters.cs)
**Section sources**
- [ClilocFilterConfigureViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/Filters/ClilocFilterConfigureViewModel.cs)
- [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.cs)
- [IncomingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketFilters.cs)
- [OutgoingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketFilters.cs)
### Configuration Export/Import
- Use options binding to serialize filter settings to persistent storage.
- Provide commands in ViewModels to export/import configurations (e.g., JSON files).
- Ensure schema versioning to support migration between versions.
```mermaid
flowchart TD
Start(["Export/Import Action"]) --> Serialize["Serialize filter settings"]
Serialize --> FileIO["Write to file / Read from file"]
FileIO --> ValidateSchema{"Schema valid?"}
ValidateSchema --> |No| HandleError["Show migration/import error"]
ValidateSchema --> |Yes| Apply["Apply settings to filters"]
Apply --> Persist["Save to options store"]
Persist --> Done(["Complete"])
HandleError --> Done
```
[No diagram sources since this section describes conceptual export/import flow]
**Section sources**
- [OptionsBindingAttribute.cs](file://ClassicAssist.Shared/UI/Misc/OptionsBindingAttribute.cs)
- [ClilocFilterConfigureViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/Filters/ClilocFilterConfigureViewModel.cs)
### Help Systems and Rich UI Composition
- Use resource strings for localized labels and help text.
- Bind help content to UI elements (tooltips, side panels) via ViewModels.
- Compose complex UIs with reusable controls and converters.
**Section sources**
- [Strings.resx](file://ClassicAssist.Shared/Resources/Strings.resx)
- [ClilocFilterConfigureWindow.axaml](file://ClassicAssist.Avalonia/Views/Filters/ClilocFilterConfigureWindow.axaml)
- [ClilocFilterConfigureViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/Filters/ClilocFilterConfigureViewModel.cs)
### Configuration Migration Between Versions
- Maintain a schema version in persisted options.
- On load, detect version and run migration steps to upgrade legacy settings.
- Provide rollback or backup before applying migrations.
```mermaid
flowchart TD
Load(["Load options"]) --> Detect["Detect schema version"]
Detect --> NeedsMigrate{"Needs migration?"}
NeedsMigrate --> |No| ApplyCurrent["Apply current settings"]
NeedsMigrate --> |Yes| Backup["Create backup"]
Backup --> Migrate["Run migration steps"]
Migrate --> Validate["Validate migrated settings"]
Validate --> ApplyMigrated["Apply migrated settings"]
ApplyCurrent --> Done(["Ready"])
ApplyMigrated --> Done
```
[No diagram sources since this section describes conceptual migration flow]
### Backup and Restore Procedures
- Before major operations (migration, import), create backups of current configuration.
- Provide restore functionality to revert to previous states.
- Store backups with timestamps and descriptive labels.
**Section sources**
- [ClilocFilterConfigureViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/Filters/ClilocFilterConfigureViewModel.cs)
- [OptionsBindingAttribute.cs](file://ClassicAssist.Shared/UI/Misc/OptionsBindingAttribute.cs)
## Dependency Analysis
The following diagram highlights key dependencies among filter components, UI, and engine:
```mermaid
graph LR
ICF["IConfigurableFilter.cs"] --> CF["ClilocFilter.cs"]
ICF --> RMF["RepeatedMessagesFilter.cs"]
FOA["FilterOptionsAttribute.cs"] --> CF
FOA --> RMF
FEng["Filters.cs"] --> IPF["IncomingPacketFilters.cs"]
FEng --> OPF["OutgoingPacketFilters.cs"]
IPF --> PF["PacketFilter.cs"]
OPF --> PF
PF --> PFC["PacketFilterCondition.cs"]
PF --> PFCs["PacketFilterConditions.cs"]
PF --> PFI["PacketFilterInfo.cs"]
CVM["ClilocFilterConfigureViewModel.cs"] --> ICF
CVM --> FOA
CWX["ClilocFilterConfigureWindow.axaml"] --> CVM
RMX["RepeatedMessagesFilterConfigureWindow.axaml"] --> RMF
DWX["DialogWindow.axaml"] --> DWMV["DialogWindowViewModel.cs"]
MVM["MainWindowViewModel.cs"] --> OTVM["OptionsTabViewModel.cs"]
OTVM --> CVM
OTVM --> DWMV
```
**Diagram sources**
- [IConfigurableFilter.cs](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.cs)
- [FilterOptionsAttribute.cs](file://ClassicAssist.Shared/Data/Filters/FilterOptionsAttribute.cs)
- [ClilocFilter.cs](file://ClassicAssist.Shared/Data/Filters/ClilocFilter.cs)
- [RepeatedMessagesFilter.cs](file://ClassicAssist.Shared/Data/Filters/RepeatedMessagesFilter.cs)
- [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.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)
- [PacketFilterCondition.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterCondition.cs)
- [PacketFilterConditions.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterConditions.cs)
- [PacketFilterInfo.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterInfo.cs)
- [ClilocFilterConfigureViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/Filters/ClilocFilterConfigureViewModel.cs)
- [ClilocFilterConfigureWindow.axaml](file://ClassicAssist.Avalonia/Views/Filters/ClilocFilterConfigureWindow.axaml)
- [RepeatedMessagesFilterConfigureWindow.axaml](file://ClassicAssist.Avalonia/Views/Filters/RepeatedMessagesFilterConfigureWindow.axaml)
- [DialogWindow.axaml](file://ClassicAssist.Avalonia/Views/DialogWindow.axaml)
- [DialogWindowViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/DialogWindowViewModel.cs)
- [MainWindowViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/MainWindowViewModel.cs)
- [OptionsTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/OptionsTabViewModel.cs)
**Section sources**
- [IConfigurableFilter.cs](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.cs)
- [FilterOptionsAttribute.cs](file://ClassicAssist.Shared/Data/Filters/FilterOptionsAttribute.cs)
- [ClilocFilter.cs](file://ClassicAssist.Shared/Data/Filters/ClilocFilter.cs)
- [RepeatedMessagesFilter.cs](file://ClassicAssist.Shared/Data/Filters/RepeatedMessagesFilter.cs)
- [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.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)
- [PacketFilterCondition.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterCondition.cs)
- [PacketFilterConditions.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterConditions.cs)
- [PacketFilterInfo.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilterInfo.cs)
- [ClilocFilterConfigureViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/Filters/ClilocFilterConfigureViewModel.cs)
- [ClilocFilterConfigureWindow.axaml](file://ClassicAssist.Avalonia/Views/Filters/ClilocFilterConfigureWindow.axaml)
- [RepeatedMessagesFilterConfigureWindow.axaml](file://ClassicAssist.Avalonia/Views/Filters/RepeatedMessagesFilterConfigureWindow.axaml)
- [DialogWindow.axaml](file://ClassicAssist.Avalonia/Views/DialogWindow.axaml)
- [DialogWindowViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/DialogWindowViewModel.cs)
- [MainWindowViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/MainWindowViewModel.cs)
- [OptionsTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/OptionsTabViewModel.cs)
## Performance Considerations
- Avoid heavy computations in property setters; defer expensive work to background tasks or throttled events.
- Use lazy evaluation for preview rendering; only compute when visible.
- Minimize UI thread contention by batching updates and using efficient data structures.
- Keep filter condition checks lightweight; precompute stable parts where possible.
[No sources needed since this section provides general guidance]
## Troubleshooting Guide
Common issues and resolutions:
- Property not updating in UI: Ensure two-way binding and correct property paths; verify ViewModel implements change notifications.
- Validation errors not shown: Confirm validation logic is wired to UI feedback mechanisms and error messages are exposed.
- Changes not applied at runtime: Verify that filter reconfiguration is triggered after property updates and that the engine listens for changes.
- Import/export failures: Check schema version compatibility and validate serialized data before applying.
**Section sources**
- [ClilocFilterConfigureViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/Filters/ClilocFilterConfigureViewModel.cs)
- [OptionsBindingAttribute.cs](file://ClassicAssist.Shared/UI/Misc/OptionsBindingAttribute.cs)
- [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.cs)
## Conclusion
ClassicAssist.Avalonia’s filter configuration system combines robust metadata-driven design, clean MVVM patterns, and a flexible packet filtering pipeline. By leveraging IConfigurableFilter and FilterOptionsAttribute, developers can build intuitive configuration windows with validation, live preview, and seamless persistence. Following the patterns outlined here ensures maintainable, extensible, and user-friendly filter management across versions.
[No sources needed since this section summarizes without analyzing specific files]
## Appendices
### Creating a Custom Configuration Window for a New Filter
Steps:
- Implement IConfigurableFilter for your filter type and decorate properties with FilterOptionsAttribute.
- Create a ViewModel that binds to the filter instance, handles validation, and exposes commands for save/apply.
- Build an AXAML view that binds to the ViewModel’s properties and commands.
- Integrate the window into the main UI via OptionsTabViewModel or MainWindowViewModel.
- Wire up persistence using options binding and ensure migration handling if schema evolves.
**Section sources**
- [IConfigurableFilter.cs](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.cs)
- [FilterOptionsAttribute.cs](file://ClassicAssist.Shared/Data/Filters/FilterOptionsAttribute.cs)
- [ClilocFilterConfigureViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/Filters/ClilocFilterConfigureViewModel.cs)
- [ClilocFilterConfigureWindow.axaml](file://ClassicAssist.Avalonia/Views/Filters/ClilocFilterConfigureWindow.axaml)
- [ClilocFilterConfigureWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/Filters/ClilocFilterConfigureWindow.axaml.cs)
- [DialogWindow.axaml](file://ClassicAssist.Avalonia/Views/DialogWindow.axaml)
- [DialogWindow.axaml.cs](file://ClassicAssist.Avalonia/Views/DialogWindow.axaml.cs)
- [DialogWindowViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/DialogWindowViewModel.cs)
- [OptionsTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/OptionsTabViewModel.cs)
- [MainWindowViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/MainWindowViewModel.cs)
- [OptionsBindingAttribute.cs](file://ClassicAssist.Shared/UI/Misc/OptionsBindingAttribute.cs)
@@ -0,0 +1,439 @@
# Filter System
<cite>
**Referenced Files in This Document**
- [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.cs)
- [FilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/FilterEntry.cs)
- [IConfigurableFilter.cs](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.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)
- [WeatherFilter.cs](file://ClassicAssist.Shared/Data/Filters/WeatherFilter.cs)
- [DynamicFilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/DynamicFilterEntry.cs)
- [FilterOptionsAttribute.cs](file://ClassicAssist.Shared/Data/Filters/FilterOptionsAttribute.cs)
- [ChatManager.cs](file://ClassicAssist.Shared/Data/Chat/ChatManager.cs)
- [ChatMessage.cs](file://ClassicAssist.Shared/Data/Chat/ChatMessage.cs)
- [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs)
- [IncomingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketFilters.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)
- [ClilocFilterConfigureViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/Filters/ClilocFilterConfigureViewModel.cs)
- [ClilocFilterConfigureWindow.xaml.cs](file://ClassicAssist.Avalonia/Views/Filters/ClilocFilterConfigureWindow.xaml.cs)
- [RepeatedMessagesFilterConfigureWindow.xaml.cs](file://ClassicAssist.Avalonia/Views/Filters/RepeatedMessagesFilterConfigureWindow.xaml.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)
## Introduction
This document explains the ClassicAssist.Avalonia filter system architecture and implementation with a focus on message filtering for chat and related game events. It covers the filter pipeline, message processing flow, registration mechanisms, built-in filters (ClilocFilter, RepeatedMessagesFilter, LightLevelFilter, WeatherFilter), configuration UI integration, dynamic loading, regular expression support, pattern matching, performance considerations, chaining, optimization techniques, debugging, and troubleshooting.
## Project Structure
The filter system spans shared logic and Avalonia UI:
- Shared core defines filter interfaces, base classes, built-in filters, and the engine-level filter orchestration.
- Chat and packet handling integrate with the filter pipeline to process incoming messages.
- Avalonia provides configuration UI for filters and view models that bind to filter options.
```mermaid
graph TB
subgraph "Shared Core"
FE["FilterEntry"]
ICF["IConfigurableFilter"]
FOA["FilterOptionsAttribute"]
DFE["DynamicFilterEntry"]
CF["ClilocFilter"]
RMF["RepeatedMessagesFilter"]
LLF["LightLevelFilter"]
WF["WeatherFilter"]
ENG["Filters (engine)"]
CM["ChatManager"]
MSG["ChatMessage"]
end
subgraph "UO Network"
IPH["IncomingPacketHandlers"]
IPF["IncomingPacketFilters"]
PF["PacketFilter"]
PFI["PacketFilterInfo"]
PFC["PacketFilterCondition"]
PFCs["PacketFilterConditions"]
end
subgraph "Avalonia UI"
CVM["ClilocFilterConfigureViewModel"]
CW["ClilocFilterConfigureWindow"]
RMW["RepeatedMessagesFilterConfigureWindow"]
end
CM --> ENG
ENG --> FE
FE --> ICF
FE --> FOA
FE --> DFE
CF --> FE
RMF --> FE
LLF --> FE
WF --> FE
IPH --> IPF
IPF --> PF
PF --> PFI
PFI --> PFC
PFC --> PFCs
CVM --> CF
CW --> CVM
RMW --> RMF
```
**Diagram sources**
- [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.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)
- [DynamicFilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/DynamicFilterEntry.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)
- [WeatherFilter.cs](file://ClassicAssist.Shared/Data/Filters/WeatherFilter.cs)
- [ChatManager.cs](file://ClassicAssist.Shared/Data/Chat/ChatManager.cs)
- [ChatMessage.cs](file://ClassicAssist.Shared/Data/Chat/ChatMessage.cs)
- [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs)
- [IncomingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketFilters.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)
- [ClilocFilterConfigureViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/Filters/ClilocFilterConfigureViewModel.cs)
- [ClilocFilterConfigureWindow.xaml.cs](file://ClassicAssist.Avalonia/Views/Filters/ClilocFilterConfigureWindow.xaml.cs)
- [RepeatedMessagesFilterConfigureWindow.xaml.cs](file://ClassicAssist.Avalonia/Views/Filters/RepeatedMessagesFilterConfigureWindow.xaml.cs)
**Section sources**
- [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.cs)
- [FilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/FilterEntry.cs)
- [IConfigurableFilter.cs](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.cs)
- [ChatManager.cs](file://ClassicAssist.Shared/Data/Chat/ChatManager.cs)
- [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs)
- [IncomingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketFilters.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)
- [ClilocFilterConfigureViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/Filters/ClilocFilterConfigureViewModel.cs)
- [ClilocFilterConfigureWindow.xaml.cs](file://ClassicAssist.Avalonia/Views/Filters/ClilocFilterConfigureWindow.xaml.cs)
- [RepeatedMessagesFilterConfigureWindow.xaml.cs](file://ClassicAssist.Avalonia/Views/Filters/RepeatedMessagesFilterConfigureWindow.xaml.cs)
## Core Components
- FilterEntry: Base class for all filters; encapsulates metadata, enable/disable state, priority, and common evaluation hooks.
- IConfigurableFilter: Interface for filters that expose user-configurable options via attributes and UI.
- FilterOptionsAttribute: Attribute-driven configuration discovery used by UI to render options for configurable filters.
- DynamicFilterEntry: Helper to wrap or dynamically create filter entries at runtime.
- Engine Filters: Central registry and pipeline orchestrator that loads, orders, and executes filters against messages.
Key responsibilities:
- Registration: Filters are discovered and registered into the central registry.
- Ordering: Priority determines execution order.
- Evaluation: Each filter receives a message context and returns a decision (e.g., allow/deny).
- Configuration: Configurable filters expose properties bound to UI controls.
**Section sources**
- [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)
- [DynamicFilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/DynamicFilterEntry.cs)
- [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.cs)
## Architecture Overview
The filter pipeline integrates with both high-level chat processing and low-level packet handling.
```mermaid
sequenceDiagram
participant Net as "IncomingPacketHandlers"
participant PFilt as "IncomingPacketFilters"
participant Pkt as "PacketFilter"
participant Eng as "Filters (engine)"
participant F as "FilterEntry"
participant Cfg as "IConfigurableFilter"
participant UI as "Avalonia Configure Window"
Net->>PFilt : "Dispatch incoming packet"
PFilt->>Pkt : "Apply PacketFilter rules"
Pkt-->>Net : "Filtered packet stream"
Net->>Eng : "Route relevant events/messages"
Eng->>F : "Evaluate(filter, message)"
alt "Filter is configurable"
F->>Cfg : "Expose options via attributes"
UI-->>Cfg : "User updates options"
end
F-->>Eng : "Decision (allow/deny/modify)"
Eng-->>Net : "Aggregated result"
```
**Diagram sources**
- [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs)
- [IncomingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketFilters.cs)
- [PacketFilter.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilter.cs)
- [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.cs)
- [FilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/FilterEntry.cs)
- [IConfigurableFilter.cs](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.cs)
- [ClilocFilterConfigureWindow.xaml.cs](file://ClassicAssist.Avalonia/Views/Filters/ClilocFilterConfigureWindow.xaml.cs)
## Detailed Component Analysis
### Filter Pipeline and Message Processing Flow
- Entry points: Incoming packets are handled by network handlers and may be pre-filtered by packet-level filters before reaching higher-level systems.
- Chat messages: ChatManager routes messages through the filter engine.
- Filter engine: Iterates registered filters in priority order, invoking each filter’s evaluation method with a message context.
- Decision semantics: A filter can allow, deny, or transform a message. Short-circuiting behavior depends on policy (e.g., first-deny wins).
```mermaid
flowchart TD
Start(["Message Received"]) --> Pre["Pre-process (packet filters if applicable)"]
Pre --> Route["Route to appropriate subsystem (e.g., Chat)"]
Route --> EngEval["Engine iterates registered filters"]
EngEval --> NextF{"More filters?"}
NextF --> |Yes| Eval["Evaluate next filter"]
Eval --> Decision{"Filter decision"}
Decision --> |Allow| NextF
Decision --> |Deny| Stop(["Stop propagation"])
Decision --> |Modify| Update["Update message/context"]
Update --> NextF
NextF --> |No| End(["Deliver to consumer"])
```
[No sources needed since this diagram shows conceptual workflow, not actual code structure]
**Section sources**
- [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs)
- [IncomingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketFilters.cs)
- [PacketFilter.cs](file://ClassicAssist.Shared/UO/Network/PacketFilter/PacketFilter.cs)
- [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.cs)
- [ChatManager.cs](file://ClassicAssist.Shared/Data/Chat/ChatManager.cs)
### Filter Registration Mechanisms
- Static registration: Built-in filters are typically registered during application startup.
- Dynamic registration: DynamicFilterEntry enables runtime creation and registration of filters based on configuration or external inputs.
- Discovery: The engine scans known types implementing the filter contracts and constructs entries accordingly.
```mermaid
classDiagram
class FilterEntry {
+bool Enabled
+int Priority
+string Name
+Evaluate(message) Result
}
class IConfigurableFilter {
<<interface>>
+object Options
}
class ClilocFilter
class RepeatedMessagesFilter
class LightLevelFilter
class WeatherFilter
class DynamicFilterEntry
FilterEntry <|-- ClilocFilter
FilterEntry <|-- RepeatedMessagesFilter
FilterEntry <|-- LightLevelFilter
FilterEntry <|-- WeatherFilter
FilterEntry ..> IConfigurableFilter : "optional"
DynamicFilterEntry --> FilterEntry : "wraps/creates"
```
**Diagram sources**
- [FilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/FilterEntry.cs)
- [IConfigurableFilter.cs](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.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)
- [WeatherFilter.cs](file://ClassicAssist.Shared/Data/Filters/WeatherFilter.cs)
- [DynamicFilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/DynamicFilterEntry.cs)
**Section sources**
- [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.cs)
- [DynamicFilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/DynamicFilterEntry.cs)
### Creating Custom Filters
To implement a custom filter:
- Implement IConfigurableFilter if you need user-configurable options.
- Extend FilterEntry to inherit common behavior (state, priority, name).
- Use FilterOptionsAttribute on public properties to expose options to the UI automatically.
- Register your filter via the engine’s registration mechanism (statically or dynamically using DynamicFilterEntry).
Best practices:
- Keep Evaluate fast and avoid heavy allocations.
- Prefer compiled regex patterns when using regular expressions.
- Cache expensive lookups and reuse objects where safe.
**Section sources**
- [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)
- [DynamicFilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/DynamicFilterEntry.cs)
- [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.cs)
### Built-in Filters
#### ClilocFilter
Purpose:
- Match chat or system messages against cliloc-based text patterns.
Use cases:
- Hide or route specific localized messages.
Configuration:
- Pattern list and matching mode exposed via options.
Regex support:
- Supports regular expressions for flexible matching.
**Section sources**
- [ClilocFilter.cs](file://ClassicAssist.Shared/Data/Filters/ClilocFilter.cs)
- [ClilocFilterConfigureViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/Filters/ClilocFilterConfigureViewModel.cs)
- [ClilocFilterConfigureWindow.xaml.cs](file://ClassicAssist.Avalonia/Views/Filters/ClilocFilterConfigureWindow.xaml.cs)
#### RepeatedMessagesFilter
Purpose:
- Suppress duplicate or near-duplicate messages within a time window.
Use cases:
- Reduce noise from spammy or repeated system messages.
Configuration:
- Time window and threshold settings.
Regex support:
- Optional normalization via regex before comparison.
**Section sources**
- [RepeatedMessagesFilter.cs](file://ClassicAssist.Shared/Data/Filters/RepeatedMessagesFilter.cs)
- [RepeatedMessagesFilterConfigureWindow.xaml.cs](file://ClassicAssist.Avalonia/Views/Filters/RepeatedMessagesFilterConfigureWindow.xaml.cs)
#### LightLevelFilter
Purpose:
- Filter messages or events based on current light level conditions.
Use cases:
- Adjust UI or notifications depending on ambient lighting.
Configuration:
- Thresholds and ranges for light levels.
**Section sources**
- [LightLevelFilter.cs](file://ClassicAssist.Shared/Data/Filters/LightLevelFilter.cs)
#### WeatherFilter
Purpose:
- Filter messages or events based on weather conditions.
Use cases:
- Context-aware filtering for weather-dependent gameplay.
Configuration:
- Weather states and transitions to match.
**Section sources**
- [WeatherFilter.cs](file://ClassicAssist.Shared/Data/Filters/WeatherFilter.cs)
### Regular Expression Support and Pattern Matching
- Many filters accept regex patterns for advanced matching.
- Recommendations:
- Compile patterns once and reuse them.
- Avoid catastrophic backtracking; keep patterns efficient.
- Normalize input (trim, case folding) before matching when appropriate.
**Section sources**
- [ClilocFilter.cs](file://ClassicAssist.Shared/Data/Filters/ClilocFilter.cs)
- [RepeatedMessagesFilter.cs](file://ClassicAssist.Shared/Data/Filters/RepeatedMessagesFilter.cs)
### Advanced Filtering Logic
- Chaining: Multiple filters run in sequence; decisions can short-circuit or pass along.
- Contextual data: Filters can inspect message metadata (sender, type, timestamp) to make nuanced decisions.
- Transformations: Some filters may modify message content before downstream consumers.
**Section sources**
- [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.cs)
- [ChatMessage.cs](file://ClassicAssist.Shared/Data/Chat/ChatMessage.cs)
## Dependency Analysis
The following diagram highlights key dependencies between filter components, engine, and UI.
```mermaid
graph LR
FE["FilterEntry"] --> ICF["IConfigurableFilter"]
FE --> FOA["FilterOptionsAttribute"]
CF["ClilocFilter"] --> FE
RMF["RepeatedMessagesFilter"] --> FE
LLF["LightLevelFilter"] --> FE
WF["WeatherFilter"] --> FE
DFE["DynamicFilterEntry"] --> FE
ENG["Filters (engine)"] --> FE
CM["ChatManager"] --> ENG
IPH["IncomingPacketHandlers"] --> IPF["IncomingPacketFilters"]
IPF --> PF["PacketFilter"]
PF --> PFI["PacketFilterInfo"]
PFI --> PFC["PacketFilterCondition"]
PFC --> PFCs["PacketFilterConditions"]
CVM["ClilocFilterConfigureViewModel"] --> CF
CW["ClilocFilterConfigureWindow"] --> CVM
RMW["RepeatedMessagesFilterConfigureWindow"] --> RMF
```
**Diagram sources**
- [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)
- [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)
- [WeatherFilter.cs](file://ClassicAssist.Shared/Data/Filters/WeatherFilter.cs)
- [DynamicFilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/DynamicFilterEntry.cs)
- [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.cs)
- [ChatManager.cs](file://ClassicAssist.Shared/Data/Chat/ChatManager.cs)
- [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs)
- [IncomingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketFilters.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)
- [ClilocFilterConfigureViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/Filters/ClilocFilterConfigureViewModel.cs)
- [ClilocFilterConfigureWindow.xaml.cs](file://ClassicAssist.Avalonia/Views/Filters/ClilocFilterConfigureWindow.xaml.cs)
- [RepeatedMessagesFilterConfigureWindow.xaml.cs](file://ClassicAssist.Avalonia/Views/Filters/RepeatedMessagesFilterConfigureWindow.xaml.cs)
**Section sources**
- [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.cs)
- [IncomingPacketHandlers.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketHandlers.cs)
- [IncomingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketFilters.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)
## Performance Considerations
- Minimize allocations inside hot paths (message evaluation).
- Cache compiled regex patterns and lookup tables.
- Prefer early exits and simple checks before complex operations.
- Use priority ordering to place cheap, high-impact filters earlier.
- Avoid blocking operations in Evaluate; offload to background tasks if necessary.
- For repeated message suppression, use sliding windows with bounded memory.
[No sources needed since this section provides general guidance]
## Troubleshooting Guide
Common issues and resolutions:
- Filter not applied:
- Verify registration and enabled state.
- Check priority ordering relative to other filters.
- Regex errors:
- Validate patterns; avoid catastrophic backtracking.
- Ensure consistent input normalization.
- UI options not updating:
- Confirm FilterOptionsAttribute usage and property setters raise change notifications.
- Ensure configure window binds to the correct ViewModel.
- Performance regressions:
- Profile Evaluate methods; reduce allocations and heavy computations.
- Review filter chain length and consider short-circuiting logic.
**Section sources**
- [FilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/FilterEntry.cs)
- [FilterOptionsAttribute.cs](file://ClassicAssist.Shared/Data/Filters/FilterOptionsAttribute.cs)
- [ClilocFilterConfigureViewModel.cs](file://ClassicAssist.Avalonia/ViewModels/Filters/ClilocFilterConfigureViewModel.cs)
- [ClilocFilterConfigureWindow.xaml.cs](file://ClassicAssist.Avalonia/Views/Filters/ClilocFilterConfigureWindow.xaml.cs)
- [RepeatedMessagesFilterConfigureWindow.xaml.cs](file://ClassicAssist.Avalonia/Views/Filters/RepeatedMessagesFilterConfigureWindow.xaml.cs)
## Conclusion
The ClassicAssist.Avalonia filter system provides a flexible, extensible pipeline for processing chat and related messages. With a clear separation between core logic and UI, attribute-driven configuration, and strong integration with packet and chat layers, it supports both simple and advanced filtering scenarios. By following best practices for performance and leveraging built-in filters and tools, developers can build robust, maintainable filtering solutions tailored to their needs.
@@ -0,0 +1,626 @@
# Plugin Architecture
<cite>
**Referenced Files in This Document**
- [HotkeyCommandAttribute.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommandAttribute.cs)
- [HotkeyCommand.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommand.cs)
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
- [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs)
- [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.cs)
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
- [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs)
- [Program.cs](file://ClassicAssist.Avalonia/Program.cs)
- [PluginEntry.cs](file://ClassicAssist.Launcher/PluginEntry.cs)
- [ManifestEntry.cs](file://ClassicAssist.Launcher/ManifestEntry.cs)
- [ShardManager.cs](file://ClassicAssist.Launcher/ShardManager.cs)
- [Browser.Models.Manifest.cs](file://ClassicAssist/Browser/Models/Manifest.cs)
- [Browser.Models.Metadata.cs](file://ClassicAssist/Browser/Models/Metadata.cs)
- [Browser.Data.Database.cs](file://ClassicAssist/Browser/Data/Database.cs)
- [Browser.Data.Filter.cs](file://ClassicAssist/Browser/Data/Filter.cs)
- [Browser.Data.FilterType.cs](file://ClassicAssist/Browser/Data/FilterType.cs)
- [Browser.MacroBrowserControl.xaml.cs](file://ClassicAssist/Browser/MacroBrowserControl.xaml.cs)
- [Browser.MacroBrowserViewModel.cs](file://ClassicAssist/Browser/MacroBrowserViewModel.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 plugin architecture and extension points for ClassicAssist.Avalonia, focusing on:
- Reflection-based command discovery
- Dynamic assembly loading and plugin lifecycle management
- Creating custom commands via HotkeyCommandAttribute
- Extending the macro system
- Plugin loading mechanism, dependency resolution, and version compatibility
- Security considerations, sandboxing, and isolation
- Distribution format, installation process, and updates
- Debugging, error handling, and performance monitoring for plugins
The goal is to provide both a high-level overview and detailed technical guidance for building robust plugins that integrate with hotkeys, macros, and UI components.
## Project Structure
At a high level, the repository contains:
- Shared core types and managers (hotkeys, macros, reflection helpers)
- Avalonia application entry points and engine initialization
- Launcher utilities for plugin entries and manifests
- Browser features for browsing and managing macros and metadata
```mermaid
graph TB
subgraph "Shared Core"
HKAttr["HotkeyCommandAttribute"]
HKCmd["HotkeyCommand base"]
HKMgr["HotkeyManager"]
MacroInv["MacroInvoker"]
MacroMgr["MacroManager"]
Refl["Reflection Helpers"]
end
subgraph "Avalonia App"
Prog["Program"]
AppXaml["App.axaml.cs"]
EngineAva["Engine.cs (Avalonia)"]
end
subgraph "Launcher"
PluginEntry["PluginEntry"]
ManifestEntry["ManifestEntry"]
ShardMgr["ShardManager"]
end
subgraph "Browser"
DB["Database"]
Filter["Filter / FilterType"]
Meta["Metadata"]
Manifest["Manifest"]
MBVM["MacroBrowserViewModel"]
MBCtrl["MacroBrowserControl"]
end
Prog --> AppXaml --> EngineAva
EngineAva --> HKMgr
EngineAva --> MacroMgr
HKMgr --> HKAttr
HKMgr --> HKCmd
MacroMgr --> MacroInv
MacroInv --> Refl
ShardMgr --> PluginEntry
ShardMgr --> ManifestEntry
MBVM --> DB
MBVM --> Filter
MBVM --> Meta
MBVM --> Manifest
MBCtrl --> MBVM
```
**Diagram sources**
- [Program.cs](file://ClassicAssist.Avalonia/Program.cs)
- [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs)
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
- [HotkeyCommandAttribute.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommandAttribute.cs)
- [HotkeyCommand.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommand.cs)
- [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs)
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
- [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.cs)
- [PluginEntry.cs](file://ClassicAssist.Launcher/PluginEntry.cs)
- [ManifestEntry.cs](file://ClassicAssist.Launcher/ManifestEntry.cs)
- [ShardManager.cs](file://ClassicAssist.Launcher/ShardManager.cs)
- [Browser.Data.Database.cs](file://ClassicAssist/Browser/Data/Database.cs)
- [Browser.Data.Filter.cs](file://ClassicAssist/Browser/Data/Filter.cs)
- [Browser.Data.FilterType.cs](file://ClassicAssist/Browser/Data/FilterType.cs)
- [Browser.Models.Metadata.cs](file://ClassicAssist/Browser/Models/Metadata.cs)
- [Browser.Models.Manifest.cs](file://ClassicAssist/Browser/Models/Manifest.cs)
- [Browser.MacroBrowserViewModel.cs](file://ClassicAssist/Browser/MacroBrowserViewModel.cs)
- [Browser.MacroBrowserControl.xaml.cs](file://ClassicAssist/Browser/MacroBrowserControl.xaml.cs)
**Section sources**
- [Program.cs](file://ClassicAssist.Avalonia/Program.cs)
- [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs)
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
- [HotkeyCommandAttribute.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommandAttribute.cs)
- [HotkeyCommand.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommand.cs)
- [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs)
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
- [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.cs)
- [PluginEntry.cs](file://ClassicAssist.Launcher/PluginEntry.cs)
- [ManifestEntry.cs](file://ClassicAssist.Launcher/ManifestEntry.cs)
- [ShardManager.cs](file://ClassicAssist.Launcher/ShardManager.cs)
- [Browser.Data.Database.cs](file://ClassicAssist/Browser/Data/Database.cs)
- [Browser.Data.Filter.cs](file://ClassicAssist/Browser/Data/Filter.cs)
- [Browser.Data.FilterType.cs](file://ClassicAssist/Browser/Data/FilterType.cs)
- [Browser.Models.Metadata.cs](file://ClassicAssist/Browser/Models/Metadata.cs)
- [Browser.Models.Manifest.cs](file://ClassicAssist/Browser/Models/Manifest.cs)
- [Browser.MacroBrowserViewModel.cs](file://ClassicAssist/Browser/MacroBrowserViewModel.cs)
- [Browser.MacroBrowserControl.xaml.cs](file://ClassicAssist/Browser/MacroBrowserControl.xaml.cs)
## Core Components
- Hotkey command discovery and registration
- Commands are discovered by scanning assemblies for classes implementing a specific base type and decorated with an attribute. The manager registers them into a central registry and binds them to configured shortcuts.
- Macro execution and extensibility
- Macros are parsed and executed through an invoker that resolves commands at runtime using reflection. A manager maintains macro definitions and provides APIs for invocation and control.
- Reflection helpers
- Utility methods for enumerating types, reading attributes, and constructing instances without hard-coded dependencies.
- Application engine and bootstrap
- The Avalonia app initializes subsystems including hotkey and macro managers, ensuring they are ready before user interaction.
Key responsibilities:
- HotkeyCommandAttribute: Declares metadata for discoverable commands (e.g., name, description).
- HotkeyCommand: Base class or interface for all hotkey commands.
- HotkeyManager: Scans loaded assemblies, discovers commands, and wires up shortcut handlers.
- MacroInvoker: Executes macro steps by resolving command implementations dynamically.
- MacroManager: Manages macro entries, persistence, and orchestration.
- Reflection: Provides safe and efficient reflection operations used across discovery and invocation.
**Section sources**
- [HotkeyCommandAttribute.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommandAttribute.cs)
- [HotkeyCommand.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommand.cs)
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
- [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs)
- [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.cs)
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
## Architecture Overview
The plugin architecture centers around dynamic discovery and late binding:
- Plugins ship as compiled assemblies placed in designated directories.
- At startup, the engine scans these assemblies for known patterns (attributes and base types).
- Discovered commands and macro extensions are registered into centralized managers.
- Runtime dispatch uses reflection to invoke command implementations based on configuration and user actions.
```mermaid
sequenceDiagram
participant Boot as "Program"
participant App as "App.axaml.cs"
participant Eng as "Engine.cs"
participant HKM as "HotkeyManager"
participant Mgr as "MacroManager"
participant Inv as "MacroInvoker"
participant Ref as "Reflection"
Boot->>App : Initialize Avalonia
App->>Eng : Create and configure engine
Eng->>HKM : Initialize hotkey subsystem
Eng->>Mgr : Initialize macro subsystem
HKM->>Ref : Enumerate types in loaded assemblies
HKM->>HKM : Discover commands via attributes/base types
Mgr->>Ref : Enumerate macro command types
Mgr->>Inv : Register resolvers and handlers
Note over HKM,Inv : Discovery complete; runtime dispatch ready
```
**Diagram sources**
- [Program.cs](file://ClassicAssist.Avalonia/Program.cs)
- [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs)
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
- [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs)
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
- [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.cs)
## Detailed Component Analysis
### Hotkey Command System
Hotkey commands are implemented as classes that derive from a common base and are annotated with a metadata attribute. The hotkey manager performs discovery and registration.
```mermaid
classDiagram
class HotkeyCommand {
+Execute()
+CanExecute() bool
}
class HotkeyCommandAttribute {
+Name
+Description
}
class HotkeyManager {
+Initialize()
+Register(command)
+Unregister(command)
+OnShortcut(key)
}
HotkeyManager --> HotkeyCommand : "discovers and registers"
HotkeyCommand <.. HotkeyCommandAttribute : "decorated by"
```
- Discovery pattern:
- Scan assemblies for types implementing the base command type.
- Require the presence of the metadata attribute to include a command.
- Registration:
- Add discovered commands to a registry keyed by identifier.
- Bind configured shortcuts to command identifiers.
- Execution:
- On shortcut activation, resolve the command instance and call Execute.
Implementation references:
- Attribute definition and metadata fields
- Base command contract
- Manager initialization, discovery loop, and shortcut wiring
**Diagram sources**
- [HotkeyCommandAttribute.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommandAttribute.cs)
- [HotkeyCommand.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommand.cs)
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
**Section sources**
- [HotkeyCommandAttribute.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommandAttribute.cs)
- [HotkeyCommand.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommand.cs)
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
### Macro System Extension Points
Macros are composed of steps that map to commands. The macro manager stores macro definitions, while the invoker resolves and executes commands at runtime.
```mermaid
sequenceDiagram
participant User as "User"
participant UI as "UI Layer"
participant MM as "MacroManager"
participant MI as "MacroInvoker"
participant Ref as "Reflection"
User->>UI : Run macro
UI->>MM : Invoke(macroId)
MM->>MI : Resolve steps and parameters
MI->>Ref : Find command implementation
MI->>MI : Execute step(s)
MI-->>MM : Result/status
MM-->>UI : Completion event
```
Key behaviors:
- Command resolution:
- Map macro step names to concrete implementations using reflection.
- Parameter binding:
- Parse and bind parameters to method signatures safely.
- Error propagation:
- Wrap exceptions during execution and report back to the caller.
References:
- Macro manager for storage and orchestration
- Invoker for resolution and execution
- Reflection helpers for safe type inspection
**Diagram sources**
- [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs)
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
- [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.cs)
**Section sources**
- [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs)
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
- [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.cs)
### Reflection-Based Discovery Flow
Discovery is driven by scanning loaded assemblies for known patterns.
```mermaid
flowchart TD
Start(["Start Discovery"]) --> LoadAssemblies["Load plugin assemblies"]
LoadAssemblies --> EnumTypes["Enumerate public types"]
EnumTypes --> CheckBase{"Implements base command?"}
CheckBase --> |No| NextType["Next type"]
CheckBase --> |Yes| CheckAttr{"Has metadata attribute?"}
CheckAttr --> |No| NextType
CheckAttr --> |Yes| CreateInstance["Create instance"]
CreateInstance --> Register["Register in manager"]
Register --> NextType
NextType --> Done(["Done"])
```
**Diagram sources**
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
- [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.cs)
**Section sources**
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
- [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.cs)
### Plugin Loading Mechanism and Lifecycle
Plugins are distributed as assemblies and loaded at runtime. The launcher and browser modules provide structures for manifest and plugin entries, while the engine coordinates initialization.
```mermaid
sequenceDiagram
participant Boot as "Program"
participant App as "App.axaml.cs"
participant Eng as "Engine.cs"
participant SM as "ShardManager"
participant PE as "PluginEntry"
participant ME as "ManifestEntry"
participant DB as "Database"
Boot->>App : Initialize
App->>Eng : Configure engine
Eng->>SM : Load plugin manifests
SM->>ME : Read manifest entries
SM->>PE : Build plugin entries
SM->>DB : Persist/update catalog
Eng->>Eng : Scan and load plugin assemblies
Eng->>Eng : Initialize discovered plugins
```
Lifecycle stages:
- Manifest parsing:
- Read metadata and dependency information.
- Assembly loading:
- Load plugin assemblies into the current context.
- Initialization:
- Call plugin entry points if provided.
- Teardown:
- Unregister commands and release resources on shutdown.
References:
- Plugin and manifest entry models
- Database integration for cataloging
- Engine initialization hooks
**Diagram sources**
- [Program.cs](file://ClassicAssist.Avalonia/Program.cs)
- [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs)
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
- [ShardManager.cs](file://ClassicAssist.Launcher/ShardManager.cs)
- [PluginEntry.cs](file://ClassicAssist.Launcher/PluginEntry.cs)
- [ManifestEntry.cs](file://ClassicAssist.Launcher/ManifestEntry.cs)
- [Browser.Data.Database.cs](file://ClassicAssist/Browser/Data/Database.cs)
**Section sources**
- [Program.cs](file://ClassicAssist.Avalonia/Program.cs)
- [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs)
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
- [ShardManager.cs](file://ClassicAssist.Launcher/ShardManager.cs)
- [PluginEntry.cs](file://ClassicAssist.Launcher/PluginEntry.cs)
- [ManifestEntry.cs](file://ClassicAssist.Launcher/ManifestEntry.cs)
- [Browser.Data.Database.cs](file://ClassicAssist/Browser/Data/Database.cs)
### Version Compatibility and Dependency Resolution
Compatibility and dependencies are described via manifest and metadata structures. The loader validates versions and resolves required packages before loading.
```mermaid
flowchart TD
ReadManifest["Read ManifestEntry"] --> ValidateVersion["Validate target framework/version"]
ValidateVersion --> ResolveDeps["Resolve dependencies"]
ResolveDeps --> Missing{"Missing deps?"}
Missing --> |Yes| ReportError["Report missing dependencies"]
Missing --> |No| LoadAssembly["Load plugin assembly"]
LoadAssembly --> InitPlugin["Initialize plugin"]
InitPlugin --> Ready(["Ready"])
ReportError --> End(["Abort"])
```
References:
- Manifest and metadata models
- Loader logic for validation and resolution
**Diagram sources**
- [ManifestEntry.cs](file://ClassicAssist.Launcher/ManifestEntry.cs)
- [Browser.Models.Manifest.cs](file://ClassicAssist/Browser/Models/Manifest.cs)
- [Browser.Models.Metadata.cs](file://ClassicAssist/Browser/Models/Metadata.cs)
**Section sources**
- [ManifestEntry.cs](file://ClassicAssist.Launcher/ManifestEntry.cs)
- [Browser.Models.Manifest.cs](file://ClassicAssist/Browser/Models/Manifest.cs)
- [Browser.Models.Metadata.cs](file://ClassicAssist/Browser/Models/Metadata.cs)
### UI Integration and Browsing
The browser component integrates with the macro system and database to present available content and manage metadata.
```mermaid
graph TB
VM["MacroBrowserViewModel"]
DB["Database"]
Filter["Filter / FilterType"]
Meta["Metadata"]
Manifest["Manifest"]
Ctrl["MacroBrowserControl"]
VM --> DB
VM --> Filter
VM --> Meta
VM --> Manifest
Ctrl --> VM
```
Responsibilities:
- Query and filter macro entries
- Display metadata and manifest details
- Provide user interactions to install/update content
**Diagram sources**
- [Browser.MacroBrowserViewModel.cs](file://ClassicAssist/Browser/MacroBrowserViewModel.cs)
- [Browser.MacroBrowserControl.xaml.cs](file://ClassicAssist/Browser/MacroBrowserControl.xaml.cs)
- [Browser.Data.Database.cs](file://ClassicAssist/Browser/Data/Database.cs)
- [Browser.Data.Filter.cs](file://ClassicAssist/Browser/Data/Filter.cs)
- [Browser.Data.FilterType.cs](file://ClassicAssist/Browser/Data/FilterType.cs)
- [Browser.Models.Metadata.cs](file://ClassicAssist/Browser/Models/Metadata.cs)
- [Browser.Models.Manifest.cs](file://ClassicAssist/Browser/Models/Manifest.cs)
**Section sources**
- [Browser.MacroBrowserViewModel.cs](file://ClassicAssist/Browser/MacroBrowserViewModel.cs)
- [Browser.MacroBrowserControl.xaml.cs](file://ClassicAssist/Browser/MacroBrowserControl.xaml.cs)
- [Browser.Data.Database.cs](file://ClassicAssist/Browser/Data/Database.cs)
- [Browser.Data.Filter.cs](file://ClassicAssist/Browser/Data/Filter.cs)
- [Browser.Data.FilterType.cs](file://ClassicAssist/Browser/Data/FilterType.cs)
- [Browser.Models.Metadata.cs](file://ClassicAssist/Browser/Models/Metadata.cs)
- [Browser.Models.Manifest.cs](file://ClassicAssist/Browser/Models/Manifest.cs)
## Dependency Analysis
The following diagram shows key dependencies between core components involved in plugin discovery and execution.
```mermaid
graph LR
Program["Program"] --> AppXaml["App.axaml.cs"]
AppXaml --> EngineAva["Engine.cs"]
EngineAva --> HKM["HotkeyManager"]
EngineAva --> MacroMgr["MacroManager"]
HKM --> HKAttr["HotkeyCommandAttribute"]
HKM --> HKCmd["HotkeyCommand"]
MacroMgr --> MacroInv["MacroInvoker"]
MacroInv --> Refl["Reflection"]
ShardMgr["ShardManager"] --> PluginEntry["PluginEntry"]
ShardMgr --> ManifestEntry["ManifestEntry"]
MBVM["MacroBrowserViewModel"] --> DB["Database"]
MBVM --> Filter["Filter"]
MBVM --> Meta["Metadata"]
MBVM --> Manifest["Manifest"]
```
**Diagram sources**
- [Program.cs](file://ClassicAssist.Avalonia/Program.cs)
- [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs)
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
- [HotkeyCommandAttribute.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommandAttribute.cs)
- [HotkeyCommand.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommand.cs)
- [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs)
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
- [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.cs)
- [ShardManager.cs](file://ClassicAssist.Launcher/ShardManager.cs)
- [PluginEntry.cs](file://ClassicAssist.Launcher/PluginEntry.cs)
- [ManifestEntry.cs](file://ClassicAssist.Launcher/ManifestEntry.cs)
- [Browser.MacroBrowserViewModel.cs](file://ClassicAssist/Browser/MacroBrowserViewModel.cs)
- [Browser.Data.Database.cs](file://ClassicAssist/Browser/Data/Database.cs)
- [Browser.Data.Filter.cs](file://ClassicAssist/Browser/Data/Filter.cs)
- [Browser.Models.Metadata.cs](file://ClassicAssist/Browser/Models/Metadata.cs)
- [Browser.Models.Manifest.cs](file://ClassicAssist/Browser/Models/Manifest.cs)
**Section sources**
- [Program.cs](file://ClassicAssist.Avalonia/Program.cs)
- [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs)
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
- [HotkeyCommandAttribute.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommandAttribute.cs)
- [HotkeyCommand.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommand.cs)
- [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs)
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
- [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.cs)
- [ShardManager.cs](file://ClassicAssist.Launcher/ShardManager.cs)
- [PluginEntry.cs](file://ClassicAssist.Launcher/PluginEntry.cs)
- [ManifestEntry.cs](file://ClassicAssist.Launcher/ManifestEntry.cs)
- [Browser.MacroBrowserViewModel.cs](file://ClassicAssist/Browser/MacroBrowserViewModel.cs)
- [Browser.Data.Database.cs](file://ClassicAssist/Browser/Data/Database.cs)
- [Browser.Data.Filter.cs](file://ClassicAssist/Browser/Data/Filter.cs)
- [Browser.Models.Metadata.cs](file://ClassicAssist/Browser/Models/Metadata.cs)
- [Browser.Models.Manifest.cs](file://ClassicAssist/Browser/Models/Manifest.cs)
## Performance Considerations
- Minimize reflection overhead:
- Cache discovered types and constructed delegates where possible.
- Avoid heavy work on the UI thread:
- Use background threads for discovery and I/O; marshal results back to the UI thread.
- Limit assembly scanning scope:
- Scan only known directories and avoid unnecessary assemblies.
- Batch operations:
- Group registrations and UI updates to reduce churn.
- Resource cleanup:
- Ensure plugins release handles and unsubscribe events during teardown.
[No sources needed since this section provides general guidance]
## Troubleshooting Guide
Common issues and strategies:
- Missing dependencies:
- Validate manifest entries and ensure required packages are present before loading.
- Type not found:
- Confirm that command classes implement the expected base type and have the required attribute.
- Invocation errors:
- Inspect exception messages from the invoker and verify parameter binding.
- UI thread violations:
- Ensure cross-thread calls use the dispatcher or UI invoker.
- Logging and diagnostics:
- Centralize logging around discovery and execution paths to capture failures early.
Relevant areas to inspect:
- Hotkey manager discovery and registration
- Macro invoker resolution and execution
- Reflection helper usage
- Engine initialization sequence
**Section sources**
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
- [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.cs)
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
## Conclusion
The ClassicAssist.Avalonia plugin architecture leverages reflection-based discovery and dynamic loading to enable extensible hotkey commands and macro systems. By adhering to the established contracts and leveraging the provided managers, developers can create robust plugins that integrate seamlessly with the host application. Proper attention to security, performance, and error handling ensures reliable operation and maintainability.
[No sources needed since this section summarizes without analyzing specific files]
## Appendices
### How to Create a Custom Hotkey Command
- Implement a class deriving from the base command type.
- Decorate the class with the metadata attribute to expose it to discovery.
- Place the compiled assembly in the plugin directory so the loader can find it.
- Verify registration by checking the hotkey manager’s registry after startup.
References:
- [HotkeyCommand.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommand.cs)
- [HotkeyCommandAttribute.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommandAttribute.cs)
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
**Section sources**
- [HotkeyCommand.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommand.cs)
- [HotkeyCommandAttribute.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommandAttribute.cs)
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
### How to Extend the Macro System
- Define new macro commands by implementing the appropriate interfaces or classes recognized by the invoker.
- Ensure your command types are discoverable by the macro manager’s scanning routine.
- Test parameter binding and error handling within your command implementation.
References:
- [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs)
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
- [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.cs)
**Section sources**
- [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs)
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
- [Reflection.cs](file://ClassicAssist.Shared/Helpers/Reflection.cs)
### Plugin Distribution Format and Installation
- Package your plugin as a .NET assembly compatible with the host framework.
- Include a manifest describing metadata, dependencies, and version constraints.
- Install by placing the assembly and manifest in the expected directories.
- Use the browser or launcher to validate and update plugins.
References:
- [PluginEntry.cs](file://ClassicAssist.Launcher/PluginEntry.cs)
- [ManifestEntry.cs](file://ClassicAssist.Launcher/ManifestEntry.cs)
- [Browser.Models.Manifest.cs](file://ClassicAssist/Browser/Models/Manifest.cs)
- [Browser.Models.Metadata.cs](file://ClassicAssist/Browser/Models/Metadata.cs)
- [Browser.Data.Database.cs](file://ClassicAssist/Browser/Data/Database.cs)
**Section sources**
- [PluginEntry.cs](file://ClassicAssist.Launcher/PluginEntry.cs)
- [ManifestEntry.cs](file://ClassicAssist.Launcher/ManifestEntry.cs)
- [Browser.Models.Manifest.cs](file://ClassicAssist/Browser/Models/Manifest.cs)
- [Browser.Models.Metadata.cs](file://ClassicAssist/Browser/Models/Metadata.cs)
- [Browser.Data.Database.cs](file://ClassicAssist/Browser/Data/Database.cs)
### Security, Sandboxing, and Isolation
- Prefer least-privilege principles: restrict file and network access where possible.
- Validate inputs and sanitize outputs to prevent injection.
- Consider running plugins in isolated contexts if supported by the host environment.
- Monitor resource usage and enforce timeouts for long-running operations.
[No sources needed since this section provides general guidance]
### Debugging, Error Handling, and Performance Monitoring
- Enable detailed logging around discovery and execution paths.
- Capture and log exceptions with stack traces for diagnostics.
- Use performance counters or timers to measure hot paths.
- Validate plugin versions and dependencies prior to loading to fail fast.
References:
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
**Section sources**
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
- [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs)
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)