Skip to content

Vendor RatEye into monorepo and update name-scan marker - #2

Merged
DysektAI merged 74 commits into
masterfrom
feat/vendor-rateye
Jul 21, 2026
Merged

Vendor RatEye into monorepo and update name-scan marker#2
DysektAI merged 74 commits into
masterfrom
feat/vendor-rateye

Conversation

@DysektAI

@DysektAI DysektAI commented Jul 11, 2026

Copy link
Copy Markdown
Member

User description

Summary

  • Vendor RatEye v4.0.1 sources into RatEye/ and switch RatScanner from the NuGet package to an in-repo ProjectReference, so scan/marker/OCR changes ship with the app in one PR.
  • Align RatEye package versions with the app (RatStash 6.0.0, System.Drawing.Common 8.0.7), disable NuGet packaging on the vendored project, and document the layout in RatEye/VENDOR.md and AGENTS.md.
  • Update the name-scan magnifier marker to the post-patch template (embedded in RatEye resources + RatScanner/Data/icon_search.png override) and set MarkerItemScale to 16/28.

Test plan

  • dotnet restore RatScanner.sln
  • dotnet build RatScanner.sln (Debug) — 0 errors
  • dotnet build RatScanner.sln -c Release — 0 errors
  • Confirm CI Build workflow passes on this PR
  • Smoke-run the app and verify name-scan / icon-scan still work with the new marker template

CodeAnt-AI Description

Ship RatEye with the app and update scan detection to the new marker

What Changed

  • The image-processing library now lives in the repository and is built with RatScanner, so scan and OCR updates ship together with the app
  • Name-scan uses the updated magnifier marker template and the new marker scale, which improves detection with the current in-game UI
  • Inventory and item scanning now include the current item backgrounds, highlighted inventory support, and rotated icon handling
  • App startup now uses the in-repo processing library instead of a separate package

Impact

✅ Fewer broken scans after UI changes
✅ More reliable name and item detection
✅ Cleaner marker matching on current inspection windows

💡 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.

DysektAI added 2 commits July 11, 2026 15:34
Bring RatEye v4.0.1 sources under RatEye/ and wire the app via
ProjectReference so scan/marker changes land with the app. Align
RatStash and System.Drawing.Common with the app major versions, disable
package publish on the vendored project, and document the layout.
Convert provided WebP (28x28) to PNG for System.Drawing, embed it in
RatEye resources, set MarkerItemScale to 16/28, and ship a Data copy.
@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR forks RatScanner as the "TarkovTracker Edition," removing the legacy application and rebuilding it as a new App project targeting .NET 10, alongside an in-repo vendored RatEye scan engine, restructured integrations (TarkovDev, TarkovTracker, display detection), a Blazor UI, presentation layer, expanded tooling/CI/documentation, and a new xUnit test suite.

Estimated code review effort: 5 (Critical) | ~180 minutes

Changes

RatScanner TarkovTracker Edition rewrite

