@ -2,19 +2,16 @@
using LibGit2Sharp ;
using LibGit2Sharp ;
using log4net ;
using log4net ;
using System ;
using System ;
using System.Collections.Generic ;
using System.Diagnostics ;
using System.Diagnostics ;
using System.IO ;
using System.IO ;
using System.IO.Compression ;
using System.IO.Compression ;
using System.Linq ;
using System.Linq ;
using System.Text ;
using System.Text.RegularExpressions ;
using System.Text.RegularExpressions ;
using System.Threading ;
namespace AM2RLauncher.Core
namespace AM2RLauncher.Core ;
{
/// <summary>
/// <summary>
/// An enum, that has possible return codes for <see cref=" HelperMethods .CheckIfZipIsAM2R11"/>.
/// An enum, that has possible return codes for <see cref=" Profile .CheckIfZipIsAM2R11"/>.
/// </summary>
/// </summary>
public enum IsZipAM2R11ReturnCodes
public enum IsZipAM2R11ReturnCodes
{
{
@ -32,15 +29,15 @@ namespace AM2RLauncher.Core
{
{
/// <summary>
/// <summary>
/// The logger for <see cref="MainForm "/>, used to write any caught exceptions.
/// The logger for <see cref="Core "/>, used to write any caught exceptions.
/// </summary>
/// </summary>
private static readonly ILog L og = Core . Log ;
private static readonly ILog l og = Core . Log ;
/// <summary>
/// <summary>
/// Caches the result of <see cref="Is11Installed"/> so that we don't extract and verify it too often.
/// Caches the result of <see cref="Is11Installed"/> so that we don't extract and verify it too often.
/// </summary>
/// </summary>
private static bool? isAM2R11InstalledCache = null ;
private static bool? isAM2R11InstalledCache ;
/// <summary>
/// <summary>
/// Caches the MD5 hash of the provided AM2R_11.zip so we don't end up checking the zip if it hasn't changed.
/// Caches the MD5 hash of the provided AM2R_11.zip so we don't end up checking the zip if it hasn't changed.
@ -62,11 +59,11 @@ namespace AM2RLauncher.Core
// Return safely if file doesn't exist
// Return safely if file doesn't exist
if ( ! File . Exists ( am2r11file ) ) return false ;
if ( ! File . Exists ( am2r11file ) ) return false ;
lastAM2R11ZipMD5 = HelperMethods . CalculateMD5 ( am2r11file ) ;
lastAM2R11ZipMD5 = HelperMethods . CalculateMD5 ( am2r11file ) ;
var returnCode = Profile . CheckIfZipIsAM2R11 ( am2r11file ) ;
var returnCode = CheckIfZipIsAM2R11 ( am2r11file ) ;
// Check if it's valid, if not log it, rename it and silently leave
// Check if it's valid, if not log it, rename it and silently leave
if ( returnCode ! = IsZipAM2R11ReturnCodes . Successful )
if ( returnCode ! = IsZipAM2R11ReturnCodes . Successful )
{
{
L og. Info ( "Detected invalid AM2R_11 zip with following error code: " + returnCode ) ;
l og. Info ( "Detected invalid AM2R_11 zip with following error code: " + returnCode ) ;
HelperMethods . RecursiveRollover ( am2r11file ) ;
HelperMethods . RecursiveRollover ( am2r11file ) ;
isAM2R11InstalledCache = false ;
isAM2R11InstalledCache = false ;
return false ;
return false ;
@ -91,7 +88,7 @@ namespace AM2RLauncher.Core
/// <summary>
/// <summary>
/// Git Pulls from the repository.
/// Git Pulls from the repository.
/// </summary>
/// </summary>
public static void PullPatchData ( Func < TransferProgress , bool > T ransferProgressHandlerMethod)
public static void PullPatchData ( Func < TransferProgress , bool > t ransferProgressHandlerMethod)
{
{
using ( var repo = new Repository ( CrossPlatformOperations . CURRENTPATH + "/PatchData" ) )
using ( var repo = new Repository ( CrossPlatformOperations . CURRENTPATH + "/PatchData" ) )
{
{
@ -107,7 +104,7 @@ namespace AM2RLauncher.Core
PullOptions options = new PullOptions ( ) ;
PullOptions options = new PullOptions ( ) ;
options . FetchOptions = new FetchOptions ( ) ;
options . FetchOptions = new FetchOptions ( ) ;
options . FetchOptions . OnTransferProgress + = ( tp ) = > T ransferProgressHandlerMethod( tp ) ;
options . FetchOptions . OnTransferProgress + = tp = > t ransferProgressHandlerMethod( tp ) ;
// User information to create a merge commit
// User information to create a merge commit
var signature = new Signature ( "null" , "null" , DateTimeOffset . Now ) ;
var signature = new Signature ( "null" , "null" , DateTimeOffset . Now ) ;
@ -119,20 +116,22 @@ namespace AM2RLauncher.Core
}
}
catch
catch
{
{
L og. Error ( "Repository pull attempt failed!" ) ;
l og. Error ( "Repository pull attempt failed!" ) ;
return ;
return ;
}
}
}
}
L og. Info ( "Repository pulled successfully." ) ;
l og. Info ( "Repository pulled successfully." ) ;
}
}
/// <summary>
/// <summary>
/// Installs <paramref name="profile"/>.
/// Installs <paramref name="profile"/>.
/// </summary>
/// </summary>
/// <param name="profile"><see cref="ProfileXML"/> to be installed.</param>
/// <param name="profile"><see cref="ProfileXML"/> to be installed.</param>
/// <param name="useHqMusic">Wether to patch this with high quality music or not.</param>
/// <param name="progress">Provides the current progress of this method.</param>
public static void InstallProfile ( ProfileXML profile , bool useHqMusic , IProgress < int > progress )
public static void InstallProfile ( ProfileXML profile , bool useHqMusic , IProgress < int > progress )
{
{
L og. Info ( "Installing profile " + profile . Name + "..." ) ;
l og. Info ( "Installing profile " + profile . Name + "..." ) ;
string profilesHomePath = CrossPlatformOperations . CURRENTPATH + "/Profiles" ;
string profilesHomePath = CrossPlatformOperations . CURRENTPATH + "/Profiles" ;
string profilePath = profilesHomePath + "/" + profile . Name ;
string profilePath = profilesHomePath + "/" + profile . Name ;
@ -168,7 +167,7 @@ namespace AM2RLauncher.Core
Directory . CreateDirectory ( profilePath + "/Resources" ) ;
Directory . CreateDirectory ( profilePath + "/Resources" ) ;
profilePath + = "/Resources" ;
profilePath + = "/Resources" ;
L og. Info ( "ProfileInstallation: Created folder structure." ) ;
l og. Info ( "ProfileInstallation: Created folder structure." ) ;
}
}
// Extract 1.1
// Extract 1.1
@ -176,7 +175,7 @@ namespace AM2RLauncher.Core
// Extracted 1.1
// Extracted 1.1
progress . Report ( 33 ) ;
progress . Report ( 33 ) ;
L og. Info ( "Profile folder created and AM2R_11.zip extracted." ) ;
l og. Info ( "Profile folder created and AM2R_11.zip extracted." ) ;
// Set local datapath for installation files
// Set local datapath for installation files
var dataPath = CrossPlatformOperations . CURRENTPATH + profile . DataPath ;
var dataPath = CrossPlatformOperations . CURRENTPATH + profile . DataPath ;
@ -194,7 +193,7 @@ namespace AM2RLauncher.Core
// Use the exe name based on the desktop file in the appimage, rather than hardcoding it.
// Use the exe name based on the desktop file in the appimage, rather than hardcoding it.
string desktopContents = File . ReadAllText ( CrossPlatformOperations . CURRENTPATH + "/PatchData/data/AM2R.AppDir/AM2R.desktop" ) ;
string desktopContents = File . ReadAllText ( CrossPlatformOperations . CURRENTPATH + "/PatchData/data/AM2R.AppDir/AM2R.desktop" ) ;
exe = Regex . Match ( desktopContents , @"(?<=Exec=).*" ) . Value ;
exe = Regex . Match ( desktopContents , @"(?<=Exec=).*" ) . Value ;
L og. Info ( "According to AppImage desktop file, using \"" + exe + "\" as game name." ) ;
l og. Info ( "According to AppImage desktop file, using \"" + exe + "\" as game name." ) ;
}
}
else if ( OS . IsMac )
else if ( OS . IsMac )
{
{
@ -203,10 +202,10 @@ namespace AM2RLauncher.Core
}
}
else
else
{
{
L og. Error ( OS . Name + " does not have valid runner / data.win names!" ) ;
l og. Error ( OS . Name + " does not have valid runner / data.win names!" ) ;
}
}
L og. Info ( "Attempting to patch in " + profilePath ) ;
l og. Info ( "Attempting to patch in " + profilePath ) ;
if ( OS . IsWindows )
if ( OS . IsWindows )
{
{
@ -244,13 +243,13 @@ namespace AM2RLauncher.Core
}
}
else
else
{
{
L og. Error ( OS . Name + " does not have patching methods!" ) ;
l og. Error ( OS . Name + " does not have patching methods!" ) ;
}
}
// Applied patch
// Applied patch
if ( OS . IsWindows | | OS . IsMac ) progress . Report ( 66 ) ;
if ( OS . IsWindows | | OS . IsMac ) progress . Report ( 66 ) ;
else if ( OS . IsLinux ) progress . Report ( 44 ) ; // Linux will take a bit longer, due to appimage creation
else if ( OS . IsLinux ) progress . Report ( 44 ) ; // Linux will take a bit longer, due to appimage creation
L og. Info ( "xdelta patch(es) applied." ) ;
l og. Info ( "xdelta patch(es) applied." ) ;
// Install new datafiles
// Install new datafiles
HelperMethods . DirectoryCopy ( dataPath + "/files_to_copy" , profilePath ) ;
HelperMethods . DirectoryCopy ( dataPath + "/files_to_copy" , profilePath ) ;
@ -283,7 +282,7 @@ namespace AM2RLauncher.Core
File . Copy ( profilePath + "/" + exe , profilePath + "/AM2R.AppDir/usr/bin/" + exe ) ;
File . Copy ( profilePath + "/" + exe , profilePath + "/AM2R.AppDir/usr/bin/" + exe ) ;
progress . Report ( 66 ) ;
progress . Report ( 66 ) ;
L og. Info ( "Gtk-specific formatting finished." ) ;
l og. Info ( "Gtk-specific formatting finished." ) ;
// Temp save the currentWorkingDirectory and console.error, change it to profilePath and null, call the script, and change it back.
// Temp save the currentWorkingDirectory and console.error, change it to profilePath and null, call the script, and change it back.
string workingDir = Directory . GetCurrentDirectory ( ) ;
string workingDir = Directory . GetCurrentDirectory ( ) ;
@ -321,13 +320,13 @@ namespace AM2RLauncher.Core
// 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" ) ;
// Installed datafiles
// Installed datafiles
progress . Report ( 100 ) ;
progress . Report ( 100 ) ;
L og. Info ( "Successfully installed profile " + profile . Name + "." ) ;
l og. Info ( "Successfully installed profile " + profile . Name + "." ) ;
}
}
/// <summary>
/// <summary>
@ -338,10 +337,10 @@ namespace AM2RLauncher.Core
public static bool IsProfileInstalled ( ProfileXML profile )
public static bool IsProfileInstalled ( ProfileXML profile )
{
{
if ( OS . IsWindows ) return File . Exists ( CrossPlatformOperations . CURRENTPATH + "/Profiles/" + profile . Name + "/AM2R.exe" ) ;
if ( OS . IsWindows ) return File . Exists ( CrossPlatformOperations . CURRENTPATH + "/Profiles/" + profile . Name + "/AM2R.exe" ) ;
else if ( OS . IsLinux ) return File . Exists ( CrossPlatformOperations . CURRENTPATH + "/Profiles/" + profile . Name + "/AM2R.AppImage" ) ;
if ( OS . IsLinux ) return File . Exists ( CrossPlatformOperations . CURRENTPATH + "/Profiles/" + profile . Name + "/AM2R.AppImage" ) ;
else if ( OS . IsMac ) return Directory . Exists ( CrossPlatformOperations . CURRENTPATH + "/Profiles/" + profile . Name + "/AM2R.app" ) ;
if ( OS . IsMac ) return Directory . Exists ( CrossPlatformOperations . CURRENTPATH + "/Profiles/" + profile . Name + "/AM2R.app" ) ;
L og. Error ( OS . Name + " can't have profiles installed!" ) ;
l og. Error ( OS . Name + " can't have profiles installed!" ) ;
return false ;
return false ;
}
}
@ -349,6 +348,8 @@ namespace AM2RLauncher.Core
/// Creates an APK of the selected <paramref name="profile"/>.
/// Creates an APK of the selected <paramref name="profile"/>.
/// </summary>
/// </summary>
/// <param name="profile"><see cref="ProfileXML"/> to be compiled into an APK.</param>
/// <param name="profile"><see cref="ProfileXML"/> to be compiled into an APK.</param>
/// <param name="useHqMusic">Wether to create the APK with high quality music or not.</param>
/// <param name="progress">Provides the current progress of this method.</param>
public static void CreateAPK ( ProfileXML profile , bool useHqMusic , IProgress < int > progress )
public static void CreateAPK ( ProfileXML profile , bool useHqMusic , IProgress < int > progress )
{
{
// Overall safety check just in case of bad situations
// Overall safety check just in case of bad situations
@ -357,7 +358,7 @@ namespace AM2RLauncher.Core
progress . Report ( 100 ) ;
progress . Report ( 100 ) ;
return ;
return ;
}
}
L og. Info ( "Creating Android APK for profile " + profile . Name + "." ) ;
l og. Info ( "Creating Android APK for profile " + profile . Name + "." ) ;
// Create working dir after some cleanup
// Create working dir after some cleanup
string apktoolPath = CrossPlatformOperations . CURRENTPATH + "/PatchData/utilities/android/apktool.jar" ,
string apktoolPath = CrossPlatformOperations . CURRENTPATH + "/PatchData/utilities/android/apktool.jar" ,
@ -368,12 +369,12 @@ namespace AM2RLauncher.Core
Directory . Delete ( tempDir , true ) ;
Directory . Delete ( tempDir , true ) ;
Directory . CreateDirectory ( tempDir ) ;
Directory . CreateDirectory ( tempDir ) ;
L og. Info ( "Cleanup, variables, and working directory created." ) ;
l og. Info ( "Cleanup, variables, and working directory created." ) ;
progress . Report ( 14 ) ;
progress . Report ( 14 ) ;
// Decompile AM2RWrapper.apk
// Decompile AM2RWrapper.apk
CrossPlatformOperations . RunJavaJar ( "\"" + apktoolPath + "\" d \"" + dataPath + "/android/AM2RWrapper.apk\"" , tempDir ) ;
CrossPlatformOperations . RunJavaJar ( "\"" + apktoolPath + "\" d \"" + dataPath + "/android/AM2RWrapper.apk\"" , tempDir ) ;
L og. Info ( "AM2RWrapper decompiled." ) ;
l og. Info ( "AM2RWrapper decompiled." ) ;
progress . Report ( 28 ) ;
progress . Report ( 28 ) ;
// Add datafiles: 1.1, new datafiles, hq music, am2r.ini
// Add datafiles: 1.1, new datafiles, hq music, am2r.ini
@ -387,12 +388,12 @@ namespace AM2RLauncher.Core
foreach ( FileInfo file in new DirectoryInfo ( dataPath ) . GetFiles ( ) . Where ( f = > f . Name . EndsWith ( "ini" ) ) )
foreach ( FileInfo file in new DirectoryInfo ( dataPath ) . GetFiles ( ) . Where ( f = > f . Name . EndsWith ( "ini" ) ) )
File . Copy ( file . FullName , workingDir + "/" + file . Name ) ;
File . Copy ( file . FullName , workingDir + "/" + file . Name ) ;
L og. Info ( "AM2R_11.zip extracted and datafiles copied into AM2RWrapper." ) ;
l og. Info ( "AM2R_11.zip extracted and datafiles copied into AM2RWrapper." ) ;
progress . Report ( 42 ) ;
progress . Report ( 42 ) ;
// Patch data.win to game.droid
// Patch data.win to game.droid
CrossPlatformOperations . ApplyXdeltaPatch ( workingDir + "/data.win" , dataPath + "/droid.xdelta" , workingDir + "/game.droid" ) ;
CrossPlatformOperations . ApplyXdeltaPatch ( workingDir + "/data.win" , dataPath + "/droid.xdelta" , workingDir + "/game.droid" ) ;
L og. Info ( "game.droid successfully patched." ) ;
l og. Info ( "game.droid successfully patched." ) ;
progress . Report ( 56 ) ;
progress . Report ( 56 ) ;
// Delete unnecessary files
// Delete unnecessary files
@ -410,12 +411,12 @@ namespace AM2RLauncher.Core
string apktoolText = File . ReadAllText ( workingDir + "/../apktool.yml" ) ;
string apktoolText = File . ReadAllText ( workingDir + "/../apktool.yml" ) ;
apktoolText = apktoolText . Replace ( "doNotCompress:" , "doNotCompress:\n- ogg" ) ;
apktoolText = apktoolText . Replace ( "doNotCompress:" , "doNotCompress:\n- ogg" ) ;
File . WriteAllText ( workingDir + "/../apktool.yml" , apktoolText ) ;
File . WriteAllText ( workingDir + "/../apktool.yml" , apktoolText ) ;
L og. Info ( "Unnecessary files removed, apktool.yml modified to prevent ogg compression." ) ;
l og. Info ( "Unnecessary files removed, apktool.yml modified to prevent ogg compression." ) ;
progress . Report ( 70 ) ;
progress . Report ( 70 ) ;
// Rebuild APK
// Rebuild APK
CrossPlatformOperations . RunJavaJar ( "\"" + apktoolPath + "\" b AM2RWrapper -o \"" + profile . Name + ".apk\"" , tempDir ) ;
CrossPlatformOperations . RunJavaJar ( "\"" + apktoolPath + "\" b AM2RWrapper -o \"" + profile . Name + ".apk\"" , tempDir ) ;
L og. Info ( "AM2RWrapper rebuilt into " + profile . Name + ".apk." ) ;
l og. Info ( "AM2RWrapper rebuilt into " + profile . Name + ".apk." ) ;
progress . Report ( 84 ) ;
progress . Report ( 84 ) ;
// Debug-sign APK
// Debug-sign APK
@ -423,12 +424,12 @@ namespace AM2RLauncher.Core
// Extra file cleanup
// Extra file cleanup
File . Copy ( tempDir + "/" + profile . Name + "-aligned-debugSigned.apk" , CrossPlatformOperations . CURRENTPATH + "/" + profile . Name + ".apk" , true ) ;
File . Copy ( tempDir + "/" + profile . Name + "-aligned-debugSigned.apk" , CrossPlatformOperations . CURRENTPATH + "/" + profile . Name + ".apk" , true ) ;
L og. Info ( profile . Name + ".apk signed and moved to " + CrossPlatformOperations . CURRENTPATH + "/" + profile . Name + ".apk." ) ;
l og. Info ( profile . Name + ".apk signed and moved to " + CrossPlatformOperations . CURRENTPATH + "/" + profile . Name + ".apk." ) ;
HelperMethods . DeleteDirectory ( tempDir ) ;
HelperMethods . DeleteDirectory ( tempDir ) ;
// Done
// Done
progress . Report ( 100 ) ;
progress . Report ( 100 ) ;
L og. Info ( "Successfully created Android APK for profile " + profile . Name + "." ) ;
l og. Info ( "Successfully created Android APK for profile " + profile . Name + "." ) ;
CrossPlatformOperations . OpenFolderAndSelectFile ( CrossPlatformOperations . CURRENTPATH + "/" + profile . Name + ".apk" ) ;
CrossPlatformOperations . OpenFolderAndSelectFile ( CrossPlatformOperations . CURRENTPATH + "/" + profile . Name + ".apk" ) ;
}
}
@ -443,7 +444,7 @@ namespace AM2RLauncher.Core
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 ) ) ;
L og. Info ( "Launching game profile " + profile . Name + "." ) ;
l og. Info ( "Launching game profile " + profile . Name + "." ) ;
if ( OS . IsWindows )
if ( OS . IsWindows )
{
{
// Sets the arguments to empty, or to the profiles save path/logs and create time based logs. Creates the folder if necessary.
// Sets the arguments to empty, or to the profiles save path/logs and create time based logs. Creates the folder if necessary.
@ -452,7 +453,7 @@ namespace AM2RLauncher.Core
// Game logging
// Game logging
if ( useLogging )
if ( useLogging )
{
{
L og. Info ( "Performing logging setup for profile " + profile . Name + "." ) ;
l og. 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 ) ;
@ -464,7 +465,7 @@ namespace AM2RLauncher.Core
stream . WriteLine ( "AM2RLauncher " + Core . VERSION + " log generated at " + date ) ;
stream . WriteLine ( "AM2RLauncher " + Core . VERSION + " log generated at " + date ) ;
if ( Core . i sThisRunningFromWine)
if ( Core . I sThisRunningFromWine)
stream . WriteLine ( "Using WINE!" ) ;
stream . WriteLine ( "Using WINE!" ) ;
stream . Flush ( ) ;
stream . Flush ( ) ;
@ -480,20 +481,19 @@ namespace AM2RLauncher.Core
proc . FileName = proc . WorkingDirectory + "/AM2R.exe" ;
proc . FileName = proc . WorkingDirectory + "/AM2R.exe" ;
proc . Arguments = arguments ;
proc . Arguments = arguments ;
L og. Info ( "CWD of Profile is " + proc . WorkingDirectory ) ;
l og. Info ( "CWD of Profile is " + proc . WorkingDirectory ) ;
using ( var p = Process . Start ( proc ) )
using var p = Process . Start ( proc ) ;
{
Core . SetForegroundWindow ( p . MainWindowHandle ) ;
Core . SetForegroundWindow ( p . MainWindowHandle ) ;
p . WaitForExit ( ) ;
p . WaitForExit ( ) ;
}
}
}
else if ( OS . IsLinux )
else if ( OS . IsLinux )
{
{
ProcessStartInfo startInfo = new ProcessStartInfo ( ) ;
ProcessStartInfo startInfo = new ProcessStartInfo ( ) ;
L og. Info ( "Is the environment textbox null or whitespace = " + String . IsNullOrWhiteSpace ( envVars ) ) ;
l og. Info ( "Is the environment textbox null or whitespace = " + String . IsNullOrWhiteSpace ( envVars ) ) ;
//TODO: make this more readable at one day
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 + + )
@ -503,7 +503,7 @@ namespace AM2RLauncher.Core
envVars = envVars . Replace ( variable + "=" , "" ) ;
envVars = envVars . Replace ( variable + "=" , "" ) ;
// This thing here is the value parser. Since values are sometimes in quotes, i need to compensate for them.
// This thing here is the value parser. Since values are sometimes in quotes, i need to compensate for them.
int valueSubstringLength = 0 ;
int valueSubstringLength ;
if ( envVars [ 0 ] ! = '"' ) // If value is not embedded in "", check if there are spaces left. If yes, get the index of the space, if not that was the last
if ( envVars [ 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 )
if ( envVars . IndexOf ( ' ' ) > = 0 )
@ -523,7 +523,7 @@ namespace AM2RLauncher.Core
string value = envVars . Substring ( 0 , valueSubstringLength ) ;
string value = envVars . Substring ( 0 , valueSubstringLength ) ;
envVars = envVars . Substring ( value . Length ) ;
envVars = envVars . Substring ( value . Length ) ;
L og. Info ( "Adding variable \"" + variable + "\" with value \"" + value + "\"" ) ;
l og. Info ( "Adding variable \"" + variable + "\" with value \"" + value + "\"" ) ;
startInfo . EnvironmentVariables [ variable ] = value ;
startInfo . EnvironmentVariables [ variable ] = value ;
}
}
}
}
@ -535,12 +535,12 @@ namespace AM2RLauncher.Core
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" ;
L og. Info ( "CWD of Profile is " + startInfo . WorkingDirectory ) ;
l og. Info ( "CWD of Profile is " + startInfo . WorkingDirectory ) ;
L og. Info ( "Launching game with following variables: " ) ;
l og. Info ( "Launching game with following variables: " ) ;
foreach ( System . Collections . DictionaryEntry item in startInfo . EnvironmentVariables )
foreach ( System . Collections . DictionaryEntry item in startInfo . EnvironmentVariables )
{
{
L og. Info ( "Key: \"" + item . Key + "\" Value: \"" + item . Value + "\"" ) ;
l og. Info ( "Key: \"" + item . Key + "\" Value: \"" + item . Value + "\"" ) ;
}
}
using ( Process p = new Process ( ) )
using ( Process p = new Process ( ) )
@ -549,10 +549,10 @@ namespace AM2RLauncher.Core
if ( useLogging )
if ( useLogging )
{
{
p . StartInfo . RedirectStandardOutput = true ;
p . StartInfo . RedirectStandardOutput = true ;
p . OutputDataReceived + = ( sender , e ) = > { terminalOutput + = e . Data + "\n" ; } ;
p . OutputDataReceived + = ( _ , e ) = > { terminalOutput + = e . Data + "\n" ; } ;
p . StartInfo . RedirectStandardError = true ;
p . StartInfo . RedirectStandardError = true ;
p . ErrorDataReceived + = ( sender , e ) = > { terminalOutput + = e . Data + "\n" ; } ;
p . ErrorDataReceived + = ( _ , e ) = > { terminalOutput + = e . Data + "\n" ; } ;
}
}
p . Start ( ) ;
p . Start ( ) ;
@ -568,7 +568,7 @@ namespace AM2RLauncher.Core
if ( terminalOutput ! = null )
if ( terminalOutput ! = null )
{
{
L og. Info ( "Performed logging setup for profile " + profile . Name + "." ) ;
l og. Info ( "Performed logging setup for profile " + profile . Name + "." ) ;
if ( ! Directory . Exists ( logDir . FullName ) )
if ( ! Directory . Exists ( logDir . FullName ) )
Directory . CreateDirectory ( logDir . FullName ) ;
Directory . CreateDirectory ( logDir . FullName ) ;
@ -598,7 +598,7 @@ namespace AM2RLauncher.Core
// Game logging
// Game logging
if ( useLogging )
if ( useLogging )
{
{
L og. Info ( "Performing logging setup for profile " + profile . Name + "." ) ;
l og. 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 ) ;
@ -623,17 +623,15 @@ namespace AM2RLauncher.Core
proc . FileName = "open" ;
proc . FileName = "open" ;
proc . Arguments = arguments ;
proc . Arguments = arguments ;
L og. Info ( "CWD of Profile is " + proc . WorkingDirectory ) ;
l og. Info ( "CWD of Profile is " + proc . WorkingDirectory ) ;
using ( var p = Process . Start ( proc ) )
using var p = Process . Start ( proc ) ;
{
p ? . WaitForExit ( ) ;
p ? . WaitForExit ( ) ;
}
}
}
else
else
L og. Error ( OS . Name + " cannot run games!" ) ;
l og. Error ( OS . Name + " cannot run games!" ) ;
L og. Info ( "Profile " + profile . Name + " process exited." ) ;
l og. Info ( "Profile " + profile . Name + " process exited." ) ;
}
}
/// <summary>
/// <summary>
@ -700,8 +698,7 @@ namespace AM2RLauncher.Core
Directory . Delete ( tmpPath , true ) ;
Directory . Delete ( tmpPath , true ) ;
// If we didn't exit before, everything is fine
// If we didn't exit before, everything is fine
L og. Info ( "AM2R_11 check successful!" ) ;
l og. Info ( "AM2R_11 check successful!" ) ;
return IsZipAM2R11ReturnCodes . Successful ;
return IsZipAM2R11ReturnCodes . Successful ;
}
}
}
}
}