Subversion Repositories spk

Rev

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