Skip to content

Fix name scan after BSG magnifier change and language switch race#1

Open
Syklass wants to merge 2 commits into
tarkovtracker-org:masterfrom
Syklass:fix/name-scan-marker-and-language-cache
Open

Fix name scan after BSG magnifier change and language switch race#1
Syklass wants to merge 2 commits into
tarkovtracker-org:masterfrom
Syklass:fix/name-scan-marker-and-language-cache

Conversation

@Syklass

@Syklass Syklass commented Jul 11, 2026

Copy link
Copy Markdown

User description

Summary

  • Load search marker from Data/icon_search.png with updated MarkerItemScale
  • Preload offline item cache and add TryGetItemById to avoid Unknown item during language switches
  • Unregister hotkeys while saving settings; skip scans when item cache is not ready
  • Bump version to 3.9.4

Related issue

Fixes #... (если есть issue; иначе опиши баг)

Test plan

  • dotnet build RatScanner.sln -c Release
  • Name scan on inspect magnifier (Russian UI, Name Scan Language = Russian)
  • Switch UI / name scan language in Settings → Save → scan again (no crash)
  • Icon scan still works
  • Data/icon_search.png present locally (note for release: needs RatScannerData update)

Release note

Requires updated icon_search.png in the Data bundle (RatScannerData).


CodeAnt-AI Description

Fix name scans during language changes and restore search marker detection after the BSG magnifier update

What Changed

  • Name and icon scans now wait for the needed item data to be available, so scans no longer fail or crash during language switches or while the cache is still loading
  • Search-marker detection now uses the updated in-game marker image and scale, which restores name scanning with the changed magnifier UI
  • Saving settings no longer leaves hotkeys unregistered if something goes wrong partway through the save process

Impact

✅ Fewer scan crashes after changing language
✅ Restored name scanning with the new magnifier UI
✅ Fewer missed scans while item data is still loading

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

Load the search marker from Data/icon_search.png with scale calibrated
to the new template width. Preload offline item cache on startup and
resolve items via TryGetItemById to avoid crashes when the cache is
still loading after a language change. Unregister hotkeys while saving
settings and skip scans gracefully when an item is not cached yet.

Track icon_search.png in repo: required for Name Scan after BSG magnifier UI change.

Bump version to 3.9.4.
@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes
    • Improved item and icon scanning by safely handling cases where referenced item data isn’t available.
    • Enhanced offline startup by preloading cached game data for the current language.
    • Ensured hotkeys are reliably re-registered even if saving settings fails.
    • Fixed the packaged search icon so it’s included and resolved correctly.
  • Release
    • Updated the application version to 3.9.4.
  • Developer Experience
    • Added streamlined VS Code build, publish, and debug configurations.

Walkthrough

The changes add cached item lookup and scan guards, centralize inspection configuration, guarantee hotkey restoration during settings saves, and add VS Code build/debug/publish configuration. The shipped search icon path and project version are also updated.

Changes

Scanner cache and scan handling

Layer / File(s) Summary
Cache loading and item lookup
RatScanner/TarkovDevAPI.cs
Offline entries are loaded for selected data types, and item lookup searches current-language and cached item responses.
Scan resolution and safeguards
RatScanner/RatScannerMain.cs, RatScanner/Scan/*
Name and icon scans validate item availability through the centralized lookup before creating scan objects.
Inspection marker configuration
RatScanner/RatScannerMain.cs, RatScanner/RatConfig.cs
Inspection configuration creation is centralized and uses the configured data-directory search icon.

Settings hotkey lifecycle

Layer / File(s) Summary
Guaranteed hotkey restoration
RatScanner/ViewModel/SettingsVM.cs
Settings saving unregisters hotkeys before updates and re-registers them in a finally block.

Development and release configuration

Layer / File(s) Summary
Build, debug, and publish setup
.vscode/launch.json, .vscode/tasks.json
VS Code build, debug, and Windows publish tasks are defined.
Shipped asset and version metadata
.gitignore, RatScanner/RatScanner.csproj
The search icon is explicitly retained in the data directory, and the project version becomes 3.9.4.

Estimated code review effort: 3 (Moderate) | ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 31.25% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: fixing name scans around the magnifier update and language-switch race.
Description check ✅ Passed The description matches the changeset and covers the marker, cache, hotkey, and version updates.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codeant-ai codeant-ai Bot added the size:L This PR changes 100-499 lines, ignoring generated files label Jul 11, 2026
Comment on lines +59 to +62
internal SettingsVM(LocalizationService localizationService) {
_localizationService = localizationService;
LoadSettings();
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Add an explicit null check for the localizationService constructor argument before assigning it so later calls cannot dereference a null dependency. [custom_rule]

Severity Level: Major ⚠️

Why it matters? ⭐

The constructor stores localizationService directly into a field and then later uses _localizationService.SetLanguage(...) without any explicit null guard or validation. This matches the nullable-handling rule because a null dependency could be propagated and dereferenced later.

Rule source 📖

=== AGENTS.md === (line 66)

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** RatScanner/ViewModel/SettingsVM.cs
**Line:** 59:62
**Comment:**
	*Custom Rule: Add an explicit null check for the `localizationService` constructor argument before assigning it so later calls cannot dereference a null dependency.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

Comment on lines +318 to +321
if (!TarkovDevAPI.TryGetItemById(inspection.Item!.Id, out _)) {
Logger.LogWarning($"Skipping name scan: item {inspection.Item.Id} is not in cache yet.");
return false;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Add an explicit null guard for inspection.Item at the start of the helper and avoid relying on the null-forgiving operator when reading the item id. [custom_rule]

Severity Level: Major ⚠️

Why it matters? ⭐

The helper dereferences inspection.Item with the null-forgiving operator instead of explicitly guarding it. This is a changed C# nullable-reference usage without explicit null handling, so the suggestion matches the custom rule.

Rule source 📖

=== AGENTS.md === (line 66)

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** RatScanner/RatScannerMain.cs
**Line:** 318:321
**Comment:**
	*Custom Rule: Add an explicit null guard for `inspection.Item` at the start of the helper and avoid relying on the null-forgiving operator when reading the item id.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

RatConfig.ToolTip.Duration);

ItemScans.Enqueue(tempNameScan);
TryEnqueueNameScan(inspection, toolTipPosition);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Add an explicit null check for the nullable inspection value in the loop before passing it to the enqueue helper. [custom_rule]

Severity Level: Major ⚠️

Why it matters? ⭐

The loop variable is declared as Inspection? inspection, but the code passes it directly to TryEnqueueNameScan without an explicit null check. That is a nullable-reference usage introduced in changed code and is not explicitly handled, so the rule applies.

Rule source 📖

=== AGENTS.md === (line 66)

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** RatScanner/RatScannerMain.cs
**Line:** 354:354
**Comment:**
	*Custom Rule: Add an explicit null check for the nullable `inspection` value in the loop before passing it to the enqueue helper.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

InventoryConfig = new Config.Processing.Inventory() {
OptimizeHighlighted = highlighted,
},
InspectionConfig = CreateInspectionConfig(),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: CreateInspectionConfig() allocates a new Bitmap each time RatEye is reconfigured, but no disposal path is introduced for previously created marker bitmaps, which can leak GDI handles/memory over repeated SetupRatEye calls. Ensure old inspection marker resources are disposed when replacing the engine/config. [resource leak]

Severity Level: Major ⚠️
⚠️ RatEye reconfiguration accumulates GDI handles over time.
⚠️ Long-running sessions risk memory/handle exhaustion during scans.
Steps of Reproduction ✅
1. Start the application so that `RatScannerMain` is constructed
(`RatScanner/RatScannerMain.cs:19-83`), which logs "Initializing RatEye..." and calls
`SetupRatEye()` at line 58-59.

2. In `SetupRatEye()` (`RatScanner/RatScannerMain.cs:35-41`), a new `RatEyeEngine`
instance is created with `GetRatEyeConfig()`, which in turn sets
`ProcessingConfig.InspectionConfig = CreateInspectionConfig()`
(`RatScanner/RatScannerMain.cs:43-60).

3. `CreateInspectionConfig()` (`RatScanner/RatScannerMain.cs:64-70`) allocates a new
`Bitmap` from `RatConfig.Paths.SearchIcon` and assigns it to the `Marker` property of the
`Config.Processing.Inspection` object; no disposal of previous markers or the created
bitmap is performed here.

4. Later, when the item cache becomes ready, `WaitForItemsAndSeedAsync()`
(`RatScanner/RatScannerMain.cs:101-114`) calls `SetupRatEye()` again at line 107, creating
a second `RatEyeEngine` and a new inspection config marker bitmap; the previous
`RatEyeEngine` and its `InspectionConfig.Marker` are replaced without an explicit
`Dispose` call, so repeated reconfiguration within a long-lived process will continually
allocate new marker bitmaps, relying only on GC/finalizers and effectively leaking GDI
handles until collection.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** RatScanner/RatScannerMain.cs
**Line:** 208:208
**Comment:**
	*Resource Leak: `CreateInspectionConfig()` allocates a new `Bitmap` each time RatEye is reconfigured, but no disposal path is introduced for previously created marker bitmaps, which can leak GDI handles/memory over repeated `SetupRatEye` calls. Ensure old inspection marker resources are disposed when replacing the engine/config.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

Comment on lines 118 to +173
@@ -123,11 +125,11 @@ public async Task SaveSettings() {
RatConfig.IconScan.Enable = EnableIconScan;
RatConfig.IconScan.ScanRotatedIcons = ScanRotatedIcons;
RatConfig.IconScan.UseCachedIcons = UseCachedIcons;
RatConfig.IconScan.Hotkey = IconScanHotkey;

RatConfig.ToolTip.Duration = int.TryParse(ToolTipDuration, out int i) ? i : 0;
RatConfig.ToolTip.Duration = ToolTipMilli;
RatConfig.UserInterface.Language = UiLanguage;
RatConfig.IconScan.Hotkey = IconScanHotkey;
RatConfig.ToolTip.Duration = int.TryParse(ToolTipDuration, out int i) ? i : 0;
RatConfig.ToolTip.Duration = ToolTipMilli;
RatConfig.UserInterface.Language = UiLanguage;

RatConfig.MinimalUi.ShowName = ShowName;
RatConfig.MinimalUi.ShowAvgDayPrice = ShowAvgDayPrice;
@@ -163,11 +165,13 @@ public async Task SaveSettings() {
PageSwitcher.Instance.ResetWindowSize();
await TarkovDevAPI.InitializeCache();
if (updateTarkovTrackerToken || updateTarkovTrackerBackend) UpdateTarkovTrackerToken();
if (updateUiLanguage) _localizationService.SetLanguage(UiLanguage);
if (updateResolution || updateLanguage) RatScannerMain.Instance.SetupRatEye();
if (updateUiLanguage) _localizationService.SetLanguage(UiLanguage);
if (updateResolution || updateLanguage) RatScannerMain.Instance.SetupRatEye();

RatEye.Config.LogDebug = RatConfig.LogDebug;
RatScannerMain.Instance.HotkeyManager.RegisterHotkeys();
} finally {
RatScannerMain.Instance.HotkeyManager.RegisterHotkeys();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Saving settings now always unregisters and re-registers hotkeys, but the hotkey cleanup path does not dispose all registered hotkeys (the close-overlay hotkey is left alive), so each save adds another active handler. This causes accumulating listeners and resource leakage over time; either fully dispose all hotkeys in the manager or avoid full re-registration here. [missing cleanup]

Severity Level: Major ⚠️
⚠️ Escape close overlay hotkey accumulates multiple active listeners.
⚠️ Extra handlers increase event dispatch and background work.
⚠️ Hotkey lifecycle inconsistent; destructor never cleans close hotkey.
Steps of Reproduction ✅
1. Inspect application startup flow in `RatScanner/RatScannerMain.cs:12-20`: the
constructor creates `HotkeyManager = new HotkeyManager();` (line 13), whose constructor
(`RatScanner/HotkeyManager.cs:20-23`) calls `RegisterHotkeys()` and creates
`NameScanHotkey`, `IconScanHotkey`, `OpenInteractableOverlayHotkey`, and
`CloseInteractableOverlayHotkey` (lines 46-50). Immediately after, `RatScannerMain` calls
`HotkeyManager.UnregisterHotkeys();` (line 14).

2. Examine `HotkeyManager.UnregisterHotkeys()` in `RatScanner/HotkeyManager.cs:56-60`: it
disposes `NameScanHotkey`, `IconScanHotkey`, and `OpenInteractableOverlayHotkey`, but does
not dispose `CloseInteractableOverlayHotkey`, leaving its `UserActivityHelper` event
subscriptions active (see `ActiveHotkey.Dispose()` in
`RatScanner/ActiveHotkey.cs:117-119`, which unregisters event listeners).

3. Inspect settings save flow: the Save button in
`RatScanner/Pages/App/Settings/SettingsSave.razor:24-29` calls `SettingsVM.SaveSettings()`
(line 26). In `SaveSettings` (`RatScanner/ViewModel/SettingsVM.cs:110-174`), line 118
calls `RatScannerMain.Instance.HotkeyManager.UnregisterHotkeys();`, and the `finally`
block at lines 172-173 calls `RatScannerMain.Instance.HotkeyManager.RegisterHotkeys();`,
which itself begins by calling `UnregisterHotkeys()` again (`HotkeyManager.cs:42-44`) and
then re-creates all four hotkeys, including a new `CloseInteractableOverlayHotkey` (line
50).

4. Because `UnregisterHotkeys()` never disposes `CloseInteractableOverlayHotkey`, each
call sequence `UnregisterHotkeys()``RegisterHotkeys()` during startup and every
settings save leaves existing close-hotkey instances subscribed and creates a new one.
Over time, multiple `ActiveHotkey` instances for Escape accumulate, all handling key-up
events via `ActiveHotkey.OnKeyUp` (`ActiveHotkey.cs:86-92`). Pressing Escape to close the
interactable overlay will trigger multiple handlers and the app retains unnecessary event
subscriptions, demonstrating a real resource leak tied directly to `SaveSettings()` usage.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** RatScanner/ViewModel/SettingsVM.cs
**Line:** 118:173
**Comment:**
	*Missing Cleanup: Saving settings now always unregisters and re-registers hotkeys, but the hotkey cleanup path does not dispose all registered hotkeys (the close-overlay hotkey is left alive), so each save adds another active handler. This causes accumulating listeners and resource leakage over time; either fully dispose all hotkeys in the manager or avoid full re-registration here.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@RatScanner/RatScannerMain.cs`:
- Around line 213-220: Update CreateInspectionConfig to validate that
RatConfig.Paths.SearchIcon exists before constructing the Bitmap. If the file is
missing, throw or report a clear user-facing error that identifies
icon_search.png and instructs the user to update or reinstall the RatScannerData
bundle, while preserving the existing inspection configuration for valid files.

In `@RatScanner/ViewModel/SettingsVM.cs`:
- Around line 130-131: Remove the redundant assignment that parses
ToolTipDuration, leaving the RatConfig.ToolTip.Duration assignment from
ToolTipMilli as the sole tooltip-duration update in the settings save flow.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2db570e8-472b-41f1-ba8f-9dff49d3941d

📥 Commits

Reviewing files that changed from the base of the PR and between 2ebae7c and 21a88d6.

⛔ Files ignored due to path filters (1)
  • RatScanner/Data/icon_search.png is excluded by !**/*.png
