Subversion Repositories spk

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 cycrow 1
#include "spkprogress.h"
2
 
3
#ifndef _INCLUDE7ZIP
4
#include <ansi7zip/7Decoder.h>
5
#endif
6
 
7
#include <MultiSpkFile.h>
4 cycrow 8
#include "../../HiP/HiP.h"
1 cycrow 9
 
10
 
11
#ifdef _DEBUG
12
#define CLEANUP fclose ( id ); if ( data ) delete data; if ( uncomprData ) delete uncomprData; if ( !removeFile.Empty() ) remove ( removeFile.c_str() ); char pause; printf ( "Press Enter to Close\n" ); scanf ( "%c", &pause );
13
#else
14
#define CLEANUP fclose ( id ); if ( data ) delete data; if ( uncomprData ) delete uncomprData; if ( !removeFile.Empty() ) remove ( removeFile.c_str() ); 
15
#endif
16
 
4 cycrow 17
char *ReadNextLine ( char *data, long *len, CyString *str )
1 cycrow 18
{
19
	int pos = 0;
20
	bool end = false;
21
	while ( pos < *len )
22
	{
23
		if ( data[pos] == '\n' )
24
			break;
25
		if ( data[pos] == '\0' )
26
		{
27
			end = true;
28
			break;
29
		}
30
		++pos;
31
	}
32
 
33
	if ( end )
34
	{
35
		*len = 0;
36
		*str = data;
37
		return NULL;
38
	}
39
 
40
	data[pos] = '\0';
41
	*str = data;
42
	data[pos] = '\n';
43
	*len -= (pos + 1);
44
 
45
	return data + (pos + 1);
46
}
47
 
4 cycrow 48
char *LineByLineRead ( char *data, long *len, CyString end, CyString *readData )
1 cycrow 49
{
4 cycrow 50
	CyString line;
1 cycrow 51
	while ( true )
52
	{
53
		data = ReadNextLine ( data, len, &line );
54
 
55
		if ( line == end )
56
			break;
57
		*readData += (line + "\n");
58
	}
59
 
60
	return data;
61
}
62
 