Layer / File(s) Summary
Repository tooling, CI, scripts, and documentation
.editorconfig, .gitattributes, .gitignore, .github/..., docs/agent-context/*, scripts/*, AGENTS.md, CONTRIBUTING.md, README.md, BACKLOG.md, .vscode/*, dotnet-tools.json, package.json
Adds formatting/lint config, CI workflow with vulnerability audits and release automation, dev/publish/data-setup scripts, agent-context documentation, and repo hygiene updates for the TarkovTracker fork.
Legacy RatScanner application (superseded)
RatScanner/**
Old RatScanner/ project source shown as removed/reformatted, superseded by the new src/App project.
Vendored RatEye scan engine
src/ScanEngine/**
Adds the in-tree RatEye engine (config, icon manager, OCR/inspection/inventory processing, resources) referenced via ProjectReference instead of NuGet.
New App host, config, hotkeys, scan pipeline, and integrations
src/App/*.cs, src/App/TarkovDev/*, src/App/Display/*, src/App/FetchModels/*, src/App/Scan/*, src/App/Presentation/*, src/App/View/*.xaml.cs
Establishes App startup/runtime, RatConfig, hotkey/scan pipeline, TarkovDevAPI/TarkovTrackerDB/display detection integrations, presentation adapters, and GitHubUpdateService.
App settings persistence, hotkeys, and settings VM
SettingsPersistenceService.cs, SettingsVM.cs, HotkeySelector.razor, ImmediateSettingSwitch.razor
Adds atomic settings persistence, hotkey capture UI, and the game-display/settings draft view model.
App Blazor UI, pages, layouts, and localization
src/App/Pages/**, src/App/Shared/**, src/App/Components/**, src/App/wwwroot/**, src/App/i18n/**
Adds Blazor scan/settings/history/credits pages, shared layouts, dialogs, theme CSS, and translated locale catalogs.
Test suite
tests/RatScanner.Tests/**
Adds unit/integration tests for config migration, display detection, presentation services, OpenCV/RatEye processing, localization, and TarkovTracker reliability.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.21% 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 clearly matches the main change: vendoring RatEye and updating the name-scan marker.
Description check ✅ Passed The description accurately summarizes vendoring RatEye, switching to a project reference, and updating the marker template.
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
  • Commit unit tests in branch feat/vendor-rateye

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

@codeant-ai codeant-ai Bot added the size:XXL This PR changes 1000+ lines, ignoring generated files label Jul 11, 2026
@socket-security

socket-security Bot commented Jul 11, 2026

Copy link
Copy Markdown

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Action Severity Alert  (click "▶" to expand/collapse)
Warn High
Obfuscated code: nuget runtime.debian.8-x64.runtime.native.system.security.cryptography.openssl is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: src/App/RatScanner.csprojnuget/ratstash@6.0.0nuget/runtime.debian.8-x64.runtime.native.system.security.cryptography.openssl@4.3.0

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore nuget/runtime.debian.8-x64.runtime.native.system.security.cryptography.openssl@4.3.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
Obfuscated code: nuget runtime.ubuntu.14.04-x64.runtime.native.system.security.cryptography.openssl is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: src/App/RatScanner.csprojnuget/ratstash@6.0.0nuget/runtime.ubuntu.14.04-x64.runtime.native.system.security.cryptography.openssl@4.3.0

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore nuget/runtime.ubuntu.14.04-x64.runtime.native.system.security.cryptography.openssl@4.3.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
Obfuscated code: nuget system.net.http is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: src/App/RatScanner.csprojnuget/ratstash@6.0.0nuget/system.net.http@4.3.0

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore nuget/system.net.http@4.3.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
High CVE: .NET Core Information Disclosure in nuget system.net.http

CVE: GHSA-7jgj-8wvc-jh57 .NET Core Information Disclosure (HIGH)

Affected versions: < 4.3.4

Patched version: 4.3.4

From: src/App/RatScanner.csprojnuget/ratstash@6.0.0nuget/system.net.http@4.3.0

ℹ Read more on: This package | This alert | What is a CVE?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Remove or replace dependencies that include known high severity CVEs. Consumers can use dependency overrides or npm audit fix --force to remove vulnerable dependencies.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore nuget/system.net.http@4.3.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
Obfuscated code: nuget system.reflection.emit.ilgeneration is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: src/ScanEngine/RatEye.csprojnuget/tesseract@5.2.0nuget/ratstash@6.0.0nuget/system.reflection.emit.ilgeneration@4.7.0

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore nuget/system.reflection.emit.ilgeneration@4.7.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

Comment thread RatEye/Config/Path.cs Outdated
Comment thread RatEye/Config/Processing/Inspection.cs Outdated
Comment thread RatEye/Processing/Icon.cs Outdated
Comment thread RatEye/Processing/Inventory.cs Outdated
Comment thread RatEye/Processing/Inventory.cs Outdated
Comment thread RatEye/Processing/MultiInspection.cs Outdated
Comment thread RatEye/Processing/MultiInspection.cs Outdated
Comment thread RatEye/Properties/Resources.resx Outdated
Comment thread RatEye/Config/Path.cs Outdated
Comment thread RatEye/Processing/Inspection.cs Outdated
Comment thread RatEye/Processing/Icon.cs Outdated
Comment thread RatEye/Processing/Icon.cs Outdated
Comment thread RatEye/IconManager.cs Outdated
Comment thread RatEye/IconManager.cs Outdated
@kilo-code-bot

This comment was marked as resolved.

Comment thread RatEye/Extensions.cs Outdated
Comment thread RatEye/Extensions.cs Outdated
Comment thread RatEye/Logger.cs Outdated
Comment thread RatEye/Processing/Inspection.cs Outdated
Comment thread RatEye/Processing/Inspection.cs Outdated
Comment thread RatEye/Processing/Inspection.cs Outdated
Comment thread .github/workflows/build.yml Fixed
Comment thread src/App/Scan/ItemQueue.cs
Comment thread RatScanner/TarkovDevAPI.cs Outdated
Comment thread RatScanner/TarkovDevAPI.cs Outdated
Comment thread RatScanner/ViewModel/MenuVM.cs Outdated
Comment thread src/ScanEngine/RatEyeEngine.cs
@DysektAI DysektAI self-assigned this Jul 13, 2026
Comment thread RatScanner/Pages/App/Index.razor Outdated
DysektAI added 7 commits July 13, 2026 11:42
Production reliability
- Do not terminate the process for missing/corrupt maps.json or failed
  remote resource downloads; Logger.LogError exits, so use LogWarning.
- Keep icon scans alive when Data/icons is absent by degrading to empty
  matches instead of throwing from EnsureStaticIconsLoaded.
- Prevent offering pre-release GitHub updates to stable installs.
- Null-coalesce ItemIconScan.IconPath; tolerate missing screens during
  full-screen name scan; use a seed placeholder when ItemQueue is empty.
- Use LazyThreadSafetyMode.ExecutionAndPublication for TarkovDevAPI
  request deduplication.

Dead code and asset cleanup
These were confirmed unreferenced at runtime (call-site + history audit):
- Remove unused Discord OAuth stack (AuthService, OAuth2) and legacy
  api.ratscanner.com ApiManager resource client, kept only for abandoned
  patronage/updater flows after GitHub-update migration.
- Drop OAuthRefreshToken config, Paths.Updater, unused Patreon/Discord
  SVG constants, and unused DeepCloner/upgrade-assistant packages.
- Delete orphaned WPF assets left after 2021 UI rewrite: iconMods.png
  (old HasMods badge) and settings.png (old settings button), now
  replaced by MudBlazor Material icons.
- Delete unused Data/icon_search.png duplicate; RatEye embeds the name-
  scan magnifier as the sole marker source.
- Delete unused bender fonts (theme uses Segoe UI; fonts were already
  excluded from publish).
- Delete dead ASP.NET Error.cshtml stubs, WindowsServices click-through
  helper, empty CSS stubs, and unused Resource model.

Why
- Reliability fixes prevent non-fatal data/network issues from becoming
  full app exits, and stop accidental beta auto-updates.
- Cleanup reduces maintenance cost and repo bulk without changing product
  behavior: removed paths had zero live consumers since the WPF to Blazor
  shell migration and GitHub-based updates.

Verified: dotnet test RatScanner.sln (71 passed).
Day-to-day coding should use Debug + dotnet watch, not a full
single-file publish. This makes that path one command and documents
it clearly.

Added
- dev.bat / scripts/dev.ps1: ensure Data, restore, then
  `dotnet watch --non-interactive --no-hot-reload run`
  (restart-on-save; WPF/WebView2 hot reload is not reliable)
- scripts/Expand-Zip.ps1: Expand-Archive -> ZipFile -> python
  so setup/publish work when PowerShell Archive fails

Hardened
- setup-data.ps1: skip if Data already valid, -Force re-download,
  curl fallback, nested archive layout handling
- publish.bat: shared zip helper, error checks, Data validation,
  overwriteable zip; tip to use dev.bat for iteration
- RatScanner.csproj: exclude Data/** from DefaultItemExcludes and
  mark Content Watch=false so ~4k icons do not flood the watcher
  while still copying Data into bin/publish
- BlazorUI dispose: null-safe WebView dispose for clean restarts

Docs
- README + AGENTS: local workflow, dev vs publish, hot-reload note
Delete leftover watch-verify/watch-test stdout/stderr captures from
local tooling checks and keep them out of git status going forward.
Rename project folders so the monorepo no longer looks like nested
product repos at the root. Assemblies and C# namespaces are unchanged
(RatScanner app, RatEye engine) to avoid a huge API churn.

Layout
- RatScanner/      -> src/App/
- RatEye/          -> src/ScanEngine/
- RatScanner.Tests/ -> tests/RatScanner.Tests/

Wiring
- RatScanner.sln project paths
- ProjectReference paths (App -> ScanEngine, Tests -> App)
- publish.bat, CI workflow, setup-data/dev/bench scripts
- gitignore Data path: src/App/Data

Docs
- README + AGENTS: new layout, Data path, local commands
- ScanEngine/VENDOR.md: provenance + explicit license note
  (upstream RatEye still has no LICENSE file)

Local Data remains gitignored under src/App/Data.
@DysektAI
DysektAI dismissed stale reviews from coderabbitai[bot], coderabbitai[bot], coderabbitai[bot], coderabbitai[bot], coderabbitai[bot], coderabbitai[bot], coderabbitai[bot], coderabbitai[bot], coderabbitai[bot], and coderabbitai[bot] July 20, 2026 16:46

All actionable findings in this superseded bot review have been addressed or triaged; all review threads are resolved and current local/CI validation is green.

coderabbitai[bot]

This comment was marked as resolved.

@DysektAI

Copy link
Copy Markdown
Member Author

Addressed the latest CodeRabbit finding in e64e7cf: the cancellation/rollback regression test now explicitly records and asserts that the throwing restore delegate was invoked, so the test cannot pass from cancellation alone. Focused test: 3/3 passed; full Release build: 0 warnings/errors; full tests: 196/196 passed.

@DysektAI
DysektAI dismissed coderabbitai[bot]’s stale review July 20, 2026 17:42

Addressed in e64e7cf with an explicit restoreAttempted assertion; focused and full test suites pass, and the review thread is resolved.

DysektAI added 2 commits July 21, 2026 04:12
…ant scanner status section

The IconScan and OpenInteractableOverlay hotkeys were constructed with
three positional arguments, which C# resolved to the 3-param
ActiveHotkey constructor (Hotkey, handler, bool suppressHotkey) instead
of the 5-param one (Hotkey, handler, bool enabled, bool suppressHotkey,
Func? canHandle). IconScan.Enable (true) was silently passed as
suppressHotkey, so the low-level mouse/keyboard hook swallowed
LBUTTONUP and Shift KEYUP events via return 1 instead of calling
CallNextHookEx. The game never saw the button/key release, leaving both
Shift and Left Click logically stuck (Alt+Tab cycled backwards, drag
selection never ended).

Fix: pass enabled/suppressHotkey explicitly by name so overload
resolution selects the 5-param constructor. SuppressHotkey is now
always false for scan hotkeys, so hook events pass through to the OS.

Also removes the redundant "Scanner status" section from the scanning
settings page — the toolbar already shows scanner status via the
ScannerStatus component in the top-right of the app. Removes the
ScanningStatusSection and ScanningStatusDescription i18n keys from all
seven locales.

Adds debug logging through the mouse/keyboard hook -> ActiveHotkey ->
HotkeyManager -> RatScannerMain scan pipeline to aid future diagnosis.
Adds .html/.js to the dev.ps1 file watcher so wwwroot edits trigger
rebuilds.
Collapse the two identical fire-and-forget ActivateTrackerModeAsync +
ContinueWith(OnlyOnFaulted) blocks (PvP source and team visibility
changes) into a single RefreshTrackerInBackground(failureMessage) helper.
Behavior is unchanged and the race/generation safety comment is preserved.
@greptile-apps

This comment was marked as resolved.

@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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (10)
scripts/dev.ps1 (4)

41-47: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Reject non-positive debounce values.

-Debounce 0 removes the quiet period, while negative values also bypass the -lt $Debounce check at Line [241]. Validate the parameter as a positive integer.

Proposed fix
-    [int]$Debounce = 15,
+    [ValidateRange(1, 2147483647)]
+    [int]$Debounce = 15,
🤖 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 `@scripts/dev.ps1` around lines 41 - 47, Update the parameter validation in
scripts/dev.ps1 for the Debounce parameter to reject zero and negative values,
requiring a positive integer while preserving the existing default and
NoDebounce behavior.

101-105: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Add a UTF-8 BOM or use ASCII-only text.

PSScriptAnalyzer flags this file as missing a BOM while it contains Unicode punctuation. Since dev.bat invokes Windows PowerShell, save the script as UTF-8 with BOM to avoid garbled output.

🤖 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 `@scripts/dev.ps1` around lines 101 - 105, Update scripts/dev.ps1 encoding to
UTF-8 with a BOM, preserving the existing Unicode punctuation and script
behavior so Windows PowerShell invoked by dev.bat displays output correctly.

Source: Linters/SAST tools


175-183: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Handle FileSystemWatcher errors and dropped events.

FileSystemWatcher raises Error when monitoring fails or its buffer overflows; overflowed events are lost. Without recovery, the app can remain stale until another filesystem event arrives. (learn.microsoft.com)

Register an Error handler that marks the state dirty and triggers a rebuild or watcher recreation.

🤖 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 `@scripts/dev.ps1` around lines 175 - 183, Register an Error event handler
alongside the existing Changed, Created, Deleted, and Renamed subscriptions for
the FileSystemWatcher created in the watcher setup. Ensure the handler marks the
synchronization state dirty and triggers the existing rebuild or
watcher-recreation flow so monitoring recovers after failures or buffer
overflows.

Source: MCP tools


190-196: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Wait for the old process to exit before rebuilding

Stop-AppProcess ignores the WaitForExit(5000) result, so a failed kill or a slow shutdown can still let the rebuild path launch a second app instance. Check the return value and stop the restart flow if the process is still running.

🤖 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 `@scripts/dev.ps1` around lines 190 - 196, Update Stop-AppProcess to check the
result of WaitForExit(5000) after taskkill; if the process remains running,
signal failure and prevent the rebuild/restart flow from launching another app
instance, while preserving the existing behavior for processes that exit
successfully.

Source: MCP tools

src/App/Pages/App/Settings/SettingsTracking.razor (4)

91-115: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Prevent switching PvP credential sources during validation.

The source radio remains editable while an Org or IO test is running. A user can start an Org test, switch to IO, and start an IO test; both workflows may then persist tokens and update PvpSource, with completion order deciding which credential becomes active. Disable source changes while either workflow is testing and defensively guard both connect methods.

As per coding guidelines, meaningful App Razor defects should be fixed, validated, and covered with focused regression tests.

Also applies to: 326-331, 339-343, 454-458

🤖 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 `@src/App/Pages/App/Settings/SettingsTracking.razor` around lines 91 - 115,
Prevent PvP source changes while either Org or IO validation is active by
disabling the MudRadioGroup around _pvpDraftSource and enforcing the same guard
in both connect methods referenced by the affected ranges. Ensure guarded
methods return without testing, persisting tokens, or updating PvpSource when
validation is already running, and add focused regression coverage for the
concurrent-switch scenario.

Source: Coding guidelines


424-445: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Reactivate the tracker after Org-to-IO fallback.

After switching PvpSource to IO, IsIoCredential(mode) becomes true, so the condition at Line [444] skips ActivateTrackerModeAsync. An active PvP session can therefore continue using the removed Org token while the UI reports IO as the active credential.

Suggested adjustment
-        if (RatConfig.GameMode == mode && !IsIoCredential(mode))
+        if (RatConfig.GameMode == mode)
             await RatScannerMain.Instance.ActivateTrackerModeAsync(mode);

Then synchronize _ioState or _orgState[mode] from the post-activation database state.

As per coding guidelines, meaningful App Razor defects should be fixed, validated, and covered with focused regression tests.

🤖 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 `@src/App/Pages/App/Settings/SettingsTracking.razor` around lines 424 - 445,
Update the Org-to-IO fallback flow around SetTarkovTrackerPvpSourceAsync so an
already-active tracker is reactivated after switching credentials, rather than
relying on the IsIoCredential(mode) guard to skip activation. Ensure the
activation uses the post-switch database state and synchronize the corresponding
_ioState or _orgState[mode] afterward; add focused regression coverage for this
fallback path.

Source: Coding guidelines


375-385: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Make credential and source updates atomic on failure.

The connect paths ignore the result of token rollback when source persistence fails. The removal paths delete the token first, then return without restoring it if source normalization fails, leaving configuration and UI state inconsistent. Use a transactional/compensating workflow, inspect rollback failures, and avoid rewriting PvpSource when it already has the desired value.

As per coding guidelines, meaningful App Razor defects should be fixed, validated, and covered with focused regression tests.

Also applies to: 435-439, 490-500, 549-564

🤖 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 `@src/App/Pages/App/Settings/SettingsTracking.razor` around lines 375 - 385,
Make the credential connect and removal flows in SettingsTracking transactional:
inspect the result of SetTarkovTrackerOrgTokenAsync rollback and preserve the
prior token/source when source normalization or persistence fails. In the
affected source-update paths, only call SetTarkovTrackerPvpSourceAsync when
PvpSource differs from the desired value, and keep UI/error state consistent for
rollback failures. Add focused regression tests covering connect and removal
failures, including unsuccessful compensating updates.

Source: Coding guidelines


702-711: 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

Avoid disposing the validation CTS from Dispose() while a connect task may still be running.
ConnectOrgAsync/ConnectIoAsync read validation.Token after awaits, so component teardown can cancel/dispose the same source before those continuations finish and hit ObjectDisposedException. Cancel here, but let the in-flight async owner dispose it after completion or coordinate shutdown first.

🤖 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 `@src/App/Pages/App/Settings/SettingsTracking.razor` around lines 702 - 711,
Update Dispose so it cancels, but does not dispose, the validation
CancellationTokenSource instances in _orgValidation and _ioValidation while
ConnectOrgAsync or ConnectIoAsync may still be running. Ensure each in-flight
async owner disposes its own source after completion, or coordinate teardown so
disposal occurs only after those continuations finish.

Source: Coding guidelines

src/App/ActiveHotkey.cs (1)

26-102: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Ambiguous constructor overloads are the root cause of the stuck-hotkey bug HotkeyManager.cs works around.

HotkeyManager.cs needs an 8-line comment (lines 54-60) to explain why callers must use named arguments, because two overloads here differ only by which positional bool slot they bind (suppressHotkey vs enabled) — exactly the ambiguity that previously caused stuck LBUTTONUP/Shift-KEYUP events. Fixing call sites with named args mitigates today's usage but leaves the trap in place for any future constructor call.

Consider replacing the overload set with distinctly-named static factory methods (e.g. ActiveHotkey.Create(...), ActiveHotkey.CreateWithHandling(...)) or making enabled/suppressHotkey/canHandle mandatory named-only parameters so a positional-argument mismatch fails to compile rather than silently binding to the wrong flag.

🤖 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 `@src/App/ActiveHotkey.cs` around lines 26 - 102, Replace the ambiguous
ActiveHotkey constructor overloads with distinct factory methods or an API
requiring enabled, suppressHotkey, and canHandle to be explicitly named, so
positional booleans cannot silently bind to the wrong option. Preserve the
existing initialization behavior and handler-registration flow across all
constructor variants, including the overloads taking Hotkey and keyboard/mouse
lists.
src/App/UserActivityHelper.cs (1)

382-427: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Debug instrumentation now runs unconditionally on the global, OS-wide input-hook thread. KeyboardHookProc/MouseHookProc are WH_KEYBOARD_LL/WH_MOUSE_LL callbacks that fire for input in every application on the system, and each subscribed ActiveHotkey.OnKeyUp/IsPressed runs synchronously inside that same callback before any Task.Run offload. The new logging in this PR (string interpolation plus a GetInvocationList() allocation) executes as an eagerly-evaluated call argument on every qualifying system-wide event, regardless of whether RatConfig.LogDebug is actually enabled — e.g. every keystroke release or mouse click anywhere on the OS now pays this cost. Low-level hooks are expected to return quickly to avoid Windows-enforced callback timeouts; sustained per-event overhead here risks the exact input-lag/stuck-key class of bug this PR is trying to fix.

  • src/App/UserActivityHelper.cs#L382-L427: gate the MouseHookProc debug logging (and the GetInvocationList().Length allocation) behind an early if (!Config.LogDebug) -style check, or drop it, so the cost isn't paid on every system-wide mouse event.
  • src/App/UserActivityHelper.cs#L291-L299: same treatment for the KeyboardHookProc modifier-key logging, which currently fires on every Shift/Ctrl/Alt press/release anywhere on the OS.
  • src/App/ActiveHotkey.cs#L120-L196: gate or remove the per-event Logger.LogDebug calls in OnKeyUp/IsPressed (including the per-key-in-loop logging), since these run once per ActiveHotkey instance for every matching system-wide event, compounding the hook-level overhead above.
🤖 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 `@src/App/UserActivityHelper.cs` around lines 382 - 427, Gate or remove the
per-event debug instrumentation on the low-level hook paths: in
src/App/UserActivityHelper.cs lines 382-427, guard MouseHookProc logging and
GetInvocationList allocation with Config.LogDebug; apply the same treatment to
modifier logging in KeyboardHookProc at lines 291-299. In
src/App/ActiveHotkey.cs lines 120-196, gate or remove per-event Logger.LogDebug
calls in OnKeyUp and IsPressed, including per-key loop logging, while preserving
event handling behavior.
🤖 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.

Outside diff comments:
In `@scripts/dev.ps1`:
- Around line 41-47: Update the parameter validation in scripts/dev.ps1 for the
Debounce parameter to reject zero and negative values, requiring a positive
integer while preserving the existing default and NoDebounce behavior.
- Around line 101-105: Update scripts/dev.ps1 encoding to UTF-8 with a BOM,
preserving the existing Unicode punctuation and script behavior so Windows
PowerShell invoked by dev.bat displays output correctly.
- Around line 175-183: Register an Error event handler alongside the existing
Changed, Created, Deleted, and Renamed subscriptions for the FileSystemWatcher
created in the watcher setup. Ensure the handler marks the synchronization state
dirty and triggers the existing rebuild or watcher-recreation flow so monitoring
recovers after failures or buffer overflows.
- Around line 190-196: Update Stop-AppProcess to check the result of
WaitForExit(5000) after taskkill; if the process remains running, signal failure
and prevent the rebuild/restart flow from launching another app instance, while
preserving the existing behavior for processes that exit successfully.

In `@src/App/ActiveHotkey.cs`:
- Around line 26-102: Replace the ambiguous ActiveHotkey constructor overloads
with distinct factory methods or an API requiring enabled, suppressHotkey, and
canHandle to be explicitly named, so positional booleans cannot silently bind to
the wrong option. Preserve the existing initialization behavior and
handler-registration flow across all constructor variants, including the
overloads taking Hotkey and keyboard/mouse lists.

In `@src/App/Pages/App/Settings/SettingsTracking.razor`:
- Around line 91-115: Prevent PvP source changes while either Org or IO
validation is active by disabling the MudRadioGroup around _pvpDraftSource and
enforcing the same guard in both connect methods referenced by the affected
ranges. Ensure guarded methods return without testing, persisting tokens, or
updating PvpSource when validation is already running, and add focused
regression coverage for the concurrent-switch scenario.
- Around line 424-445: Update the Org-to-IO fallback flow around
SetTarkovTrackerPvpSourceAsync so an already-active tracker is reactivated after
switching credentials, rather than relying on the IsIoCredential(mode) guard to
skip activation. Ensure the activation uses the post-switch database state and
synchronize the corresponding _ioState or _orgState[mode] afterward; add focused
regression coverage for this fallback path.
- Around line 375-385: Make the credential connect and removal flows in
SettingsTracking transactional: inspect the result of
SetTarkovTrackerOrgTokenAsync rollback and preserve the prior token/source when
source normalization or persistence fails. In the affected source-update paths,
only call SetTarkovTrackerPvpSourceAsync when PvpSource differs from the desired
value, and keep UI/error state consistent for rollback failures. Add focused
regression tests covering connect and removal failures, including unsuccessful
compensating updates.
- Around line 702-711: Update Dispose so it cancels, but does not dispose, the
validation CancellationTokenSource instances in _orgValidation and _ioValidation
while ConnectOrgAsync or ConnectIoAsync may still be running. Ensure each
in-flight async owner disposes its own source after completion, or coordinate
teardown so disposal occurs only after those continuations finish.

In `@src/App/UserActivityHelper.cs`:
- Around line 382-427: Gate or remove the per-event debug instrumentation on the
low-level hook paths: in src/App/UserActivityHelper.cs lines 382-427, guard
MouseHookProc logging and GetInvocationList allocation with Config.LogDebug;
apply the same treatment to modifier logging in KeyboardHookProc at lines
291-299. In src/App/ActiveHotkey.cs lines 120-196, gate or remove per-event
Logger.LogDebug calls in OnKeyUp and IsPressed, including per-key loop logging,
while preserving event handling behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 56135fc7-053b-4834-a0ed-a126ea1f1122

📥 Commits

Reviewing files that changed from the base of the PR and between e64e7cf and 03414b7.

📒 Files selected for processing (16)
  • scripts/dev.ps1
  • src/App/ActiveHotkey.cs
  • src/App/Components/ChangeConnectionDialog.razor
  • src/App/HotkeyManager.cs
  • src/App/Pages/App/Settings/SettingsScanning.razor
  • src/App/Pages/App/Settings/SettingsTracking.razor
  • src/App/RatScannerMain.cs
  • src/App/UserActivityHelper.cs
  • src/App/ViewModel/SettingsVM.cs
  • src/App/i18n/en.json
  • src/App/i18n/es.json
  • src/App/i18n/fr.json
  • src/App/i18n/pl.json
  • src/App/i18n/pt.json
  • src/App/i18n/ru.json
  • src/App/i18n/zh.json
💤 Files with no reviewable changes (1)
  • src/App/Pages/App/Settings/SettingsScanning.razor

Add a `deploy` boolean input to the Build workflow's workflow_dispatch so a
release can be cut from the GitHub Actions "Run workflow" button. The release
job now runs on either a v* tag push or a manual deploy, resolves the version
from src/App/RatScanner.csproj <Version>, refuses to overwrite an existing
tag/release on manual deploys, auto-creates the tag, and publishes the GitHub
release directly as Latest (draft: false, prerelease: false, make_latest: true).

Publishing as a non-prerelease Latest release is required for the in-app
updater, which reads /releases/latest (drafts and pre-releases are hidden
there). Bump product version to 4.0.0-beta and update release docs to match.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL This PR changes 1000+ lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants