From 32781b1462c6dd47effa20c26dedcc2cb7d79b27 Mon Sep 17 00:00:00 2001 From: Boki Date: Fri, 13 Feb 2026 09:52:06 -0500 Subject: [PATCH] work on inventory --- src/Poe2Trade.Bot/BotOrchestrator.cs | 12 +- src/Poe2Trade.Core/ConfigStore.cs | 1 + src/Poe2Trade.Inventory/IInventoryManager.cs | 2 + src/Poe2Trade.Inventory/InventoryManager.cs | 4 + src/Poe2Trade.Trade/TradeMonitor.cs | 2 +- src/Poe2Trade.Ui/App.axaml | 1 + .../Converters/ValueConverters.cs | 15 + .../ViewModels/MainWindowViewModel.cs | 18 ++ .../ViewModels/SettingsViewModel.cs | 4 + src/Poe2Trade.Ui/Views/MainWindow.axaml | 268 +++++++++--------- src/Poe2Trade.Ui/Views/MainWindow.axaml.cs | 59 +++- 11 files changed, 240 insertions(+), 146 deletions(-) diff --git a/src/Poe2Trade.Bot/BotOrchestrator.cs b/src/Poe2Trade.Bot/BotOrchestrator.cs index b25b12f..f54c813 100644 --- a/src/Poe2Trade.Bot/BotOrchestrator.cs +++ b/src/Poe2Trade.Bot/BotOrchestrator.cs @@ -181,14 +181,17 @@ public class BotOrchestrator : IAsyncDisposable await ocrWarmup; - Emit("info", "Checking inventory for leftover items..."); - await Inventory.ClearToStash(); - Emit("info", "Inventory cleared"); - // Wire executor events TradeExecutor.StateChanged += _ => UpdateExecutorState(); TradeQueue.TradeCompleted += () => { _tradesCompleted++; StatusUpdated?.Invoke(); }; TradeQueue.TradeFailed += () => { _tradesFailed++; StatusUpdated?.Invoke(); }; + Inventory.Updated += () => StatusUpdated?.Invoke(); + + _started = true; + + Emit("info", "Checking inventory for leftover items..."); + await Inventory.ClearToStash(); + Emit("info", "Inventory cleared"); // Load links var allUrls = new HashSet(cliUrls); @@ -207,7 +210,6 @@ public class BotOrchestrator : IAsyncDisposable // Wire trade monitor events TradeMonitor.NewListings += OnNewListings; - _started = true; Emit("info", $"Loaded {allUrls.Count} trade link(s)"); Log.Information("Bot started"); } diff --git a/src/Poe2Trade.Core/ConfigStore.cs b/src/Poe2Trade.Core/ConfigStore.cs index 1e438df..f617513 100644 --- a/src/Poe2Trade.Core/ConfigStore.cs +++ b/src/Poe2Trade.Core/ConfigStore.cs @@ -29,6 +29,7 @@ public class SavedSettings public double? WindowY { get; set; } public double? WindowWidth { get; set; } public double? WindowHeight { get; set; } + public bool Headless { get; set; } = true; } public class ConfigStore diff --git a/src/Poe2Trade.Inventory/IInventoryManager.cs b/src/Poe2Trade.Inventory/IInventoryManager.cs index dae69d5..cedc791 100644 --- a/src/Poe2Trade.Inventory/IInventoryManager.cs +++ b/src/Poe2Trade.Inventory/IInventoryManager.cs @@ -4,7 +4,9 @@ namespace Poe2Trade.Inventory; public interface IInventoryManager { + event Action? Updated; InventoryTracker Tracker { get; } + byte[]? LastScreenshot { get; } bool IsAtOwnHideout { get; } string SellerAccount { get; } void SetLocation(bool atHome, string? seller = null); diff --git a/src/Poe2Trade.Inventory/InventoryManager.cs b/src/Poe2Trade.Inventory/InventoryManager.cs index 00a4372..d36e60a 100644 --- a/src/Poe2Trade.Inventory/InventoryManager.cs +++ b/src/Poe2Trade.Inventory/InventoryManager.cs @@ -10,6 +10,7 @@ public class InventoryManager : IInventoryManager { private static readonly string SalvageTemplate = Path.Combine("assets", "salvage.png"); + public event Action? Updated; public InventoryTracker Tracker { get; } = new(); private bool _atOwnHideout = true; @@ -19,6 +20,7 @@ public class InventoryManager : IInventoryManager private readonly IClientLogWatcher _logWatcher; private readonly SavedSettings _config; + public byte[]? LastScreenshot { get; private set; } public bool IsAtOwnHideout => _atOwnHideout; public string SellerAccount => _sellerAccount; @@ -44,6 +46,7 @@ public class InventoryManager : IInventoryManager await _game.OpenInventory(); var result = await _screen.Grid.Scan("inventory"); + LastScreenshot = await _screen.CaptureRegion(GridLayouts.Inventory.Region); var cells = new bool[5, 12]; foreach (var cell in result.Occupied) @@ -52,6 +55,7 @@ public class InventoryManager : IInventoryManager cells[cell.Row, cell.Col] = true; } Tracker.InitFromScan(cells, result.Items, defaultAction); + Updated?.Invoke(); await _game.PressEscape(); await Helpers.Sleep(Delays.PostFocus); diff --git a/src/Poe2Trade.Trade/TradeMonitor.cs b/src/Poe2Trade.Trade/TradeMonitor.cs index cea1234..6f84d2a 100644 --- a/src/Poe2Trade.Trade/TradeMonitor.cs +++ b/src/Poe2Trade.Trade/TradeMonitor.cs @@ -52,7 +52,7 @@ public class TradeMonitor : ITradeMonitor _config.BrowserUserDataDir, new BrowserTypeLaunchPersistentContextOptions { - Headless = false, + Headless = _config.Headless, ViewportSize = null, Args = [ "--disable-blink-features=AutomationControlled", diff --git a/src/Poe2Trade.Ui/App.axaml b/src/Poe2Trade.Ui/App.axaml index 6ae79d7..ad15f76 100644 --- a/src/Poe2Trade.Ui/App.axaml +++ b/src/Poe2Trade.Ui/App.axaml @@ -13,5 +13,6 @@ + diff --git a/src/Poe2Trade.Ui/Converters/ValueConverters.cs b/src/Poe2Trade.Ui/Converters/ValueConverters.cs index 9706398..4315a2e 100644 --- a/src/Poe2Trade.Ui/Converters/ValueConverters.cs +++ b/src/Poe2Trade.Ui/Converters/ValueConverters.cs @@ -45,6 +45,7 @@ public class LinkModeToColorConverter : IValueConverter { LinkMode.Live => new SolidColorBrush(Color.Parse("#1f6feb")), LinkMode.Scrap => new SolidColorBrush(Color.Parse("#9e6a03")), + _ => new SolidColorBrush(Color.Parse("#30363d")), }; } @@ -79,6 +80,20 @@ public class ActiveOpacityConverter : IValueConverter => throw new NotSupportedException(); } +public class BoolToOverlayBrushConverter : IValueConverter +{ + public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + { + var occupied = value is true; + return occupied + ? new SolidColorBrush(Color.FromArgb(64, 56, 168, 50)) + : Brushes.Transparent; + } + + public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) + => throw new NotSupportedException(); +} + public class CellBorderConverter : IValueConverter { public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) diff --git a/src/Poe2Trade.Ui/ViewModels/MainWindowViewModel.cs b/src/Poe2Trade.Ui/ViewModels/MainWindowViewModel.cs index 5e8dbeb..d55c0f7 100644 --- a/src/Poe2Trade.Ui/ViewModels/MainWindowViewModel.cs +++ b/src/Poe2Trade.Ui/ViewModels/MainWindowViewModel.cs @@ -1,4 +1,6 @@ using System.Collections.ObjectModel; +using System.IO; +using Avalonia.Media.Imaging; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using Poe2Trade.Bot; @@ -39,6 +41,8 @@ public partial class MainWindowViewModel : ObservableObject [NotifyCanExecuteChangedFor(nameof(PauseCommand))] private bool _isStarted; + [ObservableProperty] private Bitmap? _inventoryImage; + [ObservableProperty] private string _newUrl = ""; [ObservableProperty] private string _newLinkName = ""; [ObservableProperty] private LinkMode _newLinkMode = LinkMode.Live; @@ -178,6 +182,20 @@ public partial class MainWindowViewModel : ObservableObject } } + var bytes = _bot.Inventory.LastScreenshot; + if (bytes != null) + { + var old = InventoryImage; + InventoryImage = new Bitmap(new MemoryStream(bytes)); + old?.Dispose(); + } + else + { + var old = InventoryImage; + InventoryImage = null; + old?.Dispose(); + } + OnPropertyChanged(nameof(InventoryFreeCells)); } } diff --git a/src/Poe2Trade.Ui/ViewModels/SettingsViewModel.cs b/src/Poe2Trade.Ui/ViewModels/SettingsViewModel.cs index 31d4b2d..0240770 100644 --- a/src/Poe2Trade.Ui/ViewModels/SettingsViewModel.cs +++ b/src/Poe2Trade.Ui/ViewModels/SettingsViewModel.cs @@ -14,6 +14,7 @@ public partial class SettingsViewModel : ObservableObject [ObservableProperty] private decimal? _stashScanTimeoutMs = 10000; [ObservableProperty] private decimal? _waitForMoreItemsMs = 20000; [ObservableProperty] private decimal? _betweenTradesDelayMs = 5000; + [ObservableProperty] private bool _headless = true; [ObservableProperty] private bool _isSaved; public SettingsViewModel(BotOrchestrator bot) @@ -31,6 +32,7 @@ public partial class SettingsViewModel : ObservableObject StashScanTimeoutMs = s.StashScanTimeoutMs; WaitForMoreItemsMs = s.WaitForMoreItemsMs; BetweenTradesDelayMs = s.BetweenTradesDelayMs; + Headless = s.Headless; } [RelayCommand] @@ -44,6 +46,7 @@ public partial class SettingsViewModel : ObservableObject s.StashScanTimeoutMs = (int)(StashScanTimeoutMs ?? 10000); s.WaitForMoreItemsMs = (int)(WaitForMoreItemsMs ?? 20000); s.BetweenTradesDelayMs = (int)(BetweenTradesDelayMs ?? 5000); + s.Headless = Headless; }); IsSaved = true; @@ -55,4 +58,5 @@ public partial class SettingsViewModel : ObservableObject partial void OnStashScanTimeoutMsChanged(decimal? value) => IsSaved = false; partial void OnWaitForMoreItemsMsChanged(decimal? value) => IsSaved = false; partial void OnBetweenTradesDelayMsChanged(decimal? value) => IsSaved = false; + partial void OnHeadlessChanged(bool value) => IsSaved = false; } diff --git a/src/Poe2Trade.Ui/Views/MainWindow.axaml b/src/Poe2Trade.Ui/Views/MainWindow.axaml index 4fa6f88..b4f27e0 100644 --- a/src/Poe2Trade.Ui/Views/MainWindow.axaml +++ b/src/Poe2Trade.Ui/Views/MainWindow.axaml @@ -3,14 +3,14 @@ xmlns:vm="using:Poe2Trade.Ui.ViewModels" x:Class="Poe2Trade.Ui.Views.MainWindow" x:DataType="vm:MainWindowViewModel" - Title="POE2 Trade Bot" - Width="960" Height="720" + Title="Automata" + Width="960" Height="640" Background="#0d1117"> - + - @@ -24,30 +24,30 @@ - - + - + - + @@ -66,134 +66,127 @@ - - - + + + + BorderThickness="1" CornerRadius="8" Padding="8" Margin="0,0,0,6"> - + - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - - - - - - - - - -