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