Subversion Repositories spk

Rev

Rev 204 | Rev 214 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 cycrow 1
/*
2
 SPKInstall V1.00 Created by Cycrow (Matthew Gravestock)
3
*/
4
 
5
// Main Spk File Library Include
6
#ifdef _WIN32
7
#include <spk.h>
8
#else
9
#include "../spk/spk.h"
10
#endif
11
#include <time.h>
12
 
13
#ifdef _WIN32
14
#include <windows.h>
15
#include <direct.h>
16
#include <shlobj.h>
17
#endif
18
 
46 cycrow 19
#include <Package/InstallText.h>
20
 
1 cycrow 21
#define BETA 1
22
 
23
class CProgressConsole : public CProgressInfo
24
{
25
public:
26
	CProgressConsole() : CProgressInfo()
27
	{
28
		m_iCount = 0;
29
		m_fNextPercent = 0.0f;
30
	}
31
 
32
	void Finish(bool newline = true)
33
	{
34
		for ( int i = m_iCount; i < 20; i++ )
35
			printf ( "*" );
36
		if ( newline )
37
			printf ( "\n");
38
		m_fNextPercent = 0.0f;
39
		m_iCount = 0;
40
	}
41
 
42
protected:
43
	virtual void ProgressUpdated ( const long cur, const long max )
44
	{
45
		float percent = ((float)cur / (float)max) * 100.0f;
46
		if ( m_bDoHalf )
47
		{
48
			percent /= 2.0f;
49
			if ( m_bSecondHalf )
50
				percent += 50.0f;
51
			else if ( percent > 50.0f )
52
				percent = 50.0f;
53
		}
54
		if ( (percent - m_fNextPercent) >= 5.0f )
55
		{
56
			printf ( "*" );
57
			m_fNextPercent += 5.0f;
58
			++m_iCount;
59
		}
60
	}
61
	virtual void DoingFile ( C_File *file )
62
	{
63
	}
64
 
65
private:
66
	float m_fNextPercent;
67
	int   m_iCount;
68
};
69
 
70
#define FLAGS "[-voctm][-d destination][-l langid]"
71
 
72
CyString	g_dir;
73
bool	g_debug = false;
74
bool	g_force = false;
75
int		g_indent = 0;
76
/*
77
	Func:	GetInput
78
	Desc:	Gets an input from the user, ie, any settings required to be typed in
79
*/
206 cycrow 80
Utils::WString GetInput ()
1 cycrow 81
{
82
//	g_read = true;
83
 
206 cycrow 84
	Utils::WString line;
1 cycrow 85
	char c = getchar();
86
 
87
	while ( (c != '\n') && (c != '\0') )
88
	{
206 cycrow 89
		line += Utils::WString(c);
1 cycrow 90
		c = getchar();
91
	}
92
 
93
	return line;
94
}
95
 
96
void PrintSyntax ( CyString cmd )
97
{
98
	printf ( "Syntax: %s %s </command> [arguments]\n", cmd.c_str(), FLAGS );
99
	printf ( "\nCommands:\n" );
100
	printf ( "   /list\n\t- Lists installed packages\n" );
101
	printf ( "   /install <file>\n\t- Installs a package file\n" );
102
	printf ( "   /uninstall <package#>\n\t- Uninstalls a package, use id number from list\n" );
103
	printf ( "   /enable <package#>\n\t- Enables an installed package\n" );
104
	printf ( "   /disable <package#>\n\t- Disables an installed package\n" );
105
	printf ( "   /removeuninstall\n\t- Removes uninstall scripts\n" );
106
	printf ( "   /removeshared\n\t- Removes unused sharded files\n" );
107
	printf ( "\nSwitchs:\n" );
108
	printf ( "   -d (--directory) [directory]\n\tChange destination directory, otherwise uses current\n\n" );
109
	printf ( "   -v (--verbose)\n\tTurns on verbose mode\n\n" );
110
	printf ( "   -o (--override)\n\tOverride install warnings\n\tIE. allows you to install older scripts\n\n" );
111
	printf ( "   -t (--textrename)\n\tForces text file renaming for installed packages\n\n" );
112
	printf ( "   -l (--language) <language>\n\tSets the language id for text file renaming\n\totheriwse reads game lang.dat\n\n" );
113
	printf ( "   -c (--enablechild)\n\tAuto Enabled all children when parent is enabled\n\n" );
114
	printf ( "   -m (--forcemod\n\tForces a mod enabled even if theres one already enabled\n\n" );
115
}
116
 
