Subversion Repositories spk

Rev

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

Rev Author Line No. Line
1 cycrow 1
/*
2
 SPKTool V1.00 Created by Cycrow (Matthew Gravestock)
3
*/
4
 
5
// Main Spk File Library Include
6
#ifdef _WIN32
7
#include <spk.h>
8
#include <MultiSpkFile.h>
9
#include <spkcmdprogress.h>
10
#else
11
#include "../spk/spk.h"
12
#include "../spk/MultiSpkFile.h"
13
#include "../spk/spkcmdprogress.h"
14
#endif
15
// Multi Spk File format, required if using Multi Spk files
16
// Displays 7Zip compression progress to the command line
17
#include <time.h>
18
#ifdef _WIN32
19
#include <windows.h>
20
#include <direct.h>
21
#include <shlobj.h>
22
#endif
23
 
24
CyString g_dir;
25
bool g_read;
26
 
134 cycrow 27
class CFileProgress : public CProgressInfo
28
{
29
private:
30
	Utils::String _display;
31
	CBaseFile *_package;
32
	CPackages *_packages;
33
 
34
public:
35
	CFileProgress(CPackages *packages, CBaseFile *package, const Utils::String &display) : 
36
		_display(display),
37
		_packages(packages),
38
		_package(package)
39
	{
40
 
41
	}
42
 
43
protected:
44
	void ProgressUpdated(const long cur, const long max)
45
	{
46
	}
47
	void DoingFile(C_File *file)
48
	{
49
		Utils::String game;
50
 
51
		if (!file->game() || file->game() == GAME_ALLNEW)
52
			game = "All Games";
53
		else if (_packages)
54
		{
55
			for (unsigned int i = 0; i < 31; ++i)
56
			{
57
				if (file->game() & (1 << i))
58
				{
59
					Utils::String g = _packages->GetGameExe()->GetGameNameFromType(i - 1);
60
					if (!g.empty())
61
					{
62
						if (game.empty())
63
							game = g;
64
						else
65
							game = game + ", " + g;
66
					}
67
				}
68
			}
69
		}
70
 
71
		if(game.empty())
72
			printf("%s: %s\n", _display.c_str(), file->getNameDirectory(_package).c_str());
73
		else
74
			printf("%s: %s [%s]\n", _display.c_str(), file->getNameDirectory(_package).c_str(), game.c_str());
75
	}
76
 
77
};
78
 
1 cycrow 79
/*
80
	Func:	GetInput
81
	Desc:	Gets an input from the user, ie, any settings required to be typed in
82
*/
127 cycrow 83
Utils::String GetInput ()
1 cycrow 84
{
85
	g_read = true;
86
 
127 cycrow 87
	Utils::String line;
1 cycrow 88
	char c = getchar();
89
 
90
	while ( (c != '\n') && (c != '\0') )
91
	{
92
		line += c;
93
		c = getchar();
94
	}
95
 
96
	return line;
97
}
98
 
99
 
100
/*
101
	Func:	PrintSyntax
102
	Args:	String cmd - The command name to be displayed
103
	Desc:	Displays the syntax for the program
104
*/
105
void PrintSyntax ( CyString cmd )
106
{
107
	printf ( "Syntax: %s <command>\n", cmd.c_str() );
108
	printf ( "Commands:\n" );
134 cycrow 109
	printf ( "\t-v <spkfile>\n\t--view <spkfile>\n\t\tViews the contents of a spk file\n\n" );
1 cycrow 110
	printf ( "\t-e <spkfile> [destination]\n\t--extractall <spkfile> [destination]\n\t\tExtracts all the files to the destination directory [or current if no destiantion is set]\n\n" );
111
	printf ( "\t-x <spkfile> <type> <file> [destination]\n\t--extract <spkfile> <type> <file> [destination]\n\t\tExtracts a single file of <type> to destination directory\n\n" );
112
	printf ( "\t-x <multispkfile> <file> [destination]\n\t--extractspk <multispkfile> <spkfile> [destination]\n\t\tExtracts a single spk file from a Multi-Spk Package\n\n" );
113
	printf ( "\t-c <spkfile>\n\t--create\n\t\tCreates a new spk file\n\n" );
114
	printf ( "\t-a <spkfile> <type> <filename>\n\t--append <spkfile> <type> <filename>\n\t\tAppends a file to the package of set <type>\n\n" );
115
	printf ( "\t-r <spkfile> <type> <filename>\n\t--remove <spkfile> <type> <filename>\n\t\tRemoves a file from the package of set <type>\n\n" );
116
	printf ( "\t-r <multispkfile> <filename>\n\t--removespk <multispkfile> <filename>\n\t\tRemoves a spk file from the Multi-SPK package\n\n" );
117
	printf ( "\t-m <spkfile> <spkfile>\n\t--mergemulti <spkfile> <spkfile>\n\t\tMerges spk files together, the second file will be merged into the first\n\n" );
118
	printf ( "\t-n <multispkfile>\n\t--createmulti\n\t\tCreates a multi spk file, and adds the spkfiles in\n\n" );
119
	printf ( "\t-s <multispkfile> [destination]\n\t--splitmulti <multispkfile> [destination]\n\t\tSplits a Multi-SPK file up, saves all the spk files to Destination\n\n" );
120
	printf ( "\t--set <setting> [value]\n\t\tChanges the settings of the script\n\n" );
121
	printf ( "\t--convertxsp <oldxsp> [newxsp]\n\t\tConverts an old XSP file into the new format\n\n");
122
	printf ( "\t--createscript <packagescript>\n\t\tCreates a spk file from a packager script\n\n");
123
	printf ( "\t--verifyscript <packagescript>\n\t\tChecks a packager script is valid without creating the resulting file\n\n");
124
	printf ( "\t--generatescript <package> [packagescript]\n\t\tCreates a packager script (.sps) from a spk file\n\n");
125
	printf ( "\t--extractship <modfile> <xspfile> [shipid]\n\t\tCreates an XSP ship file from a mod package\n\n");
126
	printf ( "\t--generateupdatefile <package>\n\t\tCreates an update file for the spk/xsp file\n\n");
126 cycrow 127
	printf ( "\t--packagelist <filenames>\n\t\tThis will generate the update file to allow downloading packages from a server.\n\n");
128
	//	printf ( "\t--convertxspwizard <oldxsp> [newxsp]\n\t\tConverts an old XSP file into the new format\n\n");
1 cycrow 129
}
130
 
131
void Settings(CyString filename, CyString settings, int argc, char **argv, CyString cmd)
132
{
133
	if ( settings.Compare("author") )
134
	{
135
		if ( argc < 5 )
136
		{
137
			printf ( "Syntax: %s -set <spkfile> Author <authorname>\n\tSets the authors name of the package\n", cmd.c_str() );
138
			return;
139
		}
140
	}
141
	else
142
	{
143
		printf("Error! Unknown settings: %s\n", settings.c_str());
144
		return;
145
	}
146
 
147
	// first chekc if file even exists
148
	FILE *id = fopen ( filename.c_str(), "rb+" );
149
	if ( !id )
150
	{
151
		printf ( "Error: File, %s, doesn't exist\n", filename.c_str() );
152
		return;
153
	}
154
	fclose ( id );
155
 
156
	int check = CSpkFile::CheckFile ( filename );
157
	if ( check == SPKFILE_SINGLE )
158
	{
159
		CSpkFile spkfile;
160
		printf ( "* Opening SPK File, %s...\n", filename.c_str() );
161
		if ( !spkfile.ReadFile ( filename, SPKREAD_ALL ) )
162
		{
163
			printf ( "Failed to open the spk files, %s\n", filename.c_str() );
164
			return;
165
		}
166
 
167
		// now do the settings
168
		if ( settings.Compare("author") )
169
		{
50 cycrow 170
			spkfile.setAuthor(argv[4]);
171
			printf( "Settings Author to: %s\n", spkfile.author().c_str());
1 cycrow 172
		}
173
 
174
		spkfile.WriteFile ( filename );
175
		printf ( "\nSPK file has been written sucessfully\n" );
176
	}
177
	else
178
		printf ( "File, %s, is not a valid SPK file\n", filename.c_str() );
179
}
180
 
181
void SetRating ( CyString filename, int ease, int changing, int rec )
182
{
183
	if ( ease > 5 )
184
		ease = 5;
185
	if ( changing > 5 )
186
		changing = 5;
187
	if ( changing > 5 )
188
		changing = 5;
189
 
190
	FILE *id = fopen ( filename.c_str(), "rb+" );
191
	if ( !id )
192
	{
193
		printf ( "Error: File, %s, doesn't exist\n", filename.c_str() );
194
		return;
195
	}
196
	fclose ( id );
197
 
198
	int check = CSpkFile::CheckFile ( filename );
199
	if ( check == SPKFILE_SINGLE )
200
	{
201
		CSpkFile spkfile;
202
		printf ( "* Opening SPK File, %s...\n", filename.c_str() );
203
		if ( !spkfile.ReadFile ( filename, SPKREAD_ALL ) )
204
		{
205
			printf ( "Failed to open the spk files, %s\n", filename.c_str() );
206
			return;
207
		}
208
 
209
		printf ( "File Format Version: %.2f\n", spkfile.GetFileVersion() );
210
 
211
		printf ( "Assigning Ease Of Use:\t\t%d\nAssigning Game Changing:\t%d\nAssigning Recommended:\t\t%d\n", ease, changing, rec);
46 cycrow 212
		spkfile.setEaseOfUse(ease);
213
		spkfile.setGameChanging(changing);
214
		spkfile.setRecommended(rec);
1 cycrow 215
		spkfile.WriteFile ( filename );
216
		printf ( "\nSPK file has been written sucessfully\n" );
217
 
218
	}
219
	else
220
		printf ( "File, %s, is not a valid SPK file\n", filename.c_str() );
221
}
222
 
223
CyString GetTerranConflictDir()
224
{
225
	while ( true )
226
	{
227
		printf ( "\nPlease enter the directory for terran conflict: ");
228
		CyString dir = GetInput();
229
		if ( dir.Empty() )
230
			return NullString;
231
 
232
		// check if the directory exists
52 cycrow 233
		if ( CFileIO(dir + "/x3tc.exe").ExistsOld() )
1 cycrow 234
			return dir;
235
		printf("\nTerran Conflict installation doesn't exist: %s\n\n", dir.c_str());
236
	}
237
 
238
	return NullString;
239
}
240
 
241
void ConvertXsp(CyString filename, CyString tofile, bool wizard)
242
{
243
	// first chekc if file even exists
244
	FILE *id = fopen ( filename.c_str(), "rb+" );
245
	if ( !id )
246
	{
247
		printf ( "Error: File, %s, doesn't exist\n", filename.c_str() );
248
		return;
249
	}
250
	fclose ( id );
251
 
252
	// check its not a new format already
253
	int check = CSpkFile::CheckFile ( filename );
160 cycrow 254
	if ( check == SPKFILE_INVALID && CFileIO(filename).isFileExtension("xsp") )
1 cycrow 255
	{
256
		printf ( "* Converting XSP File, %s... ", filename.c_str() );
257
		CXspFile xspFile;
39 cycrow 258
		if ( !xspFile.ConvertOld(filename.ToString()) )
1 cycrow 259
		{
260
			printf ( "[ERROR]\n\nFailed to convert old xsp file, %s\n", filename.c_str() );
261
			return;
262
		}
263
 
264
		printf ( "[DONE]\n");
265
 
266
		CyString dir;
267
		printf ("Do you want to create weapon masks for Terran conflict? ");
268
		CyString input = GetInput();
269
		if ( input.Compare("y") || input.Compare("yes") )
270
		{
271
			dir = GetTerranConflictDir();
272
			if ( !dir.Empty() )
273
			{
274
			}
275
		}
276
 
277
		printf ( "* Writing XSP File, %s... ", tofile.c_str() );
278
		// now we need to save it
279
		if ( !xspFile.WriteFile(tofile) )
280
			printf ( "[ERROR]\n\nFailed to write file to, %s\n", tofile.c_str() );
281
		else
282
			printf ( "[DONE]\n\nFile: %s, has been converted to, %s\n", filename.c_str(), tofile.c_str() );
283
	}
284
	else
285
		printf ( "Error: File, %s, is not an old style XSP file\n", filename.c_str() );
286
}
287
 
288
void ExtractShip(CyString catfile, CyString to, CyString shipid)
289
{
52 cycrow 290
	if ( !CFileIO(catfile).ExistsOld() )
1 cycrow 291
	{
292
		printf ( "Error: Mod File, %s, does not exist\n", catfile.c_str() );
293
		return;
294
	}
295
 
36 cycrow 296
	CVirtualFileSystem *pVfs = new CVirtualFileSystem();
37 cycrow 297
	if ( !pVfs->loadMod(catfile.ToString()) ) {
1 cycrow 298
		printf("Error: Unable to read mod file, %s\n", catfile.c_str());
36 cycrow 299
		delete pVfs;
1 cycrow 300
		return;
301
	}
302
 
101 cycrow 303
	Utils::CStringList *ships = pVfs->getTShipsEntries();
1 cycrow 304
	if ( !ships )
305
	{
306
		printf("Error: Failed to read %s::types\\TShips.pck\n", catfile.c_str());
36 cycrow 307
		delete pVfs;
1 cycrow 308
		return;
309
	}
310
 
311
	// now get the ship line to extract
101 cycrow 312
	Utils::String tShipsLine;
1 cycrow 313
	if ( shipid.Empty() )
314
	{
315
		// no ship id, lets get one
101 cycrow 316
		Utils::String ids[2];
1 cycrow 317
		int i = 0;
318
		int id = 0;
116 cycrow 319
		for ( Utils::SStringList *str = ships->first(); str; str = ships->next() )
1 cycrow 320
		{
116 cycrow 321
			ids[i++] = str->data;
1 cycrow 322
			if ( i >= 2 )
323
			{
324
				printf("[%3d][%30s]\t[%3d][%30s]\n", id - 1, ids[0].c_str(), id, ids[1].c_str());
325
				for ( i = 0; i < 2; i++ )
326
					ids[i] = "";
327
				i = 0;
328
			}
329
			++id;
330
		}
331
		if ( i == 1 )
332
			printf("[%3d][%30s]\n", id, ids[0].c_str());
333
		printf("Enter ID to use > ");
334
		shipid = GetInput();
335
 
336
		if ( shipid.IsNumber() )
116 cycrow 337
			tShipsLine = ships->get(shipid.ToInt())->str;
1 cycrow 338
		else
101 cycrow 339
			tShipsLine = ships->findData(shipid.ToString(), true);
1 cycrow 340
	}
341
	else
101 cycrow 342
		ships->findData(shipid.ToString(), true);
1 cycrow 343
 
101 cycrow 344
	if ( tShipsLine.empty() )
1 cycrow 345
	{
346
		printf("Error, %s is not a valid ship id to use\n", shipid.c_str());
36 cycrow 347
		delete pVfs;
1 cycrow 348
		return;
349
	}
350
 
351
	// now we have the tships to use, lets start to extract the ship
101 cycrow 352
	printf("Extracting ship from %s, Ship=%s\n", catfile.c_str(), tShipsLine.token(";", -2).c_str());
1 cycrow 353
 
354
	CXspFile ship;
101 cycrow 355
	if ( ship.extractShip(pVfs, tShipsLine.token(";", -2), 0) )
1 cycrow 356
	{
357
		printf ( "Ship has been successfully extracted\n" );
358
 
359
		printf("\t- Models:\t %d\n", ship.CountFiles(FILETYPE_SHIPMODEL));
360
		printf("\t- Textures:\t %d\n", ship.CountFiles(FILETYPE_SHIPOTHER));
361
		printf("\t- Dummies:\t %d\n", ship.GetDummies()->size());
362
		printf("\t- Components:\t %d\n", ship.GetComponents()->size());
363
		printf("\t- Bodies:\t %d\n", ship.GetBodies()->Count());
364
		printf("\t- Cockpits:\t %d\n", ship.GetCockpits()->size());
365
		printf("\t- Text Entries:\t %d\n", ship.GetTexts()->size());
366
 
367
		printf("\nEnter the name for the ship: ");
127 cycrow 368
		ship.setName(GetInput());
1 cycrow 369
		printf("Enter the author for the ship: ");
127 cycrow 370
		ship.setAuthor(GetInput());
1 cycrow 371
		printf("Enter the version for the ship: V");
127 cycrow 372
		ship.setVersion(GetInput());
1 cycrow 373
		printf("Enter the description for the ship: ");
127 cycrow 374
		ship.setDescription(GetInput());
1 cycrow 375
 
376
		struct tm   *currDate;
377
		char    dateString[100];
378
		time_t now = time(NULL);
379
		currDate = localtime( &now );
380
		strftime(dateString, sizeof dateString, "%d/%m/%Y", currDate);
50 cycrow 381
		ship.setCreationDate(dateString);
1 cycrow 382
 
383
		printf("\nWriting file: %s...\n", to.c_str());
384
		if ( ship.WriteFile(to) )
385
			printf("Ship file has been created: %s\n", to.c_str());
386
		else
387
			printf("Error: Unable to write ship file, %s\n", to.c_str());
388
	}
389
	else
390
		printf("Error: Unable to extract the ship\n");
36 cycrow 391
 
392
	delete pVfs;
1 cycrow 393
}
394
 
395
CyString GetGameName(int game)
396
{
397
	switch(game)
398
	{
399
		case GAME_X2:
400
			return "X2: The Threat";
401
		case GAME_X3:
402
			return "X3: Reunion";
403
		case GAME_X3TC:
404
			return "X3: Terran Conflict";
405
		case GAME_X3AP:
406
			return "X3: Albion Prelude";
126 cycrow 407
		case GAME_X3FL:
408
			return "X3: Farnham's Legacy";
1 cycrow 409
	}
410
	return "Unknown";
411
}
134 cycrow 412
void DisplayVersion(const Utils::String &filename)
1 cycrow 413
{
414
	// first chekc if file even exists
415
	FILE *id = fopen ( filename.c_str(), "rb+" );
416
	if ( !id )
417
	{
418
		printf ( "Error: File, %s, doesn't exist\n", filename.c_str() );
419
		return;
420
	}
421
	fclose ( id );
422
 
423
	bool read = false;
424
	CBaseFile *pBaseFile = NULL;
425
 
426
	int check = CSpkFile::CheckFile ( filename );
427
	if ( check == SPKFILE_BASE )
428
	{
429
		pBaseFile = new CBaseFile();
430
		printf ( "* Opening SPK File, %s...\n", filename.c_str() );
431
		if ( !pBaseFile->ReadFile ( filename, SPKREAD_NODATA ) )
432
		{
433
			printf ( "Failed to open the spk files, %s\n", filename.c_str() );
434
			return;
435
		}
436
		read = true;
437
	}
438
	else if ( check == SPKFILE_SINGLE )
439
	{
440
		pBaseFile = (CBaseFile *)new CSpkFile();
441
		printf ( "* Opening SPK File, %s...\n", filename.c_str() );
442
		if ( !pBaseFile->ReadFile ( filename, SPKREAD_NODATA ) )
443
		{
444
			printf ( "Failed to open the spk files, %s\n", filename.c_str() );
445
			return;
446
		}
447
		read = true;
448
	}
449
	else if ( check == SPKFILE_SINGLESHIP )
450
	{
451
		pBaseFile = (CBaseFile *)new CXspFile();
452
		printf ( "* Opening XSP File, %s...\n", filename.c_str() );
453
		if ( !pBaseFile->ReadFile ( filename, SPKREAD_NODATA ) )
454
		{
455
			printf ( "Failed to open the xsp files, %s\n", filename.c_str() );
456
			return;
457
		}
458
		read = true;
459
	}
460
	// otherwise its an old ship file
160 cycrow 461
	else if ( CFileIO(filename).isFileExtension("xsp") )
1 cycrow 462
	{
463
		printf ( "* Converting XSP File, %s...\n", filename.c_str() );
464
		pBaseFile = new CXspFile;
134 cycrow 465
		if ( !((CXspFile *)pBaseFile)->ConvertOld(filename) )
1 cycrow 466
		{
467
			delete pBaseFile;
468
			pBaseFile = NULL;
469
			printf ( "Failed to convert old xsp file, %s\n", filename.c_str() );
470
			return;
471
		}
472
		check = SPKFILE_SINGLESHIP;
473
		read = true;
474
	}
475
 
476
	if ( pBaseFile && read)
477
	{
478
		CPackages p;
134 cycrow 479
		p.startup(".", ".", ".");
1 cycrow 480
 
481
		CSpkFile *pSpkFile = NULL;
482
		CXspFile *pXspFile = NULL;
483
		if ( check == SPKFILE_SINGLE )
484
			pSpkFile = (CSpkFile *)pBaseFile;
485
		else
486
			pXspFile = (CXspFile *)pBaseFile;
487
 
488
		printf ( "File Format Version: %.2f\n", pBaseFile->GetFileVersion() );
489
 
490
		CyString sType;
491
		if ( check == SPKFILE_SINGLESHIP )
492
			sType = "Ship";
493
		else
494
			sType = "Package";
495
 
50 cycrow 496
		printf ( "%s Name: %s\n", sType.c_str(), pBaseFile->name().c_str() );
49 cycrow 497
		if ( !pBaseFile->email().empty() )
50 cycrow 498
			printf ( "%s Author: %s (%s)\n", sType.c_str(), pBaseFile->author().c_str(), pBaseFile->email().c_str() );
1 cycrow 499
		else
50 cycrow 500
			printf ( "%s Author: %s\n", sType.c_str(), pBaseFile->author().c_str() );
501
		if ( !pBaseFile->version().empty() ) printf ( "%s Version: %s\n", sType.c_str(), pBaseFile->version().c_str() );
1 cycrow 502
 
503
		//for game
504
		printf("For Games: ");
505
		if ( !pBaseFile->AnyGameCompatability() )
506
			printf("All");
507
		else
152 cycrow 508
			printf("%s", p.getGameTypesString(pBaseFile, true).c_str());
1 cycrow 509
		printf("\n");
510
 
511
		if ( pXspFile )
512
		{
513
			printf ("Ship Display Name: %s\n", pXspFile->GetShipName(44).c_str());
514
			if ( pXspFile->IsExistingShip() )
515
				printf ( "Ship ID: %s (Replace Existing Ship)\n", pXspFile->GetShipID().c_str() );
516
			else
517
				printf ( "Ship ID: %s\n", pXspFile->GetShipID().c_str() );
518
 
519
			if ( pXspFile->AnyShipyards() )
520
			{
521
				printf ( "Add To Shipyards:\n" );
522
				for ( int i = 1; i <= GetMaxShipyards(); i *= 2 )
523
				{
524
					if ( pXspFile->IsShipyard(i) )
525
						printf("\t%s\n", GetShipyardName(i).c_str());
526
				}
527
			}
528
 
529
			for ( SWeaponMask *text = pXspFile->GetLaserMasks()->First(); text; text = pXspFile->GetLaserMasks()->Next() )
530
				printf ( "Laser Mask, Game: %s, Mask: %d\n", GetGameName(text->iGame).c_str(), text->iMask);
531
			for ( SWeaponMask *text = pXspFile->GetMissileMasks()->First(); text; text = pXspFile->GetMissileMasks()->Next() )
532
				printf ( "Missile Mask, Game: %s, Mask: %d\n", GetGameName(text->iGame).c_str(), text->iMask);
533
 
534
			if ( pXspFile->GetOriginalDescription() )
535
				printf("Use Existing Text, ID: %d\n", pXspFile->GetOriginalDescription());
536
 
537
			if ( pXspFile->AnyTexts() )
538
			{
539
				for ( SText *text = pXspFile->GetTexts()->First(); text; text = pXspFile->GetTexts()->Next() )
540
				{
541
					printf("Ship Text, Language: %d\n", text->iId);
39 cycrow 542
					if ( !text->sName.empty() )
1 cycrow 543
						printf("\tName: %s\n", text->sName.c_str());
39 cycrow 544
					if ( !text->sDesc.empty() )
1 cycrow 545
						printf("\tDescription: %s\n", text->sDesc.c_str());
546
				}
547
			}
548
 
549
			if ( pXspFile->AnyComponents() )
550
			{
551
				printf ( "Component Entries:\n" );
552
				for ( SComponent *c = pXspFile->GetComponents()->First(); c; c = pXspFile->GetComponents()->Next() )
553
					printf ( "\t%s\n\t\t%s\n\t\t\t%s\n", c->sSection.c_str(), c->sSection2.c_str(), c->sData.c_str());
554
			}
555
			if ( pXspFile->AnyDummies() )
556
			{
557
				printf ( "Dummy Entries:\n" );
558
				for ( SDummy *d = pXspFile->GetDummies()->First(); d; d = pXspFile->GetDummies()->Next() )
559
					printf ( "\t%s\n\t\t%s\n", d->sSection.c_str(), d->sData.c_str());
560
			}
561
			if ( pXspFile->AnyCockpits() )
562
			{
563
				printf ( "Cockpit Entries:\n" );
564
				for ( SCockpit *c = pXspFile->GetCockpits()->First(); c; c = pXspFile->GetCockpits()->Next() )
565
					printf("\t%s\n", c->sCockpit.c_str());
566
			}
165 cycrow 567
			if ( pXspFile->anyCutData() )
1 cycrow 568
			{
165 cycrow 569
				printf ( "CutData Entries [%d]:\n", pXspFile->getCutData().size() );
570
				for(auto itr = pXspFile->getCutData().begin(); itr != pXspFile->getCutData().end(); itr++)
571
					printf("\t%s\n", (*itr)->str.c_str());
1 cycrow 572
			}
573
		}
574
 
50 cycrow 575
		if ( !pBaseFile->creationDate().empty() ) printf ( "Creation Date: %s\n", pBaseFile->creationDate().c_str() );
48 cycrow 576
		if ( !pBaseFile->description().empty() ) printf ( "Description: %s\n", pBaseFile->description().c_str() );
1 cycrow 577
		if ( pSpkFile )
578
		{
579
			if ( pSpkFile->IsLibrary() )
580
				printf ( "Script Type: Library\n" );
581
			else if ( pSpkFile->IsPatch() )
582
				printf ( "Script Type: Patch Mod\n" );
583
			else if ( pSpkFile->IsCustomStart() )
584
				printf ( "Script Type: Custom Start\n" );
585
			else if ( pSpkFile->IsPackageUpdate() )
586
				printf ( "Script Type: Package Update\n" );
10 cycrow 587
			else if ( !pSpkFile->GetScriptTypeString(44).empty() )
1 cycrow 588
				printf ( "Script Type: %s\n", pSpkFile->GetScriptTypeString(44).c_str() );
589
 
590
			if ( !pSpkFile->GetWaresList()->empty() )
591
			{
592
				for ( CListNode<SWares> * wNode = pSpkFile->GetWaresList()->Front(); wNode; wNode = wNode->next() )
593
				{
594
					SWares *w = wNode->Data();
595
					printf ( "Ware: (%c) %s\n", w->cType, CSpkFile::GetWareText(w, 44).c_str() );
596
					CyString desc = CSpkFile::GetWareDesc(w, 44);
597
					if ( !desc.Empty() )
598
						printf ( "\tDescription: %s\n", desc.c_str() );
599
				}
600
			}
601
		}
49 cycrow 602
		if ( !pBaseFile->forumLink().empty() ) printf ( "Forum Link: %s\n", pBaseFile->forumLink().c_str() );
603
		if ( !pBaseFile->webSite().empty() ) printf ( "Web Site Address: %s\n", pBaseFile->webSite().c_str() );
604
		if ( !pBaseFile->webAddress().empty() ) printf ( "Update Address: %s\n", pBaseFile->webAddress().c_str() );
1 cycrow 605
 
162 cycrow 606
		if ( pBaseFile->anyWebMirrors() )
1 cycrow 607
		{
608
			printf("Update Mirror Addresses:\n");
162 cycrow 609
			for ( int i = 0; i < pBaseFile->getMaxWebMirrors(); i++ )
610
				printf ("\t%s\n", pBaseFile->getWebMirror(i).c_str());
1 cycrow 611
		}
612
		if ( pSpkFile )
613
		{
10 cycrow 614
			if ( (!pSpkFile->GetOtherName().empty()) && (!pSpkFile->GetOtherAuthor().empty()) )
1 cycrow 615
				printf ( "Script is a child to the mod: %s by %s\n", pSpkFile->GetOtherName().c_str(), pSpkFile->GetOtherAuthor().c_str() );
616
		}
617
 
618
		if ( pBaseFile->AnyDependacies() )
619
		{
620
			printf ( "Required Dependacies:\n" );
621
			for ( SNeededLibrary *needed = pBaseFile->GetNeededLibraries()->First(); needed; needed = pBaseFile->GetNeededLibraries()->Next() )
622
				printf ( "\t%s by %s (Minimum Version=%s)\n", needed->sName.c_str(), needed->sAuthor.c_str(), needed->sMinVersion.c_str() );
623
		}
46 cycrow 624
		if ( pBaseFile->easeOfUse() != -1 ) printf ( "Ease Of Use Rating: %d\n", pBaseFile->easeOfUse() );
625
		if ( pBaseFile->gameChanging() != -1 ) printf ( "Game Changing Rating: %d\n", pBaseFile->gameChanging() );
626
		if ( pBaseFile->recommended() != -1 ) printf ( "Recommendation Rating: %d\n", pBaseFile->recommended() );
1 cycrow 627
		if ( pBaseFile->GetIcon() )
628
		{
629
			C_File *icon = pBaseFile->GetIcon();
158 cycrow 630
			printf ( "Icon File Found, Type: %s, Size: %s\n", pBaseFile->iconExt().c_str(), icon->dataSizeString().c_str() );
1 cycrow 631
		}
632
 
633
		if ( pBaseFile->GetFileList()->size() )
634
		{
134 cycrow 635
			printf("\nListing files in package:\n");
1 cycrow 636
			CLinkList<C_File> *list = pBaseFile->GetFileList();
134 cycrow 637
 
638
			for (unsigned int game = 0; game < 31; ++game)
639
			{
640
				bool heading = true;
641
				for (C_File *file = list->First(); file; file = list->Next())
642
				{
643
					bool display = false;
644
					if (game == 0 && (!file->game() || file->game() == GAME_ALLNEW))
645
						display = true;
646
					if (game > 0 && file->game() & (1 << game))
647
						display = true;
648
 
649
					if (display)
650
					{
651
						if (heading)
652
						{
653
							Utils::String sGame = p.GetGameExe()->GetGameNameFromType(game - 1);
654
							printf("\tGame: %s\n", sGame.c_str());
655
							heading = false;
656
						}
657
						printf("\t\t%s (%s) Size: %s\n", file->GetNameDirectory(pBaseFile).c_str(), file->fileTypeString().c_str(), file->dataSizeString().c_str());
658
 
659
					}
660
				}
661
			}
662
 
1 cycrow 663
		}
664
		else
665
			printf ( "\nThere are currently no files in the package\n" );
666
	}
667
	else if ( check == SPKFILE_MULTI )
668
	{
669
		CMultiSpkFile spkfile;
670
		printf ( "* Opening Multi-SPK file, %s...\n", filename.c_str() );
671
		if ( !pBaseFile->ReadFile ( filename, false ) )
672
		{
673
			printf ( "Error: Failed to open the Multi-SPK file, %s\n", filename.c_str() );
674
			return;
675
		}
676
 
677
		printf ( "Multi Package Name: %s\n", spkfile.GetName().c_str() );
678
		printf ( "Selection Mode: " );
679
		if ( spkfile.IsSelection () )
680
			printf ( "On\n" );
681
		else
682
			printf ( "Off\n" );
683
 
684
		CLinkList<SMultiSpkFile> *list = spkfile.GetFileList();
685
		for ( SMultiSpkFile *ms = list->First(); ms; ms = list->Next() )
686
		{
687
			printf ( "File, %s:\n", ms->sName.c_str() );
688
			printf ( "\tSize: %s\n", SPK::GetSizeString (ms->lSize).c_str() );
689
			if ( (!ms->sScriptName.Empty()) && (!ms->sScriptAuthor.Empty()) )
690
				printf ( "\tScript: %s %s by %s\n", ms->sScriptName.c_str(), ms->sScriptVersion.c_str(), ms->sScriptAuthor.c_str() );
691
			printf ( "\tDefault Install: " );
692
			if ( ms->bOn )
693
				printf ( "Yes\n" );
694
			else
695
				printf ( "No\n" );
696
		}
697
	}
698
	else
699
		printf ( "File, %s, is not a valid SPK file\n", filename.c_str() );
700
 
701
	if ( pBaseFile )
702
		delete pBaseFile;
703
}
704
 
705
void AppendFile ( CyString sfile, CyString type, CyString addfile )
706
{
155 cycrow 707
	int t = GetFileTypeFromString(type.ToString());
1 cycrow 708
	if ( t == -1 )
709
	{
710
		printf ( "The file type \"%s\" is invalid\n", type.c_str() );
711
		return;
712
	}
713
 
714
	int check = CSpkFile::CheckFile ( sfile );
715
	CBaseFile *pBaseFile = 0;
716
	if ( check == SPKFILE_SINGLE )
717
		pBaseFile = new CSpkFile();
718
	else if ( check == SPKFILE_SINGLESHIP )
719
		pBaseFile = new CXspFile();
720
	else if ( check == SPKFILE_BASE )
721
		pBaseFile = new CBaseFile();
722
 
723
	if ( !pBaseFile )
724
	{
725
		printf ( "Error: Invalid file format, unable to open\n" );
726
		return;
727
	}
728
 
729
	printf ( "Opening File, %s... ", sfile.c_str() );
730
	if ( !pBaseFile->ReadFile ( sfile ) )
731
	{
732
		printf ( "(Error)\nUnable to open the file, %s\n", sfile.c_str() );
733
		return;
734
	}
735
	printf ( "(Done)\n" );
736
 
737
	MyProgress progress(0);
738
 
739
	printf ( "Adding file %s to package\n\t>", addfile.c_str() );
740
 
155 cycrow 741
	if ( pBaseFile->appendFile(addfile.ToString(), t, 0, false, Utils::String::Null(), &progress))
1 cycrow 742
	{
743
		progress.PrintDone();
744
		printf ( "< (Done)\n" );
745
 
746
		pBaseFile->WriteFile ( sfile );
747
		printf ( "\nFile has been written sucessfully\n" );
748
	}
749
	else
750
		printf ( "< (Error)\n" );
751
}
752
 
753
void RemoveFile ( CyString sfile, CyString type, CyString addfile )
754
{
755
	FILE *id = fopen ( sfile.c_str(), "rb+" );
756
	if ( !id )
757
	{
758
		printf ( "Error: File, %s, doesn't exist\n", sfile.c_str() );
759
		return;
760
	}
761
 
762
	if ( addfile.Empty() )
763
	{
764
		printf ( "Error: Remove filename is invalid\n" );
765
		return;
766
	}
155 cycrow 767
	int t = GetFileTypeFromString(type.ToString());
1 cycrow 768
	if ( t == -1 )
769
	{
770
		printf ( "The file type \"%s\" is invalid\n", type.c_str() );
771
		return;
772
	}
773
 
774
	int check = CSpkFile::CheckFile ( sfile );
775
	CBaseFile *pBaseFile = 0;
776
	if ( check == SPKFILE_SINGLE )
777
		pBaseFile = new CSpkFile();
778
	else if ( check == SPKFILE_SINGLESHIP )
779
		pBaseFile = new CXspFile();
780
	else if ( check == SPKFILE_BASE )
781
		pBaseFile = new CBaseFile();
782
 
783
	if ( pBaseFile )
784
	{
785
		printf ( "Opening File, %s... ", sfile.c_str() );
786
		if ( !pBaseFile->ReadFile ( sfile ) )
787
		{
788
			printf ( "(Error)\nUnable to open the file, %s\n", sfile.c_str() );
789
			return;
790
		}
791
		printf ( "(Done)\n" );
792
 
793
		printf ( "Removing file, %s, from Package\n", addfile.c_str() );
794
 
795
		if ( pBaseFile->RemoveFile ( addfile, t ) )
796
		{
797
			printf ( "File, %s, has been remove from package\n", addfile.c_str() );
798
			pBaseFile->WriteFile ( sfile );
799
			printf ( "File has been written to disk successfully\n" );
800
		}
801
		else
802
			printf ( "Unable to remove the file, %s, from the package\n", addfile.c_str() );
803
	}
804
	else if ( check == SPKFILE_MULTI )
805
	{
806
		CMultiSpkFile spkfile;
807
		printf ( "Opening Multi-SPK file, %s...", sfile.c_str() );
808
		if ( !spkfile.ReadFile ( sfile ) )
809
		{
810
			printf ( "(Error)\nUnable to open the Multi-SPK file, %s\n", sfile.c_str() );
811
			return;
812
		}
813
		printf ( "(Done)\n" );
814
 
815
		SMultiSpkFile *ms = spkfile.FindFile ( type );
816
		if ( !ms )
817
		{
818
			printf ( "Unable to find the file \"%s\" in the package\n", type.c_str() );
819
			return;
820
		}
821
 
822
		printf ( "Removing file, %s, from Package\n", addfile.c_str() );
823
		if ( !spkfile.RemoveFile ( ms ) )
824
		{
825
			printf ( "Error: Unable to remove file, %s, from package\n", type.c_str() );
826
			return;
827
		}
828
 
829
		printf ( "Writing SPK File, %s... ", sfile.c_str() );
830
		if ( spkfile.WriteFile ( sfile ) )
831
			printf ( "(Done)\n" );
832
		else
833
			printf ( "(Error)\n" );
834
	}
835
	else
836
		printf ( "Error: Invalid file format, unable to open\n" );
837
}
838
 
839
 
840
void CreateMultiFile ( CyString filename )
841
{
842
	printf ( "* Creating new Multi-SPK File, %s\n\n", filename.c_str() );
843
 
844
	FILE *id = fopen ( filename.c_str(), "rb+" );
845
	if ( id )
846
	{
847
		fclose ( id );
848
		printf ( "* File already exists, unable to create\n" );
849
		return;
850
	}
851
 
852
	id = fopen ( filename.c_str(), "wb" );
853
	if ( !id )
854
	{
855
		printf ( "* Unable to open file for writing\n" );
856
		return;
857
	}
858
	fclose ( id );
859
	remove ( filename.c_str() );
860
 
861
	CMultiSpkFile spkfile;
862
 
863
	CyString sInput;
864
	printf ( "Enter Multi-Spk Package Name: " );
865
	spkfile.SetName ( GetInput() );
866
 
867
	while ( true )
868
	{
869
		printf ( "\nDo you want users to select scripts to install? (Y/N): " );
870
		CyString i = GetInput();
871
		i = i.ToUpper();
872
		if ( i == "Y" )
873
			spkfile.SetSelection ( true );
874
		if ( (i == "Y") || (i == "N") )
875
			break;
876
	}
877
 
878
	while ( true )
879
	{
880
		printf ( "\nEnter Spk File to add (Enter \"0\" to finish): " );
881
		sInput = GetInput();
882
		if ( sInput == "0" )
883
			break;
884
 
885
		// check if file can be opened
886
		FILE *id2 = fopen ( sInput.c_str(), "rb+" );
887
		if ( !id2 )
888
			printf ( "Error: Unable to open SPK file %s\n", sInput.c_str() );
889
		else
890
		{
891
			fclose ( id2 );
892
			if ( !spkfile.AddFile ( sInput ) )
893
				printf ( "Error: Unable to add SPK file to package\n" );
894
			else
895
				printf ( "File Added to package (%s)\n", sInput.c_str() );
896
		}
897
	}
898
 
899
	if ( spkfile.GetNumFiles() < 1 )
900
		printf ( "\nError: You have added no files, you must add at least one file to create a package\n" );
901
	else
902
	{
903
		printf ( "Writing MultiSpk file... " );
904
		if ( spkfile.WriteFile ( filename ) )
905
			printf ( "(Done)\n" );
906
		else
907
			printf ( "(Error)\n" );
908
	}
909
 
910
}
911
 
912
void CreateFile ( CyString filename )
913
{
914
	printf ( "* Creating new SPK File, %s\n\n", filename.c_str() );
915
 
916
	FILE *id = fopen ( filename.c_str(), "rb+" );
917
	if ( id )
918
	{
919
		fclose ( id );
920
		printf ( "* File already exists, unable to create\n" );
921
		return;
922
	}
923
 
924
	id = fopen ( filename.c_str(), "wb" );
925
	if ( !id )
926
	{
927
		printf ( "* Unable to open file for writing\n" );
928
		return;
929
	}
930
	fclose ( id );
931
	remove ( filename.c_str() );
932
 
933
	CSpkFile spkfile;
934
 
935
	printf ( "Enter Script Name: " );
127 cycrow 936
	spkfile.setName(GetInput());
1 cycrow 937
 
938
	printf ( "Enter Script Author: " );
127 cycrow 939
	spkfile.setAuthor(GetInput());
1 cycrow 940
 
941
	printf ( "Enter Script Version: " );
127 cycrow 942
	spkfile.setVersion(GetInput());
1 cycrow 943
 
944
	printf ( "Enter Script Description: " );
127 cycrow 945
	spkfile.setDescription(GetInput());
1 cycrow 946
 
947
	struct tm   *currDate;
948
	char    dateString[100];
949
	time_t now = time(NULL);
950
 
951
	currDate = localtime( &now );
952
	strftime(dateString, sizeof dateString, "%d %m %Y", currDate);
50 cycrow 953
	spkfile.setCreationDate(dateString);
1 cycrow 954
 
955
	spkfile.WriteFile ( filename, NULL );
956
	printf ( "SPK file has been written to disk: %s\n", filename.c_str() );
957
}
958
 
129 cycrow 959
void ExtractFiles (const Utils::String &sfile, const Utils::String &dir, int game )
1 cycrow 960
{
961
	// First checks if the file exists by opening it
962
	FILE *id = fopen ( sfile.c_str(), "rb+" );
963
	if ( !id )
964
	{
965
		printf ( "Error: File, %s, doesn't exist\n", sfile.c_str() );
966
		return;
967
	}
968
	fclose ( id );
969
 
129 cycrow 970
	CPackages packages;
971
	packages.startup(".", ".", ".");
972
 
1 cycrow 973
	int check = CSpkFile::CheckFile ( sfile );
974
 
975
	// extracts a file from single packages file
976
	if ( check == SPKFILE_SINGLE || check == SPKFILE_BASE || check == SPKFILE_SINGLESHIP )
977
	{
978
		// creates the spkfile object
979
		CBaseFile *pBaseFile = 0;
980
		if ( check == SPKFILE_SINGLE )
981
			pBaseFile = (CBaseFile *)new CSpkFile();
982
		else if ( check == SPKFILE_SINGLESHIP )
983
			pBaseFile = (CBaseFile *)new CXspFile();
984
		else
985
			pBaseFile = new CBaseFile();
986
 
987
		printf ( "Opening File, %s... ", sfile.c_str() );
988
		// reads the file into memory
989
		// the SPKREAD_NODATA flag causes it to just read the settings, and skips the file data
990
		if ( !pBaseFile->ReadFile ( sfile, SPKREAD_NODATA ) )
991
		{
992
			printf ( "(Error)\nUnable to open the file, %s\n", sfile.c_str() );
993
			return;
994
		}
995
		printf ( "(Done)\n" );
996
 
134 cycrow 997
		if(game == 0)
998
			printf("Extracting all files from archive...\n\n");
1 cycrow 999
		else
134 cycrow 1000
			printf("Extracting %s files from archive...\n\n", packages.GetGameExe()->GetGameNameFromType(game - 1).c_str());
1001
 
1002
		CFileProgress info(&packages, pBaseFile, "Extracting");
1003
		if (packages.extractAll(pBaseFile, dir, game, true, &info) )
1004
			printf ( "\n(Done)\nFiles have been extracted successfully\n" );
1005
		else
1006
			printf ( "\n(Error)\nThere was a problem extracting the files\n" );
1 cycrow 1007
	}
1008
	else
1009
		printf("Invalid package file, %s\n", sfile.c_str());
1010
}
1011
 
1012
 
1013
/*
1014
	Func:	AppendMultiFile
1015
	Args:	String toFile	- The spk file to append onto
1016
			String addfile	- The spk file to append
1017
	Desc:	Appends a spk file into a Multi-Spk Archive
1018
			If toFile is a single spk file, it will be converted to a Multi-Spk File
1019
			if addfile is a Multi-Spk file, all files from it will be appended
1020
*/
1021
void AppendMultiFile ( CyString toFile, CyString addfile )
1022
{
1023
	// create destination object
1024
	CMultiSpkFile spkfile;
1025
 
1026
	// checks the destination
1027
	int checkto = CSpkFile::CheckFile ( toFile );
1028
 
1029
	// if the destination is a single file, then convert it to a Multi-Spk package
1030
	if ( checkto == SPKFILE_SINGLE )
1031
	{
1032
		// adds the single file to the Multi-Spk object
1033
		// Add file also reads it into memory
1034
		if ( !spkfile.AddFile ( toFile ) )
1035
		{
1036
			printf ( "Error: Unable to create Multi-Spk file\n" );
1037
			return;
1038
		}
1039
	}
1040
	else
1041
	{
1042
		// if its already a multispk file, then simply open it and read it to memory
1043
		if ( !spkfile.ReadFile ( toFile ) )
1044
		{
1045
			printf ( "Error: Unable to open Multi-Spk file, %s\n", toFile.c_str() );
1046
			return;
1047
		}
1048
	}
1049
 
1050
	// now add the file into the Multi-Spk Object
1051
	// the AddFile function will handle both single and Multi-Spk files
1052
	// So you dont need to test what the appending file is
1053
	if ( spkfile.AddFile ( addfile ) )
1054
	{
1055
 
1056
		// if it added correctly, then simply write the new Multi-Spk Object to disk
1057
		printf ( "File, %s, has been added to Multi-Spk Package\n", addfile.c_str() );
1058
		printf ( "Saving Multi-Spk File: %s... ", toFile.c_str() );
1059
		if ( spkfile.WriteFile ( toFile ) )
1060
			printf ( "(Done)\n" );
1061
		else
1062
			printf ( "(Error)\n" );
1063
	}
1064
	else
1065
		printf ( "Error: Unable to add files, %s, to Multi-Spk Package\n", addfile.c_str() );
1066
}
1067
 
1068
/*
1069
	Func:	ExtractFile
1070
	Args:	String sfile	- the spk file to read from
1071
			String type		- the type of the file to find
1072
			String addfile	- The filename to extract
1073
			String dir		- The directory to extract to
1074
	Desc:	Finds and extracts a file from a Spk Package
1075
*/
134 cycrow 1076
void ExtractFile (const Utils::String &sfile, const Utils::String &type, const Utils::String &addfile, const Utils::String &dir)
1 cycrow 1077
{
1078
	// First checks if the file exists by opening it
1079
	FILE *id = fopen ( sfile.c_str(), "rb+" );
1080
	if ( !id )
1081
	{
1082
		printf ( "Error: File, %s, doesn't exist\n", sfile.c_str() );
1083
		return;
1084
	}
1085
	fclose ( id );
1086
 
1087
	// now check the type of file it is, using the static function CheckFile(filename).
1088
	// This will return the type of file
1089
	//		SPK_INVALID		- Invalid file format, wont be able to open
1090
	//		SPK_SINGLE		- A Single spk package file
1091
	//		SPK_MULTI		- A Multi-Spk Archive
1092
	//		SPK_BASE		- A Base File
1093
	//		SPK_SINGLESHIP	- A Ship file
1094
	int check = CSpkFile::CheckFile ( sfile );
1095
 
1096
	// extracts a file from single packages file
1097
	if ( check == SPKFILE_SINGLE || check == SPKFILE_BASE || check == SPKFILE_SINGLESHIP )
1098
	{
1099
		// first get the file type is valid
1100
		// converts the string type into its filetype flag
1101
		int t = GetFileTypeFromString(type);
1102
		// incorrect text type, display the error
1103
		if ( t == -1 )
1104
		{
1105
			printf ( "The file type \"%s\" is invalid\n", type.c_str() );
1106
			return;
1107
		}
1108
 
1109
		// creates the spkfile object
1110
		CBaseFile *pBaseFile = 0;
1111
		if ( check == SPKFILE_SINGLE )
1112
			pBaseFile = (CBaseFile *)new CSpkFile();
1113
		else if ( check == SPKFILE_SINGLESHIP )
1114
			pBaseFile = (CBaseFile *)new CXspFile();
1115
		else
1116
			pBaseFile = new CBaseFile();
1117
 
1118
		printf ( "Opening File, %s... ", sfile.c_str() );
1119
		// reads the file into memory
1120
		// the SPKREAD_NODATA flag causes it to just read the settings, and skips the file data
1121
		if ( !pBaseFile->ReadFile ( sfile, SPKREAD_NODATA ) )
1122
		{
1123
			printf ( "(Error)\nUnable to open the file, %s\n", sfile.c_str() );
1124
			return;
1125
		}
1126
 
1127
		// No read all the file data into memory
1128
		// This can be done all together in the ReadFile function
1129
		// Doing it seperatly allows you to save time if an error occurs, so you dont have to wait for it to read the whole thing
1130
		pBaseFile->ReadAllFilesToMemory ();
1131
 
1132
		printf ( "(Done)\n" );
1133
 
1134
		// uses the FindFile function to find the selected file in the archive
1135
		// requires the filename, type and custom directory (only for Extra File Type)
1136
		C_File *f = pBaseFile->FindFile ( addfile, t );
1137
		if ( !f )
1138
		{
1139
			printf ( "Unable to find the file \"%s\" in the package\n", addfile.c_str() );
1140
			return;
1141
		}
1142
 
1143
		// creates the directory so it can be extracted
1144
		CDirIO Dir(dir);
160 cycrow 1145
		if ( !Dir.create(f->getDirectory(pBaseFile)) )
1 cycrow 1146
		{
1147
			printf ( "Unable to create the directory \"%s\" to extract into\n", dir.c_str() );
1148
			return;
1149
		}
1150
 
1151
		// sets up the progress pointer
1152
		// if it uses 7zip, the progress will be displayed in the command prompt
1153
		MyProgress progress(0);
1154
		printf ( "Extracting the file from package\n\t>" );
1155
 
1156
		// Extracts the file to the specified directory
1157
		if ( !pBaseFile->ExtractFile ( f, dir, true, &progress ) )
1158
			printf ( "< (Error)\nUnable to extract the file\n" );
1159
		else
1160
		{
1161
			progress.PrintDone ();
1162
			printf ( "< (Done)\nFile has been extracted successfully\n" );
1163
		}
1164
	}
1165
 
1166
	// the file is a Multi-Spk File, extracts a single spk file from the archive
1167
	else if ( check == SPKFILE_MULTI )
1168
	{
1169
		// creates MultiSpkFile object
1170
		CMultiSpkFile spkfile;
1171
		printf ( "Opening Multi-SPK file, %s...", sfile.c_str() );
1172
 
1173
		// reads the MultiSpkFile into memory
1174
		if ( !spkfile.ReadFile ( sfile ) )
1175
		{
1176
			printf ( "(Error)\nUnable to open the Multi-SPK file, %s\n", sfile.c_str() );
1177
			return;
1178
		}
1179
		printf ( "(Done)\n" );
1180
 
1181
		// searchs the archive for a matching file
1182
		SMultiSpkFile *ms = spkfile.FindFile ( type );
1183
		if ( !ms )
1184
		{
1185
			printf ( "Unable to find the file \"%s\" in the package\n", type.c_str() );
1186
			return;
1187
		}
1188
 
1189
		// extracts the file from the archive, to the given directory
1190
		printf ( "Extracting SPK file, %s, from package... ", ms->sName.c_str() );
1191
		if ( spkfile.ExtractFile ( ms, addfile ) )
1192
			printf ( "(Done)\n" );
1193
		else
1194
			printf ( "(Error)\n" );
1195
	}
1196
	else
1197
		printf ( "Error: Invalid file format, unable to open\n" );
1198
}
1199
 
1200
/*
1201
	Func:	SplitMulti
1202
	Args:	String filename - the filename of the multispk file to open
1203
			String dest		- The destination directory to extract the files to
1204
	Desc:	Splits a multi-spk file into its seperate spk files
1205
*/
1206
void SplitMulti ( CyString filename, CyString dest )
1207
{
1208
	// Check the file type, Must return SPKFILE_MULTI, otherwise its not a Multi-Spk Packages
1209
	if ( CSpkFile::CheckFile ( filename ) != SPKFILE_MULTI )
1210
	{
1211
		printf ( "Error: The file is not a Multi-Spk packages\n" );
1212
		return;
1213
	}
1214
 
1215
	printf ( "Spliting Multi-SPK File to, %s... ", dest.c_str() );
1216
 
1217
	// create the MultiSpkFile object
1218
	CMultiSpkFile spkfile;
1219
 
1220
	// Splits the files to the destination
1221
	if ( !spkfile.SplitMulti  ( filename, dest ) )
1222
	{
1223
		printf ( "(Error)\nUnable to split Multi-SPK package, %s\n", filename.c_str() );
1224
		return;
1225
	}
1226
 
1227
	printf ( "(Done)\n" );
1228
}
1229
 
127 cycrow 1230
Utils::String GetAsk(const Utils::String &command)
1 cycrow 1231
{
1232
	printf("(ASK) Enter the value for, %s: ", command.c_str());
1233
	return GetInput();
1234
}
1235
 
126 cycrow 1236
void GenerateUpdateList(int argc, char **argv)
1237
{
1238
	Utils::String currentDir = CFileIO(argv[0]).dir();
1239
	CDirIO Dir(currentDir);
1240
 
1241
	Utils::CStringList list;
1242
	for (int i = 2; i < argc; ++i)
1243
	{
1244
		Utils::String file(argv[i]);
1245
		if (CFileIO::Exists(file))
1246
			list.pushBack(file, "file");
1247
		else if (CFileIO::Exists(Dir.file(file)))
1248
			list.pushBack(Dir.file(file), "file");
1249
		else if (CDirIO::Exists(file))
1250
			list.pushBack(file, "dir");
1251
		else if (CDirIO::Exists(Dir.dir(file)))
1252
			list.pushBack(Dir.dir(file), "dir");
1253
		else
1254
			list.pushBack(file, "pattern");
1255
	}
1256
 
1257
	if (list.empty())
1258
		printf("unable to find any packages");
1259
	else
1260
	{
1261
		Utils::CStringList fileList;
1262
		for (auto itr = list.begin(); itr != list.end(); itr++)
1263
		{
1264
			Utils::String file = (*itr)->str;
1265
			Utils::String data = (*itr)->data;
1266
			if (data == "file")
1267
				fileList.pushBack(file);
1268
			else if (data == "dir")
1269
			{
1270
				CDirIO dir(file);
1271
				Utils::CStringList d;
1272
				if (dir.dirList(d))
1273
				{
1274
					for (auto itr2 = d.begin(); itr2 != d.end(); itr2++)
1275
					{
1276
						Utils::String ext = CFileIO((*itr2)->str).extension().lower();
1277
						if(ext == "xsp" || ext == "spk")
1278
							fileList.pushBack(dir.file((*itr2)->str));
1279
					}
1280
				}
1281
			}
1282
			else if (data == "pattern")
1283
			{				
1284
				CFileIO f(file);
1285
				CDirIO dir(f.dir());
1286
 
1287
				if (!dir.exists())
1288
					dir = CDirIO(Dir.dir(dir.dir()));
1289
 
1290
				Utils::CStringList d;
1291
				if (dir.dirList(d, Utils::String::Null(), f.filename()))
1292
				{
1293
					for (auto itr2 = d.begin(); itr2 != d.end(); itr2++)
1294
					{
1295
						Utils::String ext = CFileIO((*itr2)->str).extension().lower();
1296
						if (ext == "xsp" || ext == "spk")
1297
							fileList.pushBack(dir.file((*itr2)->str));
1298
					}
1299
				}
1300
			}
1301
		}
1302
 
1303
		if (fileList.empty())
1304
			printf("unable to find any packages");
1305
		else
1306
		{
1307
			CPackages packages;
1308
 
1309
			Utils::CStringList filedata;
1310
			for (auto itr = fileList.begin(); itr != fileList.end(); itr++)
1311
			{
1312
				printf("Reading file: %s\n", (*itr)->str.c_str());
1313
 
1314
				int error = 0;
1315
				CBaseFile *p = packages.OpenPackage((*itr)->str, &error, 0, SPKREAD_NODATA);
1316
				if (!p)
1317
				{
1318
					printf("\tERROR!\n");
1319
					continue;
1320
				}
1321
				printf("\tData extracted: %s %s by %s\n", p->name().c_str(), p->version().c_str(), p->author().c_str());
1322
				if (!p->creationDate().empty())
1323
					printf("\t\tCreated: %s\n", p->creationDate().c_str());
1324
				if(!p->description().empty())
1325
					printf("\t\t%s\n", p->description().c_str());
1326
 
1327
				filedata.pushBack(CPackages::FormatAvailablePackageData(p));
1328
				delete p;
1329
			}
1330
 
1331
			if (filedata.empty())
1332
				printf("unable to find any packages");
1333
			else				
1334
			{
1335
				Utils::String dest = Dir.file("xpackagedata.dat");
1336
				if (CFileIO(dest).writeFile(&filedata))
1337
					printf("web update file, xpackagedata.dat, generated");
1338
				else
1339
					printf("unable to write update file");
1340
			}
1341
		}
1342
	}
1343
}
1344
 
1 cycrow 1345
void GenerateUpdateFile(CyString spkfile)
1346
{
52 cycrow 1347
	if ( !CFileIO(spkfile).ExistsOld() )
1 cycrow 1348
	{
1349
		printf("Error: The package file, %s, does not exist", spkfile.c_str());
1350
		return;
1351
	}
1352
 
1353
	int check = CSpkFile::CheckFile(spkfile);
1354
	if ( check == SPKFILE_MULTI )
1355
	{
1356
		printf("Error: Multi-Package files currently not supported\n");
1357
		return;
1358
	}
1359
	else if ( check == SPKFILE_OLD )
1360
	{
1361
		printf("Error: unable to read old format spk file, try spkconvert first\n");
1362
		return;
1363
	}
1364
	else if ( check == SPKFILE_INVALID )
1365
	{
1366
		printf("Error: %s doesn't appear to be a valid package file\n", spkfile.c_str());
1367
		return;
1368
	}
1369
 
1370
	CPackages p;
1371
	int error;
1372
	CBaseFile *package = p.OpenPackage(spkfile, &error, 0, SPKREAD_NODATA);
1373
	if ( !package )
1374
	{
1375
		printf("Error: unable to open package file, %s, Error=%d\n", spkfile.c_str(), error);
1376
		return;
1377
	}
1378
 
134 cycrow 1379
	Utils::String file = package->createUpdateFile(CFileIO(spkfile).dir());
102 cycrow 1380
	if ( file.empty() )
1381
		printf("Error: unable to create update file for: %s, Directory=%s\n", spkfile.c_str(), CFileIO(spkfile).dir().c_str());
1 cycrow 1382
	else
1383
		printf("Update file: %s has been created for package, %s\n", file.c_str(), spkfile.c_str());
1384
 
1385
	delete package;
1386
 
1387
}
1388
 
126 cycrow 1389
void GeneratePackagerScript(const Utils::String &spkfile, CyString toFile, int game)
1 cycrow 1390
{
126 cycrow 1391
	if (!CFileIO::Exists(spkfile))
1 cycrow 1392
	{
1393
		printf("Error: The package file, %s, does not exist", spkfile.c_str());
1394
		return;
1395
	}
1396
 
1397
	int check = CSpkFile::CheckFile(spkfile);
1398
	if ( check == SPKFILE_MULTI )
1399
	{
1400
		printf("Error: Cant generate a script from a multi-spk file\n");
1401
		return;
1402
	}
1403
	else if ( check == SPKFILE_OLD )
1404
	{
1405
		printf("Error: unable to read old format spk file, try spkconvert first\n");
1406
		return;
1407
	}
1408
	else if ( check == SPKFILE_INVALID )
1409
	{
1410
		printf("Error: %s doesn't appear to be a spk file\n", spkfile.c_str());
1411
		return;
1412
	}
1413
 
1414
	CPackages p;
127 cycrow 1415
	p.startup(".", ".", ".");
1 cycrow 1416
	int error;
1417
	CBaseFile *package = p.OpenPackage(spkfile, &error, 0, SPKREAD_NODATA);
1418
	if ( !package )
1419
	{
1420
		printf("Error: unable to open package files, %s, Error=%d\n", spkfile.c_str(), error);
1421
		return;
1422
	}
1423
 
126 cycrow 1424
	Utils::CStringList list;
127 cycrow 1425
	if ( !p.generatePackagerScript(package, true, &list, game) )
1 cycrow 1426
	{
1427
		printf("Error: Unable to generate packager script\n");
1428
		return;
1429
	}
1430
 
1431
	if ( toFile.Empty() )
160 cycrow 1432
		toFile = CFileIO(spkfile).GetDirIO().file(package->name() + "_" + package->author() + ".sps");
1 cycrow 1433
 
1434
	// save package file
126 cycrow 1435
	if ( CFileIO(toFile).writeFile(&list) )
1 cycrow 1436
		printf("Packager script, %s, has been geenrated\n", toFile.c_str());
1437
	else
1438
		printf("Error: unable to write packager script, %s\n", toFile.c_str());
1439
 
1440
	delete package;
1441
}
1442
 
1443
/*
1444
	Func:	LoadPackagerScript
1445
	Args:	String filename	-	The filename of the packager script to load
1446
	Desc:	Loads the packager scripts and creates a spk/xsp file from it
1447
*/
131 cycrow 1448
void LoadPackagerScript(const Utils::String &filename, bool verify)
1 cycrow 1449
{
131 cycrow 1450
	if ( !CFileIO::Exists(filename) )
1 cycrow 1451
	{
1452
		printf("Error: The packager script, %s, does not exist", filename.c_str());
1453
		return;
1454
	}
1455
 
131 cycrow 1456
	Utils::String myDoc;
1 cycrow 1457
#ifdef _WIN32
1458
	TCHAR pszPath[MAX_PATH];
1459
	if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, pszPath)))
1460
	{
1461
		myDoc = (char *)pszPath;
1462
	}
1463
#endif
1464
 
1465
	if ( verify )
1466
		printf("Verifying Packager Script: %s\n", filename.c_str());
1467
 
1468
	CPackages p;
131 cycrow 1469
	p.startup(".", ".", myDoc);
1470
	Utils::CStringList malformed, unknown;
1 cycrow 1471
 
131 cycrow 1472
	Utils::String curDir = CFileIO(filename).dir();
1473
	if ( curDir.empty() ) curDir = "./";
1 cycrow 1474
 
131 cycrow 1475
	Utils::CStringList variables;
1476
	variables.pushBack("$PATH", curDir);
1 cycrow 1477
 
134 cycrow 1478
	CFileProgress info(&p, NULL, "Adding File");
1479
	CBaseFile *package = p.LoadPackagerScript(filename, -1, (verify) ? NULL : &GetAsk, &malformed, &unknown, &variables, &info);
1 cycrow 1480
 
134 cycrow 1481
	printf("\n");
1482
 
1 cycrow 1483
	if ( verify )
1484
	{
131 cycrow 1485
		if ( !malformed.empty() )
1 cycrow 1486
		{
131 cycrow 1487
			printf("Malformed Lines (%d):\n", malformed.size());
1488
			for(auto itr = malformed.begin(); itr != malformed.end(); itr++)				
1489
				printf("\t(Line %3d) %s\n", (*itr)->data.toInt(), (*itr)->str.c_str());
1 cycrow 1490
		}
131 cycrow 1491
		if ( !unknown.empty() )
1 cycrow 1492
		{
131 cycrow 1493
			printf("Unknown Commands (%d):\n", unknown.size());
1494
			for (auto itr = unknown.begin(); itr != unknown.end(); itr++)
1495
				printf("\t* Command: %s = %s\n", (*itr)->str.c_str(), (*itr)->data.c_str());
1 cycrow 1496
		}
1497
	}
1498
 
1499
	if ( !package )
1500
	{
1501
		if ( verify )
1502
			printf("Error: There are errors in the packager script which prevents it from being created\n");
1503
		else
1504
			printf("Error: Unable to create package, from script: %s\n", filename.c_str());
1505
	}
1506
	else
1507
	{
131 cycrow 1508
		Utils::String saveto = package->filename();
1509
		saveto = saveto.findReplace("$DEFAULTDIR", curDir + "/");
1510
		saveto = saveto.findReplace("$PATH", curDir);
1511
		saveto = saveto.findReplace("\\", "/");
1512
		saveto = saveto.findReplace("//", "/");
1513
		if ( !saveto.right(4).Compare(".spk") && package->GetType() != TYPE_XSP )
1 cycrow 1514
			saveto += ".spk";
131 cycrow 1515
		else if ( !saveto.right(4).Compare(".xsp") && package->GetType() == TYPE_XSP )
1 cycrow 1516
			saveto += ".xsp";
102 cycrow 1517
		printf("Saving file to: %s\n", CFileIO(saveto).fullFilename().c_str());
1 cycrow 1518
		if ( verify )
1519
			printf("Package can be created from this script\n");
1520
		else
1521
		{
1522
			// write script
1523
			if ( package->WriteFile(saveto) )
1524
			{
1525
				if ( package->AutoGenerateUpdateFile() )
134 cycrow 1526
					package->createUpdateFile(CFileIO(saveto).dir());
1 cycrow 1527
				printf("Package: %s was created\n", saveto.c_str());
1528
			}
1529
			else
1530
				printf("Error! There was a problem writing the package\n");
1531
		}
1532
 
50 cycrow 1533
		saveto = package->exportFilename();
131 cycrow 1534
		if ( !saveto.empty() ) {
1535
			saveto = saveto.findReplace("$DEFAULTDIR", curDir + "/");
1536
			saveto = saveto.findReplace("$PATH", curDir);
1537
			saveto = saveto.findReplace("\\", "/");
1538
			saveto = saveto.findReplace("//", "/");
102 cycrow 1539
			printf("Exporting file to: %s\n", CFileIO(saveto).fullFilename().c_str());
1 cycrow 1540
			if ( verify )
1541
				printf("Package can be exported from this script\n");
1542
			else
1543
			{
1544
				// export
126 cycrow 1545
				if ( package->SaveToArchive(saveto, 0, p.GetGameExe()) ) {
1 cycrow 1546
					if ( package->IsAnyGameInPackage() ) {
1547
						for ( int i = 0; i < p.GetGameExe()->GetNumGames(); i++ ) {
1548
							if ( package->IsGameInPackage(i + 1) ) {								
102 cycrow 1549
								Utils::String exportFile = CFileIO(saveto).dir() + "/" + CFileIO(saveto).baseName() + "_" + CBaseFile::ConvertGameToString(i + 1) + "." + CFileIO(saveto).extension();
126 cycrow 1550
								package->SaveToArchive(exportFile, i + 1, p.GetGameExe());
1 cycrow 1551
							}
1552
						}
1553
					}
1554
					printf("Package: %s was exported\n", saveto.c_str());
1555
				}
1556
				else
1557
					printf("Error! There was a problem exporting the package\n");
1558
			}
1559
		}
1560
	}
1561
}
1562
 
