Cleanup commit nr 2

pull/32/head
Miepee 5 years ago
parent c0cdd1799d
commit 8e34b55398

@ -5,6 +5,7 @@
<TargetFramework>net5.0</TargetFramework> <TargetFramework>net5.0</TargetFramework>
<ApplicationIcon>icon64.ico</ApplicationIcon> <ApplicationIcon>icon64.ico</ApplicationIcon>
<RollForward>LatestMajor</RollForward> <RollForward>LatestMajor</RollForward>
<LangVersion>latest</LangVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

@ -4,101 +4,101 @@ using log4net.Config;
using System; using System;
using System.IO; using System.IO;
namespace AM2RLauncher.Gtk namespace AM2RLauncher.Gtk;
/// <summary>
/// The main class for the GTK project.
/// </summary>
static class MainClass
{ {
/// <summary> /// <summary>
/// The main class for the GTK project. /// The logger for <see cref="MainForm"/>, used to write any caught exceptions.
/// </summary>
private static readonly ILog Log = LogManager.GetLogger(typeof(MainForm));
/// <summary>
/// The main method for the GTK project.
/// </summary> /// </summary>
static class MainClass [STAThread]
public static void Main()
{ {
/// <summary> string launcherDataPath = GenerateCurrentPath();
/// The logger for <see cref="MainForm"/>, used to write any caught exceptions.
/// </summary>
private static readonly ILog Log = LogManager.GetLogger(typeof(MainForm));
/// <summary>
/// The main method for the GTK project.
/// </summary>
[STAThread]
public static void Main(string[] args)
{
string launcherDataPath = GenerateCurrentPath();
// Make sure first, ~/.local/share/AM2RLauncher exists // Make sure first, ~/.local/share/AM2RLauncher exists
if (!Directory.Exists(launcherDataPath)) if (!Directory.Exists(launcherDataPath))
Directory.CreateDirectory(launcherDataPath); Directory.CreateDirectory(launcherDataPath);
// Now, see if log4netConfig exists, if not write it again. // Now, see if log4netConfig exists, if not write it again.
if (!File.Exists(launcherDataPath + "/log4net.config")) if (!File.Exists(launcherDataPath + "/log4net.config"))
File.WriteAllText(launcherDataPath + "/log4net.config", Properties.Resources.log4netContents.Replace("${DATADIR}", launcherDataPath)); File.WriteAllText(launcherDataPath + "/log4net.config", Properties.Resources.log4netContents.Replace("${DATADIR}", launcherDataPath));
// Configure logger // Configure logger
XmlConfigurator.Configure(new FileInfo(launcherDataPath + "/log4net.config")); XmlConfigurator.Configure(new FileInfo(launcherDataPath + "/log4net.config"));
try try
{ {
Application GTKLauncher = new Application(Eto.Platforms.Gtk); Application GTKLauncher = new Application(Eto.Platforms.Gtk);
LauncherUpdater.Main(); LauncherUpdater.Main();
GTKLauncher.UnhandledException += GTKLauncher_UnhandledException; GTKLauncher.UnhandledException += GTKLauncher_UnhandledException;
GTKLauncher.Run(new MainForm()); GTKLauncher.Run(new MainForm());
}
catch (Exception e)
{
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!");
}
} }
catch (Exception e)
/// <summary>
/// This method gets fired when an unhandled excpetion occurs in <see cref="MainForm"/>.
/// </summary>
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.StackTrace);
Application.Instance.Invoke(() => 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!");
MessageBox.Show(Language.Text.UnhandledException + "\n*****Stack Trace*****\n\n" + e.ExceptionObject, "GTK", MessageBoxType.Error);
});
} }
}
// This is a duplicate of CrossPlatformOperations.GenerateCurrentPath, because trying to invoke that would cause a crash due to currentPlatform not being initialized. /// <summary>
private static string GenerateCurrentPath() /// This method gets fired when an unhandled excpetion occurs in <see cref="MainForm"/>.
/// </summary>
private static void GTKLauncher_UnhandledException(object sender, Eto.UnhandledExceptionEventArgs e)
{
Log.Error("An unhandled exception has occurred: \n*****Stack Trace*****\n\n" + e.ExceptionObject);
Application.Instance.Invoke(() =>
{ {
string nixHome = Environment.GetEnvironmentVariable("HOME"); MessageBox.Show(Language.Text.UnhandledException + "\n*****Stack Trace*****\n\n" + e.ExceptionObject, "GTK", MessageBoxType.Error);
// 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
return am2rLauncherDataEnvVar;
}
catch { }
}
// 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))
xdgDataHome = nixHome + "/.local/share";
// Add AM2RLauncher to the end of the dataPath
xdgDataHome += "/AM2RLauncher";
// This is a duplicate of CrossPlatformOperations.GenerateCurrentPath, because trying to invoke that would cause a crash due to currentPlatform not being initialized.
private static string GenerateCurrentPath()
{
string nixHome = Environment.GetEnvironmentVariable("HOME");
// First, we check if the user has a custom AM2RLAUNCHERDATA env var
string am2rLauncherDataEnvVar = Environment.GetEnvironmentVariable("AM2RLAUNCHERDATA");
if (!String.IsNullOrWhiteSpace(am2rLauncherDataEnvVar))
{
try try
{ {
// This will create the directories recursively if they don't exist // This will create the directories recursively if they don't exist
Directory.CreateDirectory(xdgDataHome); Directory.CreateDirectory(am2rLauncherDataEnvVar);
// Our env var is now set and directories exist // Our env var is now set and directories exist
return xdgDataHome; return am2rLauncherDataEnvVar;
} }
catch { } catch { }
}
// 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))
xdgDataHome = nixHome + "/.local/share";
return Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory); // 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
return xdgDataHome;
} }
catch { }
return Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory);
} }
} }

@ -4,79 +4,77 @@ using log4net.Config;
using System; using System;
using System.IO; using System.IO;
namespace AM2RLauncher.Mac namespace AM2RLauncher.Mac;
/// <summary>
/// The main class for the Mac project.
/// </summary>
static class MainClass
{ {
/// <summary> /// <summary>
/// The main class for the Mac project. /// The logger for <see cref="MainForm"/>, used to write any caught exceptions.
/// </summary> /// </summary>
static class MainClass private static readonly ILog Log = LogManager.GetLogger(typeof(MainForm));
{
/// <summary>
/// The logger for <see cref="MainForm"/>, used to write any caught exceptions.
/// </summary>
private static readonly ILog Log = LogManager.GetLogger(typeof(MainForm));
/// <summary> /// <summary>
/// The main method for the Mac project. /// The main method for the Mac project.
/// </summary> /// </summary>
[STAThread] [STAThread]
public static void Main(string[] args) public static void Main()
{ {
string launcherDataPath = GenerateCurrentPath(); string launcherDataPath = GenerateCurrentPath();
// Make sure first, ~/.local/share/AM2RLauncher exists // Make sure first, ~/.local/share/AM2RLauncher exists
if (!Directory.Exists(launcherDataPath)) if (!Directory.Exists(launcherDataPath))
Directory.CreateDirectory(launcherDataPath); Directory.CreateDirectory(launcherDataPath);
// Now, see if log4netConfig exists, if not write it again. // Now, see if log4netConfig exists, if not write it again.
if (!File.Exists(launcherDataPath + "/log4net.config")) if (!File.Exists(launcherDataPath + "/log4net.config"))
File.WriteAllText(launcherDataPath + "/log4net.config", Properties.Resources.log4netContents.Replace("${DATADIR}", launcherDataPath)); File.WriteAllText(launcherDataPath + "/log4net.config", Properties.Resources.log4netContents.Replace("${DATADIR}", launcherDataPath));
// Configure logger // Configure logger
XmlConfigurator.Configure(new FileInfo(launcherDataPath + "/log4net.config")); XmlConfigurator.Configure(new FileInfo(launcherDataPath + "/log4net.config"));
try try
{ {
Application MacLauncher = new Application(Eto.Platforms.Mac64); Application macLauncher = new Application(Eto.Platforms.Mac64);
LauncherUpdater.Main(); LauncherUpdater.Main();
MacLauncher.UnhandledException += MacLauncher_UnhandledException; macLauncher.UnhandledException += MacLauncher_UnhandledException;
MacLauncher.Run(new MainForm()); macLauncher.Run(new MainForm());
}
catch (Exception e)
{
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!");
}
//new Application(Eto.Platforms.Mac64).Run(new MainForm());
} }
catch (Exception e)
/// <summary>
/// This method gets fired when an unhandled excpetion occurs in <see cref="MainForm"/>.
/// </summary>
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.StackTrace);
Application.Instance.Invoke(() => 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!");
MessageBox.Show(Language.Text.UnhandledException + "\n*****Stack Trace*****\n\n" + e.ExceptionObject, "Mac", MessageBoxType.Error);
});
} }
}
// This is a duplicate of CrossPlatformOperations.GenerateCurrentPath, because trying to invoke that would cause a crash due to currentPlatform not being initialized. /// <summary>
private static string GenerateCurrentPath() /// This method gets fired when an unhandled excpetion occurs in <see cref="MainForm"/>.
/// </summary>
private static void MacLauncher_UnhandledException(object sender, Eto.UnhandledExceptionEventArgs e)
{
Log.Error("An unhandled exception has occurred: \n*****Stack Trace*****\n\n" + e.ExceptionObject);
Application.Instance.Invoke(() =>
{ {
string nixHome = Environment.GetEnvironmentVariable("HOME"); MessageBox.Show(Language.Text.UnhandledException + "\n*****Stack Trace*****\n\n" + e.ExceptionObject, "Mac", MessageBoxType.Error);
//Mac has the Path at HOME/Library/AM2RLauncher });
string macPath = nixHome + "/Library/AM2RLauncher"; }
try
{
Directory.CreateDirectory(macPath);
return macPath;
}
catch { }
return Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory); // This is a duplicate of CrossPlatformOperations.GenerateCurrentPath, because trying to invoke that would cause a crash due to currentPlatform not being initialized.
private static string GenerateCurrentPath()
{
string nixHome = Environment.GetEnvironmentVariable("HOME");
//Mac has the Path at HOME/Library/AM2RLauncher
string macPath = nixHome + "/Library/AM2RLauncher";
try
{
Directory.CreateDirectory(macPath);
return macPath;
} }
catch { }
return Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory);
} }
} }

@ -17,6 +17,7 @@
<PackageProjectUrl>https://github.com/AM2R-Community-Developers/AM2RLauncherRewrite/</PackageProjectUrl> <PackageProjectUrl>https://github.com/AM2R-Community-Developers/AM2RLauncherRewrite/</PackageProjectUrl>
<PackageLicenseExpression>GNU General Public License v3.0</PackageLicenseExpression> <PackageLicenseExpression>GNU General Public License v3.0</PackageLicenseExpression>
<Description>A Launcher for AM2R that with mod capabilities.</Description> <Description>A Launcher for AM2R that with mod capabilities.</Description>
<LangVersion>latest</LangVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">

@ -5,80 +5,80 @@ using System;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
namespace AM2RLauncher.Wpf namespace AM2RLauncher.Wpf;
/// <summary>
/// The main class for the WinForms project.
/// </summary>
static class MainClass
{ {
/// <summary> /// <summary>
/// The main class for the WinForms project. /// The logger for <see cref="MainForm"/>, used to write any caught exceptions.
/// </summary>
private static readonly ILog Log = LogManager.GetLogger(typeof(MainForm));
/// <summary>
/// The main method for the WinForms project.
/// </summary> /// </summary>
static class MainClass [STAThread]
public static void Main()
{ {
/// <summary> string launcherDataPath = GenerateCurrentPath();
/// The logger for <see cref="MainForm"/>, used to write any caught exceptions.
/// </summary>
private static readonly ILog Log = LogManager.GetLogger(typeof(MainForm));
/// <summary>
/// The main method for the WinForms project.
/// </summary>
[STAThread]
public static void Main(string[] args)
{
string launcherDataPath = GenerateCurrentPath();
// Make sure first, that the path exists // Make sure first, that the path exists
if (!Directory.Exists(launcherDataPath)) if (!Directory.Exists(launcherDataPath))
Directory.CreateDirectory(launcherDataPath); Directory.CreateDirectory(launcherDataPath);
// Now, see if log4netConfig exists, if not write it again. // Now, see if log4netConfig exists, if not write it again.
if (!File.Exists(launcherDataPath + "/log4net.config")) if (!File.Exists(launcherDataPath + "/log4net.config"))
File.WriteAllText(launcherDataPath + "/log4net.config", Properties.Resources.log4netContents.Replace("${DATADIR}", launcherDataPath)); File.WriteAllText(launcherDataPath + "/log4net.config", Properties.Resources.log4netContents.Replace("${DATADIR}", launcherDataPath));
// Configure logger // Configure logger
XmlConfigurator.Configure(new FileInfo(launcherDataPath + "/log4net.config")); XmlConfigurator.Configure(new FileInfo(launcherDataPath + "/log4net.config"));
// Try catch in case it ever crashes before actually getting to the Eto application // Try catch in case it ever crashes before actually getting to the Eto application
try try
{ {
Application winLauncher = new Application(Eto.Platforms.WinForms); Application winLauncher = new Application(Eto.Platforms.WinForms);
LauncherUpdater.Main(); LauncherUpdater.Main();
winLauncher.UnhandledException += WinLauncher_UnhandledException; winLauncher.UnhandledException += WinLauncher_UnhandledException;
winLauncher.Run(new MainForm()); winLauncher.Run(new MainForm());
}
catch (Exception e)
{
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);
}
} }
catch (Exception e)
/// <summary>
/// This method gets fired when an unhandled excpetion occurs in <see cref="MainForm"/>.
/// </summary>
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.StackTrace);
MessageBox.Show(Language.Text.UnhandledException + "\n*****Stack Trace*****\n\n" + e.ExceptionObject, "Microsoft .NET Framework", MessageBoxType.Error); 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);
} }
}
/// <summary>
/// This method gets fired when an unhandled excpetion occurs in <see cref="MainForm"/>.
/// </summary>
private static void WinLauncher_UnhandledException(object sender, Eto.UnhandledExceptionEventArgs e)
{
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);
}
// This is a duplicate of CrossPlatformOperations.GenerateCurrentPath, because trying to invoke that would cause a crash due to currentPlatform not being initialized. // This is a duplicate of CrossPlatformOperations.GenerateCurrentPath, because trying to invoke that would cause a crash due to currentPlatform not being initialized.
private static string GenerateCurrentPath() 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))
{ {
// First, we check if the user has a custom AM2RLAUNCHERDATA env var try
string am2rLauncherDataEnvVar = Environment.GetEnvironmentVariable("AM2RLAUNCHERDATA");
if (!String.IsNullOrWhiteSpace(am2rLauncherDataEnvVar))
{ {
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 // Our env var is now set and directories exist
return am2rLauncherDataEnvVar; return am2rLauncherDataEnvVar;
}
catch { }
} }
// Windows has the path where the exe is located as default catch { }
return Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location);
} }
// Windows has the path where the exe is located as default
return Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location);
} }
} }

@ -45,9 +45,9 @@ namespace AM2RLauncher
/// Linux: Will point to XDG_CONFIG_HOME/AM2RLauncher <br/> /// Linux: Will point to XDG_CONFIG_HOME/AM2RLauncher <br/>
/// Mac: Will point to ~/Library/Preferences/AM2RLauncher /// Mac: Will point to ~/Library/Preferences/AM2RLauncher
/// </summary> /// </summary>
private static readonly string NIXLAUNCHERCONFIGPATH = CurrentPlatform.IsGtk ? ((String.IsNullOrWhiteSpace(LINUXXDGCONFIG) ? (NIXHOME + "/.config") private static readonly string NIXLAUNCHERCONFIGPATH = CurrentPlatform.IsGtk ? (String.IsNullOrWhiteSpace(LINUXXDGCONFIG) ? NIXHOME + "/.config"
: LINUXXDGCONFIG) + "/AM2RLauncher") : LINUXXDGCONFIG) + "/AM2RLauncher"
: NIXHOME + "/Library/Preferences/AM2RLauncher"; : NIXHOME + "/Library/Preferences/AM2RLauncher";
/// <summary> /// <summary>
/// Config file path for *nix based systems. Will be <see cref="NIXLAUNCHERCONFIGPATH"/> + "/config.xml". /// Config file path for *nix based systems. Will be <see cref="NIXLAUNCHERCONFIGPATH"/> + "/config.xml".
@ -154,7 +154,7 @@ namespace AM2RLauncher
if (appConfig == null) if (appConfig == null)
throw new NullReferenceException("Could not find the Config file! Please make sure it exists!"); throw new NullReferenceException("Could not find the Config file! Please make sure it exists!");
ConnectionStringsSection connectionStringsSection = (ConnectionStringsSection)appConfig.GetSection("connectionStrings"); ConnectionStringsSection connectionStringsSection = (ConnectionStringsSection)appConfig.GetSection("connectionStrings");
if (connectionStringsSection == null || connectionStringsSection.ConnectionStrings[property]?.ConnectionString == null) if (connectionStringsSection?.ConnectionStrings[property]?.ConnectionString == null)
throw new ArgumentException("The property " + property + " could not be found."); throw new ArgumentException("The property " + property + " could not be found.");
connectionStringsSection.ConnectionStrings[property].ConnectionString = value.ToString(); connectionStringsSection.ConnectionStrings[property].ConnectionString = value.ToString();
appConfig.Save(); appConfig.Save();
@ -512,7 +512,7 @@ namespace AM2RLauncher
{ {
// First check if XDG_DATA_HOME is set, if not we'll use ~/.local/share // First check if XDG_DATA_HOME is set, if not we'll use ~/.local/share
string xdgDataHome = Environment.GetEnvironmentVariable("XDG_DATA_HOME"); string xdgDataHome = Environment.GetEnvironmentVariable("XDG_DATA_HOME");
if (string.IsNullOrWhiteSpace(xdgDataHome)) if (String.IsNullOrWhiteSpace(xdgDataHome))
{ {
Log.Info("Using default Linux CurrentPath."); Log.Info("Using default Linux CurrentPath.");
xdgDataHome = NIXHOME + "/.local/share"; xdgDataHome = NIXHOME + "/.local/share";

@ -18,18 +18,18 @@ namespace AM2RLauncher
// Auto updating is fun! // Auto updating is fun!
/// <summary>The Version that identifies this current release.</summary> /// <summary>The Version that identifies this current release.</summary>
public static readonly string VERSION = "2.2.0"; public const string VERSION = "2.2.0";
/// <summary>The current Running platform.</summary> /// <summary>The current Running platform.</summary>
private static readonly Platform currentPlatform = Platform.Instance; // Needs to be declared here as well, because I can't access the one from eto, private static readonly Platform CurrentPlatform = Platform.Instance; // Needs to be declared here as well, because I can't access the one from eto,
// Since isn't loaded at this point // Since isn't loaded at this point
/// <summary>The Path of the oldConfig. Only gets used Windows-only</summary> /// <summary>The Path of the oldConfig. Only gets used Windows-only</summary>
private static readonly string oldConfigPath = CrossPlatformOperations.CURRENTPATH + "/" + CrossPlatformOperations.LAUNCHERNAME + ".oldCfg"; private static readonly string OldConfigPath = CrossPlatformOperations.CURRENTPATH + "/" + CrossPlatformOperations.LAUNCHERNAME + ".oldCfg";
/// <summary>The actual Path where the executable is stored, only used for updating.</summary> /// <summary>The actual Path where the executable is stored, only used for updating.</summary>
//TODO: for mac, this reports the path of the mac runner, not the actual .app //TODO: for mac, this reports the path of the mac runner, not the actual .app
private static readonly string updatePath = currentPlatform.IsWinForms ? CrossPlatformOperations.CURRENTPATH : Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory); private static readonly string UpdatePath = CurrentPlatform.IsWinForms ? CrossPlatformOperations.CURRENTPATH : Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory);
/// <summary> /// <summary>
/// Our log object, that handles logging the current execution to a file. /// Our log object, that handles logging the current execution to a file.
@ -51,19 +51,19 @@ namespace AM2RLauncher
Log.Info("AM2RLauncher.bak detected. Removing file."); Log.Info("AM2RLauncher.bak detected. Removing file.");
File.Delete(CrossPlatformOperations.CURRENTPATH + "/AM2RLauncher.bak"); File.Delete(CrossPlatformOperations.CURRENTPATH + "/AM2RLauncher.bak");
} }
if (currentPlatform.IsWinForms && File.Exists(oldConfigPath)) if (CurrentPlatform.IsWinForms && File.Exists(OldConfigPath))
{ {
Log.Info(CrossPlatformOperations.LAUNCHERNAME + ".oldCfg detected. Removing file."); Log.Info(CrossPlatformOperations.LAUNCHERNAME + ".oldCfg detected. Removing file.");
File.Delete(oldConfigPath); File.Delete(OldConfigPath);
} }
if (currentPlatform.IsWinForms && Directory.Exists(CrossPlatformOperations.CURRENTPATH + "/oldLib")) if (CurrentPlatform.IsWinForms && 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); Directory.Delete(CrossPlatformOperations.CURRENTPATH + "/oldLib", true);
} }
// Clean up old update libs // Clean up old update libs
if (currentPlatform.IsWinForms && Directory.Exists(CrossPlatformOperations.CURRENTPATH + "/lib")) if (CurrentPlatform.IsWinForms && Directory.Exists(CrossPlatformOperations.CURRENTPATH + "/lib"))
{ {
foreach (FileInfo file in new DirectoryInfo(CrossPlatformOperations.CURRENTPATH + "/lib").GetFiles()) foreach (FileInfo file in new DirectoryInfo(CrossPlatformOperations.CURRENTPATH + "/lib").GetFiles())
{ {
@ -91,7 +91,7 @@ namespace AM2RLauncher
// This is supposed to fix the updater throwing an exception on windows 7 and earlier(?) // 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 // See this for information: https://stackoverflow.com/q/2859790 and https://stackoverflow.com/a/50977774
if (currentPlatform.IsWinForms) if (CurrentPlatform.IsWinForms)
{ {
ServicePointManager.Expect100Continue = true; ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
@ -132,89 +132,90 @@ namespace AM2RLauncher
Log.Info((isCurrentVersionOutdated ? "Updating" : "Not Updating") + " from " + VERSION + " to " + onlineVersion); Log.Info((isCurrentVersionOutdated ? "Updating" : "Not Updating") + " from " + VERSION + " to " + onlineVersion);
if (isCurrentVersionOutdated) // No new update, exiting
{ if (!isCurrentVersionOutdated)
Log.Info("Current version (" + VERSION + ") is outdated! Initiating update for version " + onlineVersion + "."); return;
Log.Info("Current version (" + VERSION + ") is outdated! Initiating update for version " + onlineVersion + ".");
string tmpUpdatePath = CrossPlatformOperations.CURRENTPATH + "/tmpupdate/"; string tmpUpdatePath = CrossPlatformOperations.CURRENTPATH + "/tmpupdate/";
string zipPath = CrossPlatformOperations.CURRENTPATH + "/launcher.zip"; string zipPath = CrossPlatformOperations.CURRENTPATH + "/launcher.zip";
// Clean tmpupdate // Clean tmpupdate
if (Directory.Exists(tmpUpdatePath)) if (Directory.Exists(tmpUpdatePath))
Directory.Delete(tmpUpdatePath, true); Directory.Delete(tmpUpdatePath, true);
if (!Directory.Exists(tmpUpdatePath)) if (!Directory.Exists(tmpUpdatePath))
Directory.CreateDirectory(tmpUpdatePath); Directory.CreateDirectory(tmpUpdatePath);
try try
{
using (var client = new WebClient())
{ {
using (var client = new WebClient()) string platformSuffix = "";
{ if (CurrentPlatform.IsWinForms) platformSuffix = "_win";
string platformSuffix = ""; else if (CurrentPlatform.IsGtk) platformSuffix = "_lin";
if (currentPlatform.IsWinForms) platformSuffix = "_win";
else if (currentPlatform.IsGtk) 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); 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.");
MessageBox.Show(Language.Text.UnauthorizedAccessMessage);
return;
} }
}
catch (UnauthorizedAccessException)
{
Log.Error("UnauthorizedAccessException caught! Displaying MessageBox.");
MessageBox.Show(Language.Text.UnauthorizedAccessMessage);
return;
}
ZipFile.ExtractToDirectory(zipPath, tmpUpdatePath); ZipFile.ExtractToDirectory(zipPath, tmpUpdatePath);
Log.Info("Updates successfully extracted to " + tmpUpdatePath); Log.Info("Updates successfully extracted to " + tmpUpdatePath);
File.Delete(zipPath); File.Delete(zipPath);
File.Move(updatePath + "/" + CrossPlatformOperations.LAUNCHERNAME, CrossPlatformOperations.CURRENTPATH + "/AM2RLauncher.bak"); File.Move(UpdatePath + "/" + CrossPlatformOperations.LAUNCHERNAME, CrossPlatformOperations.CURRENTPATH + "/AM2RLauncher.bak");
if (currentPlatform.IsWinForms) File.Move(CrossPlatformOperations.LAUNCHERNAME + ".config", CrossPlatformOperations.LAUNCHERNAME + ".oldCfg"); if (CurrentPlatform.IsWinForms) File.Move(CrossPlatformOperations.LAUNCHERNAME + ".config", CrossPlatformOperations.LAUNCHERNAME + ".oldCfg");
foreach (var file in new DirectoryInfo(tmpUpdatePath).GetFiles()) 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);
}
// For windows, the actual application is in "AM2RLauncher.dll". Which means, we need to update the lib folder as well.
if (CurrentPlatform.IsWinForms && Directory.Exists(CrossPlatformOperations.CURRENTPATH + "/lib"))
{
// So, because Windows behavior is dumb...
// Rename all files in lib to *.bak
foreach (FileInfo file in new DirectoryInfo(CrossPlatformOperations.CURRENTPATH + "/lib").GetFiles())
{ {
Log.Info("Moving " + file.FullName + " to " + CrossPlatformOperations.CURRENTPATH + "/" + file.Name); file.CopyTo(file.Directory + "/" + file.Name + ".bak");
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 (currentPlatform.IsWinForms && Directory.Exists(CrossPlatformOperations.CURRENTPATH + "/lib"))
{
// So, because Windows behavior is dumb...
// Rename all files in lib to *.bak
foreach (FileInfo file in new DirectoryInfo(CrossPlatformOperations.CURRENTPATH + "/lib").GetFiles())
{
file.CopyTo(file.Directory + "/" + file.Name + ".bak");
}
// Do the same for each subdir // Do the same for each subdir
foreach (DirectoryInfo dir in new DirectoryInfo(CrossPlatformOperations.CURRENTPATH + "/lib").GetDirectories()) foreach (DirectoryInfo dir in new DirectoryInfo(CrossPlatformOperations.CURRENTPATH + "/lib").GetDirectories())
{
foreach (FileInfo file in dir.GetFiles())
{ {
foreach (FileInfo file in dir.GetFiles()) file.CopyTo(file.Directory + "/" + file.Name + ".bak");
{
file.CopyTo(file.Directory + "/" + file.Name + ".bak");
}
} }
// Yes, the above calls could be recursive. No, I can't be bothered to make them as such.
if (Directory.Exists(tmpUpdatePath + "lib"))
HelperMethods.DirectoryCopy(tmpUpdatePath + "lib", CrossPlatformOperations.CURRENTPATH + "/lib");
} }
Directory.Delete(tmpUpdatePath, true); // Yes, the above calls could be recursive. No, I can't be bothered to make them as such.
if (Directory.Exists(tmpUpdatePath + "lib"))
HelperMethods.DirectoryCopy(tmpUpdatePath + "lib", CrossPlatformOperations.CURRENTPATH + "/lib");
}
CrossPlatformOperations.CopyOldConfigToNewConfig(); Directory.Delete(tmpUpdatePath, true);
Log.Info("Files extracted. Preparing to restart executable..."); CrossPlatformOperations.CopyOldConfigToNewConfig();
if (currentPlatform.IsGtk) System.Diagnostics.Process.Start("chmod", "+x ./AM2RLauncher.Gtk"); Log.Info("Files extracted. Preparing to restart executable...");
System.Diagnostics.Process.Start(updatePath + "/" + CrossPlatformOperations.LAUNCHERNAME); if (CurrentPlatform.IsGtk) System.Diagnostics.Process.Start("chmod", "+x ./AM2RLauncher.Gtk");
Environment.Exit(0);
} System.Diagnostics.Process.Start(UpdatePath + "/" + CrossPlatformOperations.LAUNCHERNAME);
Environment.Exit(0);
} }
else else
{ {

@ -67,14 +67,15 @@ namespace AM2RLauncher.Helpers
} }
// If copying subdirectories, copy them and their contents to new location. // If copying subdirectories, copy them and their contents to new location.
if (copySubDirs) if (!copySubDirs)
return;
foreach (DirectoryInfo subDir in dirs)
{ {
foreach (DirectoryInfo subdir in dirs) string tempPath = Path.Combine(destDirName, subDir.Name);
{ DirectoryCopy(subDir.FullName, tempPath, overwriteFiles);
string tempPath = Path.Combine(destDirName, subdir.Name);
DirectoryCopy(subdir.FullName, tempPath, overwriteFiles, copySubDirs);
}
} }
} }
@ -170,10 +171,9 @@ namespace AM2RLauncher.Helpers
{ {
Log.Info("Checking internet connection..."); Log.Info("Checking internet connection...");
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://github.com"); HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://github.com");
HttpWebResponse response = null;
try try
{ {
response = (HttpWebResponse)request.GetResponse(); HttpWebResponse response = (HttpWebResponse)request.GetResponse();
} }
catch (WebException) catch (WebException)
{ {

@ -30,7 +30,7 @@ namespace AM2RLauncher
/// <param name="hWnd">Pointer to the process you want to have in the foreground.</param> /// <param name="hWnd">Pointer to the process you want to have in the foreground.</param>
/// <returns></returns> /// <returns></returns>
[DllImport("user32.dll")] [DllImport("user32.dll")]
static extern bool SetForegroundWindow(IntPtr hWnd); private static extern bool SetForegroundWindow(IntPtr hWnd);
/// <summary> /// <summary>
/// After the <see cref="playButton"/> has bee loaded, git pull if a repo has been cloned already. /// After the <see cref="playButton"/> has bee loaded, git pull if a repo has been cloned already.
@ -38,120 +38,120 @@ namespace AM2RLauncher
private async void PlayButtonLoadComplete(object sender, EventArgs e) private async void PlayButtonLoadComplete(object sender, EventArgs e)
{ {
LoadProfiles(); LoadProfiles();
if (HelperMethods.IsPatchDataCloned() && (bool)autoUpdateAM2RCheck.Checked) if (!HelperMethods.IsPatchDataCloned() || !(bool)autoUpdateAM2RCheck.Checked)
{ return;
SetPlayButtonState(UpdateState.Downloading);
SetPlayButtonState(UpdateState.Downloading);
progressBar.Visible = true; progressBar.Visible = true;
progressLabel.Visible = true; progressLabel.Visible = true;
progressBar.Value = 0; progressBar.Value = 0;
// Try to pull first. // Try to pull first.
try try
{ {
await Task.Run(PullPatchData); await Task.Run(PullPatchData);
// Thank you druid, for this case that should never happen // Thank you druid, for this case that should never happen
if (!File.Exists(CrossPlatformOperations.CURRENTPATH + "/PatchData/profile.xml")) if (!File.Exists(CrossPlatformOperations.CURRENTPATH + "/PatchData/profile.xml"))
{
Log.Error("Druid PatchData corruption occurred!");
await Application.Instance.InvokeAsync(() =>
{ {
Log.Error("Druid PatchData corruption occurred!"); MessageBox.Show(Language.Text.CorruptPatchData, Language.Text.ErrorWindowTitle, MessageBoxType.Error);
await Application.Instance.InvokeAsync(() => });
{ HelperMethods.DeleteDirectory(CrossPlatformOperations.CURRENTPATH + "/PatchData");
MessageBox.Show(Language.Text.CorruptPatchData, Language.Text.ErrorWindowTitle, MessageBoxType.Error); return;
});
HelperMethods.DeleteDirectory(CrossPlatformOperations.CURRENTPATH + "/PatchData");
return;
}
} }
catch (UserCancelledException) { } // We deliberately cancelled this! }
catch (LibGit2SharpException ex) // This is for any exceptions from libgit catch (UserCancelledException) { } // We deliberately cancelled this!
catch (LibGit2SharpException ex) // This is for any exceptions from libgit
{
// Libgit2sharp error messages are always in english!
if (ex.Message.ToLower().Contains("failed to send request") || ex.Message.ToLower().Contains("connection with the server was terminated") ||
ex.Message.ToLower().Contains("failed to resolve address"))
{ {
// Libgit2sharp error messages are always in english! if (!(bool)autoUpdateAM2RCheck.Checked)
if (ex.Message.ToLower().Contains("failed to send request") || ex.Message.ToLower().Contains("connection with the server was terminated") ||
ex.Message.ToLower().Contains("failed to resolve address"))
{ {
if (!(bool)autoUpdateAM2RCheck.Checked) Log.Error("Internet connection failed while attempting to pull repository" + currentMirror + "!");
{ MessageBox.Show(Language.Text.InternetConnectionDrop, Language.Text.WarningWindowTitle, MessageBoxType.Warning);
Log.Error("Internet connection failed while attempting to pull repository" + currentMirror + "!");
MessageBox.Show(Language.Text.InternetConnectionDrop, Language.Text.WarningWindowTitle, MessageBoxType.Warning);
}
}
else
{
Log.Error(ex.Message + "\n*****Stack Trace*****\n\n" + ex.StackTrace);
MessageBox.Show(ex.Message + "\n*****Stack Trace*****\n\n" + ex.StackTrace, Language.Text.ErrorWindowTitle, MessageBoxType.Error);
} }
} }
catch (Exception ex) // This is if somehow any other exception might get thrown as well. else
{ {
Log.Error(ex.Message + "\n*****Stack Trace*****\n\n" + ex.StackTrace); Log.Error(ex.Message + "\n*****Stack Trace*****\n\n" + ex.StackTrace);
MessageBox.Show(ex.Message + "\n*****Stack Trace*****\n\n" + ex.StackTrace, Language.Text.ErrorWindowTitle, MessageBoxType.Error); MessageBox.Show(ex.Message + "\n*****Stack Trace*****\n\n" + ex.StackTrace, Language.Text.ErrorWindowTitle, MessageBoxType.Error);
} }
finally }
{ catch (Exception ex) // This is if somehow any other exception might get thrown as well.
progressBar.Visible = false; {
progressLabel.Visible = false; Log.Error(ex.Message + "\n*****Stack Trace*****\n\n" + ex.StackTrace);
LoadProfiles(); MessageBox.Show(ex.Message + "\n*****Stack Trace*****\n\n" + ex.StackTrace, Language.Text.ErrorWindowTitle, MessageBoxType.Error);
} }
finally
// Handling for updates - if current version does not match PatchData version, rename folder so that we attempt to install! {
// Also, add a non-installable profile for it so people can access the older version or delete it from the mod manager. progressBar.Visible = false;
if (profileList.Count > 0 && IsProfileInstalled(profileList[0])) progressLabel.Visible = false;
{ LoadProfiles();
ProfileXML currentXML = Serializer.Deserialize<ProfileXML>(File.ReadAllText(CrossPlatformOperations.CURRENTPATH + "/Profiles/Community Updates (Latest)/profile.xml")); }
if (currentXML.Version != profileList[0].Version)
{
Log.Info("New game version (" + profileList[0].Version + ") detected! Beginning archival of version " + currentXML.Version + "...");
string profileArchivePath = CrossPlatformOperations.CURRENTPATH + "/Profiles/Community Updates (" + currentXML.Version + ")"; // Handling for updates - if current version does not match PatchData version, rename folder so that we attempt to install!
// Also, add a non-installable profile for it so people can access the older version or delete it from the mod manager.
if (profileList.Count > 0 && IsProfileInstalled(profileList[0]))
{
ProfileXML currentXML = Serializer.Deserialize<ProfileXML>(File.ReadAllText(CrossPlatformOperations.CURRENTPATH + "/Profiles/Community Updates (Latest)/profile.xml"));
// Do NOT overwrite if a path with this name already exists! It is likely an existing user archive. if (currentXML.Version != profileList[0].Version)
if (!Directory.Exists(profileArchivePath)) {
{ Log.Info("New game version (" + profileList[0].Version + ") detected! Beginning archival of version " + currentXML.Version + "...");
// Rename current Community Updates
Directory.Move(CrossPlatformOperations.CURRENTPATH + "/Profiles/Community Updates (Latest)", profileArchivePath);
currentXML.Name = "Community Updates (" + currentXML.Version + ")"; string profileArchivePath = CrossPlatformOperations.CURRENTPATH + "/Profiles/Community Updates (" + currentXML.Version + ")";
// Set as non-installable so that it's just treated as a launching reference // Do NOT overwrite if a path with this name already exists! It is likely an existing user archive.
currentXML.Installable = false; if (!Directory.Exists(profileArchivePath))
currentXML.SupportsAndroid = false; {
// Rename current Community Updates
Directory.Move(CrossPlatformOperations.CURRENTPATH + "/Profiles/Community Updates (Latest)", profileArchivePath);
string modArchivePath = CrossPlatformOperations.CURRENTPATH + "/Mods/" + currentXML.Name; currentXML.Name = "Community Updates (" + currentXML.Version + ")";
// Do NOT overwrite if a path with this name already exists! It is likely an existing user archive. // Set as non-installable so that it's just treated as a launching reference
if (!Directory.Exists(modArchivePath)) currentXML.Installable = false;
{ currentXML.SupportsAndroid = false;
Directory.CreateDirectory(modArchivePath);
File.WriteAllText(modArchivePath + "/profile.xml", Serializer.Serialize<ProfileXML>(currentXML));
Log.Info("Finished archival.");
}
else
{
HelperMethods.DeleteDirectory(profileArchivePath);
Log.Info("Cancelling archival! User-defined archive in Mods already exists.");
}
string modArchivePath = CrossPlatformOperations.CURRENTPATH + "/Mods/" + currentXML.Name;
// Do NOT overwrite if a path with this name already exists! It is likely an existing user archive.
if (!Directory.Exists(modArchivePath))
{
Directory.CreateDirectory(modArchivePath);
File.WriteAllText(modArchivePath + "/profile.xml", Serializer.Serialize<ProfileXML>(currentXML));
Log.Info("Finished archival.");
} }
else // If our desired rename already exists, it's probably a user archive... so we just delete the folder and move on with installation of the new version. else
{ {
HelperMethods.DeleteDirectory(CrossPlatformOperations.CURRENTPATH + "/Profiles/Community Updates (Latest)"); HelperMethods.DeleteDirectory(profileArchivePath);
Log.Info("Cancelling archival! User-defined archive in Profiles already exists."); Log.Info("Cancelling archival! User-defined archive in Mods already exists.");
} }
profileDropDown.SelectedIndex = 0;
LoadProfiles(); }
else // If our desired rename already exists, it's probably a user archive... so we just delete the folder and move on with installation of the new version.
{
HelperMethods.DeleteDirectory(CrossPlatformOperations.CURRENTPATH + "/Profiles/Community Updates (Latest)");
Log.Info("Cancelling archival! User-defined archive in Profiles already exists.");
}
profileDropDown.SelectedIndex = 0;
} LoadProfiles();
}
SetPlayButtonState(UpdateState.Install);
UpdateStateMachine(); }
} }
SetPlayButtonState(UpdateState.Install);
UpdateStateMachine();
} }
/// <summary> /// <summary>
@ -282,7 +282,7 @@ namespace AM2RLauncher
Title = Language.Text.Select11FileDialog Title = Language.Text.Select11FileDialog
}; };
fileFinder.Filters.Add(new FileFilter(Language.Text.ZipArchiveText, new[] { ".zip" })); fileFinder.Filters.Add(new FileFilter(Language.Text.ZipArchiveText, ".zip"));
if (fileFinder.ShowDialog(this) != DialogResult.Ok) if (fileFinder.ShowDialog(this) != DialogResult.Ok)
{ {
@ -290,7 +290,7 @@ namespace AM2RLauncher
return; return;
} }
if (!string.IsNullOrWhiteSpace(fileFinder.FileName)) // This is default if (!String.IsNullOrWhiteSpace(fileFinder.FileName)) // This is default
{ {
if (Directory.Exists(fileFinder.FileName)) if (Directory.Exists(fileFinder.FileName))
{ {
@ -416,13 +416,11 @@ namespace AM2RLauncher
{ {
progressBar.MinValue = 0; progressBar.MinValue = 0;
progressBar.MaxValue = transferProgress.TotalObjects; progressBar.MaxValue = transferProgress.TotalObjects;
if (currentGitObject < transferProgress.ReceivedObjects) if (currentGitObject >= transferProgress.ReceivedObjects)
{ return;
progressLabel.Text = Language.Text.ProgressbarProgress + " " + transferProgress.ReceivedObjects + " (" + (int)transferProgress.ReceivedBytes / 1000000 + "MB) / " + transferProgress.TotalObjects + " objects"; progressLabel.Text = Language.Text.ProgressbarProgress + " " + transferProgress.ReceivedObjects + " (" + (int)transferProgress.ReceivedBytes / 1000000 + "MB) / " + transferProgress.TotalObjects + " objects";
currentGitObject = transferProgress.ReceivedObjects; currentGitObject = transferProgress.ReceivedObjects;
progressBar.Value = transferProgress.ReceivedObjects; progressBar.Value = transferProgress.ReceivedObjects;
}
}); });
return true; return true;
@ -507,7 +505,7 @@ namespace AM2RLauncher
Title = Language.Text.SelectModFileDialog Title = Language.Text.SelectModFileDialog
}; };
fileFinder.Filters.Add(new FileFilter(Language.Text.ZipArchiveText, new[] { ".zip" })); fileFinder.Filters.Add(new FileFilter(Language.Text.ZipArchiveText, ".zip"));
if (fileFinder.ShowDialog(this) != DialogResult.Ok) if (fileFinder.ShowDialog(this) != DialogResult.Ok)
{ {
@ -515,7 +513,7 @@ namespace AM2RLauncher
return; return;
} }
if (!string.IsNullOrWhiteSpace(fileFinder.FileName)) // This is default if (!String.IsNullOrWhiteSpace(fileFinder.FileName)) // This is default
{ {
Log.Info("User selected \"" + fileFinder.FileName + "\""); Log.Info("User selected \"" + fileFinder.FileName + "\"");
@ -607,12 +605,11 @@ namespace AM2RLauncher
/// </summary> /// </summary>
private void ProfilesButtonClickEvent(object sender, EventArgs e) private void ProfilesButtonClickEvent(object sender, EventArgs e)
{ {
if (IsProfileIndexValid()) if (!IsProfileIndexValid())
{ return;
Log.Info("User opened the profile directory for profile " + profileList[settingsProfileDropDown.SelectedIndex].Name + Log.Info("User opened the profile directory for profile " + profileList[settingsProfileDropDown.SelectedIndex].Name +
", which is " + profileList[settingsProfileDropDown.SelectedIndex].SaveLocation); ", which is " + profileList[settingsProfileDropDown.SelectedIndex].SaveLocation);
CrossPlatformOperations.OpenFolder(CrossPlatformOperations.CURRENTPATH + "/Profiles/" + profileList[settingsProfileDropDown.SelectedIndex].Name); CrossPlatformOperations.OpenFolder(CrossPlatformOperations.CURRENTPATH + "/Profiles/" + profileList[settingsProfileDropDown.SelectedIndex].Name);
}
} }
/// <summary> /// <summary>
@ -657,12 +654,11 @@ namespace AM2RLauncher
saveButton.Enabled = true; saveButton.Enabled = true;
saveButton.ToolTip = Language.Text.OpenSaveFolderToolTip.Replace("$NAME", settingsProfileDropDown.Items[settingsProfileDropDown.SelectedIndex].Text); saveButton.ToolTip = Language.Text.OpenSaveFolderToolTip.Replace("$NAME", settingsProfileDropDown.Items[settingsProfileDropDown.SelectedIndex].Text);
if (!(settingsProfileDropDown.SelectedIndex < 0 || settingsProfileDropDown.Items.Count == 0)) if (settingsProfileDropDown.SelectedIndex < 0 || settingsProfileDropDown.Items.Count == 0)
{ return;
profileNotesTextArea.TextColor = colGreen; profileNotesTextArea.TextColor = colGreen;
profileNotesTextArea.Text = Language.Text.ProfileNotes + "\n" + profileList[settingsProfileDropDown.SelectedIndex].ProfileNotes; profileNotesTextArea.Text = Language.Text.ProfileNotes + "\n" + profileList[settingsProfileDropDown.SelectedIndex].ProfileNotes;
}
} }
/// <summary> /// <summary>
@ -673,17 +669,16 @@ namespace AM2RLauncher
{ {
// Safety check // Safety check
if (settingsProfileDropDown == null) return; if (settingsProfileDropDown == null) return;
if (settingsProfileDropDown.Items.Count == 0) if (settingsProfileDropDown.Items.Count != 0)
{ return;
addModButton.Enabled = false; addModButton.Enabled = false;
settingsProfileLabel.TextColor = colInactive; settingsProfileLabel.TextColor = colInactive;
settingsProfileDropDown.Enabled = false; settingsProfileDropDown.Enabled = false;
profileButton.Enabled = false; profileButton.Enabled = false;
saveButton.Enabled = false; saveButton.Enabled = false;
updateModButton.Enabled = false; updateModButton.Enabled = false;
deleteModButton.Enabled = false; deleteModButton.Enabled = false;
profileNotesTextArea.TextColor = colInactive; profileNotesTextArea.TextColor = colInactive;
}
} }
/// <summary> /// <summary>
@ -942,7 +937,7 @@ namespace AM2RLauncher
Title = Language.Text.SelectModFileDialog Title = Language.Text.SelectModFileDialog
}; };
fileFinder.Filters.Add(new FileFilter(Language.Text.ZipArchiveText, new[] { ".zip" })); fileFinder.Filters.Add(new FileFilter(Language.Text.ZipArchiveText, ".zip"));
if (fileFinder.ShowDialog(this) != DialogResult.Ok) if (fileFinder.ShowDialog(this) != DialogResult.Ok)
{ {
@ -950,7 +945,7 @@ namespace AM2RLauncher
return; return;
} }
if (!string.IsNullOrWhiteSpace(fileFinder.FileName)) // This is default if (!String.IsNullOrWhiteSpace(fileFinder.FileName)) // This is default
{ {
Log.Info("User selected \"" + fileFinder.FileName + "\""); Log.Info("User selected \"" + fileFinder.FileName + "\"");
@ -1047,32 +1042,34 @@ namespace AM2RLauncher
CrossPlatformOperations.WriteToConfig("Width", ClientSize.Width); CrossPlatformOperations.WriteToConfig("Width", ClientSize.Width);
CrossPlatformOperations.WriteToConfig("Height", ClientSize.Height); CrossPlatformOperations.WriteToConfig("Height", ClientSize.Height);
CrossPlatformOperations.WriteToConfig("IsMaximized", (this.WindowState == WindowState.Maximized)); CrossPlatformOperations.WriteToConfig("IsMaximized", this.WindowState == WindowState.Maximized);
if (updateState == UpdateState.Downloading) switch (updateState)
{ {
var result = MessageBox.Show(Language.Text.CloseOnCloningText, Language.Text.WarningWindowTitle, MessageBoxButtons.YesNo, case UpdateState.Downloading:
MessageBoxType.Warning, MessageBoxDefaultButton.No);
if (result == DialogResult.No)
{ {
e.Cancel = true; var result = MessageBox.Show(Language.Text.CloseOnCloningText, Language.Text.WarningWindowTitle, MessageBoxButtons.YesNo,
MessageBoxType.Warning, MessageBoxDefaultButton.No);
if (result == DialogResult.No)
{
e.Cancel = true;
}
else
isGitProcessGettingCancelled = true;
// We don't need to delete any folders here, the cancelled gitClone will do that automatically for us :)
break;
} }
else case UpdateState.Installing:
isGitProcessGettingCancelled = true; MessageBox.Show(Language.Text.CloseOnInstallingText, Language.Text.WarningWindowTitle, MessageBoxButtons.OK, MessageBoxType.Warning);
// We don't need to delete any folders here, the cancelled gitClone will do that automatically for us :) e.Cancel = true;
break;
}
else if (updateState == UpdateState.Installing)
{
MessageBox.Show(Language.Text.CloseOnInstallingText, Language.Text.WarningWindowTitle, MessageBoxButtons.OK, MessageBoxType.Warning);
e.Cancel = true;
} }
// This needs to be made invisible, otherwise a tray indicator will be visible (on linux?) that clicking crashes the application // This needs to be made invisible, otherwise a tray indicator will be visible (on linux?) that clicking crashes the application
trayIndicator.Visible = false; trayIndicator.Visible = false;
if (e.Cancel) if (e.Cancel)
Log.Info("Cancelled MainForm closing event during UpdateState." + updateState.ToString() + "."); Log.Info("Cancelled MainForm closing event during UpdateState." + updateState + ".");
else else
Log.Info("Successfully closed MainForm. Exiting main thread."); Log.Info("Successfully closed MainForm. Exiting main thread.");
} }

@ -131,7 +131,7 @@ namespace AM2RLauncher
if (reloadProfileList) if (reloadProfileList)
LoadProfiles(); LoadProfiles();
Log.Info("Succesfully deleted profile " + profile.Name + "."); Log.Info("Successfully deleted profile " + profile.Name + ".");
} }
/// <summary> /// <summary>
@ -165,19 +165,18 @@ namespace AM2RLauncher
{ {
foreach (FileInfo file in dir.GetFiles()) foreach (FileInfo file in dir.GetFiles())
{ {
if (file.Name == "profile.xml") if (file.Name != "profile.xml")
continue;
ProfileXML prof = Serializer.Deserialize<ProfileXML>(File.ReadAllText(dir.FullName + "/profile.xml"));
if (prof.Installable || IsProfileInstalled(prof)) // Safety check for non-installable profiles
{ {
ProfileXML prof = Serializer.Deserialize<ProfileXML>(File.ReadAllText(dir.FullName + "/profile.xml")); prof.DataPath = "/Mods/" + dir.Name;
if (prof.Installable || IsProfileInstalled(prof)) // Safety check for non-installable profiles profileList.Add(prof);
{ }
prof.DataPath = "/Mods/" + dir.Name; else if (!IsProfileInstalled(prof)) // If not installable and isn't installed, remove it
profileList.Add(prof); {
} prof.DataPath = "/Mods/" + dir.Name;
else if (!IsProfileInstalled(prof)) // If not installable and isn't installed, remove it DeleteProfile(prof, false);
{
prof.DataPath = "/Mods/" + dir.Name;
DeleteProfile(prof, false);
}
} }
} }
} }
@ -284,7 +283,7 @@ namespace AM2RLauncher
Directory.CreateDirectory(profilePath + "/Resources"); Directory.CreateDirectory(profilePath + "/Resources");
profilePath += "/Resources"; profilePath += "/Resources";
Log.Info("ProfileInstallstion: Created folder structure."); Log.Info("ProfileInstallation: Created folder structure.");
} }
// Extract 1.1 // Extract 1.1
@ -345,7 +344,7 @@ namespace AM2RLauncher
CrossPlatformOperations.ApplyXdeltaPatch(profilePath + "/data.win", dataPath + "/game.xdelta", profilePath + "/" + datawin); CrossPlatformOperations.ApplyXdeltaPatch(profilePath + "/data.win", dataPath + "/game.xdelta", profilePath + "/" + datawin);
CrossPlatformOperations.ApplyXdeltaPatch(profilePath + "/AM2R.exe", dataPath + "/AM2R.xdelta", profilePath + "/" + exe); CrossPlatformOperations.ApplyXdeltaPatch(profilePath + "/AM2R.exe", dataPath + "/AM2R.xdelta", profilePath + "/" + exe);
// Just in case the resulting file isn't chmoddded... // Just in case the resulting file isn't chmoddded...
Process.Start("chmod", "+x \"" + profilePath + "/" + exe + "\"").WaitForExit(); Process.Start("chmod", "+x \"" + profilePath + "/" + exe + "\"")?.WaitForExit();
// These are not needed by linux or Mac at all, so we delete them // These are not needed by linux or Mac at all, so we delete them
File.Delete(profilePath + "/data.win"); File.Delete(profilePath + "/data.win");
@ -409,7 +408,7 @@ namespace AM2RLauncher
Directory.SetCurrentDirectory(profilePath); Directory.SetCurrentDirectory(profilePath);
Console.SetError(new StreamWriter(Stream.Null)); Console.SetError(new StreamWriter(Stream.Null));
Environment.SetEnvironmentVariable("ARCH", "x86_64"); Environment.SetEnvironmentVariable("ARCH", "x86_64");
Process.Start(CrossPlatformOperations.CURRENTPATH + "/PatchData/utilities/appimagetool-x86_64.AppImage", "-n AM2R.AppDir").WaitForExit(); Process.Start(CrossPlatformOperations.CURRENTPATH + "/PatchData/utilities/appimagetool-x86_64.AppImage", "-n AM2R.AppDir")?.WaitForExit();
Directory.SetCurrentDirectory(workingDir); Directory.SetCurrentDirectory(workingDir);
Console.SetError(cliError); Console.SetError(cliError);
@ -439,7 +438,7 @@ namespace AM2RLauncher
// Copy profile.xml so we can grab data to compare for updates later! // Copy profile.xml so we can grab data to compare for updates later!
// tldr; check if we're in PatchData or not // tldr; check if we're in PatchData or not
if (new DirectoryInfo(dataPath).Parent.Name == "PatchData") if (new DirectoryInfo(dataPath)?.Parent?.Name == "PatchData")
File.Copy(dataPath + "/../profile.xml", profilePath + "/profile.xml"); File.Copy(dataPath + "/../profile.xml", profilePath + "/profile.xml");
else File.Copy(dataPath + "/profile.xml", profilePath + "/profile.xml"); else File.Copy(dataPath + "/profile.xml", profilePath + "/profile.xml");
@ -567,217 +566,217 @@ namespace AM2RLauncher
/// </summary> /// </summary>
private void RunGame() private void RunGame()
{ {
if (IsProfileIndexValid()) if (!IsProfileIndexValid())
{ return;
ProfileXML profile = profileList[profileIndex.Value];
ProfileXML profile = profileList[profileIndex.Value];
// These are used on both windows and linux for game logging // These are used on both windows and linux for game logging
string savePath = Platform.IsWinForms ? profile.SaveLocation.Replace("%localappdata%", Environment.GetEnvironmentVariable("LOCALAPPDATA")) string savePath = Platform.IsWinForms ? profile.SaveLocation.Replace("%localappdata%", Environment.GetEnvironmentVariable("LOCALAPPDATA"))
: profile.SaveLocation.Replace("~", CrossPlatformOperations.NIXHOME); : profile.SaveLocation.Replace("~", CrossPlatformOperations.NIXHOME);
DirectoryInfo logDir = new DirectoryInfo(savePath + "/logs"); DirectoryInfo logDir = new DirectoryInfo(savePath + "/logs");
string date = string.Join("-", DateTime.Now.ToString().Split(Path.GetInvalidFileNameChars(), StringSplitOptions.RemoveEmptyEntries)); string date = String.Join("-", DateTime.Now.ToString().Split(Path.GetInvalidFileNameChars(), StringSplitOptions.RemoveEmptyEntries));
Log.Info("Launching game profile " + profile.Name + "."); Log.Info("Launching game profile " + profile.Name + ".");
bool isLoggingEnabled = false; bool isLoggingEnabled = false;
Application.Instance.Invoke(new Action(() => isLoggingEnabled = (bool)profileDebugLogCheck.Checked)); Application.Instance.Invoke(new Action(() => isLoggingEnabled = (bool)profileDebugLogCheck.Checked));
if (Platform.IsWinForms) if (Platform.IsWinForms)
{ {
// Sets the arguments to empty, or to the profiles save path/logs and create time based logs. Creates the folder if necessary. // Sets the arguments to empty, or to the profiles save path/logs and create time based logs. Creates the folder if necessary.
string arguments = ""; string arguments = "";
// Game logging // Game logging
if (isLoggingEnabled) if (isLoggingEnabled)
{ {
Log.Info("Performing logging setup for profile " + profile.Name + "."); Log.Info("Performing logging setup for profile " + profile.Name + ".");
if (!Directory.Exists(logDir.FullName)) if (!Directory.Exists(logDir.FullName))
Directory.CreateDirectory(logDir.FullName); Directory.CreateDirectory(logDir.FullName);
if (File.Exists(logDir.FullName + "/" + profile.Name + ".txt")) if (File.Exists(logDir.FullName + "/" + profile.Name + ".txt"))
HelperMethods.RecursiveRollover(logDir.FullName + "/" + profile.Name + ".txt", 5); 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 " + VERSION + " log generated at " + date); stream.WriteLine("AM2RLauncher " + VERSION + " log generated at " + date);
if (isThisRunningFromWine) if (isThisRunningFromWine)
stream.WriteLine("Using WINE!"); 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.WorkingDirectory = CrossPlatformOperations.CURRENTPATH + "/Profiles/" + profile.Name;
proc.FileName = proc.WorkingDirectory + "/AM2R.exe"; proc.FileName = proc.WorkingDirectory + "/AM2R.exe";
proc.Arguments = arguments; 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)) using (var p = Process.Start(proc))
{
SetForegroundWindow(p.MainWindowHandle);
p.WaitForExit();
}
}
else if (Platform.IsGtk)
{ {
SetForegroundWindow(p.MainWindowHandle);
p.WaitForExit();
}
}
else if (Platform.IsGtk)
{
ProcessStartInfo startInfo = new ProcessStartInfo(); ProcessStartInfo startInfo = new ProcessStartInfo();
string envVars = ""; string envVars = "";
Application.Instance.Invoke(new Action(() => envVars = customEnvVarTextBox.Text)); Application.Instance.Invoke(new Action(() => envVars = customEnvVarTextBox.Text));
Log.Info("Is the environment textbox null or whitespace = " + string.IsNullOrWhiteSpace(envVars)); Log.Info("Is the environment textbox null or whitespace = " + String.IsNullOrWhiteSpace(envVars));
if (!string.IsNullOrWhiteSpace(envVars)) 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 = 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
{ {
// Env var variable int secondQuoteIndex = envVars.IndexOf('"', envVars.IndexOf('"') + 1);
string variable = envVars.Substring(0, envVars.IndexOf('=')); if (envVars.IndexOf(' ', secondQuoteIndex) >= 0)
envVars = envVars.Replace(variable + "=", ""); valueSubstringLength = envVars.IndexOf(' ', secondQuoteIndex) + 1;
else
// This thing here is the value parser. Since values are sometimes in quotes, i need to compensate for them. valueSubstringLength = envVars.Length;
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;
} }
// 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 // 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; string terminalOutput = null;
startInfo.UseShellExecute = false; startInfo.UseShellExecute = false;
startInfo.WorkingDirectory = CrossPlatformOperations.CURRENTPATH + "/Profiles/" + profile.Name; startInfo.WorkingDirectory = CrossPlatformOperations.CURRENTPATH + "/Profiles/" + profile.Name;
startInfo.FileName = startInfo.WorkingDirectory + "/AM2R.AppImage"; 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: "); Log.Info("Launching game with following variables: ");
foreach (System.Collections.DictionaryEntry item in startInfo.EnvironmentVariables) foreach (System.Collections.DictionaryEntry item in startInfo.EnvironmentVariables)
{ {
Log.Info("Key: \"" + item.Key + "\" Value: \"" + item.Value + "\""); Log.Info("Key: \"" + item.Key + "\" Value: \"" + item.Value + "\"");
} }
using (Process p = new Process()) using (Process p = new Process())
{
p.StartInfo = startInfo;
if (isLoggingEnabled)
{ {
p.StartInfo = startInfo; p.StartInfo.RedirectStandardOutput = true;
if (isLoggingEnabled) p.OutputDataReceived += (sender, e) => { terminalOutput += e.Data + "\n"; };
{
p.StartInfo.RedirectStandardOutput = true;
p.OutputDataReceived += (sender, e) => { terminalOutput += e.Data + "\n"; };
p.StartInfo.RedirectStandardError = true; p.StartInfo.RedirectStandardError = true;
p.ErrorDataReceived += (sender, e) => { terminalOutput += e.Data + "\n"; }; p.ErrorDataReceived += (sender, e) => { terminalOutput += e.Data + "\n"; };
} }
p.Start();
if (isLoggingEnabled) p.Start();
{
p.BeginOutputReadLine();
p.BeginErrorReadLine();
}
p.WaitForExit(); if (isLoggingEnabled)
{
p.BeginOutputReadLine();
p.BeginErrorReadLine();
} }
if (terminalOutput != null) p.WaitForExit();
{ }
Log.Info("Performed logging setup for profile " + profile.Name + ".");
if (!Directory.Exists(logDir.FullName)) if (terminalOutput != null)
Directory.CreateDirectory(logDir.FullName); {
Log.Info("Performed logging setup for profile " + profile.Name + ".");
if (File.Exists(logDir.FullName + "/" + profile.Name + ".txt")) if (!Directory.Exists(logDir.FullName))
HelperMethods.RecursiveRollover(logDir.FullName + "/" + profile.Name + ".txt", 5); 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 StreamWriter stream = File.AppendText(logDir.FullName + "/" + profile.Name + ".txt");
stream.WriteLine("AM2RLauncher " + VERSION + " log generated at " + date);
// Write what was in the terminal // Write general info
stream.WriteLine(terminalOutput); stream.WriteLine("AM2RLauncher " + VERSION + " log generated at " + date);
stream.Flush(); // Write what was in the terminal
stream.WriteLine(terminalOutput);
stream.Close(); stream.Flush();
}
stream.Close();
} }
else if (Platform.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 (isLoggingEnabled) else if (Platform.IsMac)
{ {
Log.Info("Performing logging setup for profile " + profile.Name + "."); // 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 (isLoggingEnabled)
{
Log.Info("Performing logging setup for profile " + profile.Name + ".");
if (!Directory.Exists(logDir.FullName)) if (!Directory.Exists(logDir.FullName))
Directory.CreateDirectory(logDir.FullName); Directory.CreateDirectory(logDir.FullName);
if (File.Exists(logDir.FullName + "/" + profile.Name + ".txt")) if (File.Exists(logDir.FullName + "/" + profile.Name + ".txt"))
HelperMethods.RecursiveRollover(logDir.FullName + "/" + profile.Name + ".txt", 5); 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 " + VERSION + " log generated at " + date); stream.WriteLine("AM2RLauncher " + VERSION + " log generated at " + date);
stream.Flush(); stream.Flush();
stream.Close(); stream.Close();
arguments += " --stdout \"" + logDir.FullName + "/" + profile.Name + ".txt\" --stderr \"" + logDir.FullName + "/" + profile.Name + ".txt\""; arguments += " --stdout \"" + logDir.FullName + "/" + profile.Name + ".txt\" --stderr \"" + logDir.FullName + "/" + profile.Name + ".txt\"";
} }
ProcessStartInfo proc = new ProcessStartInfo(); ProcessStartInfo proc = new ProcessStartInfo();
proc.WorkingDirectory = CrossPlatformOperations.CURRENTPATH + "/Profiles/" + profile.Name; proc.WorkingDirectory = CrossPlatformOperations.CURRENTPATH + "/Profiles/" + profile.Name;
proc.FileName = "open"; proc.FileName = "open";
proc.Arguments = arguments; 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)) using (var p = Process.Start(proc))
{ {
p?.WaitForExit(); p?.WaitForExit();
}
} }
else
Log.Error(Platform.ID + " cannot run games!");
Log.Info("Profile " + profile.Name + " process exited.");
} }
else
Log.Error(Platform.ID + " cannot run games!");
Log.Info("Profile " + profile.Name + " process exited.");
} }
} }
} }

@ -79,30 +79,24 @@ namespace AM2RLauncher
private void UpdateApkState() private void UpdateApkState()
{ {
// Safety check // Safety check
if (apkButton != null) if (apkButton == null)
return;
// If profile supports Android...
if (IsProfileIndexValid() && profileList[profileIndex.Value].SupportsAndroid && profileList[profileIndex.Value].Installable)
{ {
// If profile supports Android... // If we are NOT already creating an APK...
if (IsProfileIndexValid() && profileList[profileIndex.Value].SupportsAndroid && profileList[profileIndex.Value].Installable) if (apkButtonState == ApkButtonState.Create)
{ {
// If we are NOT already creating an APK... // Switch status based on main button's state
if (apkButtonState == ApkButtonState.Create) switch (updateState)
{
// Switch status based on main button's state
switch (updateState)
{
case UpdateState.Download: apkButton.Enabled = false; apkButton.ToolTip = Language.Text.ApkButtonDisabledToolTip; break;
case UpdateState.Downloading: apkButton.Enabled = false; apkButton.ToolTip = Language.Text.ApkButtonDisabledToolTip; break;
case UpdateState.Select11: apkButton.Enabled = false; apkButton.ToolTip = Language.Text.ApkButtonDisabledToolTip; break;
case UpdateState.Install: apkButton.Enabled = true; apkButton.ToolTip = Language.Text.ApkButtonEnabledToolTip.Replace("$NAME", profileDropDown?.Items[profileDropDown.SelectedIndex]?.Text ?? ""); break;
case UpdateState.Installing: apkButton.Enabled = false; apkButton.ToolTip = Language.Text.ApkButtonDisabledToolTip; break;
case UpdateState.Play: apkButton.Enabled = true; apkButton.ToolTip = Language.Text.ApkButtonEnabledToolTip.Replace("$NAME", profileDropDown?.Items[profileDropDown.SelectedIndex]?.Text ?? ""); break;
case UpdateState.Playing: apkButton.Enabled = false; apkButton.ToolTip = Language.Text.ApkButtonDisabledToolTip; break;
}
}
else // Otherwise, disable.
{ {
apkButton.Enabled = false; case UpdateState.Download: apkButton.Enabled = false; apkButton.ToolTip = Language.Text.ApkButtonDisabledToolTip; break;
apkButton.ToolTip = Language.Text.ApkButtonDisabledToolTip; case UpdateState.Downloading: apkButton.Enabled = false; apkButton.ToolTip = Language.Text.ApkButtonDisabledToolTip; break;
case UpdateState.Select11: apkButton.Enabled = false; apkButton.ToolTip = Language.Text.ApkButtonDisabledToolTip; break;
case UpdateState.Install: apkButton.Enabled = true; apkButton.ToolTip = Language.Text.ApkButtonEnabledToolTip.Replace("$NAME", profileDropDown?.Items[profileDropDown.SelectedIndex]?.Text ?? ""); break;
case UpdateState.Installing: apkButton.Enabled = false; apkButton.ToolTip = Language.Text.ApkButtonDisabledToolTip; break;
case UpdateState.Play: apkButton.Enabled = true; apkButton.ToolTip = Language.Text.ApkButtonEnabledToolTip.Replace("$NAME", profileDropDown?.Items[profileDropDown.SelectedIndex]?.Text ?? ""); break;
case UpdateState.Playing: apkButton.Enabled = false; apkButton.ToolTip = Language.Text.ApkButtonDisabledToolTip; break;
} }
} }
else // Otherwise, disable. else // Otherwise, disable.
@ -111,6 +105,11 @@ namespace AM2RLauncher
apkButton.ToolTip = Language.Text.ApkButtonDisabledToolTip; apkButton.ToolTip = Language.Text.ApkButtonDisabledToolTip;
} }
} }
else // Otherwise, disable.
{
apkButton.Enabled = false;
apkButton.ToolTip = Language.Text.ApkButtonDisabledToolTip;
}
} }
/// <summary> /// <summary>
@ -119,31 +118,30 @@ namespace AM2RLauncher
private void UpdateProfileState() private void UpdateProfileState()
{ {
// Safety check // Safety check
if (profileDropDown != null) if (profileDropDown == null)
return;
switch (updateState)
{ {
switch (updateState) case UpdateState.Download: profileDropDown.Enabled = false; break;
{ case UpdateState.Downloading: profileDropDown.Enabled = false; break;
case UpdateState.Download: profileDropDown.Enabled = false; break; case UpdateState.Select11: profileDropDown.Enabled = true; break;
case UpdateState.Downloading: profileDropDown.Enabled = false; break; case UpdateState.Install: profileDropDown.Enabled = true; break;
case UpdateState.Select11: profileDropDown.Enabled = true; break; case UpdateState.Installing: profileDropDown.Enabled = false; break;
case UpdateState.Install: profileDropDown.Enabled = true; break; case UpdateState.Play: profileDropDown.Enabled = true; break;
case UpdateState.Installing: profileDropDown.Enabled = false; break; case UpdateState.Playing: profileDropDown.Enabled = false; break;
case UpdateState.Play: profileDropDown.Enabled = true; break; }
case UpdateState.Playing: profileDropDown.Enabled = false; break; switch (apkButtonState)
} {
switch (apkButtonState) case ApkButtonState.Creating: profileDropDown.Enabled = false; break;
{ }
case ApkButtonState.Creating: profileDropDown.Enabled = false; break;
}
Color col = profileDropDown.Enabled ? colGreen : colInactive; Color col = profileDropDown.Enabled ? colGreen : colInactive;
if (Platform.IsWinForms) if (Platform.IsWinForms)
profileDropDown.TextColor = col; profileDropDown.TextColor = col;
profileAuthorLabel.TextColor = col; profileAuthorLabel.TextColor = col;
profileVersionLabel.TextColor = col; profileVersionLabel.TextColor = col;
profileLabel.TextColor = col; profileLabel.TextColor = col;
}
} }
/// <summary> /// <summary>
@ -152,51 +150,49 @@ namespace AM2RLauncher
private void UpdateProfileSettingsState() private void UpdateProfileSettingsState()
{ {
// Safety check // Safety check
if (settingsProfileDropDown == null) return; if (settingsProfileDropDown == null || settingsProfileDropDown.Items.Count <= 0) return;
if (settingsProfileDropDown.Items.Count > 0)
bool enabled = false;
switch (updateState)
{ {
bool enabled = false; case UpdateState.Download: enabled = false; break;
switch (updateState) case UpdateState.Downloading: enabled = false; break;
{ case UpdateState.Select11: enabled = false; break;
case UpdateState.Download: enabled = false; break; case UpdateState.Install: enabled = true; break;
case UpdateState.Downloading: enabled = false; break; case UpdateState.Installing: enabled = false; break;
case UpdateState.Select11: enabled = false; break; case UpdateState.Play: enabled = true; break;
case UpdateState.Install: enabled = true; break; case UpdateState.Playing: enabled = false; break;
case UpdateState.Installing: enabled = false; break; }
case UpdateState.Play: enabled = true; break; if (apkButtonState == ApkButtonState.Creating) enabled = false;
case UpdateState.Playing: enabled = false; break;
}
if (apkButtonState == ApkButtonState.Creating) enabled = false;
settingsProfileLabel.TextColor = colGreen; settingsProfileLabel.TextColor = colGreen;
settingsProfileDropDown.Enabled = enabled; settingsProfileDropDown.Enabled = enabled;
profileButton.Enabled = enabled; profileButton.Enabled = enabled;
profileButton.ToolTip = Language.Text.OpenProfileFolderToolTip.Replace("$NAME", settingsProfileDropDown.Items[settingsProfileDropDown.SelectedIndex].Text); profileButton.ToolTip = Language.Text.OpenProfileFolderToolTip.Replace("$NAME", settingsProfileDropDown.Items[settingsProfileDropDown.SelectedIndex].Text);
saveButton.Enabled = enabled; saveButton.Enabled = enabled;
saveButton.ToolTip = Language.Text.OpenSaveFolderToolTip.Replace("$NAME", settingsProfileDropDown.Items[settingsProfileDropDown.SelectedIndex].Text); saveButton.ToolTip = Language.Text.OpenSaveFolderToolTip.Replace("$NAME", settingsProfileDropDown.Items[settingsProfileDropDown.SelectedIndex].Text);
addModButton.Enabled = enabled; addModButton.Enabled = enabled;
addModButton.ToolTip = Language.Text.AddNewModToolTip; addModButton.ToolTip = Language.Text.AddNewModToolTip;
// Only enable these, when we're not on the community updates // Only enable these, when we're not on the community updates
if (settingsProfileDropDown.SelectedIndex > 0) if (settingsProfileDropDown.SelectedIndex > 0)
{ {
updateModButton.Enabled = enabled; updateModButton.Enabled = enabled;
updateModButton.ToolTip = Language.Text.UpdateModButtonToolTip.Replace("$NAME", settingsProfileDropDown.Items[settingsProfileDropDown.SelectedIndex].Text); updateModButton.ToolTip = Language.Text.UpdateModButtonToolTip.Replace("$NAME", settingsProfileDropDown.Items[settingsProfileDropDown.SelectedIndex].Text);
deleteModButton.Enabled = enabled; deleteModButton.Enabled = enabled;
deleteModButton.ToolTip = Language.Text.DeleteModButtonToolTip.Replace("$NAME", settingsProfileDropDown.Items[settingsProfileDropDown.SelectedIndex].Text); deleteModButton.ToolTip = Language.Text.DeleteModButtonToolTip.Replace("$NAME", settingsProfileDropDown.Items[settingsProfileDropDown.SelectedIndex].Text);
} }
Color col = enabled ? colGreen : colInactive; Color col = enabled ? colGreen : colInactive;
if (Platform.IsWinForms) if (Platform.IsWinForms)
settingsProfileDropDown.TextColor = col; settingsProfileDropDown.TextColor = col;
settingsProfileLabel.TextColor = col; settingsProfileLabel.TextColor = col;
if (enabled) if (enabled)
{ {
settingsProfileDropDown.SelectedIndex = profileDropDown.SelectedIndex; settingsProfileDropDown.SelectedIndex = profileDropDown.SelectedIndex;
}
} }
} }
@ -255,8 +251,8 @@ namespace AM2RLauncher
case UpdateState.Installing: return Language.Text.Installing; case UpdateState.Installing: return Language.Text.Installing;
case UpdateState.Play: return Language.Text.Play; case UpdateState.Play: return Language.Text.Play;
case UpdateState.Playing: return Language.Text.Playing; case UpdateState.Playing: return Language.Text.Playing;
default: return null;
} }
return null;
} }
/// <summary> /// <summary>
@ -269,8 +265,8 @@ namespace AM2RLauncher
{ {
case ApkButtonState.Create: return Language.Text.CreateAPK; case ApkButtonState.Create: return Language.Text.CreateAPK;
case ApkButtonState.Creating: return Language.Text.CreatingAPK; case ApkButtonState.Creating: return Language.Text.CreatingAPK;
default: return null;
} }
return null;
} }
/// <summary> /// <summary>
/// Checks if AM2R 1.1 has been installed already, aka if a valid AM2R 1.1 Zip exists. /// Checks if AM2R 1.1 has been installed already, aka if a valid AM2R 1.1 Zip exists.

@ -28,7 +28,7 @@ namespace AM2RLauncher
/// <summary> /// <summary>
/// An enum, that has possible states for our Launcher. /// An enum, that has possible states for our Launcher.
/// </summary> /// </summary>
enum UpdateState private enum UpdateState
{ {
Download, Download,
Downloading, Downloading,
@ -42,7 +42,7 @@ namespace AM2RLauncher
/// <summary> /// <summary>
/// An enum, that has different states for <see cref="apkButton"/>. /// An enum, that has different states for <see cref="apkButton"/>.
/// </summary> /// </summary>
enum ApkButtonState private enum ApkButtonState
{ {
Create, Create,
Creating Creating
@ -52,11 +52,10 @@ namespace AM2RLauncher
/// <summary> /// <summary>
/// A <see cref="string"/>-<see cref="Array"/> of custom splashes. /// A <see cref="string"/>-<see cref="Array"/> of custom splashes.
/// </summary> /// </summary>
/// <summary> /// <summary>
/// The current Launcher version. /// The current Launcher version.
/// </summary> /// </summary>
private static readonly string VERSION = LauncherUpdater.VERSION; private const string VERSION = LauncherUpdater.VERSION;
/// <summary> /// <summary>
/// A <see cref="Bitmap"/> of the AM2R icon. /// A <see cref="Bitmap"/> of the AM2R icon.
@ -124,11 +123,10 @@ namespace AM2RLauncher
Process current = Process.GetCurrentProcess(); Process current = Process.GetCurrentProcess();
foreach (Process process in Process.GetProcessesByName(current.ProcessName)) foreach (Process process in Process.GetProcessesByName(current.ProcessName))
{ {
if (process.Id != current.Id) if (process.Id == current.Id)
{ continue;
SetForegroundWindow(process.MainWindowHandle); SetForegroundWindow(process.MainWindowHandle);
break; break;
}
} }
} }
Environment.Exit(0); Environment.Exit(0);
@ -173,7 +171,7 @@ namespace AM2RLauncher
// Set the language to what User wanted or choose local language // Set the language to what User wanted or choose local language
string userLanguage = CrossPlatformOperations.ReadFromConfig("Language").ToLower(); string userLanguage = CrossPlatformOperations.ReadFromConfig("Language").ToLower();
if (!userLanguage.Equals("default")) if (!userLanguage.Equals("default"))
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultures(CultureTypes.AllCultures).Where(c => c.NativeName.ToLower().Contains(userLanguage)).First(); Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultures(CultureTypes.AllCultures).First(c => c.NativeName.ToLower().Contains(userLanguage));
Log.Info("Language has been set to: " + Thread.CurrentThread.CurrentUICulture.EnglishName); Log.Info("Language has been set to: " + Thread.CurrentThread.CurrentUICulture.EnglishName);
@ -181,8 +179,8 @@ namespace AM2RLauncher
Log.Info("Beginning UI initialization..."); Log.Info("Beginning UI initialization...");
// System tray indicator // System tray indicator
showButton = new ButtonMenuItem() { Text = Language.Text.TrayButtonShow }; showButton = new ButtonMenuItem { Text = Language.Text.TrayButtonShow };
trayIndicator = new TrayIndicator() trayIndicator = new TrayIndicator
{ {
Menu = new ContextMenu(showButton), Menu = new ContextMenu(showButton),
Title = "AM2RLauncher", Title = "AM2RLauncher",
@ -198,9 +196,9 @@ namespace AM2RLauncher
profileList = new List<ProfileXML>(); profileList = new List<ProfileXML>();
profileNames = new List<ListItem>(); profileNames = new List<ListItem>();
for (int i = 0; i < profileList.Count; i++) foreach (var profile in profileList)
{ {
profileNames.Add(profileList[i].Name); profileNames.Add(profile.Name);
} }
// Custom splash texts // Custom splash texts
@ -243,15 +241,15 @@ namespace AM2RLauncher
Title = "AM2RLauncher " + VERSION + ": " + splash; Title = "AM2RLauncher " + VERSION + ": " + splash;
MinimumSize = new Size(500, 400); 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 // TODO: for some reason, this sometimes doesn't work on Linux. Was reported at eto, stays here until its fixed
ClientSize = new Size(int.Parse(CrossPlatformOperations.ReadFromConfig("Width")), int.Parse(CrossPlatformOperations.ReadFromConfig("Height"))); ClientSize = new Size(Int32.Parse(CrossPlatformOperations.ReadFromConfig("Width")), Int32.Parse(CrossPlatformOperations.ReadFromConfig("Height")));
if (ClientSize.Width < 500) if (ClientSize.Width < 500)
ClientSize = new Size(500, ClientSize.Height); ClientSize = new Size(500, ClientSize.Height);
if (ClientSize.Height < 400) if (ClientSize.Height < 400)
ClientSize = new Size(ClientSize.Width, 400); ClientSize = new Size(ClientSize.Width, 400);
Log.Info("Start the launcher with Size: " + ClientSize.Width + ", " + ClientSize.Height); Log.Info("Start the launcher with Size: " + ClientSize.Width + ", " + ClientSize.Height);
if (bool.Parse(CrossPlatformOperations.ReadFromConfig("IsMaximized"))) Maximize(); if (Boolean.Parse(CrossPlatformOperations.ReadFromConfig("IsMaximized"))) Maximize();
drawable = new Drawable() { BackgroundColor = colBGNoAlpha }; drawable = new Drawable { BackgroundColor = colBGNoAlpha };
// Drawable paint event // Drawable paint event
drawable.Paint += DrawablePaintEvent; drawable.Paint += DrawablePaintEvent;
@ -318,7 +316,7 @@ namespace AM2RLauncher
Height = 15, Height = 15,
Text = "", Text = "",
TextColor = colGreen, TextColor = colGreen,
Visible = false, Visible = false
}; };
centerInterface.AddRow(progressLabel); centerInterface.AddRow(progressLabel);
@ -331,7 +329,7 @@ namespace AM2RLauncher
BackgroundColor = colBG, BackgroundColor = colBG,
Height = 15, Height = 15,
Text = Language.Text.CurrentProfile, Text = Language.Text.CurrentProfile,
TextColor = colGreen, TextColor = colGreen
}; };
centerInterface.AddRow(profileLabel); centerInterface.AddRow(profileLabel);
@ -344,7 +342,7 @@ namespace AM2RLauncher
profileDropDown = new DropDown profileDropDown = new DropDown
{ {
TextColor = colGreen, TextColor = colGreen,
BackgroundColor = Platform.IsWinForms ? colBGNoAlpha : new Color(), BackgroundColor = Platform.IsWinForms ? colBGNoAlpha : new Color()
}; };
// In order to not have conflicting theming, we just always respect the users theme for dropdown on GTK. // In order to not have conflicting theming, we just always respect the users theme for dropdown on GTK.
if (Platform.IsGtk) if (Platform.IsGtk)
@ -382,23 +380,23 @@ namespace AM2RLauncher
Width = 20, Width = 20,
Height = 55, Height = 55,
Text = Language.Text.SaveLocationWarning, Text = Language.Text.SaveLocationWarning,
TextColor = colRed, TextColor = colRed
}; };
centerInterface.AddRow(saveWarningLabel); centerInterface.AddRow(saveWarningLabel);
// Social buttons // Social buttons
var redditButton = new ImageButton() { ToolTip = Language.Text.RedditToolTip, Image = redditIcon }; var redditButton = new ImageButton { ToolTip = Language.Text.RedditToolTip, Image = redditIcon };
redditButton.Click += RedditIconOnClick; redditButton.Click += RedditIconOnClick;
var githubButton = new ImageButton() { ToolTip = Language.Text.GithubToolTip, Image = githubIcon }; var githubButton = new ImageButton { ToolTip = Language.Text.GithubToolTip, Image = githubIcon };
githubButton.Click += GithubIconOnClick; githubButton.Click += GithubIconOnClick;
var youtubeButton = new ImageButton() { ToolTip = Language.Text.YoutubeToolTip, Image = youtubeIcon }; var youtubeButton = new ImageButton { ToolTip = Language.Text.YoutubeToolTip, Image = youtubeIcon };
youtubeButton.Click += YoutubeIconOnClick; youtubeButton.Click += YoutubeIconOnClick;
var discordButton = new ImageButton() { ToolTip = Language.Text.DiscordToolTip, Image = discordIcon }; var discordButton = new ImageButton { ToolTip = Language.Text.DiscordToolTip, Image = discordIcon };
discordButton.Click += DiscordIconOnClick; discordButton.Click += DiscordIconOnClick;
@ -534,7 +532,7 @@ namespace AM2RLauncher
// Language DropDown menu // Language DropDown menu
List<ListItem> languageList = new List<ListItem>() List<ListItem> languageList = new List<ListItem>
{ {
Language.Text.SystemLanguage, Language.Text.SystemLanguage,
"Deutsch", "Deutsch",
@ -551,7 +549,7 @@ namespace AM2RLauncher
languageDropDown = new DropDown languageDropDown = new DropDown
{ {
TextColor = colGreen, TextColor = colGreen,
BackgroundColor = Platform.IsWinForms ? colBGNoAlpha : new Color(), BackgroundColor = Platform.IsWinForms ? colBGNoAlpha : new Color()
}; };
if (Platform.IsGtk) if (Platform.IsGtk)
languageDropDown = new DropDown(); languageDropDown = new DropDown();
@ -559,7 +557,7 @@ namespace AM2RLauncher
languageDropDown.Items.AddRange(languageList); languageDropDown.Items.AddRange(languageList);
var tmpLanguage = CrossPlatformOperations.ReadFromConfig("Language"); var tmpLanguage = CrossPlatformOperations.ReadFromConfig("Language");
languageDropDown.SelectedIndex = tmpLanguage == "Default" ? 0 : languageDropDown.Items.IndexOf(languageDropDown.Items.Where(x => x.Text.Equals(tmpLanguage)).FirstOrDefault()); languageDropDown.SelectedIndex = tmpLanguage == "Default" ? 0 : languageDropDown.Items.IndexOf(languageDropDown.Items.FirstOrDefault(x => x.Text.Equals(tmpLanguage)));
if (languageDropDown.SelectedIndex == -1) if (languageDropDown.SelectedIndex == -1)
{ {
@ -570,7 +568,7 @@ namespace AM2RLauncher
// autoUpdateAM2R checkbox // autoUpdateAM2R checkbox
autoUpdateAM2RCheck = new CheckBox autoUpdateAM2RCheck = new CheckBox
{ {
Checked = bool.Parse(CrossPlatformOperations.ReadFromConfig("AutoUpdateAM2R")), Checked = Boolean.Parse(CrossPlatformOperations.ReadFromConfig("AutoUpdateAM2R")),
Text = Language.Text.AutoUpdateAM2R, Text = Language.Text.AutoUpdateAM2R,
TextColor = colGreen TextColor = colGreen
}; };
@ -579,7 +577,7 @@ namespace AM2RLauncher
// autoUpdateLauncher checkbox // autoUpdateLauncher checkbox
autoUpdateLauncherCheck = new CheckBox autoUpdateLauncherCheck = new CheckBox
{ {
Checked = bool.Parse(CrossPlatformOperations.ReadFromConfig("AutoUpdateLauncher")), Checked = Boolean.Parse(CrossPlatformOperations.ReadFromConfig("AutoUpdateLauncher")),
Text = Language.Text.AutoUpdateLauncher, Text = Language.Text.AutoUpdateLauncher,
TextColor = colGreen TextColor = colGreen
}; };
@ -587,7 +585,7 @@ namespace AM2RLauncher
// HQ music, PC // HQ music, PC
hqMusicPCCheck = new CheckBox hqMusicPCCheck = new CheckBox
{ {
Checked = bool.Parse(CrossPlatformOperations.ReadFromConfig("MusicHQPC")), Checked = Boolean.Parse(CrossPlatformOperations.ReadFromConfig("MusicHQPC")),
Text = Language.Text.HighQualityPC, Text = Language.Text.HighQualityPC,
TextColor = colGreen TextColor = colGreen
}; };
@ -595,7 +593,7 @@ namespace AM2RLauncher
// HQ music, Android // HQ music, Android
hqMusicAndroidCheck = new CheckBox hqMusicAndroidCheck = new CheckBox
{ {
Checked = bool.Parse(CrossPlatformOperations.ReadFromConfig("MusicHQAndroid")), Checked = Boolean.Parse(CrossPlatformOperations.ReadFromConfig("MusicHQAndroid")),
Text = Language.Text.HighQualityAndroid, Text = Language.Text.HighQualityAndroid,
TextColor = colGreen TextColor = colGreen
}; };
@ -641,13 +639,14 @@ namespace AM2RLauncher
mirrorDropDown = new DropDown mirrorDropDown = new DropDown
{ {
TextColor = colGreen, TextColor = colGreen,
BackgroundColor = Platform.IsWinForms ? colBGNoAlpha : new Color(), BackgroundColor = Platform.IsWinForms ? colBGNoAlpha : new Color()
}; };
if (Platform.IsGtk) if (Platform.IsGtk)
mirrorDropDown = new DropDown(); mirrorDropDown = new DropDown();
mirrorDropDown.Items.AddRange(mirrorDescriptionList); // As above, find a way to get this inside the dropDown definition mirrorDropDown.Items.AddRange(mirrorDescriptionList); // As above, find a way to get this inside the dropDown definition
mirrorIndex = (int.Parse(CrossPlatformOperations.ReadFromConfig("MirrorIndex")) < mirrorDropDown.Items.Count) ? int.Parse(CrossPlatformOperations.ReadFromConfig("MirrorIndex")) : 0; mirrorIndex = (Int32.Parse(CrossPlatformOperations.ReadFromConfig("MirrorIndex")) < mirrorDropDown.Items.Count) ? Int32.Parse(CrossPlatformOperations.ReadFromConfig("MirrorIndex"))
: 0;
mirrorDropDown.SelectedIndex = mirrorIndex; mirrorDropDown.SelectedIndex = mirrorIndex;
currentMirror = mirrorList[mirrorDropDown.SelectedIndex]; currentMirror = mirrorList[mirrorDropDown.SelectedIndex];
@ -655,7 +654,7 @@ namespace AM2RLauncher
// Custom mirror // Custom mirror
customMirrorCheck = new CheckBox customMirrorCheck = new CheckBox
{ {
Checked = bool.Parse(CrossPlatformOperations.ReadFromConfig("CustomMirrorEnabled")), Checked = Boolean.Parse(CrossPlatformOperations.ReadFromConfig("CustomMirrorEnabled")),
Text = Language.Text.CustomMirrorCheck, Text = Language.Text.CustomMirrorCheck,
TextColor = colGreen TextColor = colGreen
}; };
@ -712,7 +711,7 @@ namespace AM2RLauncher
settingsProfileDropDown = new DropDown settingsProfileDropDown = new DropDown
{ {
TextColor = colGreen, TextColor = colGreen,
BackgroundColor = Platform.IsWinForms ? colBGNoAlpha : new Color(), BackgroundColor = Platform.IsWinForms ? colBGNoAlpha : new Color()
}; };
// In order to not have conflicting theming, we just always respect the users theme for dropdown on GTK. // In order to not have conflicting theming, we just always respect the users theme for dropdown on GTK.
@ -815,7 +814,7 @@ namespace AM2RLauncher
}; };
#region EVENTS #region EVENTS
Log.Info("All UI objects have been initalized, UI has been set up."); Log.Info("All UI objects have been initialized, UI has been set up.");
Log.Info("Beginning event linkage..."); Log.Info("Beginning event linkage...");
Closing += MainformClosing; Closing += MainformClosing;

@ -12,7 +12,7 @@ namespace AM2RLauncher
/// <summary> /// <summary>
/// Cross-Platform splash strings /// Cross-Platform splash strings
/// </summary> /// </summary>
static readonly string[] GeneralSplash = private static readonly string[] GeneralSplash =
{ {
"The real Ridley is the friends we made along the way.", "The real Ridley is the friends we made along the way.",
"Now with 100% more Septoggs!", "Now with 100% more Septoggs!",
@ -48,7 +48,7 @@ namespace AM2RLauncher
/// <summary> /// <summary>
/// Linux only splash strings /// Linux only splash strings
/// </summary> /// </summary>
static readonly string[] LinuxSplash = private static readonly string[] LinuxSplash =
{ {
"Sorry this is ugly, but at least it works.", "Sorry this is ugly, but at least it works.",
"GTK + QT = 💣", "GTK + QT = 💣",
@ -75,7 +75,7 @@ namespace AM2RLauncher
/// Get a random splash string, according to the current OS. /// Get a random splash string, according to the current OS.
/// </summary> /// </summary>
/// <returns>The randomly chosen splash as a <see cref="string"/>.</returns> /// <returns>The randomly chosen splash as a <see cref="string"/>.</returns>
static public string GetSplash() public static string GetSplash()
{ {
string[] combinedSplash; string[] combinedSplash;
Random rng = new Random(); Random rng = new Random();

@ -7,7 +7,7 @@ namespace AM2RLauncher.XML
/// <summary> /// <summary>
/// The <c>Serializer</c> class, that serializes to and deserializes from XML files. /// The <c>Serializer</c> class, that serializes to and deserializes from XML files.
/// </summary> /// </summary>
public class Serializer public static class Serializer
{ {
/// <summary> /// <summary>
/// Serializes <paramref name="item"/> as a <typeparamref name="T"/> to XML. /// Serializes <paramref name="item"/> as a <typeparamref name="T"/> to XML.

Loading…
Cancel
Save