using Avalonia; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; using Microsoft.Extensions.DependencyInjection; using Automata.Bot; using Automata.Core; using Automata.Game; using Automata.GameLog; using Automata.Inventory; using Automata.Items; using Automata.Screen; using Automata.Screen.Ocr; using Automata.Trade; using Automata.Ui.Overlay; using Automata.Ui.ViewModels; using Automata.Ui.Views; namespace Automata.Ui; public partial class App : Application { public override void Initialize() { AvaloniaXamlLoader.Load(this); } public override void OnFrameworkInitializationCompleted() { if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { // Initialize Sidekick parser (fire-and-forget, non-blocking) _ = Task.Run(async () => { try { await SidekickBootstrapper.InitializeAsync(); } catch (Exception ex) { Serilog.Log.Warning(ex, "Sidekick init failed"); } }); var services = new ServiceCollection(); // Config services.AddSingleton(); services.AddSingleton(sp => sp.GetRequiredService().Settings); // Services services.AddSingleton(sp => { var settings = sp.GetRequiredService(); return OcrEngineFactory.Create(settings.OcrEngine); }); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(sp => new ClientLogWatcher(sp.GetRequiredService().GameLogPath)); services.AddSingleton(); services.AddSingleton(); // Bot services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); // ViewModels services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); var provider = services.BuildServiceProvider(); var store = provider.GetRequiredService(); var bot = provider.GetRequiredService(); var modPool = provider.GetRequiredService(); // Fire-and-forget: load RePoE data, then populate CraftingVM base items _ = Task.Run(async () => { await modPool.LoadAsync(); Avalonia.Threading.Dispatcher.UIThread.Post(() => { var craftVm = provider.GetRequiredService(); craftVm.LoadBaseItems(); }); }); var mainVm = provider.GetRequiredService(); mainVm.DebugVm = provider.GetRequiredService(); mainVm.SettingsVm = provider.GetRequiredService(); mainVm.MappingVm = provider.GetRequiredService(); mainVm.AtlasVm = provider.GetRequiredService(); mainVm.CraftingVm = provider.GetRequiredService(); mainVm.MemoryVm = provider.GetRequiredService(); mainVm.RobotoVm = provider.GetRequiredService(); mainVm.BrowserVm = provider.GetRequiredService(); var window = new MainWindow { DataContext = mainVm }; window.SetConfigStore(store); desktop.MainWindow = window; desktop.ShutdownMode = Avalonia.Controls.ShutdownMode.OnMainWindowClose; var overlay = new D2dOverlay(bot); overlay.Start(); desktop.ShutdownRequested += async (_, _) => { overlay.Shutdown(); mainVm.Shutdown(); mainVm.RobotoVm?.Shutdown(); await bot.DisposeAsync(); }; } base.OnFrameworkInitializationCompleted(); } }