117
void DisplayPackage(CBaseFile *p, int indent, int language)
118
{
204 cycrow 119
	Utils::WString version = p->version();
1 cycrow 120
	if ( version.lower()[0] != 'v' )
204 cycrow 121
		version.prepend(L"v");
1 cycrow 122
 
123
	printf ( "  [%5d] ", p->GetNum() + 1 );
124
 
125
	if ( indent > g_indent )
126
	{
127
		printf (" \\->");
128
	}
129
	for ( int i = 0; i < indent; i++ )
130
		printf("\t");
131
 
132
	g_indent = indent;
133
 
134
	if ( !p->IsEnabled() )
135
		printf("[D] ");
136
 
204 cycrow 137
	wprintf(L"%s %s by %s\n", p->name(language).c_str(), version.c_str(), p->author().c_str() );
1 cycrow 138
}
139
 
140
void DoAllChildren(CPackages *packages, CBaseFile *p, CLinkList<CBaseFile> *doneList, int indent)
141
{
142
	CLinkList<CBaseFile> children;
143
	if ( packages->GetChildPackages(p, &children) )
144
	{
145
		for ( CBaseFile *child = children.First(); p; p = children.Next() )
146
		{
147
			DisplayPackage(child, indent, packages->GetLanguage());
148
			doneList->push_back(child);
149
 
150
			DoAllChildren(packages, child, doneList, indent + 1);
151
		}
152
	}
153
}
154
 
155
void ListPackages(CPackages *packages)
156
{
157
	CProgressConsole progress;
158
 
159
	CLinkList<CBaseFile> doneList;
160
 
161
	g_indent = 0;
162
	printf ( "\nPackages:\n" );
163
	for ( CBaseFile *p = packages->PackageList()->First(); p; p = packages->PackageList()->Next() )
164
	{
165
		// already done?
166
		if ( doneList.FindData(p) )
167
			continue;
168
 
169
		if ( p->GetType() != TYPE_SPK )
170
			continue;
171
 
172
		DisplayPackage(p, 0, packages->GetLanguage());
173
		doneList.push_back(p);
174
 
175
		// find all children
176
		DoAllChildren(packages, p, &doneList, 1);
177
	}
178
}
179
 
180
int SplitArguments(char **argv, int argc, int start, CyStringList *argList)
181
{
182
	for ( int i = start; i < argc; i++ )
183
	{
184
		CyString arg = argv[i];
185
		if ( !arg.Empty() )
186
			argList->PushBack(arg);
187
	}
188
 
189
	return argList->Count();
190
}
191
 
203 cycrow 192
Utils::WString InstallPackage(CyStringList *lArguments, Utils::WStringList *errors, CPackages *packages, bool disabled)
1 cycrow 193
{
194
	CProgressConsole progress;
195
 
196
	int error;
197
 
198
	if ( !lArguments || !lArguments->Count() )
203 cycrow 199
		return Utils::WString::Null();
1 cycrow 200
 
201
	// append spk on the end
202
	for ( SStringList *node = lArguments->Head(); node; node = node->next )
203
	{
185 cycrow 204
		if (!CFileIO::Exists(node->str.ToString()))
1 cycrow 205
		{
197 cycrow 206
			if (CFileIO(node->str.ToString()).extension().lower() != L"spk")
1 cycrow 207
				node->str += ".spk";
208
		}
209
	}
210
 
211
	CLinkList<CBaseFile> lPackages;
212
 
213
	// open the package file
214
	printf ( "  - Opening Package                \n" );
215
	for ( SStringList *node = lArguments->Head(); node; node = node->next )
216
	{
182 cycrow 217
		Utils::String spkFilename = node->str.ToString();
1 cycrow 218
 
182 cycrow 219
		if ( spkFilename.length() > 30 )
220
			printf ( "    ..%28s ", spkFilename.right(28).c_str() );
1 cycrow 221
		else
182 cycrow 222
			printf ( "    %30s ", spkFilename.right(30).c_str() );
1 cycrow 223
 
224
		CLinkList<CBaseFile> lPackageList;
182 cycrow 225
		CBaseFile *package = packages->openPackage(spkFilename, &error, &progress);
1 cycrow 226
 
227
		// multi packages
228
		if ( !package && error == INSTALLERR_NOMULTI )
229
		{
182 cycrow 230
			if ( !packages->openMultiPackage(spkFilename, &lPackageList, &error, &progress) )
1 cycrow 231
			{
232
				printf ( "Error!\n");
233
				continue;
234
			}
235
			progress.Finish();
236
		}
237
 
238
		else if ( package )
239
		{
240
			progress.Finish();
241
			lPackageList.push_back(package);
242
		}
243
		else
244
		{
245
			printf ( "ERROR!  " );
246
			switch ( error )
247
			{
248
				case INSTALLERR_OLD:
249
					printf ( "File is in old format no longer supported" );
250
					break;
251
				case INSTALLERR_NOEXIST:
252
					printf ( "file doesn't exist" );
253
					break;
254
				case INSTALLERR_INVALID:
255
					printf ( "Invalid package file" );
256
					break;
257
				case INSTALLERR_NOSHIP:
258
					printf ( "Ship Packages are currently not supported" );
259
					break;
260
				case INSTALLERR_VERSION:
261
					printf ( "Package file was created in a newer version, unable to open" );
262
					break;
263
			}
264
			printf ( "\n");
265
			continue;
266
		}
267
 
268
		for ( CListNode<CBaseFile> *pNode = lPackageList.Front(); pNode; pNode = pNode->next() )
269
		{
270
			CBaseFile *package = pNode->Data();
271
 
272
			// compare versions
203 cycrow 273
			Utils::WString packageName = package->getFullPackageName(packages->GetLanguage());
1 cycrow 274
 
275
			int checkFlags = IC_ALL;
276
			int check = packages->PrepareInstallPackage(package, (disabled) ? true : !package->IsEnabled(), false, checkFlags);
277
 
278
			switch (check)
279
			{
280
				case INSTALLCHECK_OLDVERSION:
203 cycrow 281
					wprintf(L"Newer version of \"%s\" already installed", packageName.c_str() );
1 cycrow 282
					if ( !g_force )
283
					{
284
						printf ( ", Unable to install older, use -o to force installation\n" );
285
						continue;
286
					}
287
					else
288
					{
289
						printf ( ", Overriding install\n" );
290
						if ( packages->PrepareInstallPackage(package, disabled, true) != INSTALLCHECK_OK )
291
							continue;
292
						break;
293
					}
294
					break;
295
					// wait for the rest to be added
296
				case INSTALLCHECK_WRONGGAME:
203 cycrow 297
					wprintf ( L"ERROR! \"%s\" Wrong Game (Requires: %s)", packageName.c_str(), packages->getGameTypesString(package, false).c_str() );
1 cycrow 298
					if ( g_force )
299
					{
300
						printf ( " [FORCED]\n" );
301
						if ( packages->PrepareInstallPackage(package, disabled, true) != INSTALLCHECK_OK )
302
							continue;
303
					}
304
					else
305
					{
306
						printf("\n");
307
						continue;
308
					}
309
					break;
310
 
311
				case INSTALLCHECK_WRONGVERSION:
203 cycrow 312
					wprintf ( L"ERROR! \"%s\" Wrong Game Version (Requires: %s)\n", packageName.c_str(), packages->getGameVersionString(package).c_str() );
1 cycrow 313
					if ( g_force )
314
					{
315
						printf ( " [FORCED]\n" );
316
						if ( packages->PrepareInstallPackage(package, disabled, true) != INSTALLCHECK_OK )
317
							continue;
318
					}
319
					else
320
					{
321
						printf("\n");
322
						continue;
323
					}
324
					break;
325
			}
326
 
46 cycrow 327
			if ( package->installText()->any() )
1 cycrow 328
			{
206 cycrow 329
				Utils::WString installtext = packages->getInstallBeforeText(package);
182 cycrow 330
				if ( !installtext.empty() )
1 cycrow 331
				{
182 cycrow 332
					installtext = installtext.stripHtml();
206 cycrow 333
					wprintf(L"Installing %s: %s\n", packageName.c_str(), installtext.c_str() );
1 cycrow 334
					printf ( "Do you want to continue with the install? " );
335
 
336
					if ( g_force )
337
						printf ( "(FORCED)\n" );
338
					else
339
					{
206 cycrow 340
						Utils::WString input = GetInput().lower();
1 cycrow 341
 
342
						if ( input != "y" && input != "yes" )
343
						{
344
							printf ( "\nInstallion aborted!!\n\n" );
345
							packages->RemovePreparedInstall(package);
346
							continue;
347
						}
348
					}
349
				}
350
			}
351
 
352
			lPackages.push_back(package);
353
		}
354
	}
355
 
356
	// is there any that couldn't install
357
	CLinkList<CBaseFile> lCheckPackages;
358
	if ( packages->CheckPreparedInstallRequired(&lCheckPackages) )
359
	{
360
		printf ( "\nError! Some packages are missing dependacies:\n" );
361
		for ( CListNode<CBaseFile> *pNode = lCheckPackages.Front(); pNode; pNode = pNode->next() )
362
		{
363
			CSpkFile *spk = (CSpkFile *)pNode->Data();
204 cycrow 364
			wprintf(L"\t%s V%s by %s (Requires: %hs by %hs)\n", spk->name(packages->GetLanguage()).c_str(), spk->version().c_str(), spk->author().c_str(), spk->GetOtherName().c_str(), spk->GetOtherAuthor().c_str());
1 cycrow 365
		}
366
	}
367
 
368
	// no packages will be installed
369
	if ( packages->GetNumPackagesInQueue() < 1 )
203 cycrow 370
		return Utils::WString::Null();
1 cycrow 371
 
372
	// install the package file
373
	printf ( "  - Installing                     " );
374
	CLinkList<CBaseFile> erroredPackages;
183 cycrow 375
	if ( packages->installPreparedPackages(errors, &progress, &erroredPackages) )
1 cycrow 376
		progress.Finish();
377
	else
378
	{
379
		printf ( "ERROR!\n" );
203 cycrow 380
		return Utils::WString::Null();
1 cycrow 381
	}
382
 
383
	// delete any errored packages
384
	for ( CListNode<CBaseFile> *pNode = erroredPackages.Front(); pNode; pNode = pNode->next() )
385
	{
386
		lPackages.remove(pNode->Data());
387
		pNode->DeleteData();
388
	}
389
 
390
	// now display the packages
203 cycrow 391
	Utils::WString retStr = L"Packages Installed:\n";
1 cycrow 392
	for ( CListNode<CBaseFile> *pNode = lPackages.Front(); pNode; pNode = pNode->next() )
393
	{
394
		CBaseFile *package = pNode->Data();
395
 
203 cycrow 396
		retStr += L"  <> ";
170 cycrow 397
		retStr += package->getFullPackageName(packages->GetLanguage());
203 cycrow 398
		retStr += L"\n";
1 cycrow 399
 
182 cycrow 400
		if ( !packages->getInstallAfterText(package).empty() )
1 cycrow 401
		{
206 cycrow 402
			Utils::WString afterText = packages->getInstallAfterText(package).stripHtml();
403
			afterText = afterText.findReplace(L"\n", L"\n\t");
203 cycrow 404
			retStr += L"\t";
206 cycrow 405
			retStr += afterText;
203 cycrow 406
			retStr += L"\n";
1 cycrow 407
		}
408
	}
409
 
410
	return retStr;
411
}
412
 
413
CBaseFile *FindPackage(int packageNum, CPackages *packages)
414
{
415
	for ( CBaseFile *p = packages->PackageList()->First(); p; p = packages->PackageList()->Next() )
416
	{
417
		if ( p->GetNum() == (packageNum - 1) )
418
			return p;
419
	}
420
 
421
	return 0;
422
}
423
 
206 cycrow 424
bool UninstallPackage(int uninstallNum, Utils::WStringList *errors, CPackages *packages, Utils::WString &endMessage)
1 cycrow 425
{
426
	CBaseFile *p = FindPackage(uninstallNum, packages);
427
	if ( !p )
428
		return false;
429
 
430
	// lets check for the uninstall text
206 cycrow 431
	Utils::WString uText = packages->getUninstallBeforeText(p).stripHtml();
182 cycrow 432
	if (!uText.empty())
1 cycrow 433
	{
206 cycrow 434
		wprintf(L"Uninstalling: %s\n", uText.c_str() );
1 cycrow 435
		printf ( "Do you wish to continue with the uninstall? " );
436
		if ( g_force )
437
			printf ( "(FORCED)\n" );
438
		else
439
		{
206 cycrow 440
			Utils::WString input = GetInput().lower();
1 cycrow 441
			if ( input != "y" && input != "yes" )
442
			{
443
				printf ( "\nUninstallation has been aborted!!\n" );
444
				return false;
445
			}
446
		}
447
	}
448
 
449
	CProgressConsole progress;
450
 
206 cycrow 451
	endMessage = L"Uninstalled: " + p->getFullPackageName(packages->GetLanguage());
1 cycrow 452
	// add the uninstall after text
182 cycrow 453
	uText = packages->getUninstallAfterText(p).stripHtml();
454
	if (!uText.empty())
1 cycrow 455
	{
206 cycrow 456
		endMessage += L"\n\n";
182 cycrow 457
		endMessage += uText;
206 cycrow 458
		endMessage += L"\n";
1 cycrow 459
	}
460
 
461
	printf ( "  - Unistalling                    " );
462
	packages->PrepareUninstallPackage(p);
183 cycrow 463
	if ( packages->uninstallPreparedPackages(errors, &progress) )
1 cycrow 464
	{
465
		progress.Finish();
466
	}
467
	else
468
	{
206 cycrow 469
		endMessage = L"";
1 cycrow 470
		printf ( "ERROR!\n" );
471
		return false;
472
	}
473
 
474
 
475
	return true;
476
}
477
 
206 cycrow 478
bool EnablePackage(int uninstallNum, Utils::WStringList *errors, CPackages *packages, Utils::WString &endMessage)
1 cycrow 479
{
480
	CBaseFile *p = FindPackage(uninstallNum, packages);
481
	if ( !p )
482
		return false;
483
 
484
	CProgressConsole progress;
485
 
206 cycrow 486
	endMessage = L"Enabled: " + p->getFullPackageName(packages->GetLanguage());
1 cycrow 487
 
488
	printf ( "  - Enabling                       " );
183 cycrow 489
	if ( packages->enablePackage(p, errors, &progress) )
1 cycrow 490
	{
491
		progress.Finish();
492
	}
493
	else
494
	{
495
		int error = packages->GetError();
182 cycrow 496
		endMessage = "";
1 cycrow 497
		printf ( "ERROR! " );
498
		if ( error == PKERR_NOPARENT )
499
			printf ( "Parent package is disabled" );
500
		printf ( "\n" );
501
		return false;
502
	}
503
	return true;
504
}
505
 
206 cycrow 506
bool DisablePackage(int uninstallNum, Utils::WStringList *errors, CPackages *packages, Utils::WString &endMessage)
1 cycrow 507
{
508
	CBaseFile *p = FindPackage(uninstallNum, packages);
509
	if ( !p )
510
		return false;
511
 
512
	CProgressConsole progress;
513
 
206 cycrow 514
	endMessage = L"Disabled: " + p->getFullPackageName(packages->GetLanguage());
1 cycrow 515
 
516
	printf ( "  - Disabling                      " );
183 cycrow 517
	if ( packages->disablePackage(p, errors, &progress) )
1 cycrow 518
	{
519
		progress.Finish();
520
	}
521
	else
522
	{
206 cycrow 523
		endMessage = L"";
1 cycrow 524
		printf ( "ERROR!\n" );
525
		return false;
526
	}
527
	return true;
528
}
529
 
197 cycrow 530
void RemoveUninstallScripts(CPackages *packages, Utils::WStringList *errors)
1 cycrow 531
{
532
	CProgressConsole progress;
533
	printf ( "  - Removing uninstall scripts     " );
183 cycrow 534
	packages->removeUninstallScripts(errors, &progress);
1 cycrow 535
	progress.Finish();
536
}
537
 
197 cycrow 538
void RemoveUnusedShared(CPackages *packages, Utils::WStringList *errors)
1 cycrow 539
{
540
	CProgressConsole progress;
541
	printf ( "  - Removing unused shared files   " );
183 cycrow 542
	packages->removeUnusedSharedFiles(errors, &progress);
1 cycrow 543
	progress.Finish();
544
}
545
 
546
 
547
void PrintDebug(CyStringList *errors)
548
{
549
	if ( !g_debug )
550
		return;
551
 
552
	if ( errors && errors->Count() )
553
		printf ( "\n");
554
 
555
	for ( SStringList *str = errors->Head(); str; str = str->next )
556
	{
557
		int errornum = str->str.ToInt();
558
		CyString rest = str->str.GetToken(" ", 2);
559
 
200 cycrow 560
		Utils::WString err = FormatErrorString(errornum, rest.ToString());
561
		wprintf(L"  * %s\n", err.c_str());
1 cycrow 562
	}
563
 
564
	if ( errors && errors->Count() )
565
		printf ( "\n");
566
}
567
 
568
 
569
 
570
 
571
void Pause()
572
{
573
#ifdef _DEBUG
574
	char pause;
575
	scanf ( "%s", &pause );
576
#endif
577
}
578
 
579
 
182 cycrow 580
int ParseCommandSwitchs(char c, Utils::String &destination, CPackages *packages, int start, int *arg, char **argv)
1 cycrow 581
{
582
	switch ( c )
583
	{
584
		case 'o':
585
			g_force = true;
586
			break;
587
		case 'v':
588
			g_debug = true;
589
			break;
590
		case 'd':
182 cycrow 591
			destination = argv[*arg];
592
			destination = destination.findReplace("\\", "/");
1 cycrow 593
			++(*arg);
594
			++start;
595
			break;
596
		case 't':
597
			packages->SetRenameText(true);
598
			break;
599
		case 'l':
600
			packages->SetLanguage(CyString(argv[*arg]).ToInt());
601
			++(*arg);
602
			++start;
603
			break;
604
		case 'c':
605
			packages->SetAutoEnable(true);
606
			break;
607
		case 'm':
608
			packages->SetForceModInstall(true);
609
			break;
610
	}
611
 
612
	return start;
613
}
614
 
615
/*
616
TODO:
617
Additional Features
618
	Patch Mods
619
	Update Packages
620
*/
621
 
622
/*
623
	Main entry point to program
624
*/
625
int main ( int argc, char **argv )
626
{
627
 	// display program header to command prompt
628
	printf ( "\nSPKInstall V0.90 (SPK Library Version %.2f) 18/10/2009 Created by Cycrow\n\n", GetLibraryVersion() );
629
 
630
	// parse the cmd name
631
	CyString cmd (argv[0]);
632
 
633
	cmd = cmd.FindReplace ( "\\", "/" );
634
	g_dir = cmd.GetToken ( 0, cmd.NumToken('/') - 1, '/' );
635
	cmd = cmd.GetToken ( cmd.NumToken('/'), '/' );
636
 
637
	if ( g_dir.Empty() )
638
	{
639
	    #ifdef _WIN32
640
		g_dir = CyString(_getcwd(NULL, 0));
641
		#else
642
		g_dir = CyString(getcwd(NULL, 0));
643
		#endif
644
		if ( g_dir.Empty() )
645
			g_dir = "./";
646
	}
647
 
648
	// not enough arguments, display the syntax and exit
649
	if ( argc < 2 )
650
	{
651
		PrintSyntax(cmd);
652
		Pause();
653
		exit ( 1 );
654
	}
655
 
182 cycrow 656
	Utils::String destination = g_dir.ToString();
1 cycrow 657
	CyStringList errors;
197 cycrow 658
	Utils::WStringList lErrors;
1 cycrow 659
 
660
	// get the command flag
661
	CyString command(argv[1]);
662
	command = command.lower();
663
 
664
	CPackages packages;
665
	CyString myDoc = g_dir;
666
#ifdef _WIN32
667
	TCHAR pszPath[MAX_PATH];
668
	if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, pszPath)))
669
		myDoc = (char *)pszPath;
670
#endif
158 cycrow 671
	packages.startup(g_dir.c_str(), g_dir.c_str(), myDoc.c_str());
1 cycrow 672
 
673
	int start = 2;
674
	// check for switchs
675
	while ( command[0] == '-' )
676
	{
677
		if ( argc < (start + 1) )
678
		{
679
			PrintSyntax(cmd);
680
			Pause();
681
			exit ( 1 );
682
		}
683
		++start;
684
 
685
		// single long commands
686
		int arg = 2;
687
		if ( command.Left(2) == "--" )
688
		{
689
			CyString cmd = command.Right(-2);
690
			cmd = cmd.ToLower();
691
 
692
			char c = 0;
693
			if ( cmd == "override" )
694
				c = 'o';
695
			else if ( cmd == "verbose" )
696
				c = 'v';
697
			else if ( cmd == "directory" )
698
				c = 'd';
699
			else if ( cmd == "textrename" )
700
				c = 't';
701
			else if ( cmd == "enablechild" )
702
				c = 'c';
703
			else if ( cmd == "language" )
704
				c = 'l';
705
			else if ( cmd == "forcemod" )
706
				c = 'm';
707
 
708
			if ( c )
182 cycrow 709
				start = ParseCommandSwitchs(c, destination, &packages, start, &arg, argv);
1 cycrow 710
		}
711
		else
712
		{
713
			// now parse arguments
714
			for ( int i = 1; i < (int)command.Length(); i++ )
182 cycrow 715
				start = ParseCommandSwitchs(command[i], destination, &packages, start, &arg, argv);
1 cycrow 716
		}
717
 
718
		if ( argc < start )
719
		{
720
			PrintSyntax(cmd);
721
			exit( 1 );
722
		}
723
		command = argv[start - 1];
724
	}
725
 
726
	if ( command[0] == '/' )
