Newer
Older
Qwilight / Qwilight / View / QwilightClass.xaml.cs
@Taehui Taehui on 18 Jul 6 KB v1.16.34
using Ionic.Zip;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml;
using Microsoft.Win32;
using Qwilight.Utilities;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.IO;
using System.Runtime;
using System.Runtime.InteropServices;
using System.Text;
using Windows.Win32;
using Windows.Win32.Foundation;
using Windows.Win32.UI.WindowsAndMessaging;
using SplashScreen = System.Windows.SplashScreen;
using StartupEventArgs = System.Windows.StartupEventArgs;
using VirtualKey = Windows.System.VirtualKey;

namespace Qwilight.View
{
    public sealed partial class QwilightClass
    {
        static SplashScreen _wpfLoadingAsset = new("Assets/Drawing/Loading.png");

        [STAThread]
        static void Main(string[] args)
        {
            #region COMPATIBLE
            Compatible.Compatible.Qwilight(QwilightComponent.QwilightEntryPath);
            #endregion

            if (Utility.HasInput(VirtualKey.LeftShift))
            {
                PInvoke.AllocConsole();
            }

            GPUConfigure.Instance.Load();
            switch (GPUConfigure.Instance.GPUModeValue)
            {
                case GPUConfigure.GPUMode.NVIDIA:
                    NativeLibrary.TryLoad("nvapi64", out _);
                    break;
            }
            _wpfLoadingAsset.Show(true);

            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
#if DEBUG
            Environment.SetEnvironmentVariable("ENABLE_XAML_DIAGNOSTICS_SOURCE_INFO", "1");
#endif
            Environment.SetEnvironmentVariable("WEBVIEW2_USER_DATA_FOLDER", QwilightComponent.EdgeEntryPath);

            ProfileOptimization.SetProfileRoot(QwilightComponent.QwilightEntryPath);
            ProfileOptimization.StartProfile("Qwilight.$");
            ThreadPool.GetMaxThreads(out var tw, out var tIOCP);
            ThreadPool.SetMinThreads(tw, tIOCP);
            _ = PInvoke.timeBeginPeriod(1);

            try
            {
                using (var r = Registry.LocalMachine.OpenSubKey("SOFTWARE")?.OpenSubKey("WOW6432Node")?.OpenSubKey("Microsoft")?.OpenSubKey("EdgeUpdate")?.OpenSubKey("Clients")?.OpenSubKey("{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}"))
                {
                    if (string.IsNullOrEmpty(r?.GetValue("pv") as string))
                    {
                        using var exe = Process.Start(Path.Combine(QwilightComponent.AssetsEntryPath, "MicrosoftEdgeWebview2Setup.exe"));
                        exe.WaitForExit();
                    }
                }
            }
            catch
            {
            }

            Application.Start(p =>
            {
                try
                {
                    SynchronizationContext.SetSynchronizationContext(new DispatcherQueueSynchronizationContext(DispatcherQueue.GetForCurrentThread()));
                    new QwilightClass().Run();
                }
                finally
                {
                    Application.Current.Exit();
                }
            });
        }

        QwilightClass() => InitializeComponent();

        protected override void OnStartup(StartupEventArgs e)
        {
            var handledFaults = new ConcurrentDictionary<Exception, bool>();
            void OnUnhandledFault(Exception e)
            {
                if (handledFaults.TryAdd(e, default))
                {
                    var (logFilePath, faultText) = Utility.SaveFaultFile(QwilightComponent.FaultEntryPath, e);
                    if (!QwilightComponent.IsVS && !(e is OutOfMemoryException))
                    {
                        _ = TwilightSystem.Instance.PostWwwParallel($"{QwilightComponent.QwilightAPI}/fault", faultText);
                    }
                    if (PInvoke.MessageBox(HWND.Null, e.Message, "Qwilight", MESSAGEBOX_STYLE.MB_OKCANCEL | MESSAGEBOX_STYLE.MB_ICONERROR | MESSAGEBOX_STYLE.MB_DEFBUTTON2) == MESSAGEBOX_RESULT.IDOK)
                    {
                        Utility.OpenAs(logFilePath);
                    }
                }
            }

            AppDomain.CurrentDomain.UnhandledException += (sender, e) =>
            {
                OnUnhandledFault(e.ExceptionObject as Exception);
            };
            DispatcherUnhandledException += (sender, e) =>
            {
                e.Handled = MainWindow?.IsLoaded == true;
                OnUnhandledFault(e.Exception);
            };
            UIHandler.Instance.Init(Dispatcher);

            QwilightComponent.OnGetBuiltInData = data => TryFindResource(data);

            try
            {
                Directory.CreateDirectory(QwilightComponent.BundleEntryPath);
                Directory.CreateDirectory(QwilightComponent.CommentEntryPath);
                Directory.CreateDirectory(QwilightComponent.EdgeEntryPath);
                Directory.CreateDirectory(QwilightComponent.MediaEntryPath);
                Directory.CreateDirectory(LevelSystem.EntryPath);
            }
            catch
            {
                PInvoke.MessageBox(HWND.Null, $"Cannot run Qwilight from {QwilightComponent.QwilightEntryPath}", "Qwilight", MESSAGEBOX_STYLE.MB_OK | MESSAGEBOX_STYLE.MB_ICONERROR);
                Environment.Exit(1);
            }

            PIDClass.Instance.HaveIt(_wpfLoadingAsset);

            Utility.CopyEntry(Path.Combine(QwilightComponent.AssetsEntryPath, "UI"), Path.Combine(QwilightComponent.UIEntryPath));

            var qwilightBundleFilePath = Path.Combine(QwilightComponent.QwilightEntryPath, "Qwilight.zip");
            if (File.Exists(qwilightBundleFilePath))
            {
                using (var zipFile = new ZipFile(qwilightBundleFilePath))
                {
                    zipFile.ExtractAll(QwilightComponent.QwilightEntryPath, ExtractExistingFileAction.OverwriteSilently);
                }
                Utility.WipeFile(qwilightBundleFilePath);
            }

            Configure.Instance.Load();
            if (Configure.Instance.WMPointer)
            {
                AppContext.SetSwitch("Switch.System.Windows.Input.Stylus.EnablePointerSupport", true);
            }
            LanguageSystem.Instance.Init(Configure.Instance.Language);

            DB.Instance.Load();
            FastDB.Instance.Load();
            PositionSystem.Instance.Load();
            AudioSystem.Instance.Init();

            _wpfLoadingAsset = null;
        }
    }
}