Subversion Repositories spk

Rev

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