mirror of
https://github.com/babalae/better-genshin-impact
synced 2025-01-07 03:17:16 +08:00
290 lines
10 KiB
C#
290 lines
10 KiB
C#
using BetterGenshinImpact.GameTask;
|
||
using BetterGenshinImpact.Helpers;
|
||
using BetterGenshinImpact.Helpers.Extensions;
|
||
using BetterGenshinImpact.Hutao;
|
||
using BetterGenshinImpact.Service;
|
||
using BetterGenshinImpact.Service.Interface;
|
||
using BetterGenshinImpact.Service.Notification;
|
||
using BetterGenshinImpact.Service.Notifier;
|
||
using BetterGenshinImpact.View;
|
||
using BetterGenshinImpact.View.Pages;
|
||
using BetterGenshinImpact.ViewModel;
|
||
using BetterGenshinImpact.ViewModel.Pages;
|
||
using Microsoft.Extensions.DependencyInjection;
|
||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||
using Microsoft.Extensions.Hosting;
|
||
using Microsoft.Extensions.Logging;
|
||
using Serilog;
|
||
using Serilog.Events;
|
||
using Serilog.Sinks.RichTextBox.Abstraction;
|
||
using System;
|
||
using System.Diagnostics;
|
||
using System.IO;
|
||
using System.Threading.Tasks;
|
||
using System.Windows;
|
||
using BetterGenshinImpact.View.Pages.View;
|
||
using BetterGenshinImpact.ViewModel.Pages.OneDragon;
|
||
using BetterGenshinImpact.ViewModel.Pages.View;
|
||
using Wpf.Ui;
|
||
using Wpf.Ui.Violeta.Controls;
|
||
|
||
namespace BetterGenshinImpact;
|
||
|
||
public partial class App : Application
|
||
{
|
||
// The.NET Generic Host provides dependency injection, configuration, logging, and other services.
|
||
// https://docs.microsoft.com/dotnet/core/extensions/generic-host
|
||
// https://docs.microsoft.com/dotnet/core/extensions/dependency-injection
|
||
// https://docs.microsoft.com/dotnet/core/extensions/configuration
|
||
// https://docs.microsoft.com/dotnet/core/extensions/logging
|
||
private static readonly IHost _host = Host.CreateDefaultBuilder()
|
||
.CheckIntegration()
|
||
.UseElevated()
|
||
.UseSingleInstance("BetterGI")
|
||
.ConfigureLogging(builder =>
|
||
{
|
||
builder.ClearProviders();
|
||
})
|
||
.ConfigureServices(
|
||
(context, services) =>
|
||
{
|
||
// 提前初始化配置
|
||
var configService = new ConfigService();
|
||
services.AddSingleton<IConfigService>(sp => configService);
|
||
var all = configService.Get();
|
||
|
||
var logFolder = Path.Combine(AppContext.BaseDirectory, "log");
|
||
Directory.CreateDirectory(logFolder);
|
||
var logFile = Path.Combine(logFolder, "better-genshin-impact.log");
|
||
|
||
var richTextBox = new RichTextBoxImpl();
|
||
services.AddSingleton<IRichTextBox>(richTextBox);
|
||
|
||
var loggerConfiguration = new LoggerConfiguration()
|
||
.WriteTo.File(path: logFile, outputTemplate: "[{Timestamp:HH:mm:ss.fff}] [{Level:u3}] {SourceContext}{NewLine}{Message}{NewLine}{Exception}{NewLine}", rollingInterval: RollingInterval.Day)
|
||
.MinimumLevel.Debug()
|
||
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
|
||
.MinimumLevel.Override("Microsoft.Hosting.Lifetime", LogEventLevel.Warning);
|
||
if (all.MaskWindowConfig.MaskEnabled)
|
||
{
|
||
loggerConfiguration.WriteTo.RichTextBox(richTextBox, LogEventLevel.Information, outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}");
|
||
}
|
||
|
||
Log.Logger = loggerConfiguration.CreateLogger();
|
||
services.AddLogging(c => c.AddSerilog());
|
||
|
||
// App Host
|
||
services.AddHostedService<ApplicationHostService>();
|
||
// Page resolver service
|
||
services.AddSingleton<IPageService, PageService>();
|
||
|
||
// Service containing navigation, same as INavigationWindow... but without window
|
||
services.AddSingleton<INavigationService, NavigationService>();
|
||
services.AddSingleton<ISnackbarService, SnackbarService>();
|
||
|
||
// Main window with navigation
|
||
services.AddView<INavigationWindow, MainWindow, MainWindowViewModel>();
|
||
services.AddSingleton<NotifyIconViewModel>();
|
||
|
||
// Views
|
||
services.AddView<HomePage, HomePageViewModel>();
|
||
services.AddView<ScriptControlPage, ScriptControlViewModel>();
|
||
services.AddView<TriggerSettingsPage, TriggerSettingsPageViewModel>();
|
||
services.AddView<MacroSettingsPage, MacroSettingsPageViewModel>();
|
||
services.AddView<CommonSettingsPage, CommonSettingsPageViewModel>();
|
||
services.AddView<TaskSettingsPage, TaskSettingsPageViewModel>();
|
||
services.AddView<HotKeyPage, HotKeyPageViewModel>();
|
||
// services.AddView<NotificationSettingsPage, NotificationSettingsPageViewModel>();
|
||
services.AddView<KeyMouseRecordPage, KeyMouseRecordPageViewModel>();
|
||
services.AddView<JsListPage, JsListViewModel>();
|
||
services.AddView<MapPathingPage, MapPathingViewModel>();
|
||
services.AddView<OneDragonFlowPage, OneDragonFlowViewModel>();
|
||
services.AddSingleton<PathingConfigViewModel>();
|
||
// services.AddView<PathingConfigView, PathingConfigViewModel>();
|
||
services.AddView<KeyBindingsSettingsPage, KeyBindingsSettingsPageViewModel>();
|
||
|
||
// 一条龙 ViewModels
|
||
// services.AddSingleton<CraftViewModel>();
|
||
// services.AddSingleton<DailyCommissionViewModel>();
|
||
// services.AddSingleton<DailyRewardViewModel>();
|
||
// services.AddSingleton<DomainViewModel>();
|
||
// services.AddSingleton<ForgingViewModel>();
|
||
// services.AddSingleton<LeyLineBlossomViewModel>();
|
||
// services.AddSingleton<MailViewModel>();
|
||
// services.AddSingleton<SereniteaPotViewModel>();
|
||
// services.AddSingleton<TcgViewModel>();
|
||
|
||
// My Services
|
||
services.AddSingleton<TaskTriggerDispatcher>();
|
||
services.AddSingleton<NotificationService>();
|
||
services.AddHostedService(sp => sp.GetRequiredService<NotificationService>());
|
||
services.AddSingleton<NotifierManager>();
|
||
services.AddSingleton<IScriptService, ScriptService>();
|
||
services.AddSingleton<HutaoNamedPipe>();
|
||
|
||
// Configuration
|
||
//services.Configure<AppConfig>(context.Configuration.GetSection(nameof(AppConfig)));
|
||
}
|
||
)
|
||
.Build();
|
||
|
||
public static ILogger<T> GetLogger<T>()
|
||
{
|
||
return _host.Services.GetService<ILogger<T>>()!;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Gets registered service.
|
||
/// </summary>
|
||
/// <typeparam name="T">Type of the service to get.</typeparam>
|
||
/// <returns>Instance of the service or <see langword="null"/>.</returns>
|
||
public static T? GetService<T>() where T : class
|
||
{
|
||
return _host.Services.GetService(typeof(T)) as T;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Gets registered service.
|
||
/// </summary>
|
||
/// <returns>Instance of the service or <see langword="null"/>.</returns>
|
||
/// <returns></returns>
|
||
public static object? GetService(Type type)
|
||
{
|
||
return _host.Services.GetService(type);
|
||
}
|
||
|
||
/// <summary>
|
||
/// Occurs when the application is loading.
|
||
/// </summary>
|
||
protected override async void OnStartup(StartupEventArgs e)
|
||
{
|
||
base.OnStartup(e);
|
||
|
||
try
|
||
{
|
||
RegisterEvents();
|
||
await _host.StartAsync();
|
||
await UrlProtocolHelper.RegisterAsync();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
// DEBUG only, no overhead
|
||
Debug.WriteLine(ex);
|
||
|
||
if (Debugger.IsAttached)
|
||
{
|
||
Debugger.Break();
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Occurs when the application is closing.
|
||
/// </summary>
|
||
protected override async void OnExit(ExitEventArgs e)
|
||
{
|
||
base.OnExit(e);
|
||
|
||
await _host.StopAsync();
|
||
_host.Dispose();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 注册事件
|
||
/// </summary>
|
||
private void RegisterEvents()
|
||
{
|
||
//Task线程内未捕获异常处理事件
|
||
TaskScheduler.UnobservedTaskException += TaskSchedulerUnobservedTaskException;
|
||
|
||
//UI线程未捕获异常处理事件(UI主线程)
|
||
this.DispatcherUnhandledException += AppDispatcherUnhandledException;
|
||
|
||
//非UI线程未捕获异常处理事件(例如自己创建的一个子线程)
|
||
AppDomain.CurrentDomain.UnhandledException += CurrentDomainUnhandledException;
|
||
}
|
||
|
||
private static void TaskSchedulerUnobservedTaskException(object? sender, UnobservedTaskExceptionEventArgs e)
|
||
{
|
||
try
|
||
{
|
||
HandleException(e.Exception);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
HandleException(ex);
|
||
}
|
||
finally
|
||
{
|
||
e.SetObserved();
|
||
}
|
||
}
|
||
|
||
//非UI线程未捕获异常处理事件(例如自己创建的一个子线程)
|
||
private static void CurrentDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
|
||
{
|
||
try
|
||
{
|
||
if (e.ExceptionObject is Exception exception)
|
||
{
|
||
HandleException(exception);
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
HandleException(ex);
|
||
}
|
||
finally
|
||
{
|
||
//ignore
|
||
}
|
||
}
|
||
|
||
//UI线程未捕获异常处理事件(UI主线程)
|
||
private static void AppDispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
|
||
{
|
||
try
|
||
{
|
||
HandleException(e.Exception);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
HandleException(ex);
|
||
}
|
||
finally
|
||
{
|
||
//处理完后,我们需要将Handler=true表示已此异常已处理过
|
||
e.Handled = true;
|
||
}
|
||
}
|
||
|
||
private static void HandleException(Exception e)
|
||
{
|
||
if (e.InnerException != null)
|
||
{
|
||
e = e.InnerException;
|
||
}
|
||
|
||
try
|
||
{
|
||
ExceptionReport.Show(e);
|
||
}
|
||
catch
|
||
{
|
||
// Fallback.
|
||
System.Windows.Forms.MessageBox.Show(
|
||
$"""
|
||
程序异常:{e.Source}
|
||
--
|
||
{e.StackTrace}
|
||
--
|
||
{e.Message}
|
||
"""
|
||
);
|
||
}
|
||
|
||
// log
|
||
GetLogger<App>().LogDebug(e, "UnHandle Exception");
|
||
}
|
||
}
|