mirror of
https://github.com/EpinelPS/EpinelPS.git
synced 2025-12-12 15:04:36 +01:00
improve server selector
This commit is contained in:
@@ -1,8 +1,6 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
using ServerSelector.ViewModels;
|
||||
using ServerSelector.Views;
|
||||
|
||||
namespace ServerSelector;
|
||||
@@ -18,17 +16,11 @@ public partial class App : Application
|
||||
{
|
||||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
{
|
||||
desktop.MainWindow = new MainWindow
|
||||
{
|
||||
DataContext = new MainViewModel()
|
||||
};
|
||||
desktop.MainWindow = new MainWindow();
|
||||
}
|
||||
else if (ApplicationLifetime is ISingleViewApplicationLifetime singleViewPlatform)
|
||||
{
|
||||
singleViewPlatform.MainView = new MainView
|
||||
{
|
||||
DataContext = new MainViewModel()
|
||||
};
|
||||
singleViewPlatform.MainView = new MainView();
|
||||
}
|
||||
|
||||
base.OnFrameworkInitializationCompleted();
|
||||
|
||||
@@ -12,9 +12,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia" Version="11.1.3" />
|
||||
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.1.3" />
|
||||
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.1.3" />
|
||||
<PackageReference Include="Avalonia.ReactiveUI" Version="11.1.3" />
|
||||
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
|
||||
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.1.3" />
|
||||
<PackageReference Include="FluentAvaloniaUI" Version="2.1.0" />
|
||||
|
||||
@@ -10,23 +10,123 @@ namespace ServerSelector
|
||||
private static int GameAssemblySodiumIntegrityFuncHint = 0x5877FFB;
|
||||
private static byte[] GameAssemblySodiumIntegrityFuncOrg = [0xE8, 0xF0, 0x9D, 0x43, 0xFB];
|
||||
private static byte[] GameAssemblySodiumIntegrityFuncPatch = [0xb0, 0x01, 0x90, 0x90, 0x90];
|
||||
private const string HostsStartMarker = "# begin ServerSelector entries";
|
||||
private const string HostsEndMarker = "# end ServerSelector entries";
|
||||
|
||||
public static bool IsUsingOfficalServer()
|
||||
{
|
||||
var hostsFile = File.ReadAllText("C:\\Windows\\System32\\drivers\\etc\\hosts");
|
||||
return !hostsFile.Contains("cloud.nikke-kr.com");
|
||||
return !hostsFile.Contains("global-lobby.nikke-kr.com");
|
||||
}
|
||||
|
||||
public static string CheckIntegrity()
|
||||
public static bool IsOffline()
|
||||
{
|
||||
var hostsFile = File.ReadAllText("C:\\Windows\\System32\\drivers\\etc\\hosts");
|
||||
return hostsFile.Contains("cloud.nikke-kr.com");
|
||||
}
|
||||
|
||||
public static async Task<string> CheckIntegrity(string gamePath, string launcherPath)
|
||||
{
|
||||
if (IsUsingOfficalServer())
|
||||
return "Official server";
|
||||
|
||||
// TODO
|
||||
|
||||
if (!Directory.Exists(gamePath))
|
||||
{
|
||||
return "Game path does not exist";
|
||||
}
|
||||
|
||||
if (!Directory.Exists(launcherPath))
|
||||
{
|
||||
return "Launcher path does not exist";
|
||||
}
|
||||
|
||||
if (!File.Exists(Path.Combine(launcherPath, "nikke_launcher.exe")))
|
||||
{
|
||||
return "Launcher path is invalid. Make sure that the game executable exists in the launcher folder";
|
||||
}
|
||||
|
||||
string sodiumLib = AppDomain.CurrentDomain.BaseDirectory + "sodium.dll";
|
||||
string gameSodium = gamePath + "/nikke_Data/Plugins/x86_64/sodium.dll";
|
||||
string gameAssembly = gamePath + "/GameAssembly.dll";
|
||||
string sodiumBackup = gameSodium + ".bak";
|
||||
string hostsFilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "drivers/etc/hosts");
|
||||
var CAcert = await File.ReadAllTextAsync(AppDomain.CurrentDomain.BaseDirectory + "myCA.pem");
|
||||
|
||||
string launcherCertList = launcherPath + "/intl_service/cacert.pem";
|
||||
string gameCertList = gamePath + "/nikke_Data/Plugins/x86_64/cacert.pem";
|
||||
|
||||
var certList1 = await File.ReadAllTextAsync(launcherCertList);
|
||||
|
||||
int goodSslIndex1 = certList1.IndexOf("Good SSL Ca");
|
||||
if (goodSslIndex1 == -1)
|
||||
return "Patch missing";
|
||||
|
||||
var certList2 = await File.ReadAllTextAsync(gameCertList);
|
||||
|
||||
int goodSslIndex2 = certList2.IndexOf("Good SSL Ca");
|
||||
if (goodSslIndex2 == -1)
|
||||
return "Patch missing";
|
||||
|
||||
|
||||
// TODO: Check sodium lib
|
||||
// TODO: Check if gameassembly was patched
|
||||
|
||||
return "OK";
|
||||
}
|
||||
|
||||
public static async Task SaveCfg(bool useOffical, string gamePath, string launcherPath, string ip)
|
||||
public static async Task RevertHostsFile()
|
||||
{
|
||||
string hostsFilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "drivers/etc/hosts");
|
||||
var txt = await File.ReadAllTextAsync(hostsFilePath);
|
||||
|
||||
// remove stuff
|
||||
try
|
||||
{
|
||||
|
||||
int startIdx = txt.IndexOf(HostsStartMarker);
|
||||
int endIdx;
|
||||
if (startIdx == -1)
|
||||
{
|
||||
startIdx = txt.IndexOf("cloud.nikke-kr.com");
|
||||
}
|
||||
|
||||
string endIndexStr = HostsEndMarker;
|
||||
if (!txt.Contains(endIndexStr))
|
||||
{
|
||||
// old code, find new line character before start index
|
||||
for (int i = startIdx - 1; i >= 0; i--)
|
||||
{
|
||||
var c = txt[i];
|
||||
if (c == '\n')
|
||||
{
|
||||
startIdx = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
endIndexStr = "y.io";
|
||||
endIdx = txt.IndexOf(endIndexStr) + endIndexStr.Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
// add/subtract 2 to take into account newline
|
||||
startIdx = txt.IndexOf(HostsStartMarker) - 2;
|
||||
endIdx = txt.IndexOf(endIndexStr) + endIndexStr.Length;
|
||||
}
|
||||
|
||||
txt = txt.Substring(0, startIdx) + txt.Substring(endIdx);
|
||||
|
||||
|
||||
await File.WriteAllTextAsync(hostsFilePath, txt);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task SaveCfg(bool useOffical, string gamePath, string launcherPath, string ip, bool offlineMode)
|
||||
{
|
||||
string sodiumLib = AppDomain.CurrentDomain.BaseDirectory + "sodium.dll";
|
||||
string gameSodium = gamePath + "/nikke_Data/Plugins/x86_64/sodium.dll";
|
||||
@@ -42,40 +142,12 @@ namespace ServerSelector
|
||||
// TODO: allow changing ip address
|
||||
if (useOffical)
|
||||
{
|
||||
var txt = await File.ReadAllTextAsync(hostsFilePath);
|
||||
|
||||
// remove stuff
|
||||
try
|
||||
{
|
||||
|
||||
int startIdx = txt.IndexOf("cloud.nikke-kr.com");
|
||||
|
||||
// find new line character before start index
|
||||
for (int i = startIdx - 1; i >= 0; i--)
|
||||
{
|
||||
var c = txt[i];
|
||||
if (c == '\n')
|
||||
{
|
||||
startIdx = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int endIdx = txt.IndexOf("y.io") + 4;
|
||||
txt = txt.Substring(0, startIdx) + txt.Substring(endIdx);
|
||||
|
||||
await File.WriteAllTextAsync(hostsFilePath, txt);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
await RevertHostsFile();
|
||||
|
||||
// remove cert
|
||||
X509Store store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
|
||||
store.Open(OpenFlags.ReadWrite);
|
||||
store.Remove(new X509Certificate2(X509Certificate2.CreateFromCertFile(AppDomain.CurrentDomain.BaseDirectory + "myCA.pfx")));
|
||||
store.Remove(new X509Certificate2(X509Certificate.CreateFromCertFile(AppDomain.CurrentDomain.BaseDirectory + "myCA.pfx")));
|
||||
store.Close();
|
||||
|
||||
// restore sodium
|
||||
@@ -117,17 +189,29 @@ namespace ServerSelector
|
||||
}
|
||||
|
||||
var certList1 = await File.ReadAllTextAsync(launcherCertList);
|
||||
await File.WriteAllTextAsync(launcherCertList, certList1.Substring(0, certList1.IndexOf("Good SSL Ca")));
|
||||
|
||||
int goodSslIndex1 = certList1.IndexOf("Good SSL Ca");
|
||||
if (goodSslIndex1 != -1)
|
||||
await File.WriteAllTextAsync(launcherCertList, certList1.Substring(0, goodSslIndex1));
|
||||
|
||||
var certList2 = await File.ReadAllTextAsync(gameCertList);
|
||||
await File.WriteAllTextAsync(gameCertList, certList2.Substring(0, certList2.IndexOf("Good SSL Ca")));
|
||||
|
||||
int goodSslIndex2 = certList2.IndexOf("Good SSL Ca");
|
||||
if (goodSslIndex2 != -1)
|
||||
await File.WriteAllTextAsync(gameCertList, certList2.Substring(0, goodSslIndex2));
|
||||
}
|
||||
else
|
||||
{
|
||||
// add to hosts file
|
||||
string hosts = $@"{ip} cloud.nikke-kr.com
|
||||
string hosts = $@"{HostsStartMarker}
|
||||
{ip} global-lobby.nikke-kr.com
|
||||
{ip} jp-lobby.nikke-kr.com
|
||||
";
|
||||
if (offlineMode)
|
||||
{
|
||||
hosts += $"{ip} cloud.nikke-kr.com" + Environment.NewLine;
|
||||
}
|
||||
|
||||
hosts += $@"{ip} jp-lobby.nikke-kr.com
|
||||
{ip} us-lobby.nikke-kr.com
|
||||
{ip} kr-lobby.nikke-kr.com
|
||||
{ip} sea-lobby.nikke-kr.com
|
||||
@@ -141,13 +225,15 @@ namespace ServerSelector
|
||||
255.255.221.21 na.fleetlogd.com
|
||||
{ip} www.jupiterlauncher.com
|
||||
{ip} data-aws-na.intlgame.com
|
||||
255.255.221.21 sentry.io";
|
||||
255.255.221.21 sentry.io
|
||||
{HostsEndMarker}";
|
||||
|
||||
await RevertHostsFile();
|
||||
if (!(await File.ReadAllTextAsync(hostsFilePath)).Contains("global-lobby.nikke-kr.com"))
|
||||
{
|
||||
using StreamWriter w = File.AppendText(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "drivers/etc/hosts"));
|
||||
w.WriteLine();
|
||||
w.WriteLine(hosts);
|
||||
w.Write(hosts);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
namespace ServerSelector.ViewModels;
|
||||
|
||||
public class MainViewModel : ViewModelBase
|
||||
{
|
||||
public string Greeting => "Welcome to Avalonia!";
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
using ReactiveUI;
|
||||
|
||||
namespace ServerSelector.ViewModels;
|
||||
|
||||
public class ViewModelBase : ReactiveObject
|
||||
{
|
||||
}
|
||||
@@ -3,17 +3,10 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:vm="clr-namespace:ServerSelector.ViewModels"
|
||||
mc:Ignorable="d" d:DesignWidth="370" d:DesignHeight="250"
|
||||
mc:Ignorable="d" d:DesignWidth="370" d:DesignHeight="300"
|
||||
x:Class="ServerSelector.Views.MainView"
|
||||
x:DataType="vm:MainViewModel"
|
||||
xmlns:ui="using:FluentAvalonia.UI.Controls"
|
||||
>
|
||||
<Design.DataContext>
|
||||
<!-- This only sets the DataContext for the previewer in an IDE,
|
||||
to set the actual DataContext for runtime, set the DataContext property in code (look at App.axaml.cs) -->
|
||||
<vm:MainViewModel />
|
||||
</Design.DataContext>
|
||||
|
||||
<Grid>
|
||||
<TabControl x:Name="MainUI">
|
||||
<TabItem Header="PC" x:Name="TabPc">
|
||||
@@ -34,15 +27,17 @@
|
||||
<RowDefinition Height="auto"></RowDefinition>
|
||||
<RowDefinition Height="5"></RowDefinition>
|
||||
<RowDefinition Height="auto"></RowDefinition>
|
||||
<RowDefinition Height="5"></RowDefinition>
|
||||
<RowDefinition Height="auto"></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
|
||||
<TextBlock VerticalAlignment="Center" Margin="5" Grid.Row="0" Grid.Column="0">Game path: </TextBlock>
|
||||
<TextBox x:Name="txtGamePath" Grid.Row="0" Grid.Column="1">C:\NIKKE\NIKKE\game</TextBox>
|
||||
<TextBox x:Name="txtGamePath" Grid.Row="0" Grid.Column="1" TextChanged="GamePath_TextChanged">C:\NIKKE\NIKKE\game</TextBox>
|
||||
<Button x:Name="btnSelectGamePath" Grid.Row="0" Grid.Column="2" Content="..." Click="BtnSelectGamePath_Click"></Button>
|
||||
|
||||
<TextBlock VerticalAlignment="Center" Margin="5" Grid.Row="2" Grid.Column="0">Launcher path: </TextBlock>
|
||||
<TextBox x:Name="txtLauncherPath" Grid.Row="2" Grid.Column="1">C:\NIKKE\Launcher</TextBox>
|
||||
<TextBox x:Name="txtLauncherPath" Grid.Row="2" Grid.Column="1" TextChanged="LauncherPath_TextChanged">C:\NIKKE\Launcher</TextBox>
|
||||
<Button x:Name="btnSelectLauncherPath" Grid.Row="2" Grid.Column="2" Content="..." Click="BtnSelectLauncherPath_Click"></Button>
|
||||
|
||||
|
||||
@@ -55,11 +50,13 @@
|
||||
</ComboBox.Items>
|
||||
</ComboBox>
|
||||
|
||||
<TextBlock VerticalAlignment="Center" Margin="5" Grid.Row="6" Grid.Column="0">IP: </TextBlock>
|
||||
<TextBlock x:Name="LblIp" VerticalAlignment="Center" Margin="5" Grid.Row="6" Grid.Column="0">IP: </TextBlock>
|
||||
<TextBox x:Name="TxtIpAddress" Grid.Row="6" Grid.Column="1" Grid.ColumnSpan="2">127.0.0.1</TextBox>
|
||||
|
||||
<TextBlock Grid.Row="8" Grid.Column="0" VerticalAlignment="Center" Margin="5" x:Name="LblStatus">Status: OK</TextBlock>
|
||||
<Button HorizontalAlignment="Right" Margin="5" Click="Save_Click" Grid.Row="8" Grid.Column="1" Grid.ColumnSpan="2" Classes="accent">Save</Button>
|
||||
<CheckBox x:Name="ChkOffline" VerticalAlignment="Center" Margin="5" Grid.Row="8" Grid.Column="0" Grid.ColumnSpan="3" ToolTip.Tip="Enables the ability to run the game offline by making the game download the assets from the server, and not the official server. This only works if enableOffline is enabled on the server. Please note that this should not be enabled on public servers due to copyright issues.">Enable offline mode</CheckBox>
|
||||
|
||||
<TextBlock Grid.Row="10" Grid.Column="0" VerticalAlignment="Center" Margin="5" x:Name="LblStatus" ToolTip.Tip="Shows the status of the patches to the game. All patches are reverted when server is set to official.">Status: OK</TextBlock>
|
||||
<Button HorizontalAlignment="Right" Margin="5" Click="Save_Click" Grid.Row="10" Grid.Column="1" Grid.ColumnSpan="2" Classes="accent">Save</Button>
|
||||
</Grid>
|
||||
</TabItem>
|
||||
<TabItem Header="Android">
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Media;
|
||||
using Avalonia.Platform.Storage;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using System;
|
||||
@@ -17,6 +18,7 @@ public partial class MainView : UserControl
|
||||
CmbServerSelection.SelectedIndex = ServerSwitcher.IsUsingOfficalServer() ? 0 : 1;
|
||||
|
||||
TxtIpAddress.IsEnabled = !ServerSwitcher.IsUsingOfficalServer();
|
||||
ChkOffline.IsChecked = ServerSwitcher.IsOffline();
|
||||
|
||||
if (OperatingSystem.IsWindows() && !new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator))
|
||||
{
|
||||
@@ -28,40 +30,108 @@ public partial class MainView : UserControl
|
||||
};
|
||||
}
|
||||
|
||||
LblStatus.Text = "Status: " + ServerSwitcher.CheckIntegrity();
|
||||
UpdateIntegrityLabel();
|
||||
}
|
||||
|
||||
private void Save_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||
private void SetGamePathValid(bool isValid)
|
||||
{
|
||||
if (string.IsNullOrEmpty(txtGamePath.Text) || string.IsNullOrEmpty(txtLauncherPath.Text))
|
||||
if (isValid)
|
||||
{
|
||||
ShowWarningMsg("Game path / launcher path is empty", "Error");
|
||||
return;
|
||||
txtGamePath.BorderBrush = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
txtGamePath.BorderBrush = new SolidColorBrush(Color.FromRgb(255,0,0));
|
||||
}
|
||||
}
|
||||
private void SetLauncherPathValid(bool isValid)
|
||||
{
|
||||
if (isValid)
|
||||
{
|
||||
txtLauncherPath.BorderBrush = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
txtLauncherPath.BorderBrush = new SolidColorBrush(Color.FromRgb(255, 0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
private bool ValidatePaths(bool showMessage)
|
||||
{
|
||||
if (string.IsNullOrEmpty(txtGamePath.Text))
|
||||
{
|
||||
SetGamePathValid(false);
|
||||
if (showMessage)
|
||||
ShowWarningMsg("Game path is blank", "Error");
|
||||
return false;
|
||||
}
|
||||
if (string.IsNullOrEmpty(txtLauncherPath.Text))
|
||||
{
|
||||
SetLauncherPathValid(false);
|
||||
if (showMessage)
|
||||
ShowWarningMsg("Launcher path is blank", "Error");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Directory.Exists(txtGamePath.Text))
|
||||
{
|
||||
ShowWarningMsg("Game path folder does not exist", "Error");
|
||||
return;
|
||||
SetGamePathValid(false);
|
||||
if (showMessage)
|
||||
ShowWarningMsg("Game path does not exist", "Error");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Directory.Exists(txtLauncherPath.Text))
|
||||
{
|
||||
ShowWarningMsg("Launcher folder does not exist", "Error");
|
||||
return;
|
||||
SetLauncherPathValid(false);
|
||||
if (showMessage)
|
||||
ShowWarningMsg("Launcher path does not exist", "Error");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!File.Exists(Path.Combine(txtLauncherPath.Text, "nikke_launcher.exe")))
|
||||
{
|
||||
ShowWarningMsg("Launcher path is invalid. Make sure that the game executable exists in the launcher folder", "Error");
|
||||
return;
|
||||
SetGamePathValid(false);
|
||||
if (showMessage)
|
||||
ShowWarningMsg("Launcher path is invalid. Make sure that the game executable exists in the launcher folder", "Error");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!File.Exists(Path.Combine(txtGamePath.Text, "nikke.exe")))
|
||||
{
|
||||
ShowWarningMsg("Game path is invalid. Make sure that nikke.exe exists in the launcher folder", "Error");
|
||||
SetGamePathValid(true);
|
||||
SetLauncherPathValid(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private async void UpdateIntegrityLabel()
|
||||
{
|
||||
if (!ValidatePaths(false) || txtGamePath.Text == null || txtLauncherPath.Text == null)
|
||||
return;
|
||||
|
||||
SetLoadingScreenVisible(true);
|
||||
LblStatus.Text = "Status: " + await ServerSwitcher.CheckIntegrity(txtGamePath.Text, txtLauncherPath.Text);
|
||||
SetLoadingScreenVisible(false);
|
||||
}
|
||||
|
||||
private void SetLoadingScreenVisible(bool visible)
|
||||
{
|
||||
if (visible)
|
||||
{
|
||||
MainUI.IsVisible = false;
|
||||
LoadingUI.IsVisible = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LoadingUI.IsVisible = false;
|
||||
MainUI.IsVisible = true;
|
||||
}
|
||||
}
|
||||
|
||||
private async void Save_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||
{
|
||||
if (!ValidatePaths(true) || txtGamePath.Text == null || txtLauncherPath.Text == null)
|
||||
return;
|
||||
|
||||
if (CmbServerSelection.SelectedIndex == 1)
|
||||
{
|
||||
@@ -73,26 +143,27 @@ public partial class MainView : UserControl
|
||||
}
|
||||
if (TxtIpAddress.Text == null) TxtIpAddress.Text = "";
|
||||
|
||||
MainUI.IsVisible = false;
|
||||
LoadingUI.IsVisible = true;
|
||||
|
||||
SetLoadingScreenVisible(true);
|
||||
try
|
||||
{
|
||||
ServerSwitcher.SaveCfg(CmbServerSelection.SelectedIndex == 0, txtGamePath.Text, txtLauncherPath.Text, TxtIpAddress.Text);
|
||||
await ServerSwitcher.SaveCfg(CmbServerSelection.SelectedIndex == 0, txtGamePath.Text, txtLauncherPath.Text, TxtIpAddress.Text, ChkOffline.IsChecked ?? false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ShowWarningMsg("Failed to save configuration: " + ex.ToString(), "Error");
|
||||
}
|
||||
|
||||
LoadingUI.IsVisible = false;
|
||||
MainUI.IsVisible = true;
|
||||
UpdateIntegrityLabel();
|
||||
SetLoadingScreenVisible(false);
|
||||
}
|
||||
|
||||
private void CmbServerSelection_SelectionChanged(object? sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (CmbServerSelection != null)
|
||||
{
|
||||
TxtIpAddress.IsEnabled = CmbServerSelection.SelectedIndex == 1;
|
||||
ChkOffline.IsEnabled = CmbServerSelection.SelectedIndex == 1;
|
||||
LblIp.IsEnabled = CmbServerSelection.SelectedIndex == 1;
|
||||
}
|
||||
}
|
||||
|
||||
public static void ShowWarningMsg(string text, string title)
|
||||
@@ -127,6 +198,7 @@ public partial class MainView : UserControl
|
||||
return;
|
||||
}
|
||||
}
|
||||
UpdateIntegrityLabel();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -156,8 +228,16 @@ public partial class MainView : UserControl
|
||||
return;
|
||||
}
|
||||
}
|
||||
UpdateIntegrityLabel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void GamePath_TextChanged(object? sender, Avalonia.Controls.TextChangedEventArgs e)
|
||||
{
|
||||
UpdateIntegrityLabel();
|
||||
}
|
||||
private void LauncherPath_TextChanged(object? sender, Avalonia.Controls.TextChangedEventArgs e)
|
||||
{
|
||||
UpdateIntegrityLabel();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:views="clr-namespace:ServerSelector.Views"
|
||||
mc:Ignorable="d" d:DesignWidth="370" d:DesignHeight="250"
|
||||
mc:Ignorable="d" d:DesignWidth="370" d:DesignHeight="300"
|
||||
x:Class="ServerSelector.Views.MainWindow"
|
||||
Title="Server Switcher" Width="370" Height="260" CanResize="False">
|
||||
Title="Server Switcher" Width="370" Height="300" CanResize="False">
|
||||
<views:MainView />
|
||||
</Window>
|
||||
|
||||
21
ServerSelector/myCA.cer
Normal file
21
ServerSelector/myCA.cer
Normal file
@@ -0,0 +1,21 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDazCCAlOgAwIBAgIUcJP1SCl3PCMhEjSXcn1Ps1Wx+2kwDQYJKoZIhvcNAQEL
|
||||
BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
|
||||
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yNDA3MDQxNTAwNDRaFw0yNjEw
|
||||
MDcxNTAwNDRaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw
|
||||
HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB
|
||||
AQUAA4IBDwAwggEKAoIBAQCl2jEFtcvfIyvmqz0+RgsaijaU6YsWT4N2Xm+UE5SK
|
||||
k+C5EuGK/hhaFkIOjWHsxtxvVJQuXJcRZSjGhWLllOnvYtaIvKhvqQ/d1w6AhtoR
|
||||
KdZw76T4v7p+gcV+3OpJOcYpZMHY9N4i4+gg3ZSXjOMqCbzgmpF5Fyv75nFq+HR/
|
||||
ZERt29OH6jLul1oAAcHGbfm5eZY9RS5HS3/uADZjhjnt7MURUes6P/xrWb75wcdD
|
||||
yLaEwN+DzOZ+VvgbpJmS8hSWkm4e6h/vRsIjKTqnvw7dJIhrkeF7juIM8Z7QY96y
|
||||
CYWME+hHWWEz0M6yg1GDWt7EuVHzzINpSgbZZhvizDgPAgMBAAGjUzBRMB0GA1Ud
|
||||
DgQWBBTVvYY5ktXDZNPcsQjIoLMOhb88LTAfBgNVHSMEGDAWgBTVvYY5ktXDZNPc
|
||||
sQjIoLMOhb88LTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBx
|
||||
cXZMZwV8Q4Lfxm3z9cOlG8zp0b5JujeVqv6OV2p+CQ8Py8/R7/DD+IjpZ2QpKJ74
|
||||
UUSuqyyrL8zM21yiksgjYYZVxK4USjjL8kIB28Ml0+UmYtfkKmiXJNWs1gGPt8Q3
|
||||
aKLMNAj2aHx2vt1+Eu3iex8Pn9RZFsf/tUmxkara1jfVjEeNG/qjt1iM8yXbeyc0
|
||||
bx1y8LJKxWo8alux7ncNnDBF3td1ZchhoSg36IX+i6RTM8j/BNCTx3IiiY3hbfaH
|
||||
hH3FPD4U/Do9+GjidDFVku8OK8MIggYdD02AqR56tG+Sw2RNP35Ky23HcqUyRK5/
|
||||
NkmdLtIH+gwww/0oBb4I
|
||||
-----END CERTIFICATE-----
|
||||
Reference in New Issue
Block a user