diff --git a/PUBG2017PSLauncher/App.xaml.cs b/PUBG2017PSLauncher/App.xaml.cs
new file mode 100644
index 0000000..5a420d7
--- /dev/null
+++ b/PUBG2017PSLauncher/App.xaml.cs
@@ -0,0 +1,43 @@
+using System.Reflection;
+using System.Windows;
+using System.Drawing;
+
+namespace PUBG2017PSLauncher
+{
+ ///
+ /// Interaction logic for App.xaml
+ ///
+ public partial class App : System.Windows.Application
+ {
+ static NotifyIcon trayIcon;
+ protected override void OnStartup(StartupEventArgs e)
+ {
+ trayIcon = new NotifyIcon()
+ {
+ Text = "OG:BG 启动器",
+ Icon = Icon.ExtractAssociatedIcon(Assembly.GetEntryAssembly().ManifestModule.Name),
+ ContextMenuStrip = new ContextMenuStrip()
+ {
+ Items = {new ToolStripMenuItem("退出启动器", null, ExitFromTray)}
+ },
+ Visible = true
+ };
+
+ trayIcon.Click += TrayLeftClicked;
+
+ base.OnStartup(e);
+ }
+
+ void ExitFromTray(object sender, EventArgs e)
+ {
+ Current.Shutdown();
+ }
+
+ void TrayLeftClicked(object sender, EventArgs e)
+ {
+ MainWindow.Visibility = Visibility.Visible;
+ MainWindow.ShowInTaskbar = true;
+ }
+ }
+
+}
diff --git a/PUBG2017PSLauncher/AssemblyInfo.cs b/PUBG2017PSLauncher/AssemblyInfo.cs
new file mode 100644
index 0000000..b0ec827
--- /dev/null
+++ b/PUBG2017PSLauncher/AssemblyInfo.cs
@@ -0,0 +1,10 @@
+using System.Windows;
+
+[assembly: ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
diff --git a/PUBG2017PSLauncher/MainWindow.xaml b/PUBG2017PSLauncher/MainWindow.xaml
new file mode 100644
index 0000000..78dba4a
--- /dev/null
+++ b/PUBG2017PSLauncher/MainWindow.xaml
@@ -0,0 +1,146 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/PUBG2017PSLauncher/MainWindow.xaml.cs b/PUBG2017PSLauncher/MainWindow.xaml.cs
new file mode 100644
index 0000000..4ee7cdb
--- /dev/null
+++ b/PUBG2017PSLauncher/MainWindow.xaml.cs
@@ -0,0 +1,850 @@
+using System.ComponentModel;
+using System.IO;
+using System.Net.Http;
+using System.Text.Json;
+using System.Windows;
+using System.Diagnostics;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Threading;
+using System.Security.Cryptography;
+using Microsoft.Win32;
+
+//all of this code was written in 3 days, so expect it to be all over the fucking place lmao
+
+namespace PUBG2017PSLauncher
+{
+ public partial class MainWindow : Window
+ {
+ static readonly HttpClient client = new HttpClient();
+ static CancellationTokenSource cancellationToken = new CancellationTokenSource();
+ static List gameHashes = new List();
+ static List localGameHashes = new List();
+ static List filesToUpdate = new List();
+ static List gameFolders = new List();
+ static Config config = new Config() { gameInstall = AppContext.BaseDirectory+"GameInstall", startOnBoot = false, startMinimized = false, gameIsInstalled = false, lastPlayed = DateTime.Now, playtime = 0, webServerIp = "https://w3.dev.tlogin.zxwmr.top/resource/files/game/" };
+ static GameInfo gameInfo = new GameInfo();
+ static LauncherInfo launcherInfo = new LauncherInfo();
+
+ static Process? pubgProcess = null;
+ static DispatcherTimer playtimeTimer = new DispatcherTimer();
+
+ static DispatcherTimer updateCheckTimer = new DispatcherTimer();
+
+ static readonly string configPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\OGBG\\config.json";
+
+ bool inMainPage = true;
+ bool justLaunched = true;
+ bool downloadInProgress = false;
+ bool updateAvailable = false;
+ bool gameIsRunning = false;
+ bool repairInProgress = false;
+
+ static long totalDownloadSize;
+ static long downloadedAmount;
+ static double downloadSpeed;
+
+ const int launcherVersion = 3;
+
+ public MainWindow()
+ {
+ InitializeComponent();
+
+ if (!Directory.Exists(Path.GetDirectoryName(configPath))) Directory.CreateDirectory(Path.GetDirectoryName(configPath));
+ if (!Directory.Exists(AppContext.BaseDirectory + "\\Temp")) Directory.CreateDirectory(AppContext.BaseDirectory + "\\Temp");
+
+ if (!File.Exists(configPath))
+ {
+ File.WriteAllText(configPath, JsonSerializer.Serialize(config));
+ LoadConfig();
+ }
+ else LoadConfig();
+
+ if (string.IsNullOrEmpty(config.webServerIp))
+ {
+ config.webServerIp = "https://w3.dev.tlogin.zxwmr.top/resource/files/game/";
+ }
+
+ if (!config.startMinimized)
+ {
+ Visibility = Visibility.Visible;
+ ShowInTaskbar = true;
+ }
+
+ playtimeText.Text = string.Format("{0:F1}", config.playtime/3600f) + " 小时";
+ lastPlayedText.Text = config.lastPlayed.ToString();
+
+ playtimeTimer.Interval = TimeSpan.FromSeconds(1);
+ playtimeTimer.Tick += playtimeTimerTick;
+
+ updateCheckTimer.Interval = TimeSpan.FromMinutes(2);
+ updateCheckTimer.Tick += updateCheckTimerTick;
+ updateCheckTimer.Start();
+
+ if (config.gameIsInstalled && !Directory.EnumerateFileSystemEntries(config.gameInstall).Any())
+ {
+ config.gameIsInstalled = false;
+ }
+
+ if(config.gameIsInstalled)
+ {
+ repairGameBtn.IsEnabled = true;
+ uninstallGameBtn.IsEnabled = true;
+ }
+
+ UpdateInstallButton();
+
+ if (!Directory.Exists(config.gameInstall)) Directory.CreateDirectory(config.gameInstall);
+
+ if (System.Windows.Application.Current.MainWindow.IsInitialized && justLaunched)
+ {
+ try
+ {
+ gameInfo = JsonSerializer.Deserialize(Get($"{config.webServerIp}json/gameinfo.json").Result);
+ gameHashes = JsonSerializer.Deserialize>(Get($"{config.webServerIp}json/hashes.json").Result);
+ gameFolders = JsonSerializer.Deserialize>(Get($"{config.webServerIp}json/folders.json").Result);
+ launcherInfo = JsonSerializer.Deserialize(Get($"{config.webServerIp}json/launcherinfo.json").Result);
+ }
+ catch(Exception ex)
+ {
+ ThrowExceptionMessage(ex);
+ }
+
+ CheckForLauncherUpdate();
+
+ whatsNewText.Text = gameInfo.whatsNew;
+
+ justLaunched = false;
+ }
+
+ if (config.gameIsInstalled && File.Exists(config.gameInstall + "\\hashes.json"))
+ {
+ CheckForGameUpdate();
+ }
+ }
+
+ private void updateCheckTimerTick(object? sender, EventArgs e)
+ {
+ CheckForGameUpdate();
+ }
+
+ void UpdatePage()
+ {
+ if(inMainPage)
+ {
+ mainMenu.Visibility = Visibility.Visible;
+ settingsMenu.Visibility = Visibility.Collapsed;
+ mainBtn.Background = new SolidColorBrush(System.Windows.Media.Color.FromRgb(33, 33, 33));
+ mainBtn.Foreground = new SolidColorBrush(Colors.White);
+ settingsBtn.Background = new SolidColorBrush(Colors.Transparent);
+ settingsBtn.Foreground = new SolidColorBrush(System.Windows.Media.Color.FromRgb(110, 119, 131));
+ }
+ else
+ {
+ mainMenu.Visibility = Visibility.Collapsed;
+ settingsMenu.Visibility = Visibility.Visible;
+ mainBtn.Background = new SolidColorBrush(Colors.Transparent);
+ mainBtn.Foreground = new SolidColorBrush(System.Windows.Media.Color.FromRgb(110, 119, 131));
+ settingsBtn.Background = new SolidColorBrush(System.Windows.Media.Color.FromRgb(33, 33, 33));
+ settingsBtn.Foreground = new SolidColorBrush(Colors.White);
+ }
+ }
+
+ void LoadConfig()
+ {
+ config = JsonSerializer.Deserialize(File.ReadAllText(configPath));
+ gamePathTextBox.Text = config?.gameInstall;
+ startOnBootCheck.IsChecked = config?.startOnBoot;
+ startMinimizedCheck.IsChecked = config?.startMinimized;
+ }
+
+ void SaveConfig()
+ {
+ config.gameInstall = gamePathTextBox.Text;
+ config.startOnBoot = (bool)startOnBootCheck.IsChecked;
+ config.startMinimized = (bool)startMinimizedCheck.IsChecked;
+ File.WriteAllText(configPath, JsonSerializer.Serialize(config));
+ }
+
+ private static async Task Get(string url)
+ {
+ try
+ {
+ var resp = await client.GetAsync(url).ConfigureAwait(false);
+ var content = await resp.Content.ReadAsStringAsync();
+
+ // === 调试:打印返回内容 ===
+ Debug.WriteLine($"[DEBUG] {url}");
+ Debug.WriteLine($"[DEBUG] RESP: {content}");
+ // ============================
+
+ return resp.IsSuccessStatusCode ? content : string.Empty;
+ }
+ catch
+ {
+ System.Windows.MessageBox.Show("无法连接服务器,请检查网络。", "OG:BG 启动器", MessageBoxButton.OK, MessageBoxImage.Error);
+ return string.Empty;
+ }
+ }
+
+ private void Border_MouseDown(object sender, MouseButtonEventArgs e)
+ {
+ if(e.LeftButton == MouseButtonState.Pressed)
+ {
+ this.DragMove();
+ }
+ }
+
+ private void closeBtnClick(object sender, RoutedEventArgs e)
+ {
+ System.Windows.Application.Current.Shutdown();
+ }
+
+ private void minimizeBtnClick(object sender, RoutedEventArgs e)
+ {
+ WindowState = WindowState.Minimized;
+ }
+
+ private async void installBtnClick(object sender, RoutedEventArgs e)
+ {
+ if(!config.gameIsInstalled && !downloadInProgress)
+ {
+ downloadInProgress = true;
+ updateCheckTimer.Stop();
+ gameInstallPathBtn.IsEnabled = false;
+ UpdateInstallButton();
+
+ if (!Directory.Exists(config.gameInstall)) Directory.CreateDirectory(config.gameInstall);
+ if (!Directory.Exists(AppContext.BaseDirectory + "\\Temp")) Directory.CreateDirectory(AppContext.BaseDirectory + "\\Temp");
+
+ File.WriteAllText(config.gameInstall + "\\hashes.json", JsonSerializer.Serialize(gameHashes));
+
+ for(int i = 0; i < gameFolders.Count; i++)
+ {
+ if(!Directory.Exists(config.gameInstall+"\\"+gameFolders[i].path)) Directory.CreateDirectory(config.gameInstall + "\\" + gameFolders[i].path);
+ }
+
+ totalDownloadSize = 0;
+ GetDownloadSize(gameHashes);
+
+ DispatcherTimer timer = new DispatcherTimer();
+ timer.Interval = TimeSpan.FromSeconds(1);
+ timer.Tick += timerTick;
+ timer.Start();
+
+
+ ToggleDownloadBarVisibility(true);
+
+ for (int i = 0; i < gameHashes.Count; i++)
+ {
+ if (!cancellationToken.IsCancellationRequested)
+ {
+ Console.WriteLine(gameHashes[i].path);
+ await DownloadFileAsync($"{config.webServerIp}files/{gameHashes[i].path.Replace("\\", "/")}", config.gameInstall + "\\" + gameHashes[i].path, cancellationToken.Token);
+ }
+ else
+ {
+ timer.Stop();
+ updateCheckTimer.Start();
+ ToggleDownloadBarVisibility(false);
+ downloadedAmount = 0;
+ totalDownloadSize = 0;
+ downloadSpeed = 0;
+ downloadInProgress = false;
+ gameInstallPathBtn.IsEnabled = true;
+ UpdateInstallButton();
+ Directory.Delete(config.gameInstall, true);
+ cancellationToken = new CancellationTokenSource();
+ return;
+ }
+ }
+
+ ToggleDownloadBarVisibility(false);
+ updateCheckTimer.Start();
+ config.gameIsInstalled = true;
+ uninstallGameBtn.IsEnabled = true;
+ repairGameBtn.IsEnabled = true;
+ gameInstallPathBtn.IsEnabled = true;
+ downloadInProgress = false;
+ UpdateInstallButton();
+ }
+
+ if(downloadInProgress)
+ {
+ cancellationToken.Cancel();
+ }
+
+ if (config.gameIsInstalled && !updateAvailable && !gameIsRunning)
+ {
+ try
+ {
+ pubgProcess = new Process();
+ pubgProcess.StartInfo.FileName = config.gameInstall + "\\" + gameInfo.startupExecutable;
+ pubgProcess.StartInfo.Arguments = gameInfo.startupArgs;
+ pubgProcess.Start();
+ gameIsRunning = true;
+ pubgProcess.EnableRaisingEvents = true;
+ pubgProcess.Exited += PubgProcessEnded;
+
+ playtimeTimer.Start();
+ }
+ catch(Exception ex)
+ {
+ ThrowExceptionMessage(ex, "游戏已崩溃!这通常可能由于你修改了游戏的某些文件,建议尝试修复游戏文件重试!");
+ }
+
+
+ config.lastPlayed = DateTime.Now;
+ lastPlayedText.Text = DateTime.Now.ToString();
+ uninstallGameBtn.IsEnabled = false;
+ repairGameBtn.IsEnabled = false;
+ gameInstallPathBtn.IsEnabled = false;
+ UpdateInstallButton();
+ return;
+ }
+
+ if (gameIsRunning && !pubgProcess.HasExited)
+ {
+ DialogResult result = System.Windows.Forms.MessageBox.Show("你确定吗?", "OG:BG 启动器", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
+ if(result == System.Windows.Forms.DialogResult.Yes)
+ {
+ try
+ {
+ pubgProcess.Kill();
+ }
+ catch(Exception ex)
+ {
+ Console.WriteLine(ex.Message);
+ }
+ }
+ }
+
+ if(updateAvailable & !downloadInProgress)
+ {
+ downloadInProgress = true;
+
+ uninstallGameBtn.IsEnabled = false;
+ repairGameBtn.IsEnabled = false;
+ gameInstallPathBtn.IsEnabled = false;
+ UpdateInstallButton();
+
+ GetDownloadSize(filesToUpdate);
+ if (!Directory.Exists(AppContext.BaseDirectory + "\\Temp")) Directory.CreateDirectory(AppContext.BaseDirectory + "\\Temp");
+
+ DispatcherTimer timer = new DispatcherTimer();
+ timer.Interval = TimeSpan.FromSeconds(1);
+ timer.Tick += timerTick;
+ timer.Start();
+
+ ToggleDownloadBarVisibility(true);
+
+ for (int i = 0; i < filesToUpdate.Count; i++)
+ {
+ if(!cancellationToken.IsCancellationRequested)
+ {
+ Console.WriteLine($"正在更新: {filesToUpdate[i].path}");
+ await DownloadFileAsync($"{config.webServerIp}files/{filesToUpdate[i].path.Replace("\\", "/")}", config.gameInstall + "\\" + filesToUpdate[i].path, cancellationToken.Token);
+ filesToUpdate.Remove(filesToUpdate[i]);
+ }
+ else
+ {
+ timer.Stop();
+ ToggleDownloadBarVisibility(false);
+ downloadedAmount = 0;
+ totalDownloadSize = 0;
+ downloadSpeed = 0;
+ downloadInProgress = false;
+ uninstallGameBtn.IsEnabled = true;
+ repairGameBtn.IsEnabled = true;
+ gameInstallPathBtn.IsEnabled = true;
+ UpdateInstallButton();
+ cancellationToken = new CancellationTokenSource();
+ return;
+ }
+ }
+ timer.Stop();
+ ToggleDownloadBarVisibility(false);
+ downloadInProgress = false;
+ updateAvailable = false;
+ downloadedAmount = 0;
+ downloadSpeed = 0;
+ totalDownloadSize = 0;
+ uninstallGameBtn.IsEnabled = true;
+ repairGameBtn.IsEnabled = true;
+ gameInstallPathBtn.IsEnabled = true;
+ File.WriteAllText(config.gameInstall + "\\hashes.json", JsonSerializer.Serialize(gameHashes));
+ UpdateInstallButton();
+ return;
+ }
+ }
+
+ private void playtimeTimerTick(object? sender, EventArgs e)
+ {
+ config.playtime++;
+ playtimeText.Text = string.Format("{0:F1}", config.playtime/3600f) + " 小时";
+ }
+
+ //prepare to see a function with the most for loops :)
+ private async void repairGame(object sender, RoutedEventArgs e)
+ {
+ repairInProgress = true;
+ string[] files = Array.Empty();
+
+ try
+ {
+ files = Directory.GetFiles(config.gameInstall, "*.*", SearchOption.AllDirectories);
+ }
+ catch(Exception ex)
+ {
+ ThrowExceptionMessage(ex);
+ }
+
+
+ List installedFiles = new List();
+ List installedFilesPaths = new List();
+ List filesToRepair = new List();
+ List filesToCheck = new List();
+
+ installBtn.IsEnabled = false;
+ repairGameBtn.IsEnabled = false;
+ uninstallGameBtn.IsEnabled = false;
+ UpdateInstallButton();
+ ToggleDownloadBarVisibility(true);
+
+ downloadText.Text = "校验文件中...";
+ for(int i = 0; i < files.Length; i++)
+ {
+ var relativePath = Path.GetRelativePath(config.gameInstall, files[i]);
+ Console.WriteLine($"获取 MD5 哈希值: {relativePath}");
+ installedFiles.Add(new FileHash() { path = relativePath, hash = await GetMD5(files[i])});
+ downloadProgress.Value = (i*1d) / (files.Length*1d) * 100;
+ }
+
+
+ for(int i = 0; i < installedFiles.Count; i++)
+ {
+ if(installedFiles[i].path == "hashes.json")
+ {
+ installedFiles.Remove(installedFiles[i]); //fuck you hashes, yall dont belong here >:(
+ break;
+ }
+ }
+
+ downloadText.Text = "扫描损坏/丢失文件...";
+
+ for (int i = 0; i < installedFiles.Count; i++)
+ {
+ installedFilesPaths.Add(installedFiles[i].path);
+ }
+
+ for(int i = 0; i < gameHashes.Count; i++)
+ {
+ if(!installedFilesPaths.Contains(gameHashes[i].path))
+ {
+ Console.WriteLine($"丢失文件: {gameHashes[i].path}");
+ filesToRepair.Add(gameHashes[i]);
+ }
+ }
+
+ filesToCheck = gameHashes;
+
+ for(int i = 0; i < filesToRepair.Count; i++)
+ {
+ filesToCheck.Remove(filesToRepair[i]);
+ }
+
+ for (int i = 0; i < filesToCheck.Count; i++)
+ {
+ if (filesToCheck[i].hash != installedFiles[i].hash)
+ {
+ Console.WriteLine($"{filesToCheck[i].path} is borked");
+ filesToRepair.Add(filesToCheck[i]);
+ }
+ }
+
+ if(filesToRepair.Count == 0)
+ {
+ System.Windows.MessageBox.Show("所有文件均已校验成功!", "OG:BG 启动器", MessageBoxButton.OK, MessageBoxImage.Information);
+ }
+ else
+ {
+ downloadInProgress = true;
+
+ if (!Directory.Exists(AppContext.BaseDirectory + "\\Temp")) Directory.CreateDirectory(AppContext.BaseDirectory + "\\Temp");
+ GetDownloadSize(filesToRepair);
+
+ DispatcherTimer timer = new DispatcherTimer();
+ timer.Interval = TimeSpan.FromSeconds(1);
+ timer.Tick += timerTick;
+ timer.Start();
+
+ for (int i = 0; i < filesToRepair.Count; i++)
+ {
+ await DownloadFileAsync($"{config.webServerIp}files/{filesToRepair[i].path.Replace("\\", "/")}", config.gameInstall + "\\" + filesToRepair[i].path, cancellationToken.Token);
+ }
+ timer.Stop();
+ }
+ ToggleDownloadBarVisibility(false);
+ downloadInProgress = false;
+ repairInProgress = false;
+ downloadedAmount = 0;
+ downloadSpeed = 0;
+ totalDownloadSize = 0;
+ installBtn.IsEnabled = true;
+ repairGameBtn.IsEnabled = true;
+ uninstallGameBtn.IsEnabled = true;
+ UpdateInstallButton();
+ }
+
+ private void uninstallGame(object sender, RoutedEventArgs e)
+ {
+ DialogResult result = System.Windows.Forms.MessageBox.Show("你确定吗?", "OG:BG 启动器", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
+ if(result == System.Windows.Forms.DialogResult.Yes)
+ {
+ try
+ {
+ Directory.Delete(config.gameInstall, true);
+ }
+ catch(Exception ex)
+ {
+ ThrowExceptionMessage(ex);
+ }
+ config.gameIsInstalled = false;
+ uninstallGameBtn.IsEnabled = false;
+ repairGameBtn.IsEnabled = false;
+ UpdateInstallButton();
+ }
+ }
+
+ private async void CheckForGameUpdate()
+ {
+ gameHashes = JsonSerializer.Deserialize>(await Get($"{config.webServerIp}json/hashes.json"));
+ localGameHashes = JsonSerializer.Deserialize>(File.ReadAllText(config.gameInstall + "\\hashes.json"));
+
+ for (int i = 0; i < gameHashes.Count; i++)
+ {
+ if (File.Exists(config.gameInstall + "\\" + gameHashes[i].path))
+ {
+ if (gameHashes[i].hash != localGameHashes[i].hash)
+ {
+ filesToUpdate.Add(gameHashes[i]);
+ }
+ }
+ else
+ {
+ filesToUpdate.Add(gameHashes[i]);
+ }
+ }
+
+ if (filesToUpdate.Any())
+ {
+ updateAvailable = true;
+ UpdateInstallButton();
+ }
+ }
+
+ private async Task DownloadFileAsync(string url, string filename, CancellationToken token)
+ {
+ try
+ {
+ var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, token);
+
+ if (File.Exists(AppContext.BaseDirectory + "\\Temp\\" + Path.GetFileName(filename))) File.Delete(AppContext.BaseDirectory + "\\Temp\\" + Path.GetFileName(filename));
+
+ if (!response.IsSuccessStatusCode)
+ {
+ throw new Exception(string.Format("尝试请求,服务器 HTTP 返回 {0}", response.StatusCode));
+ }
+
+ var total = response.Content.Headers.ContentLength.HasValue ? response.Content.Headers.ContentLength.Value : -1L;
+ var canReportProgress = total != -1;
+
+ using (var stream = await response.Content.ReadAsStreamAsync())
+ {
+ var buffer = new byte[4096];
+ var isMoreToRead = true;
+
+ do
+ {
+
+ var read = await stream.ReadAsync(buffer, 0, buffer.Length, token);
+
+ if (read == 0)
+ {
+ isMoreToRead = false;
+ }
+ else
+ {
+ var data = new byte[read];
+ buffer.ToList().CopyTo(0, data, 0, read);
+
+ using (var fs = new FileStream(AppContext.BaseDirectory+"\\Temp\\"+Path.GetFileName(filename), FileMode.Append))
+ {
+ await fs.WriteAsync(data, 0, data.Length);
+ }
+
+ downloadedAmount += read;
+ downloadSpeed += read;
+
+ if (canReportProgress)
+ {
+ //progress = ((downloadedAmount * 1d) / (totalDownloadSize * 1d) * 100);
+ //downloadText.Text = string.Format("{0:F1}", downloadedAmount / 1073741824f) + "/" + string.Format("{0:F1}", totalDownloadSize / 1073741824f) + " GB (" + string.Format("{0:F1}", downloadSpeed / 1048576f) + " MB/s)";
+ }
+ }
+ } while (isMoreToRead);
+ }
+ File.Copy(AppContext.BaseDirectory + "\\Temp\\" + Path.GetFileName(filename), filename, true);
+ File.Delete(AppContext.BaseDirectory + "\\Temp\\" + Path.GetFileName(filename));
+ }
+ catch (TaskCanceledException) when (cancellationToken.IsCancellationRequested)
+ {
+ Console.WriteLine("用户取消请求");
+ }
+ catch (TaskCanceledException ex)
+ {
+ ThrowExceptionMessage(ex);
+ }
+ catch(Exception ex)
+ {
+ ThrowExceptionMessage(ex);
+ }
+
+ }
+
+ private void UpdateInstallButton()
+ {
+ if (downloadInProgress)
+ {
+ installBtnText.Text = "取消安装";
+ installBtn.Background = new SolidColorBrush(System.Windows.Media.Color.FromRgb(201, 34, 16));
+ }
+ else if (config.gameIsInstalled && !gameIsRunning && !updateAvailable && !repairInProgress)
+ {
+ installBtnText.Text = "开始游戏";
+ installBtn.Background = new SolidColorBrush(System.Windows.Media.Color.FromRgb(246, 192, 0));
+ installBtn.Foreground = new SolidColorBrush(Colors.Black);
+ }
+ else if (!downloadInProgress && !config.gameIsInstalled)
+ {
+ installBtnText.Text = "安装游戏";
+ installBtn.Background = new SolidColorBrush(System.Windows.Media.Color.FromRgb(246, 192, 0));
+ installBtn.Foreground = new SolidColorBrush(Colors.Black);
+ }
+ else if (pubgProcess != null)
+ {
+ installBtnText.Text = "停止游戏";
+ installBtn.Background = new SolidColorBrush(System.Windows.Media.Color.FromRgb(201, 34, 16));
+ }
+ else if (updateAvailable && !downloadInProgress && !gameIsRunning)
+ {
+ installBtnText.Text = "更新游戏";
+ installBtn.Background = new SolidColorBrush(System.Windows.Media.Color.FromRgb(246, 192, 0));
+ installBtn.Foreground = new SolidColorBrush(Colors.Black);
+ }
+ else if(repairInProgress)
+ {
+ installBtnText.Text = "...";
+ installBtn.Background = new SolidColorBrush(System.Windows.Media.Color.FromRgb(48, 48, 48));
+ installBtn.Foreground = new SolidColorBrush(System.Windows.Media.Color.FromRgb(110, 119, 131));
+ }
+
+ }
+
+ private void ToggleDownloadBarVisibility(bool visible)
+ {
+ if(visible)
+ {
+ downloadBar.Visibility = Visibility.Visible;
+ lastPlayed.Visibility = Visibility.Collapsed;
+ playtime.Visibility = Visibility.Collapsed;
+ miscButtons.Visibility = Visibility.Collapsed;
+ }
+ else
+ {
+ downloadBar.Visibility = Visibility.Collapsed;
+ playtime.Visibility = Visibility.Visible;
+ lastPlayed.Visibility = Visibility.Visible;
+ miscButtons.Visibility = Visibility.Visible;
+ }
+ }
+
+ private void timerTick(object state, EventArgs args)
+ {
+ downloadProgress.Value = (downloadedAmount * 1d) / (totalDownloadSize * 1d) * 100;
+ if(totalDownloadSize >= 1073741824)
+ {
+ downloadText.Text = string.Format("{0:F1}", downloadedAmount / 1073741824f) + "/" + string.Format("{0:F1}", totalDownloadSize / 1073741824f) + " GB (" + string.Format("{0:F1}", downloadSpeed / 1048576d) + " MB/s)";
+ }
+ else if(totalDownloadSize < 1073741824)
+ {
+ downloadText.Text = string.Format("{0:F1}", downloadedAmount / 1048576f) + "/" + string.Format("{0:F1}", totalDownloadSize / 1048576f) + " MB (" + string.Format("{0:F1}", downloadSpeed / 1048576d) + " MB/s)";
+ }
+ else if(totalDownloadSize < 1048576)
+ {
+ downloadText.Text = string.Format("{0:F1}", downloadedAmount / 1024f) + "/" + string.Format("{0:F1}", totalDownloadSize / 1024f) + " KB (" + string.Format("{0:F1}", downloadSpeed / 1048576d) + " MB/s)";
+ }
+ downloadSpeed = 0;
+ }
+
+ private void PubgProcessEnded(object sender, EventArgs args)
+ {
+ pubgProcess = null;
+ gameIsRunning = false;
+ playtimeTimer.Stop();
+ config.lastPlayed = DateTime.Now;
+
+ if (!Dispatcher.CheckAccess())
+ {
+ Dispatcher.Invoke(()=>UpdateInstallButton(), DispatcherPriority.Normal);
+ Dispatcher.Invoke(() => uninstallGameBtn.IsEnabled = true, DispatcherPriority.Normal);
+ Dispatcher.Invoke(() => repairGameBtn.IsEnabled = true, DispatcherPriority.Normal);
+ Dispatcher.Invoke(() => gameInstallPathBtn.IsEnabled = true, DispatcherPriority.Normal);
+ Dispatcher.Invoke(() => lastPlayedText.Text = DateTime.Now.ToString(), DispatcherPriority.Normal);
+ }
+ else
+ {
+ UpdateInstallButton();
+ lastPlayedText.Text = DateTime.Now.ToString();
+ uninstallGameBtn.IsEnabled = true;
+ repairGameBtn.IsEnabled = true;
+ gameInstallPathBtn.IsEnabled = true;
+ }
+ }
+
+ private static void GetDownloadSize(List files)
+ {
+ for (int i = 0; i < files.Count; i++)
+ {
+ totalDownloadSize += files[i].size;
+ }
+ }
+
+ async void CheckForLauncherUpdate()
+ {
+ if (launcherInfo.version > launcherVersion)
+ {
+ DialogResult result = System.Windows.Forms.MessageBox.Show("已检测到新版本,是否更新?", "OG:BG 启动器", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
+ if (result == System.Windows.Forms.DialogResult.Yes)
+ {
+ totalDownloadSize = launcherInfo.size;
+ ToggleDownloadBarVisibility(true);
+
+ DispatcherTimer timer = new DispatcherTimer();
+ timer.Interval = TimeSpan.FromSeconds(1);
+ timer.Tick += timerTick;
+ timer.Start();
+
+ await DownloadFileAsync($"{config.webServerIp}launcher/update.zip", AppContext.BaseDirectory + "\\update.zip", cancellationToken.Token);
+ timer.Stop();
+ Process.Start(AppContext.BaseDirectory+"Updater\\Updater.exe");
+ System.Windows.Application.Current.Shutdown();
+ }
+ }
+ }
+
+ private void settingsBtnClick(object sender, RoutedEventArgs e)
+ {
+ inMainPage = false;
+ UpdatePage();
+ }
+
+ private void startOnBootChecked(object sender, RoutedEventArgs e)
+ {
+ RegistryKey rk = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
+ rk.SetValue("OG:BG Launcher", '"' + Process.GetCurrentProcess().MainModule.FileName + '"');
+ }
+
+ private void startOnBootUnchecked(object sender, RoutedEventArgs e)
+ {
+ RegistryKey rk = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
+
+ if(rk.GetValueNames().Contains("OG:BG Launcher"))
+ rk.DeleteValue("OG:BG Launcher");
+ }
+
+ private void playBtnClick(object sender, RoutedEventArgs e)
+ {
+ inMainPage = true;
+ UpdatePage();
+ }
+
+ private void gameInstallBtnClick(object sender, RoutedEventArgs e)
+ {
+ using (var path = new FolderBrowserDialog())
+ {
+ DialogResult result = path.ShowDialog();
+
+ if(result == System.Windows.Forms.DialogResult.OK && !Directory.EnumerateFileSystemEntries(path.SelectedPath).Any())
+ {
+ config.gameInstall = path.SelectedPath;
+ gamePathTextBox.Text = path.SelectedPath;
+ }
+ else if(result == System.Windows.Forms.DialogResult.OK && Directory.EnumerateFileSystemEntries(path.SelectedPath).Any())
+ {
+ System.Windows.MessageBox.Show("请选择空文件夹!", "OG:BG 启动器", MessageBoxButton.OK, MessageBoxImage.Warning);
+ }
+ }
+ }
+
+ private void windowIsClosing(object sender, CancelEventArgs e)
+ {
+ SaveConfig();
+ }
+
+ static async Task GetMD5(string filename)
+ {
+ using (var md5 = MD5.Create())
+ {
+ using (var stream = File.OpenRead(filename))
+ {
+ var hash = await md5.ComputeHashAsync(stream);
+ return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
+ }
+ }
+ }
+
+ static void ThrowExceptionMessage(Exception ex, string customMessage = "")
+ {
+ var st = new StackTrace(ex, true);
+ var frame = st.GetFrame(st.FrameCount-1);
+
+ System.Windows.MessageBox.Show($"第 {frame.GetFileLineNumber()} 行: {frame.GetMethod()}: {ex.Message}"+Environment.NewLine+customMessage, "OG:BG 启动器", MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ }
+ class FileHash
+ {
+ public string? path { get; set; }
+ public string? hash { get; set; }
+ public long size { get; set; }
+ }
+
+ class GameInfo
+ {
+ public string? whatsNew { get; set; }
+ public string? startupExecutable { get; set; }
+ public string? startupArgs { get; set; }
+ }
+
+ class Folder
+ {
+ public string? path { get; set; }
+ }
+
+ class Config
+ {
+ public string? gameInstall { get; set; }
+ public bool startOnBoot { get; set; }
+ public bool startMinimized { get; set; }
+ public bool gameIsInstalled { get; set; }
+ public DateTime lastPlayed { get; set; }
+ public int playtime { get; set; }
+ public string? webServerIp { get; set; }
+ }
+
+ class LauncherInfo
+ {
+ public int version { get; set; }
+ public int size { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/PUBG2017PSLauncher/PUBG2017PSLauncher.csproj b/PUBG2017PSLauncher/PUBG2017PSLauncher.csproj
new file mode 100644
index 0000000..5b4a00a
--- /dev/null
+++ b/PUBG2017PSLauncher/PUBG2017PSLauncher.csproj
@@ -0,0 +1,40 @@
+
+
+
+ WinExe
+ net8.0-windows
+ enable
+ enable
+ true
+ True
+ icon.ico
+ AnyCPU;x64
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+