1563
/*
1564
	Main entry point to program
1565
*/
1566
int main ( int argc, char **argv )
1567
{
1568
	// display program header to command prompt
126 cycrow 1569
	printf ( "\nSPKTool V1.50 (SPK File Version %.2f) 14/02/2021 Created by Cycrow\n\n", (float)FILEVERSION );
1 cycrow 1570
 
1571
	// parse the cmd name
1572
	CyString cmd (argv[0]);
1573
	cmd = cmd.FindReplace ( "\\", "/" );
1574
	g_dir = cmd.GetToken ( 0, cmd.NumToken('/') - 1, '/' );
1575
	cmd = cmd.GetToken ( cmd.NumToken('/'), '/' );
1576
 
1577
	g_read = false;
1578
 
1579
	// not enough arguments, display the syntax and exit
1580
	if ( argc < 2 )
1581
	{
1582
		PrintSyntax ( cmd );
1583
		exit ( 1 );
1584
	}
1585
 
1586
	CyString fileTypes;
1587
	for ( int i = 0; i < FILETYPE_MAX; i++ )
1588
	{
1589
		CyString sT = GetFileTypeString(i);
1590
		if ( !sT.Empty() )
1591
		{
1592
			if ( fileTypes.Empty() )
1593
				fileTypes = sT;
1594
			else
1595
			{
1596
				fileTypes += ", ";
1597
				fileTypes += sT;
1598
			}
1599
		}
1600
	}
1601
 
1602
	// get the command flag
134 cycrow 1603
	Utils::String command(argv[1]);
1 cycrow 1604
 
1605
	// display the contents of the spk file
134 cycrow 1606
	if ( command == "-v" || command == "--view" || command == "--version")
1 cycrow 1607
	{
1608
		if ( argc < 3 )
1609
			printf ( "Syntax: %s -v <spkfile>\n\tWill open and display the contents of the spkfile\n", cmd.c_str() );
1610
		else
134 cycrow 1611
			DisplayVersion(argv[2]);
1 cycrow 1612
	}
1613
 
1614
	// creates a new spk file
1615
	else if ( command == "-c" || command == "--create" )
1616
	{
1617
		if ( argc < 3 )
1618
			printf ( "Syntax:\n\t%s -c <spkfile>\n\t%s --create <spkfile>\n\t\tThis will create a new SPK file and allow you to set some basic settings for the file\n", cmd.c_str(), cmd.c_str() );
1619
		else
1620
			CreateFile ( argv[2] );
1621
	}
1622
 
1623
	// appends a file onto the spk archive
1624
	else if ( command == "-a" || command == "--append" )
1625
	{
1626
		if ( argc < 4 )
1627
			printf ( "Syntax:\n\t%s -a <spkfile> <type> <filename>\n\t%s --append <spkfile> <type> <filename>\n\t\tThis will append the file into the archive and compress it according to the files default compression\n\t<type> = %s\n", cmd.c_str(), cmd.c_str(), fileTypes.c_str() );
1628
		else
1629
		{
1630
			CyString arg4;
1631
			if ( argc > 4 )
1632
				arg4 = argv[4];
1633
			AppendFile ( argv[2], argv[3], arg4 );
1634
		}
1635
	}
1636
 
1637
	// removes a file from the spk archive
1638
	else if ( command == "-r" || command == "--remove" || command == "--removespk" )
1639
	{
1640
		if ( argc < 4 )
1641
		{
1642
			printf ( "Syntax:\n\t%s -r <spkfile> <type> <filename>\n\t%s --remove <spkfile> <type> <filename\n\t\tThis will remove a file from the archive\n\t<type> = %s\n", cmd.c_str(), cmd.c_str(), fileTypes.c_str() );
1643
			printf ( "\t%s -r <multispkfile> <filename>\n\t%s --removespk <multispkfile> <filename>\n\t\tThis will remove a spk file from the Multi-SPK package\n", cmd.c_str(), cmd.c_str() );
1644
		}
1645
		else
1646
		{
1647
			CyString arg4;
1648
			if ( argc > 4 )
1649
				arg4 = argv[4];
1650
			RemoveFile ( argv[2], argv[3], arg4 );
1651
		}
1652
	}
1653
 
1654
	// extracts a file from a spk file
1655
	else if ( command == "--extractspk" )
1656
	{
1657
		if ( argc < 4 )
1658
			printf ( "Syntax:\n\t%s --extractspk <multispkfile> <filename> [destination]\n\tThis will extract a spk file from the Multi-Spk package and save it to the destination path\n", cmd.c_str() );
1659
		else
1660
		{
134 cycrow 1661
			Utils::String arg4;
1 cycrow 1662
			if ( argc > 4 )
1663
				arg4 = argv[3];
134 cycrow 1664
			ExtractFile(argv[2], argv[3], arg4, Utils::String::Null());
1 cycrow 1665
		}
1666
	}
1667
	else if ( command == "-x" || command == "--extract")
1668
	{
1669
		if ( argc < 4 )
1670
		{
1671
			printf ( "Syntax:\n\t%s -x <spkfile> <type> <filename> [destination]\n\tThis will extract a file from the package and save it to the corect path in <directory>\n\t<type> = %s\n", cmd.c_str(), fileTypes.c_str() );
1672
			printf ( "\t%s -x <multispkfile> <filename> [destination]\n\tThis will extract a spk file from the Multi-Spk package and save it to the destination path\n", cmd.c_str() );
1673
		}
1674
		else
1675
		{
134 cycrow 1676
			Utils::String arg5, arg4;
1 cycrow 1677
			if ( argc > 5 )
1678
				arg5 = argv[5];
1679
			if ( argc > 4 )
1680
				arg4 = argv[4];
134 cycrow 1681
			ExtractFile(argv[2], argv[3], arg4, arg5);
1 cycrow 1682
		}
1683
	}
1684
 
1685
	// extracts all the files from an archive
1686
	else if ( command == "-e" || command == "--extractall" )
1687
	{
1688
		if ( argc < 3 )
1689
			printf ( "Syntax:\n\t%s -e <spkfile> [destination]\n\t--extractall <spkfile> <game> [destination]\n\t\tThis will extract all files of a set game into the destination directory\n\n\t\tGame = 0 will extract all files", cmd.c_str() );
1690
		else
1691
		{
129 cycrow 1692
			Utils::String arg4;
1 cycrow 1693
			if ( argc > 4 )
1694
				arg4 = argv[4];
134 cycrow 1695
			ExtractFiles(argv[2], arg4, CBaseFile::GetGameFromString(argv[3]));
1 cycrow 1696
		}
1697
	}
1698
 
1699
	// creates a multispk archive
1700
	else if ( command == "-n" || command == "--createmulti" )
1701
	{
1702
		if ( argc < 3 )
1703
			printf ( "Syntax:\n\t%s -n <multispkfile>\n\t%s --createmulti <multispkfile>\n\t\tThis will create a multispk file and allow you to add spk files to it\n", cmd.c_str(), cmd.c_str() );
1704
		else
1705
			CreateMultiFile ( argv[2] );
1706
	}
1707
 
1708
	// merges 2 multi-spk archives together, or appends a single spk file into a multi-spk file
1709
	else if ( command == "-m" || command == "--mergemulti" )
1710
	{
1711
		if ( argc < 4 )
1712
			printf ( "Syntax:\n\t%s -m <spkfile1> <spkfile2>\n\t%s --mergemulti <spkfile1> <spkfile2>\n\t\tThis will add spkfile2 into spkfile1, if spkfile1 is a normal SPK file, it will be saved into a Multi-Spk file\nspkfile2 can also be a Multi-Spk file, all files within it will be added\n", cmd.c_str(), cmd.c_str() );
1713
		else
1714
			AppendMultiFile ( argv[2], argv[3] );
1715
	}
1716
 
1717
	// splits the multi-spk file, exracts all spk files
1718
	else if ( command == "-s" || command == "--splitmulti" )
1719
	{
1720
		if ( argc < 3 )
1721
			printf ( "Syntax: %s -s <multispkfile> [destination]\n\tSplits the Multi-SPK file and saves each spk file to the destiantion directory\n", cmd.c_str() );
1722
		else
1723
		{
1724
			CyString arg3;
1725
			if ( argc > 3 )
1726
				arg3 = argv[3];
1727
			SplitMulti ( argv[2], arg3 );
1728
		}
1729
	}
1730
 
1731
	else if ( command == "--set" )
1732
	{
1733
		if ( argc < 4 )
1734
			printf ( "Syntax: %s --set <spkfile> <setting> [values]\n\tSets various settings in the package\n", cmd.c_str() );
1735
		else
1736
			Settings(argv[2], argv[3], argc, argv, cmd);
1737
	}
1738
	else if ( command == "--setrating" )
1739
	{
1740
		if ( argc < 6 )
1741
			printf ( "Syntax: %s --setrating <spkfile> <easeofuse> <gamechanging> <recommended>\n\tSets the rating of the spk package\n", cmd.c_str() );
1742
		else
1743
			SetRating(argv[2], CyString(argv[3]).ToInt(), CyString(argv[4]).ToInt(), CyString(argv[5]).ToInt());
1744
	}
1745
	else if ( command == "--convertxsp" || command == "--convertxspwizard" )
1746
	{
1747
		if ( argc < 3 )
1748
			printf ( "Syntax: %s %s <xspfile> [newxspfile]\n\tConverts an old format xsp file to work with the new format\n", cmd.c_str(), command.c_str() );
1749
		else
1750
		{
1751
			CyString arg3;
1752
			if ( argc > 3 )
1753
				arg3 = argv[3];
1754
			ConvertXsp(argv[2], arg3, (command == "--convertxspwizard") ? true : false);
1755
		}
1756
	}
1757
	else if ( command == "--createscript" )
1758
	{
1759
		if ( argc < 3 )
1760
			printf ( "Syntax:\n\t%s --createscript <packagerscript>\n\t\tThis will create a spk/xsp file from a packager script\n", cmd.c_str() );
1761
		else
1762
			LoadPackagerScript ( argv[2], false );
1763
	}
1764
	else if ( command == "--generatescript" )
1765
	{
1766
		if ( argc < 3 )
126 cycrow 1767
			printf ( "Syntax:\n\t%s --generatescript <package> [packagerscript]\n\t\tThis will generate a packager script file from a spk/xsp file.\n", cmd.c_str() );
1 cycrow 1768
		else
1769
		{
1770
			if ( argc < 4 )
126 cycrow 1771
				GeneratePackagerScript ( argv[2], "", 0);
1 cycrow 1772
			else
126 cycrow 1773
				GeneratePackagerScript ( argv[2], argv[3], 0);
1 cycrow 1774
		}
1775
	}
1776
	else if ( command == "--verifyscript" )
1777
	{
1778
		if ( argc < 3 )
1779
			printf ( "Syntax:\n\t%s --verifyscript <packagerscript>\n\t\tThis will read a packager script and check its correct without creating the resulting spk/xsp file\n", cmd.c_str() );
1780
		else
1781
			LoadPackagerScript ( argv[2], true );
1782
	}
1783
	else if ( command == "--extractship" )
1784
	{
1785
		if ( argc < 4 )
1786
			printf ( "Syntax:\n\t%s --extractship <modfile> <xspfile> [shipid]\n\t\tThis will create an xsp ship file by extracting from a mod file\n", cmd.c_str() );
1787
		else
1788
		{
1789
			if ( argc < 5 )
1790
				ExtractShip ( argv[2], argv[3], "" );
1791
			else
1792
				ExtractShip ( argv[2], argv[3], argv[4] );
1793
		}
1794
	}
126 cycrow 1795
	else if (command == "--generateupdatefile")
1 cycrow 1796
	{
126 cycrow 1797
	if (argc < 3)
1798
		printf("Syntax:\n\t%s --generateupdatefile <package>\n\t\tThis will generate the update file to allow auto updates for a package\n", cmd.c_str());
1799
	else
1800
		GenerateUpdateFile(argv[2]);
1801
	}
1802
	else if (command == "--packagelist")
1803
	{
1804
		if (argc < 3)
1805
			printf("Syntax:\n\t%s --packagelist <filenames>\n\t\tThis will generate the update file to allow downloading packages from a server.\n", cmd.c_str());
1 cycrow 1806
		else
126 cycrow 1807
			GenerateUpdateList(argc, argv);
1 cycrow 1808
	}
1809
 
1810
	// not a valid switch, display syntax
1811
	else
1812
		PrintSyntax ( cmd );
1813
 
1814
#ifdef _DEBUG
1815
	char pause;
1816
	scanf ( "%s", &pause );
1817
#endif
1818
 
1819
	return 0;
1820
}