63
int main ( int argc, char **argv )
64
{
4 cycrow 65
	CyString filename ( argv[0] );
1 cycrow 66
	filename = filename.GetToken ( filename.NumToken ( '\\' ), '\\' );
67
 
68
	printf ( "SPKConvert V1.10 (SPK VERSION %.2f) 28/07/2007 by Cycrow\n", FILEVERSION );
69
 
70
	if ( argc < 3 )
71
	{
72
		printf ( "Syntax, %s <oldspkfile> <newspkfile>\n", filename.c_str() );
73
		exit ( 1 );
74
	}
75
 
4 cycrow 76
	CyString oldfile ( argv[1] );
77
	CyString newfile ( argv[2] );
1 cycrow 78
 
4 cycrow 79
 
80
	int ret = CBaseFile::CheckFile ( oldfile );
81
	if ( ret != SPKFILE_INVALID && ret != SPKFILE_OLD )
1 cycrow 82
	{
83
		printf ( "Spk file is already in the new format, unable to convert\n" );
84
		exit ( 1 );
85
	}
86
 
87
	// firstcheck if the file exists
88
	FILE *id = fopen ( argv[1], "rb" );
89
	if ( !id )
90
	{
91
		printf ( "Unable to open file: %s\n", argv[1] );
92
		exit ( 0 );
93
	}
94
 
95
	// read the first 3 charaters
4 cycrow 96
	CyString check = (char)fgetc ( id );
1 cycrow 97
	check += (char)fgetc ( id );
98
	check += (char)fgetc ( id );
99
 
4 cycrow 100
	CyString removeFile;
1 cycrow 101
 
102
	unsigned char *uncomprData = NULL;
103
	unsigned char *data = NULL;
104
	long len = 0, newlen = 0;
105
 
106
	MyProgress *progress = new MyProgress ( 0 );
4 cycrow 107
 
1 cycrow 108
	if ( check == "HiP" )
109
	{
110
		fclose ( id );
111
		bool opened = false;
112
		if ( DecompressFile ( argv[1], "uncompr.tmp" ) )
113
		{
114
			removeFile = "uncompr.tmp";
115
			id = fopen ( "uncompr.tmp", "r" );
116
			if ( id )
117
				opened = true;
118
		}
119
 
120
		if ( !opened )
121
		{
122
			printf ( "Unable to uncompress file, exiting...\n" );
123
			exit ( 0 );
124
		}
125
 
126
		printf ( "* Reading file into memory... " );
127
		// get file length
128
		fseek ( id, 0, SEEK_END );
129
		len = ftell ( id );
130
 
131
		// move back to beginning
132
		fseek ( id, 0, SEEK_SET );
133
 
134
		// read the data from file into memory
135
		uncomprData = new unsigned char[len + 1];
136
		fread ( uncomprData, sizeof(unsigned char), len, id );
137
 
138
		newlen = len;
139
	}
140
	else
141
	{
142
		printf ( "* Reading file into memory... " );
143
		// get file length
144
		fseek ( id, 0, SEEK_END );
145
		len = ftell ( id );
146
 
147
		// move back to beginning
148
		fseek ( id, 0, SEEK_SET );
149
 
150
		// read the data from file into memory
151
		data = new unsigned char[len + 1];
152
		fread ( data, sizeof(unsigned char), len, id );
153
 
154
		// uncompress the file (currently only 7zip compression)
155
		printf ( "\t(Done)\n* Uncompressing file...\n\t>" );
156
		newlen = len;
157
	#ifdef _INCLUDE7ZIP
158
		uncomprData = LZMADecodeData ( data, len, newlen, progress );
159
	#else
160
		uncomprData = LZMADecode_C ( (unsigned char *)data, len, (size_t*)&newlen, NULL );
161
	#endif
162
	}
163
 
164
	// uncomressed failed
165
	if ( !uncomprData )
166
	{
167
		printf ( "\t(Error)\n" );
168
		CLEANUP
169
		exit ( 0 );
170
	}
171
 
172
	len = newlen;
173
 
174
	printf ( "< (Done)\n" );
175
 
176
	// now we can read the data
177
	char *d = (char *)uncomprData;
4 cycrow 178
	CyString str;
1 cycrow 179
	CSpkFile *spkfile = new CSpkFile;
180
	CMultiSpkFile *mspk = NULL;
181
	SMultiSpkFile *cur_mspk = NULL;
182
 
183
	int numscripts = 0, curscript = 0;
184
	bool verbose = true;
185
	float fVersion = 1;
186
 
187
	printf ( "* Reading spk data..." );
188
	if ( verbose )
189
		printf ( "\n" );
190
 
191
 
192
	while ( (d) && (len > 0) )
193
	{
194
		d = ReadNextLine ( d, &len, &str );
195
 
4 cycrow 196
		CyString first = str.GetToken ( 1, ' ' );
197
		CyString rest = str.GetToken ( 2, -1, ' ' );
1 cycrow 198
		if ( first == "MultiPackage:" )
199
			mspk = new CMultiSpkFile;
200
		else if ( (first == "SelectScript:") && (mspk) )
201
		{
202
			mspk->AddFileEntry ( rest.GetToken ( 2, -1, ' ' ) + ".spk" );
203
			++numscripts;
204
		}
205
		else if ( (str == "AllowSelection") && (mspk) )
206
			mspk->SetSelection ( true );
207
		else if ( str == "-- Start New Script --" )
208
		{
209
			if ( !mspk )
210
			{
211
				printf ( "Invalid file format, seems to be multi package file but isn't\n" );
212
				CLEANUP
213
				exit ( 0 );
214
			}
215
			cur_mspk = mspk->GetFileList()->Get ( curscript );
216
			++curscript;
217
			cur_mspk->pFile = new CSpkFile;
4 cycrow 218
			spkfile = (CSpkFile *)cur_mspk->pFile;
1 cycrow 219
		}
220
		else if ( first == "Packager:" )
221
		{
222
			fVersion = rest.ToFloat ();
223
			if ( verbose ) printf ( "\tPackager Version: %.2f\n", fVersion );
224
		}
225
		else if ( first == "Name:" )
226
		{
227
			spkfile->SetName ( rest );
228
			if ( verbose ) printf ( "\tScript Name: %s\n", rest.c_str() );
229
		}
230
		else if ( first == "Author:" )
231
		{
232
			spkfile->SetAuthor ( rest );
233
			if ( verbose ) printf ( "\tScript Author: %s\n", rest.c_str() );
234
		}
235
		else if ( str == "CustomStart" )
236
		{
4 cycrow 237
			spkfile->SetCustomStart();
1 cycrow 238
			if ( verbose ) printf ( "\tPackage is a custom start!!\n" );
239
		}
240
		else if ( first == "AnotherMod:" )
241
		{
242
			spkfile->SetAnotherMod ( rest.GetToken ( 1, '|' ), rest.GetToken ( 2, -1, '|' ) );
243
			if ( verbose ) printf ( "\tFor another Mod, Name: %s, Author: %s\n", spkfile->GetOtherName().c_str(), spkfile->GetOtherAuthor().c_str() );
244
		}
245
		else if ( str == "PATCH" )
246
		{
4 cycrow 247
			spkfile->SetPatch();
1 cycrow 248
			if ( verbose ) printf ( "\tPackage is a Patch Mod!!\n" );
249
		}
250
		else if ( first == "Version:" )
251
		{
252
			spkfile->SetVersion ( rest );
253
			if ( verbose ) printf ( "\tScript Version: %s\n", rest.c_str() );
254
		}
255
		else if ( first == "Date:" )
256
		{
257
			spkfile->SetCreationDate ( rest );
258
			if ( verbose ) printf ( "\tScript Creation Date: %s\n", rest.c_str() );
259
		}
260
		else if ( first == "Desc:" )
261
		{
262
			spkfile->SetDescription ( rest.FindReplace ( "<br>", "\n" ) );
263
			if ( verbose ) printf ( "\tScript Description: %s\n", spkfile->GetDescription().c_str() );
264
		}
265
		else if ( first == "WebAddress:" )
266
		{
267
			spkfile->SetWebAddress ( rest );
268
			if ( verbose ) printf ( "\tWeb Address: %s\n", rest.c_str() );
269
		}
270
		else if ( first == "WebMirror1:" )
271
		{
4 cycrow 272
			spkfile->AddWebMirror(rest);
1 cycrow 273
			if ( verbose ) printf ( "\tWeb Mirror Address: %s\n", rest.c_str() );
274
		}
275
		else if ( first == "WebMirror2:" )
276
		{
4 cycrow 277
			spkfile->AddWebMirror(rest);
1 cycrow 278
			if ( verbose ) printf ( "\tWeb Mirror Address: %s\n", rest.c_str() );
279
		}
280
 
281
		else if ( first == "ScriptType:" )
282
			spkfile->SetScriptType ( rest );
283
		else if ( first == "WebSite:" )
284
		{
285
			spkfile->SetWebSite ( rest );
286
			if ( verbose ) printf ( "\tWeb Site: %s\n", rest.c_str() );
287
		}
288
		else if ( first == "Email:" )
289
		{
290
			spkfile->SetEmail ( rest );
291
			if ( verbose ) printf ( "\tAuthor Email Address: %s\n", rest.c_str() );
292
		}
293
		else if ( first == "GameVersion:" )
294
		{
4 cycrow 295
			//TODO: fix this for new game version
296
			/*
1 cycrow 297
			int version = rest.ToInt();
298
			if ( version == 0 )
299
				spkfile->SetGameVersion ( 1 );
300
			else if (version == 1 )
301
				spkfile->SetGameVersion ( 0 );
302
			else
303
				spkfile->SetGameVersion ( version );
304
			if ( verbose ) printf ( "\tGame Version: %d\n", spkfile->GetGameVersion () );
4 cycrow 305
			*/
1 cycrow 306
		}
307
 
308
		else if ( first == "Ware:" )
309
		{
310
			spkfile->AddWare ( rest );
311
			if ( verbose ) printf ( "\tAdding Custom Ware\n" );
312
		}
313
		else if ( first == "WareText:" )
314
			spkfile->AddWareText ( rest );
315
		else if ( first == "UninstallAfter:" )
4 cycrow 316
			spkfile->AddUninstallAfterText ( rest.GetToken ( 1, ' ' ).ToInt(), rest.GetToken ( 2, -1, ' ' ) );
1 cycrow 317
		else if ( first == "UninstallBefore:" )
4 cycrow 318
			spkfile->AddUninstallBeforeText ( rest.GetToken ( 1, ' ' ).ToInt(), rest.GetToken ( 2, -1, ' ' ) );
1 cycrow 319
		else if ( first == "InstallAfter:" )
4 cycrow 320
			spkfile->AddInstallAfterText ( rest.GetToken ( 1, ' ' ).ToInt(), rest.GetToken ( 2, -1, ' ' ) );
1 cycrow 321
		else if ( first == "InstallBefore:" )
4 cycrow 322
			spkfile->AddInstallBeforeText ( rest.GetToken ( 1, ' ' ).ToInt(), rest.GetToken ( 2, -1, ' ' ) );
1 cycrow 323
		else if ( first == "ScriptName:" )
324
		{
4 cycrow 325
			CyString lang = rest.GetToken ( 1, ':' );
326
			CyString name = rest.GetToken ( 2, -1, ':' );
327
			spkfile->AddLanguageName ( lang.ToInt(), name );
1 cycrow 328
			if ( verbose ) printf ( "\tScript Name Language (%s) %s\n", lang.c_str(), name.c_str() );
329
		}
330
		else if ( first == "Icon:" )
331
		{
4 cycrow 332
			CyString ext = rest.GetToken ( 2, ' ' );
1 cycrow 333
			long size = rest.GetToken ( 1, ' ' ).ToLong ();
334
 
4 cycrow 335
			C_File *file = new C_File ();
1 cycrow 336
			file->ReadFromData ( d, size );
337
 
338
			d += size;
339
 
340
			spkfile->SetIcon ( file, ext );
341
 
342
			if ( verbose ) printf ( "\tIcon (%s) Size: %s\n", ext.c_str(), file->GetDataSizeString ().c_str() );
343
		}
344
		else if ( (first == "$$$SharedScript:") || (first == "$$$Script:") || (first == "$$$SharedText:") || (first == "$$$Text:") || (first == "$$$Uninstall:") || (first == "$$$SharedMap:") || (first == "$$$Map:") || (first == "$$$Readme:") )
345
		{
346
			int type;
4 cycrow 347
			CyString end, print;
1 cycrow 348
			if ( (first == "$$$SharedText:") || (first == "$$$Text:") )
349
			{
350
				type = FILETYPE_TEXT;
351
				end = "-- End of Script --";
352
				print = "Text";
353
			}
354
			else if ( first == "$$$Uninstall:" )
355
			{
356
				type = FILETYPE_UNINSTALL;
357
				end = "-- End of Uninstall --";
358
				print = "Uninstall Script";
359
			}
360
			else if ( first == "$$$Readme:" )
361
			{
362
				type = FILETYPE_README;
363
				end = "-- End of Readme --";
364
				print = "Readme";
365
			}
366
			else if ( (first == "$$$SharedMap:") || (first == "$$$Map:") )
367
			{
368
				type = FILETYPE_MAP;
369
				end = "-- End of Map --";
370
				print = "Universe Map";
371
			}
372
			else
373
			{
374
				type = FILETYPE_SCRIPT;
375
				end = "-- End of Script --";
376
				print = "Script";
377
			}
378
 
4 cycrow 379
			CyString filename, dir;
1 cycrow 380
			long time = 0, size = 0;
381
			bool shared = false;
382
 
383
			if ( fVersion >= 3.00f )
384
				filename = rest.GetToken ( 3, -1, ' ' );
385
			else if ( fVersion >= 2.00f )
386
				filename = rest.GetToken ( 2, -1, ' ' );
387
			else
388
				filename = rest;
389
 
390
			if ( filename.IsIn ( "<br>" ) )
391
			{
392
				filename = filename.FindReplace ( "<br>", "|" );
393
				if ( filename[0] == '|' )
394
				{
395
					filename = filename.GetToken ( 1, '|' );
396
				}
397
				else
398
				{
399
					dir = filename.GetToken ( 1, '|' );
400
					filename = filename.GetToken ( 2, -1, '|' );
401
				}
402
			}
403
 
404
			if ( fVersion >= 2.00f )
405
				time = rest.GetToken ( 1, ' ' ).ToLong();
406
 
407
			if ( fVersion >= 3.00f )
408
				size = rest.GetToken ( 2, ' ' ).ToLong();
409
 
410
			if ( first.Left (9) == "$$$Shared" )
411
				shared = true;
412
 
4 cycrow 413
			C_File *file = new C_File ();
1 cycrow 414
 
415
			bool binaryRead = false;
4 cycrow 416
			CyString ext = filename.GetToken ( filename.NumToken ( '.' ), '.' );
1 cycrow 417
			if ( ext.ToUpper() == "PCK" )
418
				binaryRead = true;
419
 
420
			if ( verbose )
421
			{
422
				if ( shared )
423
					printf ( "\tFound %s File (Shared): %s, Reading...", print.c_str(), filename.c_str() );
424
				else
425
					printf ( "\tFound %s File: %s, Reading...", print.c_str(), filename.c_str() );
426
			}
427
 
428
			if ( binaryRead )
429
			{
430
				file->ReadFromData ( d, size );
431
				d += size;
432
			}
433
			else
434
			{
4 cycrow 435
				CyString readData;
1 cycrow 436
				d = LineByLineRead ( d, &len, end, &readData );
437
				file->ReadFromData ( (char *)readData.c_str(), (long)readData.Length() );
438
			}
439
			file->SetName ( filename );
440
			file->SetFileType ( type );
441
			file->SetShared ( shared );
442
			file->SetCreationTime ( time );
443
			if ( !dir.Empty() )
444
				file->SetDir ( dir );
445
 
446
			spkfile->AddFile ( file );
447
 
448
			printf ( "(Done) Size: %s\n", file->GetDataSizeString().c_str() );
449
 
450
		}
451
		else if ( (first == "$$$Mod:") || (first == "$$$Sound:") || (first == "$$$Extra:") || (first == "$$$Screen:") )
452
		{
453
			int type = -1;
4 cycrow 454
			CyString print;
1 cycrow 455
			if ( first == "$$$Mod:" )
456
			{
457
				type = FILETYPE_MOD;
458
				print = "Mod";
459
			}
460
			else if ( first == "$$$Extra:" )
461
			{
462
				type = FILETYPE_EXTRA;
463
				print = "Extra";
464
			}
465
			else if ( first == "$$$Screen:" )
466
			{
467
				type = FILETYPE_SCREEN;
468
				print = "Screenshot";
469
			}
470
			else if ( first == "$$$Sound:" )
471
			{
472
				type = FILETYPE_SOUND;
473
				print = "Sound Track";
474
			}
475
 
4 cycrow 476
			CyString filename = rest.GetToken ( 3, -1, ' ' ), dir;
1 cycrow 477
			long time = rest.GetToken ( 1, ' ' ).ToLong(), size = rest.GetToken ( 2, ' ' ).ToLong();
478
			bool shared = false;
479
 
480
			if ( filename.IsIn ( "<br>" ) )
481
			{
482
				filename = filename.FindReplace ( "<br>", "|" );
483
				if ( filename[0] == '|' )
484
					filename = filename.GetToken ( 1, '|' );
485
				else
486
				{
487
					dir = filename.GetToken ( 1, '|' );
488
					filename = filename.GetToken ( 2, -1, '|' );
489
				}
490
			}
491
 
4 cycrow 492
			C_File *file = new C_File ();
1 cycrow 493
			file->ReadFromData ( d, size );
494
			file->SetName ( filename );
495
			file->SetFileType ( type );
496
			file->SetShared ( shared );
497
			file->SetCreationTime ( time );
498
			if ( !dir.Empty() )
499
				file->SetDir ( dir );
500
 
501
			d += size;
502
 
503
			spkfile->AddFile ( file );
504
 
505
			if ( verbose )
506
			{
507
				if ( shared )
508
					printf ( "\tFound %s File (Shared): %s, Size(%s)\n", print.c_str(), filename.c_str(), file->GetDataSizeString().c_str() );
509
				else
510
					printf ( "\tFound %s File: %s, Size(%s)\n", print.c_str(), filename.c_str(), file->GetDataSizeString().c_str() );
511
			}
512
		}
513
	}
514
 
515
	if ( verbose ) printf ( "* Reading spk data..." );
516
	printf ( " (Done)\n" );
517
 
518
	// now save the spk file
519
	printf ( "\nStarting to write new spk file\n" );
520
	if ( mspk )
521
	{
522
		for ( SMultiSpkFile *it = mspk->GetFileList()->First(); it; it = mspk->GetFileList()->Next() )
523
		{
4 cycrow 524
			for ( C_File *f = it->pFile->GetFileList()->First(); f; f = it->pFile->GetFileList()->Next() )
1 cycrow 525
			{
526
				printf ( "* Compressing %s...\n\t>", f->GetNameDirectory(it->pFile).c_str() );
527
				if ( f->CompressData ( spkfile->GetDataCompression(), progress ) )
528
				{
529
					progress->PrintDone();
530
					printf ( "< (Done)\n" );
531
				}
532
				else
533
				{
534
					progress->Reset();
535
					printf ( "< (Error)\n" );
536
				}
537
			}
538
 
539
			FILE *id = tmpfile();
540
			if ( id )
541
			{
542
				it->pFile->WriteData ( id, NULL );
543
				it->lSize = ftell ( id );
544
				fclose ( id );
545
			}
546
		}
547
	}
548
	else
549
	{
4 cycrow 550
		for ( C_File *f = spkfile->GetFileList()->First(); f; f = spkfile->GetFileList()->Next() )
1 cycrow 551
		{
552
			printf ( "* Compressing %s...\n\t>", f->GetNameDirectory(spkfile).c_str() );
553
			if ( f->CompressData ( spkfile->GetDataCompression(), progress ) )
554
			{
555
				progress->PrintDone();
556
				printf ( "< (Done)\n" );
557
			}
558
			else
559
			{
560
				progress->Reset();
561
				printf ( "< (Error)\n" );
562
			}
563
		}
564
	}
565
 
566
	printf ( "* Writing to %s... ", argv[2] );
567
	if ( mspk )
568
	{
4 cycrow 569
		if ( mspk->WriteFile ( CyString(argv[2]) ) )
1 cycrow 570
			printf ( "(Done)\n" );
571
		else
572
			printf ( "(Error)\n" );
573
	}
574
	else
575
	{
4 cycrow 576
		spkfile->WriteFile ( CyString(argv[2]) );
1 cycrow 577
		printf ( "(Done)\n" );
578
	}
579
 
580
	printf ( "SPK file has been converted successfully\n" );
581
	CLEANUP
582
 
583
	return 1;
584
}