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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +