### System Preset Folder Structure Example Source: https://github.com/josdemmers/diablo4companion/wiki/How-to-create-a-new-System-Preset This is an example of the folder structure for a system preset, including the 'D4Companion' directory and its subfolders and files. ```plaintext \---D4Companion:. \---Tooltips | tooltip_gc_square.png (optional) | tooltip_gc_x.png (optional) | tooltip_kb_all.png | dot-affixes_greater.png | dot-affixes_normal.png | dot-affixes_reroll.png | dot-affixes_rune_invocation.png | dot-affixes_rune_ritual.png | dot-affixes_temper_defensive.png | dot-affixes_temper_mobility.png | dot-affixes_temper_offensive.png | dot-affixes_temper_resource.png | dot-affixes_temper_utility.png | dot-affixes_temper_weapons.png | dot-aspects_legendary.png | dot-aspects_unique.png | dot-socket_1.png | dot-socket_1_mask.png | dot-socket_invocation.png | dot-socket_invocation_mask.png | dot-socket_ritual.png | dot-socket_ritual_mask.png | dot-splitter_1.png | dot-splitter_top_1.png ``` -------------------------------- ### Import Diablo 4 Builds from Maxroll.gg Source: https://context7.com/josdemmers/diablo4companion/llms.txt Guides on using `IBuildsManagerMaxroll` to download, parse, and convert build data from Maxroll.gg into local `AffixPreset` objects. This involves downloading a build by its ID, accessing parsed profiles, and creating presets from specific variants. ```csharp // D4Companion.Interfaces/IBuildsManagerMaxroll.cs // D4Companion.Services/BuildsManagerMaxroll.cs IBuildsManagerMaxroll maxrollManager = /* injected */; // Step 1: Download the build JSON from Maxroll. // Build URL: https://maxroll.gg/d4/planner/dqih026y → build id: "dqih026y" maxrollManager.DownloadMaxrollBuild("dqih026y"); // Step 2: The build is now in MaxrollBuilds. // Each MaxrollBuild contains parsed profiles (class variants). List builds = maxrollManager.MaxrollBuilds; MaxrollBuild build = builds.First(b => b.Id == "dqih026y"); // build.Name => "Bone Spear Necromancer" // build.Date => "2024-11-01" // build.Data => MaxrollBuildDataJson with gear profiles // Step 3: Create a local preset from a specific profile variant. // The "profile" parameter selects the build variant (character slot index as string). maxrollManager.CreatePresetFromMaxrollBuild(build, profile: "0", name: "Bone Spear S7"); // => AffixPreset named "Bone Spear S7" is created and saved via IAffixManager. // Remove a downloaded build from local cache maxrollManager.RemoveMaxrollBuild("dqih026y"); ``` -------------------------------- ### Import Builds from D4Builds.gg Source: https://context7.com/josdemmers/diablo4companion/llms.txt Use the `IBuildsManagerD4Builds` interface to download builds from D4Builds.gg using a build UUID. The downloaded build can then be converted into a local gear preset. ```csharp // D4Companion.Interfaces/IBuildsManagerD4Builds.cs IBuildsManagerD4Builds d4BuildsManager = /* injected */; // Build URL: https://d4builds.gg/builds/23ae9cbb-933e-4a88-999c-2241654cc8e2 // Build id : "23ae9cbb-933e-4a88-999c-2241654cc8e2" d4BuildsManager.DownloadD4BuildsBuild("23ae9cbb-933e-4a88-999c-2241654cc8e2"); List builds = d4BuildsManager.D4BuildsBuilds; D4BuildsBuild build = builds.First(b => b.Id == "23ae9cbb-933e-4a88-999c-2241654cc8e2"); // Each build has multiple D4BuildsBuildVariant entries (e.g. endgame, leveling) D4BuildsBuildVariant variant = build.Variants.First(); // Convert the chosen variant into a local AffixPreset d4BuildsManager.CreatePresetFromD4BuildsBuild( variant, buildNameOriginal: build.Name, buildName: "My Sorc Build" ); // Remove d4BuildsManager.RemoveD4BuildsBuild("23ae9cbb-933e-4a88-999c-2241654cc8e2"); ``` -------------------------------- ### Import Builds from D2Core.com Source: https://context7.com/josdemmers/diablo4companion/llms.txt Utilize the `IBuildsManagerD2Core` interface to import builds from D2Core.com's D4 Planner using a short URL code. The imported build can be directly converted into a local AffixPreset. ```csharp // D4Companion.Interfaces/IBuildsManagerD2Core.cs IBuildsManagerD2Core d2CoreManager = /* injected */; // Build URL: https://www.d2core.com/d4/planner?bd=1N1m → build id: "1N1m" d2CoreManager.DownloadD2CoreBuild("1N1m"); List builds = d2CoreManager.D2CoreBuilds; D2CoreBuild build = builds.First(b => b.Id == "1N1m"); // Convert directly to a local AffixPreset // (D2Core builds have a single variant — no variant selection needed) d2CoreManager.CreatePresetFromD2CoreBuild( build, buildNameOriginal: build.Name, buildName: "Sorc Blizzard D2Core" ); d2CoreManager.RemoveD2CoreBuild("1N1m"); ``` -------------------------------- ### Registering Services with Dependency Injection in C# Source: https://context7.com/josdemmers/diablo4companion/llms.txt This code demonstrates how to configure and register services as singletons and ViewModels as transient using Microsoft.Extensions.DependencyInjection. It also shows how to resolve a service from the service provider. ```csharp // D4Companion/App.xaml.cs private static IServiceProvider ConfigureServices() { var services = new ServiceCollection(); // Structured logging via NLog services.AddLogging(loggingBuilder => loggingBuilder.AddNLog(configFileRelativePath: "Config/NLog.config")); // Core services — all singletons services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); // ViewModels — transient services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); return services.BuildServiceProvider(); } // Resolving a service from a view's code-behind: var affixManager = (App.Current.Services.GetService(typeof(IAffixManager)) as IAffixManager)!; ``` -------------------------------- ### Enable and Configure Multi-Build Mode Source: https://context7.com/josdemmers/diablo4companion/llms.txt Configure `MultiBuild` settings to compare affix matches across up to three builds simultaneously. Each build is assigned a distinct color for overlay rendering. ```csharp // D4Companion.Entities/MultiBuild.cs | D4Companion.Entities/SettingsD4.cs // Enable multi-build mode in settings ISettingsManager settingsManager = /* injected */; settingsManager.Settings.IsMultiBuildModeEnabled = true; // Configure 3 concurrent builds settingsManager.Settings.MultiBuildList = new List { new MultiBuild { Index = 0, Name = "Bone Spear", Color = Colors.Cyan }, new MultiBuild { Index = 1, Name = "Bone Spirit", Color = Colors.Orange }, new MultiBuild { Index = 2, Name = "Minion Master", Color = Colors.Purple } }; settingsManager.SaveSettings(); // The overlay will render separate colored icons per build: // - Cyan icon → affix matches "Bone Spear" preset // - Orange icon → affix matches "Bone Spirit" preset // - Purple icon → affix matches "Minion Master" preset // - No icon → affix doesn't match any of the 3 builds // Individual per-affix colors from each preset are ignored in this mode. ``` -------------------------------- ### Import Builds from Mobalytics.gg Source: https://context7.com/josdemmers/diablo4companion/llms.txt Use the `IBuildsManagerMobalytics` interface to import builds from Mobalytics.gg. It supports direct build URLs and profile-linked builds. Profile pages must be added first for profile-linked builds. ```csharp // D4Companion.Interfaces/IBuildsManagerMobalytics.cs IBuildsManagerMobalytics mobalyticsManager = /* injected */; // --- Format 1: Direct build URL --- // https://mobalytics.gg/diablo-4/profile/210623d7-d551-492f-82fc-632f760d8751/builds/2c55a596-4d61-4e92-a419-fe738512f27b mobalyticsManager.DownloadMobalyticsBuild( "https://mobalytics.gg/diablo-4/profile/210623d7.../builds/2c55a596..." ); // --- Format 2: Profile page + build selection --- // First add the profile so its builds can be listed: // mobalyticsManager.DownloadMobalyticsBuild("https://mobalytics.gg/diablo-4/profile/Sanctum"); List builds = mobalyticsManager.MobalyticsBuilds; List profiles = mobalyticsManager.MobalyticsProfiles; MobalyticsBuild build = builds.First(); MobalyticsBuildVariant variant = build.Variants.First(); // Create local preset from variant mobalyticsManager.CreatePresetFromMobalyticsBuild( variant, buildNameOriginal: build.Name, buildName: "Druid Pulverize" ); // Remove builds and profiles mobalyticsManager.RemoveMobalyticsBuild(build.Id); mobalyticsManager.RemoveMobalyticsProfile("Sanctum"); ``` -------------------------------- ### Define Gear Affix Preset Data Model with AffixPreset Source: https://context7.com/josdemmers/diablo4companion/llms.txt The AffixPreset class models a build preset, storing affixes, aspects, sigils, runes, and paragon board configurations. It supports cloning for 'Save As' functionality. ```csharp // D4Companion.Entities/AffixPreset.cs var preset = new AffixPreset { Name = "Necro Bone Spear", ItemAffixes = new List { new ItemAffix { Id = "critical_strike_chance", Type = "helm", // ItemTypeConstants.Helm Color = Colors.Green, IsGreater = true // flag as desired greater affix }, new ItemAffix { Id = "movement_speed", Type = "boots", Color = Colors.Orange, IsTempered = true // tempered affix } }, ItemAspects = new List { new ItemAffix { Id = "aspect_of_disobedience", Type = "chest" } }, ItemSigils = new List { new ItemAffix { Id = "dungeon_arcane_tremors", Type = "sigil" } }, ItemRunes = new List { new ItemAffix { Id = "rune_sol", Type = "rune" } }, // Paragon boards imported from build sites ParagonBoardsList = new List> { new List { new ParagonBoard { Name = "Scourge", Glyph = "Territorial", Rotation = "0", Nodes = new bool[21 * 21] // 441 node bitmask } } } }; // Clone a preset for "Save As" functionality AffixPreset copy = preset.Clone(); copy.Name = "Necro Bone Spear v2"; ``` -------------------------------- ### ScreenCapture Methods Source: https://context7.com/josdemmers/diablo4companion/llms.txt Methods for capturing screen content using Win32 BitBlt. ```APIDOC ## ScreenCapture ### Description Provides low-level Win32 GDI `BitBlt`-based screen capture. ### Methods #### GetScreenCapture Captures the entire window of a given HWND. - **Parameters** - `hwnd` (HWND) - The handle to the window to capture. - **Returns** - `System.Drawing.Bitmap` - The captured bitmap of the entire window. #### GetScreenCaptureArea Captures a specific pixel region of a window. - **Parameters** - `hwnd` (HWND) - The handle to the window. - `roiLeft` (float) - The absolute screen X coordinate of the region's top-left corner. - `roiTop` (float) - The absolute screen Y coordinate of the region's top-left corner. - `roiWidth` (float) - The width of the region to capture. - `roiHeight` (float) - The height of the region to capture. - **Returns** - `System.Drawing.Bitmap?` - The captured bitmap of the specified region, or null if capture fails. #### ImageSourceFromBitmap Converts a `System.Drawing.Bitmap` to a WPF `BitmapSource`. - **Parameters** - `bitmap` (System.Drawing.Bitmap) - The GDI bitmap to convert. - **Returns** - `System.Windows.Media.Imaging.BitmapSource?` - The converted WPF BitmapSource. #### BitmapFromSource Converts a WPF `BitmapSource` back to a `System.Drawing.Bitmap`. - **Parameters** - `source` (System.Windows.Media.Imaging.BitmapSource) - The WPF BitmapSource to convert. - **Returns** - `System.Drawing.Bitmap` - The converted GDI Bitmap. #### WriteBitmapToFile Saves a `System.Drawing.Bitmap` to a file (PNG format). - **Parameters** - `filePath` (string) - The path to save the file to. - `bitmap` (System.Drawing.Bitmap) - The bitmap to save. - **Returns** - `void` - This method does not return a value. ``` -------------------------------- ### Read Game Data and Manage Presets with IAffixManager Source: https://context7.com/josdemmers/diablo4companion/llms.txt Use IAffixManager to access game data like affixes and aspects, and to manage user-defined gear presets. This includes adding, removing, and filtering affixes, as well as saving and renaming presets. ```csharp // D4Companion.Interfaces/IAffixManager.cs | D4Companion.Services/AffixManager.cs // --- Reading catalog data --- IAffixManager affixManager = /* injected */; // All affixes for the selected language List allAffixes = affixManager.Affixes; // e.g. AffixInfo { IdName = "damage_percent", Description = "+{0}% Damage", AffixType = 0, ... } // Look up an affix by display name (for Maxroll import matching) AffixInfo? info = affixManager.GetAffixInfoByIdName("damage_percent"); string desc = affixManager.GetAffixDescription("damage_percent"); // => "+{0}% Damage" // Get the minimum tracked value for a filtered affix double minVal = affixManager.GetAffixMinimalValue("critical_strike_chance"); // --- Managing presets --- // Create a new preset and add it var preset = new AffixPreset { Name = "Speed Farmer" }; affixManager.AddAffixPreset(preset); // Add an affix to a specific slot; Type must match ItemTypeConstants affixManager.AddAffix( affixManager.Affixes.First(a => a.IdName == "movement_speed"), ItemTypeConstants.Boots // "boots" ); // Add an aspect affixManager.AddAspect( affixManager.Aspects.First(a => a.IdName == "aspect_of_disobedience"), ItemTypeConstants.Chest ); // Add a sigil affix affixManager.AddSigil( affixManager.Sigils.First(s => s.IdName == "dungeon_arcane_tremors"), ItemTypeConstants.Sigil ); // Add a rune affixManager.AddRune(affixManager.Runes.First(r => r.IdName == "rune_sol")); // Remove entries ItemAffix toRemove = affixManager.GetAffix("movement_speed", AffixTypeConstants.Normal, ItemTypeConstants.Boots); affixManager.RemoveAffix(toRemove); // Set a minimum value filter (e.g. only flag movement speed >= 15%) affixManager.SetAffixMinimalValue("movement_speed", 15.0); affixManager.ResetMinimalAffixValues(); // clear all min-value filters // Save/persist affixManager.SaveAffixPresets(); // Rename a preset affixManager.RenamePreset("Speed Farmer", "Speed Build v2"); // Remove a preset affixManager.RemoveAffixPreset(preset); // Check if an ItemAffix is a duplicate (already in the active preset) bool dup = affixManager.IsDuplicate(toRemove); // false after removal ``` -------------------------------- ### Manage System Presets with ISystemPresetManager Source: https://context7.com/josdemmers/diablo4companion/llms.txt Use ISystemPresetManager to manage resolution-specific image templates for the computer vision pipeline. Download, extract, and manage system presets and controller images. Presets are downloaded from a community repository. ```csharp ISystemPresetManager presetManager = /* injected */; // List all available presets (from systempresets.json on GitHub) List presets = presetManager.SystemPresets; // SystemPreset { FileName = "1440p_SMF.zip", Resolution = "2560x1440", Config = "SDR Medium Font", // TooltipWidth = "500", BrightnessThreshold = "70/255", // LanguageReadyenUS = true, LanguageReadydeDE = true, ... } // Download a community preset zip into the local presets folder presetManager.DownloadSystemPreset("1440p_SMF.zip"); // Extract a downloaded zip (makes images available to the CV pipeline) presetManager.ExtractSystemPreset("1440p_SMF.zip"); // Controller support — add/remove Xbox/PS button image overlays presetManager.AddController("xbox_controller.png"); bool active = presetManager.IsControllerActive("xbox_controller.png"); // true presetManager.RemoveController("xbox_controller.png"); // Reload controller images after adding presetManager.LoadControllerImages(); List controllerImages = presetManager.ControllerImages; // => list of file paths for currently active controller icon images // System preset folder naming convention: // 1080p_SMF = 1080p SDR Medium Font (standard languages) // 1440p_HSF = 1440p HDR Small Font // 2160p_SSF = 2160p SDR Small Font // 1440p_SMF_zhCN = 1440p SDR Medium Font, Chinese Simplified only ``` -------------------------------- ### System Preset Folder Structure Source: https://context7.com/josdemmers/diablo4companion/llms.txt Defines the required folder structure and naming conventions for custom system presets, which are reference PNG images for the computer vision pipeline. Images should be captured directly from Diablo IV. ```bash # Naming convention: # {resolution}_{H|S}{S|M|L}F[_{langCode}] # H = HDR, S = SDR | S = Small, M = Medium, L = Large | F = Font # # Examples: # 1080p_SMF = 1080p, SDR, Medium Font (multi-language) # 1440p_HSF = 1440p, HDR, Small Font # 2160p_SSF = 2160p, SDR, Small Font # 1440p_SMF_zhCN = 1440p, SDR, Medium Font, Chinese Simplified only # Required folder structure for a custom preset (e.g. 1440p_SMF): 1440p_SMF/ ├── Tooltips/ │ ├── tooltip_kb_all.png # Keyboard/mouse tooltip trigger image │ ├── tooltip_kb_all_frFR.png # Language-specific variant (optional) │ ├── tooltip_gc_square.png # Controller (PlayStation) variant (optional) │ └── tooltip_gc_x.png # Controller (Xbox) variant (optional) ├── dot-affixes_normal.png # Normal affix bullet dot ├── dot-affixes_greater.png # Greater affix bullet dot ├── dot-affixes_reroll.png # Enchanted/rerolled affix bullet dot ├── dot-affixes_temper_offensive.png ├── dot-affixes_temper_defensive.png ├── dot-affixes_temper_mobility.png ├── dot-affixes_temper_resource.png ├── dot-affixes_temper_utility.png ├── dot-affixes_temper_weapons.png ├── dot-affixes_rune_ritual.png ├── dot-affixes_rune_invocation.png ├── dot-aspects_legendary.png # Legendary aspect bullet ├── dot-aspects_unique.png # Unique aspect bullet ├── dot-socket_1.png # Empty socket image ├── dot-socket_1_mask.png # Socket mask (white inside, black outside) ├── dot-socket_ritual.png # Socketed ritual rune ├── dot-socket_ritual_mask.png ├── dot-socket_invocation.png ├── dot-socket_invocation_mask.png ├── dot-splitter_1.png # Section divider line └── dot-splitter_top_1.png # Top section divider line # Capture these with Windows Snipping Tool (Shift + Win + S) directly from Diablo IV. # Recommended tool for socket mask creation: GIMP (https://www.gimp.org/) # After creating the images: # 1. Zip the folder: 1440p_SMF.zip # 2. Test via Settings > System Preset > select your preset > check Debug tab # 3. Adjust TooltipWidth if the red detection rectangle doesn't align # To share: open a GitHub issue or PR, add files to: # downloads/systempresets/images/1440p_SMF/ # downloads/systempresets/1440p_SMF.zip # downloads/systempresets/systempresets.json ← add metadata entry ``` -------------------------------- ### Capture and Save UI Images Source: https://github.com/josdemmers/diablo4companion/wiki/How-to-create-a-new-System-Preset Instructions for capturing specific UI elements using the Windows snipping tool and saving them with the correct filenames for system presets. ```plaintext 1. Save the affix location as `dot-affixes_normal.png`. 2. Save the enchanted affix location as `dot-affixes_reroll.png`. 3. Save the aspect location as `dot-aspects_legendary.png` and for unique items as `dot-aspects_unique.png`. 4. Save the socket location as `dot-socket_1.png` and `dot-socket_1_mask.png`. 5. Save the top splitter location as `dot-splitter_top_1.png`. 6. Save the other splitter location as `dot-splitter_1.png`. 7. Save the `Shift` image as `tooltip_kb_all.png` in the `Tooltips` folder. 8. From a rune item type create a `dot-affixes_rune_ritual.png` and `dot-affixes_rune_invocation.png` image. ``` -------------------------------- ### Create ItemAffix Entities Source: https://context7.com/josdemmers/diablo4companion/llms.txt Demonstrates creating `ItemAffix` objects for different types of affixes including normal, greater, tempered, and cross-type affixes. Use `IsAnyType` to specify if an affix applies to all item types. ```csharp // D4Companion.Entities/ItemAffix.cs // Normal affix with custom highlight color var normalAffix = new ItemAffix { Id = "life_percent", Type = ItemTypeConstants.Helm, // "helm" Color = Colors.Cyan, IsAnyType = false // false: slot-specific; true: highlight on any item type }; // Greater affix — shown as triangle overlay icon var greaterAffix = new ItemAffix { Id = "critical_strike_damage", Type = ItemTypeConstants.Ring, Color = Colors.Yellow, IsGreater = true }; // Tempered (rerolled) affix var temperedAffix = new ItemAffix { Id = "lucky_hit_chance", Type = ItemTypeConstants.Gloves, Color = Colors.Purple, IsTempered = true }; // Cross-type affix (match on any equipped slot) var anyTypeAffix = new ItemAffix { Id = "damage_reduction", Type = ItemTypeConstants.Chest, Color = Colors.LightBlue, IsAnyType = true // square icon; valid for all item types }; ``` -------------------------------- ### Adding App Translations with ResxTranslator Source: https://context7.com/josdemmers/diablo4companion/llms.txt Details the steps to add new UI languages to the application using the ResxTranslator tool. This involves opening the localization directory, adding a new language locale, translating strings, and saving the updated .resx file. ```bash # Steps to add a new UI language: # 1. Download source and ResxTranslator # https://github.com/josdemmers/Diablo4Companion (download zip) # https://github.com/HakanL/resxtranslator/releases # 2. Open ResxTranslator.exe # File → Open Directory → select: Diablo4Companion/D4Companion.Localization/ # 3. To add a new language: # Languages → Add new Language → More Languages... → select locale # 4. Translate each string key in the grid. # 5. Save — produces: D4Companion.Localization/Resources.fr.resx (example for French) # 6. Submit the .resx file via GitHub issue or PR. # Language code reference (used as SelectedAffixLanguage in SettingsD4): # enUS English deDE German # frFR French itIT Italian # esES Spanish (EU) esMX Spanish (LA) # plPL Polish ptBR Brazilian Portuguese # ruRU Russian trTR Turkish # zhCN Chinese (Simplified) zhTW Chinese (Traditional) ``` -------------------------------- ### System Preset Folder Naming Convention Source: https://github.com/josdemmers/diablo4companion/wiki/How-to-create-a-new-System-Preset Use this convention to name your system preset folders, including resolution and in-game settings. For languages that differ significantly, append the language code. ```plaintext 1080p_HSF : HDR Small Font 1440p_SMF : SDR Medium Font 2160p_HLF : HDR Large Font ``` ```plaintext 1440p_SMF_zhCN 1440p_SMF_zhTW 1440p_SMF_jaJP 1440p_SMF_koKR ``` -------------------------------- ### Win32 BitBlt Screen Capture with ScreenCapture Source: https://context7.com/josdemmers/diablo4companion/llms.txt Utilize ScreenCapture for low-level screen capture using Win32 GDI BitBlt. This class is essential for capturing Diablo IV's window content at specified intervals or regions. ```csharp // D4Companion.Helpers/ScreenCapture.cs using Windows.Win32.Foundation; var capture = new ScreenCapture(); // Capture the entire window of a given HWND HWND hwnd = /* PInvoke.FindWindow(null, "Diablo IV") */; System.Drawing.Bitmap fullWindow = capture.GetScreenCapture(hwnd); // Capture only a specific pixel region (e.g. tooltip area) System.Drawing.Bitmap? roi = capture.GetScreenCaptureArea( hwnd, roiLeft: 1200f, // absolute screen X roiTop: 300f, // absolute screen Y roiWidth: 500f, // matches SettingsD4.TooltipWidth roiHeight: 800f ); // Convert Bitmap to WPF BitmapSource for UI display System.Windows.Media.Imaging.BitmapSource? src = ScreenCapture.ImageSourceFromBitmap(fullWindow); // Convert WPF BitmapSource back to GDI Bitmap (e.g. for Emgu CV processing) System.Drawing.Bitmap bmp = ScreenCapture.BitmapFromSource(src!) // Save a debug screenshot to disk (PNG) ScreenCapture.WriteBitmapToFile("debug/screenshot_001.png", fullWindow); // => Creates parent directories if missing, saves as PNG ``` -------------------------------- ### Manage Trade Watchlist with ITradeItemManager Source: https://context7.com/josdemmers/diablo4companion/llms.txt Use `ITradeItemManager` to maintain a list of desired items and affixes. The manager can find matches against detected tooltip data, triggering trade value overlays. ```csharp // D4Companion.Interfaces/ITradeItemManager.cs | D4Companion.Services/TradeItemManager.cs // D4Companion.Entities/TradeItem.cs ITradeItemManager tradeManager = /* injected */; // Current trade watchlist List watchlist = tradeManager.TradeItems; // A TradeItem specifies the item type and a set of desired affixes var item = new TradeItem { Type = new TradeItemType { Name = "Gloves", Type = ItemTypeConstants.Gloves, Image = "hands_icon.png" }, Value = "500M", // estimated trade value (free-text) Affixes = new List { new ItemAffix { Id = "attack_speed", Type = ItemTypeConstants.Gloves, IsGreater = true }, new ItemAffix { Id = "critical_strike_chance", Type = ItemTypeConstants.Gloves } } }; // Finding a match (called internally by ScreenProcessHandler during tooltip scan) TradeItem? match = tradeManager.FindTradeItem( itemType: "gloves", affixes: detectedAffixes, // List> from tooltip descriptor affixAreas: detectedAffixAreas // List ); // Returns the matching TradeItem if all required affixes are found, else null. // When a match is found, the trade value is rendered at the bottom of the ingame tooltip. ``` -------------------------------- ### OCR Text Recognition with IOcrHandler Source: https://context7.com/josdemmers/diablo4companion/llms.txt Use IOcrHandler to convert game tooltip images into structured text data. It supports various matching functions for affixes, aspects, unique items, runes, sigils, item types, and power levels. ```csharp // D4Companion.Interfaces/IOcrHandler.cs | D4Companion.Services/OcrHandler.cs IOcrHandler ocrHandler = /* injected */; // Convert a raw image region to plain text System.Drawing.Image tooltipSection = /* cropped screenshot */; string rawText = ocrHandler.ConvertToText(tooltipSection); // => "Critical Strike Chance // +15.2%" // Upper section (item name / power) — uses a dedicated text extraction path string upperText = ocrHandler.ConvertToTextUpperTooltipSection(tooltipSection); // Match text to an affix id using fuzzy comparison (single-line affix) OcrResultAffix affixResult = ocrHandler.ConvertToAffix("Critical Strike Chance"); // => OcrResultAffix { AffixId = "critical_strike_chance", TextValue = 0.0, Text = "Critical Strike Chance" } // Multi-line affixes (e.g. tempered affixes that wrap) OcrResultAffix multiResult = ocrHandler.ConvertToAffixMultiline("Lucky Hit Chance to Freeze Enemies"); // => OcrResultAffix { AffixId = "lucky_hit_freeze_chance", ... } // Match an aspect description OcrResultAffix aspectResult = ocrHandler.ConvertToAspect("Disobedience increases Armor"); // => OcrResultAffix { AffixId = "aspect_of_disobedience", ... } // Match unique item text OcrResultAffix uniqueResult = ocrHandler.ConvertToUnique("Tibault's Will"); // => OcrResultAffix { AffixId = "tib_pants_unique", ... } // Match a rune name OcrResultAffix runeResult = ocrHandler.ConvertToRune("Sol"); // => OcrResultAffix { AffixId = "rune_sol", ... } // Match a sigil name OcrResultAffix sigilResult = ocrHandler.ConvertToSigil("Arcane Tremors"); // => OcrResultAffix { AffixId = "dungeon_arcane_tremors", ... } // Identify item type + rarity from tooltip header OcrResultItemType itemType = ocrHandler.ConvertToItemType("Sacred Gloves"); // => OcrResultItemType { Type = "Gloves", TypeId = "gloves", Rarity = "Sacred", Similarity = 95 } // Parse item power number OcrResult power = ocrHandler.ConvertToPower("Item Power 800"); // => OcrResult { Text = "Item Power 800", TextClean = "800" } ``` -------------------------------- ### IOcrHandler Methods Source: https://context7.com/josdemmers/diablo4companion/llms.txt Methods for converting image regions and text into structured data for game item parsing. ```APIDOC ## IOcrHandler ### Description Wraps TesseractOCR and FuzzierSharp for OCR text recognition and fuzzy string matching. ### Methods #### ConvertToText Converts a raw image region to plain text. - **Parameters** - `tooltipSection` (System.Drawing.Image) - The image region to process. - **Returns** - `string` - The extracted plain text. #### ConvertToTextUpperTooltipSection Uses a dedicated text extraction path for the upper section of the tooltip (item name/power). - **Parameters** - `tooltipSection` (System.Drawing.Image) - The image region of the upper tooltip section. - **Returns** - `string` - The extracted text from the upper tooltip section. #### ConvertToAffix Matches single-line text to an affix ID using fuzzy comparison. - **Parameters** - `text` (string) - The single line of text to match. - **Returns** - `OcrResultAffix` - The result of the affix matching. #### ConvertToAffixMultiline Matches multi-line text (e.g., wrapped tempered affixes) to an affix ID. - **Parameters** - `text` (string) - The multi-line text to match. - **Returns** - `OcrResultAffix` - The result of the multi-line affix matching. #### ConvertToAspect Matches aspect description text to an aspect ID. - **Parameters** - `text` (string) - The aspect description text. - **Returns** - `OcrResultAffix` - The result of the aspect matching. #### ConvertToUnique Matches unique item name text to a unique item ID. - **Parameters** - `text` (string) - The unique item name text. - **Returns** - `OcrResultAffix` - The result of the unique item matching. #### ConvertToRune Matches rune name text to a rune ID. - **Parameters** - `text` (string) - The rune name text. - **Returns** - `OcrResultAffix` - The result of the rune matching. #### ConvertToSigil Matches sigil name text to a sigil ID. - **Parameters** - `text` (string) - The sigil name text. - **Returns** - `OcrResultAffix` - The result of the sigil matching. #### ConvertToItemType Identifies item type and rarity from tooltip header text. - **Parameters** - `text` (string) - The tooltip header text (e.g., "Sacred Gloves"). - **Returns** - `OcrResultItemType` - The identified item type and rarity. #### ConvertToPower Parses item power number from text. - **Parameters** - `text` (string) - The text containing the item power (e.g., "Item Power 800"). - **Returns** - `OcrResult` - The parsed result containing the power number. ``` -------------------------------- ### Access Tooltip Analysis Results with ItemTooltipDescriptor Source: https://context7.com/josdemmers/diablo4companion/llms.txt The `ItemTooltipDescriptor` object aggregates all data from a tooltip scan. Access item metadata, affix matches, screen coordinates, and performance timings. ```csharp // D4Companion.Entities/ItemTooltipDescriptor.cs // This is populated automatically by ScreenProcessHandler during each scan cycle. // Access it from messages (e.g. TooltipDataReadyMessage) or OverlayHandler. var tooltip = new ItemTooltipDescriptor(); // After processing: // Item metadata int power = tooltip.ItemPower; // e.g. 800 string rarity = tooltip.ItemRarity; // "Sacred", "Ancestral", "Unique" string type = tooltip.ItemType; // "gloves" bool isUnique = tooltip.IsUniqueItem; double similarity = tooltip.Similarity; // Tooltip image match confidence // Screen position of the tooltip rectangle System.Drawing.Rectangle loc = tooltip.Location; // Detected and matched affixes (index = display row, ItemAffix = matched preset entry) List> matched = tooltip.ItemAffixes; // For multi-build mode: per-build match lists List>> multiBuild = tooltip.ItemAffixesBuildList; // Affix area bounding boxes (for overlay dot placement) List areas = tooltip.ItemAffixAreas; List locations = tooltip.ItemAffixLocations; // Detected aspect ItemAffix aspect = tooltip.ItemAspect; System.Drawing.Rectangle aspectArea = tooltip.ItemAspectArea; // Socket locations List sockets = tooltip.ItemSocketLocations; // OCR raw results for debugging OcrResultAffix ocrAspect = tooltip.OcrResultAspect; OcrResultItemType ocrItemType = tooltip.OcrResultItemType; OcrResult ocrPower = tooltip.OcrResultPower; // Trade match (null if no trade item matched) TradeItem? trade = tooltip.TradeItem; // Per-stage timing for performance profiling (ms) int totalMs = tooltip.PerformanceResults["Total"]; int ocrMs = tooltip.PerformanceResults["Affixes"]; ``` -------------------------------- ### Affix and Item Type Constants Source: https://context7.com/josdemmers/diablo4companion/llms.txt Shows usage of `AffixTypeConstants` and `ItemTypeConstants` for identifying affixes and gear slots. These string constants are used when looking up entries in `IAffixManager`. ```csharp // D4Companion.Constants/AffixTypeConstants.cs // D4Companion.Constants/ItemTypeConstants.cs // Affix type values string implicit_ = AffixTypeConstants.Implicit; // "implicit" string normal = AffixTypeConstants.Normal; // "normal" string greater = AffixTypeConstants.Greater; // "greater" string tempered = AffixTypeConstants.Tempered; // "tempered" string rune = AffixTypeConstants.Rune; // "rune" // Gear slot values string helm = ItemTypeConstants.Helm; // "helm" string chest = ItemTypeConstants.Chest; // "chest" string gloves = ItemTypeConstants.Gloves; // "gloves" string pants = ItemTypeConstants.Pants; // "pants" string boots = ItemTypeConstants.Boots; // "boots" string amulet = ItemTypeConstants.Amulet; // "amulet" string ring = ItemTypeConstants.Ring; // "ring" string weapon = ItemTypeConstants.Weapon; // "weapon" string ranged = ItemTypeConstants.Ranged; // "ranged" string offhand = ItemTypeConstants.Offhand; // "offhand" string sigil = ItemTypeConstants.Sigil; // "sigil" string runeSlot = ItemTypeConstants.Rune; // "rune" // Seasonal/special slot types string occultGem = ItemTypeConstants.OccultGem; // Season 7 string witcherSigil = ItemTypeConstants.WitcherSigil; // Season 7 string dungeonEsc = ItemTypeConstants.DungeonEscalation; // Season 9+ string horadricJwl = ItemTypeConstants.HoradricJewel; // Season 9 string bloodiedLair = ItemTypeConstants.BloodiedLair; // Season 12 // Example: look up an affix for a specific slot and type IAffixManager affixManager = /* injected */; ItemAffix entry = affixManager.GetAffix( "critical_strike_chance", AffixTypeConstants.Normal, ItemTypeConstants.Ring ); ``` -------------------------------- ### Manage Application Settings with ISettingsManager Source: https://context7.com/josdemmers/diablo4companion/llms.txt Use ISettingsManager to read and save application configuration. Modify settings like tooltip dimensions, loot filter toggles, overlay display options, language, and hotkey bindings. Changes are persisted to Config/Settings.json. ```csharp ISettingsManager settingsManager = /* injected */; // Read current settings SettingsD4 s = settingsManager.Settings; // --- Screen capture & OCR tuning --- s.TooltipWidth = 500; // Width of tooltip capture region (px), default 500 for 1440p s.TooltipMaxHeight = 200; // Max height to limit item type detection area s.ThresholdMin = 70; // Brightness lower bound (SDR default: 70/255) s.ThresholdMax = 255; // Brightness upper bound s.ThresholdSimilarityTooltip = 0.05; // Image similarity for tooltip detection s.ThresholdSimilarityAffixLocation = 0.05; s.ThresholdSimilarityAspectLocation = 0.05; s.MinimalOcrMatchType = 80; // Minimum fuzzy-match % for item type OCR (try 60-70 for non-EN) // --- Loot filter toggles --- s.IsMinimalAffixValueFilterEnabled = true; // Enable min-value filter s.IsItemPowerLimitEnabled = true; s.ItemPowerLimit = 800; // Ignore items below this power s.IsAspectDetectionEnabled = true; s.IsRuneDetectionEnabled = true; s.IsTemperedAffixDetectionEnabled = true; s.IsUniqueDetectionEnabled = true; // --- Overlay display --- s.SelectedOverlayMarkerMode = "Show All"; // or "Show Matched Only" s.SelectedSigilDisplayMode = "Whitelisting"; // or "Blacklisting" s.OverlayFontSize = 18; s.OverlayUpdateDelay = 5; // ms between overlay refresh cycles s.IsTopMost = false; s.ShowCurrentItem = true; s.IsTradeOverlayEnabled = true; s.IsMultiBuildModeEnabled = false; // Enable up to 3 simultaneous build comparisons // --- Language & preset --- s.SelectedAffixLanguage = "enUS"; // Affix data language (enUS, deDE, frFR, zhCN, ...) s.SelectedAppLanguage = "en-US"; s.SelectedSystemPreset = "1440p_SMF"; s.SelectedAffixPreset = "Bone Spear Necro"; // --- Controller support --- s.ControllerMode = false; // --- Hotkeys --- s.KeyBindingConfigSwitchPreset = new KeyBindingConfig { IsEnabled = true, Name = "Switch Preset", KeyGestureKey = Key.F5, KeyGestureModifier = ModifierKeys.Control }; s.KeyBindingConfigToggleOverlay = new KeyBindingConfig { IsEnabled = true, Name = "Toggle Overlay", KeyGestureKey = Key.F12, KeyGestureModifier = ModifierKeys.Control }; // Persist changes settingsManager.SaveSettings(); // => writes to Config/Settings.json ``` -------------------------------- ### Tooltip Image Naming for Different Languages Source: https://github.com/josdemmers/diablo4companion/wiki/How-to-create-a-new-System-Preset Customize tooltip images by appending language codes to the default filename. This ensures the correct image is used for specific language versions. ```plaintext tooltip_kb_all_esES.png tooltip_kb_all_esMX.png tooltip_kb_all_frFR.png tooltip_kb_all_itIT.png ``` -------------------------------- ### AddRange for ObservableCollection Source: https://context7.com/josdemmers/diablo4companion/llms.txt Adds a convenience `AddRange` extension method to `System.Collections.ObjectModel.Collection` and `ObservableCollection` for bulk adding items. This method triggers a single `CollectionChanged` event per item added. ```csharp // D4Companion.Extensions/CollectionExtensions.cs using D4Companion.Extensions; using System.Collections.ObjectModel; var observableList = new ObservableCollection(); // Add multiple items at once — triggers one CollectionChanged per item IEnumerable items = new[] { "enUS", "deDE", "frFR", "zhCN" }; observableList.AddRange(items); // observableList.Count == 4 // Works with any Collection var affixCollection = new Collection(); affixCollection.AddRange(affixManager.Affixes.Where(a => a.AffixType == 0)); // ArgumentNullException if collection or items is null try { observableList.AddRange(null!); // throws ArgumentNullException } catch (ArgumentNullException ex) { Console.WriteLine(ex.ParamName); // "items" } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.