@ -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 Mod s 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 ( ! s tring. IsNullOrWhiteSpace ( fileFinder . FileName ) ) // This is default
if ( ! S tring. 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 ( ! s tring. IsNullOrWhiteSpace ( fileFinder . FileName ) ) // This is default
if ( ! S tring. 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 ( ! s tring. IsNullOrWhiteSpace ( fileFinder . FileName ) ) // This is default
if ( ! S tring. 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." ) ;
}
}