diff --git a/src/Poe2Trade.Inventory/StashCalibrator.cs b/src/Poe2Trade.Inventory/StashCalibrator.cs
index 105e9f0..a528ee1 100644
--- a/src/Poe2Trade.Inventory/StashCalibrator.cs
+++ b/src/Poe2Trade.Inventory/StashCalibrator.cs
@@ -16,7 +16,8 @@ public class StashCalibrator
private static readonly Region SubTabRegion = new(23, 165, 840, 50);
// Horizontal gap (px) between OCR words to split into separate tab names
private const int TabGapThreshold = 25;
- private const int PostClickDelay = 600;
+ private const int PostTabClickMin = 120;
+ private const int PostTabClickMax = 250;
public StashCalibrator(IScreenReader screen, IGameController game)
{
@@ -27,21 +28,24 @@ public class StashCalibrator
///
/// Calibrates an already-open stash/shop panel.
/// OCRs tab bar, clicks each tab, detects folders and grid size.
+ /// When firstFolderOnly is true (shop), only the first folder is inspected.
///
- public async Task CalibrateOpenPanel()
+ public async Task CalibrateOpenPanel(bool firstFolderOnly = false)
{
var tabs = await OcrTabBar(TabBarRegion);
Log.Information("StashCalibrator: found {Count} tabs: {Names}",
tabs.Count, string.Join(", ", tabs.Select(t => t.Name)));
- for (var i = 0; i < tabs.Count; i++)
+ var limit = firstFolderOnly ? Math.Min(1, tabs.Count) : tabs.Count;
+
+ for (var i = 0; i < limit; i++)
{
var tab = tabs[i];
tab.Index = i;
// Click this tab
await _game.LeftClickAt(tab.ClickX, tab.ClickY);
- await Helpers.Sleep(PostClickDelay);
+ await Helpers.RandomDelay(PostTabClickMin, PostTabClickMax);
// Check for sub-tabs (folder detection)
var subTabs = await OcrTabBar(SubTabRegion);
@@ -58,7 +62,7 @@ public class StashCalibrator
// Click sub-tab to detect its grid size
await _game.LeftClickAt(sub.ClickX, sub.ClickY);
- await Helpers.Sleep(PostClickDelay);
+ await Helpers.RandomDelay(PostTabClickMin, PostTabClickMax);
sub.GridCols = await DetectGridSize(isFolder: true);
}
@@ -73,6 +77,10 @@ public class StashCalibrator
}
}
+ // For firstFolderOnly, trim to only the inspected tabs
+ if (firstFolderOnly && tabs.Count > limit)
+ tabs = tabs.GetRange(0, limit);
+
return new StashCalibration
{
Tabs = tabs,
diff --git a/src/Poe2Trade.Ui/App.axaml.cs b/src/Poe2Trade.Ui/App.axaml.cs
index 1fe3ca7..d177b9f 100644
--- a/src/Poe2Trade.Ui/App.axaml.cs
+++ b/src/Poe2Trade.Ui/App.axaml.cs
@@ -66,6 +66,7 @@ public partial class App : Application
var window = new MainWindow { DataContext = mainVm };
window.SetConfigStore(store);
desktop.MainWindow = window;
+ desktop.ShutdownMode = Avalonia.Controls.ShutdownMode.OnMainWindowClose;
var overlay = new OverlayWindow(bot);
overlay.Show();
diff --git a/src/Poe2Trade.Ui/ViewModels/DebugViewModel.cs b/src/Poe2Trade.Ui/ViewModels/DebugViewModel.cs
index fd8875f..5f0ff79 100644
--- a/src/Poe2Trade.Ui/ViewModels/DebugViewModel.cs
+++ b/src/Poe2Trade.Ui/ViewModels/DebugViewModel.cs
@@ -212,7 +212,7 @@ public partial class DebugViewModel : ObservableObject
// Focus game and open stash
await _bot.Game.FocusGame();
- await Helpers.Sleep(Delays.PostFocus);
+ await Helpers.RandomDelay(150, 300);
var stashPos = await _bot.Inventory.FindAndClickNameplate("STASH");
if (!stashPos.HasValue)
@@ -220,30 +220,30 @@ public partial class DebugViewModel : ObservableObject
DebugResult = "STASH nameplate not found. Stand near your stash.";
return;
}
- await Helpers.Sleep(Delays.PostStashOpen);
+ await Helpers.RandomDelay(300, 500);
// Calibrate stash
var stashCal = await calibrator.CalibrateOpenPanel();
// Close stash, try shop
await _bot.Game.PressEscape();
- await Helpers.Sleep(Delays.PostEscape);
+ await Helpers.RandomDelay(200, 400);
StashCalibration? shopCal = null;
var angePos = await _bot.Inventory.FindAndClickNameplate("ANGE");
if (angePos.HasValue)
{
- await Helpers.Sleep(Delays.PostStashOpen);
+ await Helpers.RandomDelay(300, 500);
// ANGE opens a dialog — click "Manage Shop" to open shop tabs
var managePos = await _bot.Screen.FindTextOnScreen("Manage Shop", fuzzy: true);
if (managePos.HasValue)
{
await _bot.Game.LeftClickAt(managePos.Value.X, managePos.Value.Y);
- await Helpers.Sleep(Delays.PostStashOpen);
+ await Helpers.RandomDelay(300, 500);
}
- shopCal = await calibrator.CalibrateOpenPanel();
+ shopCal = await calibrator.CalibrateOpenPanel(firstFolderOnly: true);
await _bot.Game.PressEscape();
- await Helpers.Sleep(Delays.PostEscape);
+ await Helpers.RandomDelay(200, 400);
}
// Save