//Validates the path the user informs in the install private static void ValidateFilePath(MainWindow window, PatcherPOCO patcher, string gamePath) { window.PathText.Text = gamePath; if (!CheckValidFileExists(gamePath, patcher)) { _log.Info("Wrong path selected"); window.TextWarningPath_SetTextError($"Path is INVALID for '{patcher.FriendlyName}'\n" + $"(Couldn't find {patcher.GetFriendlyExeNamesList()})"); window.BtnInstall.IsEnabled = false; // window.BtnUninstall.IsEnabled = false; } else { //installer won't run properly if install location is on a different drive to the installer. //Just warn the user to move the install file to the same drive. string currentDrive = Path.GetPathRoot(Environment.CurrentDirectory).ToLower(); string selectedPathDrive = Path.GetPathRoot(gamePath).ToLower(); if (currentDrive != selectedPathDrive) { MessageBox.Show($"Warning!! The installer is on a different drive to the game location!\n\n" + $"Please move the installer to the {selectedPathDrive} drive, and start the installer again!"); _log.Info($"Installer on different drive inst: {currentDrive} game: {selectedPathDrive}"); } _log.Info("Correct path selected"); window.TextWarningPath_SetTextSuccess($"Path is valid for '{patcher.FriendlyName}'\n" + $"(Found {patcher.GetFriendlyExeNamesList()})"); window.BtnInstall.IsEnabled = true; // window.BtnUninstall.IsEnabled = true; } }
public static Boolean CheckValidFileExists(String path, PatcherPOCO patcher) { foreach (string ExeName in patcher.GetExeNames()) { string file = path + "\\" + ExeName; if (File.Exists(file) || Directory.Exists(file)) { return(true); } } return(false); }
/// <summary> /// Show a FolderPicker Dialog for the user to select the game directory, then validates it is correct /// </summary> public static void AskFilePathAndValidate(MainWindow window, PatcherPOCO patcher) { _log.Info("Checking if path is valid"); var dialog = new CommonOpenFileDialog(); dialog.IsFolderPicker = true; CommonFileDialogResult result = dialog.ShowDialog(); if (result.ToString() == "Ok") { ValidateFilePath(window, patcher, dialog.FileName); } }
public MainWindow() { GlobalExceptionHandler.Setup(); patcher = new PatcherPOCO(ExecutionModeComboViewModel); patcher.ImagePath = "/Resources/logo.png"; // Set the default installation method according to windows version // (see https://stackoverflow.com/questions/2819934/detect-windows-version-in-net for versions) if (System.Environment.OSVersion.Version.Major < 10) { ExecutionModeComboViewModel.BatchFileExecutionMode = PatcherPOCO.BatchFileExecutionModeEnum.ShellExecuteWithLogging; } DataContext = this; InitializeComponent(); Logger.Setup(); patcher.IsFull = true; //Set title window this.Title = $"07th Mod Patcher v1.21 | LogFile: [{Logger.GetFullLogFilePath()}]"; //Old .Net versions will crash when creating the JobManagement class - tell users to update .Net //They are missing the function "System.Runtime.InteropServices.Marshal.StructureToPtr()" try { Utils.InitJobManagement(); } catch (Exception exception) { _log.Error(exception); MessageBox.Show("You probably have a very old version of .Net. Although the installer should work anyway, upgrading is highly recommended"); if (MessageBox.Show("Do you want to open the .Net download Page?", "Question", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.Yes) { MessageBox.Show("Remember, click '.Net Framework [X.X.X] Runtime', NOT the SDK versions!"); Process.Start("https://www.microsoft.com/net/download/windows"); System.Threading.Thread.Sleep(2000); MessageBox.Show("Remember, click '.Net Framework [X.X.X] Runtime', NOT the SDK versions!"); } else { MessageBox.Show("The installer will try to run anyway, but if you have issues, please try to update your .net version!"); } } //Programmatically make window smaller to hide right hand side panel //Not done in xaml so that xaml can still be edited Application.Current.MainWindow.Width = 450; }
/*Checks if there's something informed in the path component before switching grids * No need to check if the path is valid because the method below already does just that. * Also disables the icon grid so the user can't change chapters after this point*/ public static void CheckValidFilePath(MainWindow window, PatcherPOCO patcher) { if (window.PathText.Text != "Insert install folder for the chapter") { _log.Info("Confirmation grid"); window.InstallGrid.Visibility = Visibility.Collapsed; window.ConfirmationGrid.Visibility = Visibility.Visible; window.LockIconGrid(); ConstructPatcher(window, patcher); } else { window.TextWarningPath_SetTextError("Please select a folder before installing!"); } }
//Responsible for changing the layout depending on what option is selected in the combo public static void InstallComboChoose(MainWindow window, PatcherPOCO patcher) { switch (window.InstallCombo.SelectedItem.ToString().Split(new string[] { ": " }, StringSplitOptions.None).Last()) { case "Full": ResetDropBox(patcher); patcher.IsFull = true; TreatCheckboxes(window, false); break; case "Custom": ResetDropBox(patcher); patcher.IsCustom = true; TreatCheckboxes(window, true); break; case "Voice only": ResetDropBox(patcher); patcher.IsVoiceOnly = true; TreatCheckboxes(window, false); break; } }
/// <summary> /// Attempts to Auto-detect steam game install path. On failure, no action is taken. /// On success, still does the regular validation of the path as if path was selcted manually /// </summary> public static bool AutoDetectGamePathAndValidate(MainWindow window, PatcherPOCO patcher) { try { if (GetSteamappsCommonFolderFromRegistry(out string steamPath)) { foreach (string gameFolder in Directory.EnumerateDirectories(steamPath)) { if (CheckValidFileExists(gameFolder, patcher)) { ValidateFilePath(window, patcher, gameFolder); return(true); } } } } catch (Exception e) { _log.Info($"Couldn't auto-detect path: {e}"); } return(false); }
/* Populates the object for installation * And fills the list in the grid for user confirmation */ public static void ConstructPatcher(MainWindow window, PatcherPOCO patcher) { _log.Info("Constructing the patcher"); string tempFolder = window.PathText.Text + "\\temp"; Directory.CreateDirectory(tempFolder); patcher.InstallPath = tempFolder; patcher.IsBackup = (Boolean)window.ChkBackup.IsChecked; patcher.InstallUpdate = "Installation"; window.List1.Content = "Chapter: " + patcher.FriendlyName; window.List2.Content = "Path: " + window.PathText.Text; window.List3.Content = "Process: Installation"; window.List5.Content = "Backup: " + (patcher.IsBackup ? "Yes" : "No"); if (patcher.IsCustom) { patcher.InstallType = "Custom"; window.List4.Content = "Installation Type: Custom"; patcher.BatName = "custom.bat"; } else if (patcher.IsFull) { patcher.InstallType = "Full"; window.List4.Content = "Installation Type: Full"; patcher.BatName = "install.bat"; } else { patcher.InstallType = "Voice Only"; window.List4.Content = "Installation Type: Voice Only"; patcher.BatName = "voice.bat"; } //For the log PatcherInfo(patcher); }
public static void ResetDropBox(PatcherPOCO patcher) { patcher.IsVoiceOnly = false; patcher.IsCustom = false; patcher.IsFull = false; }
//downloads and extracts the resources of the temp folder public static async Task <bool> DownloadResources(MainWindow window, PatcherPOCO patcher) { //Note: this function captures the 'window' variable from outer scope. void DownloadResourcesProgressCallback(object sender, DownloadProgressChangedEventArgs e, String descriptiveFileName) { window.Dispatcher.Invoke(() => { InstallerProgressBar(window, $"Downloading {descriptiveFileName}...", $"{e.BytesReceived / 1e6:F2}/{e.TotalBytesToReceive / 1e6:F2}MB", $"{e.ProgressPercentage}%", e.ProgressPercentage); }); } void InstallBatCallback(object sender, DownloadProgressChangedEventArgs e) => DownloadResourcesProgressCallback(sender, e, patcher.BatName); void ResourcesZipCallback(object sender, DownloadProgressChangedEventArgs e) => DownloadResourcesProgressCallback(sender, e, "resources.zip"); try { _log.Info("Downloading install bat and creating temp folder"); using (var client = new WebClient()) { _log.Info("Downloading " + patcher.BatName); client.DownloadProgressChanged += InstallBatCallback; await client.DownloadFileTaskAsync("https://raw.githubusercontent.com/07th-mod/resources/master/" + patcher.ChapterName + "/" + patcher.BatName, patcher.InstallPath + "\\" + patcher.BatName); _log.Info("Downloading resources.zip"); client.DownloadProgressChanged -= InstallBatCallback; client.DownloadProgressChanged += ResourcesZipCallback; await client.DownloadFileTaskAsync("http://07th-mod.com/dependencies.zip", patcher.InstallPath + "\\resources.zip"); } } catch (WebException webException) { string friendlyMessage = "Couldn't reach 07th mod server to download patch files.\n\n" + "Note that we have blocked Japan from downloading (VPNs are compatible with this installer, however)\n\n" + $"[{webException.Message}]\nClick 'Show Detailed Progress' to view the full error."; _log.Error(friendlyMessage + webException); MessageBox.Show(friendlyMessage); return(false); } catch (Exception error) { string errormsg = "Couldn't download resources for installer: " + error; MessageBox.Show(errormsg); _log.Error(errormsg); return(false); } //extracting can fail if the files are still in use or if the zip file is corrupted _log.Info("Extracting resources"); try { ExtractZipArchive(Path.Combine(patcher.InstallPath, "resources.zip"), patcher.InstallPath); } catch (System.IO.IOException error) { string errormsg = "Couldn't extract files - probably temp/aria2c.exe or temp/7zip.exe are in use: " + error; MessageBox.Show(errormsg); _log.Error(errormsg); return(false); } catch (Exception error) { string errormsg = "An unexpected exception occured while extracting the zip file: " + error; MessageBox.Show(errormsg); _log.Error(errormsg); return(false); } _log.Info("Downloaded and extracted resources successfully"); return(true); }
public static void PatcherInfo(PatcherPOCO patcher) { _log.Info("Chapter: " + patcher.ChapterName); _log.Info("Install path: " + patcher.InstallPath); }