Add files via upload

This commit is contained in:
casksteven 2023-02-10 21:19:10 -05:00 committed by GitHub
commit d4c4bb05c5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
50 changed files with 4492 additions and 0 deletions

26
App.config Normal file
View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.ComponentModel.Annotations" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.1.0" newVersion="4.2.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.1.2" newVersion="4.0.1.2" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

25
App.xaml Normal file
View file

@ -0,0 +1,25 @@
<Application
x:Class="Launcher.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Launcher"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Style/NavigationItemContainerStyle.xaml" />
<ResourceDictionary Source="pack://application:,,,/Panuon.WPF.UI;component/Control.xaml" />
</ResourceDictionary.MergedDictionaries>
<DropShadowEffect
x:Key="defaultShadow"
BlurRadius="10"
Opacity="0.2"
ShadowDepth="0" />
<FontFamily x:Key="remix">pack://application:,,,/Launcher;component/Res/#remixicon</FontFamily>
</ResourceDictionary>
</Application.Resources>
</Application>

103
App.xaml.cs Normal file
View file

@ -0,0 +1,103 @@
using Launcher.Model;
using Launcher.ViewModel;
using Newtonsoft.Json;
using System;
using System.Globalization;
using System.Net;
using System.Threading;
using System.Windows;
using System.Windows.Navigation;
namespace Launcher
{
/// <summary>
/// App.xaml 的交互逻辑
/// </summary>
public partial class App : Application
{
//#if DEBUG
// private CultureInfo cultureOverride = new CultureInfo("en-US");
//#endif
System.Threading.Mutex mutex;
protected override void OnStartup(StartupEventArgs e)
{
ServicePointManager.ServerCertificateValidationCallback += (s, cert, chain, sslPolicyErrors) => true;
AppDomain currentDomain = AppDomain.CurrentDomain;
// 当前作用域出现未捕获异常时使用MyHandler函数响应事件
#if !DEBUG
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyHandler);
#endif
//单例
bool ret;
mutex = new System.Threading.Mutex(true, "ElectronicNeedleTherapySystem", out ret);
if (App.launcherConfig == null)
{
App.launcherConfig = LauncherConfig.Load("config.json");
if (!string.IsNullOrEmpty(App.launcherConfig.Language))
{
CultureInfo cultureOverride = new CultureInfo(App.launcherConfig.Language);
Thread.CurrentThread.CurrentCulture = cultureOverride;
Thread.CurrentThread.CurrentUICulture = cultureOverride;
}
}
if (!ret)
{
MessageBox.Show(Launcher.Properties.Resources.tip_alreadyrunning);
Environment.Exit(0);
}
base.OnStartup(e);
}
static void MyHandler(object sender, UnhandledExceptionEventArgs args)
{
Exception e = (Exception)args.ExceptionObject;
MessageBox.Show(e.Message + "\n" + "请吧程序目录下的 err.log 提交至项目issues", Launcher.Properties.Resources.tip_crash_title);
System.IO.File.WriteAllText("err.log", e.Message + JsonConvert.SerializeObject(e));
Environment.Exit(0);
}
protected override void OnLoadCompleted(NavigationEventArgs e)
{
base.OnLoadCompleted(e);
}
protected override void OnExit(ExitEventArgs e)
{
try
{
launcherConfig.Save("config.json");
if (HomeVM.Instacne.proxyController!=null)
{
HomeVM.Instacne.proxyController.Stop();
}
}
catch { }
base.OnExit(e);
}
public static LauncherConfig launcherConfig;
}
}

140
Common/EmbedFileManager.cs Normal file
View file

@ -0,0 +1,140 @@
using System;
using System.IO;
using System.Reflection;
namespace Launcher.Common
{
internal class EmbedFileManager
{
/// <summary>
/// 释放内嵌资源至指定位置
/// </summary>
/// <param name="resource">嵌入的资源,此参数写作:命名空间.文件夹名.文件名.扩展名</param>
/// <param name="path">释放到位置</param>
public static void ExtractFile(string file, string path)
{
var resource = $"Launcher.{file}";
Assembly assembly = Assembly.GetExecutingAssembly();
BufferedStream input = new BufferedStream(assembly.GetManifestResourceStream(resource));
FileStream output = new FileStream(path, FileMode.Create);
byte[] data = new byte[1024];
int lengthEachRead;
while ((lengthEachRead = input.Read(data, 0, data.Length)) > 0)
{
output.Write(data, 0, lengthEachRead);
}
output.Flush();
output.Close();
}
}
public static class RawFileHelper
{
public static byte[] GetKey(string file)
{
Stream sr = null; ;
try
{
var _assembly = Assembly.GetExecutingAssembly();//获取当前执行代码的程序集
sr = _assembly.GetManifestResourceStream($"Launcher.RSAPatch.{file}");
}
catch
{
//AConsole.e(new Spectre.Console.Markup("访问资源错误"));
throw;
}
return streamToByteArray(sr);
}
private static byte[] streamToByteArray(Stream input)
{
MemoryStream ms = new MemoryStream();
input.CopyTo(ms);
return ms.ToArray();
}
}
public static class RSAPatchHelper
{
public static string TempFolder = Path.Combine(System.IO.Path.GetTempPath(),"com.launcher");
public static string WriteMhypbaseAllTo(Model.ServerItem item)
{
if (!Directory.Exists(TempFolder))
{
Directory.CreateDirectory(TempFolder);
}
var r = WriteDllTo(TempFolder);
WriteInITo(TempFolder, item);
return r;
}
public static void CleanTemp()
{
Directory.Delete(TempFolder, true);
}
public static string WriteDllTo(string folder)
{
string target_dll = Path.Combine(folder, "rsa.dll");
try
{
EmbedFileManager.ExtractFile("RSAPatch.RSAPatch.dll", target_dll);
}
catch
{
throw;
}
return target_dll;
}
public static void WriteInITo(string folder, Model.ServerItem item)
{
try
{
if (App.launcherConfig.DebugMode)
{
// debug
}
if (!string.IsNullOrEmpty(item.RSAPrivateKey))
{
File.WriteAllText(Path.Combine(folder,"PrivateKey.txt"), item.RSAPrivateKey);
}
if (!string.IsNullOrEmpty(item.RSAPublicKey))
{
File.WriteAllText(Path.Combine(folder, "PublicKey.txt"), item.RSAPublicKey);
}
else
{
// use default
File.WriteAllBytes(Path.Combine(folder, "PublicKey.txt"), RawFileHelper.GetKey("PublicKey.txt"));
}
}
catch
{
throw;
}
}
private static byte[] streamToByteArray(Stream input)
{
MemoryStream ms = new MemoryStream();
input.CopyTo(ms);
return ms.ToArray();
}
}
}

186
Common/GameHelper.cs Normal file
View file

@ -0,0 +1,186 @@
using CommunityToolkit.Mvvm.Input;
using Launcher.Control;
using Microsoft.Win32;
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows;
namespace Launcher.Common
{
internal class GameHelper
{
[DllImport("InjectorLib.dll", CallingConvention = CallingConvention.Cdecl)]
extern static bool Begin(string game_path, string dll_path);
public static void StartGame(string filePath,string target_dll)
{
string currentDir = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
string dll_file = Path.Combine(currentDir, "InjectorLib.dll");
if (File.Exists(filePath))
{
//if (!File.Exists("InjectorLib.dll"))
//{
// EmbedFileManager.ExtractFile("InjectorLib.dll", dll_file);
//}
target_dll =Path.Combine(currentDir, target_dll);
bool r=Begin(filePath, target_dll);
if (r)
{
SnackBar.Show("Inject Success!",null);
}
else
{
SnackBar.Show("Inject Failed!", null);
}
}
else
{
}
}
public static class GameRegReader
{
/// <summary>
/// 获取游戏目录,是静态方法
/// </summary>
/// <returns></returns>
public static string GetGamePath()
{
try
{
string startpath = "";
string launcherpath = GetLauncherPath();
#region
string cfgPath = Path.Combine(launcherpath, "config.ini");
if (File.Exists(launcherpath) || File.Exists(cfgPath))
{
//获取游戏本体路径
using (StreamReader reader = new StreamReader(cfgPath))
{
string[] abc = reader.ReadToEnd().Split(new string[] { "\r\n" }, StringSplitOptions.None);
foreach (var item in abc)
{
//从官方获取更多配置
if (item.IndexOf("game_install_path") != -1)
{
startpath += item.Substring(item.IndexOf("=") + 1);
}
}
}
}
byte[] bytearr = Encoding.UTF8.GetBytes(startpath);
string path = Encoding.UTF8.GetString(bytearr);
return path;
}
catch
{
return null;
}
#endregion
}
/// <summary>
/// 启动器地址
/// </summary>
/// <returns></returns>
public static string GetLauncherPath()
{
try
{
RegistryKey key = Registry.LocalMachine; //打开指定注册表根
//获取官方启动器路径
string launcherpath = "";
try
{
launcherpath = key.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\原神").GetValue("InstallPath").ToString();
}
catch (Exception)
{
launcherpath = key.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Genshin Impact").GetValue("InstallPath").ToString();
}
byte[] bytepath = Encoding.UTF8.GetBytes(launcherpath); //编码转换
string path = Encoding.UTF8.GetString(bytepath);
return path;
}
catch
{
return null;
}
}
public static string GetGameExePath()
{
var gamepath = GetGamePath();
if (gamepath == null)
{
return null;
}
var cnpath = gamepath + @"/YuanShen.exe";
var ospath = gamepath + @"/GenshinImpact.exe";
if (File.Exists(cnpath))
{
return cnpath;
}
else if (File.Exists(ospath))
{
return ospath;
}
else
{
return null;
}
}
}
public static class GameLocalReader
{
public static string GetGameExePath()
{
string Self = Process.GetCurrentProcess().MainModule.FileName;
var Folder = Path.GetDirectoryName(Self);
string ret;
string cn = Path.Combine(Folder, "YuanShen.exe");
string os = Path.Combine(Folder, "GenshinImpact.exe");
if (File.Exists(cn))
{
ret = Path.Combine(Folder, cn);
}
else if (File.Exists(os))
{
ret = Path.Combine(Folder, os);
}
else
{
throw new Exception("未能从当前路径找到原神游戏文件!");
}
return ret;
}
public static string GetGameExeFolder()
{
return Path.GetDirectoryName(GetGameExePath());
}
}
}
}

17
Common/IProxy.cs Normal file
View file

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Launcher.Common
{
public interface IProxyController
{
bool _IsRun { get; set; }
void Start();
void Stop();
}
}

43
Common/IniHelper.cs Normal file
View file

@ -0,0 +1,43 @@
using System.IO;
namespace Launcher.Common
{
public static class IniHelper
{
// 声明INI文件的写操作函数 WritePrivateProfileString()
[System.Runtime.InteropServices.DllImport("kernel32")]
private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
// 声明INI文件的读操作函数 GetPrivateProfileString()
[System.Runtime.InteropServices.DllImport("kernel32")]
private static extern int GetPrivateProfileString(string section, string key, string def, System.Text.StringBuilder retVal, int size, string filePath);
/// 写入INI的方法
public static void INIWrite(string section, string key, string value, string path)
{
// section=配置节点名称key=键名value=返回键值path=路径
WritePrivateProfileString(section, key, value, path);
}
//读取INI的方法
public static string INIRead(string section, string key, string path)
{
// 每次从ini中读取多少字节
System.Text.StringBuilder temp = new System.Text.StringBuilder(255);
// section=配置节点名称key=键名temp=上面path=路径
GetPrivateProfileString(section, key, "", temp, 255, path);
return temp.ToString();
}
//删除一个INI文件
public static void INIDelete(string FilePath)
{
File.Delete(FilePath);
}
}
}

40
Common/ProcessWatcher.cs Normal file
View file

@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Launcher.Common
{
internal class ProcessWatcher
{
public Process proc;
EventHandler pro_Exited;
public ProcessWatcher(EventHandler pro_Exited)
{
this.pro_Exited = pro_Exited;
}
public void Watch()
{
Process[] ps = Process.GetProcesses();
foreach (Process p in ps)
{
if (p.ProcessName== "GenshinImpact"||p.ProcessName== "YuanShen")
{
proc = p;
}
}
if (proc!=null)
{
proc.EnableRaisingEvents = true;
proc.Exited += new EventHandler(pro_Exited);
}
}
}
}

209
Common/ProxyHelper.cs Normal file
View file

