diff --git a/AM2RLauncher/AM2RLauncher.Gtk/Program.cs b/AM2RLauncher/AM2RLauncher.Gtk/Program.cs
index 95ca7f2..6000355 100644
--- a/AM2RLauncher/AM2RLauncher.Gtk/Program.cs
+++ b/AM2RLauncher/AM2RLauncher.Gtk/Program.cs
@@ -9,12 +9,12 @@ namespace AM2RLauncher.Gtk;
///
/// The main class for the GTK project.
///
-static class MainClass
+internal static class MainClass
{
///
/// The logger for , used to write any caught exceptions.
///
- private static readonly ILog Log = LogManager.GetLogger(typeof(MainForm));
+ private static readonly ILog log = LogManager.GetLogger(typeof(MainForm));
///
/// The main method for the GTK project.
///
@@ -36,14 +36,14 @@ static class MainClass
try
{
- Application GTKLauncher = new Application(Eto.Platforms.Gtk);
+ Application gtkLauncher = new Application(Eto.Platforms.Gtk);
LauncherUpdater.Main();
- GTKLauncher.UnhandledException += GTKLauncher_UnhandledException;
- GTKLauncher.Run(new MainForm());
+ gtkLauncher.UnhandledException += GTKLauncher_UnhandledException;
+ gtkLauncher.Run(new MainForm());
}
catch (Exception e)
{
- Log.Error("An unhandled exception has occurred: \n*****Stack Trace*****\n\n" + e.StackTrace);
+ log.Error("An unhandled exception has occurred: \n*****Stack Trace*****\n\n" + e.StackTrace);
Console.WriteLine(Language.Text.UnhandledException + "\n" + e.Message + "\n*****Stack Trace*****\n\n" + e.StackTrace);
Console.WriteLine("Check the logs at " + launcherDataPath + " for more info!");
}
@@ -54,7 +54,7 @@ static class MainClass
///
private static void GTKLauncher_UnhandledException(object sender, Eto.UnhandledExceptionEventArgs e)
{
- Log.Error("An unhandled exception has occurred: \n*****Stack Trace*****\n\n" + e.ExceptionObject);
+ log.Error("An unhandled exception has occurred: \n*****Stack Trace*****\n\n" + e.ExceptionObject);
Application.Instance.Invoke(() =>
{
MessageBox.Show(Language.Text.UnhandledException + "\n*****Stack Trace*****\n\n" + e.ExceptionObject, "GTK", MessageBoxType.Error);
@@ -100,5 +100,4 @@ static class MainClass
return Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory);
}
-}
-
+}
\ No newline at end of file
diff --git a/AM2RLauncher/AM2RLauncher.Mac/Program.cs b/AM2RLauncher/AM2RLauncher.Mac/Program.cs
index 9042367..f25560f 100644
--- a/AM2RLauncher/AM2RLauncher.Mac/Program.cs
+++ b/AM2RLauncher/AM2RLauncher.Mac/Program.cs
@@ -2,6 +2,7 @@
using log4net;
using log4net.Config;
using System;
+using System.Diagnostics.CodeAnalysis;
using System.IO;
namespace AM2RLauncher.Mac;
@@ -9,12 +10,12 @@ namespace AM2RLauncher.Mac;
///
/// The main class for the Mac project.
///
-static class MainClass
+internal static class MainClass
{
///
/// The logger for , used to write any caught exceptions.
///
- private static readonly ILog Log = LogManager.GetLogger(typeof(MainForm));
+ private static readonly ILog log = LogManager.GetLogger(typeof(MainForm));
///
/// The main method for the Mac project.
@@ -44,7 +45,7 @@ static class MainClass
}
catch (Exception e)
{
- Log.Error("An unhandled exception has occurred: \n*****Stack Trace*****\n\n" + e.StackTrace);
+ log.Error("An unhandled exception has occurred: \n*****Stack Trace*****\n\n" + e.StackTrace);
Console.WriteLine(Language.Text.UnhandledException + "\n" + e.Message + "\n*****Stack Trace*****\n\n" + e.StackTrace);
Console.WriteLine("Check the logs at " + launcherDataPath + " for more info!");
}
@@ -55,7 +56,7 @@ static class MainClass
///
private static void MacLauncher_UnhandledException(object sender, Eto.UnhandledExceptionEventArgs e)
{
- Log.Error("An unhandled exception has occurred: \n*****Stack Trace*****\n\n" + e.ExceptionObject);
+ log.Error("An unhandled exception has occurred: \n*****Stack Trace*****\n\n" + e.ExceptionObject);
Application.Instance.Invoke(() =>
{
MessageBox.Show(Language.Text.UnhandledException + "\n*****Stack Trace*****\n\n" + e.ExceptionObject, "Mac", MessageBoxType.Error);
@@ -63,8 +64,23 @@ static class MainClass
}
// This is a duplicate of CrossPlatformOperations.GenerateCurrentPath, because trying to invoke that would cause a crash due to currentPlatform not being initialized.
+ [return: NotNull]
private static string GenerateCurrentPath()
{
+ string am2rLauncherDataEnvVar = Environment.GetEnvironmentVariable("AM2RLAUNCHERDATA");
+ if (!String.IsNullOrWhiteSpace(am2rLauncherDataEnvVar))
+ {
+ try
+ {
+ // This will create the directories recursively if they don't exist
+ Directory.CreateDirectory(am2rLauncherDataEnvVar);
+
+ // Our env var is now set and directories exist
+ return am2rLauncherDataEnvVar;
+ }
+ catch { }
+ }
+
string nixHome = Environment.GetEnvironmentVariable("HOME");
//Mac has the Path at HOME/Library/AM2RLauncher
string macPath = nixHome + "/Library/AM2RLauncher";
diff --git a/AM2RLauncher/AM2RLauncher.Wpf/Program.cs b/AM2RLauncher/AM2RLauncher.Wpf/Program.cs
index 77ed605..7f2a945 100644
--- a/AM2RLauncher/AM2RLauncher.Wpf/Program.cs
+++ b/AM2RLauncher/AM2RLauncher.Wpf/Program.cs
@@ -10,12 +10,12 @@ namespace AM2RLauncher.Wpf;
///
/// The main class for the WinForms project.
///
-static class MainClass
+internal static class MainClass
{
///
/// The logger for , used to write any caught exceptions.
///
- private static readonly ILog Log = LogManager.GetLogger(typeof(MainForm));
+ private static readonly ILog log = LogManager.GetLogger(typeof(MainForm));
///
/// The main method for the WinForms project.
///
@@ -45,7 +45,7 @@ static class MainClass
}
catch (Exception e)
{
- Log.Error("An unhandled exception has occurred: \n*****Stack Trace*****\n\n" + e.StackTrace);
+ log.Error("An unhandled exception has occurred: \n*****Stack Trace*****\n\n" + e.StackTrace);
System.Windows.Forms.MessageBox.Show(Language.Text.UnhandledException + "\n" + e.Message + "\n*****Stack Trace*****\n\n" + e.StackTrace, "Microsoft .NET Framework",
System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
}
@@ -56,7 +56,7 @@ static class MainClass
///
private static void WinLauncher_UnhandledException(object sender, Eto.UnhandledExceptionEventArgs e)
{
- Log.Error("An unhandled exception has occurred: \n*****Stack Trace*****\n\n" + e.ExceptionObject);
+ log.Error("An unhandled exception has occurred: \n*****Stack Trace*****\n\n" + e.ExceptionObject);
MessageBox.Show(Language.Text.UnhandledException + "\n*****Stack Trace*****\n\n" + e.ExceptionObject, "Microsoft .NET Framework", MessageBoxType.Error);
}
@@ -65,20 +65,22 @@ static class MainClass
{
// First, we check if the user has a custom AM2RLAUNCHERDATA env var
string am2rLauncherDataEnvVar = Environment.GetEnvironmentVariable("AM2RLAUNCHERDATA");
- if (!String.IsNullOrWhiteSpace(am2rLauncherDataEnvVar))
+ // Windows has the path where the exe is located as default
+ string defaultPath = Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location);
+ if (String.IsNullOrWhiteSpace(am2rLauncherDataEnvVar))
+ return defaultPath;
+
+ try
{
- try
- {
- // This will create the directories recursively if they don't exist
- Directory.CreateDirectory(am2rLauncherDataEnvVar);
+ // This will create the directories recursively if they don't exist
+ Directory.CreateDirectory(am2rLauncherDataEnvVar);
- // Our env var is now set and directories exist
- return am2rLauncherDataEnvVar;
- }
- catch { }
+ // Our env var is now set and directories exist
+ return am2rLauncherDataEnvVar;
+ }
+ catch
+ {
+ return defaultPath;
}
- // Windows has the path where the exe is located as default
- return Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location);
}
-}
-
+}
\ No newline at end of file
diff --git a/AM2RLauncher/AM2RLauncher/LauncherUpdater.cs b/AM2RLauncher/AM2RLauncher/LauncherUpdater.cs
index 95acdd5..5491b87 100644
--- a/AM2RLauncher/AM2RLauncher/LauncherUpdater.cs
+++ b/AM2RLauncher/AM2RLauncher/LauncherUpdater.cs
@@ -1,5 +1,4 @@
using AM2RLauncher.Core;
-using Eto;
using Eto.Forms;
using log4net;
using System;
@@ -21,41 +20,41 @@ namespace AM2RLauncher
public const string VERSION = Core.Core.VERSION;
/// The Path of the oldConfig. Only gets used Windows-only
- private static readonly string OldConfigPath = CrossPlatformOperations.CURRENTPATH + "/" + CrossPlatformOperations.LAUNCHERNAME + ".oldCfg";
+ private static readonly string oldConfigPath = CrossPlatformOperations.CURRENTPATH + "/" + CrossPlatformOperations.LAUNCHERNAME + ".oldCfg";
/// The actual Path where the executable is stored, only used for updating.
//TODO: for mac, this reports the path of the mac runner, not the actual .app
- private static readonly string UpdatePath = OS.IsWindows ? CrossPlatformOperations.CURRENTPATH : Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory);
+ private static readonly string updatePath = OS.IsWindows ? CrossPlatformOperations.CURRENTPATH : Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory);
//TODO: Mac support for this in general
///
/// Our log object, that handles logging the current execution to a file.
///
- private static readonly ILog Log = LogManager.GetLogger(typeof(MainForm));
+ private static readonly ILog log = LogManager.GetLogger(typeof(MainForm));
///
/// Performs the entire AM2RLauncher update procedure.
///
public static void Main()
{
- Log.Info("Running update check...");
+ log.Info("Running update check...");
// Update section
// Clean old files that have been left
if (File.Exists(CrossPlatformOperations.CURRENTPATH + "/AM2RLauncher.bak"))
{
- Log.Info("AM2RLauncher.bak detected. Removing file.");
+ log.Info("AM2RLauncher.bak detected. Removing file.");
File.Delete(CrossPlatformOperations.CURRENTPATH + "/AM2RLauncher.bak");
}
- if (OS.IsWindows && File.Exists(OldConfigPath))
+ if (OS.IsWindows && File.Exists(oldConfigPath))
{
- Log.Info(CrossPlatformOperations.LAUNCHERNAME + ".oldCfg detected. Removing file.");
- File.Delete(OldConfigPath);
+ log.Info(CrossPlatformOperations.LAUNCHERNAME + ".oldCfg detected. Removing file.");
+ File.Delete(oldConfigPath);
}
if (OS.IsWindows && Directory.Exists(CrossPlatformOperations.CURRENTPATH + "/oldLib"))
{
- Log.Info("Old lib folder detected, removing folder.");
+ log.Info("Old lib folder detected, removing folder.");
Directory.Delete(CrossPlatformOperations.CURRENTPATH + "/oldLib", true);
}
@@ -80,11 +79,11 @@ namespace AM2RLauncher
}
// Check settings if autoUpdateLauncher is set to true
- bool autoUpdate = bool.Parse(CrossPlatformOperations.ReadFromConfig("AutoUpdateLauncher"));
+ bool autoUpdate = Boolean.Parse(CrossPlatformOperations.ReadFromConfig("AutoUpdateLauncher"));
if (autoUpdate)
{
- Log.Info("AutoUpdate Launcher set to true!");
+ log.Info("AutoUpdate Launcher set to true!");
// This is supposed to fix the updater throwing an exception on windows 7 and earlier(?)
// See this for information: https://stackoverflow.com/q/2859790 and https://stackoverflow.com/a/50977774
@@ -102,7 +101,7 @@ namespace AM2RLauncher
}
catch (WebException)
{
- Log.Error("WebException caught! Displaying MessageBox.");
+ log.Error("WebException caught! Displaying MessageBox.");
MessageBox.Show(Language.Text.NoInternetConnection);
return;
}
@@ -116,24 +115,24 @@ namespace AM2RLauncher
for (int i = 0; i < localVersionArray.Length; i++)
{
- int onlineNum = int.Parse(onlineVersionArray[i]);
- int localNum = int.Parse(localVersionArray[i]);
+ int onlineNum = Int32.Parse(onlineVersionArray[i]);
+ int localNum = Int32.Parse(localVersionArray[i]);
if (onlineNum > localNum)
{
isCurrentVersionOutdated = true;
break;
}
- else if (localNum > onlineNum)
+ if (localNum > onlineNum)
break;
}
- Log.Info((isCurrentVersionOutdated ? "Updating" : "Not Updating") + " from " + VERSION + " to " + onlineVersion);
+ log.Info((isCurrentVersionOutdated ? "Updating" : "Not Updating") + " from " + VERSION + " to " + onlineVersion);
// No new update, exiting
if (!isCurrentVersionOutdated)
return;
- Log.Info("Current version (" + VERSION + ") is outdated! Initiating update for version " + onlineVersion + ".");
+ log.Info("Current version (" + VERSION + ") is outdated! Initiating update for version " + onlineVersion + ".");
string tmpUpdatePath = CrossPlatformOperations.CURRENTPATH + "/tmpupdate/";
string zipPath = CrossPlatformOperations.CURRENTPATH + "/launcher.zip";
@@ -152,31 +151,31 @@ namespace AM2RLauncher
if (OS.IsWindows) platformSuffix = "_win";
else if (OS.IsLinux) platformSuffix = "_lin";
- Log.Info("Downloading https://github.com/AM2R-Community-Developers/AM2RLauncher/releases/latest/download/AM2RLauncher_" + onlineVersion + platformSuffix + ".zip to " + zipPath + ".");
+ log.Info("Downloading https://github.com/AM2R-Community-Developers/AM2RLauncher/releases/latest/download/AM2RLauncher_" + onlineVersion + platformSuffix + ".zip to " + zipPath + ".");
client.DownloadFile("https://github.com/AM2R-Community-Developers/AM2RLauncher/releases/latest/download/AM2RLauncher_" + onlineVersion + platformSuffix + ".zip", zipPath);
- Log.Info("File successfully downloaded.");
+ log.Info("File successfully downloaded.");
}
}
catch (UnauthorizedAccessException)
{
- Log.Error("UnauthorizedAccessException caught! Displaying MessageBox.");
+ log.Error("UnauthorizedAccessException caught! Displaying MessageBox.");
MessageBox.Show(Language.Text.UnauthorizedAccessMessage);
return;
}
ZipFile.ExtractToDirectory(zipPath, tmpUpdatePath);
- Log.Info("Updates successfully extracted to " + tmpUpdatePath);
+ log.Info("Updates successfully extracted to " + tmpUpdatePath);
File.Delete(zipPath);
- File.Move(UpdatePath + "/" + CrossPlatformOperations.LAUNCHERNAME, CrossPlatformOperations.CURRENTPATH + "/AM2RLauncher.bak");
+ File.Move(updatePath + "/" + CrossPlatformOperations.LAUNCHERNAME, CrossPlatformOperations.CURRENTPATH + "/AM2RLauncher.bak");
if (OS.IsWindows) File.Move(CrossPlatformOperations.LAUNCHERNAME + ".config", CrossPlatformOperations.LAUNCHERNAME + ".oldCfg");
foreach (var file in new DirectoryInfo(tmpUpdatePath).GetFiles())
{
- Log.Info("Moving " + file.FullName + " to " + CrossPlatformOperations.CURRENTPATH + "/" + file.Name);
- File.Copy(file.FullName, UpdatePath + "/" + file.Name, true);
+ log.Info("Moving " + file.FullName + " to " + CrossPlatformOperations.CURRENTPATH + "/" + file.Name);
+ File.Copy(file.FullName, updatePath + "/" + file.Name, true);
}
// For windows, the actual application is in "AM2RLauncher.dll". Which means, we need to update the lib folder as well.
if (OS.IsWindows && Directory.Exists(CrossPlatformOperations.CURRENTPATH + "/lib"))
@@ -207,17 +206,17 @@ namespace AM2RLauncher
CrossPlatformOperations.CopyOldConfigToNewConfig();
- Log.Info("Files extracted. Preparing to restart executable...");
+ log.Info("Files extracted. Preparing to restart executable...");
if (OS.IsLinux) System.Diagnostics.Process.Start("chmod", "+x ./AM2RLauncher.Gtk");
- System.Diagnostics.Process.Start(UpdatePath + "/" + CrossPlatformOperations.LAUNCHERNAME);
+ System.Diagnostics.Process.Start(updatePath + "/" + CrossPlatformOperations.LAUNCHERNAME);
Environment.Exit(0);
}
else
{
- Log.Info("AutoUpdate Launcher set to false. Exiting update check.");
+ log.Info("AutoUpdate Launcher set to false. Exiting update check.");
}
}
}
-}
+}
\ No newline at end of file
diff --git a/AM2RLauncher/AM2RLauncher/MainForm/MainForm.Events.cs b/AM2RLauncher/AM2RLauncher/MainForm/MainForm.Events.cs
index 8ac3fc9..709da3f 100644
--- a/AM2RLauncher/AM2RLauncher/MainForm/MainForm.Events.cs
+++ b/AM2RLauncher/AM2RLauncher/MainForm/MainForm.Events.cs
@@ -7,7 +7,6 @@ using System.ComponentModel;
using System.IO;
using System.IO.Compression;
using System.Linq;
-using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
@@ -538,7 +537,7 @@ namespace AM2RLauncher
{
Log.Info("User requested to add mod. Requesting user input for new mod .zip...");
- ProfileXML addedProfile = null;
+ ProfileXML addedProfile;
OpenFileDialog fileFinder = new OpenFileDialog
{
@@ -721,8 +720,8 @@ namespace AM2RLauncher
private void DrawablePaintEvent(object sender, PaintEventArgs e)
{
// Get drawing variables
- int height = drawable.Height;
- int width = drawable.Width;
+ float height = drawable.Height;
+ float width = drawable.Width;
float scaleDivisor = OS.IsWindows ? 955f : 715f; // Magic brute-forced values. Don't ask questions, because we don't have answers >_>
// Also, seems like nix systems share the same scaleDivisor. Again, don't ask.
float scale = height / scaleDivisor;
diff --git a/AM2RLauncher/AM2RLauncher/MainForm/MainForm.Methods.cs b/AM2RLauncher/AM2RLauncher/MainForm/MainForm.Methods.cs
index c0cb0ca..588e014 100644
--- a/AM2RLauncher/AM2RLauncher/MainForm/MainForm.Methods.cs
+++ b/AM2RLauncher/AM2RLauncher/MainForm/MainForm.Methods.cs
@@ -1,19 +1,9 @@
using Eto.Forms;
-using LibGit2Sharp;
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.IO.Compression;
-using System.Linq;
-using System.Text.RegularExpressions;
-using System.Threading;
namespace AM2RLauncher
{
public partial class MainForm : Form
{
-
-
///
/// Method that updates .
///
@@ -40,7 +30,6 @@ namespace AM2RLauncher
UpdateProgressBar(value, 0, 100);
}
-
///
/// Safety check function before accessing .
///
@@ -49,9 +38,5 @@ namespace AM2RLauncher
{
return profileIndex != null;
}
-
-
-
-
}
-}
+}
\ No newline at end of file
diff --git a/AM2RLauncher/AM2RLauncher/MainForm/MainForm.StateMachine.cs b/AM2RLauncher/AM2RLauncher/MainForm/MainForm.StateMachine.cs
index 9f96efd..23c6ac7 100644
--- a/AM2RLauncher/AM2RLauncher/MainForm/MainForm.StateMachine.cs
+++ b/AM2RLauncher/AM2RLauncher/MainForm/MainForm.StateMachine.cs
@@ -160,13 +160,14 @@ namespace AM2RLauncher
bool enabled = false;
switch (updateState)
{
- case UpdateState.Download: enabled = false; break;
- case UpdateState.Downloading: enabled = false; break;
- case UpdateState.Select11: enabled = false; break;
- case UpdateState.Install: enabled = true; break;
- case UpdateState.Installing: enabled = false; break;
- case UpdateState.Play: enabled = true; break;
+ case UpdateState.Download:
+ case UpdateState.Downloading:
+ case UpdateState.Select11:
+ case UpdateState.Installing:
case UpdateState.Playing: enabled = false; break;
+ case UpdateState.Install:
+ case UpdateState.Play: enabled = true; break;
+
}
if (apkButtonState == ApkButtonState.Creating) enabled = false;
diff --git a/AM2RLauncher/AM2RLauncher/MainForm/MainForm.UI.cs b/AM2RLauncher/AM2RLauncher/MainForm/MainForm.UI.cs
index 4b57ce9..ade52c5 100644
--- a/AM2RLauncher/AM2RLauncher/MainForm/MainForm.UI.cs
+++ b/AM2RLauncher/AM2RLauncher/MainForm/MainForm.UI.cs
@@ -81,21 +81,20 @@ namespace AM2RLauncher
///
private static string currentMirror;
- private static bool isInternetThere = Core.Core.isInternetThere;
+ private static bool isInternetThere = Core.Core.IsInternetThere;
- private static bool isThisRunningFromWine = Core.Core.isThisRunningFromWine;
+ private static bool isThisRunningFromWine = Core.Core.IsThisRunningFromWine;
+
+ private static bool singleInstance;
+
+ // This mutex needs to CONTINUE existing for the entire application's lifetime, or else the rest of this won't ever work!
+ // We're basically using it to key a thread and scan for other instances of that tag.
+ Mutex mutex = new Mutex(true, "AM2RLauncher", out singleInstance);
public MainForm()
{
// Exit if we're already running the AM2RLauncher
-
// Thanks, StackOverflow! https://stackoverflow.com/questions/184084/how-to-force-c-sharp-net-app-to-run-only-one-instance-in-windows
- bool singleInstance;
-
- // This mutex needs to CONTINUE existing for the entire application's lifetime, or else the rest of this won't ever work!
- // We're basically using it to key a thread and scan for other instances of that tag.
- Mutex mutex = new Mutex(true, "AM2RLauncher", out singleInstance);
-
if (!singleInstance)
{
// If on Windows, set the original app to the foreground window to prevent confusion
@@ -149,7 +148,7 @@ namespace AM2RLauncher
Log.Info("Actual Launcher location: " + Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory));
// Set the language to what User wanted or choose local language
- string userLanguage = Core.CrossPlatformOperations.ReadFromConfig("Language").ToLower();
+ string userLanguage = CrossPlatformOperations.ReadFromConfig("Language").ToLower();
if (!userLanguage.Equals("default"))
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultures(CultureTypes.AllCultures).First(c => c.NativeName.ToLower().Contains(userLanguage));
@@ -182,7 +181,7 @@ namespace AM2RLauncher
}
// Custom splash texts
- string splash = Core.Splash.GetSplash();
+ string splash = Splash.GetSplash();
Log.Info("Randomly chosen splash: " + splash);
// Load bitmaps
@@ -205,7 +204,7 @@ namespace AM2RLauncher
// Create mirror list - eventually this should be platform specific!
// We do this as a List so we can add more dynamically on user input... if necessary.
- mirrorList = Core.CrossPlatformOperations.GenerateMirrorList();
+ mirrorList = CrossPlatformOperations.GenerateMirrorList();
// Create mirror list
// We do this as a list for 1) make this dynamic and 2) make ETO happy
@@ -224,13 +223,13 @@ namespace AM2RLauncher
Title = "AM2RLauncher " + VERSION + ": " + splash;
MinimumSize = new Size(500, 400);
// TODO: for some reason, this sometimes doesn't work on Linux. Was reported at eto, stays here until its fixed
- ClientSize = new Size(Int32.Parse(Core.CrossPlatformOperations.ReadFromConfig("Width")), Int32.Parse(Core.CrossPlatformOperations.ReadFromConfig("Height")));
+ ClientSize = new Size(Int32.Parse(CrossPlatformOperations.ReadFromConfig("Width")), Int32.Parse(CrossPlatformOperations.ReadFromConfig("Height")));
if (ClientSize.Width < 500)
ClientSize = new Size(500, ClientSize.Height);
if (ClientSize.Height < 400)
ClientSize = new Size(ClientSize.Width, 400);
Log.Info("Start the launcher with Size: " + ClientSize.Width + ", " + ClientSize.Height);
- if (Boolean.Parse(Core.CrossPlatformOperations.ReadFromConfig("IsMaximized"))) Maximize();
+ if (Boolean.Parse(CrossPlatformOperations.ReadFromConfig("IsMaximized"))) Maximize();
drawable = new Drawable { BackgroundColor = colBGNoAlpha };
@@ -450,7 +449,6 @@ namespace AM2RLauncher
{
changelogWebView
}
-
}
};
@@ -541,7 +539,7 @@ namespace AM2RLauncher
languageDropDown.Items.AddRange(languageList);
- var tmpLanguage = Core.CrossPlatformOperations.ReadFromConfig("Language");
+ var tmpLanguage = CrossPlatformOperations.ReadFromConfig("Language");
languageDropDown.SelectedIndex = tmpLanguage == "Default" ? 0 : languageDropDown.Items.IndexOf(languageDropDown.Items.FirstOrDefault(x => x.Text.Equals(tmpLanguage)));
if (languageDropDown.SelectedIndex == -1)
@@ -553,7 +551,7 @@ namespace AM2RLauncher
// autoUpdateAM2R checkbox
autoUpdateAM2RCheck = new CheckBox
{
- Checked = Boolean.Parse(Core.CrossPlatformOperations.ReadFromConfig("AutoUpdateAM2R")),
+ Checked = Boolean.Parse(CrossPlatformOperations.ReadFromConfig("AutoUpdateAM2R")),
Text = Language.Text.AutoUpdateAM2R,
TextColor = colGreen
};
@@ -562,7 +560,7 @@ namespace AM2RLauncher
// autoUpdateLauncher checkbox
autoUpdateLauncherCheck = new CheckBox
{
- Checked = Boolean.Parse(Core.CrossPlatformOperations.ReadFromConfig("AutoUpdateLauncher")),
+ Checked = Boolean.Parse(CrossPlatformOperations.ReadFromConfig("AutoUpdateLauncher")),
Text = Language.Text.AutoUpdateLauncher,
TextColor = colGreen
};
@@ -570,7 +568,7 @@ namespace AM2RLauncher
// HQ music, PC
hqMusicPCCheck = new CheckBox
{
- Checked = Boolean.Parse(Core.CrossPlatformOperations.ReadFromConfig("MusicHQPC")),
+ Checked = Boolean.Parse(CrossPlatformOperations.ReadFromConfig("MusicHQPC")),
Text = Language.Text.HighQualityPC,
TextColor = colGreen
};
@@ -578,7 +576,7 @@ namespace AM2RLauncher
// HQ music, Android
hqMusicAndroidCheck = new CheckBox
{
- Checked = Boolean.Parse(Core.CrossPlatformOperations.ReadFromConfig("MusicHQAndroid")),
+ Checked = Boolean.Parse(CrossPlatformOperations.ReadFromConfig("MusicHQAndroid")),
Text = Language.Text.HighQualityAndroid,
TextColor = colGreen
};
@@ -639,14 +637,14 @@ namespace AM2RLauncher
// Custom mirror
customMirrorCheck = new CheckBox
{
- Checked = Boolean.Parse(Core.CrossPlatformOperations.ReadFromConfig("CustomMirrorEnabled")),
+ Checked = Boolean.Parse(CrossPlatformOperations.ReadFromConfig("CustomMirrorEnabled")),
Text = Language.Text.CustomMirrorCheck,
TextColor = colGreen
};
customMirrorTextBox = new TextBox
{
- Text = Core.CrossPlatformOperations.ReadFromConfig("CustomMirrorText"),
+ Text = CrossPlatformOperations.ReadFromConfig("CustomMirrorText"),
BackgroundColor = colBGNoAlpha,
TextColor = colGreen
};
@@ -985,4 +983,4 @@ namespace AM2RLauncher
#endregion
}
-}
+}
\ No newline at end of file
diff --git a/AM2RLauncher/AM2RLauncherCore/AM2RLauncher.Core.csproj b/AM2RLauncher/AM2RLauncherCore/AM2RLauncher.Core.csproj
index 409dc52..995d310 100644
--- a/AM2RLauncher/AM2RLauncherCore/AM2RLauncher.Core.csproj
+++ b/AM2RLauncher/AM2RLauncherCore/AM2RLauncher.Core.csproj
@@ -2,7 +2,6 @@
netstandard2.0
- enable
latest
@@ -12,4 +11,4 @@
-
+
\ No newline at end of file
diff --git a/AM2RLauncher/AM2RLauncherCore/Core.cs b/AM2RLauncher/AM2RLauncherCore/Core.cs
index 7d648f7..b5b95b7 100644
--- a/AM2RLauncher/AM2RLauncherCore/Core.cs
+++ b/AM2RLauncher/AM2RLauncherCore/Core.cs
@@ -1,53 +1,49 @@
-using AM2RLauncher.Core.XML;
-using log4net;
+using log4net;
using System;
-using System.Collections.Generic;
using System.Runtime.InteropServices;
-namespace AM2RLauncher.Core
-{
+namespace AM2RLauncher.Core;
+///
+/// Class that has core stuff that doesn't fit anywhere else
+///
+public static class Core
+{
///
- /// Class that has core stuff that doesn't fit anywhere else
+ /// Our log object, that handles logging the current execution to a file.
///
- public static class Core
- {
- ///
- /// Our log object, that handles logging the current execution to a file.
- ///
- public static readonly ILog Log = LogManager.GetLogger(typeof(Core));
+ public static readonly ILog Log = LogManager.GetLogger(typeof(Core));
- /// The Version that identifies this current release.
- public const string VERSION = "2.2.0";
+ /// The Version that identifies this current release.
+ public const string VERSION = "2.2.0";
- ///
- /// Checks if this is run via WINE.
- ///
- public static bool isThisRunningFromWine = CheckIfRunFromWINE();
+ ///
+ /// Checks if this is run via WINE.
+ ///
+ public static readonly bool IsThisRunningFromWine = CheckIfRunFromWINE();
- ///
- /// Indicates whether or not we have established an internet connection.
- ///
- public static readonly bool isInternetThere = HelperMethods.IsConnectedToInternet();
+ ///
+ /// Indicates whether or not we have established an internet connection.
+ ///
+ public static readonly bool IsInternetThere = HelperMethods.IsConnectedToInternet();
- ///
- /// Checks if this is ran from WINE
- ///
- /// if run from WINE, if not.
- private static bool CheckIfRunFromWINE()
- {
- if (OS.IsWindows && Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Software\\Wine") != null)
- return true;
+ ///
+ /// Checks if this is ran from WINE
+ ///
+ /// if run from WINE, if not.
+ private static bool CheckIfRunFromWINE()
+ {
+ if (OS.IsWindows && Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Software\\Wine") != null)
+ return true;
- return false;
- }
-
- ///
- /// This is used on Windows only. This sets a window to be in foreground, is used i.e. to fix am2r just being hidden.
- ///
- /// Pointer to the process you want to have in the foreground.
- ///
- [DllImport("user32.dll")]
- public static extern bool SetForegroundWindow(IntPtr hWnd);
+ return false;
}
-}
+
+ ///
+ /// This is used on Windows only. This sets a window to be in foreground, is used i.e. to fix am2r just being hidden.
+ ///
+ /// Pointer to the process you want to have in the foreground.
+ ///
+ [DllImport("user32.dll")]
+ public static extern bool SetForegroundWindow(IntPtr hWnd);
+}
\ No newline at end of file
diff --git a/AM2RLauncher/AM2RLauncherCore/CrossPlatformOperations.cs b/AM2RLauncher/AM2RLauncherCore/CrossPlatformOperations.cs
index dd09f2f..5939915 100644
--- a/AM2RLauncher/AM2RLauncherCore/CrossPlatformOperations.cs
+++ b/AM2RLauncher/AM2RLauncherCore/CrossPlatformOperations.cs
@@ -7,550 +7,539 @@ using System.IO;
using System.Reflection;
using System.Text.RegularExpressions;
-namespace AM2RLauncher.Core
+namespace AM2RLauncher.Core;
+
+///
+/// Class that does operations that work cross-platform.
+///
+public static class CrossPlatformOperations
{
///
- /// Class that does operations that work cross-platform.
+ /// The logger for , used to write any caught exceptions.
+ ///
+ private static readonly ILog log = Core.Log;
+
+ ///
+ /// Name of the Launcher executable.
+ ///
+ public static readonly string LAUNCHERNAME = AppDomain.CurrentDomain.FriendlyName;
+
+ ///
+ /// Path to the Home Folder on *Nix-based systems.
+ ///
+ public static readonly string NIXHOME = Environment.GetEnvironmentVariable("HOME");
+
+ ///
+ /// Path to the Config folder on Linux-based systems.
///
- public static class CrossPlatformOperations
+ private static readonly string LINUXXDGCONFIG = Environment.GetEnvironmentVariable("XDG_CONFIG_HOME");
+
+ ///
+ /// Path to the Config file folder on *nix based systems.
+ /// Linux: Will point to XDG_CONFIG_HOME/AM2RLauncher
+ /// Mac: Will point to ~/Library/Preferences/AM2RLauncher
+ ///
+ private static readonly string NIXLAUNCHERCONFIGPATH = OS.IsLinux ? (String.IsNullOrWhiteSpace(LINUXXDGCONFIG) ? NIXHOME + "/.config"
+ : LINUXXDGCONFIG) + "/AM2RLauncher"
+ : NIXHOME + "/Library/Preferences/AM2RLauncher";
+
+ ///
+ /// Config file path for *nix based systems. Will be + "/config.xml".
+ ///
+ private static readonly string NIXLAUNCHERCONFIGFILEPATH = NIXLAUNCHERCONFIGPATH + "/config.xml";
+
+ ///
+ /// Current Path where the Launcher is located. For more info, check .
+ ///
+ public static readonly string CURRENTPATH = GenerateCurrentPath();
+
+ ///
+ /// Generates the mirror list, depending on the current Platform.
+ ///
+ /// A containing the mirror links.
+ public static List GenerateMirrorList()
{
- ///
- /// The logger for , used to write any caught exceptions.
- ///
- private static readonly ILog Log = Core.Log;
-
- ///
- /// Name of the Launcher executable.
- ///
- public static readonly string LAUNCHERNAME = AppDomain.CurrentDomain.FriendlyName;
-
- ///
- /// Path to the Home Folder on *Nix-based systems.
- ///
- public static readonly string NIXHOME = Environment.GetEnvironmentVariable("HOME");
-
- ///
- /// Path to the Config folder on Linux-based systems.
- ///
- private static readonly string LINUXXDGCONFIG = Environment.GetEnvironmentVariable("XDG_CONFIG_HOME");
-
- ///
- /// Path to the Config file folder on *nix based systems.
- /// Linux: Will point to XDG_CONFIG_HOME/AM2RLauncher
- /// Mac: Will point to ~/Library/Preferences/AM2RLauncher
- ///
- private static readonly string NIXLAUNCHERCONFIGPATH = OS.IsLinux ? (String.IsNullOrWhiteSpace(LINUXXDGCONFIG) ? NIXHOME + "/.config"
- : LINUXXDGCONFIG) + "/AM2RLauncher"
- : NIXHOME + "/Library/Preferences/AM2RLauncher";
-
- ///
- /// Config file path for *nix based systems. Will be + "/config.xml".
- ///
- private static readonly string NIXLAUNCHERCONFIGFILEPATH = NIXLAUNCHERCONFIGPATH + "/config.xml";
-
- ///
- /// Current Path where the Launcher is located. For more info, check .
- ///
- public static readonly string CURRENTPATH = GenerateCurrentPath();
-
- ///
- /// Generates the mirror list, depending on the current Platform.
- ///
- /// A containing the mirror links.
- public static List GenerateMirrorList()
+ if (OS.IsWindows)
{
- if (OS.IsWindows)
+ return new List
{
- return new List
- {
- "https://github.com/AM2R-Community-Developers/AM2R-Autopatcher-Windows.git",
- "https://gitlab.com/am2r-community-developers/AM2R-Autopatcher-Windows.git"
- };
- }
- else if (OS.IsLinux)
+ "https://github.com/AM2R-Community-Developers/AM2R-Autopatcher-Windows.git",
+ "https://gitlab.com/am2r-community-developers/AM2R-Autopatcher-Windows.git"
+ };
+ }
+ if (OS.IsLinux)
+ {
+ return new List
{
- return new List
- {
- "https://github.com/AM2R-Community-Developers/AM2R-Autopatcher-Linux.git",
- "https://gitlab.com/am2r-community-developers/AM2R-Autopatcher-Linux.git"
- };
- }
- else if (OS.IsMac)
+ "https://github.com/AM2R-Community-Developers/AM2R-Autopatcher-Linux.git",
+ "https://gitlab.com/am2r-community-developers/AM2R-Autopatcher-Linux.git"
+ };
+ }
+ if (OS.IsMac)
+ {
+ return new List
{
- return new List
- {
- "https://github.com/Miepee/AM2R-Autopatcher-Mac.git"
- //TODO: make mac official at some point:tm:, put this on gitlab
- };
+ "https://github.com/Miepee/AM2R-Autopatcher-Mac.git"
+ //TODO: make mac official at some point:tm:, put this on gitlab
+ };
- }
- else // Should never occur, but...
- {
- Log.Error(OS.Name + " has no mirror lists!");
- return new List();
- }
}
- ///
- /// Reads the Launcher config file on the current Platform and returns the value for .
- ///
- /// The property to get the value from.
- /// The value from as a string
- public static string ReadFromConfig(string property)
+ // Should never occur, but...
+ log.Error(OS.Name + " has no mirror lists!");
+ return new List();
+ }
+
+ ///
+ /// Reads the Launcher config file on the current Platform and returns the value for .
+ ///
+ /// The property to get the value from.
+ /// The value from as a string
+ public static string ReadFromConfig(string property)
+ {
+ log.Info($"Reading {property} from config.");
+ if (OS.IsWindows)
+ {
+ // We use the configuration manager in order to read `property` from the app.config and then return it
+ ConnectionStringSettings appConfig = ConfigurationManager.ConnectionStrings[property];
+ if (appConfig == null) throw new ArgumentException("The property " + property + " could not be found.");
+ return appConfig.ConnectionString;
+ }
+ if (OS.IsUnix)
{
- Log.Info($"Reading {property} from config.");
- if (OS.IsWindows)
+ string launcherConfigPath = NIXLAUNCHERCONFIGPATH;
+ string launcherConfigFilePath = launcherConfigPath + "/config.xml";
+ XML.LauncherConfigXML launcherConfig = new XML.LauncherConfigXML();
+
+ // If folder doesn't exist, create it and the config file
+ if (!Directory.Exists(launcherConfigPath) || !File.Exists(launcherConfigFilePath))
{
- // We use the configuration manager in order to read `property` from the app.config and then return it
- ConnectionStringSettings appConfig = ConfigurationManager.ConnectionStrings[property];
- if (appConfig == null) throw new ArgumentException("The property " + property + " could not be found.");
- return appConfig.ConnectionString;
+ Directory.CreateDirectory(launcherConfigPath);
+ File.WriteAllText(launcherConfigFilePath, XML.Serializer.Serialize(launcherConfig));
}
- else if (OS.IsUnix)
- {
- string launcherConfigPath = NIXLAUNCHERCONFIGPATH;
- string launcherConfigFilePath = launcherConfigPath + "/config.xml";
- XML.LauncherConfigXML launcherConfig = new XML.LauncherConfigXML();
- // If folder doesn't exist, create it and the config file
- if (!Directory.Exists(launcherConfigPath) || !File.Exists(launcherConfigFilePath))
- {
- Directory.CreateDirectory(launcherConfigPath);
- File.WriteAllText(launcherConfigFilePath, XML.Serializer.Serialize(launcherConfig));
- }
+ // Deserialize the config xml into launcherConfig
+ launcherConfig = XML.Serializer.Deserialize(File.ReadAllText(launcherConfigFilePath));
- // Deserialize the config xml into launcherConfig
- launcherConfig = XML.Serializer.Deserialize(File.ReadAllText(launcherConfigFilePath));
+ // This uses the indexer, which means, we can use the variable in order to get the property. Look at LauncherConfigXML for more info
+ return launcherConfig[property]?.ToString();
+ }
- if (launcherConfig[property] == null)
- return null;
+ log.Error(OS.Name + " has no config to read from!");
+ return null;
+ }
- // This uses the indexer, which means, we can use the variable in order to get the property. Look at LauncherConfigXML for more info
- return launcherConfig[property]?.ToString();
- }
- else
- Log.Error(OS.Name + " has no config to read from!");
- return null;
+ ///
+ /// Writes to in the Launcher Config file.
+ ///
+ /// The property whose value you want to change.
+ /// The value that will be written.
+ public static void WriteToConfig(string property, object value)
+ {
+ log.Info($"Writing {value} of type {value.GetType()} to {property} to config.");
+ if (OS.IsWindows)
+ {
+ // We use the configuration manager in order to read from the app.config, change the value and save it
+ Configuration appConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
+ if (appConfig == null)
+ throw new NullReferenceException("Could not find the Config file! Please make sure it exists!");
+ ConnectionStringsSection connectionStringsSection = (ConnectionStringsSection)appConfig.GetSection("connectionStrings");
+ if (connectionStringsSection?.ConnectionStrings[property]?.ConnectionString == null)
+ throw new ArgumentException("The property " + property + " could not be found.");
+ connectionStringsSection.ConnectionStrings[property].ConnectionString = value.ToString();
+ appConfig.Save();
+ ConfigurationManager.RefreshSection("connectionStrings");
}
-
- ///
- /// Writes to in the Launcher Config file.
- ///
- /// The property whose value you want to change.
- /// The value that will be written.
- public static void WriteToConfig(string property, object value)
+ else if (OS.IsUnix)
{
- Log.Info($"Writing {value} of type {value.GetType()} to {property} to config.");
- if (OS.IsWindows)
- {
- // We use the configuration manager in order to read from the app.config, change the value and save it
- Configuration appConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
- if (appConfig == null)
- throw new NullReferenceException("Could not find the Config file! Please make sure it exists!");
- ConnectionStringsSection connectionStringsSection = (ConnectionStringsSection)appConfig.GetSection("connectionStrings");
- if (connectionStringsSection?.ConnectionStrings[property]?.ConnectionString == null)
- throw new ArgumentException("The property " + property + " could not be found.");
- connectionStringsSection.ConnectionStrings[property].ConnectionString = value.ToString();
- appConfig.Save();
- ConfigurationManager.RefreshSection("connectionStrings");
- }
- else if (OS.IsUnix)
+ string launcherConfigPath = NIXLAUNCHERCONFIGPATH;
+ string launcherConfigFilePath = NIXLAUNCHERCONFIGFILEPATH;
+ XML.LauncherConfigXML launcherConfig = new XML.LauncherConfigXML();
+
+ // If folder doesn't exist, create it and the config file
+ if (!Directory.Exists(launcherConfigPath) || !File.Exists(launcherConfigFilePath))
{
- string launcherConfigPath = NIXLAUNCHERCONFIGPATH;
- string launcherConfigFilePath = NIXLAUNCHERCONFIGFILEPATH;
- XML.LauncherConfigXML launcherConfig = new XML.LauncherConfigXML();
-
- // If folder doesn't exist, create it and the config file
- if (!Directory.Exists(launcherConfigPath) || !File.Exists(launcherConfigFilePath))
- {
- Directory.CreateDirectory(launcherConfigPath);
- File.WriteAllText(launcherConfigFilePath, XML.Serializer.Serialize(launcherConfig));
- }
- // Deserialize the config xml into launcherConfig
- launcherConfig = XML.Serializer.Deserialize(File.ReadAllText(launcherConfigFilePath));
-
- // Uses indexer. Look at LauncherConfigXML for more info
- launcherConfig[property] = value;
-
- // Serialize back into the file
+ Directory.CreateDirectory(launcherConfigPath);
File.WriteAllText(launcherConfigFilePath, XML.Serializer.Serialize(launcherConfig));
}
- else
- Log.Error(OS.Name + " has no config to write to!");
+ // Deserialize the config xml into launcherConfig
+ launcherConfig = XML.Serializer.Deserialize(File.ReadAllText(launcherConfigFilePath));
+
+ // Uses indexer. Look at LauncherConfigXML for more info
+ launcherConfig[property] = value;
+
+ // Serialize back into the file
+ File.WriteAllText(launcherConfigFilePath, XML.Serializer.Serialize(launcherConfig));
}
+ else
+ log.Error(OS.Name + " has no config to write to!");
+ }
- ///
- /// When a Launcher update occurs that introduces new config properties, this method ensures that the old user config is copied over as much as possible.
- ///
- public static void CopyOldConfigToNewConfig()
+ ///
+ /// When a Launcher update occurs that introduces new config properties, this method ensures that the old user config is copied over as much as possible.
+ ///
+ public static void CopyOldConfigToNewConfig()
+ {
+ if (OS.IsWindows)
{
- if (OS.IsWindows)
- {
- string oldConfigPath = LAUNCHERNAME + ".oldCfg";
- string newConfigPath = LAUNCHERNAME + ".config";
- string oldConfigText = File.ReadAllText(oldConfigPath);
- string newConfigText = File.ReadAllText(newConfigPath);
+ string oldConfigPath = LAUNCHERNAME + ".oldCfg";
+ string newConfigPath = LAUNCHERNAME + ".config";
+ string oldConfigText = File.ReadAllText(oldConfigPath);
+ string newConfigText = File.ReadAllText(newConfigPath);
- Regex settingRegex = new Regex("");
+ Regex settingRegex = new Regex("");
- MatchCollection oldMatch = settingRegex.Matches(oldConfigText);
- MatchCollection newMatch = settingRegex.Matches(newConfigText);
+ MatchCollection oldMatch = settingRegex.Matches(oldConfigText);
+ MatchCollection newMatch = settingRegex.Matches(newConfigText);
- for (int i = 0; i < oldMatch.Count; i++)
- newConfigText = newConfigText.Replace(newMatch[i].Value, oldMatch[i].Value);
+ for (int i = 0; i < oldMatch.Count; i++)
+ newConfigText = newConfigText.Replace(newMatch[i].Value, oldMatch[i].Value);
- File.WriteAllText(newConfigPath, newConfigText);
+ File.WriteAllText(newConfigPath, newConfigText);
- }
- else if (OS.IsUnix)
- {
- string launcherConfigFilePath = NIXLAUNCHERCONFIGFILEPATH;
+ }
+ else if (OS.IsUnix)
+ {
+ string launcherConfigFilePath = NIXLAUNCHERCONFIGFILEPATH;
- // For some reason deserializing and saving back again works, not exactly sure why, but I'll take it
- XML.LauncherConfigXML launcherConfig = XML.Serializer.Deserialize(File.ReadAllText(launcherConfigFilePath));
- File.WriteAllText(launcherConfigFilePath, XML.Serializer.Serialize(launcherConfig));
- }
- else
- Log.Error(OS.Name + " has no config to transfer over!");
+ // For some reason deserializing and saving back again works, not exactly sure why, but I'll take it
+ XML.LauncherConfigXML launcherConfig = XML.Serializer.Deserialize(File.ReadAllText(launcherConfigFilePath));
+ File.WriteAllText(launcherConfigFilePath, XML.Serializer.Serialize(launcherConfig));
}
+ else
+ log.Error(OS.Name + " has no config to transfer over!");
+ }
- ///
- /// This open a website cross-platform.
- ///
- /// The URL of the website to be opened.
- public static void OpenURL(string url)
+ ///
+ /// This open a website cross-platform.
+ ///
+ /// The URL of the website to be opened.
+ public static void OpenURL(string url)
+ {
+ if (OS.IsWindows)
+ Process.Start(url);
+ else if (OS.IsLinux)
+ Process.Start("xdg-open", url);
+ else if (OS.IsMac)
+ Process.Start("open", url);
+ else
+ log.Error(OS.Name + " can't open URLs!");
+ }
+
+ ///
+ /// Opens in a file explorer. Creates the directory if it doesn't exist.
+ ///
+ /// Path to open.
+ public static void OpenFolder(string path)
+ {
+ // We have to replace forward slashes with backslashes here on windows because explorer.exe is picky...
+ // And on Nix systems, we want to replace ~ with its corresponding env var
+ string realPath = OS.IsWindows ? Environment.ExpandEnvironmentVariables(path).Replace("/", "\\")
+ : path.Replace("~", NIXHOME);
+ if (!Directory.Exists(realPath))
{
- if (OS.IsWindows)
- Process.Start(url);
- else if (OS.IsLinux)
- Process.Start("xdg-open", url);
- else if (OS.IsMac)
- Process.Start("open", url);
- else
- Log.Error(OS.Name + " can't open URLs!");
+ log.Info(realPath + " did not exist and was created");
+ Directory.CreateDirectory(realPath);
}
- ///
- /// Opens in a file explorer. Creates the directory if it doesn't exist.
- ///
- /// Path to open.
- public static void OpenFolder(string path)
+ // Needs quotes otherwise paths with space wont open
+ if (OS.IsWindows)
+ // And we're using explorer.exe to prevent people from stuffing system commands in here wholesale. That would be bad.
+ Process.Start("explorer.exe", $"\"{realPath}\"");
+ // Linux only opens the directory bc opening and selecting a file is pain
+ else if (OS.IsLinux)
+ Process.Start("xdg-open", $"\"{realPath}\"");
+ else if (OS.IsMac)
+ Process.Start("open", $"\"{realPath}\"");
+ else
+ log.Error(OS.Name + " can't open folders!");
+ }
+
+ ///
+ /// Opens and selects it in a file explorer.
+ /// Only selects on Windows and Mac, on Linux it just opens the folder. Does nothing if file doesn't exist.
+ ///
+ /// Path to open.
+ public static void OpenFolderAndSelectFile(string path)
+ {
+ // We have to replace forward slashes with backslashes here on windows because explorer.exe is picky...
+ // And on nix systems, we want to replace ~ with its corresponding env var
+ string realPath = OS.IsWindows ? Environment.ExpandEnvironmentVariables(path).Replace("/", "\\")
+ : path.Replace("~", NIXHOME);
+ if (!File.Exists(realPath))
{
- // We have to replace forward slashes with backslashes here on windows because explorer.exe is picky...
- // And on Nix systems, we want to replace ~ with its corresponding env var
- string realPath = OS.IsWindows ? Environment.ExpandEnvironmentVariables(path).Replace("/", "\\")
- : path.Replace("~", NIXHOME);
- if (!Directory.Exists(realPath))
- {
- Log.Info(realPath + " did not exist and was created");
- Directory.CreateDirectory(realPath);
- }
+ log.Error(realPath + "did not exist, operation to open its folder was cancelled!");
+ return;
+ }
+
+ // Needs quotes otherwise paths with spaces wont open
+ if (OS.IsWindows)
+ // And we're using explorer.exe to prevent people from stuffing system commands in here wholesale. That would be bad.
+ Process.Start("explorer.exe", $"/select, \"{realPath}\"");
+ else if (OS.IsLinux)
+ Process.Start("xdg-open", $"\"{Path.GetDirectoryName(realPath)}\"");
+ else if (OS.IsMac)
+ Process.Start("open", $"-R \"{realPath}\"");
+ else
+ log.Error(OS.Name + " can't open select files in file explorer!");
+ }
- // Needs quotes otherwise paths with space wont open
- if (OS.IsWindows)
- // And we're using explorer.exe to prevent people from stuffing system commands in here wholesale. That would be bad.
- Process.Start("explorer.exe", $"\"{realPath}\"");
- // Linux only opens the directory bc opening and selecting a file is pain
- else if (OS.IsLinux)
- Process.Start("xdg-open", $"\"{realPath}\"");
- else if (OS.IsMac)
- Process.Start("open", $"\"{realPath}\"");
- else
- Log.Error(OS.Name + " can't open folders!");
+ ///
+ /// Checks if command-line Java is installed.
+ ///
+ /// if it is installed, if not.
+ public static bool IsJavaInstalled()
+ {
+ string process = "";
+ string arguments = "";
+
+ if (OS.IsWindows)
+ {
+ process = "cmd.exe";
+ arguments = "/C java -version";
+ }
+ else if (OS.IsUnix)
+ {
+ process = "java";
+ arguments = "-version";
}
- ///
- /// Opens and selects it in a file explorer.
- /// Only selects on Windows and Mac, on Linux it just opens the folder. Does nothing if file doesn't exist.
- ///
- /// Path to open.
- public static void OpenFolderAndSelectFile(string path)
+ ProcessStartInfo javaStart = new ProcessStartInfo
{
- // We have to replace forward slashes with backslashes here on windows because explorer.exe is picky...
- // And on nix systems, we want to replace ~ with its corresponding env var
- string realPath = OS.IsWindows ? Environment.ExpandEnvironmentVariables(path).Replace("/", "\\")
- : path.Replace("~", NIXHOME);
- if (!File.Exists(realPath))
- {
- Log.Error(realPath + "did not exist, operation to open its folder was cancelled!");
- return;
- }
+ FileName = process,
+ Arguments = arguments,
+ UseShellExecute = false,
+ CreateNoWindow = true
+ };
- // Needs quotes otherwise paths with spaces wont open
- if (OS.IsWindows)
- // And we're using explorer.exe to prevent people from stuffing system commands in here wholesale. That would be bad.
- Process.Start("explorer.exe", $"/select, \"{realPath}\"");
- else if (OS.IsLinux)
- Process.Start("xdg-open", $"\"{Path.GetDirectoryName(realPath)}\"");
- else if (OS.IsMac)
- Process.Start("open", $"-R \"{realPath}\"");
- else
- Log.Error(OS.Name + " can't open select files in file explorer!");
- }
- ///
- /// Checks if command-line Java is installed.
- ///
- /// if it is installed, if not.
- public static bool IsJavaInstalled()
+ Process java = new Process { StartInfo = javaStart };
+
+ // This is primarily for linux, but could be happening on windows as well
+ try
{
- string process = "";
- string arguments = "";
+ java.Start();
- if (OS.IsWindows)
- {
- process = "cmd.exe";
- arguments = "/C java -version";
- }
- else if (OS.IsUnix)
- {
- process = "java";
- arguments = "-version";
- }
+ java.WaitForExit();
+ }
+ catch (System.ComponentModel.Win32Exception)
+ {
+ return false;
+ }
- ProcessStartInfo javaStart = new ProcessStartInfo
- {
- FileName = process,
- Arguments = arguments,
- UseShellExecute = false,
- CreateNoWindow = true
- };
+ return java.ExitCode == 0;
+ }
+ ///
+ /// Checks if command-line xdelta is installed on non-Windows systems.
+ ///
+ /// if it is installed, if not.
+ public static bool CheckIfXdeltaIsInstalled()
+ {
+ const string process = "xdelta3";
+ const string arguments = "-V";
- Process java = new Process { StartInfo = javaStart };
+ ProcessStartInfo xdeltaStart = new ProcessStartInfo
+ {
+ FileName = process,
+ Arguments = arguments,
+ UseShellExecute = false,
+ CreateNoWindow = true
+ };
- // This is primarily for linux, but could be happening on windows as well
- try
- {
- java.Start();
- java.WaitForExit();
- }
- catch (System.ComponentModel.Win32Exception)
- {
- return false;
- }
+ Process xdelta = new Process { StartInfo = xdeltaStart };
- return java.ExitCode == 0;
- }
+ try
+ {
+ xdelta.Start();
- ///
- /// Checks if command-line xdelta is installed on non-Windows systems.
- ///
- /// if it is installed, if not.
- public static bool CheckIfXdeltaIsInstalled()
+ xdelta.WaitForExit();
+ }
+ catch (System.ComponentModel.Win32Exception)
{
- const string process = "xdelta3";
- const string arguments = "-V";
+ return false;
+ }
+
+ return xdelta.ExitCode == 0;
+ }
- ProcessStartInfo xdeltaStart = new ProcessStartInfo
+ ///
+ /// This applies an Xdelta Patch cross-platform.
+ ///
+ /// Full Path to the original file.
+ /// Full Path to the Xdelta patch to apply.
+ /// Full Path to the output file.
+ public static void ApplyXdeltaPatch(string original, string patch, string output)
+ {
+ // For *whatever reason* **sometimes** xdelta patching doesn't work, if output = original. So I'm fixing that here.
+ string originalOutput = output;
+ if (original == output)
+ output += "_";
+
+ string arguments = "-f -d -s \"" + original.Replace(CURRENTPATH + "/", "") + "\" \"" + patch.Replace(CURRENTPATH + "/", "")
+ + "\" \"" + output.Replace(CURRENTPATH + "/", "") + "\"";
+
+ if (OS.IsWindows)
+ {
+ // We want some fancy parameters for Windows because the terminal scares end users :(
+ ProcessStartInfo parameters = new ProcessStartInfo
{
- FileName = process,
- Arguments = arguments,
+ FileName = CURRENTPATH + "/PatchData/utilities/xdelta/xdelta3.exe",
+ WorkingDirectory = CURRENTPATH + "",
UseShellExecute = false,
- CreateNoWindow = true
+ CreateNoWindow = true,
+ Arguments = arguments
};
+ using Process proc = new Process { StartInfo = parameters };
+ proc.Start();
+ proc.WaitForExit();
+ }
+ else if (OS.IsUnix)
+ {
+ ProcessStartInfo parameters = new ProcessStartInfo
+ {
+ FileName = "xdelta3",
+ Arguments = arguments,
+ WorkingDirectory = CURRENTPATH
+ };
- Process xdelta = new Process { StartInfo = xdeltaStart };
+ using Process proc = Process.Start(parameters);
+ proc?.WaitForExit();
+ }
- try
- {
- xdelta.Start();
+ if (originalOutput == output || !File.Exists(output))
+ return;
+
+ File.Delete(originalOutput);
+ File.Move(output, originalOutput);
+ }
- xdelta.WaitForExit();
- }
- catch (System.ComponentModel.Win32Exception)
- {
- return false;
- }
+ public static void RunJavaJar(string arguments = null, string workingDirectory = null)
+ {
+ workingDirectory ??= Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
+ string proc = "",
+ javaArgs = "";
- return xdelta.ExitCode == 0;
+ if (OS.IsWindows)
+ {
+ proc = "cmd";
+ javaArgs = "/C java -jar";
+ }
+ else if (OS.IsUnix)
+ {
+ proc = "java";
+ javaArgs = "-jar";
}
- ///
- /// This applies an Xdelta Patch cross-platform.
- ///
- /// Full Path to the original file.
- /// Full Path to the Xdelta patch to apply.
- /// Full Path to the output file.
- public static void ApplyXdeltaPatch(string original, string patch, string output)
+ ProcessStartInfo jarStart = new ProcessStartInfo
+ {
+ FileName = proc,
+ Arguments = javaArgs + " " + arguments,
+ WorkingDirectory = workingDirectory,
+ UseShellExecute = false,
+ CreateNoWindow = true
+ };
+
+ Process jarProcess = new Process
{
- // For *whatever reason* **sometimes** xdelta patching doesn't work, if output = original. So I'm fixing that here.
- string originalOutput = output;
- if (original == output)
- output += "_";
+ StartInfo = jarStart
+ };
- string arguments = "-f -d -s \"" + original.Replace(CURRENTPATH + "/", "") + "\" \"" + patch.Replace(CURRENTPATH + "/", "")
- + "\" \"" + output.Replace(CURRENTPATH + "/", "") + "\"";
+ jarProcess.Start();
- if (OS.IsWindows)
- {
- // We want some fancy parameters for Windows because the terminal scares end users :(
- ProcessStartInfo parameters = new ProcessStartInfo
- {
- FileName = CURRENTPATH + "/PatchData/utilities/xdelta/xdelta3.exe",
- WorkingDirectory = CURRENTPATH + "",
- UseShellExecute = false,
- CreateNoWindow = true,
- Arguments = arguments
- };
-
- using (Process proc = new Process { StartInfo = parameters })
- {
- proc.Start();
-
- proc.WaitForExit();
- }
- }
- else if (OS.IsUnix)
+ jarProcess.WaitForExit();
+ }
+
+ ///
+ /// Figures out what the AM2RLauncher's should be.
+ /// Determination is as follows:
+ ///
+ /// - $AM2RLAUNCHERDATA environment variable is read and folders are recursively generated.
+ /// - The current OS is checked. For Windows, the path where the executable is located will be returned.
+ /// For Linux, $XDG_DATA_HOME/AM2RLauncher will be returned.
+ /// Should $XDG_DATA_HOME be empty, it will default to $HOME/.local/share.
+ /// - The path where the executable is located will be returned.
+ ///
+ /// Should any errors occur, it falls down to the next step.
+ ///
+ ///
+ private static string GenerateCurrentPath()
+ {
+ // First, we check if the user has a custom AM2RLAUNCHERDATA env var
+ string am2rLauncherDataEnvVar = Environment.GetEnvironmentVariable("AM2RLAUNCHERDATA");
+ if (!String.IsNullOrWhiteSpace(am2rLauncherDataEnvVar))
+ {
+ try
{
- ProcessStartInfo parameters = new ProcessStartInfo
- {
- FileName = "xdelta3",
- Arguments = arguments,
- WorkingDirectory = CURRENTPATH
- };
-
- using (Process proc = Process.Start(parameters))
- {
- proc?.WaitForExit();
- }
- }
+ // This will create the directories recursively if they don't exist
+ Directory.CreateDirectory(am2rLauncherDataEnvVar);
- if (originalOutput != output && File.Exists(output))
+ // Our env var is now set and directories exist
+ log.Info("CurrentPath is set to " + am2rLauncherDataEnvVar);
+ return am2rLauncherDataEnvVar;
+ }
+ catch (Exception ex)
{
- File.Delete(originalOutput);
- File.Move(output, originalOutput);
+ log.Error($"There was an error with '{am2rLauncherDataEnvVar}'!\n{ex.Message} {ex.StackTrace}. Falling back to defaults.");
}
}
- public static void RunJavaJar(string arguments = null, string workingDirectory = null)
+ if (OS.IsWindows)
{
- if (workingDirectory == null)
- workingDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
- string proc = "",
- javaArgs = "";
-
- if (OS.IsWindows)
- {
- proc = "cmd";
- javaArgs = "/C java -jar";
- }
- else if (OS.IsUnix)
+ log.Info("Using default Windows CurrentPath.");
+ // Windows has the path where the exe is located as default
+ return Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location);
+ }
+ else if (OS.IsLinux)
+ {
+ // First check if XDG_DATA_HOME is set, if not we'll use ~/.local/share
+ string xdgDataHome = Environment.GetEnvironmentVariable("XDG_DATA_HOME");
+ if (String.IsNullOrWhiteSpace(xdgDataHome))
{
- proc = "java";
- javaArgs = "-jar";
+ log.Info("Using default Linux CurrentPath.");
+ xdgDataHome = NIXHOME + "/.local/share";
}
- ProcessStartInfo jarStart = new ProcessStartInfo
- {
- FileName = proc,
- Arguments = javaArgs + " " + arguments,
- WorkingDirectory = workingDirectory,
- UseShellExecute = false,
- CreateNoWindow = true
- };
+ // Add AM2RLauncher to the end of the dataPath
+ xdgDataHome += "/AM2RLauncher";
- Process jarProcess = new Process
+ try
{
- StartInfo = jarStart
- };
-
- jarProcess.Start();
+ // This will create the directories recursively if they don't exist
+ Directory.CreateDirectory(xdgDataHome);
- jarProcess.WaitForExit();
- }
-
- ///
- /// Figures out what the AM2RLauncher's should be.
- /// Determination is as follows:
- ///
- /// - $AM2RLAUNCHERDATA environment variable is read and folders are recursively generated.
- /// - The current OS is checked. For Windows, the path where the executable is located will be returned.
- /// For Linux, $XDG_DATA_HOME/AM2RLauncher will be returned.
- /// Should $XDG_DATA_HOME be empty, it will default to $HOME/.local/share.
- /// - The path where the executable is located will be returned.
- ///
- /// Should any errors occur, it falls down to the next step.
- ///
- ///
- private static string GenerateCurrentPath()
- {
- // First, we check if the user has a custom AM2RLAUNCHERDATA env var
- string am2rLauncherDataEnvVar = Environment.GetEnvironmentVariable("AM2RLAUNCHERDATA");
- if (!String.IsNullOrWhiteSpace(am2rLauncherDataEnvVar))
- {
- try
- {
- // This will create the directories recursively if they don't exist
- Directory.CreateDirectory(am2rLauncherDataEnvVar);
-
- // Our env var is now set and directories exist
- Log.Info("CurrentPath is set to " + am2rLauncherDataEnvVar);
- return am2rLauncherDataEnvVar;
- }
- catch (Exception ex)
- {
- Log.Error($"There was an error with '{am2rLauncherDataEnvVar}'!\n{ex.Message} {ex.StackTrace}. Falling back to defaults.");
- }
+ // Our env var is now set and directories exist
+ log.Info("CurrentPath is set to " + xdgDataHome);
+ return xdgDataHome;
}
-
- if (OS.IsWindows)
+ catch (Exception ex)
{
- Log.Info("Using default Windows CurrentPath.");
- // Windows has the path where the exe is located as default
- return Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location);
+ log.Error($"There was an error with '{xdgDataHome}'!\n{ex.Message} {ex.StackTrace}. Falling back to defaults.");
}
- else if (OS.IsLinux)
+ }
+ else if (OS.IsMac)
+ {
+ //Mac has the Path at HOME/Library/AM2RLauncher
+ string macPath = NIXHOME + "/Library/AM2RLauncher";
+ try
{
- // First check if XDG_DATA_HOME is set, if not we'll use ~/.local/share
- string xdgDataHome = Environment.GetEnvironmentVariable("XDG_DATA_HOME");
- if (String.IsNullOrWhiteSpace(xdgDataHome))
- {
- Log.Info("Using default Linux CurrentPath.");
- xdgDataHome = NIXHOME + "/.local/share";
- }
-
- // Add AM2RLauncher to the end of the dataPath
- xdgDataHome += "/AM2RLauncher";
-
- try
- {
- // This will create the directories recursively if they don't exist
- Directory.CreateDirectory(xdgDataHome);
-
- // Our env var is now set and directories exist
- Log.Info("CurrentPath is set to " + xdgDataHome);
- return xdgDataHome;
- }
- catch (Exception ex)
- {
- Log.Error($"There was an error with '{xdgDataHome}'!\n{ex.Message} {ex.StackTrace}. Falling back to defaults.");
- }
+ Directory.CreateDirectory(macPath);
+ log.Info("Using default Mac CurrentPath.");
+ return macPath;
}
- else if (OS.IsMac)
+ catch (Exception ex)
{
- //Mac has the Path at HOME/Library/AM2RLauncher
- string macPath = NIXHOME + "/Library/AM2RLauncher";
- try
- {
- Directory.CreateDirectory(macPath);
- Log.Info("Using default Mac CurrentPath.");
- return macPath;
- }
- catch (Exception ex)
- {
- Log.Error($"There was an error with '{macPath}'!\n{ex.Message} {ex.StackTrace}. Falling back to defaults.");
- }
+ log.Error($"There was an error with '{macPath}'!\n{ex.Message} {ex.StackTrace}. Falling back to defaults.");
}
- else
- Log.Error(OS.Name + " has no current path!");
-
- Log.Info("Something went wrong, falling back to the default CurrentPath.");
- return Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory);
}
+ else
+ log.Error(OS.Name + " has no current path!");
-
+ log.Info("Something went wrong, falling back to the default CurrentPath.");
+ return Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory);
}
-}
+
+
+}
\ No newline at end of file
diff --git a/AM2RLauncher/AM2RLauncherCore/HelperMethods.cs b/AM2RLauncher/AM2RLauncherCore/HelperMethods.cs
index 4f00e85..ba5c66b 100644
--- a/AM2RLauncher/AM2RLauncherCore/HelperMethods.cs
+++ b/AM2RLauncher/AM2RLauncherCore/HelperMethods.cs
@@ -1,177 +1,163 @@
-using LibGit2Sharp;
-using log4net;
+using log4net;
using System;
-using System.Collections.Generic;
using System.IO;
-using System.IO.Compression;
-using System.Linq;
using System.Net;
using System.Security.Cryptography;
-using System.Text;
-namespace AM2RLauncher.Core
+namespace AM2RLauncher.Core;
+
+///
+/// Class that has various Helper functions. Basically anything that could be used outside the Launcher resides here.
+///
+public static class HelperMethods
{
+ // Load reference to logger
///
- /// Class that has various Helper functions. Basically anything that could be used outside the Launcher resides here.
+ /// Our log object, that handles logging the current execution to a file.
///
- public static class HelperMethods
+ private static readonly ILog log = Core.Log;
+
+ // Thank you, Microsoft docs: https://docs.microsoft.com/en-us/dotnet/standard/io/how-to-copy-directories
+ // Slightly modified by adding overwriteFiles bool, as we need to replace readme, music, etc.
+ ///
+ /// This copies the contents of a specified Directory recursively to another Directory.
+ ///
+ /// Full Path to the Directory that will be recursively copied.
+ /// Full Path to the Directory you want to copy to. If the Directory does not exist, it will be created.
+ /// Specify if Files should be overwritten or not
+ /// Specify if you want to copy Sub-Directories as well.
+ public static void DirectoryCopy(string sourceDirName, string destDirName, bool overwriteFiles = true, bool copySubDirs = true)
{
- // Load reference to logger
- ///
- /// Our log object, that handles logging the current execution to a file.
- ///
- private static readonly ILog Log = Core.Log;
-
- // Thank you, Microsoft docs: https://docs.microsoft.com/en-us/dotnet/standard/io/how-to-copy-directories
- // Slightly modified by adding overwriteFiles bool, as we need to replace readme, music, etc.
- ///
- /// This copies the contents of a specified Directory recursively to another Directory.
- ///
- /// Full Path to the Directory that will be recursively copied.
- /// Full Path to the Directory you want to copy to. If the Directory does not exist, it will be created.
- /// Specify if Files should be overwritten or not
- /// Specify if you want to copy Sub-Directories as well.
- public static void DirectoryCopy(string sourceDirName, string destDirName, bool overwriteFiles = true, bool copySubDirs = true)
+ // Get the subdirectories for the specified directory.
+ DirectoryInfo dir = new DirectoryInfo(sourceDirName);
+
+ if (!dir.Exists)
{
- // Get the subdirectories for the specified directory.
- DirectoryInfo dir = new DirectoryInfo(sourceDirName);
-
- if (!dir.Exists)
- {
- throw new DirectoryNotFoundException(
- "Source directory does not exist or could not be found: "
- + sourceDirName);
- }
-
- DirectoryInfo[] dirs = dir.GetDirectories();
-
- // If the destination directory doesn't exist, create it.
- Directory.CreateDirectory(destDirName);
-
- // Get the files in the directory and copy them to the new location.
- FileInfo[] files = dir.GetFiles();
- foreach (FileInfo file in files)
- {
- string tempPath = Path.Combine(destDirName, file.Name);
- file.CopyTo(tempPath, overwriteFiles);
- }
-
- // If copying subdirectories, copy them and their contents to new location.
- if (!copySubDirs)
- return;
-
- foreach (DirectoryInfo subDir in dirs)
- {
- string tempPath = Path.Combine(destDirName, subDir.Name);
- DirectoryCopy(subDir.FullName, tempPath, overwriteFiles);
- }
+ throw new DirectoryNotFoundException(
+ "Source directory does not exist or could not be found: "
+ + sourceDirName);
+ }
+
+ DirectoryInfo[] dirs = dir.GetDirectories();
+ // If the destination directory doesn't exist, create it.
+ Directory.CreateDirectory(destDirName);
+
+ // Get the files in the directory and copy them to the new location.
+ FileInfo[] files = dir.GetFiles();
+ foreach (FileInfo file in files)
+ {
+ string tempPath = Path.Combine(destDirName, file.Name);
+ file.CopyTo(tempPath, overwriteFiles);
}
+ // If copying subdirectories, copy them and their contents to new location.
+ if (!copySubDirs)
+ return;
- ///
- /// This is a custom method, that deletes a Directory. The reason this is used, instead of ,
- /// is because this one sets the attributes of all files to be deletable, while does not do that on it's own.
- /// It's needed, because sometimes there are read-only files being generated, that would normally need more code in order to reset the attributes.
- /// Note, that this method acts recursively.
- ///
- /// The directory to delete.
- public static void DeleteDirectory(string targetDir)
+ foreach (DirectoryInfo subDir in dirs)
{
- if (!Directory.Exists(targetDir)) return;
+ string tempPath = Path.Combine(destDirName, subDir.Name);
+ DirectoryCopy(subDir.FullName, tempPath, overwriteFiles);
+ }
+
+ }
- File.SetAttributes(targetDir, FileAttributes.Normal);
- foreach (string file in Directory.GetFiles(targetDir))
- {
- File.SetAttributes(file, FileAttributes.Normal);
- File.Delete(file);
- }
+ ///
+ /// This is a custom method, that deletes a Directory. The reason this is used, instead of ,
+ /// is because this one sets the attributes of all files to be deletable, while does not do that on it's own.
+ /// It's needed, because sometimes there are read-only files being generated, that would normally need more code in order to reset the attributes.
+ /// Note, that this method acts recursively.
+ ///
+ /// The directory to delete.
+ public static void DeleteDirectory(string targetDir)
+ {
+ if (!Directory.Exists(targetDir)) return;
- foreach (string dir in Directory.GetDirectories(targetDir))
- {
- DeleteDirectory(dir);
- }
+ File.SetAttributes(targetDir, FileAttributes.Normal);
- Directory.Delete(targetDir, false);
+ foreach (string file in Directory.GetFiles(targetDir))
+ {
+ File.SetAttributes(file, FileAttributes.Normal);
+ File.Delete(file);
}
- ///
- /// Calculates an MD5 hash from a given file.
- ///
- /// Full Path to the file whose MD5 hash is supposed to be calculated.
- /// The MD5 hash as a , empty string if file does not exist.
- public static string CalculateMD5(string filename)
+ foreach (string dir in Directory.GetDirectories(targetDir))
{
- // Check if File exists first
- if (!File.Exists(filename))
- return "";
-
- using (var stream = File.OpenRead(filename))
- {
- using (var md5 = MD5.Create())
- {
- var hash = md5.ComputeHash(stream);
- return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
- }
- }
+ DeleteDirectory(dir);
}
- ///
- /// Performs recursive rollover on a set of log files.
- ///
- /// The log file to begin the rollover from.
- /// The maximum amount of log files to retain. Default is 9, as that's the highest digit.
- public static void RecursiveRollover(string logFile, int max = 9)
+ Directory.Delete(targetDir, false);
+ }
+
+ ///
+ /// Calculates an MD5 hash from a given file.
+ ///
+ /// Full Path to the file whose MD5 hash is supposed to be calculated.
+ /// The MD5 hash as a , empty string if file does not exist.
+ public static string CalculateMD5(string filename)
+ {
+ // Check if File exists first
+ if (!File.Exists(filename))
+ return "";
+
+ using var stream = File.OpenRead(filename);
+ using var md5 = MD5.Create();
+ var hash = md5.ComputeHash(stream);
+ return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
+ }
+
+ ///
+ /// Performs recursive rollover on a set of log files.
+ ///
+ /// The log file to begin the rollover from.
+ /// The maximum amount of log files to retain. Default is 9, as that's the highest digit.
+ public static void RecursiveRollover(string logFile, int max = 9)
+ {
+ int index = 1;
+ char endChar = logFile[logFile.Length - 1];
+ string fileName;
+
+ // If not the original file, set the new index and get the new fileName.
+ if (Char.IsNumber(endChar))
{
- int index = 1;
- char endChar = logFile[logFile.Length - 1];
- string fileName;
-
- // If not the original file, set the new index and get the new fileName.
- if (char.IsNumber(endChar))
- {
- index = int.Parse(endChar.ToString()) + 1;
- fileName = logFile.Remove(logFile.Length - 1) + index;
- }
- else // Otherwise, if the original file, just set fileName to log.txt.1.
- fileName = logFile + ".1";
-
- // If new name already exists, run the rollover algorithm on it!
- if (File.Exists(fileName))
- {
- RecursiveRollover(fileName, max);
- }
-
- //TODO: this can fail if one doesnt have permissions to move or delete the file
- // If index is less than max, rename file.
- if (index < max)
- {
- File.Move(logFile, fileName);
- }
- else // Otherwise, delete the file.
- File.Delete(logFile);
+ index = Int32.Parse(endChar.ToString()) + 1;
+ fileName = logFile.Remove(logFile.Length - 1) + index;
}
+ else // Otherwise, if the original file, just set fileName to log.txt.1.
+ fileName = logFile + ".1";
+
+ // If new name already exists, run the rollover algorithm on it!
+ if (File.Exists(fileName))
+ RecursiveRollover(fileName, max);
+
+ //TODO: this can fail if one doesnt have permissions to move or delete the file
+ // If index is less than max, rename file.
+ if (index < max)
+ File.Move(logFile, fileName);
+ else // Otherwise, delete the file.
+ File.Delete(logFile);
+ }
- ///
- /// Checks if we currently have an internet connection, by pinging github.
- ///
- /// if we have internet, if not.
- public static bool IsConnectedToInternet()
+ ///
+ /// Checks if we currently have an internet connection, by pinging github.
+ ///
+ /// if we have internet, if not.
+ public static bool IsConnectedToInternet()
+ {
+ log.Info("Checking internet connection...");
+ HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://github.com");
+ try
+ {
+ HttpWebResponse _ = (HttpWebResponse)request.GetResponse();
+ }
+ catch (WebException)
{
- Log.Info("Checking internet connection...");
- HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://github.com");
- try
- {
- HttpWebResponse response = (HttpWebResponse)request.GetResponse();
- }
- catch (WebException)
- {
- Log.Info("Internet connection failed.");
- return false;
- }
- Log.Info("Internet connection established!");
- return true;
+ log.Info("Internet connection failed.");
+ return false;
}
+ log.Info("Internet connection established!");
+ return true;
}
-}
+}
\ No newline at end of file
diff --git a/AM2RLauncher/AM2RLauncherCore/OS.cs b/AM2RLauncher/AM2RLauncherCore/OS.cs
index 23e581a..09dc0ba 100644
--- a/AM2RLauncher/AM2RLauncherCore/OS.cs
+++ b/AM2RLauncher/AM2RLauncherCore/OS.cs
@@ -1,53 +1,49 @@
-using System;
-using System.Collections.Generic;
-using System.Runtime.InteropServices;
-using System.Text;
+using System.Runtime.InteropServices;
-namespace AM2RLauncher.Core
+namespace AM2RLauncher.Core;
+
+///
+/// Class that has information about the current running operating system.
+///
+public static class OS
{
///
- /// Class that has information about the current running operating system.
+ /// Determines if the current OS is Windows.
///
- public class OS
- {
- ///
- /// Determines if the current OS is Windows.
- ///
- public static readonly bool IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
+ public static readonly bool IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
- ///
- /// Determines if the current OS is Linux.
- ///
- public static readonly bool IsLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
+ ///
+ /// Determines if the current OS is Linux.
+ ///
+ public static readonly bool IsLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
- ///
- /// Determines if the current OS is Mac.
- ///
- public static readonly bool IsMac = RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
+ ///
+ /// Determines if the current OS is Mac.
+ ///
+ public static readonly bool IsMac = RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
- ///
- /// Determines if the current OS is a unix based system (Mac or Linux).
- ///
- public static readonly bool IsUnix = IsLinux || IsMac;
+ ///
+ /// Determines if the current OS is a unix based system (Mac or Linux).
+ ///
+ public static readonly bool IsUnix = IsLinux || IsMac;
- ///
- /// Gets a string representation of the current OS.
- ///
- public static readonly string Name = DetermineOSName();
+ ///
+ /// Gets a string representation of the current OS.
+ ///
+ public static readonly string Name = DetermineOsName();
- ///
- /// Generates a string representation of the current OS
- ///
- private static string DetermineOSName()
- {
- if (IsWindows)
- return "Windows";
- else if (IsLinux)
- return "Linux";
- else if (IsMac)
- return "Mac";
- else
- return "Unknown OS";
- }
+ ///
+ /// Generates a string representation of the current OS
+ ///
+ private static string DetermineOsName()
+ {
+ if (IsWindows)
+ return "Windows";
+ if (IsLinux)
+ return "Linux";
+ if (IsMac)
+ return "Mac";
+
+ return "Unknown OS";
}
-}
+}
\ No newline at end of file
diff --git a/AM2RLauncher/AM2RLauncherCore/Profile.cs b/AM2RLauncher/AM2RLauncherCore/Profile.cs
index 181ed0d..e897e92 100644
--- a/AM2RLauncher/AM2RLauncherCore/Profile.cs
+++ b/AM2RLauncher/AM2RLauncherCore/Profile.cs
@@ -2,706 +2,703 @@
using LibGit2Sharp;
using log4net;
using System;
-using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
-using System.Text;
using System.Text.RegularExpressions;
-using System.Threading;
-namespace AM2RLauncher.Core
+namespace AM2RLauncher.Core;
+
+///
+/// An enum, that has possible return codes for .
+///
+public enum IsZipAM2R11ReturnCodes
+{
+ Successful,
+ MissingOrInvalidAM2RExe,
+ MissingOrInvalidD3DX9_43Dll,
+ MissingOrInvalidDataWin,
+ GameIsInASubfolder
+}
+
+///
+/// Class that has methods related to AM2RLauncher profiles.
+///
+public static class Profile
{
- ///
- /// An enum, that has possible return codes for .
- ///
- public enum IsZipAM2R11ReturnCodes
- {
- Successful,
- MissingOrInvalidAM2RExe,
- MissingOrInvalidD3DX9_43Dll,
- MissingOrInvalidDataWin,
- GameIsInASubfolder
- }
///
- /// Class that has methods related to AM2RLauncher profiles.
+ /// The logger for , used to write any caught exceptions.
///
- public static class Profile
- {
+ private static readonly ILog log = Core.Log;
- ///
- /// The logger for , used to write any caught exceptions.
- ///
- private static readonly ILog Log = Core.Log;
+ ///
+ /// Caches the result of so that we don't extract and verify it too often.
+ ///
+ private static bool? isAM2R11InstalledCache;
- ///
- /// Caches the result of so that we don't extract and verify it too often.
- ///
- private static bool? isAM2R11InstalledCache = null;
-
- ///
- /// Caches the MD5 hash of the provided AM2R_11.zip so we don't end up checking the zip if it hasn't changed.
- ///
- private static string lastAM2R11ZipMD5 = "";
+ ///
+ /// Caches the MD5 hash of the provided AM2R_11.zip so we don't end up checking the zip if it hasn't changed.
+ ///
+ 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.
- public static bool Is11Installed()
+ ///
+ /// 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()
+ {
+ InvalidateAM2R11InstallCache();
+
+ // If we have a cache, return that instead
+ if (isAM2R11InstalledCache != null) return isAM2R11InstalledCache.Value;
+
+ string am2r11file = CrossPlatformOperations.CURRENTPATH + "/AM2R_11.zip";
+ // Return safely if file doesn't exist
+ if (!File.Exists(am2r11file)) return false;
+ lastAM2R11ZipMD5 = HelperMethods.CalculateMD5(am2r11file);
+ var returnCode = CheckIfZipIsAM2R11(am2r11file);
+ // Check if it's valid, if not log it, rename it and silently leave
+ if (returnCode != IsZipAM2R11ReturnCodes.Successful)
{
- InvalidateAM2R11InstallCache();
-
- // If we have a cache, return that instead
- if (isAM2R11InstalledCache != null) return isAM2R11InstalledCache.Value;
-
- string am2r11file = CrossPlatformOperations.CURRENTPATH + "/AM2R_11.zip";
- // Return safely if file doesn't exist
- if (!File.Exists(am2r11file)) return false;
- lastAM2R11ZipMD5 = HelperMethods.CalculateMD5(am2r11file);
- var returnCode = Profile.CheckIfZipIsAM2R11(am2r11file);
- // Check if it's valid, if not log it, rename it and silently leave
- if (returnCode != IsZipAM2R11ReturnCodes.Successful)
- {
- Log.Info("Detected invalid AM2R_11 zip with following error code: " + returnCode);
- HelperMethods.RecursiveRollover(am2r11file);
- isAM2R11InstalledCache = false;
- return false;
- }
- isAM2R11InstalledCache = true;
- return true;
+ log.Info("Detected invalid AM2R_11 zip with following error code: " + returnCode);
+ HelperMethods.RecursiveRollover(am2r11file);
+ isAM2R11InstalledCache = false;
+ return false;
}
+ isAM2R11InstalledCache = true;
+ return true;
+ }
- ///
- /// Invalidates .
- ///
- private static void InvalidateAM2R11InstallCache()
- {
- // If the file exists, and its hash matches with ours, don't invalidate
- if (File.Exists(CrossPlatformOperations.CURRENTPATH + "/AM2R_11.zip") &&
- HelperMethods.CalculateMD5(CrossPlatformOperations.CURRENTPATH + "/AM2R_11.zip") == lastAM2R11ZipMD5)
- return;
+ ///
+ /// Invalidates .
+ ///
+ private static void InvalidateAM2R11InstallCache()
+ {
+ // If the file exists, and its hash matches with ours, don't invalidate
+ if (File.Exists(CrossPlatformOperations.CURRENTPATH + "/AM2R_11.zip") &&
+ HelperMethods.CalculateMD5(CrossPlatformOperations.CURRENTPATH + "/AM2R_11.zip") == lastAM2R11ZipMD5)
+ return;
- isAM2R11InstalledCache = null;
- }
+ isAM2R11InstalledCache = null;
+ }
- ///
- /// Git Pulls from the repository.
- ///
- public static void PullPatchData(Func TransferProgressHandlerMethod)
+ ///
+ /// Git Pulls from the repository.
+ ///
+ public static void PullPatchData(Func transferProgressHandlerMethod)
+ {
+ using (var repo = new Repository(CrossPlatformOperations.CURRENTPATH + "/PatchData"))
{
- using (var repo = new Repository(CrossPlatformOperations.CURRENTPATH + "/PatchData"))
- {
- // Permanently undo commits not pushed to remote
- Branch originMaster = repo.Branches.ToList().FirstOrDefault(b => b.FriendlyName.Contains("origin/master") || b.FriendlyName.Contains("origin/main"));
+ // Permanently undo commits not pushed to remote
+ Branch originMaster = repo.Branches.ToList().FirstOrDefault(b => b.FriendlyName.Contains("origin/master") || b.FriendlyName.Contains("origin/main"));
- if (originMaster == null)
- throw new UserCancelledException("Neither branch 'master' nor branch 'main' could be found! Corrupted or invalid git repo ? Deleting PatchData...");
-
- repo.Reset(ResetMode.Hard, originMaster.Tip);
+ if (originMaster == null)
+ throw new UserCancelledException("Neither branch 'master' nor branch 'main' could be found! Corrupted or invalid git repo ? Deleting PatchData...");
- // Credential information to fetch
+ repo.Reset(ResetMode.Hard, originMaster.Tip);
- PullOptions options = new PullOptions();
- options.FetchOptions = new FetchOptions();
- options.FetchOptions.OnTransferProgress += (tp) => TransferProgressHandlerMethod(tp);
+ // Credential information to fetch
- // User information to create a merge commit
- var signature = new Signature("null", "null", DateTimeOffset.Now);
+ PullOptions options = new PullOptions();
+ options.FetchOptions = new FetchOptions();
+ options.FetchOptions.OnTransferProgress += tp => transferProgressHandlerMethod(tp);
- // Pull
- try
- {
- Commands.Pull(repo, signature, options);
- }
- catch
- {
- Log.Error("Repository pull attempt failed!");
- return;
- }
+ // User information to create a merge commit
+ var signature = new Signature("null", "null", DateTimeOffset.Now);
+
+ // Pull
+ try
+ {
+ Commands.Pull(repo, signature, options);
+ }
+ catch
+ {
+ log.Error("Repository pull attempt failed!");
+ return;
}
- Log.Info("Repository pulled successfully.");
}
+ log.Info("Repository pulled successfully.");
+ }
- ///
- /// Installs .
- ///
- /// to be installed.
- public static void InstallProfile(ProfileXML profile, bool useHqMusic, IProgress progress)
- {
- Log.Info("Installing profile " + profile.Name + "...");
+ ///
+ /// Installs .
+ ///
+ /// to be installed.
+ /// Wether to patch this with high quality music or not.
+ /// Provides the current progress of this method.
+ public static void InstallProfile(ProfileXML profile, bool useHqMusic, IProgress progress)
+ {
+ log.Info("Installing profile " + profile.Name + "...");
- string profilesHomePath = CrossPlatformOperations.CURRENTPATH + "/Profiles";
- string profilePath = profilesHomePath + "/" + profile.Name;
+ string profilesHomePath = CrossPlatformOperations.CURRENTPATH + "/Profiles";
+ string profilePath = profilesHomePath + "/" + profile.Name;
- // Failsafe for Profiles directory
- if (!Directory.Exists(profilesHomePath))
- Directory.CreateDirectory(profilesHomePath);
+ // Failsafe for Profiles directory
+ if (!Directory.Exists(profilesHomePath))
+ Directory.CreateDirectory(profilesHomePath);
- // This failsafe should NEVER get triggered, but Miepee's broken this too much for me to trust it otherwise.
- if (Directory.Exists(profilePath))
- Directory.Delete(profilePath, true);
+ // This failsafe should NEVER get triggered, but Miepee's broken this too much for me to trust it otherwise.
+ if (Directory.Exists(profilePath))
+ Directory.Delete(profilePath, true);
- // Create profile directory
+ // Create profile directory
+ Directory.CreateDirectory(profilePath);
+
+ // Switch profilePath on Gtk
+ if (OS.IsLinux)
+ {
+ profilePath += "/assets";
+ Directory.CreateDirectory(profilePath);
+ }
+ else if (OS.IsMac)
+ {
+ // Folder structure for mac is like this:
+ // am2r.app -> Contents
+ // -Frameworks (some libs)
+ // -MacOS (runner)
+ // -Resources (asset path)
+ profilePath += "/AM2R.app/Contents";
Directory.CreateDirectory(profilePath);
+ Directory.CreateDirectory(profilePath + "/MacOS");
+ Directory.CreateDirectory(profilePath + "/Resources");
+ profilePath += "/Resources";
- // Switch profilePath on Gtk
- if (OS.IsLinux)
- {
- profilePath += "/assets";
- Directory.CreateDirectory(profilePath);
- }
- else if (OS.IsMac)
- {
- // Folder structure for mac is like this:
- // am2r.app -> Contents
- // -Frameworks (some libs)
- // -MacOS (runner)
- // -Resources (asset path)
- profilePath += "/AM2R.app/Contents";
- Directory.CreateDirectory(profilePath);
- Directory.CreateDirectory(profilePath + "/MacOS");
- Directory.CreateDirectory(profilePath + "/Resources");
- profilePath += "/Resources";
-
- Log.Info("ProfileInstallation: Created folder structure.");
- }
+ log.Info("ProfileInstallation: Created folder structure.");
+ }
- // Extract 1.1
- ZipFile.ExtractToDirectory(CrossPlatformOperations.CURRENTPATH + "/AM2R_11.zip", profilePath);
+ // Extract 1.1
+ ZipFile.ExtractToDirectory(CrossPlatformOperations.CURRENTPATH + "/AM2R_11.zip", profilePath);
- // Extracted 1.1
- progress.Report(33);
- Log.Info("Profile folder created and AM2R_11.zip extracted.");
+ // Extracted 1.1
+ progress.Report(33);
+ log.Info("Profile folder created and AM2R_11.zip extracted.");
- // Set local datapath for installation files
- var dataPath = CrossPlatformOperations.CURRENTPATH + profile.DataPath;
+ // Set local datapath for installation files
+ var dataPath = CrossPlatformOperations.CURRENTPATH + profile.DataPath;
- string datawin = null, exe = null;
+ string datawin = null, exe = null;
- if (OS.IsWindows)
- {
- datawin = "data.win";
- exe = "AM2R.exe";
- }
- else if (OS.IsLinux)
- {
- datawin = "game.unx";
- // Use the exe name based on the desktop file in the appimage, rather than hardcoding it.
- string desktopContents = File.ReadAllText(CrossPlatformOperations.CURRENTPATH + "/PatchData/data/AM2R.AppDir/AM2R.desktop");
- exe = Regex.Match(desktopContents, @"(?<=Exec=).*").Value;
- Log.Info("According to AppImage desktop file, using \"" + exe + "\" as game name.");
- }
- else if (OS.IsMac)
- {
- datawin = "game.ios";
- exe = "Mac_Runner";
- }
- else
- {
- Log.Error(OS.Name + " does not have valid runner / data.win names!");
- }
-
- Log.Info("Attempting to patch in " + profilePath);
+ if (OS.IsWindows)
+ {
+ datawin = "data.win";
+ exe = "AM2R.exe";
+ }
+ else if (OS.IsLinux)
+ {
+ datawin = "game.unx";
+ // Use the exe name based on the desktop file in the appimage, rather than hardcoding it.
+ string desktopContents = File.ReadAllText(CrossPlatformOperations.CURRENTPATH + "/PatchData/data/AM2R.AppDir/AM2R.desktop");
+ exe = Regex.Match(desktopContents, @"(?<=Exec=).*").Value;
+ log.Info("According to AppImage desktop file, using \"" + exe + "\" as game name.");
+ }
+ else if (OS.IsMac)
+ {
+ datawin = "game.ios";
+ exe = "Mac_Runner";
+ }
+ else
+ {
+ log.Error(OS.Name + " does not have valid runner / data.win names!");
+ }
- if (OS.IsWindows)
- {
- // Patch game executable
- if (profile.UsesYYC)
- {
- CrossPlatformOperations.ApplyXdeltaPatch(profilePath + "/data.win", dataPath + "/AM2R.xdelta", profilePath + "/" + exe);
+ log.Info("Attempting to patch in " + profilePath);
- // Delete 1.1's data.win, we don't need it anymore!
- File.Delete(profilePath + "/data.win");
- }
- else
- {
- CrossPlatformOperations.ApplyXdeltaPatch(profilePath + "/data.win", dataPath + "/data.xdelta", profilePath + "/" + datawin);
- CrossPlatformOperations.ApplyXdeltaPatch(profilePath + "/AM2R.exe", dataPath + "/AM2R.xdelta", profilePath + "/" + exe);
- }
- }
- else if (OS.IsUnix) // YYC and VM look exactly the same on Linux and Mac so we're all good here.
+ if (OS.IsWindows)
+ {
+ // Patch game executable
+ if (profile.UsesYYC)
{
- CrossPlatformOperations.ApplyXdeltaPatch(profilePath + "/data.win", dataPath + "/game.xdelta", profilePath + "/" + datawin);
- CrossPlatformOperations.ApplyXdeltaPatch(profilePath + "/AM2R.exe", dataPath + "/AM2R.xdelta", profilePath + "/" + exe);
- // Just in case the resulting file isn't chmoddded...
- Process.Start("chmod", "+x \"" + profilePath + "/" + exe + "\"")?.WaitForExit();
+ CrossPlatformOperations.ApplyXdeltaPatch(profilePath + "/data.win", dataPath + "/AM2R.xdelta", profilePath + "/" + exe);
- // These are not needed by linux or Mac at all, so we delete them
+ // Delete 1.1's data.win, we don't need it anymore!
File.Delete(profilePath + "/data.win");
- File.Delete(profilePath + "/AM2R.exe");
- File.Delete(profilePath + "/D3DX9_43.dll");
-
- // Move exe one directory out on Linux, move to MacOS folder instead on Mac
- if (OS.IsLinux)
- File.Move(profilePath + "/" + exe, profilePath.Substring(0, profilePath.LastIndexOf("/")) + "/" + exe);
- else
- File.Move(profilePath + "/" + exe, profilePath.Replace("Resources", "MacOS") + "/" + exe);
}
else
{
- Log.Error(OS.Name + " does not have patching methods!");
+ CrossPlatformOperations.ApplyXdeltaPatch(profilePath + "/data.win", dataPath + "/data.xdelta", profilePath + "/" + datawin);
+ CrossPlatformOperations.ApplyXdeltaPatch(profilePath + "/AM2R.exe", dataPath + "/AM2R.xdelta", profilePath + "/" + exe);
}
+ }
+ else if (OS.IsUnix) // YYC and VM look exactly the same on Linux and Mac so we're all good here.
+ {
+ CrossPlatformOperations.ApplyXdeltaPatch(profilePath + "/data.win", dataPath + "/game.xdelta", profilePath + "/" + datawin);
+ CrossPlatformOperations.ApplyXdeltaPatch(profilePath + "/AM2R.exe", dataPath + "/AM2R.xdelta", profilePath + "/" + exe);
+ // Just in case the resulting file isn't chmoddded...
+ Process.Start("chmod", "+x \"" + profilePath + "/" + exe + "\"")?.WaitForExit();
- // Applied patch
- if (OS.IsWindows || OS.IsMac) progress.Report(66);
- else if (OS.IsLinux) progress.Report(44); // Linux will take a bit longer, due to appimage creation
- Log.Info("xdelta patch(es) applied.");
+ // These are not needed by linux or Mac at all, so we delete them
+ File.Delete(profilePath + "/data.win");
+ File.Delete(profilePath + "/AM2R.exe");
+ File.Delete(profilePath + "/D3DX9_43.dll");
- // Install new datafiles
- HelperMethods.DirectoryCopy(dataPath + "/files_to_copy", profilePath);
+ // Move exe one directory out on Linux, move to MacOS folder instead on Mac
+ if (OS.IsLinux)
+ File.Move(profilePath + "/" + exe, profilePath.Substring(0, profilePath.LastIndexOf("/")) + "/" + exe);
+ else
+ File.Move(profilePath + "/" + exe, profilePath.Replace("Resources", "MacOS") + "/" + exe);
+ }
+ else
+ {
+ log.Error(OS.Name + " does not have patching methods!");
+ }
- // HQ music
- if (!profile.UsesCustomMusic && useHqMusic)
- HelperMethods.DirectoryCopy(CrossPlatformOperations.CURRENTPATH + "/PatchData/data/HDR_HQ_in-game_music", profilePath);
+ // Applied patch
+ if (OS.IsWindows || OS.IsMac) progress.Report(66);
+ else if (OS.IsLinux) progress.Report(44); // Linux will take a bit longer, due to appimage creation
+ log.Info("xdelta patch(es) applied.");
+ // Install new datafiles
+ HelperMethods.DirectoryCopy(dataPath + "/files_to_copy", profilePath);
- // Linux post-process
- if (OS.IsLinux)
- {
- string assetsPath = profilePath;
- profilePath = profilePath.Substring(0, profilePath.LastIndexOf("/"));
-
- // Rename all songs to lowercase
- foreach (var file in new DirectoryInfo(assetsPath).GetFiles())
- if (file.Name.EndsWith(".ogg") && !File.Exists(file.DirectoryName + "/" + file.Name.ToLower()))
- File.Move(file.FullName, file.DirectoryName + "/" + file.Name.ToLower());
-
- // Copy AppImage template to here
- HelperMethods.DirectoryCopy(CrossPlatformOperations.CURRENTPATH + "/PatchData/data/AM2R.AppDir", profilePath + "/AM2R.AppDir/");
-
- // Safety checks, in case the folders don't exist
- Directory.CreateDirectory(profilePath + "/AM2R.AppDir/usr/bin/");
- Directory.CreateDirectory(profilePath + "/AM2R.AppDir/usr/bin/assets/");
-
- // Copy game assets to the appimageDir
- HelperMethods.DirectoryCopy(assetsPath, profilePath + "/AM2R.AppDir/usr/bin/assets/");
- File.Copy(profilePath + "/" + exe, profilePath + "/AM2R.AppDir/usr/bin/" + exe);
-
- progress.Report(66);
- Log.Info("Gtk-specific formatting finished.");
-
- // Temp save the currentWorkingDirectory and console.error, change it to profilePath and null, call the script, and change it back.
- string workingDir = Directory.GetCurrentDirectory();
- TextWriter cliError = Console.Error;
- Directory.SetCurrentDirectory(profilePath);
- Console.SetError(new StreamWriter(Stream.Null));
- Environment.SetEnvironmentVariable("ARCH", "x86_64");
- Process.Start(CrossPlatformOperations.CURRENTPATH + "/PatchData/utilities/appimagetool-x86_64.AppImage", "-n AM2R.AppDir")?.WaitForExit();
- Directory.SetCurrentDirectory(workingDir);
- Console.SetError(cliError);
-
- // Clean files
- Directory.Delete(profilePath + "/AM2R.AppDir", true);
- Directory.Delete(assetsPath, true);
- File.Delete(profilePath + "/" + exe);
- if (File.Exists(profilePath + "/AM2R.AppImage")) File.Delete(profilePath + "/AM2R.AppImage");
- File.Move(profilePath + "/" + "AM2R-x86_64.AppImage", profilePath + "/AM2R.AppImage");
- }
- // Mac post-process
- else if (OS.IsMac)
- {
- // Rename all songs to lowercase
- 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);
- // 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);
- File.Copy(CrossPlatformOperations.CURRENTPATH + "/PatchData/data/PkgInfo", profilePath.Replace("Resources", "") + "/PkgInfo", true);
- //Put profilePath back to what it was before
- profilePath = profilesHomePath + "/" + profile.Name;
- }
+ // HQ music
+ if (!profile.UsesCustomMusic && useHqMusic)
+ HelperMethods.DirectoryCopy(CrossPlatformOperations.CURRENTPATH + "/PatchData/data/HDR_HQ_in-game_music", profilePath);
- // Copy profile.xml so we can grab data to compare for updates later!
- // tldr; check if we're in PatchData or not
- if (new DirectoryInfo(dataPath)?.Parent?.Name == "PatchData")
- File.Copy(dataPath + "/../profile.xml", profilePath + "/profile.xml");
- else File.Copy(dataPath + "/profile.xml", profilePath + "/profile.xml");
- // Installed datafiles
- progress.Report(100);
- Log.Info("Successfully installed profile " + profile.Name + ".");
+ // Linux post-process
+ if (OS.IsLinux)
+ {
+ string assetsPath = profilePath;
+ profilePath = profilePath.Substring(0, profilePath.LastIndexOf("/"));
+
+ // Rename all songs to lowercase
+ foreach (var file in new DirectoryInfo(assetsPath).GetFiles())
+ if (file.Name.EndsWith(".ogg") && !File.Exists(file.DirectoryName + "/" + file.Name.ToLower()))
+ File.Move(file.FullName, file.DirectoryName + "/" + file.Name.ToLower());
+
+ // Copy AppImage template to here
+ HelperMethods.DirectoryCopy(CrossPlatformOperations.CURRENTPATH + "/PatchData/data/AM2R.AppDir", profilePath + "/AM2R.AppDir/");
+
+ // Safety checks, in case the folders don't exist
+ Directory.CreateDirectory(profilePath + "/AM2R.AppDir/usr/bin/");
+ Directory.CreateDirectory(profilePath + "/AM2R.AppDir/usr/bin/assets/");
+
+ // Copy game assets to the appimageDir
+ HelperMethods.DirectoryCopy(assetsPath, profilePath + "/AM2R.AppDir/usr/bin/assets/");
+ File.Copy(profilePath + "/" + exe, profilePath + "/AM2R.AppDir/usr/bin/" + exe);
+
+ progress.Report(66);
+ log.Info("Gtk-specific formatting finished.");
+
+ // Temp save the currentWorkingDirectory and console.error, change it to profilePath and null, call the script, and change it back.
+ string workingDir = Directory.GetCurrentDirectory();
+ TextWriter cliError = Console.Error;
+ Directory.SetCurrentDirectory(profilePath);
+ Console.SetError(new StreamWriter(Stream.Null));
+ Environment.SetEnvironmentVariable("ARCH", "x86_64");
+ Process.Start(CrossPlatformOperations.CURRENTPATH + "/PatchData/utilities/appimagetool-x86_64.AppImage", "-n AM2R.AppDir")?.WaitForExit();
+ Directory.SetCurrentDirectory(workingDir);
+ Console.SetError(cliError);
+
+ // Clean files
+ Directory.Delete(profilePath + "/AM2R.AppDir", true);
+ Directory.Delete(assetsPath, true);
+ File.Delete(profilePath + "/" + exe);
+ if (File.Exists(profilePath + "/AM2R.AppImage")) File.Delete(profilePath + "/AM2R.AppImage");
+ File.Move(profilePath + "/" + "AM2R-x86_64.AppImage", profilePath + "/AM2R.AppImage");
}
-
- ///
- /// Checks if is installed.
- ///
- /// The that should be checked for installation.
- /// if yes, if not.
- public static bool IsProfileInstalled(ProfileXML profile)
+ // Mac post-process
+ else if (OS.IsMac)
{
- if (OS.IsWindows) return File.Exists(CrossPlatformOperations.CURRENTPATH + "/Profiles/" + profile.Name + "/AM2R.exe");
- else if (OS.IsLinux) return File.Exists(CrossPlatformOperations.CURRENTPATH + "/Profiles/" + profile.Name + "/AM2R.AppImage");
- else if (OS.IsMac) return Directory.Exists(CrossPlatformOperations.CURRENTPATH + "/Profiles/" + profile.Name + "/AM2R.app");
-
- Log.Error(OS.Name + " can't have profiles installed!");
- return false;
+ // Rename all songs to lowercase
+ 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);
+ // 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);
+ File.Copy(CrossPlatformOperations.CURRENTPATH + "/PatchData/data/PkgInfo", profilePath.Replace("Resources", "") + "/PkgInfo", true);
+ //Put profilePath back to what it was before
+ profilePath = profilesHomePath + "/" + profile.Name;
}
- ///
- /// Creates an APK of the selected .
- ///
- /// to be compiled into an APK.
- public static void CreateAPK(ProfileXML profile, bool useHqMusic, IProgress progress)
+ // Copy profile.xml so we can grab data to compare for updates later!
+ // tldr; check if we're in PatchData or not
+ if (new DirectoryInfo(dataPath).Parent?.Name == "PatchData")
+ File.Copy(dataPath + "/../profile.xml", profilePath + "/profile.xml");
+ else File.Copy(dataPath + "/profile.xml", profilePath + "/profile.xml");
+
+ // Installed datafiles
+ progress.Report(100);
+ log.Info("Successfully installed profile " + profile.Name + ".");
+ }
+
+ ///
+ /// Checks if is installed.
+ ///
+ /// The that should be checked for installation.
+ /// if yes, if not.
+ public static bool IsProfileInstalled(ProfileXML profile)
+ {
+ if (OS.IsWindows) return File.Exists(CrossPlatformOperations.CURRENTPATH + "/Profiles/" + profile.Name + "/AM2R.exe");
+ if (OS.IsLinux) return File.Exists(CrossPlatformOperations.CURRENTPATH + "/Profiles/" + profile.Name + "/AM2R.AppImage");
+ if (OS.IsMac) return Directory.Exists(CrossPlatformOperations.CURRENTPATH + "/Profiles/" + profile.Name + "/AM2R.app");
+
+ log.Error(OS.Name + " can't have profiles installed!");
+ return false;
+ }
+
+ ///
+ /// Creates an APK of the selected .
+ ///
+ /// to be compiled into an APK.
+ /// Wether to create the APK with high quality music or not.
+ /// Provides the current progress of this method.
+ public static void CreateAPK(ProfileXML profile, bool useHqMusic, IProgress progress)
+ {
+ // Overall safety check just in case of bad situations
+ if (!profile.SupportsAndroid)
{
- // Overall safety check just in case of bad situations
- if (!profile.SupportsAndroid)
- {
- progress.Report(100);
- return;
- }
- Log.Info("Creating Android APK for profile " + profile.Name + ".");
-
- // Create working dir after some cleanup
- string apktoolPath = CrossPlatformOperations.CURRENTPATH + "/PatchData/utilities/android/apktool.jar",
- uberPath = CrossPlatformOperations.CURRENTPATH + "/PatchData/utilities/android/uber-apk-signer.jar",
- tempDir = new DirectoryInfo(CrossPlatformOperations.CURRENTPATH + "/temp").FullName,
- dataPath = CrossPlatformOperations.CURRENTPATH + profile.DataPath;
- if (Directory.Exists(tempDir))
- Directory.Delete(tempDir, true);
- Directory.CreateDirectory(tempDir);
-
- Log.Info("Cleanup, variables, and working directory created.");
- progress.Report(14);
-
- // Decompile AM2RWrapper.apk
- CrossPlatformOperations.RunJavaJar("\"" + apktoolPath + "\" d \"" + dataPath + "/android/AM2RWrapper.apk\"", tempDir);
- Log.Info("AM2RWrapper decompiled.");
- progress.Report(28);
-
- // Add datafiles: 1.1, new datafiles, hq music, am2r.ini
- string workingDir = tempDir + "/AM2RWrapper/assets";
- ZipFile.ExtractToDirectory(CrossPlatformOperations.CURRENTPATH + "/AM2R_11.zip", workingDir);
- HelperMethods.DirectoryCopy(dataPath + "/files_to_copy", workingDir);
-
- if (useHqMusic)
- HelperMethods.DirectoryCopy(CrossPlatformOperations.CURRENTPATH + "/PatchData/data/HDR_HQ_in-game_music", workingDir);
- // Yes, I'm aware this is dumb. If you've got any better ideas for how to copy a seemingly randomly named .ini from this folder to the APK, please let me know.
- foreach (FileInfo file in new DirectoryInfo(dataPath).GetFiles().Where(f => f.Name.EndsWith("ini")))
- File.Copy(file.FullName, workingDir + "/" + file.Name);
-
- Log.Info("AM2R_11.zip extracted and datafiles copied into AM2RWrapper.");
- progress.Report(42);
-
- // Patch data.win to game.droid
- CrossPlatformOperations.ApplyXdeltaPatch(workingDir + "/data.win", dataPath + "/droid.xdelta", workingDir + "/game.droid");
- Log.Info("game.droid successfully patched.");
- progress.Report(56);
-
- // Delete unnecessary files
- File.Delete(workingDir + "/AM2R.exe");
- File.Delete(workingDir + "/D3DX9_43.dll");
- File.Delete(workingDir + "/explanations.txt");
- File.Delete(workingDir + "/modifiers.ini");
- File.Delete(workingDir + "/readme.txt");
- File.Delete(workingDir + "/data.win");
- Directory.Delete(workingDir + "/mods", true);
- Directory.Delete(workingDir + "/lang/headers", true);
- if (OS.IsLinux) File.Delete(workingDir + "/icon.png");
-
- // Modify apktool.yml to NOT compress ogg files
- string apktoolText = File.ReadAllText(workingDir + "/../apktool.yml");
- apktoolText = apktoolText.Replace("doNotCompress:", "doNotCompress:\n- ogg");
- File.WriteAllText(workingDir + "/../apktool.yml", apktoolText);
- Log.Info("Unnecessary files removed, apktool.yml modified to prevent ogg compression.");
- progress.Report(70);
-
- // Rebuild APK
- CrossPlatformOperations.RunJavaJar("\"" + apktoolPath + "\" b AM2RWrapper -o \"" + profile.Name + ".apk\"", tempDir);
- Log.Info("AM2RWrapper rebuilt into " + profile.Name + ".apk.");
- progress.Report(84);
-
- // Debug-sign APK
- CrossPlatformOperations.RunJavaJar("\"" + uberPath + "\" -a \"" + profile.Name + ".apk\"", tempDir);
-
- // Extra file cleanup
- File.Copy(tempDir + "/" + profile.Name + "-aligned-debugSigned.apk", CrossPlatformOperations.CURRENTPATH + "/" + profile.Name + ".apk", true);
- Log.Info(profile.Name + ".apk signed and moved to " + CrossPlatformOperations.CURRENTPATH + "/" + profile.Name + ".apk.");
- HelperMethods.DeleteDirectory(tempDir);
-
- // Done
progress.Report(100);
- Log.Info("Successfully created Android APK for profile " + profile.Name + ".");
- CrossPlatformOperations.OpenFolderAndSelectFile(CrossPlatformOperations.CURRENTPATH + "/" + profile.Name + ".apk");
+ return;
}
+ log.Info("Creating Android APK for profile " + profile.Name + ".");
+
+ // Create working dir after some cleanup
+ string apktoolPath = CrossPlatformOperations.CURRENTPATH + "/PatchData/utilities/android/apktool.jar",
+ uberPath = CrossPlatformOperations.CURRENTPATH + "/PatchData/utilities/android/uber-apk-signer.jar",
+ tempDir = new DirectoryInfo(CrossPlatformOperations.CURRENTPATH + "/temp").FullName,
+ dataPath = CrossPlatformOperations.CURRENTPATH + profile.DataPath;
+ if (Directory.Exists(tempDir))
+ Directory.Delete(tempDir, true);
+ Directory.CreateDirectory(tempDir);
+
+ log.Info("Cleanup, variables, and working directory created.");
+ progress.Report(14);
+
+ // Decompile AM2RWrapper.apk
+ CrossPlatformOperations.RunJavaJar("\"" + apktoolPath + "\" d \"" + dataPath + "/android/AM2RWrapper.apk\"", tempDir);
+ log.Info("AM2RWrapper decompiled.");
+ progress.Report(28);
+
+ // Add datafiles: 1.1, new datafiles, hq music, am2r.ini
+ string workingDir = tempDir + "/AM2RWrapper/assets";
+ ZipFile.ExtractToDirectory(CrossPlatformOperations.CURRENTPATH + "/AM2R_11.zip", workingDir);
+ HelperMethods.DirectoryCopy(dataPath + "/files_to_copy", workingDir);
+
+ if (useHqMusic)
+ HelperMethods.DirectoryCopy(CrossPlatformOperations.CURRENTPATH + "/PatchData/data/HDR_HQ_in-game_music", workingDir);
+ // Yes, I'm aware this is dumb. If you've got any better ideas for how to copy a seemingly randomly named .ini from this folder to the APK, please let me know.
+ foreach (FileInfo file in new DirectoryInfo(dataPath).GetFiles().Where(f => f.Name.EndsWith("ini")))
+ File.Copy(file.FullName, workingDir + "/" + file.Name);
+
+ log.Info("AM2R_11.zip extracted and datafiles copied into AM2RWrapper.");
+ progress.Report(42);
+
+ // Patch data.win to game.droid
+ CrossPlatformOperations.ApplyXdeltaPatch(workingDir + "/data.win", dataPath + "/droid.xdelta", workingDir + "/game.droid");
+ log.Info("game.droid successfully patched.");
+ progress.Report(56);
+
+ // Delete unnecessary files
+ File.Delete(workingDir + "/AM2R.exe");
+ File.Delete(workingDir + "/D3DX9_43.dll");
+ File.Delete(workingDir + "/explanations.txt");
+ File.Delete(workingDir + "/modifiers.ini");
+ File.Delete(workingDir + "/readme.txt");
+ File.Delete(workingDir + "/data.win");
+ Directory.Delete(workingDir + "/mods", true);
+ Directory.Delete(workingDir + "/lang/headers", true);
+ if (OS.IsLinux) File.Delete(workingDir + "/icon.png");
+
+ // Modify apktool.yml to NOT compress ogg files
+ string apktoolText = File.ReadAllText(workingDir + "/../apktool.yml");
+ apktoolText = apktoolText.Replace("doNotCompress:", "doNotCompress:\n- ogg");
+ File.WriteAllText(workingDir + "/../apktool.yml", apktoolText);
+ log.Info("Unnecessary files removed, apktool.yml modified to prevent ogg compression.");
+ progress.Report(70);
+
+ // Rebuild APK
+ CrossPlatformOperations.RunJavaJar("\"" + apktoolPath + "\" b AM2RWrapper -o \"" + profile.Name + ".apk\"", tempDir);
+ log.Info("AM2RWrapper rebuilt into " + profile.Name + ".apk.");
+ progress.Report(84);
+
+ // Debug-sign APK
+ CrossPlatformOperations.RunJavaJar("\"" + uberPath + "\" -a \"" + profile.Name + ".apk\"", tempDir);
+
+ // Extra file cleanup
+ File.Copy(tempDir + "/" + profile.Name + "-aligned-debugSigned.apk", CrossPlatformOperations.CURRENTPATH + "/" + profile.Name + ".apk", true);
+ log.Info(profile.Name + ".apk signed and moved to " + CrossPlatformOperations.CURRENTPATH + "/" + profile.Name + ".apk.");
+ HelperMethods.DeleteDirectory(tempDir);
+
+ // Done
+ progress.Report(100);
+ log.Info("Successfully created Android APK for profile " + profile.Name + ".");
+ CrossPlatformOperations.OpenFolderAndSelectFile(CrossPlatformOperations.CURRENTPATH + "/" + profile.Name + ".apk");
+ }
- ///
- /// Runs the Game, works cross platform.
- ///
- public static void RunGame(ProfileXML profile, bool useLogging, string envVars = "")
+ ///
+ /// Runs the Game, works cross platform.
+ ///
+ public static void RunGame(ProfileXML profile, bool useLogging, string envVars = "")
+ {
+ // These are used on both windows and linux for game logging
+ string savePath = OS.IsWindows ? profile.SaveLocation.Replace("%localappdata%", Environment.GetEnvironmentVariable("LOCALAPPDATA"))
+ : profile.SaveLocation.Replace("~", CrossPlatformOperations.NIXHOME);
+ DirectoryInfo logDir = new DirectoryInfo(savePath + "/logs");
+ string date = String.Join("-", DateTime.Now.ToString().Split(Path.GetInvalidFileNameChars(), StringSplitOptions.RemoveEmptyEntries));
+
+ log.Info("Launching game profile " + profile.Name + ".");
+ if (OS.IsWindows)
{
- // These are used on both windows and linux for game logging
- string savePath = OS.IsWindows ? profile.SaveLocation.Replace("%localappdata%", Environment.GetEnvironmentVariable("LOCALAPPDATA"))
- : profile.SaveLocation.Replace("~", CrossPlatformOperations.NIXHOME);
- DirectoryInfo logDir = new DirectoryInfo(savePath + "/logs");
- string date = String.Join("-", DateTime.Now.ToString().Split(Path.GetInvalidFileNameChars(), StringSplitOptions.RemoveEmptyEntries));
-
- Log.Info("Launching game profile " + profile.Name + ".");
- if (OS.IsWindows)
- {
- // Sets the arguments to empty, or to the profiles save path/logs and create time based logs. Creates the folder if necessary.
- string arguments = "";
+ // Sets the arguments to empty, or to the profiles save path/logs and create time based logs. Creates the folder if necessary.
+ string arguments = "";
- // Game logging
- if (useLogging)
- {
- Log.Info("Performing logging setup for profile " + profile.Name + ".");
+ // Game logging
+ if (useLogging)
+ {
+ log.Info("Performing logging setup for profile " + profile.Name + ".");
- if (!Directory.Exists(logDir.FullName))
- Directory.CreateDirectory(logDir.FullName);
+ if (!Directory.Exists(logDir.FullName))
+ Directory.CreateDirectory(logDir.FullName);
- if (File.Exists(logDir.FullName + "/" + profile.Name + ".txt"))
- HelperMethods.RecursiveRollover(logDir.FullName + "/" + profile.Name + ".txt", 5);
+ if (File.Exists(logDir.FullName + "/" + profile.Name + ".txt"))
+ HelperMethods.RecursiveRollover(logDir.FullName + "/" + profile.Name + ".txt", 5);
- StreamWriter stream = File.AppendText(logDir.FullName + "/" + profile.Name + ".txt");
+ StreamWriter stream = File.AppendText(logDir.FullName + "/" + profile.Name + ".txt");
- stream.WriteLine("AM2RLauncher " + Core.VERSION + " log generated at " + date);
+ stream.WriteLine("AM2RLauncher " + Core.VERSION + " log generated at " + date);
- if (Core.isThisRunningFromWine)
- stream.WriteLine("Using WINE!");
+ if (Core.IsThisRunningFromWine)
+ stream.WriteLine("Using WINE!");
- stream.Flush();
+ stream.Flush();
- stream.Close();
+ stream.Close();
- arguments = "-debugoutput \"" + logDir.FullName + "/" + profile.Name + ".txt\" -output \"" + logDir.FullName + "/" + profile.Name + ".txt\"";
- }
+ arguments = "-debugoutput \"" + logDir.FullName + "/" + profile.Name + ".txt\" -output \"" + logDir.FullName + "/" + profile.Name + ".txt\"";
+ }
- ProcessStartInfo proc = new ProcessStartInfo();
+ ProcessStartInfo proc = new ProcessStartInfo();
- proc.WorkingDirectory = CrossPlatformOperations.CURRENTPATH + "/Profiles/" + profile.Name;
- proc.FileName = proc.WorkingDirectory + "/AM2R.exe";
- proc.Arguments = arguments;
+ proc.WorkingDirectory = CrossPlatformOperations.CURRENTPATH + "/Profiles/" + profile.Name;
+ proc.FileName = proc.WorkingDirectory + "/AM2R.exe";
+ proc.Arguments = arguments;
- Log.Info("CWD of Profile is " + proc.WorkingDirectory);
+ log.Info("CWD of Profile is " + proc.WorkingDirectory);
- using (var p = Process.Start(proc))
- {
- Core.SetForegroundWindow(p.MainWindowHandle);
- p.WaitForExit();
- }
- }
- else if (OS.IsLinux)
- {
+ using var p = Process.Start(proc);
+ Core.SetForegroundWindow(p.MainWindowHandle);
+ p.WaitForExit();
+ }
+ else if (OS.IsLinux)
+ {
- ProcessStartInfo startInfo = new ProcessStartInfo();
- Log.Info("Is the environment textbox null or whitespace = " + String.IsNullOrWhiteSpace(envVars));
+ ProcessStartInfo startInfo = new ProcessStartInfo();
+ log.Info("Is the environment textbox null or whitespace = " + String.IsNullOrWhiteSpace(envVars));
- if (!String.IsNullOrWhiteSpace(envVars))
+ //TODO: make this more readable at one day
+ if (!String.IsNullOrWhiteSpace(envVars))
+ {
+ for (int i = 0; i < envVars.Count(f => f == '='); i++)
{
- for (int i = 0; i < envVars.Count(f => f == '='); i++)
+ // Env var variable
+ string variable = envVars.Substring(0, envVars.IndexOf('='));
+ envVars = envVars.Replace(variable + "=", "");
+
+ // This thing here is the value parser. Since values are sometimes in quotes, i need to compensate for them.
+ int valueSubstringLength;
+ if (envVars[0] != '"') // If value is not embedded in "", check if there are spaces left. If yes, get the index of the space, if not that was the last
+ {
+ if (envVars.IndexOf(' ') >= 0)
+ valueSubstringLength = envVars.IndexOf(' ') + 1;
+ else
+ valueSubstringLength = envVars.Length;
+ }
+ else // If value is embedded in "", check if there are spaces after the "". if yes, get index of that, if not that was the last
{
- // Env var variable
- string variable = envVars.Substring(0, envVars.IndexOf('='));
- envVars = envVars.Replace(variable + "=", "");
-
- // This thing here is the value parser. Since values are sometimes in quotes, i need to compensate for them.
- int valueSubstringLength = 0;
- if (envVars[0] != '"') // If value is not embedded in "", check if there are spaces left. If yes, get the index of the space, if not that was the last
- {
- if (envVars.IndexOf(' ') >= 0)
- valueSubstringLength = envVars.IndexOf(' ') + 1;
- else
- valueSubstringLength = envVars.Length;
- }
- else // If value is embedded in "", check if there are spaces after the "". if yes, get index of that, if not that was the last
- {
- int secondQuoteIndex = envVars.IndexOf('"', envVars.IndexOf('"') + 1);
- if (envVars.IndexOf(' ', secondQuoteIndex) >= 0)
- valueSubstringLength = envVars.IndexOf(' ', secondQuoteIndex) + 1;
- else
- valueSubstringLength = envVars.Length;
- }
- // Env var value
- string value = envVars.Substring(0, valueSubstringLength);
- envVars = envVars.Substring(value.Length);
-
- Log.Info("Adding variable \"" + variable + "\" with value \"" + value + "\"");
- startInfo.EnvironmentVariables[variable] = value;
+ int secondQuoteIndex = envVars.IndexOf('"', envVars.IndexOf('"') + 1);
+ if (envVars.IndexOf(' ', secondQuoteIndex) >= 0)
+ valueSubstringLength = envVars.IndexOf(' ', secondQuoteIndex) + 1;
+ else
+ valueSubstringLength = envVars.Length;
}
+ // Env var value
+ string value = envVars.Substring(0, valueSubstringLength);
+ envVars = envVars.Substring(value.Length);
+
+ log.Info("Adding variable \"" + variable + "\" with value \"" + value + "\"");
+ startInfo.EnvironmentVariables[variable] = value;
}
+ }
- // If we're supposed to log profiles, add events that track those and append them to this var. otherwise keep it null
- string terminalOutput = null;
+ // If we're supposed to log profiles, add events that track those and append them to this var. otherwise keep it null
+ string terminalOutput = null;
- startInfo.UseShellExecute = false;
- startInfo.WorkingDirectory = CrossPlatformOperations.CURRENTPATH + "/Profiles/" + profile.Name;
- startInfo.FileName = startInfo.WorkingDirectory + "/AM2R.AppImage";
+ startInfo.UseShellExecute = false;
+ startInfo.WorkingDirectory = CrossPlatformOperations.CURRENTPATH + "/Profiles/" + profile.Name;
+ startInfo.FileName = startInfo.WorkingDirectory + "/AM2R.AppImage";
- Log.Info("CWD of Profile is " + startInfo.WorkingDirectory);
+ log.Info("CWD of Profile is " + startInfo.WorkingDirectory);
- Log.Info("Launching game with following variables: ");
- foreach (System.Collections.DictionaryEntry item in startInfo.EnvironmentVariables)
- {
- Log.Info("Key: \"" + item.Key + "\" Value: \"" + item.Value + "\"");
- }
+ log.Info("Launching game with following variables: ");
+ foreach (System.Collections.DictionaryEntry item in startInfo.EnvironmentVariables)
+ {
+ log.Info("Key: \"" + item.Key + "\" Value: \"" + item.Value + "\"");
+ }
- using (Process p = new Process())
+ using (Process p = new Process())
+ {
+ p.StartInfo = startInfo;
+ if (useLogging)
{
- p.StartInfo = startInfo;
- if (useLogging)
- {
- p.StartInfo.RedirectStandardOutput = true;
- p.OutputDataReceived += (sender, e) => { terminalOutput += e.Data + "\n"; };
-
- p.StartInfo.RedirectStandardError = true;
- p.ErrorDataReceived += (sender, e) => { terminalOutput += e.Data + "\n"; };
- }
+ p.StartInfo.RedirectStandardOutput = true;
+ p.OutputDataReceived += (_, e) => { terminalOutput += e.Data + "\n"; };
- p.Start();
+ p.StartInfo.RedirectStandardError = true;
+ p.ErrorDataReceived += (_, e) => { terminalOutput += e.Data + "\n"; };
+ }
- if (useLogging)
- {
- p.BeginOutputReadLine();
- p.BeginErrorReadLine();
- }
+ p.Start();
- p.WaitForExit();
+ if (useLogging)
+ {
+ p.BeginOutputReadLine();
+ p.BeginErrorReadLine();
}
- if (terminalOutput != null)
- {
- Log.Info("Performed logging setup for profile " + profile.Name + ".");
+ p.WaitForExit();
+ }
- if (!Directory.Exists(logDir.FullName))
- Directory.CreateDirectory(logDir.FullName);
+ if (terminalOutput != null)
+ {
+ log.Info("Performed logging setup for profile " + profile.Name + ".");
- if (File.Exists(logDir.FullName + "/" + profile.Name + ".txt"))
- HelperMethods.RecursiveRollover(logDir.FullName + "/" + profile.Name + ".txt", 5);
+ if (!Directory.Exists(logDir.FullName))
+ Directory.CreateDirectory(logDir.FullName);
- StreamWriter stream = File.AppendText(logDir.FullName + "/" + profile.Name + ".txt");
+ if (File.Exists(logDir.FullName + "/" + profile.Name + ".txt"))
+ HelperMethods.RecursiveRollover(logDir.FullName + "/" + profile.Name + ".txt", 5);
- // Write general info
- stream.WriteLine("AM2RLauncher " + Core.VERSION + " log generated at " + date);
+ StreamWriter stream = File.AppendText(logDir.FullName + "/" + profile.Name + ".txt");
- // Write what was in the terminal
- stream.WriteLine(terminalOutput);
+ // Write general info
+ stream.WriteLine("AM2RLauncher " + Core.VERSION + " log generated at " + date);
- stream.Flush();
+ // Write what was in the terminal
+ stream.WriteLine(terminalOutput);
- stream.Close();
- }
+ stream.Flush();
+ stream.Close();
}
- else if (OS.IsMac)
- {
- // Sets the arguments to only open the game, or append the profiles save path/logs and create time based logs. Creates the folder if necessary.
- string arguments = "AM2R.app -W";
- // Game logging
- if (useLogging)
- {
- Log.Info("Performing logging setup for profile " + profile.Name + ".");
+ }
+ else if (OS.IsMac)
+ {
+ // Sets the arguments to only open the game, or append the profiles save path/logs and create time based logs. Creates the folder if necessary.
+ string arguments = "AM2R.app -W";
- if (!Directory.Exists(logDir.FullName))
- Directory.CreateDirectory(logDir.FullName);
+ // Game logging
+ if (useLogging)
+ {
+ log.Info("Performing logging setup for profile " + profile.Name + ".");
- if (File.Exists(logDir.FullName + "/" + profile.Name + ".txt"))
- HelperMethods.RecursiveRollover(logDir.FullName + "/" + profile.Name + ".txt", 5);
+ if (!Directory.Exists(logDir.FullName))
+ Directory.CreateDirectory(logDir.FullName);
- StreamWriter stream = File.AppendText(logDir.FullName + "/" + profile.Name + ".txt");
+ if (File.Exists(logDir.FullName + "/" + profile.Name + ".txt"))
+ HelperMethods.RecursiveRollover(logDir.FullName + "/" + profile.Name + ".txt", 5);
- stream.WriteLine("AM2RLauncher " + Core.VERSION + " log generated at " + date);
+ StreamWriter stream = File.AppendText(logDir.FullName + "/" + profile.Name + ".txt");
- stream.Flush();
+ stream.WriteLine("AM2RLauncher " + Core.VERSION + " log generated at " + date);
- stream.Close();
+ stream.Flush();
- arguments += " --stdout \"" + logDir.FullName + "/" + profile.Name + ".txt\" --stderr \"" + logDir.FullName + "/" + profile.Name + ".txt\"";
- }
+ stream.Close();
- ProcessStartInfo proc = new ProcessStartInfo();
+ arguments += " --stdout \"" + logDir.FullName + "/" + profile.Name + ".txt\" --stderr \"" + logDir.FullName + "/" + profile.Name + ".txt\"";
+ }
- proc.WorkingDirectory = CrossPlatformOperations.CURRENTPATH + "/Profiles/" + profile.Name;
- proc.FileName = "open";
- proc.Arguments = arguments;
+ ProcessStartInfo proc = new ProcessStartInfo();
- Log.Info("CWD of Profile is " + proc.WorkingDirectory);
+ proc.WorkingDirectory = CrossPlatformOperations.CURRENTPATH + "/Profiles/" + profile.Name;
+ proc.FileName = "open";
+ proc.Arguments = arguments;
- using (var p = Process.Start(proc))
- {
- p?.WaitForExit();
- }
- }
- else
- Log.Error(OS.Name + " cannot run games!");
+ log.Info("CWD of Profile is " + proc.WorkingDirectory);
- Log.Info("Profile " + profile.Name + " process exited.");
+ using var p = Process.Start(proc);
+ p?.WaitForExit();
}
+ else
+ log.Error(OS.Name + " cannot run games!");
- ///
- /// Checks if the repository has been validly cloned already.
- ///
- /// if yes, if not.
- public static bool IsPatchDataCloned()
- {
- // isValid seems to only check for a .git folder, and there are cases where that exists, but not the profile.xml
- return Repository.IsValid(CrossPlatformOperations.CURRENTPATH + "/PatchData") && File.Exists(CrossPlatformOperations.CURRENTPATH + "/PatchData/profile.xml");
- }
+ log.Info("Profile " + profile.Name + " process exited.");
+ }
- ///
- /// Checks if a Zip file is a valid AM2R_1.1 zip.
- ///
- /// Full Path to the Zip file to check.
- /// detailing the result
- public static IsZipAM2R11ReturnCodes CheckIfZipIsAM2R11(string zipPath)
- {
- const string d3dHash = "86e39e9161c3d930d93822f1563c280d";
- const string dataWinHash = "f2b84fe5ba64cb64e284be1066ca08ee";
- const string am2rHash = "15253f7a66d6ea3feef004ebbee9b438";
-
- string tmpPath = Path.GetTempPath() + Path.GetFileNameWithoutExtension(zipPath);
-
- // Clean up in case folder exists already
- if (Directory.Exists(tmpPath))
- Directory.Delete(tmpPath, true);
-
- Directory.CreateDirectory(tmpPath);
-
- // Open archive
- ZipArchive am2rZip = ZipFile.OpenRead(zipPath);
-
- // Check if exe exists anywhere
- ZipArchiveEntry am2rExe = am2rZip.Entries.FirstOrDefault(x => x.FullName.Contains("AM2R.exe"));
- if (am2rExe == null)
- return IsZipAM2R11ReturnCodes.MissingOrInvalidAM2RExe;
- // Check if it's not in a subfolder. if it'd be in a subfolder, fullname would be "folder/AM2R.exe"
- if (am2rExe.FullName != "AM2R.exe")
- return IsZipAM2R11ReturnCodes.GameIsInASubfolder;
- // Check validity
- am2rExe.ExtractToFile(tmpPath + "/" + am2rExe.FullName);
- if (HelperMethods.CalculateMD5(tmpPath + "/" + am2rExe.FullName) != am2rHash)
- return IsZipAM2R11ReturnCodes.MissingOrInvalidAM2RExe;
-
- // Check if data.win exists / is valid
- ZipArchiveEntry dataWin = am2rZip.Entries.FirstOrDefault(x => x.FullName == "data.win");
- if (dataWin == null)
- return IsZipAM2R11ReturnCodes.MissingOrInvalidDataWin;
- dataWin.ExtractToFile(tmpPath + "/" + dataWin.FullName);
- if (HelperMethods.CalculateMD5(tmpPath + "/" + dataWin.FullName) != dataWinHash)
- return IsZipAM2R11ReturnCodes.MissingOrInvalidDataWin;
-
- // Check if d3d.dll exists / is valid
- ZipArchiveEntry d3dx = am2rZip.Entries.FirstOrDefault(x => x.FullName == "D3DX9_43.dll");
- if (d3dx == null)
- return IsZipAM2R11ReturnCodes.MissingOrInvalidD3DX9_43Dll;
- d3dx.ExtractToFile(tmpPath + "/" + d3dx.FullName);
- if (HelperMethods.CalculateMD5(tmpPath + "/" + d3dx.FullName) != d3dHash)
- return IsZipAM2R11ReturnCodes.MissingOrInvalidD3DX9_43Dll;
-
- // Clean up
+ ///
+ /// Checks if the repository has been validly cloned already.
+ ///
+ /// if yes, if not.
+ public static bool IsPatchDataCloned()
+ {
+ // isValid seems to only check for a .git folder, and there are cases where that exists, but not the profile.xml
+ return Repository.IsValid(CrossPlatformOperations.CURRENTPATH + "/PatchData") && File.Exists(CrossPlatformOperations.CURRENTPATH + "/PatchData/profile.xml");
+ }
+
+ ///
+ /// Checks if a Zip file is a valid AM2R_1.1 zip.
+ ///
+ /// Full Path to the Zip file to check.
+ /// detailing the result
+ public static IsZipAM2R11ReturnCodes CheckIfZipIsAM2R11(string zipPath)
+ {
+ const string d3dHash = "86e39e9161c3d930d93822f1563c280d";
+ const string dataWinHash = "f2b84fe5ba64cb64e284be1066ca08ee";
+ const string am2rHash = "15253f7a66d6ea3feef004ebbee9b438";
+
+ string tmpPath = Path.GetTempPath() + Path.GetFileNameWithoutExtension(zipPath);
+
+ // Clean up in case folder exists already
+ if (Directory.Exists(tmpPath))
Directory.Delete(tmpPath, true);
- // If we didn't exit before, everything is fine
- Log.Info("AM2R_11 check successful!");
- return IsZipAM2R11ReturnCodes.Successful;
- }
+ Directory.CreateDirectory(tmpPath);
+
+ // Open archive
+ ZipArchive am2rZip = ZipFile.OpenRead(zipPath);
+
+ // Check if exe exists anywhere
+ ZipArchiveEntry am2rExe = am2rZip.Entries.FirstOrDefault(x => x.FullName.Contains("AM2R.exe"));
+ if (am2rExe == null)
+ return IsZipAM2R11ReturnCodes.MissingOrInvalidAM2RExe;
+ // Check if it's not in a subfolder. if it'd be in a subfolder, fullname would be "folder/AM2R.exe"
+ if (am2rExe.FullName != "AM2R.exe")
+ return IsZipAM2R11ReturnCodes.GameIsInASubfolder;
+ // Check validity
+ am2rExe.ExtractToFile(tmpPath + "/" + am2rExe.FullName);
+ if (HelperMethods.CalculateMD5(tmpPath + "/" + am2rExe.FullName) != am2rHash)
+ return IsZipAM2R11ReturnCodes.MissingOrInvalidAM2RExe;
+
+ // Check if data.win exists / is valid
+ ZipArchiveEntry dataWin = am2rZip.Entries.FirstOrDefault(x => x.FullName == "data.win");
+ if (dataWin == null)
+ return IsZipAM2R11ReturnCodes.MissingOrInvalidDataWin;
+ dataWin.ExtractToFile(tmpPath + "/" + dataWin.FullName);
+ if (HelperMethods.CalculateMD5(tmpPath + "/" + dataWin.FullName) != dataWinHash)
+ return IsZipAM2R11ReturnCodes.MissingOrInvalidDataWin;
+
+ // Check if d3d.dll exists / is valid
+ ZipArchiveEntry d3dx = am2rZip.Entries.FirstOrDefault(x => x.FullName == "D3DX9_43.dll");
+ if (d3dx == null)
+ return IsZipAM2R11ReturnCodes.MissingOrInvalidD3DX9_43Dll;
+ d3dx.ExtractToFile(tmpPath + "/" + d3dx.FullName);
+ if (HelperMethods.CalculateMD5(tmpPath + "/" + d3dx.FullName) != d3dHash)
+ return IsZipAM2R11ReturnCodes.MissingOrInvalidD3DX9_43Dll;
+
+ // Clean up
+ Directory.Delete(tmpPath, true);
+
+ // If we didn't exit before, everything is fine
+ log.Info("AM2R_11 check successful!");
+ return IsZipAM2R11ReturnCodes.Successful;
}
-}
+}
\ No newline at end of file
diff --git a/AM2RLauncher/AM2RLauncherCore/Splash.cs b/AM2RLauncher/AM2RLauncherCore/Splash.cs
index 1c511ce..3f5da5a 100644
--- a/AM2RLauncher/AM2RLauncherCore/Splash.cs
+++ b/AM2RLauncher/AM2RLauncherCore/Splash.cs
@@ -1,131 +1,130 @@
using System;
using System.Linq;
-namespace AM2RLauncher.Core
+namespace AM2RLauncher.Core;
+
+///
+/// Class only for providing Splashes
+///
+public static class Splash
{
///
- /// Class only for providing Splashes
+ /// Cross-Platform splash strings
///
- public static class Splash
+ private static readonly string[] generalSplash =
{
- ///
- /// Cross-Platform splash strings
- ///
- private static readonly string[] generalSplash =
- {
- "The real Ridley is the friends we made along the way.",
- "Now with 100% more Septoggs!",
- "Now with 100% more Blob Throwers!",
- "Speedrun THIS, I dare you.",
- "The broken pipe is a lie.",
- "Overcommitting to April Fool's since 2018.",
- "Also try Metroid II: Return of Samus!",
- "Also try Metroid: Samus Returns!",
- "Also try Prime 2D!",
- "Trust me, it's an 'unintentional feature.'",
- "Coming soon to a PC near you!",
- "This ain't your parents' Metroid 2!",
- "Now setting boss pattern to S P E E N",
- "You S P E E N me right round, baby!",
- "Wait, I thought Metroid was a guy!",
- "jellyfish is helping yes",
- "Why can't Metroid crawl?",
- "When in doubt, blame GameMaker.",
- "It just works™",
- "Reject C++, return to ABSTRACTION",
- "C# is just C++++ with Windows support.",
- "Use of the Launcher has now been authorized!",
- "Oh? So you're patching me?",
- "I, Gawron Giovana, have a dream.",
- "Oooh weee ooo, I look just like an Omega",
- "AH THE MOLE",
- "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?"
- };
+ "The real Ridley is the friends we made along the way.",
+ "Now with 100% more Septoggs!",
+ "Now with 100% more Blob Throwers!",
+ "Speedrun THIS, I dare you.",
+ "The broken pipe is a lie.",
+ "Overcommitting to April Fool's since 2018.",
+ "Also try Metroid II: Return of Samus!",
+ "Also try Metroid: Samus Returns!",
+ "Also try Prime 2D!",
+ "Trust me, it's an 'unintentional feature.'",
+ "Coming soon to a PC near you!",
+ "This ain't your parents' Metroid 2!",
+ "Now setting boss pattern to S P E E N",
+ "You S P E E N me right round, baby!",
+ "Wait, I thought Metroid was a guy!",
+ "jellyfish is helping yes",
+ "Why can't Metroid crawl?",
+ "When in doubt, blame GameMaker.",
+ "It just works™",
+ "Reject C++, return to ABSTRACTION",
+ "C# is just C++++ with Windows support.",
+ "Use of the Launcher has now been authorized!",
+ "Oh? So you're patching me?",
+ "I, Gawron Giovana, have a dream.",
+ "Oooh weee ooo, I look just like an Omega",
+ "AH THE MOLE",
+ "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?"
+ };
- ///
- /// Windows only splash strings
- ///
- private static readonly string[] windowsSplash =
- {
- ":(",
- "All your machine are belong to MS"
- };
+ ///
+ /// Windows only splash strings
+ ///
+ private static readonly string[] windowsSplash =
+ {
+ ":(",
+ "All your machine are belong to MS"
+ };
- ///
- /// Linux only splash strings
- ///
- private static readonly string[] linuxSplash =
- {
- "Sorry this is ugly, but at least it works.",
- "GTK + QT = 💣",
- "I hope you use Arch, btw",
- "All your Ubuntu are belong to Arch btw.",
- "Help, how do I quit vim!?",
- "The bloat isn't our fault, YoYo Games forced 1GB dependencies!",
- "On second thought, maybe the bloat is our fault...",
- "The quieter you are, the more Metroids you can hear.",
- "What you are referring to as AM2R, is in fact, GNU/AM2R.",
- "GNOME be gone!",
- "Go compile your own girlfriend. This one doesn't count, she's out of your league.",
- "Year 3115, NVIDIA still doesn't support Wayland.",
- "Was a mouse really that expensive, i3 users!?",
- "Imagine using non-free software.",
- "What if... we used a non-FOSS OS? Haha just kidding... Unless?",
- "🐧",
- "You are already patched 🐸🕶",
- "Yes, do as I say!",
- "Did you find the penguin yet?"
- };
+ ///
+ /// Linux only splash strings
+ ///
+ private static readonly string[] linuxSplash =
+ {
+ "Sorry this is ugly, but at least it works.",
+ "GTK + QT = 💣",
+ "I hope you use Arch, btw",
+ "All your Ubuntu are belong to Arch btw.",
+ "Help, how do I quit vim!?",
+ "The bloat isn't our fault, YoYo Games forced 1GB dependencies!",
+ "On second thought, maybe the bloat is our fault...",
+ "The quieter you are, the more Metroids you can hear.",
+ "What you are referring to as AM2R, is in fact, GNU/AM2R.",
+ "GNOME be gone!",
+ "Go compile your own girlfriend. This one doesn't count, she's out of your league.",
+ "Year 3115, NVIDIA still doesn't support Wayland.",
+ "Was a mouse really that expensive, i3 users!?",
+ "Imagine using non-free software.",
+ "What if... we used a non-FOSS OS? Haha just kidding... Unless?",
+ "🐧",
+ "You are already patched 🐸🕶",
+ "Yes, do as I say!",
+ "Did you find the penguin yet?"
+ };
- ///
- /// Mac only splash strings
- ///
- private static readonly string[] macSplash =
- {
- "Does this even work?",
- "You weren't supposed to do that!",
- "Another Mac 2 Remake",
- "This shouldn't even be possible",
- "How long until this breaks?",
- "Have fun trying to convince modders to support this!"
- };
+ ///
+ /// Mac only splash strings
+ ///
+ private static readonly string[] macSplash =
+ {
+ "Does this even work?",
+ "You weren't supposed to do that!",
+ "Another Mac 2 Remake",
+ "This shouldn't even be possible",
+ "How long until this breaks?",
+ "Have fun trying to convince modders to support this!"
+ };
- ///
- /// Combined splash strings
- ///
- private static readonly string[] combinedSplash = combineSplashes();
+ ///
+ /// Combined splash strings
+ ///
+ private static readonly string[] combinedSplash = CombineSplashes();
- ///
- /// Get a random splash string, according to the current OS.
- ///
- /// The randomly chosen splash as a .
- public static string GetSplash()
- {
- Random rng = new Random();
+ ///
+ /// Get a random splash string, according to the current OS.
+ ///
+ /// The randomly chosen splash as a .
+ public static string GetSplash()
+ {
+ Random rng = new Random();
- string splashString = combinedSplash[rng.Next(0, combinedSplash.Length)];
- return splashString;
- }
+ string splashString = combinedSplash[rng.Next(0, combinedSplash.Length)];
+ return splashString;
+ }
- ///
- /// Creates a string srray which is concatonated with the splash array for the current OS
- ///
- /// A string array where and the splash array for the current OS have been concatonated.
- private static string[] combineSplashes()
- {
- string[] totalSplashes;
- if (OS.IsWindows)
- totalSplashes = generalSplash.Concat(windowsSplash).ToArray();
- else if (OS.IsLinux)
- totalSplashes = generalSplash.Concat(linuxSplash).ToArray();
- else if (OS.IsMac)
- totalSplashes = generalSplash.Concat(macSplash).ToArray();
- else
- totalSplashes = generalSplash;
- return totalSplashes;
- }
+ ///
+ /// Creates a string srray which is concatonated with the splash array for the current OS
+ ///
+ /// A string array where and the splash array for the current OS have been concatonated.
+ private static string[] CombineSplashes()
+ {
+ string[] totalSplashes;
+ if (OS.IsWindows)
+ totalSplashes = generalSplash.Concat(windowsSplash).ToArray();
+ else if (OS.IsLinux)
+ totalSplashes = generalSplash.Concat(linuxSplash).ToArray();
+ else if (OS.IsMac)
+ totalSplashes = generalSplash.Concat(macSplash).ToArray();
+ else
+ totalSplashes = generalSplash;
+ return totalSplashes;
}
-}
+}
\ No newline at end of file
diff --git a/AM2RLauncher/AM2RLauncherCore/XML/LauncherConfigXML.cs b/AM2RLauncher/AM2RLauncherCore/XML/LauncherConfigXML.cs
index de58353..7d7418c 100644
--- a/AM2RLauncher/AM2RLauncherCore/XML/LauncherConfigXML.cs
+++ b/AM2RLauncher/AM2RLauncherCore/XML/LauncherConfigXML.cs
@@ -2,153 +2,152 @@
using System.Linq;
using System.Xml.Serialization;
-namespace AM2RLauncher.Core.XML
+namespace AM2RLauncher.Core.XML;
+
+///
+/// Class that handles how the Launcher settings are saved as XML. Only affects Linux
+///
+[Serializable]
+[XmlRoot("settings")]
+public class LauncherConfigXML
{
+ /// Indicates wether or not to auto-update the Launcher. Used for
+ [XmlAttribute("AutoUpdateAM2R")]
+ public bool AutoUpdateAM2R
+ { get; set; }
+ /// Indicates wether or not to auto-update the Launcher. Used for
+ [XmlAttribute("AutoUpdateLauncher")]
+ public bool AutoUpdateLauncher
+ { get; set; }
+ /// Indicates the Language of the Launcher. Used for
+ [XmlAttribute("Language")]
+ public string Language
+ { get; set; }
+ /// Indicates wether or not to use High-quality music when patching to PC. Used for
+ [XmlAttribute("MusicHQPC")]
+ public bool MusicHQPC
+ { get; set; }
+ /// Indicates wether or not to use High-quality music when patching to Android. Used for
+ [XmlAttribute("MusicHQAndroid")]
+ public bool MusicHQAndroid
+ { get; set; }
+ /// Indicates the index for .
+ [XmlAttribute("MirrorIndex")]
+ public int MirrorIndex
+ { get; set; }
+ /// Indicates the index for .
+ [XmlAttribute("ProfileIndex")]
+ public string ProfileIndex
+ { get; set; }
+ /// Indicates wether or not to have custom mirrors enabled. Used for
+ [XmlAttribute("CustomMirrorEnabled")]
+ public bool CustomMirrorEnabled
+ { get; set; }
+ /// Indicates the custom mirror as a text. Used for
+ [XmlAttribute("CustomMirrorText")]
+ public string CustomMirrorText
+ { get; set; }
+ /// Indicates whether or not to create debug logs of profile. Used for
+ [XmlAttribute("ProfileDebugLog")]
+ public bool ProfileDebugLog
+ { get; set; }
+ /// Indicates the custom environment variable(s) as text. Used for
+ [XmlAttribute("CustomEnvVar")]
+ public string CustomEnvVar
+ { get; set; }
+ /// Indicates the Width of the Launcher.
+ [XmlAttribute("Width")]
+ public int Width
+ { get; set; }
+ /// Indicates the Height of the Launcher.
+ [XmlAttribute("Height")]
+ public int Height
+ { get; set; }
+ /// Indicates wether or not the Launcher is maximized or not.
+ [XmlAttribute("IsMaximized")]
+ public bool IsMaximized
+ { get; set; }
+
+ // Huge help from James for all of this!!!
+ // Here's a short explanation of this. Basically, what we do is create an indexer. This makes it possible for this class to be indexed, like this LauncherConfigXML[i]
+ // The indexer here has a get and set "submethod". And both use Reflection to get the current class as something that can be used with lambda values
+ // So for get we just lambda the properties and search for something that can be read and has the same name as the input property. After that, we just get the value and return it as a string
+ // Set is basiaclly the same, but instead of returning it, we set the prtoperty value, which would be followed after the `='.
+ // So LauncherConfigXML[property] = hellWorld would set the value of `property` to `hellWorld`
///
- /// Class that handles how the Launcher settings are saved as XML. Only affects Linux
+ /// An Indexer for . Not to be used directly, use
+ /// or instead!
///
- [Serializable]
- [XmlRoot("settings")]
- public class LauncherConfigXML
+ /// The property to get or set.
+ /// The value of as an if used as a get, if used as a set.
+ public object this[string property]
{
- /// Indicates wether or not to auto-update the Launcher. Used for
- [XmlAttribute("AutoUpdateAM2R")]
- public bool AutoUpdateAM2R
- { get; set; }
- /// Indicates wether or not to auto-update the Launcher. Used for
- [XmlAttribute("AutoUpdateLauncher")]
- public bool AutoUpdateLauncher
- { get; set; }
- /// Indicates the Language of the Launcher. Used for
- [XmlAttribute("Language")]
- public string Language
- { get; set; }
- /// Indicates wether or not to use High-quality music when patching to PC. Used for
- [XmlAttribute("MusicHQPC")]
- public bool MusicHQPC
- { get; set; }
- /// Indicates wether or not to use High-quality music when patching to Android. Used for
- [XmlAttribute("MusicHQAndroid")]
- public bool MusicHQAndroid
- { get; set; }
- /// Indicates the index for .
- [XmlAttribute("MirrorIndex")]
- public int MirrorIndex
- { get; set; }
- /// Indicates the index for .
- [XmlAttribute("ProfileIndex")]
- public string ProfileIndex
- { get; set; }
- /// Indicates wether or not to have custom mirrors enabled. Used for
- [XmlAttribute("CustomMirrorEnabled")]
- public bool CustomMirrorEnabled
- { get; set; }
- /// Indicates the custom mirror as a text. Used for
- [XmlAttribute("CustomMirrorText")]
- public string CustomMirrorText
- { get; set; }
- /// Indicates whether or not to create debug logs of profile. Used for
- [XmlAttribute("ProfileDebugLog")]
- public bool ProfileDebugLog
- { get; set; }
- /// Indicates the custom environment variable(s) as text. Used for
- [XmlAttribute("CustomEnvVar")]
- public string CustomEnvVar
- { get; set; }
- /// Indicates the Width of the Launcher.
- [XmlAttribute("Width")]
- public int Width
- { get; set; }
- /// Indicates the Height of the Launcher.
- [XmlAttribute("Height")]
- public int Height
- { get; set; }
- /// Indicates wether or not the Launcher is maximized or not.
- [XmlAttribute("IsMaximized")]
- public bool IsMaximized
- { get; set; }
-
- // Huge help from James for all of this!!!
- // Here's a short explanation of this. Basically, what we do is create an indexer. This makes it possible for this class to be indexed, like this LauncherConfigXML[i]
- // The indexer here has a get and set "submethod". And both use Reflection to get the current class as something that can be used with lambda values
- // So for get we just lambda the properties and search for something that can be read and has the same name as the input property. After that, we just get the value and return it as a string
- // Set is basiaclly the same, but instead of returning it, we set the prtoperty value, which would be followed after the `='.
- // So LauncherConfigXML[property] = hellWorld would set the value of `property` to `hellWorld`
- ///
- /// An Indexer for . Not to be used directly, use
- /// or instead!
- ///
- /// The property to get or set.
- /// The value of as an if used as a get, if used as a set.
- public object this[string property]
- {
- get
- {
- // This is gonna throw an exception, if the property can't be found. because of null.GetValue(this)
- return typeof(LauncherConfigXML).GetProperties().First(p => p.CanRead && p.Name == property).GetValue(this).ToString();
- }
- set
- {
- typeof(LauncherConfigXML).GetProperties().First(p => p.CanWrite && p.Name == property).SetValue(this, value);
- }
- }
+ get
+ {
+ // This is gonna throw an exception, if the property can't be found. because of null.GetValue(this)
+ return typeof(LauncherConfigXML).GetProperties().First(p => p.CanRead && p.Name == property).GetValue(this).ToString();
+ }
+ set
+ {
+ typeof(LauncherConfigXML).GetProperties().First(p => p.CanWrite && p.Name == property).SetValue(this, value);
+ }
+ }
- ///
- /// Creates a with a default set of attributes.
- ///
- public LauncherConfigXML()
- {
- AutoUpdateAM2R = true;
- AutoUpdateLauncher = true;
- Language = "Default";
- MusicHQPC = true;
- MusicHQAndroid = false;
- ProfileIndex = "null";
- MirrorIndex = 0;
- CustomMirrorEnabled = false;
- CustomMirrorText = "";
- ProfileDebugLog = true;
- CustomEnvVar = "";
- Width = 600;
- Height = 600;
- IsMaximized = false;
- }
+ ///
+ /// Creates a with a default set of attributes.
+ ///
+ public LauncherConfigXML()
+ {
+ AutoUpdateAM2R = true;
+ AutoUpdateLauncher = true;
+ Language = "Default";
+ MusicHQPC = true;
+ MusicHQAndroid = false;
+ ProfileIndex = "null";
+ MirrorIndex = 0;
+ CustomMirrorEnabled = false;
+ CustomMirrorText = "";
+ ProfileDebugLog = true;
+ CustomEnvVar = "";
+ Width = 600;
+ Height = 600;
+ IsMaximized = false;
+ }
- ///
- /// Creates a with custom attributes.
- ///
- /// Paramater that indicates if is enabled or not.
- /// Paramater that indicates if is enabled or not.
- /// Parameter that indicates the language of the launcher.
- /// Parameter that indicates if is enabled or not.
- /// Parameter that indicates if is enabled or not.
- /// Parameter that saves the index of the selected profile of .
- /// Parameter that saves the index of the selected mirror in .
- /// Parameter that saves custom Environment variables that will be used on Linux for launching a game.
- /// Parameter that indicates if is enabled or not.
- /// Parameter that indicates if is enabled or not.
- /// Parameter that's used for .
- /// Parameter that indicates the width of .
- /// Parameter that indicates the height of .
- /// Parameter that indicates if has been set to fullscreen or not.
- public LauncherConfigXML(bool autoUpdateAM2R, bool autoUpdateLauncher, string language, bool musicHQPC, bool musicHQAndroid,
- string profileIndex, int mirrorIndex, bool profileDebugLog, string customEnvVar, bool customMirrorEnabled,
- string customMirrorText, int width, int height, bool isMaximized)
- {
- AutoUpdateAM2R = autoUpdateAM2R;
- AutoUpdateLauncher = autoUpdateLauncher;
- Language = language;
- MusicHQPC = musicHQPC;
- MusicHQAndroid = musicHQAndroid;
- ProfileIndex = profileIndex;
- MirrorIndex = mirrorIndex;
- CustomMirrorEnabled = customMirrorEnabled;
- CustomMirrorText = customMirrorText;
- ProfileDebugLog = profileDebugLog;
- CustomEnvVar = customEnvVar;
- Width = width;
- Height = height;
- IsMaximized = isMaximized;
- }
+ ///
+ /// Creates a with custom attributes.
+ ///
+ /// Paramater that indicates if is enabled or not.
+ /// Paramater that indicates if is enabled or not.
+ /// Parameter that indicates the language of the launcher.
+ /// Parameter that indicates if is enabled or not.
+ /// Parameter that indicates if is enabled or not.
+ /// Parameter that saves the index of the selected profile of .
+ /// Parameter that saves the index of the selected mirror in .
+ /// Parameter that saves custom Environment variables that will be used on Linux for launching a game.
+ /// Parameter that indicates if is enabled or not.
+ /// Parameter that indicates if is enabled or not.
+ /// Parameter that's used for .
+ /// Parameter that indicates the width of .
+ /// Parameter that indicates the height of .
+ /// Parameter that indicates if has been set to fullscreen or not.
+ public LauncherConfigXML(bool autoUpdateAM2R, bool autoUpdateLauncher, string language, bool musicHQPC, bool musicHQAndroid,
+ string profileIndex, int mirrorIndex, bool profileDebugLog, string customEnvVar, bool customMirrorEnabled,
+ string customMirrorText, int width, int height, bool isMaximized)
+ {
+ AutoUpdateAM2R = autoUpdateAM2R;
+ AutoUpdateLauncher = autoUpdateLauncher;
+ Language = language;
+ MusicHQPC = musicHQPC;
+ MusicHQAndroid = musicHQAndroid;
+ ProfileIndex = profileIndex;
+ MirrorIndex = mirrorIndex;
+ CustomMirrorEnabled = customMirrorEnabled;
+ CustomMirrorText = customMirrorText;
+ ProfileDebugLog = profileDebugLog;
+ CustomEnvVar = customEnvVar;
+ Width = width;
+ Height = height;
+ IsMaximized = isMaximized;
}
-}
+}
\ No newline at end of file
diff --git a/AM2RLauncher/AM2RLauncherCore/XML/ProfileXML.cs b/AM2RLauncher/AM2RLauncherCore/XML/ProfileXML.cs
index 2be847c..5c6b4ba 100644
--- a/AM2RLauncher/AM2RLauncherCore/XML/ProfileXML.cs
+++ b/AM2RLauncher/AM2RLauncherCore/XML/ProfileXML.cs
@@ -1,99 +1,98 @@
using System;
using System.Xml.Serialization;
-namespace AM2RLauncher.Core.XML
+namespace AM2RLauncher.Core.XML;
+
+///
+/// Class that handles how the mod settings are saved as XML.
+///
+[Serializable]
+[XmlRoot("message")]
+public class ProfileXML
{
+ /// Indicates the Operating system the mod was made for.
+ [XmlAttribute("OperatingSystem")]
+ public string OperatingSystem
+ { get; set; }
+ /// Indicates the xml version the mod was made in.
+ [XmlAttribute("XMLVersion")]
+ public int XMLVersion
+ { get; set; }
+ /// Indicates the version of the mod.
+ [XmlAttribute("Version")]
+ public string Version
+ { get; set; }
+ /// Indicates the mod's name.
+ [XmlAttribute("Name")]
+ public string Name
+ { get; set; }
+ /// Indicates the mod's author.
+ [XmlAttribute("Author")]
+ public string Author
+ { get; set; }
+ /// Indicates wether or not the mod uses custom music.
+ [XmlAttribute("UsesCustomMusic")]
+ public bool UsesCustomMusic
+ { get; set; }
+ /// Indicates the save location of the mod.
+ [XmlAttribute("SaveLocation")]
+ public string SaveLocation
+ { get; set; }
+ /// Indicates wether or not the mod supports Android.
+ [XmlAttribute("SupportsAndroid")]
+ public bool SupportsAndroid
+ { get; set; }
+ /// Indicates wether or not the mod was compiled with YYC.
+ [XmlAttribute("UsesYYC")]
+ public bool UsesYYC
+ { get; set; }
+ /// Indicates if the mod is installable. This is only for archival community updates mods.
+ [XmlAttribute("Installable")]
+ public bool Installable
+ { get; set; }
+ /// Indicates any notes that the mod author deemed worthy to share about his mod.
+ [XmlAttribute("ProfileNotes")]
+ public string ProfileNotes
+ { get; set; }
+ /// This gets calculated at runtime, by . Indicates where the install data for the mod is stored.
+ [XmlIgnore]
+ public string DataPath
+ { get; set; }
+
+ /// Creates a with a default set of attributes.
+ public ProfileXML()
+ {
+ Installable = true;
+ }
+
///
- /// Class that handles how the mod settings are saved as XML.
+ /// Creates a with a custom set of attributes.
///
- [Serializable]
- [XmlRoot("message")]
- public class ProfileXML
+ /// The operating system the mod was made on.
+ /// The xml version the mod was created with.
+ /// The version of the mod.
+ /// The mod name.
+ /// The mod author.
+ /// Wether or not the mod uses custom music.
+ /// The save location of the mod.
+ /// Wether or not the mod works for android.
+ /// Wether or not the mod was made with YYC.
+ /// Wether or not the mod is installable.
+ /// The notes of the mod.
+ public ProfileXML(string operatingSystem, int xmlVersion, string version, string name, string author,
+ bool usesCustomMusic, string saveLocation, bool android, bool usesYYC,
+ bool installable, string profileNotes)
{
- /// Indicates the Operating system the mod was made for.
- [XmlAttribute("OperatingSystem")]
- public string OperatingSystem
- { get; set; }
- /// Indicates the xml version the mod was made in.
- [XmlAttribute("XMLVersion")]
- public int XMLVersion
- { get; set; }
- /// Indicates the version of the mod.
- [XmlAttribute("Version")]
- public string Version
- { get; set; }
- /// Indicates the mod's name.
- [XmlAttribute("Name")]
- public string Name
- { get; set; }
- /// Indicates the mod's author.
- [XmlAttribute("Author")]
- public string Author
- { get; set; }
- /// Indicates wether or not the mod uses custom music.
- [XmlAttribute("UsesCustomMusic")]
- public bool UsesCustomMusic
- { get; set; }
- /// Indicates the save location of the mod.
- [XmlAttribute("SaveLocation")]
- public string SaveLocation
- { get; set; }
- /// Indicates wether or not the mod supports Android.
- [XmlAttribute("SupportsAndroid")]
- public bool SupportsAndroid
- { get; set; }
- /// Indicates wether or not the mod was compiled with YYC.
- [XmlAttribute("UsesYYC")]
- public bool UsesYYC
- { get; set; }
- /// Indicates if the mod is installable. This is only for archival community updates mods.
- [XmlAttribute("Installable")]
- public bool Installable
- { get; set; }
- /// Indicates any notes that the mod author deemed worthy to share about his mod.
- [XmlAttribute("ProfileNotes")]
- public string ProfileNotes
- { get; set; }
- /// This gets calculated at runtime, by . Indicates where the install data for the mod is stored.
- [XmlIgnore]
- public string DataPath
- { get; set; }
-
- /// Creates a with a default set of attributes.
- public ProfileXML()
- {
- Installable = true;
- }
-
- ///
- /// Creates a with a custom set of attributes.
- ///
- /// The operating system the mod was made on.
- /// The xml version the mod was created with.
- /// The version of the mod.
- /// The mod name.
- /// The mod author.
- /// Wether or not the mod uses custom music.
- /// The save location of the mod.
- /// Wether or not the mod works for android.
- /// Wether or not the mod was made with YYC.
- /// Wether or not the mod is installable.
- /// The notes of the mod.
- public ProfileXML(string operatingSystem, int xmlVersion, string version, string name, string author,
- bool usesCustomMusic, string saveLocation, bool android, bool usesYYC,
- bool installable, string profileNotes)
- {
- OperatingSystem = operatingSystem;
- XMLVersion = xmlVersion;
- Version = version;
- Name = name;
- Author = author;
- UsesCustomMusic = usesCustomMusic;
- SaveLocation = saveLocation;
- SupportsAndroid = android;
- UsesYYC = usesYYC;
- Installable = installable;
- ProfileNotes = profileNotes;
- }
+ OperatingSystem = operatingSystem;
+ XMLVersion = xmlVersion;
+ Version = version;
+ Name = name;
+ Author = author;
+ UsesCustomMusic = usesCustomMusic;
+ SaveLocation = saveLocation;
+ SupportsAndroid = android;
+ UsesYYC = usesYYC;
+ Installable = installable;
+ ProfileNotes = profileNotes;
}
-}
+}
\ No newline at end of file
diff --git a/AM2RLauncher/AM2RLauncherCore/XML/Serializer.cs b/AM2RLauncher/AM2RLauncherCore/XML/Serializer.cs
index 328e22d..4c177cb 100644
--- a/AM2RLauncher/AM2RLauncherCore/XML/Serializer.cs
+++ b/AM2RLauncher/AM2RLauncherCore/XML/Serializer.cs
@@ -2,51 +2,48 @@
using System.IO;
using System.Text;
-namespace AM2RLauncher.Core.XML
+namespace AM2RLauncher.Core.XML;
+
+///
+/// The Serializer class, that serializes to and deserializes from XML files.
+///
+public static class Serializer
{
///
- /// The Serializer class, that serializes to and deserializes from XML files.
+ /// Serializes as a to XML.
///
- public static class Serializer
+ /// The class to serialize to.
+ /// The object that will be serialized.
+ /// The serialized XML as a .
+ public static string Serialize(object item)
{
- ///
- /// Serializes as a to XML.
- ///
- /// The class to serialize to.
- /// The object that will be serialized.
- /// The serialized XML as a .
- public static string Serialize(object item)
- {
- Type t = typeof(T);
- MemoryStream memStream = new MemoryStream();
- System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(t);
+ Type t = typeof(T);
+ MemoryStream memStream = new MemoryStream();
+ System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(t);
- serializer.Serialize(memStream, item);
+ serializer.Serialize(memStream, item);
- string xml = Encoding.UTF8.GetString(memStream.ToArray());
+ string xml = Encoding.UTF8.GetString(memStream.ToArray());
- memStream.Flush();
- memStream.Close();
- memStream.Dispose();
- memStream = null;
+ memStream.Flush();
+ memStream.Close();
+ memStream.Dispose();
+ memStream = null;
- return xml;
- }
+ return xml;
+ }
- ///
- /// Deserialize into an object of class that can be assigned.
- ///
- /// The class that will be deserialized to.
- /// An XML that will be deserialized.
- /// A deserialized object of class from .
- public static T Deserialize(string xmlString)
- {
- Type t = typeof(T);
- using (MemoryStream memStream = new MemoryStream(Encoding.UTF8.GetBytes(xmlString)))
- {
- System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(t);
- return (T)serializer.Deserialize(memStream);
- }
- }
+ ///
+ /// Deserialize into an object of class that can be assigned.
+ ///
+ /// The class that will be deserialized to.
+ /// An XML that will be deserialized.
+ /// A deserialized object of class from .
+ public static T Deserialize(string xmlString)
+ {
+ Type t = typeof(T);
+ using MemoryStream memStream = new MemoryStream(Encoding.UTF8.GetBytes(xmlString));
+ System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(t);
+ return (T)serializer.Deserialize(memStream);
}
}
\ No newline at end of file