From 9565b58c9dd11f2bc5b971fc723fcf3641cd9ed7 Mon Sep 17 00:00:00 2001 From: Miepee <38186597+Miepee@users.noreply.github.com> Date: Thu, 5 Aug 2021 16:07:04 +0200 Subject: [PATCH] Put helper methods into its own class --- AM2RLauncher/AM2RLauncher/LauncherUpdater.cs | 3 +- .../AM2RLauncher/MainForm/HelperMethods.cs | 140 +++++++++++++ .../AM2RLauncher/MainForm/MainForm.Events.cs | 19 +- .../AM2RLauncher/MainForm/MainForm.Methods.cs | 187 +++--------------- 4 files changed, 181 insertions(+), 168 deletions(-) create mode 100644 AM2RLauncher/AM2RLauncher/MainForm/HelperMethods.cs diff --git a/AM2RLauncher/AM2RLauncher/LauncherUpdater.cs b/AM2RLauncher/AM2RLauncher/LauncherUpdater.cs index 6c0c381..d480065 100644 --- a/AM2RLauncher/AM2RLauncher/LauncherUpdater.cs +++ b/AM2RLauncher/AM2RLauncher/LauncherUpdater.cs @@ -10,6 +10,7 @@ using System.Net; using System.Reflection; using System.Text; using log4net; +using AM2RLauncher.Helpers; namespace AM2RLauncher { @@ -147,7 +148,7 @@ namespace AM2RLauncher } // for windows, the actual application is in "AM2RLauncher.dll". Which means, we need to update the lib folder as well. if (currentPlatform.IsWinForms) - MainForm.DirectoryCopy(tmpUpdatePath + "lib", CrossPlatformOperations.CURRENTPATH + "/lib", true); + HelperMethods.DirectoryCopy(tmpUpdatePath + "lib", CrossPlatformOperations.CURRENTPATH + "/lib", true); Directory.Delete(tmpUpdatePath, true); diff --git a/AM2RLauncher/AM2RLauncher/MainForm/HelperMethods.cs b/AM2RLauncher/AM2RLauncher/MainForm/HelperMethods.cs new file mode 100644 index 0000000..bc8f920 --- /dev/null +++ b/AM2RLauncher/AM2RLauncher/MainForm/HelperMethods.cs @@ -0,0 +1,140 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Security.Cryptography; +using System.Text; + +namespace AM2RLauncher.Helpers +{ + static class HelperMethods + { + // Thank you, Microsoft docs: https://docs.microsoft.com/en-us/dotnet/standard/io/how-to-copy-directories + // Slightly modified by adding overwriteFiles bool, as we need to replace readme, music, etc. + /// + /// This copies the contents of a specified Directory recursively to another Directory. + /// + /// Full Path to the Directory that will be recursively copied. + /// Full Path to the Directory you want to copy to. If the Directory does not exist, it will be created. + /// Specify if Files should be overwritten or not + /// Specify if you want to copy Sub-Directories as well. + public static void DirectoryCopy(string sourceDirName, string destDirName, bool overwriteFiles = true, bool copySubDirs = true) + { + // Get the subdirectories for the specified directory. + DirectoryInfo dir = new DirectoryInfo(sourceDirName); + + if (!dir.Exists) + { + throw new DirectoryNotFoundException( + "Source directory does not exist or could not be found: " + + sourceDirName); + } + + DirectoryInfo[] dirs = dir.GetDirectories(); + + // If the destination directory doesn't exist, create it. + Directory.CreateDirectory(destDirName); + + // Get the files in the directory and copy them to the new location. + FileInfo[] files = dir.GetFiles(); + foreach (FileInfo file in files) + { + string tempPath = Path.Combine(destDirName, file.Name); + file.CopyTo(tempPath, overwriteFiles); + } + + // If copying subdirectories, copy them and their contents to new location. + if (copySubDirs) + { + foreach (DirectoryInfo subdir in dirs) + { + string tempPath = Path.Combine(destDirName, subdir.Name); + DirectoryCopy(subdir.FullName, tempPath, overwriteFiles, copySubDirs); + } + } + } + + + /// + /// This is a custom method, that deletes a Directory. The reason this is used, instead of , + /// is because this one sets the attributes of all files to be deletable, while does not do that on it's own. + /// It's needed, because sometimes there are read-only files being generated, that would normally need more code in order to reset the attributes.
+ /// Note, that this method acts recursively. + ///
+ /// The directory to delete. + public static void DeleteDirectory(string targetDir) + { + if (!Directory.Exists(targetDir)) return; + + File.SetAttributes(targetDir, FileAttributes.Normal); + + foreach (string file in Directory.GetFiles(targetDir)) + { + File.SetAttributes(file, FileAttributes.Normal); + File.Delete(file); + } + + foreach (string dir in Directory.GetDirectories(targetDir)) + { + DeleteDirectory(dir); + } + + Directory.Delete(targetDir, false); + } + + /// + /// Calculates an MD5 hash from a given file. + /// + /// Full Path to the file whose MD5 hash is supposed to be calculated. + /// The MD5 hash as a , empty string if file does not exist. + public static string CalculateMD5(string filename) + { + // Check if File exists first + if (!File.Exists(filename)) + return ""; + + using (var stream = File.OpenRead(filename)) + { + using (var md5 = MD5.Create()) + { + var hash = md5.ComputeHash(stream); + return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant(); + } + } + } + + /// + /// Performs recursive rollover on a set of log files. + /// + /// The log file to begin the rollover from. + /// The maximum amount of log files to retain. Default is int.MaxValue, in other words, never delete files. + public static void RecursiveRollover(string logFile, int max = int.MaxValue) + { + int index = 1; + char endChar = logFile[logFile.Length - 1]; + string fileName; + + // If not the original file, set the new index and get the new fileName. + if (endChar != 't') + { + index = int.Parse(endChar.ToString()) + 1; + fileName = logFile.Remove(logFile.Length - 1) + index; + } + else // Otherwise, if the original file, just set fileName to log.txt.1. + fileName = logFile + ".1"; + + // If new name already exists, run the rollover algorithm on it! + if (File.Exists(fileName)) + { + RecursiveRollover(fileName, max); + } + + // If index is less than max, rename file. + if (index < max) + { + File.Move(logFile, fileName); + } + else // Otherwise, delete the file. + File.Delete(logFile); + } + } +} diff --git a/AM2RLauncher/AM2RLauncher/MainForm/MainForm.Events.cs b/AM2RLauncher/AM2RLauncher/MainForm/MainForm.Events.cs index 6dabb09..e61b3f7 100644 --- a/AM2RLauncher/AM2RLauncher/MainForm/MainForm.Events.cs +++ b/AM2RLauncher/AM2RLauncher/MainForm/MainForm.Events.cs @@ -20,6 +20,7 @@ using System.Net; using System.IO.Compression; using AM2RLauncher.XML; +using AM2RLauncher.Helpers; namespace AM2RLauncher { @@ -62,7 +63,7 @@ namespace AM2RLauncher { log.Error("Druid PatchData corruption occurred!"); MessageBox.Show(Language.Text.CorruptPatchData, Language.Text.ErrorWindowTitle, MessageBoxType.Error); - DeleteDirectory(CrossPlatformOperations.CURRENTPATH + "/PatchData"); + HelperMethods.DeleteDirectory(CrossPlatformOperations.CURRENTPATH + "/PatchData"); return; } } @@ -128,7 +129,7 @@ namespace AM2RLauncher } else { - DeleteDirectory(profileArchivePath); + HelperMethods.DeleteDirectory(profileArchivePath); log.Info("Cancelling archival! User-defined archive in Mods already exists."); } @@ -136,7 +137,7 @@ namespace AM2RLauncher } else // If our desired rename already exists, it's probably a user archive... so we just delete the folder and move on with installation of the new version. { - DeleteDirectory(CrossPlatformOperations.CURRENTPATH + "/Profiles/Community Updates (Latest)"); + HelperMethods.DeleteDirectory(CrossPlatformOperations.CURRENTPATH + "/Profiles/Community Updates (Latest)"); log.Info("Cancelling archival! User-defined archive in Profiles already exists."); } @@ -185,7 +186,7 @@ namespace AM2RLauncher try { if (Directory.Exists(CrossPlatformOperations.CURRENTPATH + "/PatchData")) - DeleteDirectory(CrossPlatformOperations.CURRENTPATH + "/PatchData"); + HelperMethods.DeleteDirectory(CrossPlatformOperations.CURRENTPATH + "/PatchData"); await Task.Run(() => Repository.Clone(currentMirror, CrossPlatformOperations.CURRENTPATH + "/PatchData", c)); } @@ -207,7 +208,7 @@ namespace AM2RLauncher log.Error("LibGit2SharpException: " + ex.Message + "\n*****Stack Trace*****\n\n" + ex.StackTrace); MessageBox.Show(ex.Message + "\n*****Stack Trace*****\n\n" + ex.StackTrace, Language.Text.ErrorWindowTitle, MessageBoxType.Error); if (Directory.Exists(CrossPlatformOperations.CURRENTPATH + "/PatchData")) - DeleteDirectory(CrossPlatformOperations.CURRENTPATH + "/PatchData"); + HelperMethods.DeleteDirectory(CrossPlatformOperations.CURRENTPATH + "/PatchData"); } successful = false; } @@ -217,7 +218,7 @@ namespace AM2RLauncher MessageBox.Show(ex.Message + "\n*****Stack Trace*****\n\n" + ex.StackTrace, Language.Text.ErrorWindowTitle, MessageBoxType.Error); if(Directory.Exists(CrossPlatformOperations.CURRENTPATH + " / PatchData")) - DeleteDirectory(CrossPlatformOperations.CURRENTPATH + "/PatchData"); + HelperMethods.DeleteDirectory(CrossPlatformOperations.CURRENTPATH + "/PatchData"); successful = false; } @@ -558,7 +559,7 @@ namespace AM2RLauncher log.Error("Mod is for " + profile.OperatingSystem + " while current OS is " + Platform + ". Cancelling mod import."); MessageBox.Show(Language.Text.ModIsForWrongOS.Replace("$NAME",profile.Name).Replace("$OS",profile.OperatingSystem).Replace("$CURRENTOS",currentOS), Language.Text.ErrorWindowTitle, MessageBoxType.Error); - DeleteDirectory(modsDir + "/" + extractedName); + HelperMethods.DeleteDirectory(modsDir + "/" + extractedName); return; } @@ -567,7 +568,7 @@ namespace AM2RLauncher { log.Error(profile.Name + " is already installed."); MessageBox.Show(Language.Text.ModIsAlreadyInstalledMessage.Replace("$NAME", profile.Name), Language.Text.WarningWindowTitle, MessageBoxType.Warning); - DeleteDirectory(modsDir + "/" + extractedName); + HelperMethods.DeleteDirectory(modsDir + "/" + extractedName); return; } @@ -944,7 +945,7 @@ namespace AM2RLauncher if (abort) { // file cleanup - DeleteDirectory(modsDir + "/" + extractedName); + HelperMethods.DeleteDirectory(modsDir + "/" + extractedName); LoadProfiles(); return; } diff --git a/AM2RLauncher/AM2RLauncher/MainForm/MainForm.Methods.cs b/AM2RLauncher/AM2RLauncher/MainForm/MainForm.Methods.cs index c5f8744..adc5e2a 100644 --- a/AM2RLauncher/AM2RLauncher/MainForm/MainForm.Methods.cs +++ b/AM2RLauncher/AM2RLauncher/MainForm/MainForm.Methods.cs @@ -12,9 +12,9 @@ using System.Linq; using Eto.Drawing; using System.Xml.Serialization; using AM2RLauncher.XML; -using System.Security.Cryptography; using System.Net.NetworkInformation; using System.Net; +using AM2RLauncher.Helpers; namespace AM2RLauncher { @@ -40,7 +40,7 @@ namespace AM2RLauncher if (returnCode != IsZipAM2R11ReturnCodes.Successful) { log.Info("Detected invalid AM2R_11 zip with following error code: " + returnCode); - RecursiveRollover(CrossPlatformOperations.CURRENTPATH + "/AM2R_11.zip"); + HelperMethods.RecursiveRollover(CrossPlatformOperations.CURRENTPATH + "/AM2R_11.zip"); return false; } return true; @@ -67,28 +67,6 @@ namespace AM2RLauncher return profileIndex != null; } - /// - /// Checks if we currently have an internet connection, by pinging the am2r website. - /// - /// - private static bool IsConnectedToInternet() - { - log.Info("Checking internet connection..."); - HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://github.com"); - HttpWebResponse response = null; - try - { - response = (HttpWebResponse)request.GetResponse(); - } - catch (WebException) - { - log.Info("Internet connection failed."); - return false; - } - log.Info("Internet connection established!"); - return true; - } - /// /// Git Pulls from the repository. /// @@ -104,7 +82,7 @@ namespace AM2RLauncher { // Directory exists, but seems corrupted, we delete it and prompt the user to download it again. MessageBox.Show(Language.Text.CorruptPatchData, Language.Text.ErrorWindowTitle, MessageBoxType.Error); - DeleteDirectory(CrossPlatformOperations.CURRENTPATH + "/PatchData"); + HelperMethods.DeleteDirectory(CrossPlatformOperations.CURRENTPATH + "/PatchData"); throw new UserCancelledException(); } @@ -143,7 +121,7 @@ namespace AM2RLauncher // Delete folder in Mods if (Directory.Exists(CrossPlatformOperations.CURRENTPATH + profile.DataPath)) { - DeleteDirectory(CrossPlatformOperations.CURRENTPATH + profile.DataPath); + HelperMethods.DeleteDirectory(CrossPlatformOperations.CURRENTPATH + profile.DataPath); } // Delete the zip file in Mods @@ -156,7 +134,7 @@ namespace AM2RLauncher // Delete folder in Profiles if (Directory.Exists(CrossPlatformOperations.CURRENTPATH + "/Profiles/" + profile.Name)) { - DeleteDirectory(CrossPlatformOperations.CURRENTPATH + "/Profiles/" + profile.Name); + HelperMethods.DeleteDirectory(CrossPlatformOperations.CURRENTPATH + "/Profiles/" + profile.Name); } if (reloadProfileList) @@ -362,11 +340,11 @@ namespace AM2RLauncher log.Info("xdelta patch(es) applied."); // Install new datafiles - DirectoryCopy(dataPath + "/files_to_copy", profilePath); + HelperMethods.DirectoryCopy(dataPath + "/files_to_copy", profilePath); // HQ music if (!profile.UsesCustomMusic && (bool)hqMusicPCCheck.Checked) - DirectoryCopy(CrossPlatformOperations.CURRENTPATH + "/PatchData/data/HDR_HQ_in-game_music", profilePath); + HelperMethods.DirectoryCopy(CrossPlatformOperations.CURRENTPATH + "/PatchData/data/HDR_HQ_in-game_music", profilePath); // Linux post-process @@ -381,14 +359,14 @@ namespace AM2RLauncher File.Move(file.FullName, file.DirectoryName + "/" + file.Name.ToLower()); //Copy AppImage template to here - DirectoryCopy(CrossPlatformOperations.CURRENTPATH + "/PatchData/data/AM2R.AppDir", profilePath + "/AM2R.AppDir/"); + HelperMethods.DirectoryCopy(CrossPlatformOperations.CURRENTPATH + "/PatchData/data/AM2R.AppDir", profilePath + "/AM2R.AppDir/"); // safety checks, in case the folders don't exist Directory.CreateDirectory(profilePath + "/AM2R.AppDir/usr/bin/"); Directory.CreateDirectory(profilePath + "/AM2R.AppDir/usr/bin/assets/"); // copy game assets to the appimageDir - DirectoryCopy(assetsPath, profilePath + "/AM2R.AppDir/usr/bin/assets/"); + HelperMethods.DirectoryCopy(assetsPath, profilePath + "/AM2R.AppDir/usr/bin/assets/"); File.Copy(profilePath + "/" + exe, profilePath + "/AM2R.AppDir/usr/bin/" + exe); UpdateProgressBar(66); @@ -531,11 +509,11 @@ namespace AM2RLauncher ZipFile.ExtractToDirectory(CrossPlatformOperations.CURRENTPATH + "/AM2R_11.zip", workingDir); // New datafiles - DirectoryCopy(dataPath + "/files_to_copy", workingDir); + HelperMethods.DirectoryCopy(dataPath + "/files_to_copy", workingDir); // HQ music if (hqMusicAndroidCheck.Checked == true) - DirectoryCopy(CrossPlatformOperations.CURRENTPATH + "/PatchData/data/HDR_HQ_in-game_music", workingDir); + HelperMethods.DirectoryCopy(CrossPlatformOperations.CURRENTPATH + "/PatchData/data/HDR_HQ_in-game_music", workingDir); // Add AM2R.ini // Yes, I'm aware this is dumb. If you've got any better ideas for how to copy a seemingly randomly named .ini from this folder to the APK, please let me know. @@ -631,7 +609,7 @@ namespace AM2RLauncher UpdateProgressBar(100); log.Info(profile.Name + ".apk signed and moved to " + CrossPlatformOperations.CURRENTPATH + "/" + profile.Name + ".apk."); - DeleteDirectory(tempDir); + HelperMethods.DeleteDirectory(tempDir); CrossPlatformOperations.OpenFolder(CrossPlatformOperations.CURRENTPATH); @@ -669,7 +647,7 @@ namespace AM2RLauncher Directory.CreateDirectory(logDir.FullName); if (File.Exists(logDir.FullName + "/" + profile.Name + ".txt")) - RecursiveRollover(logDir.FullName + "/" + profile.Name + ".txt", 5); + HelperMethods.RecursiveRollover(logDir.FullName + "/" + profile.Name + ".txt", 5); StreamWriter stream = File.AppendText(logDir.FullName + "/" + profile.Name + ".txt"); @@ -782,7 +760,7 @@ namespace AM2RLauncher Directory.CreateDirectory(logDir.FullName); if (File.Exists(logDir.FullName + "/" + profile.Name + ".txt")) - RecursiveRollover(logDir.FullName + "/" + profile.Name + ".txt", 5); + HelperMethods.RecursiveRollover(logDir.FullName + "/" + profile.Name + ".txt", 5); StreamWriter stream = File.AppendText(logDir.FullName + "/" + profile.Name + ".txt"); @@ -803,41 +781,6 @@ namespace AM2RLauncher } } - /// - /// Performs recursive rollover on a set of log files. - /// - /// The log file to begin the rollover from. - /// The maximum amount of log files to retain. Default is int.MaxValue, in other words, never delete files. - private void RecursiveRollover(string logFile, int max = int.MaxValue) - { - int index = 1; - char endChar = logFile[logFile.Length - 1]; - string fileName; - - // If not the original file, set the new index and get the new fileName. - if (endChar != 't') - { - index = int.Parse(endChar.ToString()) + 1; - fileName = logFile.Remove(logFile.Length - 1) + index; - } - else // Otherwise, if the original file, just set fileName to log.txt.1. - fileName = logFile + ".1"; - - // If new name already exists, run the rollover algorithm on it! - if (File.Exists(fileName)) - { - RecursiveRollover(fileName, max); - } - - // If index is less than max, rename file. - if (index < max) - { - File.Move(logFile, fileName); - } - else // Otherwise, delete the file. - File.Delete(logFile); - } - /// /// Method that updates . /// @@ -1142,11 +1085,11 @@ namespace AM2RLauncher return IsZipAM2R11ReturnCodes.MissingAM2RExe; // check if d3d.dll exists, then check the hash of d3d.dll - if (CalculateMD5(tmpPath + "/D3DX9_43.dll") != d3dHash) + if (HelperMethods.CalculateMD5(tmpPath + "/D3DX9_43.dll") != d3dHash) return IsZipAM2R11ReturnCodes.MissingOrInvalidD3DX9_43Dll; // check if data.win exists and check its hash - if (CalculateMD5(tmpPath + "/data.win") != dataWinHash) + if (HelperMethods.CalculateMD5(tmpPath + "/data.win") != dataWinHash) return IsZipAM2R11ReturnCodes.MissingOrInvalidDataWin; // clean up @@ -1156,99 +1099,27 @@ namespace AM2RLauncher return IsZipAM2R11ReturnCodes.Successful; } - /// - /// Calculates an MD5 hash from a given file. - /// - /// Full Path to the file whose MD5 hash is supposed to be calculated. - /// The MD5 hash as a , empty string if file does not exist. - private string CalculateMD5(string filename) - { - // Check if File exists first - if (!File.Exists(filename)) - return ""; - - using (var stream = File.OpenRead(filename)) - { - using (var md5 = MD5.Create()) - { - var hash = md5.ComputeHash(stream); - return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant(); - } - } - } - - - // Thank you, Microsoft docs: https://docs.microsoft.com/en-us/dotnet/standard/io/how-to-copy-directories - // Slightly modified by adding overwriteFiles bool, as we need to replace readme, music, etc. - /// - /// This copies the contents of a specified Directory recursively to another Directory. - /// - /// Full Path to the Directory that will be recursively copied. - /// Full Path to the Directory you want to copy to. If the Directory does not exist, it will be created. - /// Specify if Files should be overwritten or not - /// Specify if you want to copy Sub-Directories as well. - public static void DirectoryCopy(string sourceDirName, string destDirName, bool overwriteFiles = true, bool copySubDirs = true) - { - // Get the subdirectories for the specified directory. - DirectoryInfo dir = new DirectoryInfo(sourceDirName); - - if (!dir.Exists) - { - throw new DirectoryNotFoundException( - "Source directory does not exist or could not be found: " - + sourceDirName); - } - - DirectoryInfo[] dirs = dir.GetDirectories(); - - // If the destination directory doesn't exist, create it. - Directory.CreateDirectory(destDirName); - - // Get the files in the directory and copy them to the new location. - FileInfo[] files = dir.GetFiles(); - foreach (FileInfo file in files) - { - string tempPath = Path.Combine(destDirName, file.Name); - file.CopyTo(tempPath, overwriteFiles); - } - - // If copying subdirectories, copy them and their contents to new location. - if (copySubDirs) - { - foreach (DirectoryInfo subdir in dirs) - { - string tempPath = Path.Combine(destDirName, subdir.Name); - DirectoryCopy(subdir.FullName, tempPath, overwriteFiles, copySubDirs); - } - } - } - /// - /// This is a custom method, that deletes a Directory. The reason this is used, instead of , - /// is because this one sets the attributes of all files to be deletable, while does not do that on it's own. - /// It's needed, because sometimes there are read-only files being generated, that would normally need more code in order to reset the attributes.
- /// Note, that this method acts recursively. + /// Checks if we currently have an internet connection, by pinging github. ///
- /// The directory to delete. - private void DeleteDirectory(string targetDir) + /// + private static bool IsConnectedToInternet() { - if (!Directory.Exists(targetDir)) return; - - File.SetAttributes(targetDir, FileAttributes.Normal); - - foreach (string file in Directory.GetFiles(targetDir)) + log.Info("Checking internet connection..."); + HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://github.com"); + HttpWebResponse response = null; + try { - File.SetAttributes(file, FileAttributes.Normal); - File.Delete(file); + response = (HttpWebResponse)request.GetResponse(); } - - foreach (string dir in Directory.GetDirectories(targetDir)) + catch (WebException) { - DeleteDirectory(dir); + log.Info("Internet connection failed."); + return false; } - - Directory.Delete(targetDir, false); + log.Info("Internet connection established!"); + return true; } } }