@ -0,0 +1,209 @@
using Launcher.Model;
using Microsoft.Win32;
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Threading.Tasks;
using Titanium.Web.Proxy;
using Titanium.Web.Proxy.EventArguments;
using Titanium.Web.Proxy.Models;
namespace Launcher.Common
{
internal static class ProxyHelper
{
public static ProxyConfig GetCurrentProxy()
{
ProxyConfig proxyConfig = new ProxyConfig("127.0.0.1");
try
{
using (RegistryKey regkey = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Internet Settings"))
{
if (regkey.GetValue("ProxyEnable").ToString() == "1")
{
proxyConfig.ProxyEnable = true;
}
object ps = regkey.GetValue("ProxyServer");
if (ps != null)
{
proxyConfig.ProxyServer = ps.ToString();
}
else
{
ps = null;
}
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
return proxyConfig;
}
public static void Clear_Proxy()
{
using (RegistryKey regkey = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Internet Settings", true))
{
try
{
regkey.SetValue("ProxyEnable", 0);
regkey.DeleteValue("ProxyServer");
}
catch (Exception e)
{
Debug.Print(e.Message);
}
}
}
public class ProxyController
{
ProxyServer proxyServer;
ExplicitProxyEndPoint explicitEndPoint;
private string port;
private string fakeHost;
private bool usehttp;
public ProxyController(string port, string host, bool usehttp = false)
{
this.port = port;
this.fakeHost = host;
this.usehttp = usehttp;
}
private bool IsRun;
public bool _IsRun
{
get { return proxyServer.ProxyRunning; }
set { IsRun = value; }
}
public void Start()
{
if (GetCurrentProxy().ProxyEnable)
{
Clear_Proxy();
}
proxyServer = new ProxyServer();
var docp = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
var certp = Path.Combine(docp, "rootCert.pfx");
proxyServer.CertificateManager.PfxFilePath = certp;
proxyServer.CertificateManager.EnsureRootCertificate();
proxyServer.BeforeRequest += OnRequest;
proxyServer.ServerCertificateValidationCallback += OnCertificateValidation;
if (String.IsNullOrEmpty(port))
{
port = 11451.ToString(); ;
}
explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, int.Parse(port), true);
explicitEndPoint.BeforeTunnelConnectRequest += OnBeforeTunnelConnectRequest;
proxyServer.AddEndPoint(explicitEndPoint);
proxyServer.Start();
foreach (var endPoint in proxyServer.ProxyEndPoints)
Console.WriteLine("Listening on '{0}' endpoint at Ip {1} and port: {2} ",
endPoint.GetType().Name, endPoint.IpAddress, endPoint.Port);
proxyServer.SetAsSystemHttpProxy(explicitEndPoint);
proxyServer.SetAsSystemHttpsProxy(explicitEndPoint);
}
public void Stop()
{
try
{
explicitEndPoint.BeforeTunnelConnectRequest -= OnBeforeTunnelConnectRequest;
proxyServer.BeforeRequest -= OnRequest;
proxyServer.ServerCertificateValidationCallback -= OnCertificateValidation;
}
catch { }
finally
{
if (proxyServer != null && proxyServer.ProxyRunning)
{
proxyServer.Stop();
}
else
{
}
}
}
public void UninstallCertificate()
{
proxyServer.CertificateManager.RemoveTrustedRootCertificate();
proxyServer.CertificateManager.RemoveTrustedRootCertificateAsAdmin();
}
private async Task OnBeforeTunnelConnectRequest(object sender, TunnelConnectSessionEventArgs e)
{
string hostname = e.WebSession.Request.RequestUri.Host;
if (hostname.EndsWith(".yuanshen.com") |
hostname.EndsWith(".hoyoverse.com") |
hostname.EndsWith(".mihoyo.com") | hostname.EndsWith(fakeHost))
{
e.DecryptSsl = true;
}
else
{
e.DecryptSsl = false;
}
}
private async Task OnRequest(object sender, SessionEventArgs e)
{
string hostname = e.WebSession.Request.RequestUri.Host;
if (hostname.EndsWith(".yuanshen.com") |
hostname.EndsWith(".hoyoverse.com") |
hostname.EndsWith(".mihoyo.com"))
{
string oHost = e.WebSession.Request.RequestUri.Host;
e.HttpClient.Request.Url = e.HttpClient.Request.Url.Replace(oHost, fakeHost);
if (usehttp)
{
e.HttpClient.Request.Url = e.HttpClient.Request.Url.Replace("https", "http");
}
}
}
// Allows overriding default certificate validation logic
private Task OnCertificateValidation(object sender, CertificateValidationEventArgs e)
{
e.IsValid = true;
return Task.CompletedTask;
}
}
}
}

View file

@ -0,0 +1,174 @@
<UserControl
x:Class="Launcher.Control.ServerEditControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Launcher.Control"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:prop="clr-namespace:Launcher.Properties"
xmlns:pu="clr-namespace:Panuon.WPF.UI;assembly=Panuon.WPF.UI"
Name="root"
d:DesignHeight="450"
d:DesignWidth="800"
d:Visibility="Visible"
Visibility="Collapsed"
mc:Ignorable="d">
<Grid Background="#aa000000">
<Border
Width="600"
MinHeight="200"
MaxHeight="400"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Background="#f3f6fc"
CornerRadius="20">
<Grid Margin="20">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<ScrollViewer>
<StackPanel>
<TextBlock
Margin="0,0,0,6"
FontSize="17"
FontWeight="Bold"
Foreground="#294681"
Text="{x:Static prop:Resources.h_serveredit}" />
<TextBox
xmlns:Model="clr-namespace:Launcher.Model"
Grid.Column="1"
MinWidth="100"
Margin="0,5,5,5"
Padding="8"
pu:TextBoxHelper.CornerRadius="4"
pu:TextBoxHelper.FocusedBorderBrush="#2a73c5"
pu:TextBoxHelper.Watermark="{x:Static prop:Resources.tip_srvname}"
Background="Transparent"
BorderThickness="1"
FontSize="14"
Text="{Binding ElementName=root, Path=ServerItem.Name}" />
<Grid Margin="0,0,5,0">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<TextBox
xmlns:Model="clr-namespace:Launcher.Model"
MinWidth="100"
Margin="0,5,5,5"
Padding="8"
pu:TextBoxHelper.CornerRadius="4"
pu:TextBoxHelper.FocusedBorderBrush="#2a73c5"
pu:TextBoxHelper.Watermark="127.0.0.1:8080"
Background="Transparent"
BorderThickness="1"
FontSize="14"
Text="{Binding ElementName=root, Path=ServerItem.proxy.ProxyServer}" />
<CheckBox
Grid.Column="1"
pu:CheckBoxHelper.CheckedGlyphBrush="#1e64d4"
pu:CheckBoxHelper.CornerRadius="4"
pu:CheckBoxHelper.GlyphThickness="3"
pu:CheckBoxHelper.HoverBorderBrush="#1e64d4"
Content="{x:Static prop:Resources.cb_usehttp}"
FontSize="16"
IsChecked="{Binding ElementName=root, Path=ServerItem.proxy.UseHttp}" />
</Grid>
<!--<TextBox
xmlns:Model="clr-namespace:Launcher.Model"
Grid.Column="1"
MinWidth="100"
Margin="0,5,0,5"
Padding="8"
pu:TextBoxHelper.CornerRadius="4"
pu:TextBoxHelper.FocusedBorderBrush="#2a73c5"
pu:TextBoxHelper.Watermark="服务器名称"
Background="Transparent"
BorderThickness="1"
FontSize="14"
Text="{Binding LauncherConfig.GameInfo.GameExePath}" />-->
<Expander Background="Transparent" BorderThickness="0">
<Expander.Header>
<TextBlock Text="{x:Static prop:Resources.t_advanced}" />
</Expander.Header>
<StackPanel>
<TextBox
xmlns:Model="clr-namespace:Launcher.Model"
MinWidth="100"
Margin="0,5,5,5"
Padding="8"
pu:TextBoxHelper.CornerRadius="4"
pu:TextBoxHelper.FocusedBorderBrush="#2a73c5"
pu:TextBoxHelper.Watermark="{x:Static prop:Resources.tip_publickey}"
AcceptsReturn="True"
Background="Transparent"
BorderThickness="1"
FontSize="14"
Text="{Binding ElementName=root, Path=ServerItem.RSAPublicKey}" />
<TextBox
xmlns:Model="clr-namespace:Launcher.Model"
MinWidth="100"
Margin="0,5,5,5"
Padding="8"
pu:TextBoxHelper.CornerRadius="4"
pu:TextBoxHelper.FocusedBorderBrush="#2a73c5"
pu:TextBoxHelper.Watermark="{x:Static prop:Resources.tip_privatekey}"
AcceptsReturn="True"
Background="Transparent"
BorderThickness="1"
FontSize="14"
Text="{Binding ElementName=root, Path=ServerItem.RSAPrivateKey}" />
</StackPanel>
</Expander>
</StackPanel>
</ScrollViewer>
<StackPanel
Grid.Row="1"
HorizontalAlignment="Right"
Orientation="Horizontal">
<Button
Padding="18,12"
pu:ButtonHelper.ClickBackground="#88f8fafd"
pu:ButtonHelper.CornerRadius="8"
pu:ButtonHelper.HoverBackground="#88b8daf0"
Background="Transparent"
BorderThickness="0"
Click="Button_Click_1"
Content="{x:Static prop:Resources.tb_ok}"
FontFamily="{StaticResource remix}"
FontSize="14"
FontWeight="Bold"
Foreground="#558fd1" />
<Button
Margin="8,0,0,0"
Padding="18,12"
pu:ButtonHelper.ClickBackground="#44f8fafd"
pu:ButtonHelper.CornerRadius="8"
pu:ButtonHelper.HoverBackground="#44b8daf0"
Background="Transparent"
BorderThickness="0"
Click="Button_Click"
Content="取消"
FontFamily="{StaticResource remix}"
FontSize="14"
Foreground="#558fd1"
Visibility="Collapsed" />
</StackPanel>
</Grid>
</Border>
</Grid>
</UserControl>

View file

@ -0,0 +1,61 @@
using Launcher.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Launcher.Control
{
/// <summary>
/// ServerEditControl.xaml 的交互逻辑
/// </summary>
public partial class ServerEditControl : UserControl
{
public static ServerEditControl instance;
public static void Show()
{
instance.Visibility =Visibility.Visible;
}
public ServerEditControl()
{
InitializeComponent();
instance = this;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Visibility = Visibility.Collapsed;
}
public ServerItem ServerItem
{
get { return (ServerItem)GetValue(ServerItemProperty); }
set { SetValue(ServerItemProperty, value); }
}
// Using a DependencyProperty as the backing store for ServerItem. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ServerItemProperty =
DependencyProperty.Register("ServerItem", typeof(ServerItem), typeof(ServerEditControl), new PropertyMetadata(null));
private void Button_Click_1(object sender, RoutedEventArgs e)
{
Visibility = Visibility.Collapsed;
}
}
}

36
Control/SnackBar.xaml Normal file
View file

@ -0,0 +1,36 @@
<UserControl
x:Class="Launcher.Control.SnackBar"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Launcher.Control"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:pu="clr-namespace:Panuon.WPF.UI;assembly=Panuon.WPF.UI"
d:Width="200"
mc:Ignorable="d">
<Border Background="#FF312F36" CornerRadius="10">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<TextBlock
x:Name="msg_tb"
Margin="10"
Foreground="White"
Text="这是一个SnackBar" />
<Button
x:Name="action_btn"
Grid.Column="1"
Margin="4"
pu:ButtonHelper.ClickBackground="#301c54b2"
pu:ButtonHelper.CornerRadius="4"
Background="Transparent"
Click="action_btn_Click"
Content="确定"
Cursor="Hand"
Foreground="#1c54b2" />
</Grid>
</Border>
</UserControl>

96
Control/SnackBar.xaml.cs Normal file
View file

@ -0,0 +1,96 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace Launcher.Control
{
/// <summary>
/// SnackBar.xaml 的交互逻辑
/// </summary>
public partial class SnackBar : UserControl
{
public SnackBar()
{
InitializeComponent();
}
public static void Show(string Msg, ICommand Command, string ActionStr = "确定")
{
var sb = new SnackBar();
sb.Command = Command;
sb.ActionStr = ActionStr;
sb.Msg = Msg;
MainWindow.Instance.sb_container.Children.Add(sb);
}
public string Msg
{
get { return (string)GetValue(MsgProperty); }
set { SetValue(MsgProperty, value); }
}
// Using a DependencyProperty as the backing store for Msg. This enables animation, styling, binding, etc...
public static readonly DependencyProperty MsgProperty =
DependencyProperty.Register("Msg", typeof(string), typeof(SnackBar), new PropertyMetadata("这是一个 Snack Bar", (s, e) =>
{
var bar = s as SnackBar;
if (bar != null)
bar.msg_tb.Text = e.NewValue.ToString();
}));
public string ActionStr
{
get { return (string)GetValue(ActionStrProperty); }
set { SetValue(ActionStrProperty, value); }
}
// Using a DependencyProperty as the backing store for ActionStr. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ActionStrProperty =
DependencyProperty.Register("ActionStr", typeof(string), typeof(SnackBar), new PropertyMetadata("确定", (s, e) =>
{
var bar = s as SnackBar;
if (bar != null)
bar.action_btn.Content = e.NewValue.ToString();
}));
private void action_btn_Click(object sender, RoutedEventArgs e)
{
if (Command != null)
{
Command.Execute(null);
}
this.Visibility = Visibility.Collapsed;
StackPanel stackPanel = this.Parent as StackPanel;
if (stackPanel != null)
{
stackPanel.Children.Remove(this);
}
}
public ICommand Command
{
get { return (ICommand)GetValue(CommandProperty); }
set { SetValue(CommandProperty, value); }
}
// Using a DependencyProperty as the backing store for Command. This enables animation, styling, binding, etc...
public static readonly DependencyProperty CommandProperty =
DependencyProperty.Register("Command", typeof(ICommand), typeof(SnackBar), new PropertyMetadata(null));
}
}

BIN
Costura64/InjectorLib.dll Normal file

Binary file not shown.

7
FodyWeavers.xml Normal file
View file

@ -0,0 +1,7 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<Costura>
<Unmanaged64Assemblies>
InjectorLib
</Unmanaged64Assemblies>
</Costura>
</Weavers>

404
Launcher.csproj Normal file
View file

@ -0,0 +1,404 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="packages\Costura.Fody.5.7.0\build\Costura.Fody.props" Condition="Exists('packages\Costura.Fody.5.7.0\build\Costura.Fody.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{D3AA2F83-0262-4994-928F-497847A6C8EC}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>Launcher</RootNamespace>
<AssemblyName>Launcher</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Label="MultilingualAppToolkit">
<MultilingualAppToolkitVersion>4.0</MultilingualAppToolkitVersion>
<MultilingualFallbackLanguage>zh-CN</MultilingualFallbackLanguage>
<TranslationReport Condition="'$(Configuration)' == 'Release'">true</TranslationReport>
<SuppressPseudoWarning Condition="'$(Configuration)' == 'Debug'">true</SuppressPseudoWarning>
</PropertyGroup>
<ItemGroup>
<Reference Include="BouncyCastle.Crypto, Version=1.8.8.0, Culture=neutral, PublicKeyToken=0e99375e54769942, processorArchitecture=MSIL">
<HintPath>packages\Portable.BouncyCastle.1.8.8\lib\net40\BouncyCastle.Crypto.dll</HintPath>
</Reference>
<Reference Include="BrotliSharpLib, Version=0.3.2.0, Culture=neutral, PublicKeyToken=3f4e2a1cd615fcb7, processorArchitecture=MSIL">
<HintPath>packages\BrotliSharpLib.0.3.3\lib\net451\BrotliSharpLib.dll</HintPath>
</Reference>
<Reference Include="CommunityToolkit.Mvvm, Version=8.0.0.0, Culture=neutral, PublicKeyToken=4aff67a105548ee2, processorArchitecture=MSIL">
<HintPath>packages\CommunityToolkit.Mvvm.8.0.0\lib\netstandard2.0\CommunityToolkit.Mvvm.dll</HintPath>
</Reference>
<Reference Include="Costura, Version=5.7.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>packages\Costura.Fody.5.7.0\lib\netstandard1.0\Costura.dll</HintPath>
</Reference>
<Reference Include="InjectorLib">
<HintPath>.\InjectorLib.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.Bcl.AsyncInterfaces.6.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Win32.Primitives, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.Win32.Primitives.4.3.0\lib\net46\Microsoft.Win32.Primitives.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Win32.Registry, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\Microsoft.Win32.Registry.5.0.0\lib\net461\Microsoft.Win32.Registry.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="Panuon.WPF, Version=1.0.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>packages\Panuon.WPF.1.0.1\lib\net472\Panuon.WPF.dll</HintPath>
</Reference>
<Reference Include="Panuon.WPF.UI, Version=1.1.6.5, Culture=neutral, processorArchitecture=MSIL">
<HintPath>packages\Panuon.WPF.UI.1.1.6.5\lib\net472\Panuon.WPF.UI.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.AppContext, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.AppContext.4.3.0\lib\net463\System.AppContext.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.ComponentModel.Annotations, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.ComponentModel.Annotations.5.0.0\lib\net461\System.ComponentModel.Annotations.dll</HintPath>
</Reference>
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Console, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Console.4.3.0\lib\net46\System.Console.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Diagnostics.DiagnosticSource, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>packages\System.Diagnostics.DiagnosticSource.4.3.0\lib\net46\System.Diagnostics.DiagnosticSource.dll</HintPath>
</Reference>
<Reference Include="System.Diagnostics.Tracing, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Diagnostics.Tracing.4.3.0\lib\net462\System.Diagnostics.Tracing.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Globalization.Calendars, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Globalization.Calendars.4.3.0\lib\net46\System.Globalization.Calendars.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.IO, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.IO.4.3.0\lib\net462\System.IO.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.IO.Compression, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<HintPath>packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.IO.Compression.FileSystem" />
<Reference Include="System.IO.Compression.ZipFile, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<HintPath>packages\System.IO.Compression.ZipFile.4.3.0\lib\net46\System.IO.Compression.ZipFile.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.IO.FileSystem, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.IO.FileSystem.4.3.0\lib\net46\System.IO.FileSystem.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.IO.FileSystem.Primitives, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Linq, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Linq.4.3.0\lib\net463\System.Linq.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Linq.Expressions, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Linq.Expressions.4.3.0\lib\net463\System.Linq.Expressions.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Memory, Version=4.0.1.2, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>packages\System.Memory.4.5.5\lib\net461\System.Memory.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Net.Http.4.3.0\lib\net46\System.Net.Http.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Sockets, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Net.Sockets.4.3.0\lib\net46\System.Net.Sockets.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
</Reference>
<Reference Include="System.Reflection, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Reflection.4.3.0\lib\net462\System.Reflection.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Runtime, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Runtime.4.3.0\lib\net462\System.Runtime.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.Extensions, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Runtime.Extensions.4.3.0\lib\net462\System.Runtime.Extensions.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Runtime.InteropServices, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Runtime.InteropServices.4.3.0\lib\net463\System.Runtime.InteropServices.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Runtime.InteropServices.RuntimeInformation, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Security.AccessControl, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Security.AccessControl.5.0.0\lib\net461\System.Security.AccessControl.dll</HintPath>
</Reference>
<Reference Include="System.Security.Cryptography.Algorithms, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net463\System.Security.Cryptography.Algorithms.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Security.Cryptography.Encoding, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Security.Cryptography.Primitives, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Security.Cryptography.X509Certificates, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Security.Principal.Windows, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Security.Principal.Windows.5.0.0\lib\net461\System.Security.Principal.Windows.dll</HintPath>
</Reference>
<Reference Include="System.Text.RegularExpressions, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Text.RegularExpressions.4.3.0\lib\net463\System.Text.RegularExpressions.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll</HintPath>
</Reference>
<Reference Include="System.Xml" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Xaml">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
</Reference>
<Reference Include="System.Xml.ReaderWriter, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.Xml.ReaderWriter.4.3.0\lib\net46\System.Xml.ReaderWriter.dll</HintPath>
<Private>True</Private>
<Private>True</Private>
</Reference>
<Reference Include="Titanium.Web.Proxy, Version=1.0.1.0, Culture=neutral, PublicKeyToken=8e41e1f1c790d7cf, processorArchitecture=MSIL">
<HintPath>packages\Titanium.Web.Proxy.3.2.0\lib\net461\Titanium.Web.Proxy.dll</HintPath>
</Reference>
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Compile Include="Common\EmbedFileManager.cs" />
<Compile Include="Common\GameHelper.cs" />
<Compile Include="Common\IniHelper.cs" />
<Compile Include="Common\ProcessWatcher.cs" />
<Compile Include="Common\ProxyHelper.cs" />
<Compile Include="Control\ServerEditControl.xaml.cs">
<DependentUpon>ServerEditControl.xaml</DependentUpon>
</Compile>
<Compile Include="Control\SnackBar.xaml.cs">
<DependentUpon>SnackBar.xaml</DependentUpon>
</Compile>
<Compile Include="Model\GameInfo.cs" />
<Compile Include="Model\LauncherConfig.cs" />
<Compile Include="Model\PkgVersionItem.cs" />
<Compile Include="Model\ProxyConfig.cs" />
<Compile Include="Model\ServerItem.cs" />
<Compile Include="ViewModel\HomeVM.cs" />
<Compile Include="ViewModel\SettingVM.cs" />
<Compile Include="View\About.xaml.cs">
<DependentUpon>About.xaml</DependentUpon>
</Compile>
<Compile Include="View\Home.xaml.cs">
<DependentUpon>Home.xaml</DependentUpon>
</Compile>
<Compile Include="View\Setting.xaml.cs">
<DependentUpon>Setting.xaml</DependentUpon>
</Compile>
<Page Include="Control\ServerEditControl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Control\SnackBar.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="MainWindow.xaml.cs">
<DependentUpon>MainWindow.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Page Include="Style\NavigationItemContainerStyle.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="View\About.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="View\Home.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="View\Setting.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<EmbeddedResource Include="Properties\Resources.en.resx" />
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<None Include="app.manifest" />
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Resource Include="Res\remixicon.ttf" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Costura64\InjectorLib.dll" />
</ItemGroup>
<ItemGroup>
<Resource Include="key\GC-Dispatch.txt" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="RSAPatch\PublicKey.txt" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="RSAPatch\RSAPatch.dll" />
</ItemGroup>
<ItemGroup>
<XliffResource Include="MultilingualResources\Launcher.en.xlf" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="packages\CommunityToolkit.Mvvm.8.0.0\build\netstandard2.0\CommunityToolkit.Mvvm.targets" Condition="Exists('packages\CommunityToolkit.Mvvm.8.0.0\build\netstandard2.0\CommunityToolkit.Mvvm.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('packages\CommunityToolkit.Mvvm.8.0.0\build\netstandard2.0\CommunityToolkit.Mvvm.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\CommunityToolkit.Mvvm.8.0.0\build\netstandard2.0\CommunityToolkit.Mvvm.targets'))" />
<Error Condition="!Exists('packages\Fody.6.5.5\build\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Fody.6.5.5\build\Fody.targets'))" />
<Error Condition="!Exists('packages\Costura.Fody.5.7.0\build\Costura.Fody.props')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Costura.Fody.5.7.0\build\Costura.Fody.props'))" />
<Error Condition="!Exists('packages\Costura.Fody.5.7.0\build\Costura.Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Costura.Fody.5.7.0\build\Costura.Fody.targets'))" />
</Target>
<Import Project="packages\Fody.6.5.5\build\Fody.targets" Condition="Exists('packages\Fody.6.5.5\build\Fody.targets')" />
<Import Project="packages\Costura.Fody.5.7.0\build\Costura.Fody.targets" Condition="Exists('packages\Costura.Fody.5.7.0\build\Costura.Fody.targets')" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\Multilingual App Toolkit\Microsoft.Multilingual.ResxResources.targets" Label="MultilingualAppToolkit" Condition="Exists('$(MSBuildExtensionsPath)\Microsoft\Multilingual App Toolkit\v$(MultilingualAppToolkitVersion)\Microsoft.Multilingual.ResxResources.targets')" />
<Target Name="MATPrerequisite" BeforeTargets="PrepareForBuild" Condition="!Exists('$(MSBuildExtensionsPath)\Microsoft\Multilingual App Toolkit\Microsoft.Multilingual.ResxResources.targets')" Label="MultilingualAppToolkit">
<Warning Text="$(MSBuildProjectFile) is Multilingual build enabled, but the Multilingual App Toolkit is unavailable during the build. If building with Visual Studio, please check to ensure that toolkit is properly installed." />
</Target>
</Project>

51
Launcher.sln Normal file
View file

@ -0,0 +1,51 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.3.32901.215
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Launcher", "Launcher.csproj", "{D3AA2F83-0262-4994-928F-497847A6C8EC}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "InjectorLib", "..\InjectorLib\InjectorLib.vcxproj", "{6858E5BA-50F9-489C-98BB-69A785A6FF31}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{D3AA2F83-0262-4994-928F-497847A6C8EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D3AA2F83-0262-4994-928F-497847A6C8EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D3AA2F83-0262-4994-928F-497847A6C8EC}.Debug|x64.ActiveCfg = Debug|x64
{D3AA2F83-0262-4994-928F-497847A6C8EC}.Debug|x64.Build.0 = Debug|x64
{D3AA2F83-0262-4994-928F-497847A6C8EC}.Debug|x86.ActiveCfg = Debug|Any CPU
{D3AA2F83-0262-4994-928F-497847A6C8EC}.Debug|x86.Build.0 = Debug|Any CPU
{D3AA2F83-0262-4994-928F-497847A6C8EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D3AA2F83-0262-4994-928F-497847A6C8EC}.Release|Any CPU.Build.0 = Release|Any CPU
{D3AA2F83-0262-4994-928F-497847A6C8EC}.Release|x64.ActiveCfg = Release|x64
{D3AA2F83-0262-4994-928F-497847A6C8EC}.Release|x64.Build.0 = Release|x64
{D3AA2F83-0262-4994-928F-497847A6C8EC}.Release|x86.ActiveCfg = Release|Any CPU
{D3AA2F83-0262-4994-928F-497847A6C8EC}.Release|x86.Build.0 = Release|Any CPU
{6858E5BA-50F9-489C-98BB-69A785A6FF31}.Debug|Any CPU.ActiveCfg = Debug|x64
{6858E5BA-50F9-489C-98BB-69A785A6FF31}.Debug|Any CPU.Build.0 = Debug|x64
{6858E5BA-50F9-489C-98BB-69A785A6FF31}.Debug|x64.ActiveCfg = Debug|x64
{6858E5BA-50F9-489C-98BB-69A785A6FF31}.Debug|x64.Build.0 = Debug|x64
{6858E5BA-50F9-489C-98BB-69A785A6FF31}.Debug|x86.ActiveCfg = Debug|Win32
{6858E5BA-50F9-489C-98BB-69A785A6FF31}.Debug|x86.Build.0 = Debug|Win32
{6858E5BA-50F9-489C-98BB-69A785A6FF31}.Release|Any CPU.ActiveCfg = Release|x64
{6858E5BA-50F9-489C-98BB-69A785A6FF31}.Release|Any CPU.Build.0 = Release|x64
{6858E5BA-50F9-489C-98BB-69A785A6FF31}.Release|x64.ActiveCfg = Release|x64
{6858E5BA-50F9-489C-98BB-69A785A6FF31}.Release|x64.Build.0 = Release|x64
{6858E5BA-50F9-489C-98BB-69A785A6FF31}.Release|x86.ActiveCfg = Release|Win32
{6858E5BA-50F9-489C-98BB-69A785A6FF31}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {176C524C-E912-426F-A7B3-ADBCAF646C01}
EndGlobalSection
EndGlobal

137
MainWindow.xaml Normal file
View file

@ -0,0 +1,137 @@
<Window
x:Class="Launcher.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:control="clr-namespace:Launcher.Control"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Launcher"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:prop="clr-namespace:Launcher.Properties"
xmlns:pu="clr-namespace:Panuon.WPF.UI;assembly=Panuon.WPF.UI"
Title="MainWindow"
Width="820"
Height="450"
ResizeMode="NoResize"
Topmost="False"
mc:Ignorable="d">
<WindowChrome.WindowChrome>
<WindowChrome GlassFrameThickness="1" NonClientFrameEdges="None" />
</WindowChrome.WindowChrome>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="220" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid Background="#f3f6fc" Effect="{StaticResource defaultShadow}">
<Grid.RowDefinitions>
<RowDefinition Height="60" />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Margin="0,30,0,0">
<TextBlock
HorizontalAlignment="Center"
FontSize="20"
FontWeight="Bold"
Text="Launcher" />
</StackPanel>
<ListBox
x:Name="nav"
Grid.Row="1"
Padding="10"
Background="Transparent"
BorderThickness="0"
ItemContainerStyle="{DynamicResource NavigationItemContainerStyle}"
SelectedIndex="0"
SelectionChanged="ListBox_SelectionChanged">
<ListBoxItem>
<StackPanel Orientation="Horizontal">
<TextBlock
Margin="0,0,8,0"
VerticalAlignment="Center"
FontFamily="{StaticResource remix}"
FontSize="18"
Text="&#xee2b;" />
<TextBlock Text="{x:Static prop:Resources.nav_home}" />
</StackPanel>
</ListBoxItem>
<ListBoxItem>
<StackPanel Orientation="Horizontal">
<TextBlock
Margin="0,0,8,0"
VerticalAlignment="Center"
FontFamily="{StaticResource remix}"
FontSize="18"
Text="&#xf0ee;" />
<TextBlock Text="{x:Static prop:Resources.nav_setting}" />
</StackPanel>
</ListBoxItem>
<ListBoxItem>
<StackPanel Orientation="Horizontal">
<TextBlock
Margin="0,0,8,0"
VerticalAlignment="Center"
FontFamily="{StaticResource remix}"
FontSize="18"
Text="&#xee59;" />
<TextBlock Text="{x:Static prop:Resources.nav_about}" />
</StackPanel>
</ListBoxItem>
</ListBox>
<Button
Grid.Row="1"
Width="50"
Margin="16"
Padding="8"
HorizontalAlignment="Left"
VerticalAlignment="Bottom"
pu:ButtonHelper.ClickBackground="#88FFEBEE"
pu:ButtonHelper.CornerRadius="18"
pu:ButtonHelper.HoverBackground="#ffebee"
Background="Transparent"
BorderThickness="0"
Click="Button_Click"
FontFamily="{StaticResource remix}"
FontSize="14"
Foreground="#C62828">
<!--<StackPanel Orientation="Horizontal">-->
<TextBlock
VerticalAlignment="Center"
FontFamily="{StaticResource remix}"
FontSize="18"
Text="&#xf126;" />
<!--<TextBlock Text="退出" />-->
<!--</StackPanel>-->
</Button>
</Grid>
<Grid
x:Name="dialogHost"
Grid.ColumnSpan="2"
Panel.ZIndex="100">
<control:ServerEditControl />
</Grid>
<StackPanel
xmlns:control="clr-namespace:Launcher.Control"
x:Name="sb_container"
Grid.ColumnSpan="2"
Margin="20"
HorizontalAlignment="Center"
VerticalAlignment="Bottom"
Panel.ZIndex="10">
<control:SnackBar
ActionStr="按钮"
Msg="Message!!"
Visibility="Collapsed" />
</StackPanel>
<Frame
Name="rootFrame"
Grid.Column="1"
NavigationUIVisibility="Hidden"
Source="/View/Home.xaml" />
</Grid>
</Window>

54
MainWindow.xaml.cs Normal file
View file

@ -0,0 +1,54 @@
using Launcher.Model;
using System;
using System.Globalization;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
namespace Launcher
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public static MainWindow Instance { get; private set; }
public MainWindow()
{
InitializeComponent();
Instance = this;
}
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Close();
}
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var lb = sender as ListBox;
if (rootFrame == null)
{
return;
}
switch (lb.SelectedIndex)
{
case 0: rootFrame.Navigate(new Uri("View/Home.xaml", UriKind.Relative)); break;
case 1: rootFrame.Navigate(new Uri("View/Setting.xaml", UriKind.Relative)); break;
case 2: rootFrame.Navigate(new Uri("View/About.xaml", UriKind.Relative)); break;
default:
break;
}
}
}
}

