From 44ee1ced97f2d428aa8f4d6b03e70a6573cabe7b Mon Sep 17 00:00:00 2001 From: Miepee <38186597+Miepee@users.noreply.github.com> Date: Tue, 1 Feb 2022 11:00:23 +0100 Subject: [PATCH 01/17] Readme: add java package to fedora --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 18c0cb7..3c30308 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ On Arch Linux you can install them by running this: ### Fedora On Fedora you can install them by running this command: -`dnf install dotnet-runtime-6.0 libappindicator-gtk3 xdelta mesa-libGL.i686 pulseaudio-libs.1686 openal-soft.i686` +`sudo dnf install dotnet-runtime-6.0 libappindicator-gtk3 xdelta mesa-libGL.i686 pulseaudio-libs.1686 openal-soft.i686 java-latest-openjdk` ### Other distros For other distros refer to your local package manager for instructions. From 688699be841d7d75317f8d9495e34ae4c83e19b3 Mon Sep 17 00:00:00 2001 From: Miepee <38186597+Miepee@users.noreply.github.com> Date: Tue, 1 Feb 2022 13:12:26 +0100 Subject: [PATCH 02/17] Add splash + remove invisible whitespace char --- AM2RLauncher/AM2RLauncherCore/Splash.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/AM2RLauncher/AM2RLauncherCore/Splash.cs b/AM2RLauncher/AM2RLauncherCore/Splash.cs index 3f5da5a..9255166 100644 --- a/AM2RLauncher/AM2RLauncherCore/Splash.cs +++ b/AM2RLauncher/AM2RLauncherCore/Splash.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Linq; namespace AM2RLauncher.Core; @@ -22,6 +22,7 @@ public static class Splash "Also try Metroid II: Return of Samus!", "Also try Metroid: Samus Returns!", "Also try Prime 2D!", + "Also try Skippy the Bot!", "Trust me, it's an 'unintentional feature.'", "Coming soon to a PC near you!", "This ain't your parents' Metroid 2!", @@ -127,4 +128,4 @@ public static class Splash totalSplashes = generalSplash; return totalSplashes; } -} \ No newline at end of file +} From 680fa9fd27c8b76c6afdb18285a987864059de2e Mon Sep 17 00:00:00 2001 From: Miepee <38186597+Miepee@users.noreply.github.com> Date: Sun, 6 Feb 2022 09:25:01 +0100 Subject: [PATCH 03/17] Make mac profile installation not crash --- AM2RLauncher/AM2RLauncherCore/Profile.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/AM2RLauncher/AM2RLauncherCore/Profile.cs b/AM2RLauncher/AM2RLauncherCore/Profile.cs index e897e92..9118f42 100644 --- a/AM2RLauncher/AM2RLauncherCore/Profile.cs +++ b/AM2RLauncher/AM2RLauncherCore/Profile.cs @@ -308,8 +308,9 @@ public static class Profile foreach (var file in new DirectoryInfo(profilePath).GetFiles()) if (file.Name.EndsWith(".ogg") && !File.Exists(file.DirectoryName + "/" + file.Name.ToLower())) File.Move(file.FullName, file.DirectoryName + "/" + file.Name.ToLower()); - // Loading custom fonts crashes on Mac, so we delete those - Directory.Delete(profilePath + "/lang/fonts", true); + // Loading custom fonts crashes on Mac, so we delete those if they exist + if (Directory.Exists(profilePath + "/lang/fonts")) + Directory.Delete(profilePath + "/lang/fonts", true); // Move Frameworks, Info.plist and PkgInfo over HelperMethods.DirectoryCopy(CrossPlatformOperations.CURRENTPATH + "/PatchData/data/Frameworks", profilePath.Replace("Resources", "Frameworks")); File.Copy(dataPath + "/Info.plist", profilePath.Replace("Resources", "") + "/Info.plist", true); @@ -701,4 +702,4 @@ public static class Profile log.Info("AM2R_11 check successful!"); return IsZipAM2R11ReturnCodes.Successful; } -} \ No newline at end of file +} From 42dbb9645cd6a46fc8c0c10a8c3f515aa06026d2 Mon Sep 17 00:00:00 2001 From: Miepee <38186597+Miepee@users.noreply.github.com> Date: Mon, 7 Feb 2022 17:21:51 +0100 Subject: [PATCH 04/17] [GH] Create contact links on issue page --- .github/ISSUE_TEMPLATE/config.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/config.yml diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..992118d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,14 @@ +blank_issues_enabled: false +contact_links: + - name: Discord server + url: https://discord.gg/nk7UYPbd5u + about: Chat about anything AM2R related. + - name: AM2R-FAQ + url: https://am2r-community-developers.github.io/DistributionCenter/faq.html + about: Find frequently asked questions for AM2R. + - name: AM2R Issues + url: https://github.com/AM2R-Community-Developers/AM2R-Community-Updates/issues/new/choose + about: Got an issue for AM2R itself? + - name: AM2RLauncher Wiki + url: https://github.com/AM2R-Community-Developers/AM2RLauncher/wiki + about: A more in-depth documentation for features and usage of the AM2RLauncher From c6e121f84b1708f337775f14905962e3ee0f0bf1 Mon Sep 17 00:00:00 2001 From: Miepee <38186597+Miepee@users.noreply.github.com> Date: Mon, 7 Feb 2022 17:23:26 +0100 Subject: [PATCH 05/17] [Actions] don't run on .github changes --- .github/workflows/build.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 051d786..060ee57 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,10 +5,12 @@ on: branches: [ main ] paths-ignore: - 'README.md' + - '.github/' pull_request: branches: [ main ] paths-ignore: - 'README.md' + - '.github/' jobs: build: From a9a5135d76a08d09fc0a7fed89f13c3df19d083f Mon Sep 17 00:00:00 2001 From: Miepee <38186597+Miepee@users.noreply.github.com> Date: Mon, 7 Feb 2022 17:25:34 +0100 Subject: [PATCH 06/17] [Actions] hopefully don't run on .github changes now --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 060ee57..3888e2a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,12 +5,12 @@ on: branches: [ main ] paths-ignore: - 'README.md' - - '.github/' + - '.github/**' pull_request: branches: [ main ] paths-ignore: - 'README.md' - - '.github/' + - '.github/**' jobs: build: From d768552f7aa42140208e6ac9c5a29cf5b56cbf00 Mon Sep 17 00:00:00 2001 From: Miepee Date: Tue, 8 Feb 2022 21:53:32 +0100 Subject: [PATCH 07/17] Linux: Only log env vars when on debug + set default log level to info --- AM2RLauncher/AM2RLauncher.Gtk/Program.cs | 7 ++- .../Properties/Resources.Designer.cs | 61 +++++-------------- .../Properties/Resources.resx | 2 +- AM2RLauncher/AM2RLauncher.Mac/Program.cs | 6 ++ .../Properties/Resources.Designer.cs | 2 - .../Properties/Resources.resx | 2 +- AM2RLauncher/AM2RLauncher.Wpf/Program.cs | 6 ++ .../Properties/Resources.Designer.cs | 61 +++++-------------- .../Properties/Resources.resx | 2 +- AM2RLauncher/AM2RLauncherCore/Profile.cs | 10 +-- 10 files changed, 56 insertions(+), 103 deletions(-) diff --git a/AM2RLauncher/AM2RLauncher.Gtk/Program.cs b/AM2RLauncher/AM2RLauncher.Gtk/Program.cs index a63620e..814b558 100644 --- a/AM2RLauncher/AM2RLauncher.Gtk/Program.cs +++ b/AM2RLauncher/AM2RLauncher.Gtk/Program.cs @@ -5,7 +5,7 @@ using System; using System.IO; using System.Linq; using System.Text.RegularExpressions; -using GLib; +using log4net.Repository.Hierarchy; using Application = Eto.Forms.Application; using FileInfo = System.IO.FileInfo; @@ -39,6 +39,11 @@ internal static class MainClass // Configure logger XmlConfigurator.Configure(new FileInfo(launcherDataPath + "/log4net.config")); + // if we're on debug, always set loglevel to debug + #if DEBUG + ((Logger)log.Logger).Level = log4net.Core.Level.Debug; + #endif + // Log distro and version (if it exists) if (File.Exists("/etc/os-release")) { diff --git a/AM2RLauncher/AM2RLauncher.Gtk/Properties/Resources.Designer.cs b/AM2RLauncher/AM2RLauncher.Gtk/Properties/Resources.Designer.cs index 1b88f02..4710aee 100644 --- a/AM2RLauncher/AM2RLauncher.Gtk/Properties/Resources.Designer.cs +++ b/AM2RLauncher/AM2RLauncher.Gtk/Properties/Resources.Designer.cs @@ -1,10 +1,9 @@ //------------------------------------------------------------------------------ // -// Dieser Code wurde von einem Tool generiert. -// Laufzeitversion:4.0.30319.42000 +// This code was generated by a tool. // -// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn -// der Code erneut generiert wird. +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. // //------------------------------------------------------------------------------ @@ -12,46 +11,32 @@ namespace AM2RLauncher.Gtk.Properties { using System; - /// - /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. - /// - // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert - // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert. - // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen - // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [System.Diagnostics.DebuggerNonUserCodeAttribute()] + [System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { - private static global::System.Resources.ResourceManager resourceMan; + private static System.Resources.ResourceManager resourceMan; - private static global::System.Globalization.CultureInfo resourceCulture; + private static System.Globalization.CultureInfo resourceCulture; - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal Resources() { } - /// - /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + internal static System.Resources.ResourceManager ResourceManager { get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("AM2RLauncher.Gtk.Properties.Resources", typeof(Resources).Assembly); + if (object.Equals(null, resourceMan)) { + System.Resources.ResourceManager temp = new System.Resources.ResourceManager("AM2RLauncher.Gtk.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; } } - /// - /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle - /// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + internal static System.Globalization.CultureInfo Culture { get { return resourceCulture; } @@ -60,22 +45,6 @@ namespace AM2RLauncher.Gtk.Properties { } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die <log4net> - /// <root> - /// <level value="ALL" /> - /// <appender-ref ref="file" /> - /// </root> - /// <appender name="file" type="log4net.Appender.RollingFileAppender"> - /// <file value="${DATADIR}/Logs/AM2RLauncher.log" /> - /// <appendToFile value="true" /> - /// <rollingStyle value="Once" /> - /// <maxSizeRollBackups value="7" /> - /// <maximumFileSize value="3MB" /> - /// <staticLogFileName value="true" /> - /// <layout type="log4net.Layout.PatternLayout"> - /// <conversionPattern value="%date [%thread] %level %logg [Rest der Zeichenfolge wurde abgeschnitten]"; ähnelt. - /// internal static string log4netContents { get { return ResourceManager.GetString("log4netContents", resourceCulture); diff --git a/AM2RLauncher/AM2RLauncher.Gtk/Properties/Resources.resx b/AM2RLauncher/AM2RLauncher.Gtk/Properties/Resources.resx index a2cff8e..ac17795 100644 --- a/AM2RLauncher/AM2RLauncher.Gtk/Properties/Resources.resx +++ b/AM2RLauncher/AM2RLauncher.Gtk/Properties/Resources.resx @@ -120,7 +120,7 @@ <log4net> <root> - <level value="ALL" /> + <level value="INFO" /> <appender-ref ref="file" /> </root> <appender name="file" type="log4net.Appender.RollingFileAppender"> diff --git a/AM2RLauncher/AM2RLauncher.Mac/Program.cs b/AM2RLauncher/AM2RLauncher.Mac/Program.cs index f25560f..56cfdb4 100644 --- a/AM2RLauncher/AM2RLauncher.Mac/Program.cs +++ b/AM2RLauncher/AM2RLauncher.Mac/Program.cs @@ -4,6 +4,7 @@ using log4net.Config; using System; using System.Diagnostics.CodeAnalysis; using System.IO; +using log4net.Repository.Hierarchy; namespace AM2RLauncher.Mac; @@ -36,6 +37,11 @@ internal static class MainClass // Configure logger XmlConfigurator.Configure(new FileInfo(launcherDataPath + "/log4net.config")); + // if we're on debug, always set loglevel to debug + #if DEBUG + ((Logger)log.Logger).Level = log4net.Core.Level.Debug; + #endif + try { Application macLauncher = new Application(Eto.Platforms.Mac64); diff --git a/AM2RLauncher/AM2RLauncher.Mac/Properties/Resources.Designer.cs b/AM2RLauncher/AM2RLauncher.Mac/Properties/Resources.Designer.cs index 641e315..47418bc 100644 --- a/AM2RLauncher/AM2RLauncher.Mac/Properties/Resources.Designer.cs +++ b/AM2RLauncher/AM2RLauncher.Mac/Properties/Resources.Designer.cs @@ -1,7 +1,6 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -10,7 +9,6 @@ namespace AM2RLauncher.Mac.Properties { using System; - using System.Reflection; [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] diff --git a/AM2RLauncher/AM2RLauncher.Mac/Properties/Resources.resx b/AM2RLauncher/AM2RLauncher.Mac/Properties/Resources.resx index a2cff8e..ac17795 100644 --- a/AM2RLauncher/AM2RLauncher.Mac/Properties/Resources.resx +++ b/AM2RLauncher/AM2RLauncher.Mac/Properties/Resources.resx @@ -120,7 +120,7 @@ <log4net> <root> - <level value="ALL" /> + <level value="INFO" /> <appender-ref ref="file" /> </root> <appender name="file" type="log4net.Appender.RollingFileAppender"> diff --git a/AM2RLauncher/AM2RLauncher.Wpf/Program.cs b/AM2RLauncher/AM2RLauncher.Wpf/Program.cs index 3c5172e..930cd56 100644 --- a/AM2RLauncher/AM2RLauncher.Wpf/Program.cs +++ b/AM2RLauncher/AM2RLauncher.Wpf/Program.cs @@ -4,6 +4,7 @@ using log4net.Config; using System; using System.IO; using System.Reflection; +using log4net.Repository.Hierarchy; namespace AM2RLauncher.Wpf; @@ -35,6 +36,11 @@ internal static class MainClass // Configure logger XmlConfigurator.Configure(new FileInfo(launcherDataPath + "/log4net.config")); + // if we're on debug, always set loglevel to debug + #if DEBUG + ((Logger)log.Logger).Level = log4net.Core.Level.Debug; + #endif + //Log Wine if (Core.Core.IsThisRunningFromWine) log.Info("Currently running from WINE!"); diff --git a/AM2RLauncher/AM2RLauncher.Wpf/Properties/Resources.Designer.cs b/AM2RLauncher/AM2RLauncher.Wpf/Properties/Resources.Designer.cs index ce32519..7de58d0 100644 --- a/AM2RLauncher/AM2RLauncher.Wpf/Properties/Resources.Designer.cs +++ b/AM2RLauncher/AM2RLauncher.Wpf/Properties/Resources.Designer.cs @@ -1,10 +1,9 @@ //------------------------------------------------------------------------------ // -// Dieser Code wurde von einem Tool generiert. -// Laufzeitversion:4.0.30319.42000 +// This code was generated by a tool. // -// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn -// der Code erneut generiert wird. +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. // //------------------------------------------------------------------------------ @@ -12,46 +11,32 @@ namespace AM2RLauncher.Wpf.Properties { using System; - /// - /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. - /// - // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert - // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert. - // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen - // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [System.Diagnostics.DebuggerNonUserCodeAttribute()] + [System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { - private static global::System.Resources.ResourceManager resourceMan; + private static System.Resources.ResourceManager resourceMan; - private static global::System.Globalization.CultureInfo resourceCulture; + private static System.Globalization.CultureInfo resourceCulture; - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal Resources() { } - /// - /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + internal static System.Resources.ResourceManager ResourceManager { get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("AM2RLauncher.Wpf.Properties.Resources", typeof(Resources).Assembly); + if (object.Equals(null, resourceMan)) { + System.Resources.ResourceManager temp = new System.Resources.ResourceManager("AM2RLauncher.Wpf.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; } } - /// - /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle - /// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + internal static System.Globalization.CultureInfo Culture { get { return resourceCulture; } @@ -60,22 +45,6 @@ namespace AM2RLauncher.Wpf.Properties { } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die <log4net> - /// <root> - /// <level value="ALL" /> - /// <appender-ref ref="file" /> - /// </root> - /// <appender name="file" type="log4net.Appender.RollingFileAppender"> - /// <file value="${DATADIR}/Logs/AM2RLauncher.log" /> - /// <appendToFile value="true" /> - /// <rollingStyle value="Once" /> - /// <maxSizeRollBackups value="7" /> - /// <maximumFileSize value="3MB" /> - /// <staticLogFileName value="true" /> - /// <layout type="log4net.Layout.PatternLayout"> - /// <conversionPattern value="%date [%thread] %level %logg [Rest der Zeichenfolge wurde abgeschnitten]"; ähnelt. - /// internal static string log4netContents { get { return ResourceManager.GetString("log4netContents", resourceCulture); diff --git a/AM2RLauncher/AM2RLauncher.Wpf/Properties/Resources.resx b/AM2RLauncher/AM2RLauncher.Wpf/Properties/Resources.resx index a2cff8e..ac17795 100644 --- a/AM2RLauncher/AM2RLauncher.Wpf/Properties/Resources.resx +++ b/AM2RLauncher/AM2RLauncher.Wpf/Properties/Resources.resx @@ -120,7 +120,7 @@ <log4net> <root> - <level value="ALL" /> + <level value="INFO" /> <appender-ref ref="file" /> </root> <appender name="file" type="log4net.Appender.RollingFileAppender"> diff --git a/AM2RLauncher/AM2RLauncherCore/Profile.cs b/AM2RLauncher/AM2RLauncherCore/Profile.cs index 9118f42..3fe3212 100644 --- a/AM2RLauncher/AM2RLauncherCore/Profile.cs +++ b/AM2RLauncher/AM2RLauncherCore/Profile.cs @@ -492,7 +492,7 @@ public static class Profile { ProcessStartInfo startInfo = new ProcessStartInfo(); - log.Info("Is the environment textbox null or whitespace = " + String.IsNullOrWhiteSpace(envVars)); + log.Info("User does " + (String.IsNullOrWhiteSpace(envVars) ? "not" : "") + " have custom environment variables set."); //TODO: make this more readable at one day if (!String.IsNullOrWhiteSpace(envVars)) @@ -524,7 +524,7 @@ public static class Profile string value = envVars.Substring(0, valueSubstringLength); envVars = envVars.Substring(value.Length); - log.Info("Adding variable \"" + variable + "\" with value \"" + value + "\""); + log.Info("Adding user variable \"" + variable + "\" with value \"" + value + "\""); startInfo.EnvironmentVariables[variable] = value; } } @@ -538,10 +538,10 @@ public static class Profile log.Info("CWD of Profile is " + startInfo.WorkingDirectory); - log.Info("Launching game with following variables: "); + log.Debug("Launching game with following variables: "); foreach (System.Collections.DictionaryEntry item in startInfo.EnvironmentVariables) { - log.Info("Key: \"" + item.Key + "\" Value: \"" + item.Value + "\""); + log.Debug("Key: \"" + item.Key + "\" Value: \"" + item.Value + "\""); } using (Process p = new Process()) @@ -702,4 +702,4 @@ public static class Profile log.Info("AM2R_11 check successful!"); return IsZipAM2R11ReturnCodes.Successful; } -} +} \ No newline at end of file From dcc99707b7615dcec5c794e3d0dd82630b3ea691 Mon Sep 17 00:00:00 2001 From: Lojemiru <33508026+Lojemiru@users.noreply.github.com> Date: Fri, 11 Feb 2022 01:07:56 -0600 Subject: [PATCH 08/17] wombat mall --- AM2RLauncher/AM2RLauncherCore/Splash.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/AM2RLauncher/AM2RLauncherCore/Splash.cs b/AM2RLauncher/AM2RLauncherCore/Splash.cs index 9255166..79444d8 100644 --- a/AM2RLauncher/AM2RLauncherCore/Splash.cs +++ b/AM2RLauncher/AM2RLauncherCore/Splash.cs @@ -43,7 +43,8 @@ public static class Splash "S P I D E R B A L L", "Fun is infinite with Community-Developers Inc.", "You may only proceed if you wear baggy pants.", - "Did you know that games take time to develop?" + "Did you know that games take time to develop?", + "Ask the wombat." }; /// From 339fbcd502e5e535c985c351f1de3296334f6c26 Mon Sep 17 00:00:00 2001 From: Miepee <38186597+Miepee@users.noreply.github.com> Date: Fri, 11 Feb 2022 15:46:35 +0100 Subject: [PATCH 09/17] Add launcher updater todo for later --- AM2RLauncher/AM2RLauncher/LauncherUpdater.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/AM2RLauncher/AM2RLauncher/LauncherUpdater.cs b/AM2RLauncher/AM2RLauncher/LauncherUpdater.cs index a2a4c93..ec26c08 100644 --- a/AM2RLauncher/AM2RLauncher/LauncherUpdater.cs +++ b/AM2RLauncher/AM2RLauncher/LauncherUpdater.cs @@ -207,7 +207,8 @@ namespace AM2RLauncher CrossPlatformOperations.CopyOldConfigToNewConfig(); log.Info("Files extracted. Preparing to restart executable..."); - + + // TODO: This will fail if CWD is not where the launcher is located. Use absolute path here. if (OS.IsLinux) System.Diagnostics.Process.Start("chmod", "+x ./AM2RLauncher.Gtk"); System.Diagnostics.Process.Start(updatePath + "/" + CrossPlatformOperations.LAUNCHERNAME); @@ -219,4 +220,4 @@ namespace AM2RLauncher } } } -} \ No newline at end of file +} From fcdecbd36ce1e35987cef9c5566306cb4f537770 Mon Sep 17 00:00:00 2001 From: Miepee Date: Sat, 12 Feb 2022 15:56:23 +0100 Subject: [PATCH 10/17] Fix Linux failing to lanuch updated launcher --- AM2RLauncher/AM2RLauncher/LauncherUpdater.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/AM2RLauncher/AM2RLauncher/LauncherUpdater.cs b/AM2RLauncher/AM2RLauncher/LauncherUpdater.cs index ec26c08..c40d82a 100644 --- a/AM2RLauncher/AM2RLauncher/LauncherUpdater.cs +++ b/AM2RLauncher/AM2RLauncher/LauncherUpdater.cs @@ -14,7 +14,7 @@ namespace AM2RLauncher //TODO: Mac support for autoupdater in general public static class LauncherUpdater { - // How often this was broken count: 6 + // How often this was broken count: 7 // Auto updating is fun! /// The Version that identifies this current release. @@ -207,9 +207,7 @@ namespace AM2RLauncher CrossPlatformOperations.CopyOldConfigToNewConfig(); log.Info("Files extracted. Preparing to restart executable..."); - - // TODO: This will fail if CWD is not where the launcher is located. Use absolute path here. - if (OS.IsLinux) System.Diagnostics.Process.Start("chmod", "+x ./AM2RLauncher.Gtk"); + if (OS.IsLinux) System.Diagnostics.Process.Start("chmod", "+x " + updatePath + "./AM2RLauncher.Gtk"); System.Diagnostics.Process.Start(updatePath + "/" + CrossPlatformOperations.LAUNCHERNAME); Environment.Exit(0); @@ -220,4 +218,4 @@ namespace AM2RLauncher } } } -} +} \ No newline at end of file From 56cb5528ce8daecf9e2dc79c2dbcdd80e734773e Mon Sep 17 00:00:00 2001 From: Miepee Date: Sun, 13 Feb 2022 17:11:08 +0100 Subject: [PATCH 11/17] Move LoadProfiles and DeleteProfiles to backend --- AM2RLauncher/AM2RLauncher.Gtk/Program.cs | 2 +- AM2RLauncher/AM2RLauncher/LauncherUpdater.cs | 9 ++ .../AM2RLauncher/MainForm/MainForm.Events.cs | 40 +++---- .../MainForm/MainForm.StateMachine.cs | 93 +++------------- .../AM2RLauncher/MainForm/MainForm.UI.cs | 1 - AM2RLauncher/AM2RLauncherCore/Profile.cs | 105 +++++++++++++++++- 6 files changed, 149 insertions(+), 101 deletions(-) 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 . From 52dccdb73effd630483bfa27db4245f143285855 Mon Sep 17 00:00:00 2001 From: Miepee Date: Sun, 13 Feb 2022 21:00:22 +0100 Subject: [PATCH 12/17] Add basics of mod archival during updating --- .../AM2RLauncher/Language/Text.Designer.cs | 316 ++---------------- AM2RLauncher/AM2RLauncher/Language/Text.resx | 3 + .../AM2RLauncher/MainForm/MainForm.Events.cs | 303 ++++++++--------- .../MainForm/MainForm.StateMachine.cs | 9 +- AM2RLauncher/AM2RLauncherCore/Profile.cs | 63 +++- 5 files changed, 227 insertions(+), 467 deletions(-) diff --git a/AM2RLauncher/AM2RLauncher/Language/Text.Designer.cs b/AM2RLauncher/AM2RLauncher/Language/Text.Designer.cs index c4b1e8a..663b438 100644 --- a/AM2RLauncher/AM2RLauncher/Language/Text.Designer.cs +++ b/AM2RLauncher/AM2RLauncher/Language/Text.Designer.cs @@ -1,10 +1,9 @@ //------------------------------------------------------------------------------ // -// Dieser Code wurde von einem Tool generiert. -// Laufzeitversion:4.0.30319.42000 +// This code was generated by a tool. // -// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn -// der Code erneut generiert wird. +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. // //------------------------------------------------------------------------------ @@ -12,46 +11,32 @@ namespace AM2RLauncher.Language { using System; - /// - /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. - /// - // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert - // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert. - // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen - // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [System.Diagnostics.DebuggerNonUserCodeAttribute()] + [System.Runtime.CompilerServices.CompilerGeneratedAttribute()] public class Text { - private static global::System.Resources.ResourceManager resourceMan; + private static System.Resources.ResourceManager resourceMan; - private static global::System.Globalization.CultureInfo resourceCulture; + private static System.Globalization.CultureInfo resourceCulture; - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal Text() { } - /// - /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - public static global::System.Resources.ResourceManager ResourceManager { + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + public static System.Resources.ResourceManager ResourceManager { get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("AM2RLauncher.Language.Text", typeof(Text).Assembly); + if (object.Equals(null, resourceMan)) { + System.Resources.ResourceManager temp = new System.Resources.ResourceManager("AM2RLauncher.Language.Text", typeof(Text).Assembly); resourceMan = temp; } return resourceMan; } } - /// - /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle - /// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - public static global::System.Globalization.CultureInfo Culture { + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] + public static System.Globalization.CultureInfo Culture { get { return resourceCulture; } @@ -60,791 +45,532 @@ namespace AM2RLauncher.Language { } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die ABORT ähnelt. - /// public static string Abort { get { return ResourceManager.GetString("Abort", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die ADD NEW MOD ähnelt. - /// public static string AddNewMod { get { return ResourceManager.GetString("AddNewMod", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Select a mod to be installed. ähnelt. - /// public static string AddNewModToolTip { get { return ResourceManager.GetString("AddNewModToolTip", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Can't create an APK. ähnelt. - /// public static string ApkButtonDisabledToolTip { get { return ResourceManager.GetString("ApkButtonDisabledToolTip", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Create an APK for $NAME ähnelt. - /// public static string ApkButtonEnabledToolTip { get { return ResourceManager.GetString("ApkButtonEnabledToolTip", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die This is an archive of a previously installed Community Update. It cannot be re-installed and will remove itself if its game files are deleted. It shares saves with the currently installed Community Updates, so be sure to create a backup of your saves before running this profile! ähnelt. - /// public static string ArchiveNotes { get { return ResourceManager.GetString("ArchiveNotes", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Author(s): ähnelt. - /// public static string Author { get { return ResourceManager.GetString("Author", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Automatically update AM2R ähnelt. - /// public static string AutoUpdateAM2R { get { return ResourceManager.GetString("AutoUpdateAM2R", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Automatically update the AM2RLauncher ähnelt. - /// public static string AutoUpdateLauncher { get { return ResourceManager.GetString("AutoUpdateLauncher", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Changelog ähnelt. - /// public static string ChangelogTab { get { return ResourceManager.GetString("ChangelogTab", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Are you sure you want to cancel this now? This will delete all your progress! ähnelt. - /// public static string CloseOnCloningText { get { return ResourceManager.GetString("CloseOnCloningText", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Sorry, you can't close this while it's installing! Please wait until it's finished. ähnelt. - /// public static string CloseOnInstallingText { get { return ResourceManager.GetString("CloseOnInstallingText", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die There was a problem with your Patchdata folder. It has been deleted, please download it again. ähnelt. - /// public static string CorruptPatchData { get { return ResourceManager.GetString("CorruptPatchData", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die CREATE APK ähnelt. - /// public static string CreateAPK { get { return ResourceManager.GetString("CreateAPK", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die CREATING APK ähnelt. - /// public static string CreatingAPK { get { return ResourceManager.GetString("CreatingAPK", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Current profile: ähnelt. - /// public static string CurrentProfile { get { return ResourceManager.GetString("CurrentProfile", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Enter custom game environment variables: ähnelt. - /// public static string CustomEnvVarLabel { get { return ResourceManager.GetString("CustomEnvVarLabel", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Use custom download mirror ähnelt. - /// public static string CustomMirrorCheck { get { return ResourceManager.GetString("CustomMirrorCheck", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die $NAME couldn't be deleted. ähnelt. - /// public static string DeleteModButtonCantDelete { get { return ResourceManager.GetString("DeleteModButtonCantDelete", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die $NAME was successfully deleted! ähnelt. - /// public static string DeleteModButtonSuccess { get { return ResourceManager.GetString("DeleteModButtonSuccess", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die DELETE MOD ähnelt. - /// public static string DeleteModButtonText { get { return ResourceManager.GetString("DeleteModButtonText", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Delete $NAME. ähnelt. - /// public static string DeleteModButtonToolTip { get { return ResourceManager.GetString("DeleteModButtonToolTip", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die This will delete all files for $NAME. Are you sure you want to continue? ähnelt. - /// public static string DeleteModWarning { get { return ResourceManager.GetString("DeleteModWarning", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die The Official AM2R Discord ähnelt. - /// public static string DiscordToolTip { get { return ResourceManager.GetString("DiscordToolTip", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die DOWNLOAD ähnelt. - /// public static string Download { get { return ResourceManager.GetString("Download", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die DOWNLOADING ähnelt. - /// public static string Downloading { get { return ResourceManager.GetString("Downloading", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Download source: ähnelt. - /// public static string DownloadSource { get { return ResourceManager.GetString("DownloadSource", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Error ähnelt. - /// public static string ErrorWindowTitle { get { return ResourceManager.GetString("ErrorWindowTitle", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die The Community-Developers Github Page ähnelt. - /// public static string GithubToolTip { get { return ResourceManager.GetString("GithubToolTip", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Use high quality music when patching to Android ähnelt. - /// public static string HighQualityAndroid { get { return ResourceManager.GetString("HighQualityAndroid", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Use high quality music when patching to PC ähnelt. - /// public static string HighQualityPC { get { return ResourceManager.GetString("HighQualityPC", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die INSTALL ähnelt. - /// public static string Install { get { return ResourceManager.GetString("Install", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die INSTALLING ähnelt. - /// public static string Installing { get { return ResourceManager.GetString("Installing", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Couldn't establish an internet connection! Try again later! ähnelt. - /// public static string InternetConnectionDrop { get { return ResourceManager.GetString("InternetConnectionDrop", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die $NAME is an invalid git URL! ähnelt. - /// public static string InvalidGitURL { get { return ResourceManager.GetString("InvalidGitURL", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Java not found! Cannot generate an APK without a Java installation. Please make sure that Java is installed and added to PATH. ähnelt. - /// public static string JavaNotFound { get { return ResourceManager.GetString("JavaNotFound", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Launcher Language: (requires restart to take effect) ähnelt. - /// public static string LanguageNotice { get { return ResourceManager.GetString("LanguageNotice", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Settings ähnelt. - /// public static string LauncherSettingsTab { get { return ResourceManager.GetString("LauncherSettingsTab", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die GitHub (Primary) ähnelt. - /// public static string MirrorGithubText { get { return ResourceManager.GetString("MirrorGithubText", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die GitLab (Mirror) ähnelt. - /// public static string MirrorGitlabText { get { return ResourceManager.GetString("MirrorGitlabText", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die $NAME is already installed! ähnelt. - /// public static string ModIsAlreadyInstalledMessage { get { return ResourceManager.GetString("ModIsAlreadyInstalledMessage", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die $NAME cannot be installed! It's for $OS. Download the $CURRENTOS version instead if it exists, or ask the mod authors to make one. ähnelt. - /// public static string ModIsForWrongOS { get { return ResourceManager.GetString("ModIsForWrongOS", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die $NAME is an invalid AM2R mod! ähnelt. - /// public static string ModIsInvalidMessage { get { return ResourceManager.GetString("ModIsInvalidMessage", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die $NAME was successfully added! Go to the Play Tab in order to install it! ähnelt. - /// public static string ModSuccessfullyInstalledMessage { get { return ResourceManager.GetString("ModSuccessfullyInstalledMessage", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die News ähnelt. - /// public static string NewsTab { get { return ResourceManager.GetString("NewsTab", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Couldn't establish an internet connection! You can still play the game, but updates will not occur until the launcher is restarted and can connect to the internet. ähnelt. - /// public static string NoInternetConnection { get { return ResourceManager.GetString("NoInternetConnection", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die OPEN PROFILE FOLDER ähnelt. - /// public static string OpenProfileFolder { get { return ResourceManager.GetString("OpenProfileFolder", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Opens the folder where game files are located for $NAME. ähnelt. - /// public static string OpenProfileFolderToolTip { get { return ResourceManager.GetString("OpenProfileFolderToolTip", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die OPEN PROFILE SAVE FOLDER ähnelt. - /// public static string OpenSaveFolder { get { return ResourceManager.GetString("OpenSaveFolder", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Opens the folder where save files are located for $NAME. ähnelt. - /// public static string OpenSaveFolderToolTip { get { return ResourceManager.GetString("OpenSaveFolderToolTip", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die PLAY ähnelt. - /// public static string Play { get { return ResourceManager.GetString("Play", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Currently downloading . . . ähnelt. - /// public static string PlayButtonDownladingToolTip { get { return ResourceManager.GetString("PlayButtonDownladingToolTip", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Download the necessary patch files. ähnelt. - /// public static string PlayButtonDownloadToolTip { get { return ResourceManager.GetString("PlayButtonDownloadToolTip", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Currently installing. . . ähnelt. - /// public static string PlayButtonInstallingToolTip { get { return ResourceManager.GetString("PlayButtonInstallingToolTip", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Install $NAME ähnelt. - /// public static string PlayButtonInstallToolTip { get { return ResourceManager.GetString("PlayButtonInstallToolTip", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Currently already playing! ähnelt. - /// public static string PlayButtonPlayingToolTip { get { return ResourceManager.GetString("PlayButtonPlayingToolTip", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Play ähnelt. - /// public static string PlayButtonPlayToolTip { get { return ResourceManager.GetString("PlayButtonPlayToolTip", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Select your AM2R_1.1.zip ähnelt. - /// public static string PlayButtonSelect11ToolTip { get { return ResourceManager.GetString("PlayButtonSelect11ToolTip", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die PLAYING ähnelt. - /// public static string Playing { get { return ResourceManager.GetString("Playing", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Play ähnelt. - /// public static string PlayTab { get { return ResourceManager.GetString("PlayTab", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Create game debug logs ähnelt. - /// public static string ProfileDebugCheckBox { get { return ResourceManager.GetString("ProfileDebugCheckBox", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Profile notes: ähnelt. - /// public static string ProfileNotes { get { return ResourceManager.GetString("ProfileNotes", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Mod Settings ähnelt. - /// public static string ProfileSettingsTab { get { return ResourceManager.GetString("ProfileSettingsTab", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Progress: ähnelt. - /// public static string ProgressbarProgress { get { return ResourceManager.GetString("ProgressbarProgress", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die The Official AM2R Subreddit ähnelt. - /// public static string RedditToolTip { get { return ResourceManager.GetString("RedditToolTip", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die WARNING: This profile uses the default save location! This could corrupt your save data - please ensure that you have made a backup. ähnelt. - /// public static string SaveLocationWarning { get { return ResourceManager.GetString("SaveLocationWarning", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die SELECT AM2R_1.1.zip ähnelt. - /// public static string Select11 { get { return ResourceManager.GetString("Select11", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Select AM2R_1.1.zip ähnelt. - /// public static string Select11FileDialog { get { return ResourceManager.GetString("Select11FileDialog", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Select your Mod ähnelt. - /// public static string SelectModFileDialog { get { return ResourceManager.GetString("SelectModFileDialog", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Success ähnelt. - /// public static string SuccessWindowTitle { get { return ResourceManager.GetString("SuccessWindowTitle", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die System Language ähnelt. - /// public static string SystemLanguage { get { return ResourceManager.GetString("SystemLanguage", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Show Launcher ähnelt. - /// public static string TrayButtonShow { get { return ResourceManager.GetString("TrayButtonShow", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Can't access the Folder in order to download the update! Consider moving the program, or disabling auto-updates. ähnelt. - /// public static string UnauthorizedAccessMessage { get { return ResourceManager.GetString("UnauthorizedAccessMessage", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Unhandled Exception has occured in your Application. ähnelt. - /// public static string UnhandledException { get { return ResourceManager.GetString("UnhandledException", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Select Mod Update ähnelt. - /// public static string UpdateMod { get { return ResourceManager.GetString("UpdateMod", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die UPDATE MOD ähnelt. - /// public static string UpdateModButtonText { get { return ResourceManager.GetString("UpdateModButtonText", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Select a zip to update $NAME. ähnelt. - /// public static string UpdateModButtonToolTip { get { return ResourceManager.GetString("UpdateModButtonToolTip", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Can't update $NAME with $SELECT. Add $SELECT as a new mod instead! ähnelt. - /// public static string UpdateModButtonWrongMod { get { return ResourceManager.GetString("UpdateModButtonWrongMod", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die This will replace all files for $NAME with the selected new version. Are you sure you want to continue? ähnelt. - /// public static string UpdateModWarning { get { return ResourceManager.GetString("UpdateModWarning", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Version: ähnelt. - /// public static string VersionLabel { get { return ResourceManager.GetString("VersionLabel", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die OK ähnelt. - /// public static string WarningWindowOk { get { return ResourceManager.GetString("WarningWindowOk", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die The AM2RLauncher can NOT validate custom mirror links. - /// - ///If somebody is telling you to paste a link in this field, they may be trying to infect your computer. - /// - ///Proceed with caution. ähnelt. - /// public static string WarningWindowText { get { return ResourceManager.GetString("WarningWindowText", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die WARNING ähnelt. - /// public static string WarningWindowTitle { get { return ResourceManager.GetString("WarningWindowTitle", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Xdelta not found! Cannot install Profiles without it. Please install xdelta3 from your local package manager. ähnelt. - /// public static string XdeltaNotFound { get { return ResourceManager.GetString("XdeltaNotFound", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die The Community-Developers YouTube Channel ähnelt. - /// public static string YoutubeToolTip { get { return ResourceManager.GetString("YoutubeToolTip", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die Zip Archives (*.zip) ähnelt. - /// public static string ZipArchiveText { get { return ResourceManager.GetString("ZipArchiveText", resourceCulture); } } - /// - /// Sucht eine lokalisierte Zeichenfolge, die The selected Zip is not AM2R 1.1! Please choose another Zip file. ähnelt. - /// public static string ZipIsNotAM2R11 { get { return ResourceManager.GetString("ZipIsNotAM2R11", resourceCulture); } } + + public static string ArchiveMod { + get { + return ResourceManager.GetString("ArchiveMod", resourceCulture); + } + } } } diff --git a/AM2RLauncher/AM2RLauncher/Language/Text.resx b/AM2RLauncher/AM2RLauncher/Language/Text.resx index 1ba47a2..7b98fb9 100644 --- a/AM2RLauncher/AM2RLauncher/Language/Text.resx +++ b/AM2RLauncher/AM2RLauncher/Language/Text.resx @@ -382,4 +382,7 @@ Proceed with caution. The selected Zip is not AM2R 1.1! Please choose another Zip file. + + Do you want to archive $NAME? + \ No newline at end of file diff --git a/AM2RLauncher/AM2RLauncher/MainForm/MainForm.Events.cs b/AM2RLauncher/AM2RLauncher/MainForm/MainForm.Events.cs index 53adf08..aa49ac9 100644 --- a/AM2RLauncher/AM2RLauncher/MainForm/MainForm.Events.cs +++ b/AM2RLauncher/AM2RLauncher/MainForm/MainForm.Events.cs @@ -104,46 +104,8 @@ namespace AM2RLauncher if (currentXML.Version != profileList[0].Version) { log.Info("New game version (" + profileList[0].Version + ") detected! Beginning archival of version " + currentXML.Version + "..."); - - string profileArchivePath = CrossPlatformOperations.CURRENTPATH + "/Profiles/Community Updates (" + currentXML.Version + ")"; - - // Do NOT overwrite if a path with this name already exists! It is likely an existing user archive. - if (!Directory.Exists(profileArchivePath)) - { - // Rename current Community Updates - Directory.Move(CrossPlatformOperations.CURRENTPATH + "/Profiles/Community Updates (Latest)", profileArchivePath); - - currentXML.Name = "Community Updates (" + currentXML.Version + ")"; - - // Set as non-installable so that it's just treated as a launching reference - currentXML.Installable = false; - currentXML.SupportsAndroid = false; - - string modArchivePath = CrossPlatformOperations.CURRENTPATH + "/Mods/" + currentXML.Name; - - // Do NOT overwrite if a path with this name already exists! It is likely an existing user archive. - if (!Directory.Exists(modArchivePath)) - { - Directory.CreateDirectory(modArchivePath); - File.WriteAllText(modArchivePath + "/profile.xml", Serializer.Serialize(currentXML)); - log.Info("Finished archival."); - } - else - { - HelperMethods.DeleteDirectory(profileArchivePath); - log.Info("Cancelling archival! User-defined archive in Mods already exists."); - } - - - } - 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. - { - HelperMethods.DeleteDirectory(CrossPlatformOperations.CURRENTPATH + "/Profiles/Community Updates (Latest)"); - log.Info("Cancelling archival! User-defined archive in Profiles already exists."); - } - + Profile.ArchiveProfile(currentXML); profileDropDown.SelectedIndex = 0; - LoadProfilesAndAdjustLists(); } } @@ -540,8 +502,6 @@ namespace AM2RLauncher { log.Info("User requested to add mod. Requesting user input for new mod .zip..."); - ProfileXML addedProfile; - OpenFileDialog fileFinder = new OpenFileDialog { Directory = new Uri(CrossPlatformOperations.CURRENTPATH), @@ -557,84 +517,81 @@ namespace AM2RLauncher return; } - if (!String.IsNullOrWhiteSpace(fileFinder.FileName)) // This is default + if (String.IsNullOrWhiteSpace(fileFinder.FileName)) { - log.Info("User selected \"" + fileFinder.FileName + "\""); - - // If either a directory was selected or the file somehow went missing, cancel - if (!File.Exists(fileFinder.FileName)) - { - log.Error("Selected mod .zip file not found! Cancelling import."); - return; - } - - FileInfo modFile = new FileInfo(fileFinder.FileName); + log.Error("User did not supply valid input. Cancelling import."); + LoadProfilesAndAdjustLists(); + return; + } - string modsDir = new DirectoryInfo(CrossPlatformOperations.CURRENTPATH + "/Mods").FullName; - string extractedName = modFile.Name.Replace(".zip", ""); + log.Info("User selected \"" + fileFinder.FileName + "\""); - // Extract it and see if it contains a profile.xml. If not, this is invalid + // If either a directory was selected or the file somehow went missing, cancel + if (!File.Exists(fileFinder.FileName)) + { + log.Error("Selected mod .zip file not found! Cancelling import."); + return; + } - // Check first, if the directory is already there, if yes, throw a message - if (Directory.Exists(modsDir + "/" + extractedName)) - { - ProfileXML profile2 = Serializer.Deserialize(File.ReadAllText(modsDir + "/" + extractedName + "/profile.xml")); - log.Error("Mod is already imported as " + extractedName + "! Cancelling mod import."); + FileInfo modFile = new FileInfo(fileFinder.FileName); - MessageBox.Show(Language.Text.ModIsAlreadyInstalledMessage.Replace("$NAME", profile2.Name), Language.Text.WarningWindowTitle, MessageBoxType.Warning); - return; - } - // Directory doesn't exist -> extract! - ZipFile.ExtractToDirectory(fileFinder.FileName, modsDir + "/" + extractedName); - log.Info("Imported and extracted mod .zip as " + extractedName); + string modsDir = new DirectoryInfo(CrossPlatformOperations.CURRENTPATH + "/Mods").FullName; + string extractedName = modFile.Name.Replace(".zip", ""); - // Let's check if profile.xml exists in there! If it doesn't throw an error and cleanup - if (!File.Exists(modsDir + "/" + extractedName + "/profile.xml")) - { - log.Error(fileFinder.FileName + " does not contain profile.xml! Cancelling mod import."); + // Extract it and see if it contains a profile.xml. If not, this is invalid - MessageBox.Show(Language.Text.ModIsInvalidMessage.Replace("$NAME", extractedName), Language.Text.ErrorWindowTitle, MessageBoxType.Error); - Directory.Delete(modsDir + "/" + extractedName, true); - File.Delete(CrossPlatformOperations.CURRENTPATH + "/Mods/" + modFile.Name); - return; - } + // Check first, if the directory is already there, if yes, throw a message + if (Directory.Exists(modsDir + "/" + extractedName)) + { + ProfileXML profile2 = Serializer.Deserialize(File.ReadAllText(modsDir + "/" + extractedName + "/profile.xml")); + log.Error("Mod is already imported as " + extractedName + "! Cancelling mod import."); - ProfileXML profile = Serializer.Deserialize(File.ReadAllText(modsDir + "/" + extractedName + "/profile.xml")); + MessageBox.Show(Language.Text.ModIsAlreadyInstalledMessage.Replace("$NAME", profile2.Name), Language.Text.WarningWindowTitle, MessageBoxType.Warning); + return; + } + // Directory doesn't exist -> extract! + ZipFile.ExtractToDirectory(fileFinder.FileName, modsDir + "/" + extractedName); + log.Info("Imported and extracted mod .zip as " + extractedName); - // Check if the OS versions match - if (OS.Name != profile.OperatingSystem) - { - log.Error("Mod is for " + profile.OperatingSystem + " while current OS is " + OS.Name + ". Cancelling mod import."); + // Let's check if profile.xml exists in there! If it doesn't throw an error and cleanup + if (!File.Exists(modsDir + "/" + extractedName + "/profile.xml")) + { + log.Error(fileFinder.FileName + " does not contain profile.xml! Cancelling mod import."); - MessageBox.Show(Language.Text.ModIsForWrongOS.Replace("$NAME", profile.Name).Replace("$OS", profile.OperatingSystem).Replace("$CURRENTOS", OS.Name), - Language.Text.ErrorWindowTitle, MessageBoxType.Error); - HelperMethods.DeleteDirectory(modsDir + "/" + extractedName); - return; - } + MessageBox.Show(Language.Text.ModIsInvalidMessage.Replace("$NAME", extractedName), Language.Text.ErrorWindowTitle, MessageBoxType.Error); + Directory.Delete(modsDir + "/" + extractedName, true); + File.Delete(CrossPlatformOperations.CURRENTPATH + "/Mods/" + modFile.Name); + return; + } - // Check by *name*, if the mod was installed already - if (profileList.FirstOrDefault(p => p.Name == profile.Name) != null || Directory.Exists(CrossPlatformOperations.CURRENTPATH + "/Profiles/" + profile.Name)) - { - log.Error(profile.Name + " is already installed."); - MessageBox.Show(Language.Text.ModIsAlreadyInstalledMessage.Replace("$NAME", profile.Name), Language.Text.WarningWindowTitle, MessageBoxType.Warning); - HelperMethods.DeleteDirectory(modsDir + "/" + extractedName); - return; - } + ProfileXML profile = Serializer.Deserialize(File.ReadAllText(modsDir + "/" + extractedName + "/profile.xml")); - addedProfile = profile; - log.Info(profile.Name + " successfully installed."); - MessageBox.Show(Language.Text.ModSuccessfullyInstalledMessage.Replace("$NAME", profile.Name), Language.Text.SuccessWindowTitle); + // Check if the OS versions match + if (OS.Name != profile.OperatingSystem) + { + log.Error("Mod is for " + profile.OperatingSystem + " while current OS is " + OS.Name + ". Cancelling mod import."); + MessageBox.Show(Language.Text.ModIsForWrongOS.Replace("$NAME", profile.Name).Replace("$OS", profile.OperatingSystem).Replace("$CURRENTOS", OS.Name), + Language.Text.ErrorWindowTitle, MessageBoxType.Error); + HelperMethods.DeleteDirectory(modsDir + "/" + extractedName); + return; } - else + + // Check by *name*, if the mod was installed already + if (profileList.FirstOrDefault(p => p.Name == profile.Name) != null || Directory.Exists(CrossPlatformOperations.CURRENTPATH + "/Profiles/" + profile.Name)) { - log.Error("User did not supply valid input. Cancelling import."); - LoadProfilesAndAdjustLists(); + log.Error(profile.Name + " is already installed."); + MessageBox.Show(Language.Text.ModIsAlreadyInstalledMessage.Replace("$NAME", profile.Name), Language.Text.WarningWindowTitle, MessageBoxType.Warning); + HelperMethods.DeleteDirectory(modsDir + "/" + extractedName); return; } + log.Info(profile.Name + " successfully installed."); + MessageBox.Show(Language.Text.ModSuccessfullyInstalledMessage.Replace("$NAME", profile.Name), Language.Text.SuccessWindowTitle); + LoadProfilesAndAdjustLists(); - settingsProfileDropDown.SelectedIndex = profileList.FindIndex(p => p.Name == addedProfile.Name); + // Adjust profileIndex to point to newly added mod. if its not found for whatever reason, we default to first community updates + settingsProfileDropDown.SelectedIndex = profileList.FindIndex(p => p.Name == profile.Name); if (settingsProfileDropDown.SelectedIndex == -1) settingsProfileDropDown.SelectedIndex = 0; } @@ -682,7 +639,8 @@ namespace AM2RLauncher { deleteModButton.Enabled = true; deleteModButton.ToolTip = Language.Text.DeleteModButtonToolTip.Replace("$NAME", settingsProfileDropDown.Items[settingsProfileDropDown.SelectedIndex].Text); - updateModButton.Enabled = true; + // On non-installable profiles we want to disable updating + updateModButton.Enabled = profileList[settingsProfileDropDown.SelectedIndex].Installable; updateModButton.ToolTip = Language.Text.UpdateModButtonToolTip.Replace("$NAME", settingsProfileDropDown.Items[settingsProfileDropDown.SelectedIndex].Text); } @@ -979,88 +937,111 @@ namespace AM2RLauncher return; } - if (!String.IsNullOrWhiteSpace(fileFinder.FileName)) // This is default + // Exit if nothing was selected + if (String.IsNullOrWhiteSpace(fileFinder.FileName)) { - log.Info("User selected \"" + fileFinder.FileName + "\""); + log.Info("Nothing was selected, cancelling mod update."); + LoadProfilesAndAdjustLists(); + return; + } - // If either a directory was selected or the file somehow went missing, cancel - if (!File.Exists(fileFinder.FileName)) - { - log.Error("Selected mod .zip file not found! Cancelling mod update."); - return; - } + log.Info("User selected \"" + fileFinder.FileName + "\""); - FileInfo modFile = new FileInfo(fileFinder.FileName); + // If either a directory was selected or the file somehow went missing, cancel + if (!File.Exists(fileFinder.FileName)) + { + log.Error("Selected mod .zip file not found! Cancelling mod update."); + return; + } - string modsDir = new DirectoryInfo(CrossPlatformOperations.CURRENTPATH + "/Mods").FullName; - string extractedName = modFile.Name.Replace(".zip", "_new"); + FileInfo modFile = new FileInfo(fileFinder.FileName); - // Extract it and see if it contains a profile.xml. If not, this is invalid + string modsDir = new DirectoryInfo(CrossPlatformOperations.CURRENTPATH + "/Mods").FullName; + string extractedName = modFile.Name.Replace(".zip", "_new"); + string extractedFolder = modsDir + "/" + extractedName; - // Directory doesn't exist -> extract! - ZipFile.ExtractToDirectory(fileFinder.FileName, modsDir + "/" + extractedName); + // Extract it and see if it contains a profile.xml. If not, this is invalid - // Let's check if profile.xml exists in there! If it doesn't throw an error and cleanup - if (!File.Exists(modsDir + "/" + extractedName + "/profile.xml")) - { - log.Error(fileFinder.FileName + " does not contain profile.xml! Cancelling mod update."); - MessageBox.Show(Language.Text.ModIsInvalidMessage.Replace("$NAME", extractedName), Language.Text.ErrorWindowTitle, MessageBoxType.Error); - Directory.Delete(modsDir + "/" + extractedName, true); - File.Delete(CrossPlatformOperations.CURRENTPATH + "/Mods/" + modFile.Name); - return; - } + // If for some reason old files remain, delete them + if (Directory.Exists(extractedFolder)) + Directory.Delete(extractedFolder, true); - // Check by *name*, if the mod was installed already - ProfileXML profile = Serializer.Deserialize(File.ReadAllText(modsDir + "/" + extractedName + "/profile.xml")); + // Directory doesn't exist -> extract! + ZipFile.ExtractToDirectory(fileFinder.FileName, extractedFolder); - if (profileList.FirstOrDefault(p => p.Name == profile.Name) != null || Directory.Exists(CrossPlatformOperations.CURRENTPATH + "/Profiles/" + profile.Name)) - { - // Mod is already installed, so we can update! - DialogResult result = MessageBox.Show(Language.Text.UpdateModWarning.Replace("$NAME", currentProfile.Name), Language.Text.WarningWindowTitle, - MessageBoxButtons.OKCancel, MessageBoxType.Warning, MessageBoxDefaultButton.Cancel); + // Let's check if profile.xml exists in there! If it doesn't throw an error and cleanup + if (!File.Exists(extractedFolder + "/profile.xml")) + { + log.Error(fileFinder.FileName + " does not contain profile.xml! Cancelling mod update."); + MessageBox.Show(Language.Text.ModIsInvalidMessage.Replace("$NAME", extractedName), Language.Text.ErrorWindowTitle, MessageBoxType.Error); + Directory.Delete(extractedFolder, true); + File.Delete(CrossPlatformOperations.CURRENTPATH + "/Mods/" + modFile.Name); + return; + } - if (result == DialogResult.Ok) - { - // Delete profile - DeleteProfileAndAdjustLists(currentProfile); + // Check by *name*, if the mod was installed already + ProfileXML profile = Serializer.Deserialize(File.ReadAllText(extractedFolder + "/profile.xml")); - // Rename directory to take the old one's place - string originalFolder = modsDir + "/" + extractedName.Replace("_new", ""); - Directory.Move(modsDir + "/" + extractedName, originalFolder); + if (profileList.FirstOrDefault(p => p.Name == profile.Name) != null || Directory.Exists(CrossPlatformOperations.CURRENTPATH + "/Profiles/" + profile.Name)) + { + // Mod is already installed, so we can update! + DialogResult updateResult = MessageBox.Show(Language.Text.UpdateModWarning.Replace("$NAME", currentProfile.Name), Language.Text.WarningWindowTitle, + MessageBoxButtons.OKCancel, MessageBoxType.Warning, MessageBoxDefaultButton.Cancel); - } - else // Cancel the operation! + if (updateResult == DialogResult.Ok) + { + // If the profile isn't installed, don't ask about archiving it + if (Profile.IsProfileInstalled(currentProfile)) { - log.Error("User has cancelled mod update!"); - abort = true; + //TODO: localize + DialogResult archiveResult = MessageBox.Show(Language.Text.ArchiveMod.Replace("$NAME", currentProfile.Name + " " + Language.Text.VersionLabel + currentProfile.Version), Language.Text.WarningWindowTitle, MessageBoxButtons.YesNo, MessageBoxType.Warning, MessageBoxDefaultButton.No); + + // User wants to archive profile + if (archiveResult == DialogResult.Yes) + { + ArchiveProfileAndAdjustLists(currentProfile); + DeleteProfileAndAdjustLists(currentProfile); + } } + // No archiving, Delete profile instead + else + DeleteProfileAndAdjustLists(currentProfile); + + // Rename directory to take the old one's place + string originalFolder = modsDir + "/" + extractedName.Replace("_new", ""); + Directory.Move(extractedFolder, originalFolder); } - else + else // Cancel the operation! { - // Cancel the operation! - // Show message to tell user that mod could not be found, install this separately - log.Error("Mod is not installed! Cancelling mod update."); - MessageBox.Show(Language.Text.UpdateModButtonWrongMod.Replace("$NAME", currentProfile.Name).Replace("$SELECT", profile.Name), - Language.Text.WarningWindowTitle, MessageBoxButtons.OK); + log.Error("User has cancelled mod update!"); abort = true; } + } + else + { + // Cancel the operation! + // Show message to tell user that mod could not be found, install this separately + log.Error("Mod is not installed! Cancelling mod update."); + MessageBox.Show(Language.Text.UpdateModButtonWrongMod.Replace("$NAME", currentProfile.Name).Replace("$SELECT", profile.Name), + Language.Text.WarningWindowTitle, MessageBoxButtons.OK); + abort = true; + } - if (abort) - { - // File cleanup - HelperMethods.DeleteDirectory(modsDir + "/" + extractedName); - LoadProfilesAndAdjustLists(); - return; - } - - log.Info("Successfully updated mod profile " + profile.Name + "."); - MessageBox.Show(Language.Text.ModSuccessfullyInstalledMessage.Replace("$NAME", currentProfile.Name), Language.Text.SuccessWindowTitle); - UpdateStateMachine(); + if (abort) + { + // File cleanup + HelperMethods.DeleteDirectory(extractedFolder); + LoadProfilesAndAdjustLists(); + return; } - ProfileXML currentSelectedProfile = profileList[settingsProfileDropDown.SelectedIndex]; + log.Info("Successfully updated mod profile " + profile.Name + "."); + MessageBox.Show(Language.Text.ModSuccessfullyInstalledMessage.Replace("$NAME", currentProfile.Name), Language.Text.SuccessWindowTitle); + UpdateStateMachine(); + LoadProfilesAndAdjustLists(); - settingsProfileDropDown.SelectedIndex = profileList.FindIndex(p => p.Name == currentSelectedProfile.Name); + + settingsProfileDropDown.SelectedIndex = profileList.FindIndex(p => p.Name == currentProfile.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 733f02b..382c791 100644 --- a/AM2RLauncher/AM2RLauncher/MainForm/MainForm.StateMachine.cs +++ b/AM2RLauncher/AM2RLauncher/MainForm/MainForm.StateMachine.cs @@ -285,7 +285,8 @@ namespace AM2RLauncher { // Archive version notes if (!profile.Installable) - profile.ProfileNotes = Language.Text.ArchiveNotes; + //TODO: have different text for non-community archive + profile.ProfileNotes = Language.Text.ArchiveNotes + "\n\n" + profile.ProfileNotes; profileDropDown.Items.Add(profile.Name); } @@ -337,5 +338,11 @@ namespace AM2RLauncher Profile.DeleteProfile(profile); LoadProfilesAndAdjustLists(); } + + private void ArchiveProfileAndAdjustLists(ProfileXML profile) + { + Profile.ArchiveProfile(profile); + LoadProfilesAndAdjustLists(); + } } } \ No newline at end of file diff --git a/AM2RLauncher/AM2RLauncherCore/Profile.cs b/AM2RLauncher/AM2RLauncherCore/Profile.cs index 5142580..7c16c87 100644 --- a/AM2RLauncher/AM2RLauncherCore/Profile.cs +++ b/AM2RLauncher/AM2RLauncherCore/Profile.cs @@ -45,12 +45,6 @@ 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. /// @@ -131,10 +125,6 @@ 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. @@ -187,6 +177,59 @@ public static class Profile return profileList; } + /// + /// Archives a given Profile by making a copy with "Name (version)". Does silently nothing if user archives already exist + /// + /// The profile to archive + public static void ArchiveProfile(ProfileXML profile) + { + // temporarily serialize and deserialize to essentially "clone" the variable as otherwise we'd modify references + File.WriteAllText(Path.GetTempPath() + "/" + profile.Name, Serializer.Serialize(profile)); + profile = Serializer.Deserialize(File.ReadAllText(Path.GetTempPath() + "/" + profile.Name)); + + string originalName = profile.Name; + // Change name to include version and be unique + profile.Name += " (" + profile.Version + ")"; + // if we're archiving community updates, remove the "latest" part + profile.Name = profile.Name.Replace("Community Updates Latest", "Community Updates"); + + log.Info("Archiving " + profile.Name); + + string profileArchivePath = CrossPlatformOperations.CURRENTPATH + "/Profiles/" + profile.Name; + + // Do NOT overwrite if a path with this name already exists! It is likely an existing user archive. + if (!Directory.Exists(profileArchivePath)) + { + // Rename current profile if we have it installed + if (Directory.Exists(CrossPlatformOperations.CURRENTPATH + "/Profiles/" + originalName)) + Directory.Move(CrossPlatformOperations.CURRENTPATH + "/Profiles/" + originalName, profileArchivePath); + + // Set as non-installable so that it's just treated as a launching reference + profile.Installable = false; + + string modArchivePath = CrossPlatformOperations.CURRENTPATH + "/Mods/" + profile.Name; + + // Do NOT overwrite if a path with this name already exists! It is likely an existing user archive. + if (!Directory.Exists(modArchivePath)) + { + Directory.CreateDirectory(modArchivePath); + File.WriteAllText(modArchivePath + "/profile.xml", Serializer.Serialize(profile)); + log.Info("Finished archival."); + } + else + { + HelperMethods.DeleteDirectory(profileArchivePath); + log.Info("Cancelling archival! User-defined archive in Mods already exists."); + } + } + // If our desired rename already exists, it's probably a user archive... so we just delete the original folder and move on with installation of the new version. + else + { + HelperMethods.DeleteDirectory(CrossPlatformOperations.CURRENTPATH + "/Profiles/" + originalName); + log.Info("Cancelling archival! User-defined archive in Profiles already exists."); + } + } + /// /// Deletes a profile from the Mods and Profiles folder. /// From 611614e694ffa40efd4b46667c089a897fb642c7 Mon Sep 17 00:00:00 2001 From: Miepee Date: Sun, 13 Feb 2022 21:54:35 +0100 Subject: [PATCH 13/17] fixed some bugs of mod archival + first batch of localizations --- AM2RLauncher/AM2RLauncher/Language/Text.Designer.cs | 10 ++++++++-- AM2RLauncher/AM2RLauncher/Language/Text.de.resx | 8 +++++++- AM2RLauncher/AM2RLauncher/Language/Text.es.resx | 8 +++++++- AM2RLauncher/AM2RLauncher/Language/Text.fr.resx | 8 +++++++- AM2RLauncher/AM2RLauncher/Language/Text.it.resx | 8 +++++++- AM2RLauncher/AM2RLauncher/Language/Text.ja.resx | 2 +- AM2RLauncher/AM2RLauncher/Language/Text.pt.resx | 8 +++++++- AM2RLauncher/AM2RLauncher/Language/Text.resx | 5 ++++- AM2RLauncher/AM2RLauncher/Language/Text.ru.resx | 8 +++++++- AM2RLauncher/AM2RLauncher/Language/Text.zh-Hans.resx | 2 +- AM2RLauncher/AM2RLauncher/MainForm/MainForm.Events.cs | 8 ++------ .../AM2RLauncher/MainForm/MainForm.StateMachine.cs | 11 ++++++++--- 12 files changed, 66 insertions(+), 20 deletions(-) diff --git a/AM2RLauncher/AM2RLauncher/Language/Text.Designer.cs b/AM2RLauncher/AM2RLauncher/Language/Text.Designer.cs index 663b438..cf7163b 100644 --- a/AM2RLauncher/AM2RLauncher/Language/Text.Designer.cs +++ b/AM2RLauncher/AM2RLauncher/Language/Text.Designer.cs @@ -75,9 +75,9 @@ namespace AM2RLauncher.Language { } } - public static string ArchiveNotes { + public static string ArchiveNotesCommunityUpdates { get { - return ResourceManager.GetString("ArchiveNotes", resourceCulture); + return ResourceManager.GetString("ArchiveNotesCommunityUpdates", resourceCulture); } } @@ -572,5 +572,11 @@ namespace AM2RLauncher.Language { return ResourceManager.GetString("ArchiveMod", resourceCulture); } } + + public static string ArchiveNotesMods { + get { + return ResourceManager.GetString("ArchiveNotesMods", resourceCulture); + } + } } } diff --git a/AM2RLauncher/AM2RLauncher/Language/Text.de.resx b/AM2RLauncher/AM2RLauncher/Language/Text.de.resx index a722913..7afcf65 100644 --- a/AM2RLauncher/AM2RLauncher/Language/Text.de.resx +++ b/AM2RLauncher/AM2RLauncher/Language/Text.de.resx @@ -132,7 +132,7 @@ APK erstellen für $NAME - + Dies ist ein Archiv eines vorher installierten Community-Updates. Es kann nicht erneut installiert werden und wird automatisch entfernt wenn die archivierten Spieldaten gelöscht werden. Die Speicherstände sind allerdings weiterhin die aktuellen, bitte sicherheitshalber ein Backup anlegen vor dem benutzen dieses Profils! @@ -380,4 +380,10 @@ Bitte äußerste Vorsicht walten lassen. Das ausgewählte Zip-Archiv ist nicht AM2R 1.1 oder falsch geformt! Bitte ein anderes Archiv auswählen. + + $NAME archivieren? + + + Dies ist ein Archiv einer vorher installierten Mod. Es kann nicht erneut installiert werden und wird automatisch entfernt wenn die archivierten Spieldaten gelöscht werden. + \ No newline at end of file diff --git a/AM2RLauncher/AM2RLauncher/Language/Text.es.resx b/AM2RLauncher/AM2RLauncher/Language/Text.es.resx index e3a91d5..e87658f 100644 --- a/AM2RLauncher/AM2RLauncher/Language/Text.es.resx +++ b/AM2RLauncher/AM2RLauncher/Language/Text.es.resx @@ -132,7 +132,7 @@ Crear un APK para $NAME - + Esto es una copia de la Actualización de la Comunidad instalada previamente. No puede ser reinstalada y se eliminará automáticamente si se borran sus archivos de juego. Comparte las partidas guardadas con la Actualización de la Comunidad instalada actualmente, ¡así que asegúrate de crear una copia de seguridad de tus partidas antes de ejecutar este perfil! @@ -380,4 +380,10 @@ Procede con cautela. ¡El Zip seleccionado no es AM2R_1.1! Por favor elige otro archivo Zip. + + ¿Deseas archivar $NAME? + + + Esta es una versión archivada de un Mod instalado anteriormente. No puede ser reinstalada y se eliminará automáticamente si se borran sus archivos de juego. + \ No newline at end of file diff --git a/AM2RLauncher/AM2RLauncher/Language/Text.fr.resx b/AM2RLauncher/AM2RLauncher/Language/Text.fr.resx index 7603b52..ce46b2c 100644 --- a/AM2RLauncher/AM2RLauncher/Language/Text.fr.resx +++ b/AM2RLauncher/AM2RLauncher/Language/Text.fr.resx @@ -132,7 +132,7 @@ Créer un APK pour $NAME - + Il s'agit d'une archive d'une mise à jour communautaire précédemment installée. Elle ne peut pas être réinstallée et se supprimera d'elle-même si ses fichiers de jeu sont supprimés. Elle partage des sauvegardes avec la mise à jour actuellement installée, donc assurez-vous de faire une sauvegarde de celles-ci avant de lancer ce profil ! @@ -382,4 +382,10 @@ Soyez prudent. Le Zip sélectionné n'est pas AM2R 1.1 ! Veuillez choisir un autre fichier Zip. + + Archive $NAME ? + + + Il s'agit d'une archive d'un mod précédemment installé. Il ne peut pas être réinstallé et se supprimera de lui-même si ses fichiers de jeu sont supprimés. + \ No newline at end of file diff --git a/AM2RLauncher/AM2RLauncher/Language/Text.it.resx b/AM2RLauncher/AM2RLauncher/Language/Text.it.resx index 6e2c5df..a2b4aab 100644 --- a/AM2RLauncher/AM2RLauncher/Language/Text.it.resx +++ b/AM2RLauncher/AM2RLauncher/Language/Text.it.resx @@ -132,7 +132,7 @@ Crea un APK per $NAME - + Questo è un archivio di un Aggiornamento Comunità installato in precedenza. Non può essere reinstallato e si rimuoverà da solo se i file di gioco saranno cancellati. Condivide i salvataggi con gli Aggiornamenti Comunità, quindi assicurati di creare un backup dei tuoi salvataggi prima di usare questo profilo! @@ -380,4 +380,10 @@ Procedi con cautela. Il Zip selezionato non è AM2R 1.1! Perfavore scegli un altro file Zip. + + Vuoi archiviare $NAME? + + + Questo è un archivio di una Mod precedentemente installata. Non può essere re-installata e si rimuoverà da sola se i suoi file di gioco vengono rimossi. + \ No newline at end of file diff --git a/AM2RLauncher/AM2RLauncher/Language/Text.ja.resx b/AM2RLauncher/AM2RLauncher/Language/Text.ja.resx index 75b7507..979a297 100644 --- a/AM2RLauncher/AM2RLauncher/Language/Text.ja.resx +++ b/AM2RLauncher/AM2RLauncher/Language/Text.ja.resx @@ -132,7 +132,7 @@ 次のAPKを作成します: $NAME - + これは以前インストールされたCommunity Updateのアーカイブです。再インストールはできませんし、ゲームファイルが削除されると自動的に削除されます。現在インストールされているCommunity Updateとセーブデータを共有しているため、このプロファイルを実行する前に必ずセーブデータのバックアップを作成してください diff --git a/AM2RLauncher/AM2RLauncher/Language/Text.pt.resx b/AM2RLauncher/AM2RLauncher/Language/Text.pt.resx index 8c29746..b790b60 100644 --- a/AM2RLauncher/AM2RLauncher/Language/Text.pt.resx +++ b/AM2RLauncher/AM2RLauncher/Language/Text.pt.resx @@ -132,7 +132,7 @@ Criar um APK para $NAME - + Isto é um arquivo de uma Atualização da Comunidade instalada previamente. Não é possível reinstalá-la e ela será removida automaticamente quando seus arquivos de jogo forem deletados. Os arquivos de save são compartilhados com a Atualização da Comunidade que está instalada no momento, então faça um backup de seus saves antes de executar este perfil! @@ -380,4 +380,10 @@ Prossiga com cuidado. O arquivo Zip selecionado não contém o AM2R 1.1! Por favor, selecione outro arquivo Zip + + Deseja arquivar $NAME? + + + Isso é uma versão arquivada de um Mod previamente instalado. Ele não pode ser reinstalado e será removido se seus arquivos de jogo forem deletados. + \ No newline at end of file diff --git a/AM2RLauncher/AM2RLauncher/Language/Text.resx b/AM2RLauncher/AM2RLauncher/Language/Text.resx index 7b98fb9..85a2c55 100644 --- a/AM2RLauncher/AM2RLauncher/Language/Text.resx +++ b/AM2RLauncher/AM2RLauncher/Language/Text.resx @@ -132,7 +132,7 @@ Create an APK for $NAME - + This is an archive of a previously installed Community Update. It cannot be re-installed and will remove itself if its game files are deleted. It shares saves with the currently installed Community Updates, so be sure to create a backup of your saves before running this profile! @@ -385,4 +385,7 @@ Proceed with caution. Do you want to archive $NAME? + + This is an archive of a previously installed Mod. It cannot be re-installed and will remove itself if its game files are deleted. + \ No newline at end of file diff --git a/AM2RLauncher/AM2RLauncher/Language/Text.ru.resx b/AM2RLauncher/AM2RLauncher/Language/Text.ru.resx index 671b52a..9059258 100644 --- a/AM2RLauncher/AM2RLauncher/Language/Text.ru.resx +++ b/AM2RLauncher/AM2RLauncher/Language/Text.ru.resx @@ -132,7 +132,7 @@ Создать APK-файл для $NAME - + Этот архив содержит ранее установленное обновление сообщества. Оно не может быть переустановлено и автоматически удалится при удалении файлов игры. Оно имеет общие файлы сохранения с текущим обновлением сообщества, поэтому не забудьте создать копию сохранений перед запуском! @@ -380,4 +380,10 @@ Указанный zip-файл не является файлом AM2R 1.1! Пожалуйста, выберите другой zip-файл. + + Архивировать $NAME? + + + Это архив, содержащий ранее установленный мод. Он не может быть переустановлен, и, при удалении файлов игры, так же будет удалён. + \ No newline at end of file diff --git a/AM2RLauncher/AM2RLauncher/Language/Text.zh-Hans.resx b/AM2RLauncher/AM2RLauncher/Language/Text.zh-Hans.resx index 8308588..2c92d85 100644 --- a/AM2RLauncher/AM2RLauncher/Language/Text.zh-Hans.resx +++ b/AM2RLauncher/AM2RLauncher/Language/Text.zh-Hans.resx @@ -132,7 +132,7 @@ 为 $NAME 创建 APK - + 这是先前安装过的社区更新版本的压缩文件,因此无法再重新安装一遍,并且在游戏文件被删除后也会自行删除。由于与当前安装的社区更新版本共用保存数据,所以请在运行该游戏实例前备份好保存数据! diff --git a/AM2RLauncher/AM2RLauncher/MainForm/MainForm.Events.cs b/AM2RLauncher/AM2RLauncher/MainForm/MainForm.Events.cs index aa49ac9..b30a6fe 100644 --- a/AM2RLauncher/AM2RLauncher/MainForm/MainForm.Events.cs +++ b/AM2RLauncher/AM2RLauncher/MainForm/MainForm.Events.cs @@ -998,14 +998,10 @@ namespace AM2RLauncher // User wants to archive profile if (archiveResult == DialogResult.Yes) - { ArchiveProfileAndAdjustLists(currentProfile); - DeleteProfileAndAdjustLists(currentProfile); - } } - // No archiving, Delete profile instead - else - DeleteProfileAndAdjustLists(currentProfile); + // Now we delete the profile + DeleteProfileAndAdjustLists(currentProfile); // Rename directory to take the old one's place string originalFolder = modsDir + "/" + extractedName.Replace("_new", ""); diff --git a/AM2RLauncher/AM2RLauncher/MainForm/MainForm.StateMachine.cs b/AM2RLauncher/AM2RLauncher/MainForm/MainForm.StateMachine.cs index 382c791..63269ae 100644 --- a/AM2RLauncher/AM2RLauncher/MainForm/MainForm.StateMachine.cs +++ b/AM2RLauncher/AM2RLauncher/MainForm/MainForm.StateMachine.cs @@ -175,7 +175,7 @@ namespace AM2RLauncher // Only enable these, when we're not on the community updates if (settingsProfileDropDown.SelectedIndex > 0) { - updateModButton.Enabled = enabled; + updateModButton.Enabled = profileList[settingsProfileDropDown.SelectedIndex].Installable; updateModButton.ToolTip = Language.Text.UpdateModButtonToolTip.Replace("$NAME", settingsProfileDropDown.Items[settingsProfileDropDown.SelectedIndex].Text); deleteModButton.Enabled = enabled; deleteModButton.ToolTip = Language.Text.DeleteModButtonToolTip.Replace("$NAME", settingsProfileDropDown.Items[settingsProfileDropDown.SelectedIndex].Text); @@ -285,8 +285,13 @@ namespace AM2RLauncher { // Archive version notes if (!profile.Installable) - //TODO: have different text for non-community archive - profile.ProfileNotes = Language.Text.ArchiveNotes + "\n\n" + profile.ProfileNotes; + { + //TODO: localizations + if (profile.Name.Contains("Community Updates")) + profile.ProfileNotes = Language.Text.ArchiveNotesCommunityUpdates; + else + profile.ProfileNotes = Language.Text.ArchiveNotesMods + "\n\n" + profile.ProfileNotes; + } profileDropDown.Items.Add(profile.Name); } From 12d6b5f202e7bb1f45abbb15ba1a15bc358d178b Mon Sep 17 00:00:00 2001 From: Miepee Date: Sun, 13 Feb 2022 22:26:44 +0100 Subject: [PATCH 14/17] only write profileIndex on launcher close --- AM2RLauncher/AM2RLauncher/MainForm/MainForm.Events.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/AM2RLauncher/AM2RLauncher/MainForm/MainForm.Events.cs b/AM2RLauncher/AM2RLauncher/MainForm/MainForm.Events.cs index b30a6fe..6f87feb 100644 --- a/AM2RLauncher/AM2RLauncher/MainForm/MainForm.Events.cs +++ b/AM2RLauncher/AM2RLauncher/MainForm/MainForm.Events.cs @@ -739,11 +739,9 @@ namespace AM2RLauncher 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" || - profileList[profileDropDown.SelectedIndex].SaveLocation == "default")) + profileList[profileDropDown.SelectedIndex].SaveLocation == "default")) saveWarningLabel.Visible = true; else saveWarningLabel.Visible = false; @@ -1054,6 +1052,7 @@ namespace AM2RLauncher CrossPlatformOperations.WriteToConfig("Width", ClientSize.Width); CrossPlatformOperations.WriteToConfig("Height", ClientSize.Height); CrossPlatformOperations.WriteToConfig("IsMaximized", this.WindowState == WindowState.Maximized); + CrossPlatformOperations.WriteToConfig("ProfileIndex", profileIndex.ToString()); switch (updateState) { From cbce04698d1fbd5e7f8df9cda0c85e5b3c370e29 Mon Sep 17 00:00:00 2001 From: Miepee <38186597+Miepee@users.noreply.github.com> Date: Mon, 14 Feb 2022 05:47:30 +0100 Subject: [PATCH 15/17] reference to a galaxy far, far away --- AM2RLauncher/AM2RLauncherCore/Splash.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/AM2RLauncher/AM2RLauncherCore/Splash.cs b/AM2RLauncher/AM2RLauncherCore/Splash.cs index 79444d8..e5d760d 100644 --- a/AM2RLauncher/AM2RLauncherCore/Splash.cs +++ b/AM2RLauncher/AM2RLauncherCore/Splash.cs @@ -18,6 +18,7 @@ public static class Splash "Now with 100% more Blob Throwers!", "Speedrun THIS, I dare you.", "The broken pipe is a lie.", + "I am altering the broken pipe. Pray I don't alter it any further.", "Overcommitting to April Fool's since 2018.", "Also try Metroid II: Return of Samus!", "Also try Metroid: Samus Returns!", From f047b83ef9f7cb8b18692bb75a3af3808ea296d6 Mon Sep 17 00:00:00 2001 From: Miepee Date: Mon, 14 Feb 2022 11:16:00 +0100 Subject: [PATCH 16/17] Update chinese translation of Archive text --- AM2RLauncher/AM2RLauncher/Language/Text.zh-Hans.resx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/AM2RLauncher/AM2RLauncher/Language/Text.zh-Hans.resx b/AM2RLauncher/AM2RLauncher/Language/Text.zh-Hans.resx index 2c92d85..22c5e72 100644 --- a/AM2RLauncher/AM2RLauncher/Language/Text.zh-Hans.resx +++ b/AM2RLauncher/AM2RLauncher/Language/Text.zh-Hans.resx @@ -133,7 +133,7 @@ 为 $NAME 创建 APK - 这是先前安装过的社区更新版本的压缩文件,因此无法再重新安装一遍,并且在游戏文件被删除后也会自行删除。由于与当前安装的社区更新版本共用保存数据,所以请在运行该游戏实例前备份好保存数据! + 此为以前安装过的社区更新版本的归档,无法重新安装,若对应的游戏文件被删除,该归档也会自行删除。由于和当前安装的社区更新版本共用保存数据,所以请在运行该游戏实例前备份好保存数据! 作者: @@ -382,4 +382,10 @@ 选定的文件不是 AM2R_1.1 !请选择其他 Zip 文件 + + 是否要归档 $NAME? + + + 此为以前安装过的 Mod 的归档,无法重新安装,若对应的游戏文件被删除,该归档也会自行删除。 + \ No newline at end of file From dd2f088944dada5dede4b8707b4de9fad5a4ef15 Mon Sep 17 00:00:00 2001 From: Miepee Date: Mon, 14 Feb 2022 16:40:34 +0100 Subject: [PATCH 17/17] Add in jp archive text, reprhase some comments --- AM2RLauncher/AM2RLauncher/Language/Text.ja.resx | 6 ++++++ AM2RLauncher/AM2RLauncher/LauncherUpdater.cs | 4 ++-- AM2RLauncher/AM2RLauncherCore/Core.cs | 2 ++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/AM2RLauncher/AM2RLauncher/Language/Text.ja.resx b/AM2RLauncher/AM2RLauncher/Language/Text.ja.resx index 979a297..e1997f4 100644 --- a/AM2RLauncher/AM2RLauncher/Language/Text.ja.resx +++ b/AM2RLauncher/AM2RLauncher/Language/Text.ja.resx @@ -380,4 +380,10 @@ そのZIPファイルはAM2R v1.1ではありません! 別のZIPファイルを選んで下さい + + $NAMEをアーカイブ化しますか? + + + これは既にインストールされているMODです。再インストールはできず、またゲームファイルを削除すると自動的に削除されます。 + \ No newline at end of file diff --git a/AM2RLauncher/AM2RLauncher/LauncherUpdater.cs b/AM2RLauncher/AM2RLauncher/LauncherUpdater.cs index fbb5dce..95687a8 100644 --- a/AM2RLauncher/AM2RLauncher/LauncherUpdater.cs +++ b/AM2RLauncher/AM2RLauncher/LauncherUpdater.cs @@ -132,8 +132,8 @@ namespace AM2RLauncher 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 + // For mac, we just show a message box that a new version is available, because I don't want to support 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 + "." + diff --git a/AM2RLauncher/AM2RLauncherCore/Core.cs b/AM2RLauncher/AM2RLauncherCore/Core.cs index b5b95b7..aca50d3 100644 --- a/AM2RLauncher/AM2RLauncherCore/Core.cs +++ b/AM2RLauncher/AM2RLauncherCore/Core.cs @@ -7,6 +7,8 @@ namespace AM2RLauncher.Core; /// /// Class that has core stuff that doesn't fit anywhere else /// +//TODO: "Core" is a really stupid name and either this should get renamed, or AM2RLauncher.Core should get renamed. +// I am however bad at thinking of names public static class Core { ///