XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEEDToolBox

【WinUI】XFE精英危险工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
using System.Reflection;
using System.Text.Json;
using CommunityToolkit.Mvvm.Input;
using XFEEDToolBox.Controls;
using XFEEDToolBox.Core.Data;
using XFEEDToolBox.Views;

namespace XFEEDToolBox;

public partial class App
{
    private static async Task RunRelogProbeAsync(string path)
    {
        var directory = Path.GetDirectoryName(Path.GetFullPath(path))!;
        Directory.CreateDirectory(directory);
        string? failure = null;
        object? result = null;
        static void Require(bool value, string message) { if (!value) throw new InvalidOperationException(message); }
        try
        {
            Require(ViewModel.OfflinePreview && Runtime.FlightDriver is null && Runtime.Journal.Sequence == 0,
                "The relog fixture requires an isolated offline runtime without a game connection.");
            MainWindow.AppWindow.Move(new(-30000, -30000));
            MainWindow.AppWindow.Resize(new(1680, 1080));
            MainWindow.AppWindow.Show(false);
            var projector = (PlayerProjector)typeof(JournalMonitor).GetField("projector", BindingFlags.Instance | BindingFlags.NonPublic)!.GetValue(Runtime.Journal)!;
            using var load = JsonDocument.Parse("""{"timestamp":"2026-10-23T00:00:00Z","event":"LoadGame","FID":"OFFLINE-RELOG","Commander":"离线按钮验证","GameMode":"Solo","Ship":"sidewinder"}""");
            projector.Apply(load.RootElement);
            ViewModel.DemoMode = false;
            await ViewModel.RefreshCommand.ExecuteAsync(null);
            AppShellPage.Current!.Navigate(typeof(MainPage));
            await Task.Delay(350);
            var page = (MainPage)AppShellPage.Current.CurrentPage!;
            var button = Descendants(page).OfType<Button>().Single(b => b.Content is DependencyObject content
                && Descendants(content).OfType<TextBlock>().Any(t => t.Text == "一键重进"));
            ViewModel.PluginRelogReady = false;
            await Task.Delay(50);
            Require(!button.IsEnabled && ViewModel.RelogAvailabilityText.Contains("更新"), "Old plugins must show their real disabled reason.");
            ViewModel.PluginRelogReady = true;
            await Task.Delay(80);
            Require(button.IsEnabled && ViewModel.RelogGameCommand.CanExecute(null), "The actual dashboard button did not enable with the session capability.");
            Require(Descendants(button).OfType<TextBlock>().Any(t => t.Text == "返回主菜单并重新进入单人模式"), "The actual mode hint is missing.");
            Require(!Descendants(button).OfType<TextBlock>().Any(t => t.Text.Contains("接口验证中")), "The placeholder status survived.");
            await CaptureRefinementElementAsync(button, Path.Combine(directory, "ready.png"));
            var idle = button.Content;
            var originalCommand = AsyncAction.GetCommand(button);
            var originalCancel = AsyncAction.GetCancelCommand(button);
            var countBefore = Descendants(page).OfType<Button>().Count();
            var cancelled = 0;
            // Only this synthetic action is run. The production relog command is
            // queried above for availability and is never invoked by the probe.
            var fake = new AsyncRelayCommand(async token =>
            {
                try { await Task.Delay(Timeout.Infinite, token); }
                catch (OperationCanceledException) { cancelled++; }
            });
            AsyncAction.SetCommand(button, fake);
            AsyncAction.SetCancelCommand(button, new RelayCommand(fake.Cancel));
            var operation = fake.ExecuteAsync(null);
            await Task.Delay(60);
            Require(button.IsEnabled && button.Content as string == "取消", "The same initiating button must remain cancellable.");
            Require(Descendants(page).OfType<Button>().Count() == countBefore, "A separate cancel button appeared.");
            await CaptureRefinementElementAsync(button, Path.Combine(directory, "cancel.png"));
            button.Command.Execute(null);
            await operation.WaitAsync(TimeSpan.FromSeconds(2));
            await Task.Delay(50);
            Require(cancelled == 1 && ReferenceEquals(idle, button.Content), "Cancellation did not restore the original button.");
            AsyncAction.SetCommand(button, originalCommand);
            AsyncAction.SetCancelCommand(button, originalCancel);
            result = new { oldPluginDisabled = true, readyButtonEnabled = true, originalModeHint = true, sameButtonCancellation = true,
                cancelled, gameMenuCalls = 0, gameFlightCalls = 0, gameProcessChanges = 0 };
        }
        catch (Exception error) { failure = error.ToString(); }
        await File.WriteAllTextAsync(path, JsonSerializer.Serialize(new { result, failure, offline = true }, new JsonSerializerOptions { WriteIndented = true }));
        MainWindow.Close();
    }
}