79
Model/GameInfo.cs Normal file
View file

@ -0,0 +1,79 @@
using System.IO;
namespace Launcher.Model
{
//public enum GameVer
//{
// OSRELWin3_2_0,
// CNRELWin3_2_0
//}
public class GameInfo
{
public string GameExeFolder
{
get
{
return Path.GetDirectoryName(GameExePath);
}
}
public string GetGameDataFolder()
{
var dataDirName = string.Empty;
switch (GetGameType())
{
case GameType.CN:
dataDirName = "YuanShen_Data";
break;
case GameType.OS:
dataDirName = "GenshinImpact_Data";
break;
default:
break;
}
return Path.Combine(GameExeFolder, dataDirName);
}
//public GameVer? Version { get; set; }
public GameInfo(string gameExePath)
{
GameExePath = gameExePath;
//Version = null;
//GameExeFolder = Path.GetDirectoryName(gameExePath);
}
public enum GameType
{
CN,
OS,
UnKnown,
}
public GameType GetGameType()
{
GameType gameType = GameType.UnKnown;
if (Directory.Exists(Path.Combine(GameExeFolder, "YuanShen_Data")))
{
gameType = GameType.CN;
}
else if (Directory.Exists(Path.Combine(GameExeFolder, "GenshinImpact_Data")))
{
gameType = GameType.OS;
}
return gameType;
}
public string GameExePath { get; set; }
}
}

92
Model/LauncherConfig.cs Normal file
View file

@ -0,0 +1,92 @@
using CommunityToolkit.Mvvm.ComponentModel;
using Newtonsoft.Json;
using Panuon.WPF;
using System.Collections.ObjectModel;
using System.IO;
using static Org.BouncyCastle.Math.EC.ECCurve;
namespace Launcher.Model
{
public enum ProxyType
{
OFFICIAL,
PRIVATE,
PROXY_ONLY
}
public partial class LauncherConfig : ObservableObject
{
public static LauncherConfig Load(string file)
{
if (File.Exists(file))
{
var content = File.ReadAllText(file);
return JsonConvert.DeserializeObject<LauncherConfig>(content) ?? new LauncherConfig();
}
else
{
return new LauncherConfig();
}
}
public void Save(string file)
{
File.WriteAllText(file, JsonConvert.SerializeObject(this));
}
//public GameInfo GameInfo { get; set; }
//public ProxyType ProxyType { get; set; }
//public ObservableCollection<ServerItem> Servers { get; set; }
public bool DebugMode { get; set; }
public string Language { get; set; }
public string BgUrl { get; set; } = "https://i0.hdslb.com/bfs/new_dyn/be2c9d48dfa1e57161609e693b48982a401742377.png";
private GameInfo gameInfo;
private ProxyType pType;
public ProxyType ProxyType
{
get { return pType; }
set { SetProperty(ref pType, value); }
}
public GameInfo GameInfo
{
get { return gameInfo; }
set { SetProperty(ref gameInfo, value); }
}
private int selectedSrvIndex;
public int SelectedSrvIndex
{
get { return selectedSrvIndex; }
set { SetProperty(ref selectedSrvIndex , value); }
}
private ObservableCollection<ServerItem> servers = new ObservableCollection<ServerItem>();
public ObservableCollection<ServerItem> Servers
{
get { return servers; }
set { SetProperty(ref servers, value); }
}
}
}

22
Model/PkgVersionItem.cs Normal file
View file

@ -0,0 +1,22 @@
using System;
namespace Launcher.Model
{
[Obsolete]
public class PkgVersionItem
{
/// <summary>
///
/// </summary>
public string remoteName { get; set; }
/// <summary>
///
/// </summary>
public string md5 { get; set; }
/// <summary>
///
/// </summary>
public int fileSize { get; set; }
}
}

21
Model/ProxyConfig.cs Normal file
View file

@ -0,0 +1,21 @@
namespace Launcher.Model
{
public class ProxyConfig
{
public ProxyConfig(string proxyServer, bool usehttp = false, string proxyPort = "25565")
{
ProxyServer = proxyServer;
UseHttp = usehttp;
ProxyPort = proxyPort;
}
public string ProxyServer { get; set; }
public string ProxyPort { get; set; }
public bool UseHttp { get; set; }
public bool ProxyEnable { get; internal set; }
}
}

14
Model/ServerItem.cs Normal file
View file

@ -0,0 +1,14 @@
namespace Launcher.Model
{
public class ServerItem
{
public string Name { get; set; }
public string Description { get; set; }
public ProxyConfig proxy { get; set; }
public string RSAPublicKey { get; set; }
public string RSAPrivateKey { get; set; }
}
}

View file

@ -0,0 +1,201 @@
<?xml version="1.0" encoding="utf-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="zh-CN" target-language="en" original="LAUNCHER/PROPERTIES/RESOURCES.RESX" tool-id="MultilingualAppToolkit" product-name="n/a" product-version="n/a" build-num="n/a">
<header>
<tool tool-id="MultilingualAppToolkit" tool-name="Multilingual App Toolkit" tool-version="1.0.0.0" tool-company="Microsoft" />
</header>
<body>
<group id="LAUNCHER/PROPERTIES/RESOURCES.RESX" datatype="resx">
<trans-unit id="nav_about" translate="yes" xml:space="preserve">
<source>关于</source>
<target state="needs-review-translation" state-qualifier="tm-suggestion">About</target>
</trans-unit>
<trans-unit id="nav_home" translate="yes" xml:space="preserve">
<source>主页</source>
<target state="needs-review-translation" state-qualifier="tm-suggestion">Home</target>
</trans-unit>
<trans-unit id="nav_setting" translate="yes" xml:space="preserve">
<source>设置</source>
<target state="needs-review-translation" state-qualifier="tm-suggestion">Settings</target>
</trans-unit>
<trans-unit id="about_desp" translate="yes" xml:space="preserve">
<source>+ 支持的版本:3.1, 3.2, 3.2.50, 3.3, 与 gc-toolkit/RSAPatch 保持同步。</source>
<target state="translated">+ Supported versions: 3.1, 3.2, 3.2.50, 3.3, Synchronized with gc toolkit/RSAPatch.</target>
</trans-unit>
<trans-unit id="btn_searchgame" translate="yes" xml:space="preserve">
<source>自动搜索</source>
<target state="needs-review-translation" state-qualifier="tm-suggestion">Auto Detect</target>
</trans-unit>
<trans-unit id="btn_selectgame" translate="yes" xml:space="preserve">
<source>手动选择</source>
<target state="needs-review-translation" state-qualifier="tm-suggestion">Manual</target>
</trans-unit>
<trans-unit id="cb_enabledebug" translate="yes" xml:space="preserve">
<source>开启调试</source>
<target state="translated">Enable DebugMode</target>
</trans-unit>
<trans-unit id="h_about" translate="yes" xml:space="preserve">
<source>关于</source>
<target state="needs-review-translation" state-qualifier="tm-suggestion">About</target>
</trans-unit>
<trans-unit id="h_develop" translate="yes" xml:space="preserve">
<source>开发</source>
<target state="needs-review-translation" state-qualifier="tm-suggestion">Development</target>
</trans-unit>
<trans-unit id="h_general" translate="yes" xml:space="preserve">
<source>常规</source>
<target state="translated">General</target>
</trans-unit>
<trans-unit id="repo1" translate="yes" xml:space="preserve">
<source>[感谢]:https://github.com/34736384/RSAPatch</source>
<target state="translated">[appreciate]:https://github.com/34736384/RSAPatch</target>
</trans-unit>
<trans-unit id="repoinfo" translate="yes" xml:space="preserve">
<source>[开源地址]:https://github.com/gc-toolkit/Launcher</source>
<target state="translated">[Source Code]:https://github.com/gc-toolkit/Launcher</target>
</trans-unit>
<trans-unit id="tab_official" translate="yes" xml:space="preserve">
<source>官方</source>
<target state="translated">Official Mode</target>
</trans-unit>
<trans-unit id="tab_private" translate="yes" xml:space="preserve">
<source>私有</source>
<target state="translated">Private Mode</target>
</trans-unit>
<trans-unit id="tab_proxyonly" translate="yes" xml:space="preserve">
<source>仅代理</source>
<target state="translated">Proxy Only</target>
</trans-unit>
<trans-unit id="tbtip_bgurl" translate="yes" xml:space="preserve">
<source>背景图片</source>
<target state="translated">Background Image</target>
</trans-unit>
<trans-unit id="tbtip_gamepath" translate="yes" xml:space="preserve">
<source>游戏路径</source>
<target state="translated">GamePath</target>
</trans-unit>
<trans-unit id="tip_selectone" translate="yes" xml:space="preserve">
<source>选择一个服务器</source>
<target state="translated">Select a server</target>
</trans-unit>
<trans-unit id="btn_running" translate="yes" xml:space="preserve">
<source>正在运行</source>
<target state="translated">Running</target>
</trans-unit>
<trans-unit id="btn_startgame" translate="yes" xml:space="preserve">
<source>开始游戏</source>
<target state="needs-review-translation" state-qualifier="tm-suggestion">Play</target>
</trans-unit>
<trans-unit id="btn_startproxy" translate="yes" xml:space="preserve">
<source>开启代理</source>
<target state="translated">StartProxy</target>
</trans-unit>
<trans-unit id="btn_stopproxy" translate="yes" xml:space="preserve">
<source>关闭代理</source>
<target state="translated">StopProxy</target>
</trans-unit>
<trans-unit id="cm_add" translate="yes" xml:space="preserve">
<source>添加</source>
<target state="translated">Add</target>
</trans-unit>
<trans-unit id="cm_del" translate="yes" xml:space="preserve">
<source>删除</source>
<target state="translated">Delete</target>
</trans-unit>
<trans-unit id="cm_edit" translate="yes" xml:space="preserve">
<source>编辑</source>
<target state="translated">Edit</target>
</trans-unit>
<trans-unit id="cm_export" translate="yes" xml:space="preserve">
<source>导出到剪贴板</source>
<target state="translated">Export to Clipboard</target>
</trans-unit>
<trans-unit id="cm_import" translate="yes" xml:space="preserve">
<source>从剪贴板导入</source>
<target state="translated">Import from clipboard</target>
</trans-unit>
<trans-unit id="h_servers" translate="yes" xml:space="preserve">
<source>可用服务器:</source>
<target state="needs-review-translation" state-qualifier="tm-suggestion">Available servers:</target>
</trans-unit>
<trans-unit id="tip_correctgamepath" translate="yes" xml:space="preserve">
<source>请设置正确的游戏路径!</source>
<target state="translated">Please set the correct game path!</target>
</trans-unit>
<trans-unit id="tip_exp_succ" translate="yes" xml:space="preserve">
<source>导出成功!</source>
<target state="translated">Export succeeded!</target>
</trans-unit>
<trans-unit id="tip_imp_err" translate="yes" xml:space="preserve">
<source>导入失败!</source>
<target state="translated">Import failed!</target>
</trans-unit>
<trans-unit id="tip_imp_succ" translate="yes" xml:space="preserve">
<source>导入成功!</source>
<target state="translated">Import succeeded!</target>
</trans-unit>
<trans-unit id="tip_nostart" translate="yes" xml:space="preserve">
<source>现在不能开始游戏!</source>
<target state="translated">Can't start the game now!</target>
</trans-unit>
<trans-unit id="tip_reqaddone" translate="yes" xml:space="preserve">
<source>请至少添加并选择一个服务器!</source>
<target state="translated">Please add and select at least one server!</target>
</trans-unit>
<trans-unit id="tip_reqselectone" translate="yes" xml:space="preserve">
<source>请选择一个服务器!</source>
<target state="translated">Please select a server!</target>
</trans-unit>
<trans-unit id="tip_setcfg" translate="yes" xml:space="preserve">
<source>请先设置 游戏目录 和 游戏版本!</source>
<target state="translated">Please set the game directory and game version first!</target>
</trans-unit>
<trans-unit id="cb_usehttp" translate="yes" xml:space="preserve">
<source>使用http</source>
<target state="translated">Use HTTP</target>
</trans-unit>
<trans-unit id="h_serveredit" translate="yes" xml:space="preserve">
<source>服务器编辑</source>
<target state="translated">Server Profile Edit</target>
</trans-unit>
<trans-unit id="tip_search_err" translate="yes" xml:space="preserve">
<source>搜索失败,注册表中没有相关信息!</source>
<target state="translated">Detect failed, there is no relevant information in the registry!</target>
</trans-unit>
<trans-unit id="tip_serach_succ" translate="yes" xml:space="preserve">
<source>已找到位于{0}的游戏文件!</source>
<target state="needs-review-translation">Found game file at {0}!</target>
<note from="MultilingualUpdate" annotates="source" priority="2">Please verify the translations accuracy as the source string was updated after it was translated.</note>
</trans-unit>
<trans-unit id="tip_srvname" translate="yes" xml:space="preserve">
<source>服务器名称</source>
<target state="translated">Server Name</target>
</trans-unit>
<trans-unit id="t_advanced" translate="yes" xml:space="preserve">
<source>高级</source>
<target state="translated">Advanced</target>
</trans-unit>
<trans-unit id="tb_ok" translate="yes" xml:space="preserve">
<source>确定</source>
<target state="translated">Apply</target>
</trans-unit>
<trans-unit id="tip_privatekey" translate="yes" xml:space="preserve">
<source>PrivateKey,为空则禁用</source>
<target state="translated">PrivateKey: If it is empty, it will be disabled.</target>
</trans-unit>
<trans-unit id="tip_publickey" translate="yes" xml:space="preserve">
<source>PublicKey,为空则选择割草机的key</source>
<target state="translated">PublicKey: If it is empty, it will use grasscutter's ley.</target>
</trans-unit>
<trans-unit id="tip_alreadyrunning" translate="yes" xml:space="preserve">
<source>已经有一个启动器在运行</source>
<target state="new">An instance is already running</target>
</trans-unit>
<trans-unit id="tip_crash_title" translate="yes" xml:space="preserve">
<source>崩溃了</source>
<target state="new">Crashed</target>
</trans-unit>
</group>
</body>
</file>
</xliff>

