- shit: Cleanup this mess
This commit is contained in:
194
Nebula.Launcher/ViewModels/Pages/AccountInfoViewModel.cs
Normal file
194
Nebula.Launcher/ViewModels/Pages/AccountInfoViewModel.cs
Normal file
@@ -0,0 +1,194 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Windows.Input;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using Nebula.Launcher.Services;
|
||||
using Nebula.Launcher.ViewModels.Popup;
|
||||
using Nebula.Launcher.Views.Pages;
|
||||
using Nebula.Shared;
|
||||
using Nebula.Shared.Services;
|
||||
using Nebula.Shared.Utils;
|
||||
|
||||
namespace Nebula.Launcher.ViewModels.Pages;
|
||||
|
||||
[ViewModelRegister(typeof(AccountInfoView))]
|
||||
[ConstructGenerator]
|
||||
public partial class AccountInfoViewModel : ViewModelBase
|
||||
{
|
||||
[ObservableProperty] private bool _authMenuExpand;
|
||||
|
||||
[ObservableProperty] private bool _authUrlConfigExpand;
|
||||
|
||||
[ObservableProperty] private int _authViewSpan = 1;
|
||||
|
||||
[ObservableProperty] private string _currentAuthServer = string.Empty;
|
||||
|
||||
[ObservableProperty] private string _currentLogin = string.Empty;
|
||||
|
||||
[ObservableProperty] private string _currentPassword = string.Empty;
|
||||
|
||||
[ObservableProperty] private bool _isLogged;
|
||||
|
||||
private bool _isProfilesEmpty;
|
||||
[GenerateProperty] private PopupMessageService PopupMessageService { get; } = default!;
|
||||
[GenerateProperty] private ConfigurationService ConfigurationService { get; } = default!;
|
||||
[GenerateProperty] private AuthService AuthService { get; } = default!;
|
||||
[GenerateProperty] private ViewHelperService ViewHelperService { get; } = default!;
|
||||
|
||||
public ObservableCollection<AuthLoginPasswordModel> Accounts { get; } = new();
|
||||
public ObservableCollection<string> AuthUrls { get; } = new();
|
||||
|
||||
private AuthLoginPassword CurrentAlp
|
||||
{
|
||||
get => new(CurrentLogin, CurrentPassword, CurrentAuthServer);
|
||||
set
|
||||
{
|
||||
CurrentLogin = value.Login;
|
||||
CurrentPassword = value.Password;
|
||||
CurrentAuthServer = value.AuthServer;
|
||||
}
|
||||
}
|
||||
|
||||
public string AuthItemSelect
|
||||
{
|
||||
set => CurrentAuthServer = value;
|
||||
}
|
||||
|
||||
//Design think
|
||||
protected override void InitialiseInDesignMode()
|
||||
{
|
||||
AddAccount(new AuthLoginPassword("Binka", "12341", ""));
|
||||
AuthUrls.Add("https://cinka.ru");
|
||||
AuthUrls.Add("https://cinka.ru");
|
||||
}
|
||||
|
||||
//Real think
|
||||
protected override void Initialise()
|
||||
{
|
||||
ReadAuthConfig();
|
||||
}
|
||||
|
||||
public void AuthByAlp(AuthLoginPassword authLoginPassword)
|
||||
{
|
||||
CurrentAlp = authLoginPassword;
|
||||
DoAuth();
|
||||
}
|
||||
|
||||
public async void DoAuth()
|
||||
{
|
||||
var message = ViewHelperService.GetViewModel<InfoPopupViewModel>();
|
||||
message.InfoText = "Auth think, please wait...";
|
||||
PopupMessageService.Popup(message);
|
||||
|
||||
if (await AuthService.Auth(CurrentAlp))
|
||||
{
|
||||
message.Dispose();
|
||||
IsLogged = true;
|
||||
ConfigurationService.SetConfigValue(CurrentConVar.AuthCurrent, CurrentAlp);
|
||||
}
|
||||
else
|
||||
{
|
||||
message.Dispose();
|
||||
Logout();
|
||||
PopupMessageService.Popup("Well, shit is happened: " + AuthService.Reason);
|
||||
}
|
||||
}
|
||||
|
||||
public void Logout()
|
||||
{
|
||||
IsLogged = false;
|
||||
AuthService.ClearAuth();
|
||||
}
|
||||
|
||||
private void UpdateAuthMenu()
|
||||
{
|
||||
if (AuthMenuExpand || _isProfilesEmpty)
|
||||
AuthViewSpan = 2;
|
||||
else
|
||||
AuthViewSpan = 1;
|
||||
}
|
||||
|
||||
private void AddAccount(AuthLoginPassword authLoginPassword)
|
||||
{
|
||||
var onDelete = new DelegateCommand<AuthLoginPasswordModel>(OnDeleteProfile);
|
||||
var onSelect = new DelegateCommand<AuthLoginPasswordModel>(AuthByAlp);
|
||||
|
||||
var alpm = new AuthLoginPasswordModel(
|
||||
authLoginPassword.Login,
|
||||
authLoginPassword.Password,
|
||||
authLoginPassword.AuthServer,
|
||||
onSelect,
|
||||
onDelete);
|
||||
|
||||
onDelete.TRef.Value = alpm;
|
||||
onSelect.TRef.Value = alpm;
|
||||
|
||||
Accounts.Add(alpm);
|
||||
}
|
||||
|
||||
private void ReadAuthConfig()
|
||||
{
|
||||
foreach (var profile in
|
||||
ConfigurationService.GetConfigValue(CurrentConVar.AuthProfiles)!)
|
||||
AddAccount(profile);
|
||||
|
||||
if (Accounts.Count == 0) UpdateAuthMenu();
|
||||
|
||||
var currProfile = ConfigurationService.GetConfigValue(CurrentConVar.AuthCurrent);
|
||||
|
||||
if (currProfile != null)
|
||||
{
|
||||
CurrentAlp = currProfile;
|
||||
DoAuth();
|
||||
}
|
||||
|
||||
AuthUrls.Clear();
|
||||
var authUrls = ConfigurationService.GetConfigValue(CurrentConVar.AuthServers)!;
|
||||
foreach (var url in authUrls) AuthUrls.Add(url);
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void OnSaveProfile()
|
||||
{
|
||||
AddAccount(CurrentAlp);
|
||||
_isProfilesEmpty = Accounts.Count == 0;
|
||||
UpdateAuthMenu();
|
||||
DirtyProfile();
|
||||
}
|
||||
|
||||
private void OnDeleteProfile(AuthLoginPasswordModel account)
|
||||
{
|
||||
Accounts.Remove(account);
|
||||
_isProfilesEmpty = Accounts.Count == 0;
|
||||
UpdateAuthMenu();
|
||||
DirtyProfile();
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void OnExpandAuthUrl()
|
||||
{
|
||||
AuthUrlConfigExpand = !AuthUrlConfigExpand;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void OnExpandAuthView()
|
||||
{
|
||||
AuthMenuExpand = !AuthMenuExpand;
|
||||
UpdateAuthMenu();
|
||||
}
|
||||
|
||||
private void DirtyProfile()
|
||||
{
|
||||
ConfigurationService.SetConfigValue(CurrentConVar.AuthProfiles,
|
||||
Accounts.Select(a => (AuthLoginPassword)a).ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
public record AuthLoginPasswordModel(
|
||||
string Login,
|
||||
string Password,
|
||||
string AuthServer,
|
||||
ICommand OnSelect = default!,
|
||||
ICommand OnDelete = default!)
|
||||
: AuthLoginPassword(Login, Password, AuthServer);
|
||||
382
Nebula.Launcher/ViewModels/Pages/ContentBrowserViewModel.cs
Normal file
382
Nebula.Launcher/ViewModels/Pages/ContentBrowserViewModel.cs
Normal file
@@ -0,0 +1,382 @@
|
||||
using System;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Avalonia.Media;
|
||||
using Avalonia.Media.Imaging;
|
||||
using Avalonia.Platform;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Nebula.Launcher.Services;
|
||||
using Nebula.Launcher.ViewModels.Popup;
|
||||
using Nebula.Launcher.Views.Pages;
|
||||
using Nebula.Shared.Models;
|
||||
using Nebula.Shared.Services;
|
||||
using Nebula.Shared.Utils;
|
||||
|
||||
namespace Nebula.Launcher.ViewModels.Pages;
|
||||
|
||||
[ViewModelRegister(typeof(ContentBrowserView))]
|
||||
[ConstructGenerator]
|
||||
public sealed partial class ContentBrowserViewModel : ViewModelBase
|
||||
{
|
||||
private readonly List<ContentEntry> _root = new();
|
||||
|
||||
private readonly List<string> _history = new();
|
||||
|
||||
[ObservableProperty] private string _message = "";
|
||||
[ObservableProperty] private string _searchText = "";
|
||||
|
||||
private ContentEntry? _selectedEntry;
|
||||
[ObservableProperty] private string _serverText = "";
|
||||
[GenerateProperty] private ContentService ContentService { get; } = default!;
|
||||
[GenerateProperty] private CancellationService CancellationService { get; } = default!;
|
||||
[GenerateProperty] private FileService FileService { get; } = default!;
|
||||
[GenerateProperty] private DebugService DebugService { get; } = default!;
|
||||
[GenerateProperty] private PopupMessageService PopupService { get; } = default!;
|
||||
[GenerateProperty] private HubService HubService { get; } = default!;
|
||||
[GenerateProperty] private ViewHelperService ViewHelperService { get; } = default!;
|
||||
|
||||
public ObservableCollection<ContentEntry> Entries { get; } = new();
|
||||
|
||||
public ContentEntry? SelectedEntry
|
||||
{
|
||||
get => _selectedEntry;
|
||||
set
|
||||
{
|
||||
if (value is { Item: not null })
|
||||
{
|
||||
if (FileService.ContentFileApi.TryOpen(value.Item.Value.Hash, out var stream))
|
||||
{
|
||||
var ext = Path.GetExtension(value.Item.Value.Path);
|
||||
|
||||
var myTempFile = Path.Combine(Path.GetTempPath(), "tempie" + ext);
|
||||
|
||||
using (var sw = new FileStream(myTempFile, FileMode.Create, FileAccess.Write, FileShare.None))
|
||||
{
|
||||
stream.CopyTo(sw);
|
||||
}
|
||||
|
||||
stream.Dispose();
|
||||
|
||||
var startInfo = new ProcessStartInfo(myTempFile)
|
||||
{
|
||||
UseShellExecute = true
|
||||
};
|
||||
|
||||
Process.Start(startInfo);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Entries.Clear();
|
||||
_selectedEntry = value;
|
||||
|
||||
if (value == null) return;
|
||||
|
||||
foreach (var (_, entryCh) in value.Childs) Entries.Add(entryCh);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected override void InitialiseInDesignMode()
|
||||
{
|
||||
var a = new ContentEntry(this, "A:", "A", "");
|
||||
var b = new ContentEntry(this, "B", "B", "");
|
||||
a.TryAddChild(b);
|
||||
Entries.Add(a);
|
||||
}
|
||||
|
||||
protected override void Initialise()
|
||||
{
|
||||
FillRoot(HubService.ServerList);
|
||||
|
||||
HubService.HubServerChangedEventArgs += HubServerChangedEventArgs;
|
||||
HubService.HubServerLoaded += GoHome;
|
||||
|
||||
if (!HubService.IsUpdating) GoHome();
|
||||
}
|
||||
|
||||
private void GoHome()
|
||||
{
|
||||
SelectedEntry = null;
|
||||
foreach (var entry in _root) Entries.Add(entry);
|
||||
}
|
||||
|
||||
private void HubServerChangedEventArgs(HubServerChangedEventArgs obj)
|
||||
{
|
||||
if (obj.Action == HubServerChangeAction.Clear) _root.Clear();
|
||||
if (obj.Action == HubServerChangeAction.Add) FillRoot(obj.Items);
|
||||
}
|
||||
|
||||
private void FillRoot(IEnumerable<ServerHubInfo> infos)
|
||||
{
|
||||
foreach (var info in infos) _root.Add(new ContentEntry(this, info.StatusData.Name, info.Address, info.Address));
|
||||
}
|
||||
|
||||
public async void Go(ContentPath path, bool appendHistory = true)
|
||||
{
|
||||
if (path.Pathes.Count > 0 && (path.Pathes[0].StartsWith("ss14://") || path.Pathes[0].StartsWith("ss14s://")))
|
||||
{
|
||||
ServerText = path.Pathes[0];
|
||||
path = new ContentPath("");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(ServerText))
|
||||
{
|
||||
SearchText = "";
|
||||
GoHome();
|
||||
return;
|
||||
}
|
||||
|
||||
if (ServerText != SelectedEntry?.ServerName) SelectedEntry = await CreateEntry(ServerText);
|
||||
|
||||
DebugService.Debug("Going to:" + path.Path);
|
||||
|
||||
var oriPath = path.Clone();
|
||||
try
|
||||
{
|
||||
if (SelectedEntry == null || !SelectedEntry.GetRoot().TryGetEntry(path, out var centry))
|
||||
throw new Exception("Not found! " + oriPath.Path);
|
||||
|
||||
if (appendHistory) AppendHistory(SearchText);
|
||||
SearchText = oriPath.Path;
|
||||
|
||||
SelectedEntry = centry;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
SearchText = oriPath.Path;
|
||||
PopupService.Popup(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void OnBackEnter()
|
||||
{
|
||||
Go(new ContentPath(GetHistory()), false);
|
||||
}
|
||||
|
||||
public void OnGoEnter()
|
||||
{
|
||||
Go(new ContentPath(SearchText));
|
||||
}
|
||||
|
||||
private async Task<ContentEntry> CreateEntry(string serverUrl)
|
||||
{
|
||||
var rurl = serverUrl.ToRobustUrl();
|
||||
var info = await ContentService.GetBuildInfo(rurl, CancellationService.Token);
|
||||
var loading = ViewHelperService.GetViewModel<LoadingContextViewModel>();
|
||||
loading.LoadingName = "Loading entry";
|
||||
PopupService.Popup(loading);
|
||||
var items = await ContentService.EnsureItems(info.RobustManifestInfo, loading,
|
||||
CancellationService.Token);
|
||||
|
||||
var rootEntry = new ContentEntry(this, "", "", serverUrl);
|
||||
|
||||
foreach (var item in items)
|
||||
{
|
||||
var path = new ContentPath(item.Path);
|
||||
rootEntry.CreateItem(path, item);
|
||||
}
|
||||
|
||||
loading.Dispose();
|
||||
|
||||
return rootEntry;
|
||||
}
|
||||
|
||||
private void AppendHistory(string str)
|
||||
{
|
||||
if (_history.Count >= 10) _history.RemoveAt(9);
|
||||
_history.Insert(0, str);
|
||||
}
|
||||
|
||||
private string GetHistory()
|
||||
{
|
||||
if (_history.Count == 0) return "";
|
||||
var h = _history[0];
|
||||
_history.RemoveAt(0);
|
||||
return h;
|
||||
}
|
||||
}
|
||||
|
||||
public class ContentEntry
|
||||
{
|
||||
public static IImage DirImage = new Bitmap(AssetLoader.Open(new Uri("avares://Nebula.Launcher/Assets/dir.png")));
|
||||
public static IImage IconImage = new Bitmap(AssetLoader.Open(new Uri("avares://Nebula.Launcher/Assets/file.png")));
|
||||
|
||||
private readonly Dictionary<string, ContentEntry> _childs = new();
|
||||
private readonly ContentBrowserViewModel _viewModel;
|
||||
|
||||
public RobustManifestItem? Item;
|
||||
|
||||
internal ContentEntry(ContentBrowserViewModel viewModel, string name, string pathName, string serverName)
|
||||
{
|
||||
Name = name;
|
||||
ServerName = serverName;
|
||||
PathName = pathName;
|
||||
_viewModel = viewModel;
|
||||
}
|
||||
|
||||
public bool IsDirectory => Item == null;
|
||||
|
||||
public string Name { get; private set; }
|
||||
public string PathName { get; }
|
||||
public string ServerName { get; }
|
||||
public IImage IconPath { get; set; } = DirImage;
|
||||
|
||||
public ContentEntry? Parent { get; private set; }
|
||||
public bool IsRoot => Parent == null;
|
||||
|
||||
public IReadOnlyDictionary<string, ContentEntry> Childs => _childs.ToFrozenDictionary();
|
||||
|
||||
public bool TryGetChild(string name, [NotNullWhen(true)] out ContentEntry? child)
|
||||
{
|
||||
return _childs.TryGetValue(name, out child);
|
||||
}
|
||||
|
||||
public bool TryAddChild(ContentEntry contentEntry)
|
||||
{
|
||||
if (_childs.TryAdd(contentEntry.PathName, contentEntry))
|
||||
{
|
||||
contentEntry.Parent = this;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public ContentPath GetPath()
|
||||
{
|
||||
if (Parent != null)
|
||||
{
|
||||
var path = Parent.GetPath();
|
||||
path.Pathes.Add(PathName);
|
||||
return path;
|
||||
}
|
||||
|
||||
return new ContentPath([PathName]);
|
||||
}
|
||||
|
||||
public ContentEntry GetOrCreateDirectory(ContentPath rootPath)
|
||||
{
|
||||
if (rootPath.Pathes.Count == 0) return this;
|
||||
|
||||
var fName = rootPath.GetNext();
|
||||
|
||||
if (!TryGetChild(fName, out var child))
|
||||
{
|
||||
child = new ContentEntry(_viewModel, fName, fName, ServerName);
|
||||
TryAddChild(child);
|
||||
}
|
||||
|
||||
return child.GetOrCreateDirectory(rootPath);
|
||||
}
|
||||
|
||||
public ContentEntry GetRoot()
|
||||
{
|
||||
if (Parent == null) return this;
|
||||
return Parent.GetRoot();
|
||||
}
|
||||
|
||||
public ContentEntry CreateItem(ContentPath path, RobustManifestItem item)
|
||||
{
|
||||
var dir = path.GetDirectory();
|
||||
var dirEntry = GetOrCreateDirectory(dir);
|
||||
|
||||
var name = path.GetName();
|
||||
var entry = new ContentEntry(_viewModel, name, name, ServerName)
|
||||
{
|
||||
Item = item
|
||||
};
|
||||
|
||||
dirEntry.TryAddChild(entry);
|
||||
entry.IconPath = IconImage;
|
||||
return entry;
|
||||
}
|
||||
|
||||
public bool TryGetEntry(ContentPath path, out ContentEntry? entry)
|
||||
{
|
||||
entry = null;
|
||||
|
||||
if (path.Pathes.Count == 0)
|
||||
{
|
||||
entry = this;
|
||||
return true;
|
||||
}
|
||||
|
||||
var fName = path.GetNext();
|
||||
|
||||
if (!TryGetChild(fName, out var child)) return false;
|
||||
|
||||
return child.TryGetEntry(path, out entry);
|
||||
}
|
||||
|
||||
public void OnPathGo()
|
||||
{
|
||||
_viewModel.Go(GetPath());
|
||||
}
|
||||
}
|
||||
|
||||
public struct ContentPath
|
||||
{
|
||||
public List<string> Pathes { get; }
|
||||
|
||||
public ContentPath(List<string> pathes)
|
||||
{
|
||||
Pathes = pathes;
|
||||
}
|
||||
|
||||
public ContentPath(string path)
|
||||
{
|
||||
Pathes = string.IsNullOrEmpty(path)
|
||||
? new List<string>()
|
||||
: path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries).ToList();
|
||||
}
|
||||
|
||||
public ContentPath GetDirectory()
|
||||
{
|
||||
if (Pathes.Count == 0)
|
||||
return this; // Root remains root when getting the directory.
|
||||
|
||||
var directoryPathes = Pathes.Take(Pathes.Count - 1).ToList();
|
||||
return new ContentPath(directoryPathes);
|
||||
}
|
||||
|
||||
public string GetName()
|
||||
{
|
||||
if (Pathes.Count == 0)
|
||||
throw new InvalidOperationException("Cannot get the name of the root path.");
|
||||
|
||||
return Pathes.Last();
|
||||
}
|
||||
|
||||
public string GetNext()
|
||||
{
|
||||
if (Pathes.Count == 0)
|
||||
throw new InvalidOperationException("No elements left to retrieve from the root.");
|
||||
|
||||
var nextName = Pathes[0];
|
||||
Pathes.RemoveAt(0);
|
||||
|
||||
return string.IsNullOrWhiteSpace(nextName) ? GetNext() : nextName;
|
||||
}
|
||||
|
||||
public ContentPath Clone()
|
||||
{
|
||||
return new ContentPath(new List<string>(Pathes));
|
||||
}
|
||||
|
||||
public string Path => Pathes.Count == 0 ? "/" : string.Join("/", Pathes);
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Path;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using Nebula.Shared.Models;
|
||||
|
||||
namespace Nebula.Launcher.ViewModels.Pages;
|
||||
|
||||
public class FavoriteServerListViewModel : ViewModelBase
|
||||
{
|
||||
public ObservableCollection<ServerHubInfo> Servers = new();
|
||||
|
||||
protected override void Initialise()
|
||||
{
|
||||
}
|
||||
|
||||
protected override void InitialiseInDesignMode()
|
||||
{
|
||||
}
|
||||
}
|
||||
112
Nebula.Launcher/ViewModels/Pages/ServerListViewModel.cs
Normal file
112
Nebula.Launcher/ViewModels/Pages/ServerListViewModel.cs
Normal file
@@ -0,0 +1,112 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Nebula.Launcher.Services;
|
||||
using Nebula.Launcher.Views.Pages;
|
||||
using Nebula.Shared.Models;
|
||||
using Nebula.Shared.Services;
|
||||
|
||||
namespace Nebula.Launcher.ViewModels.Pages;
|
||||
|
||||
[ViewModelRegister(typeof(ServerListView))]
|
||||
[ConstructGenerator]
|
||||
public partial class ServerListViewModel : ViewModelBase
|
||||
{
|
||||
[ObservableProperty] private string _searchText = string.Empty;
|
||||
|
||||
public Action? OnSearchChange;
|
||||
[GenerateProperty] private HubService HubService { get; } = default!;
|
||||
[GenerateProperty] private ViewHelperService ViewHelperService { get; } = default!;
|
||||
public ObservableCollection<ServerEntryModelView> ServerInfos { get; } = new();
|
||||
private List<ServerHubInfo> UnsortedServers { get; } = new();
|
||||
|
||||
//Design think
|
||||
protected override void InitialiseInDesignMode()
|
||||
{
|
||||
ServerInfos.Add(CreateServerView(new ServerHubInfo("ss14://localhost",
|
||||
new ServerStatus("Nebula", "TestCraft", ["16+", "RU"], "super", 12, 55, 1, false, DateTime.Now, 20), [])));
|
||||
}
|
||||
|
||||
//real think
|
||||
protected override void Initialise()
|
||||
{
|
||||
foreach (var info in HubService.ServerList) UnsortedServers.Add(info);
|
||||
|
||||
HubService.HubServerChangedEventArgs += HubServerChangedEventArgs;
|
||||
HubService.HubServerLoaded += HubServerLoaded;
|
||||
OnSearchChange += OnChangeSearch;
|
||||
|
||||
if (!HubService.IsUpdating) SortServers();
|
||||
}
|
||||
|
||||
private void HubServerLoaded()
|
||||
{
|
||||
SortServers();
|
||||
}
|
||||
|
||||
private void OnChangeSearch()
|
||||
{
|
||||
SortServers();
|
||||
}
|
||||
|
||||
private void HubServerChangedEventArgs(HubServerChangedEventArgs obj)
|
||||
{
|
||||
if (obj.Action == HubServerChangeAction.Add)
|
||||
foreach (var info in obj.Items)
|
||||
UnsortedServers.Add(info);
|
||||
if (obj.Action == HubServerChangeAction.Remove)
|
||||
foreach (var info in obj.Items)
|
||||
UnsortedServers.Remove(info);
|
||||
if (obj.Action == HubServerChangeAction.Clear) UnsortedServers.Clear();
|
||||
}
|
||||
|
||||
private void SortServers()
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
ServerInfos.Clear();
|
||||
UnsortedServers.Sort(new ServerComparer());
|
||||
foreach (var server in UnsortedServers.Where(CheckServerThink)) ServerInfos.Add(CreateServerView(server));
|
||||
});
|
||||
}
|
||||
|
||||
private bool CheckServerThink(ServerHubInfo hubInfo)
|
||||
{
|
||||
if (string.IsNullOrEmpty(SearchText)) return true;
|
||||
return hubInfo.StatusData.Name.ToLower().Contains(SearchText.ToLower());
|
||||
}
|
||||
|
||||
private ServerEntryModelView CreateServerView(ServerHubInfo serverHubInfo)
|
||||
{
|
||||
var svn = ViewHelperService.GetViewModel<ServerEntryModelView>();
|
||||
svn.ServerHubInfo = serverHubInfo;
|
||||
return svn;
|
||||
}
|
||||
|
||||
public void FilterRequired()
|
||||
{
|
||||
}
|
||||
|
||||
public void UpdateRequired()
|
||||
{
|
||||
Task.Run(HubService.UpdateHub);
|
||||
}
|
||||
}
|
||||
|
||||
public class ServerComparer : IComparer<ServerHubInfo>
|
||||
{
|
||||
public int Compare(ServerHubInfo? x, ServerHubInfo? y)
|
||||
{
|
||||
if (ReferenceEquals(x, y))
|
||||
return 0;
|
||||
if (ReferenceEquals(null, y))
|
||||
return 1;
|
||||
if (ReferenceEquals(null, x))
|
||||
return -1;
|
||||
|
||||
return y.StatusData.Players.CompareTo(x.StatusData.Players);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user