2022-08-20 15:20:25 +08:00
using System ;
using System.Diagnostics ;
2022-09-08 12:41:56 -07:00
using System.IO ;
using System.Linq ;
2022-08-20 15:20:25 +08:00
using System.Reflection ;
2022-08-21 13:42:28 +08:00
using System.Threading ;
2022-09-08 12:41:56 -07:00
using System.Threading.Tasks ;
using System.Windows ;
2022-08-21 13:42:28 +08:00
using System.Windows.Forms ;
2022-09-08 12:41:56 -07:00
using System.Windows.Input ;
2022-08-21 13:42:28 +08:00
using MessageBox = System . Windows . MessageBox ;
using OpenFileDialog = Microsoft . Win32 . OpenFileDialog ;
2022-09-08 12:41:56 -07:00
using Path = System . IO . Path ;
using RageCoop.Core ;
2022-08-20 15:20:25 +08:00
namespace RageCoop.Client.Installer
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow ( )
{
InitializeComponent ( ) ;
Choose ( ) ;
}
private void Choose ( )
{
var od = new OpenFileDialog ( )
{
Filter = "GTA 5 executable |GTA5.exe;PlayGTAV.exe" ,
2022-09-08 12:41:56 -07:00
Title = "Select you GTAV executable"
2022-08-20 15:20:25 +08:00
} ;
2022-08-20 17:27:05 +08:00
if ( od . ShowDialog ( ) ? ? false = = true )
2022-08-20 15:20:25 +08:00
{
2022-09-08 12:41:56 -07:00
Task . Run ( ( ) = >
{
2022-08-20 17:27:05 +08:00
try
{
Install ( Directory . GetParent ( od . FileName ) . FullName ) ;
}
catch ( Exception ex )
{
MessageBox . Show ( "Installation failed: " + ex . ToString ( ) ) ;
2022-08-21 15:13:36 +08:00
Environment . Exit ( 1 ) ;
2022-08-20 17:27:05 +08:00
}
} ) ;
2022-08-20 15:20:25 +08:00
}
else
{
Environment . Exit ( 0 ) ;
}
}
2022-09-08 12:41:56 -07:00
private void Install ( string root )
2022-08-20 15:20:25 +08:00
{
UpdateStatus ( "Checking requirements" ) ;
var shvPath = Path . Combine ( root , "ScriptHookV.dll" ) ;
var shvdnPath = Path . Combine ( root , "ScriptHookVDotNet3.dll" ) ;
var scriptsPath = Path . Combine ( root , "Scripts" ) ;
var lemonPath = Path . Combine ( scriptsPath , "LemonUI.SHVDN3.dll" ) ;
var installPath = Path . Combine ( scriptsPath , "RageCoop" ) ;
2022-09-08 12:41:56 -07:00
if ( Directory . GetParent ( Assembly . GetExecutingAssembly ( ) . Location ) . FullName = = installPath )
2022-08-21 13:42:28 +08:00
{
throw new InvalidOperationException ( "The installer is not meant to be run in the game folder, please extract the zip to somewhere else and run again." ) ;
}
2022-08-20 15:20:25 +08:00
Directory . CreateDirectory ( installPath ) ;
if ( ! File . Exists ( shvPath ) )
{
MessageBox . Show ( "Please install ScriptHookV first!" ) ;
Environment . Exit ( 1 ) ;
}
if ( ! File . Exists ( shvdnPath ) )
{
MessageBox . Show ( "Please install ScriptHookVDotNet first!" ) ;
Environment . Exit ( 1 ) ;
}
var shvdnVer = GetVer ( shvdnPath ) ;
2023-07-26 15:12:58 -03:00
if ( shvdnVer < new Version ( 3 , 6 , 0 ) )
2022-08-20 15:20:25 +08:00
{
MessageBox . Show ( "Please update ScriptHookVDotNet to latest version!" +
2023-07-26 15:12:58 -03:00
$"\nCurrent version is {shvdnVer}, 3.6.0 or higher is required" ) ;
2022-08-20 15:20:25 +08:00
Environment . Exit ( 1 ) ;
}
if ( File . Exists ( lemonPath ) )
{
2022-09-08 12:41:56 -07:00
var lemonVer = GetVer ( lemonPath ) ;
if ( lemonVer < new Version ( 1 , 7 ) )
2022-08-20 15:20:25 +08:00
{
UpdateStatus ( "Updating LemonUI" ) ;
2022-09-08 12:41:56 -07:00
File . WriteAllBytes ( lemonPath , getLemon ( ) ) ;
2022-08-20 15:20:25 +08:00
}
}
2022-08-21 13:42:28 +08:00
2022-08-20 15:20:25 +08:00
UpdateStatus ( "Removing old versions" ) ;
foreach ( var f in Directory . GetFiles ( scriptsPath , "RageCoop.*" , SearchOption . AllDirectories ) )
{
2022-08-21 15:13:36 +08:00
if ( f . EndsWith ( "RageCoop.Client.Settings.xml" ) ) { continue ; }
2022-08-20 15:20:25 +08:00
File . Delete ( f ) ;
}
foreach ( var f in Directory . GetFiles ( installPath , "*.dll" , SearchOption . AllDirectories ) )
{
File . Delete ( f ) ;
}
2022-08-22 17:30:15 +08:00
if ( File . Exists ( "RageCoop.Core.dll" ) & & File . Exists ( "RageCoop.Client.dll" ) )
2022-08-20 15:20:25 +08:00
{
UpdateStatus ( "Installing..." ) ;
2022-08-22 17:30:15 +08:00
CoreUtils . CopyFilesRecursively ( new DirectoryInfo ( Directory . GetCurrentDirectory ( ) ) , new DirectoryInfo ( installPath ) ) ;
2022-08-21 13:42:28 +08:00
Finish ( ) ;
2022-08-20 15:20:25 +08:00
}
else
{
2022-08-22 17:30:15 +08:00
throw new Exception ( "Required files are missing, please re-download the zip from official website" ) ;
2022-08-20 15:20:25 +08:00
}
2022-08-21 13:42:28 +08:00
void Finish ( )
{
2022-09-08 12:41:56 -07:00
checkKeys :
2022-08-21 13:42:28 +08:00
UpdateStatus ( "Checking conflicts" ) ;
var menyooConfig = Path . Combine ( root , @"menyooStuff\menyooConfig.ini" ) ;
2022-08-21 14:28:37 +08:00
var settingsPath = Path . Combine ( installPath , @"Data\RageCoop.Client.Settings.xml" ) ;
2022-08-21 13:42:28 +08:00
Settings settings = null ;
try
{
settings = Util . ReadSettings ( settingsPath ) ;
}
catch
{
settings = new Settings ( ) ;
}
if ( File . Exists ( menyooConfig ) )
{
2022-09-08 12:41:56 -07:00
var lines = File . ReadAllLines ( menyooConfig ) . Where ( x = > ! x . StartsWith ( ";" ) & & x . EndsWith ( " = " + ( int ) settings . MenuKey ) ) ;
2022-08-21 13:42:28 +08:00
if ( lines . Any ( ) )
{
2022-09-08 12:41:56 -07:00
if ( MessageBox . Show ( "Following menyoo config value will conflict with RAGECOOP menu key\n" +
2022-08-21 13:42:28 +08:00
string . Join ( "\n" , lines )
+ "\nDo you wish to change the Menu Key?" , "Warning!" , MessageBoxButton . YesNo ) = = MessageBoxResult . Yes )
{
2022-09-08 12:41:56 -07:00
var ae = new AutoResetEvent ( false ) ;
2022-08-21 13:42:28 +08:00
UpdateStatus ( "Press the key you wish to change to" ) ;
Dispatcher . BeginInvoke ( new Action ( ( ) = >
2022-09-08 12:41:56 -07:00
KeyDown + = ( s , e ) = >
2022-08-21 13:42:28 +08:00
{
settings . MenuKey = ( Keys ) KeyInterop . VirtualKeyFromKey ( e . Key ) ;
ae . Set ( ) ;
} ) ) ;
ae . WaitOne ( ) ;
2022-09-08 12:41:56 -07:00
if ( ! Util . SaveSettings ( settingsPath , settings ) )
2022-08-21 13:42:28 +08:00
{
MessageBox . Show ( "Error occurred when saving settings" ) ;
Environment . Exit ( 1 ) ;
}
2022-09-08 12:41:56 -07:00
MessageBox . Show ( "Menu key changed to " + settings . MenuKey ) ;
2022-08-21 13:42:28 +08:00
goto checkKeys ;
}
2022-08-21 15:13:36 +08:00
}
}
UpdateStatus ( "Checking ZeroTier" ) ;
try
{
ZeroTierHelper . Check ( ) ;
}
catch
{
2022-09-08 12:41:56 -07:00
if ( MessageBox . Show ( "You can't join ZeroTier server unless ZeroTier is installed, do you want to download and install it?" , "Install ZeroTier" , MessageBoxButton . YesNo ) = = MessageBoxResult . Yes )
2022-08-21 15:13:36 +08:00
{
var url = "https://download.zerotier.com/dist/ZeroTier%20One.msi" ;
2022-09-08 12:41:56 -07:00
UpdateStatus ( "Downloading ZeroTier from " + url ) ;
2022-08-21 15:13:36 +08:00
try
{
HttpHelper . DownloadFile ( url , "ZeroTier.msi" , ( p ) = > UpdateStatus ( "Downloading ZeroTier " + p + "%" ) ) ;
UpdateStatus ( "Installing ZeroTier" ) ;
Process . Start ( "ZeroTier.msi" ) . WaitForExit ( ) ;
}
catch
{
MessageBox . Show ( "Failed to download ZeroTier, please download it from officail website" ) ;
Process . Start ( url ) ;
}
2022-08-21 13:42:28 +08:00
}
}
UpdateStatus ( "Completed!" ) ;
MessageBox . Show ( "Installation sucessful!" ) ;
Environment . Exit ( 0 ) ;
}
2022-08-20 15:20:25 +08:00
}
2022-09-08 12:41:56 -07:00
private void UpdateStatus ( string status )
2022-08-20 15:20:25 +08:00
{
Dispatcher . BeginInvoke ( new Action ( ( ) = > Status . Content = status ) ) ;
}
2022-09-08 12:41:56 -07:00
private Version GetVer ( string location )
2022-08-20 15:20:25 +08:00
{
return Version . Parse ( FileVersionInfo . GetVersionInfo ( location ) . FileVersion ) ;
}
2022-09-08 12:41:56 -07:00
private byte [ ] getLemon ( )
2022-08-20 15:20:25 +08:00
{
return ( byte [ ] ) Resource . ResourceManager . GetObject ( "LemonUI_SHVDN3" ) ;
}
2022-09-08 12:41:56 -07:00
2022-08-20 15:20:25 +08:00
}
}