View file

@ -0,0 +1,53 @@
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("Launcher")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Launcher")]
[assembly: AssemblyCopyright("Copyright © 2022")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
//若要开始生成可本地化的应用程序,请设置
//.csproj 文件中的 <UICulture>CultureYouAreCodingWith</UICulture>
//例如,如果您在源文件中使用的是美国英语,
//使用的是美国英语,请将 <UICulture> 设置为 en-US。 然后取消
//对以下 NeutralResourceLanguage 特性的注释。 更新
//以下行中的“en-US”以匹配项目文件中的 UICulture 设置。
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //主题特定资源词典所处位置
//(未在页面中找到资源时使用,
//或应用程序资源字典中找到时使用)
ResourceDictionaryLocation.SourceAssembly //常规资源词典所处位置
//(未在页面中找到资源时使用,
//、应用程序或任何主题专用资源字典中找到时使用)
)]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

486
Properties/Resources.Designer.cs generated Normal file
View file

@ -0,0 +1,486 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本:4.0.30319.42000
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace Launcher.Properties {
using System;
/// <summary>
/// 一个强类型的资源类,用于查找本地化的字符串等。
/// </summary>
// 此类是由 StronglyTypedResourceBuilder
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
// (以 /str 作为命令选项),或重新生成 VS 项目。
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// 返回此类使用的缓存的 ResourceManager 实例。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
public static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Launcher.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// 重写当前线程的 CurrentUICulture 属性,对
/// 使用此强类型资源类的所有资源查找执行重写。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
public static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// 查找类似 + 支持的版本:3.1, 3.2, 3.2.50, 3.3, 与 gc-toolkit/RSAPatch 保持同步。 的本地化字符串。
/// </summary>
public static string about_desp {
get {
return ResourceManager.GetString("about_desp", resourceCulture);
}
}
/// <summary>
/// 查找类似 正在运行 的本地化字符串。
/// </summary>
public static string btn_running {
get {
return ResourceManager.GetString("btn_running", resourceCulture);
}
}
/// <summary>
/// 查找类似 自动搜索 的本地化字符串。
/// </summary>
public static string btn_searchgame {
get {
return ResourceManager.GetString("btn_searchgame", resourceCulture);
}
}
/// <summary>
/// 查找类似 手动选择 的本地化字符串。
/// </summary>
public static string btn_selectgame {
get {
return ResourceManager.GetString("btn_selectgame", resourceCulture);
}
}
/// <summary>
/// 查找类似 开始游戏 的本地化字符串。
/// </summary>
public static string btn_startgame {
get {
return ResourceManager.GetString("btn_startgame", resourceCulture);
}
}
/// <summary>
/// 查找类似 开启代理 的本地化字符串。
/// </summary>
public static string btn_startproxy {
get {
return ResourceManager.GetString("btn_startproxy", resourceCulture);
}
}
/// <summary>
/// 查找类似 关闭代理 的本地化字符串。
/// </summary>
public static string btn_stopproxy {
get {
return ResourceManager.GetString("btn_stopproxy", resourceCulture);
}
}
/// <summary>
/// 查找类似 开启调试 的本地化字符串。
/// </summary>
public static string cb_enabledebug {
get {
return ResourceManager.GetString("cb_enabledebug", resourceCulture);
}
}
/// <summary>
/// 查找类似 使用http 的本地化字符串。
/// </summary>
public static string cb_usehttp {
get {
return ResourceManager.GetString("cb_usehttp", resourceCulture);
}
}
/// <summary>
/// 查找类似 添加 的本地化字符串。
/// </summary>
public static string cm_add {
get {
return ResourceManager.GetString("cm_add", resourceCulture);
}
}
/// <summary>
/// 查找类似 删除 的本地化字符串。
/// </summary>
public static string cm_del {
get {
return ResourceManager.GetString("cm_del", resourceCulture);
}
}
/// <summary>
/// 查找类似 编辑 的本地化字符串。
/// </summary>
public static string cm_edit {
get {
return ResourceManager.GetString("cm_edit", resourceCulture);
}
}
/// <summary>
/// 查找类似 导出到剪贴板 的本地化字符串。
/// </summary>
public static string cm_export {
get {
return ResourceManager.GetString("cm_export", resourceCulture);
}
}
/// <summary>
/// 查找类似 从剪贴板导入 的本地化字符串。
/// </summary>
public static string cm_import {
get {
return ResourceManager.GetString("cm_import", resourceCulture);
}
}
/// <summary>
/// 查找类似 关于 的本地化字符串。
/// </summary>
public static string h_about {
get {
return ResourceManager.GetString("h_about", resourceCulture);
}
}
/// <summary>
/// 查找类似 开发 的本地化字符串。
/// </summary>
public static string h_develop {
get {
return ResourceManager.GetString("h_develop", resourceCulture);
}
}
/// <summary>
/// 查找类似 常规 的本地化字符串。
/// </summary>
public static string h_general {
get {
return ResourceManager.GetString("h_general", resourceCulture);
}
}
/// <summary>
/// 查找类似 服务器编辑 的本地化字符串。
/// </summary>
public static string h_serveredit {
get {
return ResourceManager.GetString("h_serveredit", resourceCulture);
}
}
/// <summary>
/// 查找类似 可用服务器: 的本地化字符串。
/// </summary>
public static string h_servers {
get {
return ResourceManager.GetString("h_servers", resourceCulture);
}
}
/// <summary>
/// 查找类似 关于 的本地化字符串。
/// </summary>
public static string nav_about {
get {
return ResourceManager.GetString("nav_about", resourceCulture);
}
}
/// <summary>
/// 查找类似 主页 的本地化字符串。
/// </summary>
public static string nav_home {
get {
return ResourceManager.GetString("nav_home", resourceCulture);
}
}
/// <summary>
/// 查找类似 设置 的本地化字符串。
/// </summary>
public static string nav_setting {
get {
return ResourceManager.GetString("nav_setting", resourceCulture);
}
}
/// <summary>
/// 查找类似 [感谢]:https://github.com/34736384/RSAPatch 的本地化字符串。
/// </summary>
public static string repo1 {
get {
return ResourceManager.GetString("repo1", resourceCulture);
}
}
/// <summary>
/// 查找类似 [开源地址]:https://github.com/gc-toolkit/Launcher 的本地化字符串。
/// </summary>
public static string repoinfo {
get {
return ResourceManager.GetString("repoinfo", resourceCulture);
}
}
/// <summary>
/// 查找类似 高级 的本地化字符串。
/// </summary>
public static string t_advanced {
get {
return ResourceManager.GetString("t_advanced", resourceCulture);
}
}
/// <summary>
/// 查找类似 官方 的本地化字符串。
/// </summary>
public static string tab_official {
get {
return ResourceManager.GetString("tab_official", resourceCulture);
}
}
/// <summary>
/// 查找类似 私有 的本地化字符串。
/// </summary>
public static string tab_private {
get {
return ResourceManager.GetString("tab_private", resourceCulture);
}
}
/// <summary>
/// 查找类似 仅代理 的本地化字符串。
/// </summary>
public static string tab_proxyonly {
get {
return ResourceManager.GetString("tab_proxyonly", resourceCulture);
}
}
/// <summary>
/// 查找类似 确定 的本地化字符串。
/// </summary>
public static string tb_ok {
get {
return ResourceManager.GetString("tb_ok", resourceCulture);
}
}
/// <summary>
/// 查找类似 背景图片 的本地化字符串。
/// </summary>
public static string tbtip_bgurl {
get {
return ResourceManager.GetString("tbtip_bgurl", resourceCulture);
}
}
/// <summary>
/// 查找类似 游戏路径 的本地化字符串。
/// </summary>
public static string tbtip_gamepath {
get {
return ResourceManager.GetString("tbtip_gamepath", resourceCulture);
}
}
/// <summary>
/// 查找类似 已经有一个启动器在运行 的本地化字符串。
/// </summary>
public static string tip_alreadyrunning {
get {
return ResourceManager.GetString("tip_alreadyrunning", resourceCulture);
}
}
/// <summary>
/// 查找类似 请设置正确的游戏路径! 的本地化字符串。
/// </summary>
public static string tip_correctgamepath {
get {
return ResourceManager.GetString("tip_correctgamepath", resourceCulture);
}
}
/// <summary>
/// 查找类似 崩溃了 的本地化字符串。
/// </summary>
public static string tip_crash_title {
get {
return ResourceManager.GetString("tip_crash_title", resourceCulture);
}
}
/// <summary>
/// 查找类似 导出成功! 的本地化字符串。
/// </summary>
public static string tip_exp_succ {
get {
return ResourceManager.GetString("tip_exp_succ", resourceCulture);
}
}
/// <summary>
/// 查找类似 导入失败! 的本地化字符串。
/// </summary>
public static string tip_imp_err {
get {
return ResourceManager.GetString("tip_imp_err", resourceCulture);
}
}
/// <summary>
/// 查找类似 导入成功! 的本地化字符串。
/// </summary>
public static string tip_imp_succ {
get {
return ResourceManager.GetString("tip_imp_succ", resourceCulture);
}
}
/// <summary>
/// 查找类似 现在不能开始游戏! 的本地化字符串。
/// </summary>
public static string tip_nostart {
get {
return ResourceManager.GetString("tip_nostart", resourceCulture);
}
}
/// <summary>
/// 查找类似 PrivateKey,为空则禁用 的本地化字符串。
/// </summary>
public static string tip_privatekey {
get {
return ResourceManager.GetString("tip_privatekey", resourceCulture);
}
}
/// <summary>
/// 查找类似 PublicKey,为空则选择割草机的key 的本地化字符串。
/// </summary>
public static string tip_publickey {
get {
return ResourceManager.GetString("tip_publickey", resourceCulture);
}
}
/// <summary>
/// 查找类似 请至少添加并选择一个服务器! 的本地化字符串。
/// </summary>
public static string tip_reqaddone {
get {
return ResourceManager.GetString("tip_reqaddone", resourceCulture);
}
}
/// <summary>
/// 查找类似 请选择一个服务器! 的本地化字符串。
/// </summary>
public static string tip_reqselectone {
get {
return ResourceManager.GetString("tip_reqselectone", resourceCulture);
}
}
/// <summary>
/// 查找类似 搜索失败,注册表中没有相关信息! 的本地化字符串。
/// </summary>
public static string tip_search_err {
get {
return ResourceManager.GetString("tip_search_err", resourceCulture);
}
}
/// <summary>
/// 查找类似 选择一个服务器 的本地化字符串。
/// </summary>
public static string tip_selectone {
get {
return ResourceManager.GetString("tip_selectone", resourceCulture);
}
}
/// <summary>
/// 查找类似 已找到位于{0}的游戏文件! 的本地化字符串。
/// </summary>
public static string tip_serach_succ {
get {
return ResourceManager.GetString("tip_serach_succ", resourceCulture);
}
}
/// <summary>
/// 查找类似 请先设置 游戏目录 和 游戏版本! 的本地化字符串。
/// </summary>
public static string tip_setcfg {
get {
return ResourceManager.GetString("tip_setcfg", resourceCulture);
}
}
/// <summary>
/// 查找类似 服务器名称 的本地化字符串。
/// </summary>
public static string tip_srvname {
get {
return ResourceManager.GetString("tip_srvname", resourceCulture);
}
}
}
}

View file

@ -0,0 +1,150 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="nav_about" xml:space="preserve">
<value>About</value>
</data>
<data name="nav_home" xml:space="preserve">
<value>Home</value>
</data>
<data name="nav_setting" xml:space="preserve">
<value>Settings</value>
</data>
<data name="about_desp" xml:space="preserve">
<value>+ Supported versions: 3.1, 3.2, 3.2.50, 3.3, Synchronized with gc toolkit/RSAPatch.</value>
</data>
<data name="btn_searchgame" xml:space="preserve">
<value>Auto Detect</value>
</data>
<data name="btn_selectgame" xml:space="preserve">
<value>Manual</value>
</data>
<data name="cb_enabledebug" xml:space="preserve">
<value>Enable DebugMode</value>
</data>
<data name="h_about" xml:space="preserve">
<value>About</value>
</data>
<data name="h_develop" xml:space="preserve">
<value>Development</value>
</data>
<data name="h_general" xml:space="preserve">
<value>General</value>
</data>
<data name="repo1" xml:space="preserve">
<value>[appreciate]:https://github.com/34736384/RSAPatch</value>
</data>
<data name="repoinfo" xml:space="preserve">
<value>[Source Code]:https://github.com/gc-toolkit/Launcher</value>
</data>
<data name="tab_official" xml:space="preserve">
<value>Official Mode</value>
</data>
<data name="tab_private" xml:space="preserve">
<value>Private Mode</value>
</data>
<data name="tab_proxyonly" xml:space="preserve">
<value>Proxy Only</value>
</data>
<data name="tbtip_bgurl" xml:space="preserve">
<value>Background Image</value>
</data>
<data name="tbtip_gamepath" xml:space="preserve">
<value>GamePath</value>
</data>
<data name="tip_selectone" xml:space="preserve">
<value>Select a server</value>
</data>
<data name="btn_running" xml:space="preserve">
<value>Running</value>
</data>
<data name="btn_startgame" xml:space="preserve">
<value>Play</value>
</data>
<data name="btn_startproxy" xml:space="preserve">
<value>StartProxy</value>
</data>
<data name="btn_stopproxy" xml:space="preserve">
<value>StopProxy</value>
</data>
<data name="cm_add" xml:space="preserve">
<value>Add</value>
</data>
<data name="cm_del" xml:space="preserve">
<value>Delete</value>
</data>
<data name="cm_edit" xml:space="preserve">
<value>Edit</value>
</data>
<data name="cm_export" xml:space="preserve">
<value>Export to Clipboard</value>
</data>
<data name="cm_import" xml:space="preserve">
<value>Import from clipboard</value>
</data>
<data name="h_servers" xml:space="preserve">
<value>Available servers:</value>
</data>
<data name="tip_correctgamepath" xml:space="preserve">
<value>Please set the correct game path!</value>
</data>
<data name="tip_exp_succ" xml:space="preserve">
<value>Export succeeded!</value>
</data>
<data name="tip_imp_err" xml:space="preserve">
<value>Import failed!</value>
</data>
<data name="tip_imp_succ" xml:space="preserve">
<value>Import succeeded!</value>
</data>
<data name="tip_nostart" xml:space="preserve">
<value>Can't start the game now!</value>
</data>
<data name="tip_reqaddone" xml:space="preserve">
<value>Please add and select at least one server!</value>
</data>
<data name="tip_reqselectone" xml:space="preserve">
<value>Please select a server!</value>
</data>
<data name="tip_setcfg" xml:space="preserve">
<value>Please set the game directory and game version first!</value>
</data>
<data name="cb_usehttp" xml:space="preserve">
<value>Use HTTP</value>
</data>
<data name="h_serveredit" xml:space="preserve">
<value>Server Profile Edit</value>
</data>
<data name="tip_search_err" xml:space="preserve">
<value>Detect failed, there is no relevant information in the registry!</value>
</data>
<data name="tip_serach_succ" xml:space="preserve">
<value>Found game file at {0}!</value>
</data>
<data name="tip_srvname" xml:space="preserve">
<value>Server Name</value>
</data>
<data name="t_advanced" xml:space="preserve">
<value>Advanced</value>
</data>
<data name="tb_ok" xml:space="preserve">
<value>Apply</value>
</data>
<data name="tip_privatekey" xml:space="preserve">
<value>PrivateKey: If it is empty, it will be disabled.</value>
</data>
<data name="tip_publickey" xml:space="preserve">
<value>PublicKey: If it is empty, it will use grasscutter's ley.</value>
</data>
</root>