📒 Files selected for processing (10)
  • .gitignore
  • .vscode/launch.json
  • .vscode/tasks.json
  • RatScanner/RatConfig.cs
  • RatScanner/RatScanner.csproj
  • RatScanner/RatScannerMain.cs
  • RatScanner/Scan/ItemIconScan.cs
  • RatScanner/Scan/ItemNameScan.cs
  • RatScanner/TarkovDevAPI.cs
  • RatScanner/ViewModel/SettingsVM.cs

Comment thread RatScanner/RatScannerMain.cs Outdated
Comment on lines +213 to +220
private static Config.Processing.Inspection CreateInspectionConfig() {
var marker = new Bitmap(RatConfig.Paths.SearchIcon);
// MarkerItemScale is calibrated to template width: in-game icon is ~16px at 1080p
return new Config.Processing.Inspection() {
Marker = marker,
MarkerItemScale = 16f / marker.Width,
};
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Guard against missing icon_search.png to prevent startup crash.

new Bitmap(RatConfig.Paths.SearchIcon) throws FileNotFoundException if the file is absent, crashing the app during SetupRatEye with no user-friendly message. If the RatScannerData bundle is not updated, users get an unhandled exception instead of actionable guidance.

🛡️ Proposed fix: file-existence check with helpful error
 private static Config.Processing.Inspection CreateInspectionConfig() {
+	if (!File.Exists(RatConfig.Paths.SearchIcon)) {
+		Logger.LogError($"Search icon not found at: {RatConfig.Paths.SearchIcon}. Ensure the RatScannerData bundle is up to date.");
+		throw new FileNotFoundException("Search icon file is missing. Please update the RatScannerData bundle.", RatConfig.Paths.SearchIcon);
+	}
 	var marker = new Bitmap(RatConfig.Paths.SearchIcon);
 	// MarkerItemScale is calibrated to template width: in-game icon is ~16px at 1080p
 	return new Config.Processing.Inspection() {
 		Marker = marker,
 		MarkerItemScale = 16f / marker.Width,
 	};
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
private static Config.Processing.Inspection CreateInspectionConfig() {
var marker = new Bitmap(RatConfig.Paths.SearchIcon);
// MarkerItemScale is calibrated to template width: in-game icon is ~16px at 1080p
return new Config.Processing.Inspection() {
Marker = marker,
MarkerItemScale = 16f / marker.Width,
};
}
private static Config.Processing.Inspection CreateInspectionConfig() {
if (!File.Exists(RatConfig.Paths.SearchIcon)) {
Logger.LogError($"Search icon not found at: {RatConfig.Paths.SearchIcon}. Ensure the RatScannerData bundle is up to date.");
throw new FileNotFoundException("Search icon file is missing. Please update the RatScannerData bundle.", RatConfig.Paths.SearchIcon);
}
var marker = new Bitmap(RatConfig.Paths.SearchIcon);
// MarkerItemScale is calibrated to template width: in-game icon is ~16px at 1080p
return new Config.Processing.Inspection() {
Marker = marker,
MarkerItemScale = 16f / marker.Width,
};
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@RatScanner/RatScannerMain.cs` around lines 213 - 220, Update
CreateInspectionConfig to validate that RatConfig.Paths.SearchIcon exists before
constructing the Bitmap. If the file is missing, throw or report a clear
user-facing error that identifies icon_search.png and instructs the user to
update or reinstall the RatScannerData bundle, while preserving the existing
inspection configuration for valid files.

Comment thread RatScanner/ViewModel/SettingsVM.cs Outdated
Guard missing icon_search.png with a clear Logger.LogError path, reuse
one Bitmap across RatEye reconfigs, make TryGetItemById cache-only and
game-mode-scoped so scans never queue fetches or leak cross-mode data,
and drop the dead ToolTipDuration parse on settings save.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@RatScanner/RatScannerMain.cs`:
- Around line 215-233: Update CreateInspectionConfig so a missing
RatConfig.Paths.SearchIcon does not continue to new Bitmap(path). After logging
the existing actionable guidance, throw an exception using that same custom
message so the user-facing failure includes reinstall/update instructions and
avoids the generic FileNotFoundException.

In `@RatScanner/ViewModel/SettingsVM.cs`:
- Around line 171-173: Update HotkeyManager.UnregisterHotkeys() to dispose and
clear CloseInteractableOverlayHotkey alongside the other hotkeys. Ensure
RegisterHotkeys() can safely create a new Escape listener after each save
without retaining prior subscriptions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: c772bfbd-fa26-4b49-a233-19f9db183de4

📥 Commits

Reviewing files that changed from the base of the PR and between 21a88d6 and 44518ea.

📒 Files selected for processing (3)
  • RatScanner/RatScannerMain.cs
  • RatScanner/TarkovDevAPI.cs
  • RatScanner/ViewModel/SettingsVM.cs

Comment on lines +215 to +233
private Config.Processing.Inspection CreateInspectionConfig() {
if (_searchMarker == null) {
string path = RatConfig.Paths.SearchIcon;
if (!File.Exists(path)) {
Logger.LogError(
$"Search icon not found at: {path}\n\n" +
"Name scan requires Data/icon_search.png. Reinstall or update RatScanner so the full package is present.");
}

_searchMarker = new Bitmap(path);
Logger.LogInfo($"Loaded name-scan marker {_searchMarker.Width}x{_searchMarker.Height} from {path}");
}

// MarkerItemScale is calibrated to template width: in-game icon is ~16px at 1080p
return new Config.Processing.Inspection() {
Marker = _searchMarker,
MarkerItemScale = 16f / _searchMarker.Width,
};
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Missing-file check logs but still crashes with an unhelpful exception.

The File.Exists check at line 218 logs a helpful message, but execution falls through to new Bitmap(path) at line 224, which throws FileNotFoundException with a generic .NET message. The user sees an unhandled exception dialog with no actionable guidance — the helpful text is only in the log file. This partially addresses the prior review's concern but leaves the user-facing crash experience unimproved.

🛡️ Proposed fix: throw with the custom message
 private Config.Processing.Inspection CreateInspectionConfig() {
 	if (_searchMarker == null) {
 		string path = RatConfig.Paths.SearchIcon;
 		if (!File.Exists(path)) {
 			Logger.LogError(
 				$"Search icon not found at: {path}\n\n" +
 				"Name scan requires Data/icon_search.png. Reinstall or update RatScanner so the full package is present.");
-		}
-
-		_searchMarker = new Bitmap(path);
+			throw new FileNotFoundException(
+				"Search icon file is missing. Name scan requires Data/icon_search.png. Reinstall or update RatScanner so the full package is present.",
+				path);
+		}
+
+		_searchMarker = new Bitmap(path);
 		Logger.LogInfo($"Loaded name-scan marker {_searchMarker.Width}x{_searchMarker.Height} from {path}");
 	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@RatScanner/RatScannerMain.cs` around lines 215 - 233, Update
CreateInspectionConfig so a missing RatConfig.Paths.SearchIcon does not continue
to new Bitmap(path). After logging the existing actionable guidance, throw an
exception using that same custom message so the user-facing failure includes
reinstall/update instructions and avoids the generic FileNotFoundException.

Comment on lines +171 to +173
} finally {
RatScannerMain.Instance.HotkeyManager.RegisterHotkeys();
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify CloseInteractableOverlayHotkey disposal coverage in HotkeyManager
rg -n "CloseInteractableOverlayHotkey" RatScanner/HotkeyManager.cs -C3

Repository: tarkovtracker-org/RatScanner

Length of output: 1587


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== HotkeyManager.cs ==\n'
sed -n '1,140p' RatScanner/HotkeyManager.cs

printf '\n== ActiveHotkey definitions/usages ==\n'
rg -n "class ActiveHotkey|Dispose\(|CloseInteractableOverlayHotkey|UnregisterHotkeys\(" RatScanner -C 3

printf '\n== SettingsVM save path around the finally block ==\n'
sed -n '150,190p' RatScanner/ViewModel/SettingsVM.cs

Repository: tarkovtracker-org/RatScanner

Length of output: 16283


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== ActiveHotkey.cs ==\n'
sed -n '1,180p' RatScanner/ActiveHotkey.cs

printf '\n== RatScannerMain.cs around HotkeyManager startup ==\n'
sed -n '80,110p' RatScanner/RatScannerMain.cs

printf '\n== Any explicit CloseInteractableOverlayHotkey disposal elsewhere ==\n'
rg -n "CloseInteractableOverlayHotkey.*Dispose|Dispose\(\).*CloseInteractableOverlayHotkey|CloseInteractableOverlayHotkey" RatScanner -C 2

Repository: tarkovtracker-org/RatScanner

Length of output: 8360


Dispose CloseInteractableOverlayHotkey in HotkeyManager.UnregisterHotkeys()
UnregisterHotkeys() disposes the other three hotkeys but leaves CloseInteractableOverlayHotkey subscribed. With RegisterHotkeys() reassigning that field each time, every save leaves the previous Escape listener alive and adds another one.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@RatScanner/ViewModel/SettingsVM.cs` around lines 171 - 173, Update
HotkeyManager.UnregisterHotkeys() to dispose and clear
CloseInteractableOverlayHotkey alongside the other hotkeys. Ensure
RegisterHotkeys() can safely create a new Escape listener after each save
without retaining prior subscriptions.

Comment thread .vscode/launch.json

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the .vscode/ dir is not on the .gitignore normally?

Comment thread .vscode/tasks.json

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same for this one

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is no automatic CI/CD to upgrade version and create release?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L This PR changes 100-499 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants