Subversion Repositories spk

Rev

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