261
Properties/Resources.resx Normal file
View file

@ -0,0 +1,261 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="about_desp" xml:space="preserve">
<value>+ 支持的版本:3.1, 3.2, 3.2.50, 3.3, 与 gc-toolkit/RSAPatch 保持同步。</value>
</data>
<data name="btn_running" xml:space="preserve">
<value>正在运行</value>
</data>
<data name="btn_searchgame" xml:space="preserve">
<value>自动搜索</value>
</data>
<data name="btn_selectgame" xml:space="preserve">
<value>手动选择</value>
</data>
<data name="btn_startgame" xml:space="preserve">
<value>开始游戏</value>
</data>
<data name="btn_startproxy" xml:space="preserve">
<value>开启代理</value>
</data>
<data name="btn_stopproxy" xml:space="preserve">
<value>关闭代理</value>
</data>
<data name="cb_enabledebug" xml:space="preserve">
<value>开启调试</value>
</data>
<data name="cb_usehttp" xml:space="preserve">
<value>使用http</value>
</data>
<data name="cm_add" xml:space="preserve">
<value>添加</value>
</data>
<data name="cm_del" xml:space="preserve">
<value>删除</value>
</data>
<data name="cm_edit" xml:space="preserve">
<value>编辑</value>
</data>
<data name="cm_export" xml:space="preserve">
<value>导出到剪贴板</value>
</data>
<data name="cm_import" xml:space="preserve">
<value>从剪贴板导入</value>
</data>
<data name="h_about" xml:space="preserve">
<value>关于</value>
</data>
<data name="h_develop" xml:space="preserve">
<value>开发</value>
</data>
<data name="h_general" xml:space="preserve">
<value>常规</value>
</data>
<data name="h_serveredit" xml:space="preserve">
<value>服务器编辑</value>
</data>
<data name="h_servers" xml:space="preserve">
<value>可用服务器:</value>
</data>
<data name="nav_about" xml:space="preserve">
<value>关于</value>
</data>
<data name="nav_home" xml:space="preserve">
<value>主页</value>
</data>
<data name="nav_setting" xml:space="preserve">
<value>设置</value>
</data>
<data name="repo1" xml:space="preserve">
<value>[感谢]:https://github.com/34736384/RSAPatch</value>
</data>
<data name="repoinfo" xml:space="preserve">
<value>[开源地址]:https://github.com/gc-toolkit/Launcher</value>
</data>
<data name="tab_official" xml:space="preserve">
<value>官方</value>
</data>
<data name="tab_private" xml:space="preserve">
<value>私有</value>
</data>
<data name="tab_proxyonly" xml:space="preserve">
<value>仅代理</value>
</data>
<data name="tbtip_bgurl" xml:space="preserve">
<value>背景图片</value>
</data>
<data name="tbtip_gamepath" xml:space="preserve">
<value>游戏路径</value>
</data>
<data name="tb_ok" xml:space="preserve">
<value>确定</value>
</data>
<data name="tip_alreadyrunning" xml:space="preserve">
<value>已经有一个启动器在运行</value>
</data>
<data name="tip_correctgamepath" xml:space="preserve">
<value>请设置正确的游戏路径!</value>
</data>
<data name="tip_crash_title" xml:space="preserve">
<value>崩溃了</value>
</data>
<data name="tip_exp_succ" xml:space="preserve">
<value>导出成功!</value>
</data>
<data name="tip_imp_err" xml:space="preserve">
<value>导入失败!</value>
</data>
<data name="tip_imp_succ" xml:space="preserve">
<value>导入成功!</value>
</data>
<data name="tip_nostart" xml:space="preserve">
<value>现在不能开始游戏!</value>
</data>
<data name="tip_privatekey" xml:space="preserve">
<value>PrivateKey,为空则禁用</value>
</data>
<data name="tip_publickey" xml:space="preserve">
<value>PublicKey,为空则选择割草机的key</value>
</data>
<data name="tip_reqaddone" xml:space="preserve">
<value>请至少添加并选择一个服务器!</value>
</data>
<data name="tip_reqselectone" xml:space="preserve">
<value>请选择一个服务器!</value>
</data>
<data name="tip_search_err" xml:space="preserve">
<value>搜索失败,注册表中没有相关信息!</value>
</data>
<data name="tip_selectone" xml:space="preserve">
<value>选择一个服务器</value>
</data>
<data name="tip_serach_succ" xml:space="preserve">
<value>已找到位于{0}的游戏文件!</value>
</data>
<data name="tip_setcfg" xml:space="preserve">
<value>请先设置 游戏目录 和 游戏版本!</value>
</data>
<data name="tip_srvname" xml:space="preserve">
<value>服务器名称</value>
</data>
<data name="t_advanced" xml:space="preserve">
<value>高级</value>
</data>
</root>

30
Properties/Settings.Designer.cs generated Normal file
View file

@ -0,0 +1,30 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Launcher.Properties
{
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
{
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default
{
get
{
return defaultInstance;
}
}
}
}

View file

@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

32
README.md Normal file
View file

