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,8 @@
schema_version: 1
module_path: classic_assist_wpf/agents/agents_tab_controls
title: Agents Tab Controls (WPF Views)
scope:
- ClassicAssist/UI/Views/Agents/
source_files: []
depends_on: []
related_to: []
@@ -0,0 +1 @@
Flat collection of WPF `UserControl` subclasses in namespace `ClassicAssist.UI.Views.Agents`, each paired with a `.xaml` + code-behind file. Code-behinds are minimal stubs inheriting from `System.Windows.Controls.UserControl` and only calling `InitializeComponent()`, delegating all logic to ViewModels defined under `ClassicAssist.Shared.UI.ViewModels.Agents` (e.g. `AutolootViewModel`). The XAML files declare the view's data context via `<agents:AutolootViewModel />` and compose shared UI building blocks from `ClassicAssist.UI.Controls`, `ClassicAssist.UI.Misc` behaviors (`ClipboardBehaviour`, `ItemsControlSelectNewEntryBehaviour`, `ListViewMultiSelectionBehaviour`), value converters, and localized strings from `ClassicAssist.Shared.Resources`. Each tab is a self-contained presentation layer with no cross-tab dependencies; consumers assemble them at a higher level (the agents tab host).
@@ -0,0 +1,4 @@
- Code-behind classes are empty stubs that inherit from `UserControl` and call only `InitializeComponent()`; all state and commands live in the ViewModel.
- Each tab's XAML sets its `DataContext` inline by instantiating the matching ViewModel type from `ClassicAssist.Shared.UI.ViewModels.Agents` rather than using a DI container.
- UI text is sourced through `{x:Static resources:Strings.*}` from `ClassicAssist.Shared.Resources` instead of hard-coded strings.
- Reusable interactions are implemented as attached behaviors in `ClassicAssist.UI.Misc` (e.g. `ClipboardBehaviour`, `ItemsControlSelectNewEntryBehaviour`) applied via `i:Interaction.Behaviors`.
@@ -0,0 +1 @@
WPF UserControl views that present the individual agent tabs — autoloot, counters, dress, friends, organizer, scavenger, and vendor buy/sell — bound to their corresponding ViewModels.
@@ -0,0 +1 @@
WPF (`System.Windows.Controls`) with XAML markup, Microsoft.Xaml.Behaviors for `Interaction.Behaviors`, and MVVM binding against ViewModels in the separate `ClassicAssist.Shared` assembly.
@@ -0,0 +1,8 @@
schema_version: 1
module_path: classic_assist_wpf/agents/autoloot
title: Autoloot Property Selection Dialogs (WPF)
scope:
- ClassicAssist/UI/Views/Autoloot/
source_files: []
depends_on: []
related_to: []
@@ -0,0 +1 @@
Three sibling WPF `Window` views — `PropertySelectionWindow`, `CustomPropertiesWindow`, and `ClilocSelectionWindow` — each paired with a thin code-behind class inheriting from `System.Windows.Window`. The view-models live in the cross-cutting `ClassicAssist.Shared.UI.ViewModels.Autoloot` namespace (referenced via `xmlns:autoloot`) and are instantiated directly in XAML as `Window.DataContext`, so this module owns only presentation logic. All three windows share a uniform two-column layout (content on the left, action buttons on the right), load shared resources from `../../../Resources/Icons.xaml` and `ResourceDictionary.xaml`, bind localized UI text through `ClassicAssist.Shared.Resources.Strings`, and use `CloseOnClickBehaviour` attached via `System.Windows.Interactivity` to dismiss themselves after OK/Save actions. There is no internal sub-layering beyond the standard XAML/code-behind split.
@@ -0,0 +1,5 @@
- Each window pairs a `.xaml` with an empty code-behind class whose sole job is `InitializeComponent()` and inherits from `System.Windows.Window`.
- ViewModels are declared inline in XAML via `<autoloot:... />` and set as `Window.DataContext`, keeping code-behind free of binding setup.
- All user-facing text is pulled from `ClassicAssist.Shared.Resources.Strings` using `{x:Static ...}` rather than hardcoded literals.
- Dialog dismissal is handled uniformly by attaching `misc:CloseOnClickBehaviour` to OK/Save buttons instead of calling `Close()` in code.
- Every window merges the same shared resource dictionaries (`Icons.xaml`, `ResourceDictionary.xaml`) and applies `ThemeWindowBackgroundBrush` plus `Topmost="True"`.
@@ -0,0 +1 @@
WPF dialog windows that let players pick item properties for the autoloot feature, either by browsing item definitions or searching cliloc strings.
@@ -0,0 +1 @@
WPF (`System.Windows.Window`, `System.Windows.Interactivity`) with MVVM; localization via `ClassicAssist.Shared.Resources.Strings` and theme brushes from merged resource dictionaries.
@@ -0,0 +1,9 @@
schema_version: 1
module_path: classic_assist_wpf/agents
title: Agents UI (WPF Tab Views & Autoloot Dialogs)
scope:
- ClassicAssist/UI/Views/Agents/
- ClassicAssist/UI/Views/Autoloot/
source_files: []
depends_on: []
related_to: []
@@ -0,0 +1 @@
Two sibling view folders share the same contract: every `*TabControl.xaml` in `Views/Agents/` instantiates a corresponding ViewModel from `ClassicAssist.Shared.UI.ViewModels.Agents` as its `DataContext`, while the `AutolootTabControl` additionally hosts the autoloot rule editor (items list + constraint grid) and opens the dialog windows under `Views/Autoloot/` (`ClilocSelectionWindow`, `CustomPropertiesWindow`, `PropertySelectionWindow`) through commands exposed on the same ViewModel. The code-behind of each tab control is a thin `InitializeComponent()` shell — all logic lives in the Shared ViewModels, so this module acts purely as the XAML binding layer between the game's Shared data models (`ClassicAssist.Data.Autoloot`, etc.) and the agents subsystem.
@@ -0,0 +1,3 @@
- Each `*TabControl.xaml.cs` is a one-liner constructor calling only `InitializeComponent()`, with no event handlers or logic.
- The XAML sets `DataContext` directly to a Shared ViewModel type (e.g. `<agents:AutolootViewModel />`) rather than relying on DI resolution at runtime.
- Cross-cutting interactions (clipboard, multi-select, new-entry insertion) are implemented as attached behaviors from `ClassicAssist.UI.Misc` bound via `i:Interaction.Behaviors` instead of code-behind.
@@ -0,0 +1 @@
WPF views that compose the Agents tab page and its property-selection dialogs, wiring each agent's UserControl to a Shared ViewModel via DataContext.
@@ -0,0 +1,10 @@
schema_version: 1
module_path: classic_assist_wpf/main_ui/agents_tab_controls
title: Agents Tab Panel (WPF)
scope:
- ClassicAssist/UI/Views/Agents/
- ClassicAssist/UI/Views/AgentsTabControl.xaml
- ClassicAssist/UI/Views/AgentsTabControl.xaml.cs
source_files: []
depends_on: []
related_to: []
@@ -0,0 +1 @@
Two-layer WPF composition: `AgentsTabControl.xaml` is a thin `UserControl` hosting a `TabControl` whose `TabItem`s are declared purely in XAML and each hosts one child view from the `ClassicAssist.UI.Views.Agents` namespace. The eight agent views (`Organizer`, `Dress`, `Counters`, `Friends`, `VendorBuy`, `VendorSell`, `Scavenger`, `Autoloot`) live as sibling `*.xaml` / `*.xaml.cs` pairs under `Agents/`; their code-behind classes are empty `partial` classes inheriting from `System.Windows.Controls.UserControl` with only an `InitializeComponent()` constructor, so all logic is expected to be supplied via data binding to view-models defined elsewhere. Header text for every tab is resolved through `resources:Strings.*` static resources, keeping UI text out of markup. Dependency direction is strictly inward: the parent tab control depends on the child agents; children do not reference the parent.
@@ -0,0 +1,3 @@
- Each agent feature ships as a paired `*.xaml` + `*.xaml.cs` where the code-behind is a minimal `partial class : UserControl` containing only `InitializeComponent()` in the constructor.
- Tab headers are localized by referencing `resources:Strings.<Key>` static XAML bindings rather than hard-coded strings.
- Child agent controls are referenced via a single `xmlns:agents="clr-namespace:ClassicAssist.UI.Views.Agents"` prefix and instantiated directly as XAML elements inside `TabItem` content.
@@ -0,0 +1 @@
WPF tabbed container that groups all player-agent management sub-panels — Organizer, Dress, Counters, Friends, Vendor Buy/Sell, Scavenger, and Autoloot — behind a single AgentsTabControl.
@@ -0,0 +1,8 @@
schema_version: 1
module_path: classic_assist_wpf/main_ui/autoloot_windows
title: Autoloot Property Selection Dialogs (WPF)
scope:
- ClassicAssist/UI/Views/Autoloot/
source_files: []
depends_on: []
related_to: []
@@ -0,0 +1 @@
Three sibling WPF `Window` views — `PropertySelectionWindow`, `ClilocSelectionWindow`, and `CustomPropertiesWindow` — each paired with a minimal code-behind that only calls `InitializeComponent()`. All UI logic is delegated to view models in the cross-cutting `ClassicAssist.Shared.UI.ViewModels.Autoloot` namespace (`PropertySelectionViewModel`, `ClilocSelectionViewModel`, `CustomPropertiesViewModel`), which are instantiated directly in XAML via `<autoloot:... />` bindings. The `.xaml.cs` files depend on `System.Windows` (WPF), while the XAML markup additionally references shared resources (`ClassicAssist.Shared.Resources.Strings`, `ClassicAssist.UI.Misc.CloseOnClickBehaviour`, `ClassicAssist.UI.Resources.*`) and Expression Blend interactivity for button-close behavior. Dependency direction is strictly View → ViewModel; there is no controller or service layer inside this folder.
@@ -0,0 +1,4 @@
- Each window has a one-line constructor that only invokes `InitializeComponent()`; all command handling lives in the bound ViewModel rather than in code-behind.
- XAML sets `DataContext` inline via an `<autoloot:...ViewModel />` element so each window owns its own ViewModel instance instead of using DI.
- OK/Cancel buttons use `CloseOnClickBehaviour` from `ClassicAssist.UI.Misc` through `i:Interaction.Behaviors` instead of explicit click handlers.
- User-facing text is pulled from `ClassicAssist.Shared.Resources.Strings` via `{x:Static ...}` resource lookups, never hard-coded strings.
@@ -0,0 +1 @@
WPF dialog windows that let players pick autoloot properties by item, by cliloc key, or by defining custom property entries.
@@ -0,0 +1 @@
Windows Presentation Foundation (WPF) with XAML data binding, Expression Blend Interactivity (`i:Interaction.Behaviors`), and MVVM via view models defined in the shared `ClassicAssist.Shared` assembly.
@@ -0,0 +1,10 @@
schema_version: 1
module_path: classic_assist_wpf/main_ui/core_game_features
title: Classic Assist Game UI Panels (Chat, Skills, Hotkeys)
scope:
- ClassicAssist/UI/Views/ChatWindow.xaml
- ClassicAssist/UI/Views/SkillsTabControl.xaml
- ClassicAssist/UI/Views/HotkeysTabControl.xaml
source_files: []
depends_on: []
related_to: []
@@ -0,0 +1 @@
Three independent WPF views — a top-level `Window` (`ChatWindow.xaml`) and two reusable `UserControl`s (`SkillsTabControl.xaml`, `HotkeysTabControl.xaml`) — each declaring its own `DataContext` as an MVVM ViewModel from `ClassicAssist.UI.ViewModels` (e.g. `ChatViewModel`, `SkillsTabViewModel`, `HotkeysTabViewModel`). Views are purely declarative: they bind to ViewModel properties/commands via standard WPF bindings, use `ClassicAssist.UI.Misc.ValueConverters` for display logic, and delegate cross-cutting concerns to shared resources under `../../Resources/` (`DarkTheme.xaml`, `Icons.xaml`, `ResourceDictionary.xaml`). Interaction with non-visual state is routed through `ClassicAssist.UI.Misc` behaviors (`ItemsControlAutoScrollBehaviour`, `ComboBoxBehavior`, `BindableSelectedItemBehavior`) and `ClassicAssist.Misc.BindingProxy` to reach commands inside nested visual trees such as `ContextMenu`. The Chat window additionally hosts a custom title bar via `ClassicAssist.UI.Controls.CustomWindowTitleControl` and a right-hand user list split by a `GridSplitter`; the Skills panel uses a `ListView` with `GridView` columns backed by `SkillsGridViewColumn`, while the Hotkeys panel renders a hierarchical `TreeView` of `HotkeyEntry` items bound from `ClassicAssist.Data.Hotkeys`.
@@ -0,0 +1,5 @@
- Each XAML file instantiates its ViewModel directly in markup via `<... .DataContext><viewModels:...ViewModel /></... .DataContext>` rather than setting it in code-behind.
- Shared styling and icons are loaded by merging resource dictionaries from relative paths (`../../Resources/DarkTheme.xaml`, `../../Resources/Icons.xaml`, `../../Resources/ResourceDictionary.xaml`) inside the view's `UserControl.Resources` / `Window.Resources`.
- Commands inside detached visual trees (e.g. `ContextMenu`, `DataTemplate`) are invoked through a `misc:BindingProxy` keyed as `Proxy` so the binding source can reach the parent DataContext.
- UI interactions that need code-behind access are implemented as attached behaviors in `ClassicAssist.UI.Misc` (e.g. `ItemsControlAutoScrollBehaviour`, `ComboBoxBehavior`, `BindableSelectedItemBehavior`) wired via `i:Interaction.Behaviors`.
- Localized strings are referenced through `x:Static resources:Strings.<Key>` from `ClassicAssist.Shared.Resources` instead of hard-coded text.
@@ -0,0 +1 @@
WPF XAML view definitions for the in-game chat window and two tabbed panels that let players manage skills and hotkeys.
@@ -0,0 +1,10 @@
schema_version: 1
module_path: classic_assist_wpf/main_ui/utility_windows
title: Debug & Utility Dialog Windows
scope:
- ClassicAssist/UI/Views/DebugWindow.xaml
- ClassicAssist/UI/Views/GIFRecorderWindow.xaml
- ClassicAssist/UI/Views/HuePickerWindow.xaml
source_files: []
depends_on: []
related_to: []
@@ -0,0 +1,6 @@
Three standalone WPF `Window` views (no code-behind logic here) that each own their ViewModel via inline `<Window.DataContext>` instantiation:
- `DebugWindow.xaml` is a tabbed diagnostic shell (`TabControl`) hosting multiple sub-controls from the sibling `ClassicAssist.UI.Views.Debug` namespace (gumps, menus, buff icons, special moves, vendor buy, autoloot, properties, journal, assemblies), with its toolbar styling pulled in from `Debug/DebugToolBarStyle.xaml`. It binds to `ClassicAssist.Shared.UI.ViewModels.DebugViewModel`.
- `GIFRecorderWindow.xaml` is a transparent, borderless, always-on-top overlay window using `CustomWindowTitleControl` plus three embedded `DrawingImage` resources (wait/play/stop/save) and a `misc:BindingProxy` to reach the `GIFRecorderViewModel` commands from nested controls.
- `HuePickerWindow.xaml` is a filterable list of `HueEntryControl` items bound one-way to itself (`DataContext={RelativeSource Self}`), with OK/Cancel buttons wired to an MVVM command and closed via a shared `CloseOnClickBehaviour` attached through `System.Windows.Interactivity`.
All three follow the same dependency direction: XAML → `ClassicAssist.UI.Controls`, `ClassicAssist.UI.Misc`, `ClassicAssist.Shared.Resources.Strings`, and a dedicated ViewModel in either `ClassicAssist.UI.ViewModels` or `ClassicAssist.Shared.UI.ViewModels`; they do not import each other.
@@ -0,0 +1,4 @@
- Each window declares its ViewModel directly in XAML via `<Window.DataContext><viewModels:... /></Window.DataContext>` rather than setting it in code-behind.
- User-facing strings are resolved through `{x:Static resources:Strings.*}` from `ClassicAssist.Shared.Resources` instead of hard-coded literals.
- Reusable UI chrome (window title bar, hex dump, hue entry) is composed by plugging in custom controls from `ClassicAssist.UI.Controls` rather than building visuals inline.
- Cross-naming scope behavior (closing a dialog from a button inside a child control) is achieved via `misc:BindingProxy` + `ElementName` binding or `i:Interaction.Behaviors` with `CloseOnClickBehaviour`, keeping code-behind free.
@@ -0,0 +1 @@
WPF dialog windows providing in-game debugging, GIF recording, and hue selection utilities for ClassicAssist.
@@ -0,0 +1,10 @@
schema_version: 1
module_path: classic_assist_wpf/main_ui/entity_tools
title: Entity & Profile Inspector Dialogs (WPF)
scope:
- ClassicAssist/UI/Views/EntityCollectionViewer.xaml
- ClassicAssist/UI/Views/ObjectInpectorWindow.xaml
- ClassicAssist/UI/Views/NewProfileWindow.xaml
source_files: []
depends_on: []
related_to: []
@@ -0,0 +1 @@
Pure XAML view layer — each file is a `Window` subclass whose `DataContext` is instantiated inline in markup (`EntityCollectionViewerViewModel`, `ObjectInspectorViewModel`, `NewProfileViewModel`) rather than resolved through a DI container. The views depend on sibling ViewModels in `ClassicAssist.UI.ViewModels` / `ClassicAssist.Shared.UI.ViewModels`, shared resources in `ClassicAssist.Shared.Resources.Strings`, and reusable behaviors/styles from `ClassicAssist.UI.Misc` (e.g. `MultiSelectionBehaviour`, `ListViewDoubleClickBehaviour`, `CloseOnClickBehaviour`). `EntityCollectionViewer.xaml` composes the `EntityCollectionFilterControl` sub-view and merges its own `EntityCollectionViewerResourceDictionary.xaml` plus `Debug/DebugToolBarStyle.xaml`. `ObjectInspectorWindow.xaml` groups items by a `Category` property via a `CollectionViewSource.PropertyGroupDescription` and exposes an Expander-based group template. `NewProfileWindow.xaml` uses an `EnumMatchToBooleanConverter` to bind mutually exclusive radio buttons to a single enum property. All three follow MVVM with no code-behind logic visible here; interactivity is delegated to Expression Blend `i:Interaction.Behaviors` attached to controls.
@@ -0,0 +1,4 @@
- ViewModels are created directly in XAML via `<viewModels:... />` DataContext declarations instead of being injected or resolved at runtime.
- User-facing strings are pulled from `ClassicAssist.Shared.Resources.Strings` using `{x:Static resources:Strings.*}` bindings rather than hardcoded literals.
- Cross-cutting UI interactions (multi-select, double-click-to-open, close-on-click) are implemented as Expression Blend `i:Interaction.Behaviors` from `ClassicAssist.UI.Misc` and attached declaratively.
- Toolbar/menu actions drive commands on the ViewModel with `CommandParameter` carrying strongly-typed enum values (e.g. `EntityCollectionSortStyle`) instead of string tags.
@@ -0,0 +1 @@
Three WPF dialog windows that let users browse entity collections, inspect object properties in a grouped list, and create new profiles via a small confirmation form.
@@ -0,0 +1,8 @@
schema_version: 1
module_path: classic_assist_wpf/main_ui/filters_windows
title: Filter Configuration Dialogs (WPF)
scope:
- ClassicAssist/UI/Views/Filters/
source_files: []
depends_on: []
related_to: []
@@ -0,0 +1,4 @@
Two independent WPF `Window` subclasses under the `ClassicAssist.UI.Views.Filters` namespace:
- `ClilocFilterConfigureWindow` follows MVVM: its XAML sets `DataContext` to a view model (`filters:ClilocFilterConfigureViewModel`) declared inline, while the code-behind is a minimal `InitializeComponent()` constructor. The UI composes a toolbar (save/remove), a `ListView` of configured Cliloc entries with an editable `Replacement` column via `controls:EditTextBlock`, and a lower pane that lets users search/filter available clilocs and add them.
- `RepeatedMessagesFilterConfigureWindow` uses self-binding (`DataContext="{Binding RelativeSource={RelativeSource Self}}")` and implements `INotifyPropertyChanged` directly on the window class, exposing a `MessageFilterOptions` object whose properties (`SendToJournal`, `MessageLimit`, `TimeLimit`, `BlockedTime`) are bound two-way to Xceed `IntegerUpDown` controls and a checkbox.
Both windows depend only on shared resources (`ClassicAssist.Shared.Resources.Strings`), custom controls (`ClassicAssist.UI.Controls`), value converters (`ClassicAssist.UI.Misc.ValueConverters`), and filter option models (`ClassicAssist.Data.Filters`). No cross-window communication — each dialog owns its own options instance.
@@ -0,0 +1,3 @@
- User-facing text is never hardcoded in XAML; all labels, headers, and tooltips are resolved through `x:Static resources:Strings.<Key>` from `ClassicAssist.Shared.Resources`.
- Dialogs expose their configuration state as a dedicated Options/ViewModel property and bind UI elements two-way to it, rather than reading/writing controls directly in code-behind.
- Command-driven actions (Save, Remove, Add, Close) are wired in XAML via `Command`/`CommandParameter` bindings or attached behaviors instead of Click event handlers.
@@ -0,0 +1 @@
WPF dialog windows for configuring ClassicAssist's in-game message filters, including Cliloc replacement and repeated-message suppression.
@@ -0,0 +1 @@
WPF (System.Windows) with Xceed WPF Toolkit (`xctk:IntegerUpDown`) for numeric input; Expression Blend Interactivity (`http://schemas.microsoft.com/expression/2010/interactivity`) used by `CloseOnClickBehaviour` to close dialogs without code-behind event handlers.
@@ -0,0 +1,10 @@
schema_version: 1
module_path: classic_assist_wpf/main_ui/macros_windows
title: Macros Editor & Command Browser (WPF)
scope:
- ClassicAssist/UI/Views/Macros/
- ClassicAssist/UI/Views/MacrosTabControl.xaml
- ClassicAssist/UI/Views/MacrosTabControl.xaml.cs
source_files: []
depends_on: []
related_to: []
@@ -0,0 +1,5 @@
Two WPF views driven by MVVM in the `ClassicAssist.Shared` assembly:
- `MacrosTabControl.xaml/.cs` is a `UserControl` hosting a left-side list of `MacroEntry` items (new/save/remove/record/play/stop/hotkey binding) and a right-side `ICSharpCode.AvalonEdit.TextEditor` bound to `SelectedItem.Macro`. The code-behind performs view-only initialization: loads the embedded `Python.Dark.xshd` highlighting, scans the executing assembly for public static methods decorated with `CommandsDisplayAttribute` under namespace `*Macros.Commands`, and wires AvalonEdit's completion window on text entry. A `GridSplitter` separates the two panes.
- `MacrosCommandWindow.xaml/.cs` is a standalone `Window` whose `DataContext` is `MacrosCommandViewModel`; it groups command items by `Category` via a `CollectionViewSource` and exposes an Insert button that pushes the selected command into the editor.
- Both views consume shared resources from `ClassicAssist.Shared` (`Strings`, `ShortcutKeys`, `MacroEntry`) and reuse custom controls/behaviors from `ClassicAssist.UI.Controls` and `ClassicAssist.UI.Misc` (e.g. `AvalonEditBehaviour`, `ItemsControlSelectNewEntryBehaviour`, `CloseOnClickBehaviour`).
- Dependency direction: Views → ViewModels (in `ClassicAssist.Shared`) → data model (`ClassicAssist.Data.Macros`); the code-behind only touches AvalonEdit plumbing and never owns business logic.
@@ -0,0 +1,4 @@
- View markup declares its ViewModel as `<xxx.DataContext>` inline and binds through `{Binding ...}` without any code-behind property wiring.
- Button/command bindings use `Mode=OneWay` for the `Command` property so the view cannot accidentally overwrite the VM's command reference.
- UI strings are sourced exclusively from `ClassicAssist.Shared.Resources.Strings` via `x:Static resources:Strings.Xxx` rather than hard-coded literals.
- AvalonEdit editor state is synchronized with the model through reusable `misc:AvalonEditBehaviour` / `misc:AvalonBindingBehaviour` attached behaviors instead of direct TextEditor property access in the VM.
@@ -0,0 +1 @@
WPF UI for browsing, editing, recording and executing ClassicAssist macros, plus a popup window that lists discoverable macro commands for insertion into scripts.
@@ -0,0 +1 @@
WPF + XAML with ICSharpCode.AvalonEdit for syntax-highlighted Python scripting; Expression Blend Interactivity (`i:`) for behaviors; dynamic discovery of macro commands via reflection over `*Macros.Commands` types annotated with `CommandsDisplayAttribute`.
@@ -0,0 +1,10 @@
schema_version: 1
module_path: classic_assist_wpf/main_ui/app_shell_and_settings
title: Main Window Shell & Settings UI
scope:
- ClassicAssist/UI/Views/MainWindow.xaml
- ClassicAssist/UI/Views/AboutControl.xaml
- ClassicAssist/UI/Views/GeneralControl.xaml
source_files: []
depends_on: []
related_to: []
@@ -0,0 +1 @@
Three XAML views form the top-level UI: `MainWindow.xaml` is an `Avalonia.Window` (not WPF — despite the folder name) that instantiates `MainWindowViewModel`, attaches `LoadOptionsOnWindowLoaded` and `WindowResizeBehaviour` via `System.Windows.Interactivity.Behaviors`, and hosts a `TabControl` whose tabs compose sibling user-controls (`GeneralControl`, `OptionsTabControl`, `HotkeysTabControl`, `MacrosTabControl`, `SkillsTabControl`, `AgentsTabControl`, `browser:MacroBrowserControl`, `AboutControl`). Each tab control is a leaf `UserControl` whose `DataContext` is created inline in markup (e.g. `<viewModels:GeneralControlViewModel />`) from the shared `ClassicAssist.Shared` assembly; no code-behind wiring is used. Shared resources (icons, theme brushes) are pulled in by merging `../../Resources/Icons.xaml` and `../../Resources/ResourceDictionary.xaml` into each view's `Window.Resources` / `UserControl.Resources`. All text is localized through `ClassicAssist.Shared.Resources.Strings` static properties rather than hard-coded strings. The module depends outward on `ClassicAssist.UI.Controls`, `ClassicAssist.UI.ViewModels`, `ClassicAssist.UI.Misc`, `ClassicAssist.Browser`, and `ClassicAssist.Shared`; nothing inside this scope references other UI modules.
@@ -0,0 +1,5 @@
- Each view declares its ViewModel directly in XAML via `<viewModels:...ViewModel />` as `DataContext`, avoiding code-behind instantiation.
- Localized UI text is read exclusively through `{x:Static r:Strings.<Key>}` from `ClassicAssist.Shared.Resources`, never hard-coded literals.
- Shared icons and theme brushes are loaded by merging `../../Resources/Icons.xaml` and `../../Resources/ResourceDictionary.xaml` into each view's Resources dictionary.
- Complex interactions (window loading, resize handling, combo-box command binding) are implemented as `Interaction.Behaviors` in `ClassicAssist.UI.Misc` rather than event handlers in code-behind.
- Designer previewability is enabled per-control via `d:DesignInstance` / `d:DesignStyle` so views render with sample data at design time.
@@ -0,0 +1 @@
WPF shell hosting the ClassicAssist main window with a tabbed settings surface (General, Options, Hotkeys, Macros, Skills, Agents, Macro Browser, About) and its About/General view controls.
@@ -0,0 +1 @@
Avalonia UI (XAML + MVVM) targeting Windows, using `System.Windows.Interactivity` for behaviors and `ClassicAssist.Shared` for ViewModels and localized string resources.
@@ -0,0 +1,8 @@
schema_version: 1
module_path: classic_assist_wpf/main_ui
title: Classic Assist WPF Game UI Layer
scope:
- ClassicAssist/UI/Views/
source_files: []
depends_on: []
related_to: []
@@ -0,0 +1 @@
The Views folder is a flat collection of XAML/XAML.cs pairs with no shared base class or MVVM framework — each file owns one window or control. Cross-cutting wiring happens at two levels: (1) `MainWindow.xaml` hosts an `AgentsTabControl` plus a `MacrosTabControl`, which in turn compose the sub-panels under `Agents/` (Organizer, Dress, Counters, Friends, VendorBuy/Sell, Scavenger, Autoloot); (2) top-level dialogs (`ChatWindow`, `DebugWindow`, `GIFRecorderWindow`, `HuePickerWindow`, `ObjectInpectorWindow`, `ActiveObjectsWindow`, `EntityCollectionViewer`, `NewProfileWindow`) are launched by the shell rather than embedded. All children depend on the same ClassicAssist core assemblies for data binding; there is no cross-view messaging contract inside this scope — communication flows through the application service layer outside Views.
@@ -0,0 +1,3 @@
- Every XAML view has a sibling `.xaml.cs` code-behind file; no separate ViewModel classes live under Views.
- Dialog-style windows derive from `RepositionableGumpWindow` to share drag-to-reposition behavior.
- Tabbed surfaces follow the pattern `<XxxTabControl>.xaml` hosting child panels via `<ContentPresenter>` or nested tabs.
@@ -0,0 +1 @@
WPF view layer that wires the main window shell, tabbed settings surface, and all in-game dialog windows for ClassicAssist's Ultima Online client.
@@ -0,0 +1,10 @@
schema_version: 1
module_path: classic_assist_wpf/data_utils
title: Hotkey Commands, Macro Completion & Skill Comparer
scope:
- ClassicAssist/Data/Hotkeys/
- ClassicAssist/Data/Macros/
- ClassicAssist/Data/Skills/
source_files: []
depends_on: []
related_to: []
@@ -0,0 +1,5 @@
Three independent leaf sub-packages with no internal dependencies on each other:
- `Hotkeys/Commands/` — each file is a concrete `HotkeyCommand` subclass decorated with `[HotkeyCommand(Name=..., Category=...)]`, registered by convention at startup; `Execute()` bridges game state (`ClassicAssist.Shared.UO.Commands`, `Engine.Items/Mobiles`) to WPF views in `ClassicAssist.UI.Views` (e.g. `EntityCollectionViewer`, `ChatWindow`, `GIFRecorderWindow`).
- `Macros/PythonCompletionData.cs` — implements `ICSharpCode.AvalonEdit.CodeCompletion.ICompletionData` so the macro editor can offer Python keyword completions.
- `Skills/SkillComparer.cs` — implements `System.Collections.IComparer` over `SkillEntry`, driven by `SkillsGridViewColumn.Enums` and `ListSortDirection`, used by the skills grid view.
Dependency direction is one-way: this module depends on `Shared`, `UI`, and `UO.Objects`; nothing here is depended on by Shared/UI.
@@ -0,0 +1,2 @@
- Hotkey actions are declared as classes deriving from `HotkeyCommand` and marked with the `[HotkeyCommand]` attribute carrying `Name` (and optional `Category`), with logic placed in an overridden `Execute()` method.
- WPF window launchers spin up a new background thread, set `ApartmentState.STA`, construct the window, call `Show()` / `ShowDialog()`, then pump the dispatcher via `Dispatcher.Run()`.
@@ -0,0 +1 @@
Small data-layer utilities: hotkey command implementations that open UI windows, a Python macro completion entry for AvalonEdit, and the skills grid sort comparer.
@@ -0,0 +1,8 @@
schema_version: 1
module_path: classic_assist_wpf/browser
title: Macro Browser WPF Control
scope:
- ClassicAssist/Browser/
source_files: []
depends_on: []
related_to: []
@@ -0,0 +1,8 @@
MVVM layering inside a single WPF UserControl:
- `MacroBrowserControl.xaml/.xaml.cs` is the view; it wires AvalonEdit syntax highlighting (Python.Dark.xshd) and opens hyperlinks via `Process.Start`.
- `MacroBrowserViewModel : BaseViewModel` owns all UI state (`ObservableCollection<string>` for Authors/Eras/Shards/Macros, `Category` filter), exposes `RelayCommand`/`RelayCommandAsync` actions, and drives data loading on construction by invoking a `_data` dictionary of `Func<Task<string[]>>` entries backed by the singleton `Database`.
- `Data/Database` is a thread-safe singleton wrapping an in-process LiteDB file (`macros.db`) with three collections — `repository`, `manifest`, `macros` — plus an `HttpClient` and `GitHubClient`. It fetches `metadata.json` from the repo's raw URL, caches it for 15 minutes (or until the master branch SHA changes), and lazily downloads macro source text keyed by name+SHA1.
- `Models/` holds LiteDB-persisted entities (`Macro`, `Manifest`, `Metadata`, `Repository`) plus a `Category` used as a hierarchical filter value.
- `Data/Filter` + `FilterType` model the shard/era/author/category predicate applied against the manifest before returning macro names.
- `Controls/ClearableComboBox` is a reusable ComboBox extension exposing a `ClearCommand` DP bound to the ViewModel's `ClearCommand`.
Dependency direction: View → ViewModel → Data/Models; Models are pure POCOs decorated with `[BsonId]`; no cross-dependencies between sibling subfolders except ViewModel depending on both Data and Models.
@@ -0,0 +1,5 @@
- UI state properties follow the `SetProperty(ref _field, value)` pattern inherited from `BaseViewModel`, with filter setters additionally calling `ApplyFilter()` to re-query the database.
- Commands are exposed as lazy-initialized read-only properties using `??=` with `new RelayCommand(...)` / `new RelayCommandAsync(...)`, guarded by a can-execute lambda over `SelectedItem`.
- Background work uses `Task.Run` followed by `.ContinueWith` or `_dispatcher.Invoke`/`_dispatcher.InvokeAsync` to marshal results back onto the UI thread before touching `ObservableCollection`s.
- Long-running async operations wrap their body in try/catch/finally that sets `Loading = false` and surfaces errors through `MessageBox.Show` with localized `Strings.Error`.
- LiteDB entities are plain POCOs annotated with `[BsonId]` and stored in collections created via `database.GetCollection<T>("name")` with `EnsureIndex(x => x.Id)`.
@@ -0,0 +1 @@
WPF user control that browses, filters, previews, and installs UO macros from the official ClassicAssist-Macros GitHub repository.
@@ -0,0 +1 @@
WPF with XAML code-behind, MVVM via `ClassicAssist.UI.ViewModels.BaseViewModel` and `RelayCommand`, AvalonEdit for macro preview syntax highlighting, LiteDB for local persistence (`macros.db`), Newtonsoft.Json for deserializing the remote `metadata.json`, and Octokit/GitHub REST API for commit-hash comparison.
@@ -0,0 +1,10 @@
schema_version: 1
module_path: classic_assist_wpf/engine_support
title: WPF Engine Host & UI Abstractions
scope:
- ClassicAssist/Engine.cs
- ClassicAssist/WPFDispatcher.cs
- ClassicAssist/WPFUIInvoker.cs
source_files: []
depends_on: []
related_to: []
@@ -0,0 +1,6 @@
Three cooperating types form the WPF-specific host layer around `ClassicAssist.Shared.Engine`:
- `Engine.cs` (namespace `Assistant`) is the single entry point consumed by the plugin loader. `Install(PluginHeader*)` loads `ClassicAssist.Shared.dll`, subscribes to `AssemblyResolve` to resolve dependencies from `StartupPath` plus the runtime directory (with a special-case rename for `Colletions` → `System.Collections`), then spawns a background STA thread where it constructs `WPFDispatcher`/`WPFUIInvoker`, installs the shared engine via `SEngine.Install(plugin, new WPFMessageBoxProvider())`, hooks `Options.LoadEvent`/`SaveEvent` to serialize/deserialize every `BaseViewModel` implementing `ISettingProvider`, creates `MainWindow`, and runs `Dispatcher.Run()`.
- `WPFDispatcher.cs` implements the cross-platform `IDispatcher` interface by forwarding `Invoke`/`InvokeAsync` to `System.Windows.Threading.Dispatcher`.
- `WPFUIInvoker.cs` implements `IUIInvoker`: `Invoke`/`InvokeDialog<T>` reflectively locate a `Window` subclass by name in the executing assembly, construct it with optional ctor/data-context parameters, set `DataContext`, and show it on the dispatcher thread; `GetHueAsync` spins up its own STA thread to host `HuePickerWindow`; clipboard helpers call `System.Windows.Clipboard` directly.
Dependency direction: this module depends on `ClassicAssist.Shared` (for `SEngine`, `IDispatcher`, `IUIInvoker`, `WPFMessageBoxProvider`) and on the WPF UI project (`ClassicAssist.UI.Views`, `ClassicAssist.UI.ViewModels`, `ClassicAssist.Data`, `ClassicAssist.Misc`, `CUO_API`). The shared engine never references WPF — WPF concerns are isolated behind the two interfaces so the same core can be hosted elsewhere.
@@ -0,0 +1,3 @@
- Cross-thread UI access is always funneled through `IDispatcher.Invoke`/`InvokeAsync` rather than calling WPF APIs directly from background code.
- Window discovery uses string-typed names resolved via `Assembly.GetExecutingAssembly().GetTypes().FirstOrDefault(t => t.Name == typeName && t.IsSubclassOf(typeof(Window)))`, throwing `ArgumentNullException` when not found.
- Optional constructor and data-context parameters are passed through as `object[]` arrays and materialized with `Activator.CreateInstance` at invocation time.
@@ -0,0 +1 @@
Hosts the ClassicAssist WPF application by bootstrapping the shared engine, wiring a WPF dispatcher and UI invoker, and running the main window on an STA thread.
@@ -0,0 +1 @@
WPF (`System.Windows.Threading.Dispatcher`, `System.Windows.Window`, `System.Windows.Clipboard`) as the concrete UI platform; reflection + `Activator.CreateInstance` for string-based window resolution; `TaskCompletionSource` to bridge STA dialog threads into async callers.
@@ -0,0 +1,9 @@
schema_version: 1
module_path: classic_assist_wpf/resources_assets
title: WPF Theme & Embedded Resources
scope:
- ClassicAssist/Resources/
- ClassicAssist/Properties/
source_files: []
depends_on: []
related_to: []
@@ -0,0 +1,6 @@
Two parallel resource tracks coexist in the project:
- WPF XAML resources under `Resources/` are organised as a merged-dictionary chain: `ResourceDictionary.xaml` is the single entry point that merges `DarkTheme.xaml`, which in turn merges `Colours.xaml`. `Icons.xaml` holds all vector icons as `DrawingImage` entries keyed by name (e.g. `unlinkedIcon`, `PythonIcon`, `WebIcon`) and can be merged wherever needed; `LeftRightIconToggleButton.xaml` defines a reusable control template that references those icons. `Shrink.txt` is an embedded text asset.
- .NET ResX resources under `Properties/Resources.resx` + `Resources.Designer.cs` expose strongly-typed `System.Drawing.Bitmap` and string properties (`arrow_down`, `arrow_up`, `padlock`, `python`, `Shrink`) backed by `ResourceManager` lookups. The `.resx` file points at sibling PNGs via relative paths (`..\Resources\*.png`).
Dependency direction is one-way: `DarkTheme.xaml` → `Colours.xaml`; `ResourceDictionary.xaml` → `DarkTheme.xaml`; `Icons.xaml` is standalone and consumed by consumers via merge. No C# code lives in this module — it is purely declarative assets consumed by other assemblies.
@@ -0,0 +1 @@
WPF theme assets for ClassicAssist, providing a dark colour palette, per-control styles, inline DrawingImage icons, and .NET ResX-embedded bitmaps/text.
@@ -0,0 +1,10 @@
schema_version: 1
module_path: classic_assist_wpf/ui_layer
title: WPF UI Controls, Behaviours & Value Converters
scope:
- ClassicAssist/UI/Controls/
- ClassicAssist/UI/Misc/
- ClassicAssist/UI/Models/
source_files: []
depends_on: []
related_to: []
@@ -0,0 +1,6 @@
Three sibling sub-packages with a flat dependency direction (UI → Core/Misc, never the reverse):
- `Controls/` — self-contained `UserControl`s (`CustomWindowTitleControl`, `HueEntryControl`, `HexDumpControl`, `EditTextBlock`, `TextBoxKey`) plus a layout helper (`StretchyWrapPanel`). Each control exposes its bindable surface via `DependencyProperty` + CLR wrapper pairs.
- `Misc/` — behaviour/utility layer split into three groups: (1) `System.Windows.Interactivity.Behavior<T>` subclasses (`AvalonEditBehaviour`, `AutoScrollBehaviour`, `WindowResizeBehaviour`, `ItemsControlSelectNewEntryBehaviour`, …) that attach to existing WPF elements without subclassing; (2) `ValueConverters/` implementing `IValueConverter` for data-binding transformations, with `ValueConverterGroup` enabling chained conversion in XAML; (3) markup extensions (`EnumBindingSourceExtension`) and cross-cutting helpers (`BindingProxy`, `ClipboardBehaviour`, `WPFMessageBoxProvider` which implements `IMessageBoxProvider` from `ClassicAssist.Misc` to bridge WinForms `MessageBox` into the app's abstraction).
- `Models/` — tiny INotifyPropertyChanged view-model fragments (`EntityCollectionFilter`, `EntityCollectionSortStyle`) that encapsulate filter/sort state consumed by list/grid views.
No MVVM framework is used; binding relies on standard WPF `INotifyPropertyChanged` and `DependencyObject`. The only external runtime dependencies are `System.Windows.Interactivity` (for `Behavior<T>`) and `ICSharpCode.AvalonEdit` (for `TextEditor`), while higher-level abstractions like `IMessageBoxProvider` keep this leaf decoupled from concrete message-box implementations.
@@ -0,0 +1,4 @@
- Public bindable properties are exposed as `static readonly DependencyProperty` registered with `FrameworkPropertyMetadata(..., FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)` plus a thin CLR wrapper that calls `GetValue`/`SetValue`.
- Attached behaviours extend third-party controls by subclassing `System.Windows.Interactivity.Behavior<T>` and wiring/unwiring events inside `OnAttached`/`OnDetaching` rather than subclassing the target control.
- View-models implement `INotifyPropertyChanged` through a shared `SetProperty(ref T obj, T value, [CallerMemberName])` helper that also calls `CommandManager.InvalidateRequerySuggested()` to refresh bound commands.
- XAML-only helpers live as paired `.xaml` + `.xaml.cs` files where the code-behind contains only the `InitializeComponent` constructor and property wrappers, keeping logic in attached behaviours or converters.
@@ -0,0 +1 @@
Reusable WPF presentation primitives — custom controls, attached behaviours, markup extensions, value converters, and lightweight view-model helpers used by ClassicAssist's XAML views.
@@ -0,0 +1 @@
WPF with `System.Windows.Interactivity` for attached behaviours, `ICSharpCode.AvalonEdit` for code editing, and `System.Windows.Forms.MessageBox` (via `WPFMessageBoxProvider`) as the concrete message-box implementation.
@@ -0,0 +1,8 @@
schema_version: 1
module_path: classic_assist_wpf
title: Classic Assist WPF Application Host
scope:
- ClassicAssist/
source_files: []
depends_on: []
related_to: []
@@ -0,0 +1 @@
The `Engine.Install` entry point is the single cross-child wiring point: it loads `ClassicAssist.Shared.dll`, registers a `WPFDispatcher`/`WPFUIInvoker` on `SEngine`, installs `WPFMessageBoxProvider`, subscribes to `Options.LoadEvent`/`SaveEvent` to persist every `BaseViewModel` implementing `ISettingProvider`, then creates `MainWindow` on an STA thread. `WPFUIInvoker` exposes `IUIInvoker.Invoke`/`InvokeDialog` so the shared engine can open any `Window` subclass by name with optional DataContext — this is how hotkey commands in `Data/Hotkeys/Commands` (e.g. `ShowChatWindowCommand`, `ShowGIFCaptureWindow`) and other engine code trigger UI across the `main_ui`, `agents`, and `browser` view modules. All XAML resources are merged centrally via `Resources/ResourceDictionary.xaml` (dark theme, icons, colours), consumed uniformly by every child's Views. The project is split into presentation concerns (`Browser`, `UI/*`, `Agents`, `Main Window`) plus thin data helpers (`Data/Hotkeys`, `Data/Macros`, `Data/Skills`) that depend only on the shared engine abstractions rather than each other.
@@ -0,0 +1 @@
WPF application host that boots the shared engine, wires STA-threaded UI primitives, and composes the main window shell from tabbed agent, macro, skills, and debug views.
@@ -0,0 +1,8 @@
schema_version: 1
module_path: classic_assist_avalonia
title: ClassicAssist Avalonia Desktop UI
scope:
- ClassicAssist.Avalonia/
source_files: []
depends_on: []
related_to: []
@@ -0,0 +1 @@
Entry point `Program.Main` builds an `AppBuilder` configured with `UsePlatformDetect`, `LogToTrace`, and `UseReactiveUI`; `App.OnFrameworkInitializationCompleted` creates the root `MainWindow` with a `MainWindowViewModel` and wires it into `Assistant.Engine.MainWindow`. The module is loaded as a plugin by the core engine: `Engine.Install` (in the `Assistant` namespace) loads `ClassicAssist.Shared.dll` via `Assembly.LoadFile`, subscribes to `Options.SaveEvent`/`LoadEvent` to serialize/deserialize every `BaseViewModel` implementing `ISettingProvider`, then calls `LoadUI`. `LoadUI` branches on `SEngine.GetPlatformType()`: on Unix it starts the Avalonia app on a background thread; otherwise it calls `SetupWithoutStarting()` so the core can set `SEngine.Dispatcher = new AvaloniaDispatcher(Dispatcher.UIThread)` and `SEngine.UIInvoker = new AvaloniaUIInvoker(...)` before showing windows. `AvaloniaUIInvoker` implements `IUIInvoker` using reflection to construct `Window` subclasses by name, exposing `Invoke`, `InvokeDialog<T>`, `GetHueAsync`, and clipboard access through `IClipboard`. Views live under `Views/` (root windows plus `Agents/` tabbed sub-views), each paired with a `.axaml.cs` code-behind; reusable widgets are in `Controls/` (e.g. `GroupBox` extending `HeaderedContentControl` with a XAML theme); shared helpers (`Misc/`) provide behaviors, value converters, and the `AvaloniaMessageBoxProvider`. Dependencies flow one-way: this module depends on `ClassicAssist.Shared`, `ClassicAssist.Data`, `ClassicAssist.Misc`, and `ClassicAssist.UI.ViewModels`; the core never references Avalonia types directly — it only sees the `IDispatcher`/`IUIInvoker`/`IMessageBoxProvider` abstractions.
@@ -0,0 +1,4 @@
- Each view/window follows the `.axaml` + `.axaml.cs` split where the code-behind constructor simply calls `InitializeComponent()` and leaves logic to the ViewModel.
- Cross-thread UI marshalling goes exclusively through `SEngine.Dispatcher.Invoke` / `InvokeAsync` rather than direct `Dispatcher` usage in business code.
- User-facing dialogs are surfaced to the core via `IUIInvoker.Invoke`/`InvokeDialog<T>` by type-name reflection instead of direct window construction from non-UI assemblies.
- Persistent settings are implemented by having ViewModels implement `ISettingProvider` and registering handlers on `Options.SaveEvent`/`LoadEvent` to iterate `BaseViewModel.Instances`.
@@ -0,0 +1 @@
Avalonia-based desktop shell that hosts ClassicAssist's ReactiveUI MVVM views, custom controls, and cross-platform windowing/clipboard integration.
@@ -0,0 +1 @@
Avalonia UI with ReactiveUI for MVVM binding; embedded AvaloniaEdit binaries (`AvaloniaEdit.dll/.pdb`) ship with the package; Linux uses a dedicated background thread for the Avalonia loop while Windows initializes inline via `SetupWithoutStarting()`.
@@ -0,0 +1,8 @@
schema_version: 1
module_path: launcher
title: ClassicAssist Launcher (WPF)
scope:
- ClassicAssist.Launcher/
source_files: []
depends_on: []
related_to: []
@@ -0,0 +1,7 @@
- Single WPF WinExe project (`net48`, `UseWPF=true`) whose entry point is `App.xaml.cs`; it bootstraps Exceptionless telemetry before showing the main window.
- MVVM layout: `BaseViewModel` provides `INotifyPropertyChanged` plus two in-process `ICommand` implementations (`RelayCommand`, `RelayAsyncCommand`). Each screen has a XAML view + code-behind window paired with a ViewModel (`MainViewModel`, `OptionsViewModel`, `ShardsViewModel`).
- `MainViewModel` owns the application lifecycle: reads/writes `Launcher.json` via Newtonsoft.Json, manages `ClientPaths`/`DataPaths`/`Plugins` collections, resolves shard hostnames through `Utility.ResolveAddress`, and finally `Process.Start`s `ClassicUO.exe` with `-plugins`, `-ip`, `-port`, `-uopath`, `-encryption`, `-shard` arguments. On exit it persists state back to JSON.
- Shard configuration is split between built-in presets in the singleton `ShardManager` (double-checked-lock single instance) and user-defined entries persisted in `Launcher.json`; `ShardsWindow` / `ShardsViewModel` edit them.
- ClassicUO launch flags are driven by reflection over `ClassicOptions`: each property is annotated with `ClassicOptionAttribute` (argument name, default value, conditional include rules), which both `ReadClassicOptions` (load from JSON) and `BuildClassicOptions` (emit CLI args) consume.
- UI helpers live in `Behaviours/` (WPF Interactivity behaviours), `Controls/EditTextBlock` (custom control), and `ValueConverters/` (boolean/cell-width converters). Resources are localized via `.resx` files under `Properties/`.
- Dependency direction: Views → ViewModels → `ShardManager`/`Utility`/`ClassicOptions`; no cross-viewmodel references except when one window passes its ViewModel into another (e.g. `ShowOptionsWindow` constructs `OptionsViewModel` with shared `Plugins`/`ClassicOptions`).
@@ -0,0 +1,5 @@
- ViewModels inherit `BaseViewModel` and expose properties via `SetProperty(ref _field, value)` so that `CommandManager.InvalidateRequerySuggested` is automatically called on change.
- User actions are bound to `ICommand` properties implemented as lazy-initialized `RelayCommand`/`RelayCommandAsync` fields, with optional `canExecute` predicates passed at construction.
- ClassicUO command-line flags are declared declaratively on `ClassicOptions` properties using `[ClassicOption(...)]` attributes rather than hard-coded string literals, and consumed uniformly via reflection in `ReadClassicOptions`/`BuildClassicOptions`.
- Per-user configuration is serialized/deserialized manually against `Newtonsoft.Json.Linq.JObject`/`JArray` instead of using POCO serialization, with explicit field-by-field read/write paths in `MainViewModel.Closing` and the constructor.
- Singleton services (e.g. `ShardManager`) use double-checked locking with a static `_lock` object exposed through a `GetInstance()` factory method.
@@ -0,0 +1 @@
WPF launcher that configures and starts ClassicUO clients with per-shard settings, plugin loading, and an options dialog for ClassicUO command-line flags.
@@ -0,0 +1 @@
.NET Framework 4.8 WPF; Newtonsoft.Json for JSON persistence; Trinet.Core.IO.Ntfs for NTFS alternate data stream cleanup; System.Windows.Interactivity.WPF for XAML behaviours; Exceptionless for crash reporting.
@@ -0,0 +1,8 @@
schema_version: 1
module_path: shared_core/data_subsystems
title: Shared Game Data & Assistant Subsystems
scope:
- ClassicAssist.Shared/Data/
source_files: []
depends_on: []
related_to: []
@@ -0,0 +1,9 @@
Organized as a flat `ClassicAssist.Shared/Data` tree where each feature area is its own sub-namespace (Hotkeys, Macros, Filters, Autoloot, Dress, Organizer, Scavenger, Skills, Spells, Abilities, Targeting, Chat, Vendors, Regions, BuffIcons, Counters, SpecialMoves, Commands, Friends) plus shared root types (`Options`, `AssistantOptions`, `JournalEntry`, `Language`, `Extension`, `Crypter`).
- Each subsystem follows a Manager + Entry pattern: a singleton `*Manager` class exposes an `ObservableCollectionEx<T>` of typed entries (e.g. `HotkeyManager.Items`, `MacroManager.Items`, `AutolootManager`, `DressManager`, `ScavengerManager`, `SkillManager`, `SpellManager`, `AbilitiesManager`, `BuffIconManager`, `CountersManager`, `VendorBuyAgentEntry`/`VendorSellAgentEntry`) and owns lifecycle / persistence.
- Hotkeys and Macros are the two execution engines: `HotkeyManager` reads SDL2 via P/Invoke to intercept keyboard/mouse events and dispatches `HotkeyEntry.Action`; `MacroManager` uses reflection to discover all `IMacroCommandParser` implementations at construction time, subscribes to `Engine.PacketReceivedEvent`/`PacketSentEvent` for macro recording, and runs `MacroEntry` instances on dedicated threads via `MacroInvoker`.
- Macro commands live in `Macros/Commands/` and are discovered by name; help text and categories come from resource strings consumed by `CommandsDisplayAttribute`.
- Filter pipeline is driven by the `IConfigurableFilter` interface with `Serialize`/`Deserialize`/`Configure`/`ResetOptions`, implemented by `ClilocFilter`, `LightLevelFilter`, `SeasonFilter`, `WeatherFilter`, `BardsMusicFilter`, `RepeatedMessagesFilter`, and `DynamicFilterEntry`.
- Static game data tables are embedded JSON files at the root (`Bodies.json`, `Spells.json`, `Weapons.json`, `Properties.json`, `Regions.json`, `MountID.json`, `Masteries.json`, `BuffIcons.json`) consumed by their respective managers.
- Profile persistence is centralized in `Options.cs`: `Options.Load`/`Save` emit `LoadEvent`/`SaveEvent` that individual subsystems subscribe to, and profiles are stored under a `Profiles/` directory next to the executable.
- Cross-cutting helpers: `Crypter` provides machine-name XOR encryption used by some persisted entries; `Extension` holds shared LINQ/string helpers.
@@ -0,0 +1,6 @@
- Each subsystem exposes a singleton manager accessed through a static `GetInstance()` method with double-checked locking, holding an `ObservableCollectionEx<T>` of entry objects.
- UI-bindable properties use a private backing field plus a `SetProperty(ref _field, value)` helper that calls `OnPropertyChanged`, decorated with `[NotifyPropertyChangedInvocator]` from `ClassicAssist.Annotations`.
- Persisted configuration entries implement a `Serialize()` returning a `JObject` and a `Deserialize(JToken)` constructor or method so they round-trip through `Newtonsoft.Json.Linq`.
- Pluggable command/filter types are discovered at runtime via reflection over `Assembly.GetExecutingAssembly().GetTypes()` filtered by a marker interface (`IMacroCommandParser`, `IConfigurableFilter`).
- Macro command metadata is attached with attributes (`CommandsDisplayAttribute`, `CommandsDisplayStringSeeAlsoAttribute`) whose values are resolved from localized resource strings rather than hard-coded.
- Cross-subsystem coordination goes through static events on `Options` (`LoadEvent`, `SaveEvent`) and `Engine` packet hooks (`PacketReceivedEvent`, `PacketSentEvent`) instead of direct coupling between managers.
@@ -0,0 +1 @@
Shared data layer providing hotkeys, macros, filters, autoloot, dress/organizer/scavenger agents, skills/spells/abilities, targeting, chat, vendors, and profile-based settings for the ClassicAssist client.
@@ -0,0 +1 @@
C# with Newtonsoft.Json (`JObject`/`JToken`) for profile and filter serialization; SDL2 via `[DllImport("SDL2.dll")]` for low-level key state polling; `System.ComponentModel.INotifyPropertyChanged` + `CallerMemberName` for UI-bound options; resource-driven localization via `ResourceManager` for macro command help.
@@ -0,0 +1,10 @@
schema_version: 1
module_path: shared_core/misc_helpers
title: Shared Primitives, Threading & Cross-Platform Utilities
scope:
- ClassicAssist.Shared/Misc/
- ClassicAssist.Shared/Helpers/
- ClassicAssist.Shared/Engine/
source_files: []
depends_on: []
related_to: []
@@ -0,0 +1,7 @@
Three sibling folders under ClassicAssist.Shared expose a flat set of reusable types consumed by both WPF and Avalonia UI projects:
- `Misc/` — the largest folder; holds cross-cutting primitives: key-code enums (`Keys`, `SDLKeys`) with an SDL↔WPF mapping table, display/formatting helpers (`DisplayFormatAttribute`, `HexFormatProvider`, `PropertyArrayFormatProvider`), `EntityComparers` implementing `IComparer<Entity>` for UO objects, threading primitives (`CircularBuffer<T>`, `ThreadQueue<T>`, `ThreadPriorityQueue<T>` backed by `Priority_Queue.SimplePriorityQueue`), interop (`NativeMethods.GetWindowRect`, `ExtensionMethods.DeleteObject` via gdi32/user32), and small utilities (`Utility`, `OffsetStopwatch`).
- `Helpers/Reflection.cs` — thin static helper that reads properties from types discovered through `Engine.ClassicAssembly`, used to resolve plugin/engine types at runtime.
- `Engine/` — partial-class extensions on the host `ClassicAssist.Shared.Engine` type: `Filters.cs` adds send/receive `PacketFilterInfo` registration methods (pre/post/incoming) against internal filter lists, and `PlatformDetector.cs` lazily detects Windows/Linux/macOS via `RuntimeInformation` and exposes it as `PlatformType`.
Dependency direction is one-way outward: this module depends on `ClassicAssist.Data`, `ClassicAssist.UO.Objects`, `ClassicAssist.UO.Network.PacketFilter`, and `ClassicAssist.Shared` (for `Engine` / `ClassicAssembly`), but nothing in those packages depends back on Misc/Helpers/Engine. The two provider interfaces (`ISettingProvider`, `IMessageBoxProvider`) plus their shared DTOs (`SharedWindow`, `MessageBoxResult`, etc.) are the only abstraction boundaries meant to be implemented by the WPF/Avalonia host projects.
@@ -0,0 +1,5 @@
- Cross-platform abstractions are exposed as interfaces (`ISettingProvider`, `IMessageBoxProvider`) with plain DTO structs/enums (`SharedWindow`, `MessageBoxResult`, `MessageBoxImage`, `MessageBoxButtons`) so WPF and Avalonia hosts can provide implementations without sharing UI code.
- Key input is modeled as parallel enum sets (`Keys`, `SDLKeys.SDL_Keycode`, `SDL_Scancode`) bridged by a static `INTERNAL_keyMap` dictionary and helper methods like `SDLKeyToKeys` rather than direct casting.
- Background work is dispatched through disposable queue wrappers (`ThreadQueue<T>`, `ThreadPriorityQueue<T>`) that own a background `Thread`, signal it via an `AutoResetEvent`, and terminate by enqueuing a sentinel `default` item before joining.
- P/Invoke and native resource handling are isolated in dedicated files (`NativeMethods.cs`, `ExtensionMethods.DeleteObject`) using `[DllImport]` + `[StructLayout(LayoutKind.Sequential)]` instead of scattered inline calls.
- Engine extension points are added as `partial class Engine` members in separate files (`Engine/Filters.cs`, `Engine/PlatformDetector.cs`) rather than modifying the core engine source.
@@ -0,0 +1 @@
Cross-cutting primitives (key codes, display formatting, entity comparers), thread-safe queues and buffers, P/Invoke helpers, reflection utilities, and shared Engine extension points for packet filters and platform detection.
@@ -0,0 +1 @@
C# targeting .NET Standard-style shared code; uses Newtonsoft.Json.Linq for JSON serialization contracts, Priority_Queue NuGet package for `SimplePriorityQueue<T>`, and System.Runtime.InteropServices for user32/gdi32 P/Invoke.
@@ -0,0 +1,8 @@
schema_version: 1
module_path: shared_core/resources
title: Shared UI Resources & Localization
scope:
- ClassicAssist.Shared/Resources/
source_files: []
depends_on: []
related_to: []

Some files were not shown because too many files have changed in this diff Show More