2020-06-16 17:22:29 +00:00
using GCMM.Properties ;
using Newtonsoft.Json.Linq ;
using System ;
using System.Collections.Generic ;
using System.Diagnostics ;
using System.IO.Compression ;
using System.IO ;
using System.Linq ;
using System.Net ;
using System.Text ;
using System.Threading.Tasks ;
using System.Windows.Forms ;
namespace GCMM
{
partial class MainForm
{
2020-08-18 18:56:19 +00:00
public GameState CheckIfPatched ( )
2020-06-16 17:22:29 +00:00
{
2020-08-18 18:56:19 +00:00
if ( GetExe ( ) = = null )
{
status . Text = "Status: Game not found" ;
return GameState . NotFound ;
}
2020-08-18 14:02:57 +00:00
string pnp = "Patch && Play" ;
2020-07-03 00:00:08 +00:00
if ( ! File . Exists ( GamePath ( @"\IPA.exe" ) ) )
2020-06-16 17:22:29 +00:00
{
status . Text = "Status: Patcher missing\nClicking Play will install it" ;
2020-07-18 20:25:52 +00:00
playbtn . Text = pnp ;
2020-08-18 18:56:19 +00:00
return GameState . NoPatcher ;
2020-06-16 17:22:29 +00:00
}
2020-08-18 14:02:57 +00:00
string nopatch = "Status: Unpatched\nClicking Play patches it" ;
2020-07-18 20:25:52 +00:00
string gc = GetExe ( ) . Replace ( ".exe" , "" ) ;
string backups = GamePath ( @"\IPA\Backups\" + gc ) ;
2020-07-03 00:00:08 +00:00
if ( ! Directory . Exists ( backups ) )
2020-06-16 17:22:29 +00:00
{
status . Text = nopatch ;
2020-07-18 20:25:52 +00:00
playbtn . Text = pnp ;
2020-08-18 18:56:19 +00:00
return GameState . Unpatched ;
2020-06-16 17:22:29 +00:00
}
2020-08-18 22:32:39 +00:00
string backup = Directory . EnumerateDirectories ( backups ) . OrderByDescending ( name = > Directory . GetLastWriteTimeUtc ( name ) ) . FirstOrDefault ( ) ;
2020-06-16 17:22:29 +00:00
if ( backup = = null )
{
status . Text = nopatch ;
2020-07-18 20:25:52 +00:00
playbtn . Text = pnp ;
2020-08-18 18:56:19 +00:00
return GameState . Unpatched ;
2020-06-16 17:22:29 +00:00
}
2020-07-18 20:25:52 +00:00
if ( File . GetLastWriteTime ( GamePath ( $@"\{gc}_Data\Managed\Assembly-CSharp.dll" ) )
2020-06-16 17:22:29 +00:00
> //If the file was updated at least 2 minutes after patching
Directory . GetLastWriteTime ( backup ) . AddMinutes ( 2 ) )
{
status . Text = nopatch ;
2020-07-18 20:25:52 +00:00
playbtn . Text = pnp ;
2020-08-18 18:56:19 +00:00
return GameState . Unpatched ;
2020-06-16 17:22:29 +00:00
}
2020-08-18 14:02:57 +00:00
status . Text = "Status: " + ( unpatched . Checked ? "Mods disabled" : "Patched" ) ;
playbtn . Text = "Play" + ( unpatched . Checked ? " unmodded" : "" ) ;
2020-08-18 18:56:19 +00:00
return GameState . Patched ;
2020-06-16 17:22:29 +00:00
}
2020-06-18 16:28:07 +00:00
public async Task PatchStartGame ( )
2020-06-16 17:22:29 +00:00
{
2020-06-18 16:28:07 +00:00
if ( ! BeginWork ( ) ) return ;
foreach ( ListViewItem item in modlist . SelectedItems )
item . Selected = false ;
2020-08-18 18:56:19 +00:00
var status = CheckIfPatched ( ) ;
switch ( status )
2020-06-16 17:22:29 +00:00
{
2020-08-18 18:56:19 +00:00
case GameState . NotFound :
MessageBox . Show ( "Gamecraft not found! Set the correct path in Settings." ) ;
EndWork ( false ) ;
2020-06-16 17:22:29 +00:00
return ;
2020-08-18 18:56:19 +00:00
case GameState . NoPatcher :
{
if ( MessageBox . Show ( "The patcher (GCIPA) is not found. It's necessary to load the mods. It will be downloaded from https://git.exmods.org/modtainers/GCIPA/releases and ran to patch the game. You can unpatch to run without mods at any time." , "Patcher download needed" , MessageBoxButtons . OKCancel )
= = DialogResult . Cancel )
{
EndWork ( ) ;
return ;
}
string releases = "/api/v1/repos/modtainers/GCIPA/releases" ;
string url ;
this . status . Text = "Status: Patching..." ;
using ( WebClient client = GetClient ( ) )
{
url = JArray . Parse ( await client . DownloadStringTaskAsync ( releases ) ) . First [ "assets" ] . First [ "browser_download_url" ] . ToString ( ) ;
await client . DownloadFileTaskAsync ( url , "IPA.zip" ) ;
2020-08-18 22:32:39 +00:00
using ( var fs = new FileStream ( "IPA.zip" , FileMode . Open ) )
using ( var za = new ZipArchive ( fs ) )
za . ExtractToDirectory ( Settings . Default . GamePath , true ) ; //Overwrite files that were left from a previous install of the patcher
2020-08-18 18:56:19 +00:00
}
}
2020-08-18 22:32:39 +00:00
status = CheckIfPatched ( ) ;
2020-08-18 18:56:19 +00:00
break ;
2020-06-16 17:22:29 +00:00
}
2020-08-18 18:56:19 +00:00
switch ( status )
2020-06-18 16:28:07 +00:00
{
2020-08-18 18:56:19 +00:00
case GameState . NoPatcher : //Make sure it actually worked
EndWork ( false ) ;
return ;
case GameState . Unpatched :
{ //TODO: Wine
var psi = new ProcessStartInfo ( GamePath ( @"\IPA.exe" ) , GetExe ( ) + " --nowait" )
{
UseShellExecute = false ,
RedirectStandardError = true ,
RedirectStandardOutput = true ,
WorkingDirectory = Settings . Default . GamePath ,
CreateNoWindow = true
} ;
var process = Process . Start ( psi ) ;
process . BeginErrorReadLine ( ) ;
process . BeginOutputReadLine ( ) ;
process . EnableRaisingEvents = true ;
modinfobox . Text = "" ;
DataReceivedEventHandler onoutput = ( sender , e ) = >
{
Invoke ( ( Action ) ( ( ) = > modinfobox . Text + = e . Data + Environment . NewLine ) ) ;
} ;
process . OutputDataReceived + = onoutput ;
process . ErrorDataReceived + = onoutput ;
process . Exited + = CheckStartGame ;
}
break ;
case GameState . Patched :
CheckStartGame ( null , null ) ;
break ;
2020-06-16 17:22:29 +00:00
}
2020-08-18 18:56:19 +00:00
}
public enum GameState
{
NotFound ,
NoPatcher ,
Unpatched ,
Patched
2020-06-16 17:22:29 +00:00
}
}
}