440 lines
22 KiB
Markdown
440 lines
22 KiB
Markdown
# Extension Points
|
||
|
||
<cite>
|
||
**Referenced Files in This Document**
|
||
- [IConfigurableFilter.cs](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.cs)
|
||
- [FilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/FilterEntry.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)
|
||
- [DynamicFilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/DynamicFilterEntry.cs)
|
||
- [Filters.cs](file://ClassicAssist.Shared/Engine/Filters.cs)
|
||
- [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)
|
||
- [HotkeyEntry.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyEntry.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)
|
||
- [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs)
|
||
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
|
||
- [Program.cs](file://ClassicAssist.Avalonia/Program.cs)
|
||
- [PluginEntry.cs](file://ClassicAssist.Launcher/PluginEntry.cs)
|
||
- [ShardManager.cs](file://ClassicAssist.Launcher/ShardManager.cs)
|
||
- [MainWindowViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/MainWindowViewModel.cs)
|
||
- [HotkeysTabViewModel.cs](file://ClassicAssist.Shared/UI/ViewModels/HotkeysTabViewModel.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)
|
||
10. [Appendices](#appendices)
|
||
|
||
## Introduction
|
||
This document explains how to extend ClassicAssist.Avalonia using its extension points. It focuses on:
|
||
- Filter system interfaces for custom message filters (IConfigurableFilter and FilterEntry)
|
||
- Hotkey command extension points via HotkeyCommandAttribute
|
||
- Plugin architecture guidelines including assembly loading, dependency injection, and lifecycle management
|
||
- Configuration schemas, validation rules, and testing strategies
|
||
- Security considerations, performance impact, and distribution methods
|
||
|
||
The goal is to enable developers to implement custom filters, hotkey commands, and UI extensions that integrate cleanly with the application’s runtime and configuration model.
|
||
|
||
## Project Structure
|
||
The extension points are primarily defined in the shared layer and consumed by the Avalonia UI and launcher components:
|
||
- Shared filter interfaces and attributes under Data/Filters
|
||
- Hotkey command attribute and manager under Data/Hotkeys
|
||
- Packet filtering pipeline under UO/Network
|
||
- Avalonia app bootstrap and engine initialization under ClassicAssist.Avalonia
|
||
- Launcher plugin entry and shard management under ClassicAssist.Launcher
|
||
|
||
```mermaid
|
||
graph TB
|
||
subgraph "Shared"
|
||
FIF["IConfigurableFilter.cs"]
|
||
FE["FilterEntry.cs"]
|
||
FOA["FilterOptionsAttribute.cs"]
|
||
HCA["HotkeyCommandAttribute.cs"]
|
||
HCM["HotkeyManager.cs"]
|
||
IPF["IncomingPacketFilters.cs"]
|
||
OPF["OutgoingPacketFilters.cs"]
|
||
PF["PacketFilter.cs"]
|
||
end
|
||
subgraph "Avalonia"
|
||
APP["App.axaml.cs"]
|
||
ENG["Engine.cs"]
|
||
PRG["Program.cs"]
|
||
CFW["ClilocFilterConfigureWindow.xaml.cs"]
|
||
RMFW["RepeatedMessagesFilterConfigureWindow.xaml.cs"]
|
||
end
|
||
subgraph "Launcher"
|
||
PLE["PluginEntry.cs"]
|
||
SM["ShardManager.cs"]
|
||
end
|
||
FIF --> FE
|
||
FOA --> FE
|
||
HCA --> HCM
|
||
IPF --> PF
|
||
OPF --> PF
|
||
APP --> ENG
|
||
PRG --> APP
|
||
PLE --> SM
|
||
CFW --> FE
|
||
RMFW --> FE
|
||
```
|
||
|
||
**Diagram sources**
|
||
- [IConfigurableFilter.cs](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.cs)
|
||
- [FilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/FilterEntry.cs)
|
||
- [FilterOptionsAttribute.cs](file://ClassicAssist.Shared/Data/Filters/FilterOptionsAttribute.cs)
|
||
- [HotkeyCommandAttribute.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommandAttribute.cs)
|
||
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.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)
|
||
- [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs)
|
||
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
|
||
- [Program.cs](file://ClassicAssist.Avalonia/Program.cs)
|
||
- [PluginEntry.cs](file://ClassicAssist.Launcher/PluginEntry.cs)
|
||
- [ShardManager.cs](file://ClassicAssist.Launcher/ShardManager.cs)
|
||
- [ClilocFilterConfigureWindow.xaml.cs](file://ClassicAssist.Avalonia/Views/Filters/Views/Filters/ClilocFilterConfigureWindow.xaml.cs)
|
||
- [RepeatedMessagesFilterConfigureWindow.xaml.cs](file://ClassicAssist.Avalonia/Views/Filters/RepeatedMessagesFilterConfigureWindow.xaml.cs)
|
||
|
||
**Section sources**
|
||
- [App.axaml.cs](file://ClassicAssist.Avalonia/App.axaml.cs)
|
||
- [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs)
|
||
- [Program.cs](file://ClassicAssist.Avalonia/Program.cs)
|
||
- [PluginEntry.cs](file://ClassicAssist.Launcher/PluginEntry.cs)
|
||
- [ShardManager.cs](file://ClassicAssist.Launcher/ShardManager.cs)
|
||
|
||
## Core Components
|
||
- IConfigurableFilter: Interface for creating custom message filters that can be configured through the UI.
|
||
- FilterEntry: Base type or container used to represent a filter instance and its configuration state.
|
||
- FilterOptionsAttribute: Attribute-driven metadata to describe filter options for UI binding and validation.
|
||
- HotkeyCommandAttribute: Attribute to register a class as a hotkey command, enabling discovery and registration into the hotkey system.
|
||
- HotkeyManager: Central registry and dispatcher for hotkey commands.
|
||
- IncomingPacketFilters / OutgoingPacketFilters: Pipeline hooks for intercepting network packets.
|
||
- PacketFilter: Core packet filtering infrastructure used by incoming/outgoing pipelines.
|
||
|
||
These components form the foundation for extending message filtering and keyboard shortcuts.
|
||
|
||
**Section sources**
|
||
- [IConfigurableFilter.cs](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.cs)
|
||
- [FilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/FilterEntry.cs)
|
||
- [FilterOptionsAttribute.cs](file://ClassicAssist.Shared/Data/Filters/FilterOptionsAttribute.cs)
|
||
- [HotkeyCommandAttribute.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommandAttribute.cs)
|
||
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.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)
|
||
|
||
## Architecture Overview
|
||
The extension architecture separates concerns across layers:
|
||
- Shared layer defines contracts (interfaces, attributes, base types).
|
||
- Avalonia layer provides UI integration and bootstrapping.
|
||
- Launcher handles plugin discovery and lifecycle.
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant Boot as "Program.cs"
|
||
participant App as "App.axaml.cs"
|
||
participant Engine as "Engine.cs"
|
||
participant Filters as "Filters.cs"
|
||
participant InPkt as "IncomingPacketFilters.cs"
|
||
participant OutPkt as "OutgoingPacketFilters.cs"
|
||
participant PktF as "PacketFilter.cs"
|
||
Boot->>App : Initialize application
|
||
App->>Engine : Start engine and services
|
||
Engine->>Filters : Register built-in and discovered filters
|
||
Engine->>InPkt : Attach incoming packet pipeline
|
||
Engine->>OutPkt : Attach outgoing packet pipeline
|
||
InPkt->>PktF : Apply filters to incoming packets
|
||
OutPkt->>PktF : Apply filters to outgoing packets
|
||
Note over InPkt,OutPkt : Custom filters implement IConfigurableFilter<br/>and are registered via FilterEntry
|
||
```
|
||
|
||
**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)
|
||
- [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)
|
||
|
||
## Detailed Component Analysis
|
||
|
||
### Filter System: IConfigurableFilter and FilterEntry
|
||
Custom message filters should implement IConfigurableFilter and be represented via FilterEntry. The FilterOptionsAttribute enables declarative configuration UI generation and validation.
|
||
|
||
```mermaid
|
||
classDiagram
|
||
class IConfigurableFilter {
|
||
+string Name
|
||
+bool IsEnabled
|
||
+void Configure()
|
||
+bool Evaluate(message) bool
|
||
}
|
||
class FilterEntry {
|
||
+string Id
|
||
+string Name
|
||
+bool Enabled
|
||
+object Options
|
||
+void Save()
|
||
+void Load()
|
||
}
|
||
class FilterOptionsAttribute {
|
||
+string DisplayName
|
||
+string Description
|
||
+Type ValueType
|
||
+object DefaultValue
|
||
}
|
||
IConfigurableFilter <.. FilterEntry : "implemented by"
|
||
FilterEntry --> FilterOptionsAttribute : "uses for schema"
|
||
```
|
||
|
||
Key implementation patterns:
|
||
- Implement IConfigurableFilter to define evaluation logic and configuration behavior.
|
||
- Use FilterEntry to persist and bind filter state to UI.
|
||
- Annotate configuration properties with FilterOptionsAttribute to drive UI and validation.
|
||
|
||
Example references:
|
||
- Built-in configurable filters demonstrate usage patterns:
|
||
- ClilocFilter
|
||
- RepeatedMessagesFilter
|
||
|
||
UI configuration windows:
|
||
- ClilocFilterConfigureWindow
|
||
- RepeatedMessagesFilterConfigureWindow
|
||
|
||
**Diagram sources**
|
||
- [IConfigurableFilter.cs](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.cs)
|
||
- [FilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/FilterEntry.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)
|
||
- [ClilocFilterConfigureWindow.xaml.cs](file://ClassicAssist.Avalonia/Views/Filters/ClilocFilterConfigureWindow.xaml.cs)
|
||
- [RepeatedMessagesFilterConfigureWindow.xaml.cs](file://ClassicAssist.Avalonia/Views/Filters/RepeatedMessagesFilterConfigureWindow.xaml.cs)
|
||
|
||
**Section sources**
|
||
- [IConfigurableFilter.cs](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.cs)
|
||
- [FilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/FilterEntry.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)
|
||
- [ClilocFilterConfigureWindow.xaml.cs](file://ClassicAssist.Avalonia/Views/Filters/ClilocFilterConfigureWindow.xaml.cs)
|
||
- [RepeatedMessagesFilterConfigureWindow.xaml.cs](file://ClassicAssist.Avalonia/Views/Filters/RepeatedMessagesFilterConfigureWindow.xaml.cs)
|
||
|
||
### Hotkey Command Extension Points: HotkeyCommandAttribute
|
||
To add a new hotkey command:
|
||
- Decorate your command class with HotkeyCommandAttribute.
|
||
- Ensure the class adheres to the expected contract recognized by HotkeyManager.
|
||
- The manager will discover and register the command during startup.
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant Boot as "Program.cs"
|
||
participant App as "App.axaml.cs"
|
||
participant Engine as "Engine.cs"
|
||
participant HM as "HotkeyManager.cs"
|
||
participant Cmd as "YourHotkeyCommand.cs"
|
||
Boot->>App : Initialize
|
||
App->>Engine : Start services
|
||
Engine->>HM : Discover commands via reflection
|
||
HM-->>Cmd : Instantiate decorated classes
|
||
HM->>HM : Register command mappings
|
||
Note over HM,Cmd : Commands are later invoked when user presses bound keys
|
||
```
|
||
|
||
**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)
|
||
- [HotkeyCommandAttribute.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommandAttribute.cs)
|
||
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
|
||
|
||
**Section sources**
|
||
- [HotkeyCommandAttribute.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommandAttribute.cs)
|
||
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
|
||
- [HotkeyEntry.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyEntry.cs)
|
||
|
||
### Plugin Architecture Guidelines
|
||
Guidelines for building plugins:
|
||
- Assembly loading: Place plugin assemblies in the designated directory; the launcher scans for entries compatible with the plugin manifest.
|
||
- Dependency injection: Use constructor injection where possible; rely on shared services exposed by the engine.
|
||
- Lifecycle management: Implement initialization and cleanup hooks if needed; ensure thread-safety for background operations.
|
||
- Manifest and metadata: Provide required metadata so the launcher can enumerate and load your plugin safely.
|
||
|
||
Relevant components:
|
||
- PluginEntry: Represents a plugin manifest entry.
|
||
- ShardManager: Manages shards and may coordinate plugin loading contexts.
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
Start(["Application Start"]) --> Scan["Scan Plugins Directory"]
|
||
Scan --> LoadManifest["Load PluginEntry Metadata"]
|
||
LoadManifest --> Validate{"Valid Manifest?"}
|
||
Validate --> |No| Skip["Skip Plugin"]
|
||
Validate --> |Yes| LoadAsm["Load Assembly Safely"]
|
||
LoadAsm --> DI["Resolve Dependencies"]
|
||
DI --> Init["Initialize Plugin"]
|
||
Init --> Run["Run During Session"]
|
||
Run --> Cleanup["Cleanup on Shutdown"]
|
||
Cleanup --> End(["Exit"])
|
||
Skip --> End
|
||
```
|
||
|
||
[No sources needed since this diagram shows conceptual workflow, not actual code structure]
|
||
|
||
**Section sources**
|
||
- [PluginEntry.cs](file://ClassicAssist.Launcher/PluginEntry.cs)
|
||
- [ShardManager.cs](file://ClassicAssist.Launcher/ShardManager.cs)
|
||
|
||
### Network Filtering Integration
|
||
Custom filters can participate in the packet filtering pipeline:
|
||
- IncomingPacketFilters and OutgoingPacketFilters provide hooks to apply filters to network traffic.
|
||
- PacketFilter encapsulates core filtering logic and conditions.
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
InStart(["Incoming Packet"]) --> ApplyIn["Apply Incoming Filters"]
|
||
ApplyIn --> DecisionIn{"Filtered?"}
|
||
DecisionIn --> |Yes| DropIn["Drop Packet"]
|
||
DecisionIn --> |No| DispatchIn["Dispatch to Handlers"]
|
||
OutStart(["Outgoing Packet"]) --> ApplyOut["Apply Outgoing Filters"]
|
||
ApplyOut --> DecisionOut{"Filtered?"}
|
||
DecisionOut --> |Yes| DropOut["Drop Packet"]
|
||
DecisionOut --> |No| SendOut["Send Over Network"]
|
||
```
|
||
|
||
**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)
|
||
|
||
**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)
|
||
|
||
## Dependency Analysis
|
||
High-level dependencies among extension points:
|
||
- Filters depend on IConfigurableFilter and FilterEntry for configuration and persistence.
|
||
- Hotkey commands depend on HotkeyCommandAttribute and HotkeyManager for discovery and dispatch.
|
||
- Network filters depend on IncomingPacketFilters and OutgoingPacketFilters to integrate with the packet pipeline.
|
||
|
||
```mermaid
|
||
graph LR
|
||
ICF["IConfigurableFilter.cs"] --> FE["FilterEntry.cs"]
|
||
FOA["FilterOptionsAttribute.cs"] --> FE
|
||
HCA["HotkeyCommandAttribute.cs"] --> HCM["HotkeyManager.cs"]
|
||
INPF["IncomingPacketFilters.cs"] --> PF["PacketFilter.cs"]
|
||
OUTPF["OutgoingPacketFilters.cs"] --> PF
|
||
```
|
||
|
||
**Diagram sources**
|
||
- [IConfigurableFilter.cs](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.cs)
|
||
- [FilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/FilterEntry.cs)
|
||
- [FilterOptionsAttribute.cs](file://ClassicAssist.Shared/Data/Filters/FilterOptionsAttribute.cs)
|
||
- [HotkeyCommandAttribute.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommandAttribute.cs)
|
||
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.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)
|
||
|
||
**Section sources**
|
||
- [IConfigurableFilter.cs](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.cs)
|
||
- [FilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/FilterEntry.cs)
|
||
- [FilterOptionsAttribute.cs](file://ClassicAssist.Shared/Data/Filters/FilterOptionsAttribute.cs)
|
||
- [HotkeyCommandAttribute.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommandAttribute.cs)
|
||
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.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)
|
||
|
||
## Performance Considerations
|
||
- Keep filter evaluation logic lightweight; avoid heavy allocations and blocking I/O inside hot paths.
|
||
- Prefer early-exit conditions to minimize processing overhead.
|
||
- Batch operations where possible and avoid synchronous UI calls from background threads.
|
||
- For hotkey commands, ensure quick execution; offload long-running tasks to background threads and marshal results back to the UI thread.
|
||
- Be mindful of memory retention in filter state; release resources promptly.
|
||
|
||
[No sources needed since this section provides general guidance]
|
||
|
||
## Troubleshooting Guide
|
||
Common issues and resolutions:
|
||
- Filters not appearing in UI:
|
||
- Verify IConfigurableFilter implementation and FilterEntry registration.
|
||
- Check FilterOptionsAttribute usage for correct property exposure.
|
||
- Hotkey commands not firing:
|
||
- Confirm HotkeyCommandAttribute decoration and proper registration via HotkeyManager.
|
||
- Ensure no conflicts with existing key bindings.
|
||
- Network filters not applied:
|
||
- Validate integration with IncomingPacketFilters and OutgoingPacketFilters.
|
||
- Inspect PacketFilter conditions and order of application.
|
||
|
||
Validation and diagnostics:
|
||
- Use unit tests to validate filter logic and hotkey command behavior.
|
||
- Add logging around filter evaluation and command invocation to trace issues.
|
||
|
||
**Section sources**
|
||
- [IConfigurableFilter.cs](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.cs)
|
||
- [FilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/FilterEntry.cs)
|
||
- [FilterOptionsAttribute.cs](file://ClassicAssist.Shared/Data/Filters/FilterOptionsAttribute.cs)
|
||
- [HotkeyCommandAttribute.cs](file://ClassicAssist.Shared/Data/Hotkeys/Commands/HotkeyCommandAttribute.cs)
|
||
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.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)
|
||
|
||
## Conclusion
|
||
By implementing IConfigurableFilter and leveraging FilterEntry and FilterOptionsAttribute, you can create robust, configurable message filters. Using HotkeyCommandAttribute and HotkeyManager, you can register custom keyboard shortcuts seamlessly. Follow the plugin architecture guidelines for safe assembly loading, dependency resolution, and lifecycle management. Adhering to performance best practices and security considerations ensures reliable and efficient extensions.
|
||
|
||
[No sources needed since this section summarizes without analyzing specific files]
|
||
|
||
## Appendices
|
||
|
||
### Configuration Schema and Validation Rules
|
||
- FilterOptionsAttribute drives the schema for filter options.
|
||
- Define display names, descriptions, value types, and defaults to guide UI rendering and validation.
|
||
- Persist options via FilterEntry to maintain user preferences across sessions.
|
||
|
||
**Section sources**
|
||
- [FilterOptionsAttribute.cs](file://ClassicAssist.Shared/Data/Filters/FilterOptionsAttribute.cs)
|
||
- [FilterEntry.cs](file://ClassicAssist.Shared/Data/Filters/FilterEntry.cs)
|
||
|
||
### Testing Strategies
|
||
- Unit test filter evaluation logic with representative messages.
|
||
- Mock HotkeyManager interactions to verify command registration and invocation.
|
||
- Simulate packet flows to validate network filter behavior.
|
||
|
||
**Section sources**
|
||
- [IConfigurableFilter.cs](file://ClassicAssist.Shared/Data/Filters/IConfigurableFilter.cs)
|
||
- [HotkeyManager.cs](file://ClassicAssist.Shared/Data/Hotkeys/HotkeyManager.cs)
|
||
- [IncomingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/IncomingPacketFilters.cs)
|
||
- [OutgoingPacketFilters.cs](file://ClassicAssist.Shared/UO/Network/OutgoingPacketFilters.cs)
|
||
|
||
### Security Considerations
|
||
- Validate all inputs in filters and commands to prevent injection or malformed data issues.
|
||
- Restrict file system and network access within plugins to necessary scopes.
|
||
- Avoid executing arbitrary code loaded from untrusted sources; enforce manifest checks and signature verification where applicable.
|
||
|
||
[No sources needed since this section provides general guidance]
|
||
|
||
### Distribution Methods for Plugins
|
||
- Package plugin assemblies with required dependencies.
|
||
- Include a manifest describing plugin metadata and capabilities.
|
||
- Distribute via official channels or trusted repositories; ensure users place plugins in the correct directory for discovery.
|
||
|
||
**Section sources**
|
||
- [PluginEntry.cs](file://ClassicAssist.Launcher/PluginEntry.cs)
|
||
- [ShardManager.cs](file://ClassicAssist.Launcher/ShardManager.cs) |