commit d4c4bb05c58255153f70d2d214b5ccf54bfc45ca Author: casksteven <56806651+casksteven@users.noreply.github.com> Date: Fri Feb 10 21:19:10 2023 -0500 Add files via upload diff --git a/App.config b/App.config new file mode 100644 index 0000000..04ee662 --- /dev/null +++ b/App.config @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/App.xaml b/App.xaml new file mode 100644 index 0000000..ada90f1 --- /dev/null +++ b/App.xaml @@ -0,0 +1,25 @@ + + + + + + + + + + pack://application:,,,/Launcher;component/Res/#remixicon + + + + + + diff --git a/App.xaml.cs b/App.xaml.cs new file mode 100644 index 0000000..fe07c8d --- /dev/null +++ b/App.xaml.cs @@ -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 +{ + /// + /// App.xaml 的交互逻辑 + /// + 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; + } +} diff --git a/Common/EmbedFileManager.cs b/Common/EmbedFileManager.cs new file mode 100644 index 0000000..9ac43f0 --- /dev/null +++ b/Common/EmbedFileManager.cs @@ -0,0 +1,140 @@ +using System; +using System.IO; +using System.Reflection; + +namespace Launcher.Common +{ + internal class EmbedFileManager + { + /// + /// 释放内嵌资源至指定位置 + /// + /// 嵌入的资源,此参数写作:命名空间.文件夹名.文件名.扩展名 + /// 释放到位置 + 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(); + } + } +} diff --git a/Common/GameHelper.cs b/Common/GameHelper.cs new file mode 100644 index 0000000..25dfae2 --- /dev/null +++ b/Common/GameHelper.cs @@ -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 + { + /// + /// 获取游戏目录,是静态方法 + /// + /// + 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 + } + /// + /// 启动器地址 + /// + /// + 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()); + } + + + } + } +} diff --git a/Common/IProxy.cs b/Common/IProxy.cs new file mode 100644 index 0000000..0db6e52 --- /dev/null +++ b/Common/IProxy.cs @@ -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(); + } +} diff --git a/Common/IniHelper.cs b/Common/IniHelper.cs new file mode 100644 index 0000000..6fe8525 --- /dev/null +++ b/Common/IniHelper.cs @@ -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); + } + + + } +} diff --git a/Common/ProcessWatcher.cs b/Common/ProcessWatcher.cs new file mode 100644 index 0000000..33d6ee1 --- /dev/null +++ b/Common/ProcessWatcher.cs @@ -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); + } + } + + + } +} diff --git a/Common/ProxyHelper.cs b/Common/ProxyHelper.cs new file mode 100644 index 0000000..d82d00f --- /dev/null +++ b/Common/ProxyHelper.cs @@ -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; + } + + } + } +} diff --git a/Control/ServerEditControl.xaml b/Control/ServerEditControl.xaml new file mode 100644 index 0000000..f1d7f84 --- /dev/null +++ b/Control/ServerEditControl.xaml @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs new file mode 100644 index 0000000..fa3c0c1 --- /dev/null +++ b/MainWindow.xaml.cs @@ -0,0 +1,54 @@ +using Launcher.Model; +using System; +using System.Globalization; +using System.Threading; +using System.Windows; +using System.Windows.Controls; + +namespace Launcher +{ + /// + /// MainWindow.xaml 的交互逻辑 + /// + 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; + } + } + } +} diff --git a/Model/GameInfo.cs b/Model/GameInfo.cs new file mode 100644 index 0000000..9120379 --- /dev/null +++ b/Model/GameInfo.cs @@ -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; } + + } +} diff --git a/Model/LauncherConfig.cs b/Model/LauncherConfig.cs new file mode 100644 index 0000000..6333f50 --- /dev/null +++ b/Model/LauncherConfig.cs @@ -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(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 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 servers = new ObservableCollection(); + + public ObservableCollection Servers + { + get { return servers; } + set { SetProperty(ref servers, value); } + } + + + + + } +} diff --git a/Model/PkgVersionItem.cs b/Model/PkgVersionItem.cs new file mode 100644 index 0000000..813267e --- /dev/null +++ b/Model/PkgVersionItem.cs @@ -0,0 +1,22 @@ +using System; + +namespace Launcher.Model +{ + [Obsolete] + public class PkgVersionItem + { + /// + /// + /// + public string remoteName { get; set; } + /// + /// + /// + public string md5 { get; set; } + /// + /// + /// + public int fileSize { get; set; } + + } +} diff --git a/Model/ProxyConfig.cs b/Model/ProxyConfig.cs new file mode 100644 index 0000000..6c8a48e --- /dev/null +++ b/Model/ProxyConfig.cs @@ -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; } + + } +} diff --git a/Model/ServerItem.cs b/Model/ServerItem.cs new file mode 100644 index 0000000..a751962 --- /dev/null +++ b/Model/ServerItem.cs @@ -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; } + } +} diff --git a/MultilingualResources/Launcher.en.xlf b/MultilingualResources/Launcher.en.xlf new file mode 100644 index 0000000..66ebacb --- /dev/null +++ b/MultilingualResources/Launcher.en.xlf @@ -0,0 +1,201 @@ + + + +
+ +
+ + + + 关于 + About + + + 主页 + Home + + + 设置 + Settings + + + + 支持的版本:3.1, 3.2, 3.2.50, 3.3, 与 gc-toolkit/RSAPatch 保持同步。 + + Supported versions: 3.1, 3.2, 3.2.50, 3.3, Synchronized with gc toolkit/RSAPatch. + + + 自动搜索 + Auto Detect + + + 手动选择 + Manual + + + 开启调试 + Enable DebugMode + + + 关于 + About + + + 开发 + Development + + + 常规 + General + + + [感谢]:https://github.com/34736384/RSAPatch + [appreciate]:https://github.com/34736384/RSAPatch + + + [开源地址]:https://github.com/gc-toolkit/Launcher + [Source Code]:https://github.com/gc-toolkit/Launcher + + + 官方 + Official Mode + + + 私有 + Private Mode + + + 仅代理 + Proxy Only + + + 背景图片 + Background Image + + + 游戏路径 + GamePath + + + 选择一个服务器 + Select a server + + + 正在运行 + Running + + + 开始游戏 + Play + + + 开启代理 + StartProxy + + + 关闭代理 + StopProxy + + + 添加 + Add + + + 删除 + Delete + + + 编辑 + Edit + + + 导出到剪贴板 + Export to Clipboard + + + 从剪贴板导入 + Import from clipboard + + + 可用服务器: + Available servers: + + + 请设置正确的游戏路径! + Please set the correct game path! + + + 导出成功! + Export succeeded! + + + 导入失败! + Import failed! + + + 导入成功! + Import succeeded! + + + 现在不能开始游戏! + Can't start the game now! + + + 请至少添加并选择一个服务器! + Please add and select at least one server! + + + 请选择一个服务器! + Please select a server! + + + 请先设置 游戏目录 和 游戏版本! + Please set the game directory and game version first! + + + 使用http + Use HTTP + + + 服务器编辑 + Server Profile Edit + + + 搜索失败,注册表中没有相关信息! + Detect failed, there is no relevant information in the registry! + + + 已找到位于{0}的游戏文件! + Found game file at {0}! + Please verify the translation’s accuracy as the source string was updated after it was translated. + + + 服务器名称 + Server Name + + + 高级 + Advanced + + + 确定 + Apply + + + PrivateKey,为空则禁用 + PrivateKey: If it is empty, it will be disabled. + + + PublicKey,为空则选择割草机的key + PublicKey: If it is empty, it will use grasscutter's ley. + + + 已经有一个启动器在运行 + An instance is already running + + + 崩溃了 + Crashed + + + +
+
\ No newline at end of file diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..324d404 --- /dev/null +++ b/Properties/AssemblyInfo.cs @@ -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 文件中的 CultureYouAreCodingWith +//例如,如果您在源文件中使用的是美国英语, +//使用的是美国英语,请将 设置为 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")] diff --git a/Properties/Resources.Designer.cs b/Properties/Resources.Designer.cs new file mode 100644 index 0000000..0dcc418 --- /dev/null +++ b/Properties/Resources.Designer.cs @@ -0,0 +1,486 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.42000 +// +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ + +namespace Launcher.Properties { + using System; + + + /// + /// 一个强类型的资源类,用于查找本地化的字符串等。 + /// + // 此类是由 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() { + } + + /// + /// 返回此类使用的缓存的 ResourceManager 实例。 + /// + [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; + } + } + + /// + /// 重写当前线程的 CurrentUICulture 属性,对 + /// 使用此强类型资源类的所有资源查找执行重写。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// 查找类似 + 支持的版本:3.1, 3.2, 3.2.50, 3.3, 与 gc-toolkit/RSAPatch 保持同步。 的本地化字符串。 + /// + public static string about_desp { + get { + return ResourceManager.GetString("about_desp", resourceCulture); + } + } + + /// + /// 查找类似 正在运行 的本地化字符串。 + /// + public static string btn_running { + get { + return ResourceManager.GetString("btn_running", resourceCulture); + } + } + + /// + /// 查找类似 自动搜索 的本地化字符串。 + /// + public static string btn_searchgame { + get { + return ResourceManager.GetString("btn_searchgame", resourceCulture); + } + } + + /// + /// 查找类似 手动选择 的本地化字符串。 + /// + public static string btn_selectgame { + get { + return ResourceManager.GetString("btn_selectgame", resourceCulture); + } + } + + /// + /// 查找类似 开始游戏 的本地化字符串。 + /// + public static string btn_startgame { + get { + return ResourceManager.GetString("btn_startgame", resourceCulture); + } + } + + /// + /// 查找类似 开启代理 的本地化字符串。 + /// + public static string btn_startproxy { + get { + return ResourceManager.GetString("btn_startproxy", resourceCulture); + } + } + + /// + /// 查找类似 关闭代理 的本地化字符串。 + /// + public static string btn_stopproxy { + get { + return ResourceManager.GetString("btn_stopproxy", resourceCulture); + } + } + + /// + /// 查找类似 开启调试 的本地化字符串。 + /// + public static string cb_enabledebug { + get { + return ResourceManager.GetString("cb_enabledebug", resourceCulture); + } + } + + /// + /// 查找类似 使用http 的本地化字符串。 + /// + public static string cb_usehttp { + get { + return ResourceManager.GetString("cb_usehttp", resourceCulture); + } + } + + /// + /// 查找类似 添加 的本地化字符串。 + /// + public static string cm_add { + get { + return ResourceManager.GetString("cm_add", resourceCulture); + } + } + + /// + /// 查找类似 删除 的本地化字符串。 + /// + public static string cm_del { + get { + return ResourceManager.GetString("cm_del", resourceCulture); + } + } + + /// + /// 查找类似 编辑 的本地化字符串。 + /// + public static string cm_edit { + get { + return ResourceManager.GetString("cm_edit", resourceCulture); + } + } + + /// + /// 查找类似 导出到剪贴板 的本地化字符串。 + /// + public static string cm_export { + get { + return ResourceManager.GetString("cm_export", resourceCulture); + } + } + + /// + /// 查找类似 从剪贴板导入 的本地化字符串。 + /// + public static string cm_import { + get { + return ResourceManager.GetString("cm_import", resourceCulture); + } + } + + /// + /// 查找类似 关于 的本地化字符串。 + /// + public static string h_about { + get { + return ResourceManager.GetString("h_about", resourceCulture); + } + } + + /// + /// 查找类似 开发 的本地化字符串。 + /// + public static string h_develop { + get { + return ResourceManager.GetString("h_develop", resourceCulture); + } + } + + /// + /// 查找类似 常规 的本地化字符串。 + /// + public static string h_general { + get { + return ResourceManager.GetString("h_general", resourceCulture); + } + } + + /// + /// 查找类似 服务器编辑 的本地化字符串。 + /// + public static string h_serveredit { + get { + return ResourceManager.GetString("h_serveredit", resourceCulture); + } + } + + /// + /// 查找类似 可用服务器: 的本地化字符串。 + /// + public static string h_servers { + get { + return ResourceManager.GetString("h_servers", resourceCulture); + } + } + + /// + /// 查找类似 关于 的本地化字符串。 + /// + public static string nav_about { + get { + return ResourceManager.GetString("nav_about", resourceCulture); + } + } + + /// + /// 查找类似 主页 的本地化字符串。 + /// + public static string nav_home { + get { + return ResourceManager.GetString("nav_home", resourceCulture); + } + } + + /// + /// 查找类似 设置 的本地化字符串。 + /// + public static string nav_setting { + get { + return ResourceManager.GetString("nav_setting", resourceCulture); + } + } + + /// + /// 查找类似 [感谢]:https://github.com/34736384/RSAPatch 的本地化字符串。 + /// + public static string repo1 { + get { + return ResourceManager.GetString("repo1", resourceCulture); + } + } + + /// + /// 查找类似 [开源地址]:https://github.com/gc-toolkit/Launcher 的本地化字符串。 + /// + public static string repoinfo { + get { + return ResourceManager.GetString("repoinfo", resourceCulture); + } + } + + /// + /// 查找类似 高级 的本地化字符串。 + /// + public static string t_advanced { + get { + return ResourceManager.GetString("t_advanced", resourceCulture); + } + } + + /// + /// 查找类似 官方 的本地化字符串。 + /// + public static string tab_official { + get { + return ResourceManager.GetString("tab_official", resourceCulture); + } + } + + /// + /// 查找类似 私有 的本地化字符串。 + /// + public static string tab_private { + get { + return ResourceManager.GetString("tab_private", resourceCulture); + } + } + + /// + /// 查找类似 仅代理 的本地化字符串。 + /// + public static string tab_proxyonly { + get { + return ResourceManager.GetString("tab_proxyonly", resourceCulture); + } + } + + /// + /// 查找类似 确定 的本地化字符串。 + /// + public static string tb_ok { + get { + return ResourceManager.GetString("tb_ok", resourceCulture); + } + } + + /// + /// 查找类似 背景图片 的本地化字符串。 + /// + public static string tbtip_bgurl { + get { + return ResourceManager.GetString("tbtip_bgurl", resourceCulture); + } + } + + /// + /// 查找类似 游戏路径 的本地化字符串。 + /// + public static string tbtip_gamepath { + get { + return ResourceManager.GetString("tbtip_gamepath", resourceCulture); + } + } + + /// + /// 查找类似 已经有一个启动器在运行 的本地化字符串。 + /// + public static string tip_alreadyrunning { + get { + return ResourceManager.GetString("tip_alreadyrunning", resourceCulture); + } + } + + /// + /// 查找类似 请设置正确的游戏路径! 的本地化字符串。 + /// + public static string tip_correctgamepath { + get { + return ResourceManager.GetString("tip_correctgamepath", resourceCulture); + } + } + + /// + /// 查找类似 崩溃了 的本地化字符串。 + /// + public static string tip_crash_title { + get { + return ResourceManager.GetString("tip_crash_title", resourceCulture); + } + } + + /// + /// 查找类似 导出成功! 的本地化字符串。 + /// + public static string tip_exp_succ { + get { + return ResourceManager.GetString("tip_exp_succ", resourceCulture); + } + } + + /// + /// 查找类似 导入失败! 的本地化字符串。 + /// + public static string tip_imp_err { + get { + return ResourceManager.GetString("tip_imp_err", resourceCulture); + } + } + + /// + /// 查找类似 导入成功! 的本地化字符串。 + /// + public static string tip_imp_succ { + get { + return ResourceManager.GetString("tip_imp_succ", resourceCulture); + } + } + + /// + /// 查找类似 现在不能开始游戏! 的本地化字符串。 + /// + public static string tip_nostart { + get { + return ResourceManager.GetString("tip_nostart", resourceCulture); + } + } + + /// + /// 查找类似 PrivateKey,为空则禁用 的本地化字符串。 + /// + public static string tip_privatekey { + get { + return ResourceManager.GetString("tip_privatekey", resourceCulture); + } + } + + /// + /// 查找类似 PublicKey,为空则选择割草机的key 的本地化字符串。 + /// + public static string tip_publickey { + get { + return ResourceManager.GetString("tip_publickey", resourceCulture); + } + } + + /// + /// 查找类似 请至少添加并选择一个服务器! 的本地化字符串。 + /// + public static string tip_reqaddone { + get { + return ResourceManager.GetString("tip_reqaddone", resourceCulture); + } + } + + /// + /// 查找类似 请选择一个服务器! 的本地化字符串。 + /// + public static string tip_reqselectone { + get { + return ResourceManager.GetString("tip_reqselectone", resourceCulture); + } + } + + /// + /// 查找类似 搜索失败,注册表中没有相关信息! 的本地化字符串。 + /// + public static string tip_search_err { + get { + return ResourceManager.GetString("tip_search_err", resourceCulture); + } + } + + /// + /// 查找类似 选择一个服务器 的本地化字符串。 + /// + public static string tip_selectone { + get { + return ResourceManager.GetString("tip_selectone", resourceCulture); + } + } + + /// + /// 查找类似 已找到位于{0}的游戏文件! 的本地化字符串。 + /// + public static string tip_serach_succ { + get { + return ResourceManager.GetString("tip_serach_succ", resourceCulture); + } + } + + /// + /// 查找类似 请先设置 游戏目录 和 游戏版本! 的本地化字符串。 + /// + public static string tip_setcfg { + get { + return ResourceManager.GetString("tip_setcfg", resourceCulture); + } + } + + /// + /// 查找类似 服务器名称 的本地化字符串。 + /// + public static string tip_srvname { + get { + return ResourceManager.GetString("tip_srvname", resourceCulture); + } + } + } +} diff --git a/Properties/Resources.en.resx b/Properties/Resources.en.resx new file mode 100644 index 0000000..3e01ea7 --- /dev/null +++ b/Properties/Resources.en.resx @@ -0,0 +1,150 @@ + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + About + + + Home + + + Settings + + + + Supported versions: 3.1, 3.2, 3.2.50, 3.3, Synchronized with gc toolkit/RSAPatch. + + + Auto Detect + + + Manual + + + Enable DebugMode + + + About + + + Development + + + General + + + [appreciate]:https://github.com/34736384/RSAPatch + + + [Source Code]:https://github.com/gc-toolkit/Launcher + + + Official Mode + + + Private Mode + + + Proxy Only + + + Background Image + + + GamePath + + + Select a server + + + Running + + + Play + + + StartProxy + + + StopProxy + + + Add + + + Delete + + + Edit + + + Export to Clipboard + + + Import from clipboard + + + Available servers: + + + Please set the correct game path! + + + Export succeeded! + + + Import failed! + + + Import succeeded! + + + Can't start the game now! + + + Please add and select at least one server! + + + Please select a server! + + + Please set the game directory and game version first! + + + Use HTTP + + + Server Profile Edit + + + Detect failed, there is no relevant information in the registry! + + + Found game file at {0}! + + + Server Name + + + Advanced + + + Apply + + + PrivateKey: If it is empty, it will be disabled. + + + PublicKey: If it is empty, it will use grasscutter's ley. + + \ No newline at end of file diff --git a/Properties/Resources.resx b/Properties/Resources.resx new file mode 100644 index 0000000..554657a --- /dev/null +++ b/Properties/Resources.resx @@ -0,0 +1,261 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + 支持的版本:3.1, 3.2, 3.2.50, 3.3, 与 gc-toolkit/RSAPatch 保持同步。 + + + 正在运行 + + + 自动搜索 + + + 手动选择 + + + 开始游戏 + + + 开启代理 + + + 关闭代理 + + + 开启调试 + + + 使用http + + + 添加 + + + 删除 + + + 编辑 + + + 导出到剪贴板 + + + 从剪贴板导入 + + + 关于 + + + 开发 + + + 常规 + + + 服务器编辑 + + + 可用服务器: + + + 关于 + + + 主页 + + + 设置 + + + [感谢]:https://github.com/34736384/RSAPatch + + + [开源地址]:https://github.com/gc-toolkit/Launcher + + + 官方 + + + 私有 + + + 仅代理 + + + 背景图片 + + + 游戏路径 + + + 确定 + + + 已经有一个启动器在运行 + + + 请设置正确的游戏路径! + + + 崩溃了 + + + 导出成功! + + + 导入失败! + + + 导入成功! + + + 现在不能开始游戏! + + + PrivateKey,为空则禁用 + + + PublicKey,为空则选择割草机的key + + + 请至少添加并选择一个服务器! + + + 请选择一个服务器! + + + 搜索失败,注册表中没有相关信息! + + + 选择一个服务器 + + + 已找到位于{0}的游戏文件! + + + 请先设置 游戏目录 和 游戏版本! + + + 服务器名称 + + + 高级 + + \ No newline at end of file diff --git a/Properties/Settings.Designer.cs b/Properties/Settings.Designer.cs new file mode 100644 index 0000000..2ae0089 --- /dev/null +++ b/Properties/Settings.Designer.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------ +// +// 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. +// +//------------------------------------------------------------------------------ + +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; + } + } + } +} diff --git a/Properties/Settings.settings b/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..ad2aab7 --- /dev/null +++ b/README.md @@ -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](/) diff --git a/RSAPatch/PublicKey.txt b/RSAPatch/PublicKey.txt new file mode 100644 index 0000000..8777005 --- /dev/null +++ b/RSAPatch/PublicKey.txt @@ -0,0 +1 @@ +xbbx2m1feHyrQ7jP+8mtDF/pyYLrJWKWAdEv3wZrOtjOZzeLGPzsmkcgncgoRhX4dT+1itSMR9j9m0/OwsH2UoF6U32LxCOQWQD1AMgIZjAkJeJvFTrtn8fMQ1701CkbaLTVIjRMlTw8kNXvNA/A9UatoiDmi4TFG6mrxTKZpIcTInvPEpkK2A7Qsp1E4skFK8jmysy7uRhMaYHtPTsBvxP0zn3lhKB3W+HTqpneewXWHjCDfL7Nbby91jbz5EKPZXWLuhXIvR1Cu4tiruorwXJxmXaP1HQZonytECNU/UOzP6GNLdq0eFDE4b04Wjp396551G99YiFP2nqHVJ5OMQ==AQAB \ No newline at end of file diff --git a/RSAPatch/RSAPatch.dll b/RSAPatch/RSAPatch.dll new file mode 100644 index 0000000..a980fc3 Binary files /dev/null and b/RSAPatch/RSAPatch.dll differ diff --git a/RSAPatch/rsa.dll.bak b/RSAPatch/rsa.dll.bak new file mode 100644 index 0000000..433241b Binary files /dev/null and b/RSAPatch/rsa.dll.bak differ diff --git a/Res/remixicon.ttf b/Res/remixicon.ttf new file mode 100644 index 0000000..c461f40 Binary files /dev/null and b/Res/remixicon.ttf differ diff --git a/Style/IconButtonStyle.xaml b/Style/IconButtonStyle.xaml new file mode 100644 index 0000000..825650e --- /dev/null +++ b/Style/IconButtonStyle.xaml @@ -0,0 +1,4 @@ + + + \ No newline at end of file diff --git a/Style/NavigationItemContainerStyle.xaml b/Style/NavigationItemContainerStyle.xaml new file mode 100644 index 0000000..baabf3a --- /dev/null +++ b/Style/NavigationItemContainerStyle.xaml @@ -0,0 +1,87 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/View/About.xaml b/View/About.xaml new file mode 100644 index 0000000..fc4a8c2 --- /dev/null +++ b/View/About.xaml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + diff --git a/View/About.xaml.cs b/View/About.xaml.cs new file mode 100644 index 0000000..129c660 --- /dev/null +++ b/View/About.xaml.cs @@ -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 +{ + /// + /// About.xaml 的交互逻辑 + /// + 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()); + } + } +} diff --git a/View/Home.xaml b/View/Home.xaml new file mode 100644 index 0000000..896aa9a --- /dev/null +++ b/View/Home.xaml @@ -0,0 +1,300 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Styles are the visual aspects of a UI that give it a distinct look and feel. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/View/Home.xaml.cs b/View/Home.xaml.cs new file mode 100644 index 0000000..7744ef4 --- /dev/null +++ b/View/Home.xaml.cs @@ -0,0 +1,43 @@ +using System.Windows.Controls; + +namespace Launcher.View +{ + /// + /// Home.xaml 的交互逻辑 + /// + 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; + } + } + } +} diff --git a/View/Setting.xaml b/View/Setting.xaml new file mode 100644 index 0000000..3fbb225 --- /dev/null +++ b/View/Setting.xaml @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + +