diff --git a/AM2RLauncher/AM2RLauncher.Gtk/Program.cs b/AM2RLauncher/AM2RLauncher.Gtk/Program.cs index 814b558..a4a9e01 100644 --- a/AM2RLauncher/AM2RLauncher.Gtk/Program.cs +++ b/AM2RLauncher/AM2RLauncher.Gtk/Program.cs @@ -49,7 +49,7 @@ internal static class MainClass { string osRelease = File.ReadAllText("/etc/os-release"); Regex lineRegex = new Regex(".*=.*"); - var results = lineRegex.Matches(osRelease).Cast().ToList(); + var results = lineRegex.Matches(osRelease).ToList(); var version = results.FirstOrDefault(x => x.Value.Contains("VERSION")); log.Info("Current Distro: " + results.FirstOrDefault(x => x.Value.Contains("NAME"))?.Value.Substring(5).Replace("\"", "") + (version == null ? "" : " " + version.Value.Substring(8).Replace("\"", ""))); diff --git a/AM2RLauncher/AM2RLauncher/LauncherUpdater.cs b/AM2RLauncher/AM2RLauncher/LauncherUpdater.cs index c40d82a..fbb5dce 100644 --- a/AM2RLauncher/AM2RLauncher/LauncherUpdater.cs +++ b/AM2RLauncher/AM2RLauncher/LauncherUpdater.cs @@ -131,6 +131,15 @@ namespace AM2RLauncher // No new update, exiting if (!isCurrentVersionOutdated) return; + + // For mac, we just show a message box that a new version is available, because I don't want to support for it yet + // hardcoded string, since also temporarily until it gets supported one day + if (OS.IsMac) + { + MessageBox.Show("Your current version is outdated! The newest version is " + onlineVersion + "." + + "Please recompile AM2RLauncher again or disable auto-updating"); + return; + } log.Info("Current version (" + VERSION + ") is outdated! Initiating update for version " + onlineVersion + "."); diff --git a/AM2RLauncher/AM2RLauncher/MainForm/MainForm.Events.cs b/AM2RLauncher/AM2RLauncher/MainForm/MainForm.Events.cs index 997ee6e..53adf08 100644 --- a/AM2RLauncher/AM2RLauncher/MainForm/MainForm.Events.cs +++ b/AM2RLauncher/AM2RLauncher/MainForm/MainForm.Events.cs @@ -31,7 +31,7 @@ namespace AM2RLauncher /// private async void PlayButtonLoadComplete(object sender, EventArgs e) { - LoadProfiles(); + LoadProfilesAndAdjustLists(); if (!Profile.IsPatchDataCloned() || !(bool)autoUpdateAM2RCheck.Checked) return; @@ -92,7 +92,7 @@ namespace AM2RLauncher { progressBar.Visible = false; progressLabel.Visible = false; - LoadProfiles(); + LoadProfilesAndAdjustLists(); } // Handling for updates - if current version does not match PatchData version, rename folder so that we attempt to install! @@ -144,7 +144,7 @@ namespace AM2RLauncher profileDropDown.SelectedIndex = 0; - LoadProfiles(); + LoadProfilesAndAdjustLists(); } } @@ -160,6 +160,9 @@ namespace AM2RLauncher // State Check UpdateStateMachine(); + // Check if 1.1 is installed by forcing invalidation + Profile.Is11Installed(true); + switch (updateState) { #region Download @@ -240,7 +243,7 @@ namespace AM2RLauncher SetPlayButtonState(UpdateState.Install); // This needs to be run BEFORE the state check so that the Mod Settings tab doesn't weird out - LoadProfiles(); + LoadProfilesAndAdjustLists(); // Do a state check UpdateStateMachine(); @@ -438,7 +441,7 @@ namespace AM2RLauncher progressBar.MaxValue = transferProgress.TotalObjects; if (currentGitObject >= transferProgress.ReceivedObjects) return; - progressLabel.Text = Language.Text.ProgressbarProgress + " " + transferProgress.ReceivedObjects + " (" + (int)transferProgress.ReceivedBytes / 1000000 + "MB) / " + transferProgress.TotalObjects + " objects"; + progressLabel.Text = Language.Text.ProgressbarProgress + " " + transferProgress.ReceivedObjects + " (" + ((int)transferProgress.ReceivedBytes / 1000000) + "MB) / " + transferProgress.TotalObjects + " objects"; currentGitObject = transferProgress.ReceivedObjects; progressBar.Value = transferProgress.ReceivedObjects; }); @@ -461,7 +464,7 @@ namespace AM2RLauncher return; } // Check if xdelta is installed on linux - if ((OS.IsUnix) && !CrossPlatformOperations.CheckIfXdeltaIsInstalled()) + if (OS.IsUnix && !CrossPlatformOperations.CheckIfXdeltaIsInstalled()) { MessageBox.Show(Language.Text.XdeltaNotFound, Language.Text.WarningWindowTitle, MessageBoxButtons.OK); SetApkButtonState(ApkButtonState.Create); @@ -626,11 +629,11 @@ namespace AM2RLauncher else { log.Error("User did not supply valid input. Cancelling import."); - LoadProfiles(); + LoadProfilesAndAdjustLists(); return; } - LoadProfiles(); + LoadProfilesAndAdjustLists(); settingsProfileDropDown.SelectedIndex = profileList.FindIndex(p => p.Name == addedProfile.Name); if (settingsProfileDropDown.SelectedIndex == -1) settingsProfileDropDown.SelectedIndex = 0; @@ -653,11 +656,10 @@ namespace AM2RLauncher /// private void SaveButtonClickEvent(object sender, EventArgs e) { - if (IsProfileIndexValid()) - { - log.Info("User opened the save directory for profile " + profileList[settingsProfileDropDown.SelectedIndex].Name + ", which is " + profileList[settingsProfileDropDown.SelectedIndex].SaveLocation); - CrossPlatformOperations.OpenFolder(profileList[settingsProfileDropDown.SelectedIndex].SaveLocation); - } + if (!IsProfileIndexValid()) + return; + log.Info("User opened the save directory for profile " + profileList[settingsProfileDropDown.SelectedIndex].Name + ", which is " + profileList[settingsProfileDropDown.SelectedIndex].SaveLocation); + CrossPlatformOperations.OpenFolder(profileList[settingsProfileDropDown.SelectedIndex].SaveLocation); } /// @@ -775,10 +777,11 @@ namespace AM2RLauncher if (profileDropDown.SelectedIndex == -1 && profileDropDown.Items.Count == 0) return; profileIndex = profileDropDown.SelectedIndex; - log.Info("profileDropDown.SelectedIndex has been changed to " + profileIndex + "."); + log.Debug("profileDropDown.SelectedIndex has been changed to " + profileIndex + "."); profileAuthorLabel.Text = Language.Text.Author + " " + profileList[profileDropDown.SelectedIndex].Author; profileVersionLabel.Text = Language.Text.VersionLabel + " " + profileList[profileDropDown.SelectedIndex].Version; + // TODO: only write this on application quit CrossPlatformOperations.WriteToConfig("ProfileIndex", profileIndex.ToString()); if (profileDropDown.SelectedIndex != 0 && (profileList[profileDropDown.SelectedIndex].SaveLocation == "%localappdata%/AM2R" || @@ -788,7 +791,6 @@ namespace AM2RLauncher saveWarningLabel.Visible = false; UpdateStateMachine(); - } /// Gets called when user selects a different item from and writes that to the config. @@ -940,7 +942,7 @@ namespace AM2RLauncher if (result == DialogResult.Ok) { log.Info("User did not cancel. Proceeding to delete " + profile); - DeleteProfile(profile); + DeleteProfileAndAdjustLists(profile); log.Info(profile + " has been deleted"); MessageBox.Show(Language.Text.DeleteModButtonSuccess.Replace("$NAME", profile.Name), Language.Text.SuccessWindowTitle); } @@ -1020,7 +1022,7 @@ namespace AM2RLauncher if (result == DialogResult.Ok) { // Delete profile - DeleteProfile(currentProfile); + DeleteProfileAndAdjustLists(currentProfile); // Rename directory to take the old one's place string originalFolder = modsDir + "/" + extractedName.Replace("_new", ""); @@ -1047,7 +1049,7 @@ namespace AM2RLauncher { // File cleanup HelperMethods.DeleteDirectory(modsDir + "/" + extractedName); - LoadProfiles(); + LoadProfilesAndAdjustLists(); return; } @@ -1057,7 +1059,7 @@ namespace AM2RLauncher } ProfileXML currentSelectedProfile = profileList[settingsProfileDropDown.SelectedIndex]; - LoadProfiles(); + LoadProfilesAndAdjustLists(); settingsProfileDropDown.SelectedIndex = profileList.FindIndex(p => p.Name == currentSelectedProfile.Name); if (settingsProfileDropDown.SelectedIndex == -1) settingsProfileDropDown.SelectedIndex = 0; diff --git a/AM2RLauncher/AM2RLauncher/MainForm/MainForm.StateMachine.cs b/AM2RLauncher/AM2RLauncher/MainForm/MainForm.StateMachine.cs index db8106d..733f02b 100644 --- a/AM2RLauncher/AM2RLauncher/MainForm/MainForm.StateMachine.cs +++ b/AM2RLauncher/AM2RLauncher/MainForm/MainForm.StateMachine.cs @@ -1,6 +1,5 @@ using Eto.Drawing; using System; -using System.IO; using AM2RLauncher.Core; using AM2RLauncher.Core.XML; @@ -52,7 +51,7 @@ namespace AM2RLauncher else if (isProfileValid && profileList[profileIndex.Value].Installable == false) { // We delete the profile, because we can't install it and it therefore holds no value! - DeleteProfile(profileList[profileIndex.Value]); + DeleteProfileAndAdjustLists(profileList[profileIndex.Value]); } // Otherwise, we still need to install. else @@ -269,84 +268,17 @@ namespace AM2RLauncher } /// - /// Deletes the given . Reloads the if is true. + /// Loads valid profile entries and reloads the necessary UI components. /// - private void DeleteProfile(ProfileXML profile, bool reloadProfileList = true) + private void LoadProfilesAndAdjustLists() { - log.Info("Attempting to delete profile " + profile.Name + "..."); - - // Delete folder in Mods - if (Directory.Exists(CrossPlatformOperations.CURRENTPATH + profile.DataPath)) - { - HelperMethods.DeleteDirectory(CrossPlatformOperations.CURRENTPATH + profile.DataPath); - } - - // Delete the zip file in Mods - if (File.Exists(CrossPlatformOperations.CURRENTPATH + profile.DataPath + ".zip")) - { - File.SetAttributes(CrossPlatformOperations.CURRENTPATH + profile.DataPath + ".zip", FileAttributes.Normal); // For some reason, it was set at read only, so we undo that here - File.Delete(CrossPlatformOperations.CURRENTPATH + profile.DataPath + ".zip"); - } - - // Delete folder in Profiles - if (Directory.Exists(CrossPlatformOperations.CURRENTPATH + "/Profiles/" + profile.Name)) - { - HelperMethods.DeleteDirectory(CrossPlatformOperations.CURRENTPATH + "/Profiles/" + profile.Name); - } - - if (reloadProfileList) - LoadProfiles(); - - log.Info("Successfully deleted profile " + profile.Name + "."); - } - - /// - /// Scans the PatchData and Mods folders for valid profile entries, and loads them. - /// - //TODO: Seperate this (and by extension, deleteProfile) from UI and backend - private void LoadProfiles() - { - log.Info("Loading profiles..."); - // Reset loaded profiles profileDropDown.Items.Clear(); profileList.Clear(); profileIndex = null; - // Check for and add the Community Updates profile - if (File.Exists(CrossPlatformOperations.CURRENTPATH + "/PatchData/profile.xml")) - { - profileList.Add(Serializer.Deserialize(File.ReadAllText(CrossPlatformOperations.CURRENTPATH + "/PatchData/profile.xml"))); - profileList[0].DataPath = "/PatchData/data"; - } - - // Safety check to generate the Mods folder if it does not exist - if (!Directory.Exists(CrossPlatformOperations.CURRENTPATH + "/Mods")) - Directory.CreateDirectory(CrossPlatformOperations.CURRENTPATH + "/Mods"); - - // Get Mods folder info - DirectoryInfo modsDir = new DirectoryInfo(CrossPlatformOperations.CURRENTPATH + "/Mods"); - - // Add all extracted profiles in Mods to the profileList. - foreach (DirectoryInfo dir in modsDir.GetDirectories()) - { - foreach (FileInfo file in dir.GetFiles()) - { - if (file.Name != "profile.xml") - continue; - ProfileXML prof = Serializer.Deserialize(File.ReadAllText(dir.FullName + "/profile.xml")); - if (prof.Installable || Profile.IsProfileInstalled(prof)) // Safety check for non-installable profiles - { - prof.DataPath = "/Mods/" + dir.Name; - profileList.Add(prof); - } - else if (!Profile.IsProfileInstalled(prof)) // If not installable and isn't installed, remove it - { - prof.DataPath = "/Mods/" + dir.Name; - DeleteProfile(prof, false); - } - } - } + // Load the profileList + profileList = Profile.LoadProfiles(); // Add profile names to the profileDropDown foreach (ProfileXML profile in profileList) @@ -383,8 +315,6 @@ namespace AM2RLauncher settingsProfileDropDown.Items.AddRange(profileDropDown.Items); settingsProfileDropDown.SelectedIndex = profileDropDown.Items.Count != 0 ? 0 : -1; - log.Info("Loaded " + profileList.Count + " profile(s)."); - // Refresh the author and version label on the main tab if (profileList.Count > 0) { @@ -392,7 +322,20 @@ namespace AM2RLauncher profileVersionLabel.Text = Language.Text.VersionLabel + " " + profileList[profileDropDown.SelectedIndex].Version; } + log.Info("Reloading UI components after loading successful."); + UpdateStateMachine(); } + + + /// + /// Deletes a profile and reloads the necessary UI components. + /// + /// The profile to delete. + private void DeleteProfileAndAdjustLists(ProfileXML profile) + { + Profile.DeleteProfile(profile); + LoadProfilesAndAdjustLists(); + } } } \ No newline at end of file diff --git a/AM2RLauncher/AM2RLauncher/MainForm/MainForm.UI.cs b/AM2RLauncher/AM2RLauncher/MainForm/MainForm.UI.cs index de7f67f..1fe357f 100644 --- a/AM2RLauncher/AM2RLauncher/MainForm/MainForm.UI.cs +++ b/AM2RLauncher/AM2RLauncher/MainForm/MainForm.UI.cs @@ -10,7 +10,6 @@ using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; -using System.Text.RegularExpressions; using System.Threading; namespace AM2RLauncher diff --git a/AM2RLauncher/AM2RLauncherCore/Profile.cs b/AM2RLauncher/AM2RLauncherCore/Profile.cs index 3fe3212..5142580 100644 --- a/AM2RLauncher/AM2RLauncherCore/Profile.cs +++ b/AM2RLauncher/AM2RLauncherCore/Profile.cs @@ -2,6 +2,7 @@ using LibGit2Sharp; using log4net; using System; +using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.IO.Compression; @@ -44,13 +45,21 @@ public static class Profile /// private static string lastAM2R11ZipMD5 = ""; + /*/// + /// Checks if AM2R 1.1 has been installed already, aka if a valid AM2R 1.1 Zip exists. + /// + + /// if yes, if not.*/ + /// /// Checks if AM2R 1.1 has been installed already, aka if a valid AM2R 1.1 Zip exists. /// - /// if yes, if not. - public static bool Is11Installed() + /// Determines if the AM2R_11 Cache should be invalidated + /// + public static bool Is11Installed(bool invalidateCache = false) { - InvalidateAM2R11InstallCache(); + // Only invalidate if we need to + if (invalidateCache) InvalidateAM2R11InstallCacheIfNecessary(); // If we have a cache, return that instead if (isAM2R11InstalledCache != null) return isAM2R11InstalledCache.Value; @@ -73,9 +82,9 @@ public static class Profile } /// - /// Invalidates . + /// Invalidates if necessary. /// - private static void InvalidateAM2R11InstallCache() + private static void InvalidateAM2R11InstallCacheIfNecessary() { // If the file exists, and its hash matches with ours, don't invalidate if (File.Exists(CrossPlatformOperations.CURRENTPATH + "/AM2R_11.zip") && @@ -122,6 +131,92 @@ public static class Profile } log.Info("Repository pulled successfully."); } +/* + /// + /// Scans the PatchData and Mods folders for valid profile entries, and loads them. + /// */ + + /// + /// Scans the PatchData and Mods folders for valid profile entries, creates and returns a list of them. + /// + /// A containing all valid profile entries. + public static List LoadProfiles() + { + log.Info("Loading profiles..."); + + List profileList = new List(); + + // Check for and add the Community Updates profile + if (File.Exists(CrossPlatformOperations.CURRENTPATH + "/PatchData/profile.xml")) + { + ProfileXML profile = Serializer.Deserialize(File.ReadAllText(CrossPlatformOperations.CURRENTPATH + "/PatchData/profile.xml")); + profile.DataPath = "/PatchData/data"; + profileList.Add(profile); + } + + // Safety check to generate the Mods folder if it does not exist + if (!Directory.Exists(CrossPlatformOperations.CURRENTPATH + "/Mods")) + Directory.CreateDirectory(CrossPlatformOperations.CURRENTPATH + "/Mods"); + + // Get Mods folder info + DirectoryInfo modsDir = new DirectoryInfo(CrossPlatformOperations.CURRENTPATH + "/Mods"); + + // Add all extracted profiles in Mods to the profileList. + foreach (DirectoryInfo dir in modsDir.GetDirectories()) + { + // If no profile.xml exists we don't add anything + if (!File.Exists(dir.FullName + "/profile.xml")) + continue; + + ProfileXML prof = Serializer.Deserialize(File.ReadAllText(dir.FullName + "/profile.xml")); + // Safety check for non-installable profiles + if (prof.Installable || IsProfileInstalled(prof)) + { + prof.DataPath = "/Mods/" + dir.Name; + profileList.Add(prof); + } + // If not installable and isn't installed, remove it + else if (!IsProfileInstalled(prof)) + { + prof.DataPath = "/Mods/" + dir.Name; + DeleteProfile(prof); + } + } + + log.Info("Loaded " + profileList.Count + " profile(s)."); + return profileList; + } + + /// + /// Deletes a profile from the Mods and Profiles folder. + /// + /// The profile to delete. + public static void DeleteProfile(ProfileXML profile) + { + log.Info("Attempting to delete profile " + profile.Name + "..."); + + // Delete folder in Mods + if (Directory.Exists(CrossPlatformOperations.CURRENTPATH + profile.DataPath)) + { + HelperMethods.DeleteDirectory(CrossPlatformOperations.CURRENTPATH + profile.DataPath); + } + + // Delete the zip file in Mods + if (File.Exists(CrossPlatformOperations.CURRENTPATH + profile.DataPath + ".zip")) + { + // For some reason, it was set at read only, so we undo that here + File.SetAttributes(CrossPlatformOperations.CURRENTPATH + profile.DataPath + ".zip", FileAttributes.Normal); + File.Delete(CrossPlatformOperations.CURRENTPATH + profile.DataPath + ".zip"); + } + + // Delete folder in Profiles + if (Directory.Exists(CrossPlatformOperations.CURRENTPATH + "/Profiles/" + profile.Name)) + { + HelperMethods.DeleteDirectory(CrossPlatformOperations.CURRENTPATH + "/Profiles/" + profile.Name); + } + + log.Info("Successfully deleted profile " + profile.Name + "."); + } /// /// Installs .