727
	{
728
		char c = command[1];
729
 
730
		bool disabled = false;
731
 
732
		CyString checkCmd = command.ToLower();
733
		if ( checkCmd == "/install" )
734
			c = 'i';
735
		else if ( checkCmd == "/installdisable" )
736
		{
737
			c = 'i';
738
			disabled = true;
739
		}
740
		else if ( checkCmd == "/uninstall" )
741
			c = 'u';
742
		else if ( checkCmd == "/enable" )
743
			c = 'e';
744
		else if ( checkCmd == "/disable" )
745
			c = 'd';
746
		else if ( checkCmd == "/list" )
747
			c = 'l';
748
		else if ( checkCmd == "/removeshared" )
749
			c = 's';
750
		else if ( checkCmd == "/removeunisntall" )
751
			c = 'r';
752
 
753
		if ( c == 'i' || c == 'l' || c == 'u' || c == 'e' || c == 'd' || c == 'r' || c == 's' )
754
		{
206 cycrow 755
			Utils::WString endMessage;
1 cycrow 756
 
757
			printf ( "                                   |0              100|\n\n");
758
			printf ( "  - Reading game directory         " );
759
 
760
			CProgressConsole progress;
761
 
182 cycrow 762
			if ( packages.read(destination, &progress) )
1 cycrow 763
			{
764
				packages.UpdatePackages();
765
				packages.ReadGameLanguage(false);
766
				progress.Finish(false);
767
 
197 cycrow 768
				Utils::WString gameName = packages.getGameName();
182 cycrow 769
				if ( packages.GetLanguage() || !gameName.empty())
1 cycrow 770
				{
771
					printf ( "\n\t" );
182 cycrow 772
					if ( !gameName.empty() )
197 cycrow 773
						wprintf ( L"Game: %s ", gameName.c_str());
1 cycrow 774
					if ( packages.GetLanguage() )
775
						printf ( "(Language: %d)", packages.GetLanguage() );
776
				}
777
				printf ( "\n" );
778
			}
779
			else
780
			{
781
				printf ( "ERROR!\n" );
782
				exit(1);
783
			}
784
 
785
			bool prepare = false;
786
 
787
			packages.AssignPackageNumbers();
788
 
789
			CyStringList lArguments;
790
			SplitArguments(argv, argc, start, &lArguments);
791
 
792
			switch ( c )
793
			{
794
				case 'i':
795
					if ( argc <= start )
796
						printf ( "Syntax: %s [flags] /i <file>\n\tInstalls a package to the destination\n", cmd.c_str() );
797
					else
798
					{
203 cycrow 799
						Utils::WString aftertext = InstallPackage(&lArguments, &lErrors, &packages, disabled);
182 cycrow 800
						if(!aftertext.empty())
1 cycrow 801
						{
802
							prepare = true;
206 cycrow 803
							endMessage = aftertext;
1 cycrow 804
						}
805
						PrintDebug(&errors);
806
					}
807
					break;
808
 
809
				case 'u':
810
					if ( argc <= start )
811
						printf ( "Syntax: %s [flags] /u <package#\n\tUninstalls a package, package# is from the /l list command\n", cmd.c_str() );
812
					else
813
					{
183 cycrow 814
						prepare = UninstallPackage(CyString(argv[start]).ToInt(), &lErrors, &packages, endMessage);
1 cycrow 815
						PrintDebug(&errors);
816
					}
817
					break;
818
 
819
				case 'e':
820
					if ( argc <= start )
821
						printf ( "Syntax: %s [flags] /u <package#\n\tEnabled an installed package thats been disabled\n", cmd.c_str() );
822
					else
823
					{
183 cycrow 824
						prepare = EnablePackage(CyString(argv[start]).ToInt(), &lErrors, &packages, endMessage);
1 cycrow 825
						PrintDebug(&errors);
826
					}
827
					break;
828
 
829
				case 'd':
830
					if ( argc <= start )
831
						printf ( "Syntax: %s [flags] /u <package#\n\tDisabled an installed package\n", cmd.c_str() );
832
					else
833
					{
183 cycrow 834
						prepare = DisablePackage(CyString(argv[start]).ToInt(), &lErrors, &packages, endMessage);
1 cycrow 835
						PrintDebug(&errors);
836
					}
837
					break;
838
 
839
				case 'l':
840
					ListPackages(&packages);
841
					break;
842
 
843
				case 'r':
183 cycrow 844
					RemoveUninstallScripts(&packages, &lErrors);
1 cycrow 845
					endMessage = "Removed all unused uninstall scripts";
846
					break;
847
 
848
				case 's':
183 cycrow 849
					RemoveUnusedShared(&packages, &lErrors);
1 cycrow 850
					endMessage = "Removed all unused shared files";
851
					break;
852
			}
853
 
854
			if ( prepare )
855
			{
856
				errors.Clear();
183 cycrow 857
				lErrors.clear();
1 cycrow 858
				printf ( "  - Preparing game directory       " );
183 cycrow 859
				if ( packages.closeDir(&lErrors, &progress, true) )
1 cycrow 860
					progress.Finish();
861
				else
862
				{
863
					printf ( "ERROR!\n" );
864
					Pause();
865
					exit(1);
866
				}
867
 
868
				PrintDebug(&errors);
869
			}
870
			else
871
				packages.RestoreFakePatch();
872
 
873
			printf ( "\nDone!\n" );
182 cycrow 874
			if ( !endMessage.empty() )
206 cycrow 875
				wprintf(L"\n%s\n", endMessage.c_str() );
1 cycrow 876
		}
877
		else
878
			printf ( "Unknown Command: %c\n", c );
879
	}
880
 
881
	Pause();
882
 
883
	return 0;
884
}