using GameLauncher; using System; using System.ComponentModel; using System.Configuration; using System.Diagnostics; using System.Diagnostics.Eventing.Reader; using System.IO; using System.IO.Compression; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Input; namespace GameLauncher { enum LauncherStatus { ready, failed, downloadingGame, downloadingUpdate, awaitingInput } /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { private string rootPath; private string versionFile; private string launcherVersionFile; private string tempZip; private string modZip; private string gameExe; private string launcherAssistantExe; private string launcherPath; private string configFile; private bool isNewInstall; private string chosenUserName; private string assistantPath; private string botDirectory; private LauncherStatus _status; internal LauncherStatus Status { get => _status; set { _status = value; switch (_status) { case LauncherStatus.ready: PlayButton.Content = "Play Bobocraft 2"; break; case LauncherStatus.failed: PlayButton.Content = "Install/Update Failed - Retry"; break; case LauncherStatus.downloadingGame: PlayButton.Content = "Installing Mod"; break; case LauncherStatus.downloadingUpdate: PlayButton.Content = "Updating"; break; case LauncherStatus.awaitingInput: PlayButton.Content = "Done"; break; default: break; } } } public MainWindow() { InitializeComponent(); launcherPath = Directory.GetCurrentDirectory(); assistantPath = launcherPath; gameExe = Path.Combine(launcherPath, "Robocraft 2.exe"); if (File.Exists(gameExe)) { rootPath = launcherPath; } else { rootPath = Path.Combine(launcherPath, "Game"); gameExe = Path.Combine(rootPath, "Robocraft 2.exe"); if (!File.Exists(gameExe)) { MessageBox.Show("Unable to find Robocraft 2 installation. Please make sure this file is placed inside the main /Robocraft 2 folder."); } } launcherAssistantExe = Path.Combine(assistantPath, "Bobocraft 2 Launcher Update Assistant.exe"); versionFile = Path.Combine(rootPath, "version.txt"); launcherVersionFile = Path.Combine(assistantPath, "launcherversion.txt"); tempZip = Path.Combine(rootPath, "temp"); modZip = Path.Combine(rootPath, "BepInEx", "plugins"); configFile = Path.Combine(rootPath, "BepInEx", "config", "RC2MPWE.cfg"); botDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "Bobocraft 2 Community Starter Bots"); } private void CheckForLauncherUpdates() { if (File.Exists(launcherVersionFile)) { Version localLauncherVersion = new Version(File.ReadAllText(launcherVersionFile)); LauncherVersionText.Text = localLauncherVersion.ToString(); try { WebClient webClient = new WebClient(); Version onlineLauncherVersion = new Version(webClient.DownloadString("https://drive.google.com/uc?export=download&id=16YSzW2p-mWDyS4249HdsNivMHvPU6uOu")); if (onlineLauncherVersion.IsDifferentThan(localLauncherVersion)) { UpdateLauncherAssistant(onlineLauncherVersion); } else { if (File.Exists(launcherAssistantExe)) { File.Delete(launcherAssistantExe); } CheckForUpdates(); } } catch (Exception ex) { Status = LauncherStatus.failed; MessageBox.Show($"Error checking for launcher updates: {ex}"); } } else { UpdateLauncherAssistant(Version.zero); } } private void UpdateLauncherAssistant(Version _onlinelauncherVersion) { try { WebClient webClient = new WebClient(); Status = LauncherStatus.downloadingUpdate; _onlinelauncherVersion = new Version(webClient.DownloadString("https://drive.google.com/uc?export=download&id=16YSzW2p-mWDyS4249HdsNivMHvPU6uOu")); webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(DownloadLauncherAssistantCompletedCallback); webClient.DownloadFileAsync(new Uri("https://cloud.norbipeti.eu/s/ZwRmsKb3gLNKKNH/download/assist.zip"), tempZip, _onlinelauncherVersion); } catch (Exception ex) { Status = LauncherStatus.failed; MessageBox.Show($"Error downloading launcher update: {ex}"); } } private void DownloadLauncherAssistantCompletedCallback(object sender, AsyncCompletedEventArgs e) { try { string onlineLauncherVersion = ((Version)e.UserState).ToString(); ZipFile.ExtractToDirectory(tempZip, assistantPath, true); ProcessStartInfo process = new ProcessStartInfo(@launcherAssistantExe); File.Delete(tempZip); Process.Start(process); this.Close(); } catch (Exception ex) { Status = LauncherStatus.failed; MessageBox.Show($"Error updating launcher assistant: {ex}"); } } private void CheckForUpdates() { if (File.Exists(versionFile)) { Version localVersion = new Version(File.ReadAllText(versionFile)); VersionText.Text = localVersion.ToString(); try { WebClient webClient = new WebClient(); Version onlineVersion = new Version(webClient.DownloadString("https://cloud.norbipeti.eu/s/j6TFGJbbS5z9Dp4/download/version.txt")); if (onlineVersion.IsDifferentThan(localVersion)) { InstallModFiles(true, onlineVersion); } else { Status = LauncherStatus.ready; } } catch (Exception ex) { Status = LauncherStatus.failed; MessageBox.Show($"Error checking for mod updates: {ex}"); } } else { InstallModFiles(false, Version.zero); } } private void InstallModFiles(bool _isUpdate, Version _onlineVersion) { try { WebClient webClient = new WebClient(); if (_isUpdate) { isNewInstall = false; Status = LauncherStatus.downloadingUpdate; webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(DownloadModCompletedCallback); webClient.DownloadFileAsync(new Uri("https://cloud.norbipeti.eu/s/yyk3LBaZsXa4GpR/download/RC2MPWE.zip"), tempZip, _onlineVersion); } else { isNewInstall = true; Status = LauncherStatus.downloadingGame; _onlineVersion = new Version(webClient.DownloadString("https://cloud.norbipeti.eu/s/j6TFGJbbS5z9Dp4/download/version.txt")); webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(DownloadModCompletedCallback); webClient.DownloadFileAsync(new Uri("https://cloud.norbipeti.eu/s/kZSSjFc2jqa22Hw/download/sus.zip"), tempZip, _onlineVersion); } } catch (Exception ex) { Status = LauncherStatus.failed; MessageBox.Show($"Error downloading mod files: {ex}"); } } private void InstallStarterBots(Version _zero) { try { WebClient webClient = new WebClient(); Status = LauncherStatus.downloadingUpdate; webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(DownloadStarterBotsCompletedCallback); webClient.DownloadFileAsync(new Uri("https://drive.google.com/uc?export=download&id=1DBX1tnU2rw7zVcgXFHAydG4wsbK2O-go"), tempZip, _zero); } catch (Exception ex) { Status = LauncherStatus.failed; MessageBox.Show($"Error downloading community starter bots: {ex}"); } } private void DownloadStarterBotsCompletedCallback(object sender, AsyncCompletedEventArgs e) { try { ZipFile.ExtractToDirectory(tempZip, botDirectory, true); File.Delete(tempZip); MessageBox.Show("A collection of Community Starter Bots was placed your desktop, please check the readme file for instructions on how to use them, and welcome to Bobocraft 2!"); Status = LauncherStatus.downloadingUpdate; CheckForUpdates(); } catch (Exception ex) { Status = LauncherStatus.failed; MessageBox.Show($"Error downloading community starter bots: {ex}"); } } private void DownloadModCompletedCallback(object sender, AsyncCompletedEventArgs e) { try { string onlineVersion = ((Version)e.UserState).ToString(); if (isNewInstall) { ZipFile.ExtractToDirectory(tempZip, rootPath, true); File.Delete(tempZip); File.WriteAllText(versionFile, "0.0.1"); VersionText.Text = "0.0.1"; Status = LauncherStatus.awaitingInput; mainWindowBox.Visibility = Visibility.Visible; } else { ZipFile.ExtractToDirectory(tempZip, modZip, true); File.Delete(tempZip); File.WriteAllText(versionFile, onlineVersion); VersionText.Text = onlineVersion; Status = LauncherStatus.ready; } } catch (Exception ex) { Status = LauncherStatus.failed; MessageBox.Show($"Error installing/updating mod: {ex}"); } } private void Window_ContentRendered(object sender, EventArgs e) { CheckForLauncherUpdates(); } private void PlayButton_Click(object sender, RoutedEventArgs e) { if (File.Exists(gameExe) && Status == LauncherStatus.ready) { ProcessStartInfo startInfo = new ProcessStartInfo(gameExe); startInfo.WorkingDirectory = rootPath; Process.Start(startInfo); Close(); } else if (Status == LauncherStatus.failed) { CheckForUpdates(); } else if (Status == LauncherStatus.awaitingInput) { CheckInputUsername(); } } private void CheckInputUsername() { chosenUserName = mainWindowBox.Text; if (chosenUserName.Length > 0 && chosenUserName.Length < 20 && chosenUserName != "Enter Username") { WriteUserName(chosenUserName); } else { MessageBox.Show("Invalid Username"); } } private void WriteUserName(string UserName) { if (File.Exists(configFile)) { string configString = File.ReadAllText(configFile); configString = configString.Replace("UserName = Mod_Player", "UserName = " + chosenUserName); File.WriteAllText(configFile, configString); mainWindowBox.Visibility = Visibility.Hidden; InstallStarterBots(Version.zero); } else { try { Directory.CreateDirectory(Path.Combine(rootPath, "BepInEx", "config")); } catch (Exception ex) { MessageBox.Show($"Error creating config directory: {ex}"); } try { File.WriteAllText(configFile, "[Auth]\r\nUserName = " + UserName); } catch (Exception ex) { MessageBox.Show($"Error writing config file: {ex}"); } mainWindowBox.Visibility = Visibility.Hidden; InstallStarterBots(Version.zero); } } } struct Version { internal static Version zero = new Version(0, 0, 0); private short major; private short minor; private short subMinor; internal Version(short _major, short _minor, short _subMinor) { major = _major; minor = _minor; subMinor = _subMinor; } internal Version(string _version) { string[] versionStrings = _version.Split('.'); if (versionStrings.Length != 3) { major = 0; minor = 0; subMinor = 0; return; } major = short.Parse(versionStrings[0]); minor = short.Parse(versionStrings[1]); subMinor = short.Parse(versionStrings[2]); } internal bool IsDifferentThan(Version _otherVersion) { if (major != _otherVersion.major) { return true; } else { if (minor != _otherVersion.minor) { return true; } else { if (subMinor != _otherVersion.subMinor) { return true; } } } return false; } public override string ToString() { return $"{major}.{minor}.{subMinor}"; } } }