@ -0,0 +1,32 @@
# Launcher
> 新一代的游戏启动器
# ✨ 功能
+ 提供 http / https 代理转向
+ 防止游戏出现4214错误 (多种key切换支持 publickey 和 privatekey)
+ 多服务器支持
+ 不需更改客户端内任何文件
+ 多种启动方式支持 [官方| 割草机| 仅代理]
# 🖼️预览
![image](https://user-images.githubusercontent.com/68674499/206622660-9c1590d3-8adb-4d1f-aed9-17639eca9c67.png)
![image](https://user-images.githubusercontent.com/68674499/206622695-99204b8e-047d-45e3-be9b-d9aed97fd72d.png)
# 🎁使用
1. 前往 [Release](https://github.com/gc-toolkit/Launcher/releases) 下载
2. 放到到任意目录
3. 双击运行
# 🐛常见问题
前往 [Issues](https://github.com/gc-toolkit/Launcher/issues) 具体描述你遇到的问题
# 🙇‍感谢
[https://github.com/34736384/RSAPatch](https://github.com/34736384/RSAPatch)
[akebi](/)

1
RSAPatch/PublicKey.txt Normal file
View file

@ -0,0 +1 @@
<RSAKeyValue><Modulus>xbbx2m1feHyrQ7jP+8mtDF/pyYLrJWKWAdEv3wZrOtjOZzeLGPzsmkcgncgoRhX4dT+1itSMR9j9m0/OwsH2UoF6U32LxCOQWQD1AMgIZjAkJeJvFTrtn8fMQ1701CkbaLTVIjRMlTw8kNXvNA/A9UatoiDmi4TFG6mrxTKZpIcTInvPEpkK2A7Qsp1E4skFK8jmysy7uRhMaYHtPTsBvxP0zn3lhKB3W+HTqpneewXWHjCDfL7Nbby91jbz5EKPZXWLuhXIvR1Cu4tiruorwXJxmXaP1HQZonytECNU/UOzP6GNLdq0eFDE4b04Wjp396551G99YiFP2nqHVJ5OMQ==</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>

BIN
RSAPatch/RSAPatch.dll Normal file

Binary file not shown.

BIN
RSAPatch/rsa.dll.bak Normal file

Binary file not shown.

BIN
Res/remixicon.ttf Normal file

Binary file not shown.

View file

@ -0,0 +1,4 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
</ResourceDictionary>

View file

@ -0,0 +1,87 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="FocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle
Margin="2"
SnapsToDevicePixels="true"
Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"
StrokeDashArray="1 2"
StrokeThickness="1" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<SolidColorBrush x:Key="Item.MouseOver.Background" Color="#e6e9ee" />
<SolidColorBrush x:Key="Item.MouseOver.Border" Color="#a826A0Da" />
<SolidColorBrush x:Key="Item.SelectedActive.Background" Color="#b8dbf1" />
<SolidColorBrush x:Key="Item.SelectedActive.Border" Color="#FF26A0DA" />
<SolidColorBrush x:Key="Item.SelectedInactive.Background" Color="#b8dbf1" />
<SolidColorBrush x:Key="Item.SelectedInactive.Border" Color="#FFDADADA" />
<Style x:Key="NavigationItemContainerStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Padding" Value="20,10" />
<Setter Property="FontSize" Value="14" />
<Setter Property="Margin" Value="10,0" />
<Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
<Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border
x:Name="Bd"
Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="20"
SnapsToDevicePixels="true">
<ContentPresenter
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="Bd" Property="Background" Value="{StaticResource Item.MouseOver.Background}" />
<Setter TargetName="Bd" Property="BorderBrush" Value="{StaticResource Item.MouseOver.Border}" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Selector.IsSelectionActive" Value="False" />
<Condition Property="IsSelected" Value="True" />
</MultiTrigger.Conditions>
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Foreground" Value="#111d35" />
<Setter TargetName="Bd" Property="Background" Value="{StaticResource Item.SelectedInactive.Background}" />
<Setter TargetName="Bd" Property="BorderBrush" Value="{StaticResource Item.SelectedInactive.Border}" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Selector.IsSelectionActive" Value="True" />
<Condition Property="IsSelected" Value="True" />
</MultiTrigger.Conditions>
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Foreground" Value="#111d35" />
<Setter TargetName="Bd" Property="Background" Value="{StaticResource Item.SelectedActive.Background}" />
<Setter TargetName="Bd" Property="BorderBrush" Value="{StaticResource Item.SelectedActive.Border}" />
</MultiTrigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Bd" Property="TextElement.Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

44
View/About.xaml Normal file
View file

@ -0,0 +1,44 @@
<Page
x:Class="Launcher.View.About"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Launcher.View"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:prop="clr-namespace:Launcher.Properties"
Title="About"
d:DesignHeight="450"
d:DesignWidth="800"
FontSize="14"
mc:Ignorable="d">
<StackPanel Margin="20,40,20,20">
<TextBlock
FontSize="20"
FontWeight="Bold"
Text="{x:Static prop:Resources.h_about}" />
<TextBlock Margin="0,10,0,5" Text="Launcher by SwetyCore" />
<TextBlock Margin="0,5" Text="{x:Static prop:Resources.about_desp}" />
<TextBlock
Margin="0,5"
Cursor="Hand"
Foreground="#FF006DFF"
MouseLeftButtonDown="TextBlock_MouseLeftButtonDown"
Tag="https://github.com/gc-toolkit/Launcher"
Text="{x:Static prop:Resources.repoinfo}" />
<TextBlock
Margin="0,5"
Cursor="Hand"
Foreground="#FF006DFF"
MouseLeftButtonDown="TextBlock_MouseLeftButtonDown"
Tag="https://github.com/34736384/RSAPatch"
Text="{x:Static prop:Resources.repo1}" />
</StackPanel>
</Page>

35
View/About.xaml.cs Normal file
View file

@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Launcher.View
{
/// <summary>
/// About.xaml 的交互逻辑
/// </summary>
public partial class About : Page
{
public About()
{
InitializeComponent();
}
private void TextBlock_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var tb = sender as TextBlock;
Process.Start("explorer.exe", tb.Tag.ToString());
}
}
}

300
View/Home.xaml Normal file
View file

@ -0,0 +1,300 @@
<Page
x:Class="Launcher.View.Home"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Launcher.View"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:prop="clr-namespace:Launcher.Properties"
xmlns:pu="clr-namespace:Panuon.WPF.UI;assembly=Panuon.WPF.UI"
xmlns:viewmodel="clr-namespace:Launcher.ViewModel"
Title="Home"
d:DataContext="{d:DesignInstance Type=viewmodel:HomeVM}"
d:DesignHeight="500"
d:DesignWidth="600"
mc:Ignorable="d">
<Grid Margin="20">
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<ListBox
x:Name="pt"
pu:ListBoxHelper.CornerRadius="20"
pu:ListBoxHelper.ItemsCornerRadius="20"
pu:ListBoxHelper.ItemsHeight="40"
pu:ListBoxHelper.ItemsHoverBackground="#a0b8dbf1"
pu:ListBoxHelper.ItemsPadding="20 0"
pu:ListBoxHelper.ItemsSelectedBackground="#b8dbf1"
pu:ListBoxHelper.ShadowColor="Gray"
pu:ShadowHelper.Opacity="0.2"
Background="#f3f6fc"
BorderThickness="0"
FontSize="14"
FontWeight="Bold"
IsEnabled="{Binding CanChangeProxyType}"
SelectionChanged="ListBox_SelectionChanged">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="3" IsItemsHost="True" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBoxItem>
<TextBlock HorizontalAlignment="Center" Text="{x:Static prop:Resources.tab_official}" />
</ListBoxItem>
<ListBoxItem>
<TextBlock Text="{x:Static prop:Resources.tab_private}" />
</ListBoxItem>
<ListBoxItem>
<TextBlock Text="{x:Static prop:Resources.tab_proxyonly}" />
</ListBoxItem>
</ListBox>
<Grid Grid.Row="1" Margin="0,10,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="180" />
</Grid.ColumnDefinitions>
<Grid Margin="0,0,10,0" Panel.ZIndex="2">
<Border CornerRadius="20" />
<Border
Margin="0,10,20,0"
Padding="4"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Background="#66E3F2FD"
CornerRadius="4">
<TextBlock FontSize="14" ToolTip="Fake">
<Run Text="Online:" />
<Run Text="30" />
<Run Text="/" />
<Run Text="120" />
</TextBlock>
</Border>
<StackPanel
Name="srv_list"
Margin="20"
VerticalAlignment="Bottom">
<Border
Height="160"
Background="#aaE3F2FD"
CornerRadius="15 15 15 15">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition />
</Grid.RowDefinitions>
<ToggleButton
Margin="10,10,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Background="Transparent"
BorderThickness="0"
Content="{x:Static prop:Resources.h_servers}"
FontSize="16"
FontWeight="Bold" />
<ListBox
Grid.Row="2"
Padding="4"
pu:ListBoxHelper.ItemsCornerRadius="16"
pu:ListBoxHelper.ItemsHoverBackground="#88b8dbf1"
pu:ListBoxHelper.ItemsPadding="8"
pu:ListBoxHelper.ItemsSelectedBackground="#b8dbf1"
pu:ScrollBarHelper.HoverThumbBackground="#b8dbf1"
pu:ScrollBarHelper.ThumbBackground="#aab8dbf1"
pu:ScrollBarHelper.ThumbBorderThickness="2 0 0 4"
pu:ScrollBarHelper.ThumbCornerRadius="4"
Background="Transparent"
BorderThickness="0"
FontSize="14"
ItemsSource="{Binding LauncherConfig.Servers}"
SelectedIndex="{Binding LauncherConfig.SelectedSrvIndex}"
SelectedValue="{Binding SelectedSrv}">
<pu:ListBoxHelper.EmptyContent>
<Grid>
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="16"
Text="空" />
</Grid>
</pu:ListBoxHelper.EmptyContent>
<ListBox.ContextMenu>
<ContextMenu
MinWidth="240"
Padding="0"
pu:ContextMenuHelper.CornerRadius="20"
pu:ContextMenuHelper.ItemsHeight="36"
pu:ContextMenuHelper.ItemsHoverBackground="#b8dbf1"
pu:ContextMenuHelper.ShadowColor="Gray"
pu:ShadowHelper.Opacity="0.2"
Background="#f3f6fc"
BorderThickness="0"
FontSize="14">
<MenuItem Command="{Binding EditCommand}" Header="{x:Static prop:Resources.cm_edit}" />
<MenuItem Command="{Binding AddCommand}" Header="{x:Static prop:Resources.cm_add}" />
<MenuItem Command="{Binding DeleteCommand}" Header="{x:Static prop:Resources.cm_del}" />
<MenuItem Command="{Binding ExportCommand}" Header="{x:Static prop:Resources.cm_export}" />
<MenuItem Command="{Binding ImportCommand}" Header="{x:Static prop:Resources.cm_import}" />
</ContextMenu>
</ListBox.ContextMenu>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition />
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<TextBlock
Margin="4,0,4,0"
VerticalAlignment="Center"
FontSize="16">
<Run FontFamily="{StaticResource remix}" Text="&#xf0e0;" />
</TextBlock>
<TextBlock Grid.Column="1">
<Run Text="{Binding Name}" />
</TextBlock>
<StackPanel Grid.Column="2" Orientation="Horizontal">
<!--<Button
HorizontalAlignment="Right"
pu:ButtonHelper.ClickBackground="#30EF5350"
pu:ButtonHelper.CornerRadius="4"
Background="Transparent"
FontFamily="{StaticResource remix}"
FontSize="18">
&#xec2a;
</Button>-->
</StackPanel>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Border>
</StackPanel>
</Grid>
<Border
Grid.ColumnSpan="2"
CornerRadius="20"
Effect="{StaticResource defaultShadow}"
RenderOptions.BitmapScalingMode="HighQuality">
<Border.Background>
<ImageBrush ImageSource="{Binding LauncherConfig.BgUrl}" Stretch="UniformToFill" />
</Border.Background>
<Border
Margin="350,0,0,0"
Padding="20"
Background="#88E3F2FD"
CornerRadius="0 20 20 0">
<Grid>
<TextBlock TextWrapping="Wrap">
<Run
FontSize="30"
FontWeight="Bold"
Text="{Binding SelectedSrv.Name, FallbackValue={x:Static prop:Resources.tip_selectone}}" />
<LineBreak />
<Run>
Styles are the visual aspects of a UI that give it a distinct look and feel.
</Run>
</TextBlock>
<UniformGrid VerticalAlignment="Bottom" Columns="2">
<StackPanel>
<Button
Width="50"
Height="30"
Margin="4"
pu:ButtonHelper.CornerRadius="15"
Background="#C2E7FF"
Cursor="Hand">
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontFamily="{StaticResource remix}"
FontSize="20"
Text="&#xedca;" />
</Button>
<TextBlock HorizontalAlignment="Center" Text="Github" />
</StackPanel>
<StackPanel>
<Button
Width="50"
Height="30"
Margin="4"
pu:ButtonHelper.CornerRadius="15"
Background="#C2E7FF"
Cursor="Hand">
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontFamily="{StaticResource remix}"
FontSize="20"
Text="&#xec37;" />
</Button>
<TextBlock HorizontalAlignment="Center" Text="Discord" />
</StackPanel>
</UniformGrid>
</Grid>
</Border>
</Border>
</Grid>
<Grid Grid.Row="2" Margin="0,10,0,0">
<Button
Width="140"
Height="50"
HorizontalAlignment="Right"
pu:ButtonHelper.CornerRadius="25"
pu:ButtonHelper.HoverBackground="#ee2a73c5"
pu:ButtonHelper.HoverShadowColor="#b8dbf1"
pu:ButtonHelper.ShadowColor="Gray"
pu:ShadowHelper.Opacity="0.4"
Background="#1867c0"
Command="{Binding StartGameCommand}"
Cursor="Hand"
FontSize="18"
FontWeight="Bold"
Foreground="White">
<StackPanel Orientation="Horizontal">
<TextBlock
Margin="0,0,8,0"
VerticalAlignment="Center"
FontFamily="{StaticResource remix}"
FontSize="20"
Text="&#xf00a;" />
<TextBlock Text="{Binding StartBtn_txt, FallbackValue={x:Static prop:Resources.btn_startgame}}" />
</StackPanel>
</Button>
</Grid>
</Grid>
</Page>

43
View/Home.xaml.cs Normal file
View file

@ -0,0 +1,43 @@
using System.Windows.Controls;
namespace Launcher.View
{
/// <summary>
/// Home.xaml 的交互逻辑
/// </summary>
public partial class Home : Page
{
public Home()
{
InitializeComponent();
DataContext = ViewModel.HomeVM.Instacne;
pt.SelectedIndex = (int)ViewModel.HomeVM.Instacne.LauncherConfig.ProxyType;
}
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var list = (ListBox)sender;
ViewModel.HomeVM.Instacne.LauncherConfig.ProxyType = (Model.ProxyType)list.SelectedIndex;
switch (ViewModel.HomeVM.Instacne.LauncherConfig.ProxyType)
{
case Model.ProxyType.OFFICIAL:
ViewModel.HomeVM.Instacne.StartBtn_txt = Properties.Resources.btn_startgame;
break;
case Model.ProxyType.PRIVATE:
ViewModel.HomeVM.Instacne.StartBtn_txt = Properties.Resources.btn_startgame;
break;
case Model.ProxyType.PROXY_ONLY:
ViewModel.HomeVM.Instacne.StartBtn_txt = Properties.Resources.btn_startproxy;
break;
default:
break;
}
}
}
}

136
View/Setting.xaml Normal file
View file

@ -0,0 +1,136 @@
<Page
x:Class="Launcher.View.Setting"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Launcher.View"
xmlns:m="clr-namespace:Launcher.Model"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:prop="clr-namespace:Launcher.Properties"
xmlns:pu="clr-namespace:Panuon.WPF.UI;assembly=Panuon.WPF.UI"
xmlns:viewmodel="clr-namespace:Launcher.ViewModel"
Title="Setting"
d:DataContext="{d:DesignInstance Type=viewmodel:SettingVM}"
d:DesignHeight="500"
d:DesignWidth="600"
mc:Ignorable="d">
<Grid Margin="20,40,20,20">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<ItemsControl Background="Transparent" BorderThickness="0">
<TextBlock
Margin="0,0,0,5"
FontSize="20"
FontWeight="Bold"
Foreground="#111d35"
Text="{x:Static prop:Resources.h_general}" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition />
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<TextBlock
Margin="0,0,10,0"
VerticalAlignment="Center"
FontSize="14"
Text="{x:Static prop:Resources.tbtip_gamepath}" />
<TextBox
xmlns:Model="clr-namespace:Launcher.Model"
Grid.Column="1"
MinWidth="100"
Margin="0,5,5,5"
Padding="8"
pu:TextBoxHelper.CornerRadius="4"
pu:TextBoxHelper.FocusedBorderBrush="#2a73c5"
pu:TextBoxHelper.Watermark="游戏路径"
Background="Transparent"
BorderThickness="1"
FontSize="14"
Text="{Binding LauncherConfig.GameInfo.GameExePath}" />
<StackPanel Grid.Column="2" Orientation="Horizontal">
<Button
Margin="5"
Padding="8,0"
pu:ButtonHelper.CornerRadius="6"
Background="#2a73c5"
Command="{Binding SearchGameFileCommand}"
Content="{x:Static prop:Resources.btn_searchgame}"
Foreground="White" />
<Button
Margin="5"
Padding="8,0"
pu:ButtonHelper.CornerRadius="6"
pu:ButtonHelper.HoverBackground="#302a73c5"
Background="Transparent"
BorderBrush="#2a73c5"
BorderThickness="1"
Command="{Binding SetGameExePathCommand}"
Content="{x:Static prop:Resources.btn_selectgame}"
Foreground="#2a73c5" />
</StackPanel>
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition />
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<TextBlock
Margin="0,0,10,0"
VerticalAlignment="Center"
FontSize="14"
Text="{x:Static prop:Resources.tbtip_bgurl}" />
<TextBox
xmlns:Model="clr-namespace:Launcher.Model"
Grid.Column="1"
MinWidth="100"
Margin="0,5,5,5"
Padding="8"
pu:TextBoxHelper.CornerRadius="4"
pu:TextBoxHelper.FocusedBorderBrush="#2a73c5"
pu:TextBoxHelper.Watermark="游戏路径"
Background="Transparent"
BorderThickness="1"
FontSize="14"
Text="{Binding LauncherConfig.BgUrl}" />
</Grid>
<TextBlock
Margin="0,0,0,5"
FontSize="20"
FontWeight="Bold"
Foreground="#111d35"
Text="{x:Static prop:Resources.h_develop}" />
<Grid>
<CheckBox
VerticalContentAlignment="Center"
pu:CheckBoxHelper.BoxHeight="20"
pu:CheckBoxHelper.BoxWidth="20"
pu:CheckBoxHelper.CheckedGlyphBrush="#558fd1"
pu:CheckBoxHelper.CornerRadius="4"
pu:CheckBoxHelper.GlyphThickness="3"
pu:CheckBoxHelper.HoverBorderBrush="#558fd1"
BorderThickness="1"
Content="{x:Static prop:Resources.cb_enabledebug}"
Cursor="Hand"
FontSize="16"
IsChecked="{Binding LauncherConfig.DebugMode}" />
</Grid>
</ItemsControl>
</Grid>
</Page>

21
View/Setting.xaml.cs Normal file
View file

@ -0,0 +1,21 @@
using System.Windows.Controls;
namespace Launcher.View
{
/// <summary>
/// Setting.xaml 的交互逻辑
/// </summary>
public partial class Setting : Page
{
public Setting()
{
InitializeComponent();
DataContext = ViewModel.SettingVM.Instacne;
//Visibility = Visibility.Hidden;
}
}
}

347
ViewModel/HomeVM.cs Normal file
View file

@ -0,0 +1,347 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Launcher.Model;
using System.Diagnostics;
using System;
using System.IO;
using System.Windows;
using Launcher.Common;
using static Launcher.Common.ProxyHelper;
using System.Net.Http.Headers;
using Launcher.Control;
using System.Windows.Input;
using System.Linq;
using static System.Net.Mime.MediaTypeNames;
using Newtonsoft.Json;
using System.Text;
namespace Launcher.ViewModel
{
internal class HomeVM : ObservableObject
{
public static HomeVM Instacne = new HomeVM();
public LauncherConfig LauncherConfig
{
get { return App.launcherConfig; }
set { SetProperty(ref App.launcherConfig, value); }
}
public HomeVM()
{
if (LauncherConfig == null)
{
LauncherConfig = new LauncherConfig();
LauncherConfig.Servers.Add(new ServerItem()
{
Name = "TestServer",
Description = "Styles are the visual aspects of a UI that give it a distinct look and feel.",
proxy = new ProxyConfig("127.0.0.1", true, "25566")
});
}
}
public RelayCommand StartGameCommand => new RelayCommand(StartGame);
public ProxyController proxyController;
private string startBtn_txt = Properties.Resources.btn_startgame;
public string StartBtn_txt
{
get { return startBtn_txt; }
set { SetProperty(ref startBtn_txt, value); }
}
bool CanStart = true;
private bool canChangeProxyType = true;
public bool CanChangeProxyType
{
get { return canChangeProxyType; }
set { SetProperty(ref canChangeProxyType,value); }
}
#region
private void StartGame()
{
if (!CanStart)
{
SnackBar.Show(Properties.Resources.tip_nostart,null);
return;
}
if (LauncherConfig.GameInfo==null||
LauncherConfig.GameInfo.GameExePath == null )
//LauncherConfig.GameInfo.Version == null
{
SnackBar.Show(Properties.Resources.tip_setcfg,new RelayCommand(() =>
{
//MainWindow.Instance.rootFrame.Navigate(new Uri("/View/Setting.xaml", UriKind.Relative));
MainWindow.Instance.nav.SelectedIndex = 1;
}));
return;
}
var fp = LauncherConfig.GameInfo.GameExePath;
try
{
fp = Path.GetFullPath(fp);
}
catch (Exception ex)
{
SnackBar.Show(ex.Message, new RelayCommand(() =>
{
MainWindow.Instance.nav.SelectedIndex = 1;
}));
return;
}
var fd = LauncherConfig.GameInfo.GameExeFolder;
if (!File.Exists(fp)&&LauncherConfig.ProxyType!=ProxyType.PROXY_ONLY)
{
SnackBar.Show(Properties.Resources.tip_correctgamepath, new RelayCommand(() =>
{
//MainWindow.Instance.rootFrame.Navigate(new Uri("/View/Setting.xaml", UriKind.Relative));
MainWindow.Instance.nav.SelectedIndex = 1;
}));
return;
}
switch (LauncherConfig.ProxyType)
{
case ProxyType.OFFICIAL:
ProcessStartInfo startInfo = new ProcessStartInfo()
{
CreateNoWindow = true,
FileName = fp,
UseShellExecute = true,
};
try
{
Process.Start(startInfo);
StartBtn_txt = Properties.Resources.btn_running;
CanStart = false;
CanChangeProxyType = false;
new ProcessWatcher(new EventHandler(pro_Exited)).Watch();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
break;
case ProxyType.PRIVATE:
{
if (LauncherConfig.Servers.Count==0)
{
SnackBar.Show(Properties.Resources.tip_reqaddone, null);
return;
}
if (SelectedSrv==null)
{
SnackBar.Show(Properties.Resources.tip_reqselectone, null);
return;
}
var SelectedProxy_C = SelectedSrv.proxy;
proxyController = new ProxyController(SelectedProxy_C.ProxyPort, SelectedProxy_C.ProxyServer,SelectedProxy_C.UseHttp);
proxyController.Start();
var dll = RSAPatchHelper.WriteMhypbaseAllTo(SelectedSrv); ;
if (dll != null)
{
GameHelper.StartGame(fp, dll);
}
CanChangeProxyType = false;
CanStart = false;
StartBtn_txt = Properties.Resources.btn_running;
new ProcessWatcher(new EventHandler(pro_Exited)).Watch();
break;
}
case ProxyType.PROXY_ONLY:
{
if (LauncherConfig.Servers.Count == 0||SelectedSrv==null)
{
SnackBar.Show(Properties.Resources.tip_reqaddone, null);
return;
}
var SelectedProxy_C = SelectedSrv.proxy;
if (proxyController!=null&&proxyController._IsRun)
{
CanChangeProxyType = true;
proxyController.Stop();
StartBtn_txt = Properties.Resources.btn_startproxy;
}
else
{
CanChangeProxyType = false;
proxyController = new ProxyController(SelectedProxy_C.ProxyPort, SelectedProxy_C.ProxyServer, SelectedProxy_C.UseHttp);
proxyController.Start();
StartBtn_txt = Properties.Resources.btn_stopproxy;
}
}
break;
default:
break;
}
}
private void pro_Exited(object sender, EventArgs e)
{
//MessageBox.Show("游戏退出!");
CanStart = true;
switch (LauncherConfig.ProxyType)
{
case ProxyType.OFFICIAL:
StartBtn_txt = Properties.Resources.btn_startgame;
CanChangeProxyType = true;
break;
case ProxyType.PRIVATE:
StartBtn_txt = Properties.Resources.btn_startgame;
proxyController.Stop();
CanChangeProxyType = true;
//var inif = System.IO.Path.Combine(LauncherConfig.GameInfo.GameExeFolder, "mhypbase.ini");
//if (File.Exists(inif))
//{
// File.Delete(inif);
//}
break;
case ProxyType.PROXY_ONLY:
default:
break;
}
}
#endregion
public ICommand AddCommand => new RelayCommand(Add);
public ICommand DeleteCommand => new RelayCommand(Delete);
public ICommand EditCommand => new RelayCommand(Edit);
public ICommand ImportCommand => new RelayCommand(Import);
public ICommand ExportCommand => new RelayCommand(Export);
private void Export()
{
if (SelectedSrv!=null)
{
byte[] bytes = Encoding.Default.GetBytes(JsonConvert.SerializeObject(SelectedSrv));
string str = Convert.ToBase64String(bytes);
Clipboard.SetDataObject(str, true);
SnackBar.Show(Properties.Resources.tip_exp_succ, null);
}
}
private void Import()
{
try
{
IDataObject data = Clipboard.GetDataObject();
string srv = (string)data.GetData(typeof(string));
byte[] outputb = Convert.FromBase64String(srv);
string orgStr = Encoding.Default.GetString(outputb);
LauncherConfig.Servers.Add(JsonConvert.DeserializeObject<ServerItem>(orgStr));
SnackBar.Show(Properties.Resources.tip_imp_succ, null);
}
catch (Exception ex)
{
SnackBar.Show(Properties.Resources.tip_imp_err, null);
}
}
private ServerItem selectedSrv;
public ServerItem SelectedSrv
{
get { return selectedSrv; }
set { SetProperty(ref selectedSrv , value); }
}
private void Add()
{
var item = new ServerItem()
{
proxy = new ProxyConfig("127.0.0.1")
};
ServerEditControl.instance.ServerItem = item;
ServerEditControl.Show();
LauncherConfig.Servers.Add(item);
}
private void Delete()
{
if (SelectedSrv==null)
{
return;
}
LauncherConfig.Servers.Remove(SelectedSrv);
if (LauncherConfig.SelectedSrvIndex>0)
{
LauncherConfig.SelectedSrvIndex -= 1;
}
}
private void Edit()
{
if (SelectedSrv == null)
{
return;
}
ServerEditControl.instance.ServerItem = SelectedSrv;
ServerEditControl.Show();
}
}
}

67
ViewModel/SettingVM.cs Normal file
View file

@ -0,0 +1,67 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Launcher.Common;
using Launcher.Model;
using Microsoft.Win32;
using System.IO;
using System.Windows;
using System.Windows.Input;
namespace Launcher.ViewModel
{
internal class SettingVM : ObservableObject
{
public static SettingVM Instacne = new SettingVM();
public SettingVM()
{
if (LauncherConfig == null)
{
LauncherConfig = new LauncherConfig();
}
}
public LauncherConfig LauncherConfig
{
get { return App.launcherConfig; }
set { SetProperty(ref App.launcherConfig, value); }
}
public ICommand SearchGameFileCommand => new RelayCommand(SearchGameFile);
public ICommand SetGameExePathCommand => new RelayCommand(SetGameExePath);
public void SearchGameFile()
{
LauncherConfig.GameInfo = new GameInfo(GameHelper.GameRegReader.GetGameExePath());
if (File.Exists(LauncherConfig.GameInfo.GameExePath))
{
MessageBox.Show(string.Format(Properties.Resources.tip_serach_succ,LauncherConfig.GameInfo.GameExeFolder));
}
else
{
MessageBox.Show(Properties.Resources.tip_search_err);
}
}
private void SetGameExePath()
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "原神游戏程序YuanShen.exe)|YuanShen.exe|原神游戏程序(GenshinImpact.exe)|GenshinImpact.exe";
openFileDialog.Multiselect = false;
if (openFileDialog.ShowDialog() == true)
{
LauncherConfig.GameInfo = new GameInfo(openFileDialog.FileName);
}
}
}
}

81
app.manifest Normal file
View file

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<!-- UAC 清单选项
如果想要更改 Windows 用户帐户控制级别,请使用
以下节点之一替换 requestedExecutionLevel 节点。
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
指定 requestedExecutionLevel 元素将禁用文件和注册表虚拟化。
如果你的应用程序需要此虚拟化来实现向后兼容性,则移除此
元素。
-->
<!--<requestedExecutionLevel level="asInvoker" uiAccess="false" />-->
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- 设计此应用程序与其一起工作且已针对此应用程序进行测试的
Windows 版本的列表。取消评论适当的元素,
Windows 将自动选择最兼容的环境。 -->
<!-- Windows Vista -->
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->
<!-- Windows 7 -->
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />-->
<!-- Windows 8 -->
<!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />-->
<!-- Windows 8.1 -->
<!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />-->
<!-- Windows 10 -->
<!--<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />-->
</application>
</compatibility>
<!-- 指示该应用程序可感知 DPI 且 Windows 在 DPI 较高时将不会对其进行
自动缩放。Windows Presentation Foundation (WPF)应用程序自动感知 DPI无需
选择加入。选择加入此设置的 Windows 窗体应用程序(面向 .NET Framework 4.6)还应
在其 app.config 中将 "EnableWindowsFormsHighDpiAutoResizing" 设置设置为 "true"。
将应用程序设为感知长路径。请参阅 https://docs.microsoft.com/windows/win32/fileio/maximum-file-path-limitation -->
<!--
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
</windowsSettings>
</application>
-->
<!-- 启用 Windows 公共控件和对话框的主题(Windows XP 和更高版本) -->
<!--
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
-->
</assembly>

BIN
favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

1
key/GC-Dispatch.txt Normal file
View file

@ -0,0 +1 @@
<RSAKeyValue><Modulus>xbbx2m1feHyrQ7jP+8mtDF/pyYLrJWKWAdEv3wZrOtjOZzeLGPzsmkcgncgoRhX4dT+1itSMR9j9m0/OwsH2UoF6U32LxCOQWQD1AMgIZjAkJeJvFTrtn8fMQ1701CkbaLTVIjRMlTw8kNXvNA/A9UatoiDmi4TFG6mrxTKZpIcTInvPEpkK2A7Qsp1E4skFK8jmysy7uRhMaYHtPTsBvxP0zn3lhKB3W+HTqpneewXWHjCDfL7Nbby91jbz5EKPZXWLuhXIvR1Cu4tiruorwXJxmXaP1HQZonytECNU/UOzP6GNLdq0eFDE4b04Wjp396551G99YiFP2nqHVJ5OMQ==</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>

68
packages.config Normal file
View file

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="BrotliSharpLib" version="0.3.3" targetFramework="net472" />
<package id="CommunityToolkit.Mvvm" version="8.0.0" targetFramework="net472" />
<package id="Costura.Fody" version="5.7.0" targetFramework="net472" developmentDependency="true" />
<package id="Fody" version="6.5.5" targetFramework="net472" developmentDependency="true" />
<package id="Microsoft.Bcl.AsyncInterfaces" version="6.0.0" targetFramework="net472" />
<package id="Microsoft.NETCore.Platforms" version="1.1.0" targetFramework="net472" />
<package id="Microsoft.Win32.Primitives" version="4.3.0" targetFramework="net472" />
<package id="Microsoft.Win32.Registry" version="5.0.0" targetFramework="net472" />
<package id="NETStandard.Library" version="1.6.1" targetFramework="net472" />
<package id="Newtonsoft.Json" version="13.0.1" targetFramework="net472" />
<package id="Panuon.WPF" version="1.0.1" targetFramework="net472" />
<package id="Panuon.WPF.UI" version="1.1.6.5" targetFramework="net472" />
<package id="Portable.BouncyCastle" version="1.8.8" targetFramework="net472" />
<package id="System.AppContext" version="4.3.0" targetFramework="net472" />
<package id="System.Buffers" version="4.5.1" targetFramework="net472" />
<package id="System.Collections" version="4.3.0" targetFramework="net472" />
<package id="System.Collections.Concurrent" version="4.3.0" targetFramework="net472" />
<package id="System.ComponentModel.Annotations" version="5.0.0" targetFramework="net472" />
<package id="System.Console" version="4.3.0" targetFramework="net472" />
<package id="System.Diagnostics.Debug" version="4.3.0" targetFramework="net472" />
<package id="System.Diagnostics.DiagnosticSource" version="4.3.0" targetFramework="net472" />
<package id="System.Diagnostics.Tools" version="4.3.0" targetFramework="net472" />
<package id="System.Diagnostics.Tracing" version="4.3.0" targetFramework="net472" />
<package id="System.Globalization" version="4.3.0" targetFramework="net472" />
<package id="System.Globalization.Calendars" version="4.3.0" targetFramework="net472" />
<package id="System.IO" version="4.3.0" targetFramework="net472" />
<package id="System.IO.Compression" version="4.3.0" targetFramework="net472" />
<package id="System.IO.Compression.ZipFile" version="4.3.0" targetFramework="net472" />
<package id="System.IO.FileSystem" version="4.3.0" targetFramework="net472" />
<package id="System.IO.FileSystem.Primitives" version="4.3.0" targetFramework="net472" />
<package id="System.Linq" version="4.3.0" targetFramework="net472" />
<package id="System.Linq.Expressions" version="4.3.0" targetFramework="net472" />
<package id="System.Memory" version="4.5.5" targetFramework="net472" />
<package id="System.Net.Http" version="4.3.0" targetFramework="net472" />
<package id="System.Net.Primitives" version="4.3.0" targetFramework="net472" />
<package id="System.Net.Sockets" version="4.3.0" targetFramework="net472" />
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net472" />
<package id="System.ObjectModel" version="4.3.0" targetFramework="net472" />
<package id="System.Reflection" version="4.3.0" targetFramework="net472" />
<package id="System.Reflection.Extensions" version="4.3.0" targetFramework="net472" />
<package id="System.Reflection.Primitives" version="4.3.0" targetFramework="net472" />
<package id="System.Resources.ResourceManager" version="4.3.0" targetFramework="net472" />
<package id="System.Runtime" version="4.3.0" targetFramework="net472" />
<package id="System.Runtime.CompilerServices.Unsafe" version="6.0.0" targetFramework="net472" />
<package id="System.Runtime.Extensions" version="4.3.0" targetFramework="net472" />
<package id="System.Runtime.Handles" version="4.3.0" targetFramework="net472" />
<package id="System.Runtime.InteropServices" version="4.3.0" targetFramework="net472" />
<package id="System.Runtime.InteropServices.RuntimeInformation" version="4.3.0" targetFramework="net472" />
<package id="System.Runtime.Numerics" version="4.3.0" targetFramework="net472" />
<package id="System.Security.AccessControl" version="5.0.0" targetFramework="net472" />
<package id="System.Security.Cryptography.Algorithms" version="4.3.0" targetFramework="net472" />
<package id="System.Security.Cryptography.Encoding" version="4.3.0" targetFramework="net472" />
<package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="net472" />
<package id="System.Security.Cryptography.X509Certificates" version="4.3.0" targetFramework="net472" />
<package id="System.Security.Principal.Windows" version="5.0.0" targetFramework="net472" />
<package id="System.Text.Encoding" version="4.3.0" targetFramework="net472" />
<package id="System.Text.Encoding.Extensions" version="4.3.0" targetFramework="net472" />
<package id="System.Text.RegularExpressions" version="4.3.0" targetFramework="net472" />
<package id="System.Threading" version="4.3.0" targetFramework="net472" />
<package id="System.Threading.Tasks" version="4.3.0" targetFramework="net472" />
<package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net472" />
<package id="System.Threading.Timer" version="4.3.0" targetFramework="net472" />
<package id="System.Xml.ReaderWriter" version="4.3.0" targetFramework="net472" />
<package id="System.Xml.XDocument" version="4.3.0" targetFramework="net472" />
<package id="Titanium.Web.Proxy" version="3.2.0" targetFramework="net472" />
</packages>