XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet
公开
关注 0 Fork 0 Star 0
UTF-8
using XFEEliteDangerous.Client;



using System.Text.Json.Nodes;
using CommunityToolkit.Mvvm.ComponentModel;
using Microsoft.UI.Xaml;
using XFEExtension.NetCore.WinUIHelper.Utilities;
using XFEExtension.NetCore.WinUIHelper.Utilities.Helper;

namespace XFEEliteDangerous.Desktop;

public static class DesktopContext
{
    public static bool IsAdmin => State.IsLoggedIn && State.AccountRole == "administrator";
    public static Window MainWindow { get; set; } = null!;
    public static Microsoft.UI.Dispatching.DispatcherQueue? Dispatcher { get; set; }
    public static DesktopState State { get; } = new();
    public static LocalClient Local { get; } = new();
    public static event Action? SessionChanged;
    public static event Action? LanguageChanged;
    public static void ChangeLanguage(string preference, bool persist = true)
    {
        var oldLanguage = AppText.Language;
        var oldCatalog = AppText.Catalog(oldLanguage);
        SystemProfile.Language = AppText.NormalizePreference(preference);
        AppText.Apply(SystemProfile.Language);
        State.RefreshLocalizedLabels();
        if (!State.IsLoggedIn) State.DisplayName = AppText.Get("AppShellPage.Text105");
        if (State.ServerName == oldCatalog["DesktopContext.Text107"]) State.ServerName = AppText.Get("DesktopContext.Text107");
        foreach (var key in new[] { "DesktopContext.Text108", "HomePage.Text203" })
            if (State.ConnectionStatus == oldCatalog[key]) { State.ConnectionStatus = AppText.Get(key); break; }
        if (persist) SystemProfile.SaveProfile();
        LanguageChanged?.Invoke();
    }
    public static string Role => State.RoleLabel;
    public static void Initialize()
    {

        State.ServerName = AppText.Get("DesktopContext.Text107");
        State.DisplayName = AppText.Get("AppShellPage.Text105");
        foreach (var type in new[] { typeof(NavigationHostPage), typeof(AppShellPage), typeof(HomePage), typeof(InventoryPage), typeof(FleetPage), typeof(OnlinePage),typeof(GalaxyPage), typeof(AccountPage), typeof(SettingsPage), typeof(DiagnosticsPage), typeof(PermissionsPage) })
            PageManager.RegisterPage(type);
    }
    public static void Changed() => SessionChanged?.Invoke();
    public static void ClearSession()
    {
        Local.Logout();
        State.IsLoggedIn = false;
        State.AccountRole = "anonymous";
        State.AccountId = "";
        State.DisplayName = AppText.Get("AppShellPage.Text105");
        State.CanEditCargo = State.CanEditMaterials = State.CanEditCredits = State.CanEditShips = false;
        Changed();
    }
    public static void Persist()
    {

        SystemProfile.SaveProfile();
    }
    public static async Task InvalidateSessionAsync(string? expectedToken)
    {
        void ClearCurrent() { if (Local.Token == expectedToken) ClearSession(); }
        var dispatcher = Dispatcher;
        if (dispatcher is null || dispatcher.HasThreadAccess) { ClearCurrent(); return; }
        var done = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
        if (!dispatcher.TryEnqueue(() =>
        {
            try { ClearCurrent(); done.SetResult(); }
            catch (Exception error) { done.SetException(error); }
        })) return;
        await done.Task.ConfigureAwait(false);
    }
    public static async Task RefreshPermissionsAsync()
    {
        if (State.IsLoggedIn)
        {
            var session = Local.Token;
            var account = await Local.ProfileAsync();
            if (Local.Token != session) return;
            DesktopContracts.ApplyPlayerAccount(account);
            if (IsAdmin) State.CanEditCargo = State.CanEditMaterials = State.CanEditCredits = State.CanEditShips = true;
            else
            {
                var data = await Local.PermissionsAsync();
                if (Local.Token != session) return;
                State.CanEditCargo = data.Flag("allowPlayerCargo");
                State.CanEditMaterials = data.Flag("allowPlayerMaterials");
                State.CanEditCredits = data.Flag("allowPlayerCredits");
                State.CanEditShips = data.Flag("allowPlayerShipEditing");
            }
        }
        Changed();
    }
    public static void Log(Exception error)
    {
        try
        {
            var path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "XFEEliteDangerous", "Desktop", "Logs");
            Directory.CreateDirectory(path);
            var message = error.Message;
            if (!string.IsNullOrEmpty(Local.Token)) message = message.Replace(Local.Token, "[redacted]", StringComparison.Ordinal);
            File.AppendAllText(Path.Combine(path, "desktop.log"), $"{DateTimeOffset.Now:O} {error.GetType().Name}: {message}\n{error.StackTrace}\n");
        }
        catch (IOException) { }
        catch (UnauthorizedAccessException) { }
    }
}

public partial class DesktopState : ObservableObject
{
    public void RefreshLocalizedLabels() => OnPropertyChanged(nameof(RoleLabel));

    [ObservableProperty] public partial string ServerName { get; set; } = "";
    [ObservableProperty] public partial string DisplayName { get; set; } = "";
    [ObservableProperty] public partial string AccountId { get; set; } = "";
    [ObservableProperty] public partial string ConnectionStatus { get; set; } = AppText.Get("DesktopContext.Text108");
    [ObservableProperty, NotifyPropertyChangedFor(nameof(RoleLabel))] public partial bool IsLoggedIn { get; set; }
    [ObservableProperty, NotifyPropertyChangedFor(nameof(RoleLabel))] public partial string AccountRole { get; set; } = "anonymous";
    public string RoleLabel => IsLoggedIn && AccountRole == "administrator" ? AppText.Get("DesktopContext.Text109") : AppText.Get("DesktopContext.Text110");
    [ObservableProperty] public partial bool CanEditCredits { get; set; }
    [ObservableProperty] public partial bool CanEditCargo { get; set; }
    [ObservableProperty] public partial bool CanEditMaterials { get; set; }
    [ObservableProperty] public partial bool CanEditShips { get; set; }
}

public static class JsonAccess
{
    public static string Text(this JsonNode? node, string name, string fallback = "") => node?[name]?.ToString() ?? fallback;
    public static bool Flag(this JsonNode? node, string name) => bool.TryParse(node?[name]?.ToString(), out var value) && value;
    public static long Number(this JsonNode? node, string name) => long.TryParse(node?[name]?.ToString(), out var value) ? value : 0;
    public static IEnumerable<JsonNode> Rows(this JsonNode? node) => node is JsonArray array ? array.OfType<JsonNode>() : [];
}