first commit
This commit is contained in:
+8
@@ -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: []
|
||||
+9
@@ -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.
|
||||
+6
@@ -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.
|
||||
+1
@@ -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.
|
||||
+1
@@ -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.
|
||||
+10
@@ -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: []
|
||||
+7
@@ -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.
|
||||
+5
@@ -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.
|
||||
+1
@@ -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.
|
||||
+1
@@ -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.
|
||||
+8
@@ -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: []
|
||||
+1
@@ -0,0 +1 @@
|
||||
Two parallel StronglyTypedResourceBuilder-generated classes expose the content: `Strings` (UI labels, messages, settings keys) and `MacroCommandHelp` (per-command DESCRIPTION/INSERTTEXT/EXAMPLE entries). Each class is auto-generated from a base `.resx` plus per-culture `.resx` variants (`en-AU`, `en-GB`, `it-IT`, `ko-KR`, `pl-PL`, `zh`) and exposes a static `ResourceManager` + `Culture` property so callers override `CurrentUICulture` to switch languages. Non-string assets (`.png` icons like `arrow_up.png`, `dialog-error.png`, `python.png`; `.wav` sound `kiss.wav`) are shipped alongside as embedded resources under the same namespace. The only consumer-facing surface is the two generated classes in `ClassicAssist.Shared.Resources`; there is no runtime code of its own.
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
- Each logical resource group lives in its own `<Name>.Designer.cs` / `<Name>.resx` pair (e.g. `Strings` for UI text, `MacroCommandHelp` for command docs), keeping namespaces flat under `ClassicAssist.Shared.Resources`.
|
||||
- Per-language variants are added by copying the base `.resx` and renaming it with a culture suffix (`en-AU.resx`, `it-IT.resx`, etc.) rather than using separate folders or satellite assemblies.
|
||||
- Macro command help entries follow a fixed triple-key convention per command: `<CMD>_COMMAND_DESCRIPTION`, `<CMD>_COMMAND_INSERTTEXT`, and optionally `<CMD>_COMMAND_EXAMPLE`, all uppercase with underscores.
|
||||
+1
@@ -0,0 +1 @@
|
||||
Centralized .NET resource bundle providing localized strings, macro command help text, and embedded UI assets (icons, sounds) consumed by ClassicAssist.Shared.
|
||||
+1
@@ -0,0 +1 @@
|
||||
.NET `System.Resources.ResourceManager` with Visual Studio ResX designer; strong-typed accessors generated by `StronglyTypedResourceBuilder` (v16.0.0.0).
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
schema_version: 1
|
||||
module_path: shared_core/ui_layer
|
||||
title: Shared UI ViewModels & MVVM Primitives
|
||||
scope:
|
||||
- ClassicAssist.Shared/UI/
|
||||
source_files: []
|
||||
depends_on: []
|
||||
related_to: []
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
The module is a pure ViewModel layer with no XAML or platform-specific views. It is organized by feature:
|
||||
- `ViewModels/BaseViewModel.cs` extends ReactiveUI's `ReactiveObject`, owns an `IDispatcher` from `Engine.Dispatcher`, exposes `SetProperty<T>` wrapping `RaiseAndSetIfChanged`, and registers itself in a static `_viewModels` registry (`BaseViewModel.Instances`).
|
||||
- `OptionsBindingAttribute` + `OnOptionChanged` reflection loop automatically sync any property marked `[OptionsBinding(Property = "...")]` to the matching `Options.CurrentOptions` property whenever `Options` raises `PropertyChanged`.
|
||||
- Two command implementations: synchronous `RelayCommand` and async `RelayCommandAsync` both implementing `ICommand`; many view models also use `ReactiveCommand.Create/FromTask` from System.Reactive.
|
||||
- Feature sub-folders mirror ClassicAssist agent/tab concepts: `Agents/` (Autoloot, Counters, Dress, Friends, Organizer, Scavenger, VendorBuy/Sell), `Autoloot/` (ClilocSelection, CustomProperties, PropertySelection), plus top-level tabs like `HotkeysTabViewModel`, `SkillsTabViewModel`, `MacrosTabViewModel`, `GeneralControlViewModel`, `AboutControlViewModel`, `DebugViewModel`, `MainWindowViewModel`, `NewProfileViewModel`, `ObjectInspectorViewModel`, `OptionsTabViewModel`, `RepositionableGumpViewModel`.
|
||||
- `Misc/` holds cross-cutting helpers: `ObservableCollectionEx<T>` that re-emits collection changes when contained `INotifyPropertyChanged` items change, `EnumDescriptionTypeConverter`, `PacketEntry`, and the `OptionsBindingAttribute`.
|
||||
- `Models/ObjectInspectorData.cs` is a simple data class used by the object inspector view model.
|
||||
Dependency direction is one-way: this module depends on `ClassicAssist.Data`, `ClassicAssist.Shared`, `ClassicAssist.UO.*`, and `ClassicAssist.Misc` services via static singletons (`Engine`, `Commands`, `DressManager`, `Options.CurrentOptions`) but has no dependency back into the host UI project.
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
- View-model properties are exposed as public get/set backed by private fields and updated through `SetProperty(ref _field, value)` rather than direct assignment, so ReactiveUI change notifications propagate to bindings.
|
||||
- Long-running actions are exposed as `ICommand` properties lazily initialized to either `RelayCommand`/`RelayCommandAsync` or `ReactiveCommand.Create/FromTask`, with `canExecute` predicates wired to selected-item observables.
|
||||
- Asynchronous operations set a boolean flag (e.g. `IsDressingOrUndressing`) around the await and reset it in a `finally` block to keep the UI enabled/disabled state consistent.
|
||||
- Command handlers perform early `if (!(arg is T)) return;` guards before casting the parameter, instead of relying on `canExecute` alone.
|
||||
- Feature view models implement `ISettingProvider` and provide `Serialize(JObject)` / `Deserialize(JObject, Options)` methods that read/write their settings using helper methods like `SetJsonValue`/`GetJsonValue` against `JToken`s.
|
||||
- Properties that should mirror `Options.CurrentOptions` are decorated with `[OptionsBinding(Property = "Xxx")]` and rely on `BaseViewModel.OnOptionChanged` reflection to push values from `Options` into the view model.
|
||||
+1
@@ -0,0 +1 @@
|
||||
Avalonia/MVVM view-model layer for ClassicAssist providing shared base classes, command helpers, options auto-binding, and per-feature tab view models (agents, autoloot, hotkeys, skills, etc.).
|
||||
+1
@@ -0,0 +1 @@
|
||||
ReactiveUI (`ReactiveObject`, `WhenAnyValue`, `ReactiveCommand`) combined with WPF-style `System.Windows.Input.ICommand` for commands; JSON persistence via Newtonsoft.Json `JObject`/`JArray`.
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
schema_version: 1
|
||||
module_path: shared_core/uo_networking_objects_data/data
|
||||
title: UO Client Data & Gump Utilities
|
||||
scope:
|
||||
- ClassicAssist.Shared/UO/Data/
|
||||
source_files: []
|
||||
depends_on: []
|
||||
related_to: []
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
Two internal sub-packages with distinct responsibilities:
|
||||
- `ClassicAssist.UO.Data` (root): static singletons (`MapInfo`, `TileData`, `Statics`, `Cliloc`, `Hues`, `RehueList`, `Art`) that lazily load UO client data from a shared `_dataPath`. Each singleton exposes an `Initialize(string)` entry point called once at startup; tile/land/static arrays are cached via `Lazy<T>` and indexed by block coordinates derived from the per-map size table. `Map.GetLandTile` / `Statics.GetStatics` resolve offsets into `.mul` files or `.uop` archives via `UOPIndex.Lookup`; `Map.GetMapSurface` composes land + static tiles to compute surface Z.
|
||||
- `ClassicAssist.UO.Data.Gumps`: UI-side extensions built on top of `ClassicAssist.UO.Objects.Gumps.Gump`. `RepositionableGump` is an abstract base adding a reposition button and X/Y persistence; concrete gumps (`BoatMovementGump`, `MacrosGump`, `WeaponAbilitiesGump`, `ConfirmPromptGump`, `UpdateMessageGump`) register themselves as `IExtension` implementations and react to server events (e.g. journal entries). A nested `Packets` folder holds packet builders such as `Pathfind` that wrap `PacketWriter`.
|
||||
Dependency direction: gumps depend on networking (`ClassicAssist.UO.Network.Packets`) and the engine dispatcher, while data readers depend only on `System.IO` and the shared `Engine.Player` for Z calculations — no cross-dependency between the two sub-packages except through those shared types.
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
- Each data reader is a static class exposing a one-shot `Initialize(string dataPath)` followed by lazy-loaded caches (`Lazy<T>`) keyed by map index.
|
||||
- Block-based spatial indexing uses the shared `_defaultMapSize[map,1]` table together with `x/8` and `y/8` cell math to compute linear block offsets into mul/uop files.
|
||||
- Gump classes extend `ClassicAssist.UO.Objects.Gumps.Gump` and wire behavior by overriding `OnResponse` and/or registering event handlers inside an `IExtension.Initialize()` method.
|
||||
- File paths are always resolved through `Path.Combine(_dataPath, ...)` rather than hard-coded absolute paths, allowing the client data directory to be injected at runtime.
|
||||
+1
@@ -0,0 +1 @@
|
||||
Reads Ultima Online client data files (tiledata.mul, map*.mul/statics*.mul, Cliloc.enu) and provides in-game gump helpers for the ClassicAssist Shared layer.
|
||||
+1
@@ -0,0 +1 @@
|
||||
Pure .NET `System.IO.BinaryReader`/`MemoryStream` parsing of UO's legacy `.mul` format plus the newer `.uop` archive format (via `UOPIndex`); strings parsed as ASCII/UTF8/Unicode depending on the file spec.
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
schema_version: 1
|
||||
module_path: shared_core/uo_networking_objects_data/network
|
||||
title: UO Network Packet I/O, Dispatch & Filtering
|
||||
scope:
|
||||
- ClassicAssist.Shared/UO/Network/
|
||||
source_files: []
|
||||
depends_on: []
|
||||
related_to: []
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
Two parallel registries drive the stack: `IncomingPacketHandlers` and `OutgoingPacketHandlers` each own a fixed-size `PacketHandler[] _handlers` (0x100) plus an `_extendedHandlers` array for Sphere IDs > 255. `Initialize()` registers every known packet ID → handler delegate via static `Register`/`RegisterExtended`, so routing is a direct array lookup by the first byte.
|
||||
|
||||
- `Packets/BasePacket` + one class per outgoing packet type (`CastSpell`, `UseTargetedItem`, `GumpButtonClick`, …) encapsulate serialization through a shared `PacketWriter`; many also implement `IMacroCommandParser` so the same class can turn raw bytes back into human-readable macro text.
|
||||
- Incoming packets are parsed in-place with `PacketReader` inside `On*` methods; state mutations touch `Engine.*` singletons (`Engine.Items`, `Engine.Mobiles`, `Engine.Gumps`, `Engine.Player`) and raise typed events (`MobileUpdatedEvent`, `GumpEvent`, …) consumed elsewhere.
|
||||
- A two-stage filter pipeline sits between the socket and the handler registry:
|
||||
- `IncomingPacketFilters` holds a `Dictionary<byte, OnReceive>` of early interceptors (repeated-message suppression, rehue filtering, SA world-item rewrite). Returning `true` short-circuits normal dispatch and may enqueue a modified copy on `Engine.IncomingQueue` or manually invoke the real handler (`GetHandler(id)?.OnReceive(...)`).
|
||||
- `PacketFilter` / `PacketFilterCondition` / `PacketFilterInfo` provide a separate match-on-byte-sequence engine used by dynamic filters and macro recording; it matches on packet ID plus position/length byte slices rather than full deserialization.
|
||||
- `ActionPacketQueue` / `ActionPacketQueueItem` buffer outgoing action packets (movement, use, drop) to throttle server load.
|
||||
- Dependency direction is one-way outward: this module depends on `ClassicAssist.UO.Data`, `ClassicAssist.UO.Objects`, `ClassicAssist.Shared`, and `Sentry`; nothing in the rest of the codebase depends on individual packet classes — only on the `IncomingPacketHandlers`/`OutgoingPacketHandlers` event surface.
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
- Each incoming/outgoing packet gets its own file under `Packets/` named after the UO opcode verb (e.g. `CastSpell.cs`, `ContainerContentsPacket.cs`).
|
||||
- Outgoing packet types derive from `BasePacket` and build their payload by writing directly to the protected `_writer` field rather than returning a pre-built buffer.
|
||||
- Incoming handlers follow the `static void OnXxx(PacketReader reader)` naming convention and mutate `Engine.*` singletons instead of returning values.
|
||||
- Registration is done as a flat list of `Register(0xHH, expectedLength, OnXxx)` calls inside a single `Initialize()` method, keeping the dispatch table explicit and editable.
|
||||
- Macro-friendly packets additionally implement `IMacroCommandParser.Parse(byte[], int, PacketDirection)` so the same class can both serialize and reverse-parse into macro text.
|
||||
+1
@@ -0,0 +1 @@
|
||||
Classic Ultima Online client network layer that serializes/deserializes UO packets, dispatches them to handlers, and applies pre/post filters for macro recording and packet suppression.
|
||||
+1
@@ -0,0 +1 @@
|
||||
C# with raw `byte[]` wire format; uses custom `PacketReader`/`PacketWriter` from `ClassicAssist.UO.Data` instead of a binary serializer; extended UO protocol IDs (>0xFF) handled via a separate `_extendedHandlers` table.
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
schema_version: 1
|
||||
module_path: shared_core/uo_networking_objects_data/objects
|
||||
title: UO World Object Model & Gump Serialization
|
||||
scope:
|
||||
- ClassicAssist.Shared/UO/Objects/
|
||||
source_files: []
|
||||
depends_on: []
|
||||
related_to: []
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
Two parallel hierarchies live under `ClassicAssist.UO.Objects`:
|
||||
- World objects: abstract `Entity` (`Serial`, `X/Y/Z`, `Hue`, `ID`, `Name`, `Properties`) is extended by `Item` (container/owner chain, `Layer`, `Count`, `ArtDataID`) and `Mobile` (HP/mana/stamina, `Status` flags, equipment layers via `_layerArray`, pets). Each has a sibling `*Collection` (`ItemCollection`, `MobileCollection`, `GumpCollection`, `MenuCollection`) that indexes instances by serial and exposes `GetItem`/`GetMobile` lookups into the global `Engine.Items` / `Engine.Mobiles` registries.
|
||||
- UI objects: a flat `Gump` class owns `GumpElement[]` plus optional `GumpPage[]` children; elements are identified by an `ElementType` enum and serialized through an internal `IGumpWriter` / `GumpWriter` pipeline that emits the ASCII layout protocol (packet ID `0xB0`) using `PacketWriter`. A separate `GumpParser` reconstructs gumps from incoming packets.
|
||||
- Cross-cutting: `Property` represents server-side property blocks attached to any entity; `Packet` wraps raw byte buffers with `GetPacketID()` for dispatch. Dependency direction is inward — world objects reach out to `Engine.Player`, `Engine.Items`, `Engine.Mobiles`, and `Commands` only at runtime, keeping this module a pure data/serialization layer consumed by networking and UI code.
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
- World-entity identity is based on `Serial`; `Equals`/`GetHashCode` compare solely on serial, making entities hashable by their UO serial number.
|
||||
- Display formatting is declared via `[DisplayFormat(typeof(...))]` attributes on properties (e.g. `HexFormatProvider`, `PropertyArrayFormatProvider`) so the same model can drive both debug output and UI grids.
|
||||
- Each world-object type has a matching `*Collection` class that acts as a serial-indexed registry, accessed through `Engine.Items.*` / `Engine.Mobiles.*` singletons rather than direct construction.
|
||||
- Gump UI is built declaratively: `Gump.Add*` factory methods construct `GumpElement` records with a `Type` discriminator, which are later dispatched in `GumpElement.AppendTo` by `ElementType` switch to emit the correct layout token.
|
||||
- String literals used in the gump layout protocol are pre-converted to `byte[]` via `StringToBuffer` and reused as static constants to avoid per-packet allocations.
|
||||
+1
@@ -0,0 +1 @@
|
||||
Defines the in-memory model for Ultima Online entities (entities, items, mobiles, menus, gumps) and serializes client-facing packets such as gump layouts.
|
||||
+1
@@ -0,0 +1 @@
|
||||
Pure C# POCO model with no external framework; relies on ClassicAssist's own `PacketWriter`/`PacketReader` and `UOMath` helpers for binary I/O and distance calculations.
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
schema_version: 1
|
||||
module_path: shared_core/uo_networking_objects_data
|
||||
title: UO Shared Layer (Networking, Objects & Client Data)
|
||||
scope:
|
||||
- ClassicAssist.Shared/UO/
|
||||
source_files: []
|
||||
depends_on: []
|
||||
related_to: []
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
Three cooperating sub-projects form one shared assembly consumed by both server and client:
|
||||
- `Data/` reads UO client archives (tiledata.mul, map*.mul/statics*.mul, Cliloc.enu) and exposes static lookups (Art, LandTile, Statics, Hues, Cliloc, etc.) used by every other layer.
|
||||
- `Objects/` defines the in-memory entity graph (`Entity`, `Item`, `Mobile`, `PlayerMobile`, `Gump`, `Menu`) plus collections; it depends on `Data/` for tile/art/hue lookups and on `Network/Packets/` to serialize/deserialize its state.
|
||||
- `Network/` owns the packet lifecycle: `PacketReader`/`PacketWriter` read/write raw bytes, each packet class derives from `BasePacket` and registers itself via `IncomingPacketHandlers`/`OutgoingPacketHandlers`; `PacketFilter/*` wraps handlers for macro recording and suppression.
|
||||
Cross-child wiring points: `Objects/Gumps/Gump.cs` emits gump packets through `Network/Packets/CompressedGump.cs`; `Data/UOPIndex.cs` is the common archive index reader used by both `Data/LandTile.cs` and `Data/Statics.cs`; `Compression.cs` is the shared zlib wrapper referenced by both `Network/PacketReader.cs` and `Data/UOPIndex.cs`. The three layers are strictly one-way: Network → Objects → Data, with no back-references.
|
||||
+1
@@ -0,0 +1 @@
|
||||
Shared ClassicAssist layer that wires UO client data files, the in-memory world object model, and the packet I/O pipeline into a single cross-platform runtime.
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
schema_version: 1
|
||||
module_path: shared_core
|
||||
title: ClassicAssist Shared Core Library
|
||||
scope:
|
||||
- ClassicAssist.Shared/
|
||||
source_files: []
|
||||
depends_on: []
|
||||
related_to: []
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
The project is organized as a layered shared library (`ClassicAssist.Shared`) with four cooperating sub-areas:
|
||||
|
||||
- `UO/` (networking + objects + client data) owns the wire protocol: packet classes in `Network/Packets`, their registration via `IncomingPacketHandlers` / `OutgoingPacketHandlers`, the in-memory world model (`Objects/Mobile`, `Item`, `Gump`, …), and static shard data loaders (`Data/*.json`).
|
||||
- `Data/` builds feature subsystems on top of that model — each subsystem exposes a singleton `*Manager` (HotkeyManager, MacroManager, AutolootManager, DressManager, OrganizerManager, ScavengerManager, VendorBuy/Sell, Skills, Spells, Abilities, Counters, Chat, Commands, Targeting) plus its own entry types and per-feature command sets under `Commands/`.
|
||||
- `UI/ViewModels/` provides Avalonia MVVM view models that bind to those managers; base classes (`BaseViewModel`, `RepositionableGumpViewModel`) and helpers (`OptionsBindingAttribute`, `EnumDescriptionTypeConverter`) are reused across every tab.
|
||||
- `Misc/` and `Engine/` supply cross-cutting infrastructure (`ThreadQueue`, `CircularBuffer`, `Keys`, `PlatformDetector`, `Filters`, `Reflection`) used by both `UO/` and `Data/`.
|
||||
|
||||
Wiring between layers is contract-driven rather than dependency-injected: `Data/*Manager` classes read/write state from `UO/Objects` entities and raise events consumed by `UI/ViewModels`; `Resources/` supplies localized strings and icons referenced through generated `Strings.Designer.cs`. The three native DLLs (`cuoapi.dll`, `zlib32.dll`, `zlib64.dll`) at the project root are P/Invoked by `Misc/NativeMethods` and `UO/Compression` for platform-specific I/O and zlib compression. There is no IoC container — consumers construct or access managers directly, keeping the shared library self-contained and reference-only.
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
- Each feature subsystem follows a fixed shape: a strongly-typed `*Entry` class, an `*Manager` singleton exposing CRUD + persistence, and optional `Commands/` subfolder of command implementations.
|
||||
- Feature commands are discovered by convention using attributes (`HotkeyCommandAttribute`, `CommandsDisplayAttribute`, `CommandsDisplayStringSeeAlsoAttribute`) rather than explicit registration tables.
|
||||
- UI view models inherit `BaseViewModel` and expose options via `[OptionsBinding]` properties instead of manual INotifyPropertyChanged plumbing.
|
||||
- Localized text and macro help strings are accessed exclusively through the generated `Strings.Designer` / `MacroCommandHelp.Designer` classes, never hard-coded literals.
|
||||
- P/Invoke and native-DLL usage is centralized in `Misc/NativeMethods` and `UO/Compression`; other layers call these wrappers rather than importing native code directly.
|
||||
+1
@@ -0,0 +1 @@
|
||||
Cross-platform shared library that wires UO networking, game-data subsystems, MVVM UI, and cross-cutting primitives into a single ClassicAssist runtime consumed by the client and server projects.
|
||||
+1
@@ -0,0 +1 @@
|
||||
.NET shared library targeting both the ClassicAssist client and server; Avalonia MVVM for the UI layer; embedded JSON data files (`Bodies.json`, `Spells.json`, `Regions.json`, …) loaded at startup; .NET `.resx` resource files for multi-language string localization; native `cuoapi.dll` and `zlib*.dll` binaries shipped alongside the assembly.
|
||||
Reference in New Issue
Block a user