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

XFEWarframe

【WinUI】基于Warframe游戏本体的公开服务器以及安装器

公开
关注 0 Fork 0 Star 0
UTF-8
using System.Text;
using System.Text.Json;
using System.Runtime.InteropServices;
using XFEWarframe.Client;

Console.OutputEncoding = Encoding.UTF8;
using var cancellation = new CancellationTokenSource();
Console.CancelKeyPress += (_, e) => { e.Cancel = true; cancellation.Cancel(); };
try
{
    var command = args.FirstOrDefault() ?? "help";
    string? Option(string name)
    {
        var index = Array.IndexOf(args, "--" + name);
        if (index >= 0 && index + 1 < args.Length && !args[index + 1].StartsWith("--")) return args[index + 1];
        return args.FirstOrDefault(x => x.StartsWith("--" + name + "=", StringComparison.Ordinal))?[(name.Length + 3)..];
    }
    string Game() => Option("game") ?? throw new ArgumentException("请指定 --game 游戏副本目录。");
    var progress = new ConsoleProgress();
    var installer = new ClientInstaller();
    switch (command)
    {
        case "selftest":
            var module = NativeLibrary.Load(Path.Combine(Option("payload") ?? ClientInstaller.FindPayload(), ClientInstaller.BridgeFile));
            var selfTest = Marshal.GetDelegateForFunctionPointer<NativeSelfTest>(NativeLibrary.GetExport(module, "XfeSelfTest"));
            var result = selfTest(0);
            if (result != 0) throw new InvalidOperationException($"原生组件自检失败:{result}");
            Console.WriteLine("NativeAOT、x64 指令重定位、回调和回滚自检通过。"); break;
        case "detect":
            Console.WriteLine(JsonSerializer.Serialize(GameDiscovery.Find(), ClientJson.Default.ListGameInstallation)); break;
        case "check":
            var report = Compatibility.Inspect(Game());
            Console.WriteLine(JsonSerializer.Serialize(report, ClientJson.Default.CompatibilityReport));
            return report.Compatible ? 0 : 2;
        case "install": case "repair":
            installer.Install(Game(), Option("server") ?? "http://127.0.0.1:8444", Option("payload") ?? ClientInstaller.FindPayload(), progress, cancellation.Token); break;
        case "uninstall": installer.Uninstall(Game(), progress); break;
        case "recover":
            var game = ClientInstaller.ValidateGame(Game()); ClientInstaller.EnsureStopped(game);
            // Installer entry point holds the same operation lock as the GUI.
            installer.Recover(game); Console.WriteLine("中断安装已恢复。"); break;
        case "launch":
            var pid = new GameLauncher().Launch(Game(), Option("language") ?? "en", args.Contains("--dx12"), cancellation.Token, Option("server"), args.Contains("--game-test-control"));
            Console.WriteLine($"Game PID: {pid}"); break;
        case "status":
            var configuration = ClientInstaller.VerifyInstalled(Game());
            Console.WriteLine($"安装有效 | {configuration.BuildLabel} | {configuration.ServerUrl}"); break;
        case "help": case "--help": case "-h":
            Console.WriteLine("""
                XFE Warframe · C# 安装器
                detect                                  自动检测客户端
                check --game <目录>                      只读兼容性检查(JSON)
                install --game <目录> --server <URL>      安装 / 更新并备份旧引导
                repair --game <目录> --server <URL>       校验后重新安装
                status --game <目录>                     校验安装完整性
                selftest [--payload <目录>]              原生组件自检
                launch --game <目录> [--language en] [--dx12] [--server <URL>] [--game-test-control]
                uninstall --game <目录>                  恢复原引导,保留备份与日志
                recover --game <目录>                    回滚中断的安装
                install / repair 可使用 --payload <目录> 指定离线组件。
                launch 的 --server 仅用于本次启动,不修改已安装的服务器地址。
                图形安装界面位于独立的 XFEWarframe.Player 玩家应用。
                """); break;
        default: throw new ArgumentException("未知命令,请使用 --help。");
    }
    return 0;
}
catch (OperationCanceledException) { Console.Error.WriteLine("操作已取消,未完成的文件变更已回滚。"); return 3; }
catch (Exception ex) { Console.Error.WriteLine(ex.Message); return 1; }

internal sealed class ConsoleProgress : IProgress<string> { public void Report(string value) => Console.WriteLine(value); }
[UnmanagedFunctionPointer(CallingConvention.StdCall)] internal delegate uint NativeSelfTest(nint unused);