Subversion Repositories spk

Rev

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

Rev Author Line No. Line
7 cycrow 1
//header
1 cycrow 2
#include "SpkFile.h"
3
 
7 cycrow 4
// debug logging
5
#include "Logging/Log.h"
6
 
7
// old style compression (needed to convert old formats)
8
#include "../../HiP/HiP.h"
9
 
10
//TODO: remove this
11
unsigned char *LineByLineRead ( unsigned char *data, CyString end, CyString *readData )
12
{
13
	CyString line;
14
	while ( true )
15
	{
16
		data = line.GetEndOfLine(data);
17
		//data = ReadNextLine ( data, len, &line );
18
 
19
		if ( (*readData).Empty() && line.Empty() ) continue;
20
		if ( line == end )
21
			break;
22
		*readData += (line + "\r\n");
23
	}
24
 
25
	return data;
26
}
27
 
28
 
1 cycrow 29
CSpkFile::CSpkFile() : CBaseFile ()
30
{
31
	SetDefaults ();
32
 
33
	m_iType = TYPE_SPK;
34
}
35
 
36
CSpkFile::~CSpkFile()
37
{
38
	Delete ();
39
}
40
/*
41
	Func:   SetDefaults
42
	Desc:   Sets the  default values when class is created
43
*/
44
void CSpkFile::SetDefaults ()
45
{
46
	m_pLastWare = NULL;
47
	m_iPackageType = PACKAGETYPE_NORMAL;
48
	m_bForceProfile = false;
49
	m_iScriptType = SCRIPTTYPE_CUSTOM;
50
 
51
	CBaseFile::SetDefaults ();
52
}
53
 
54
void CSpkFile::Delete ()
55
{
56
	m_lWares.clear(true);
57
	m_lSettings.clear(true);
58
 
59
	CBaseFile::Delete ();
60
}
61
 
62
 
63
bool CSpkFile::CheckHeader ( CyString header )
64
{
65
	if ( header.Compare("SPKCycrow") )
66
		return true;
67
	return false;
68
}
69
/*
70
	Func:   ParseValueLine
71
	Input:  String - single line from a file to set
72
	Return: Boolean - returns true if value exists
73
	Desc:   Reads the line and assigns the parameters for the file
74
*/
75
bool CSpkFile::ParseValueLine ( CyString line )
76
{
77
	CyString first = line.GetToken ( 1, ' ' );
78
	CyString rest  = line.GetToken ( 2, -1, ' ' );
79
 
80
	if ( first == "AnotherMod:" )
81
	{
82
		m_sOtherAuthor = rest.GetToken ( 1, '|' );
83
		m_sOtherName = rest.GetToken ( 2, -1, '|' );
84
	}
85
	else if ( line == "CustomStart" )
86
		m_iPackageType = PACKAGETYPE_CUSTOMSTART;
87
	else if ( line == "PackageUpdate" )
88
		m_iPackageType = PACKAGETYPE_UPDATE;
89
	else if ( line == "Patch" )
90
		m_iPackageType = PACKAGETYPE_PATCH;
91
	else if ( line == "ForceProfile" )
92
		m_bForceProfile = true;
93
	else if ( line == "Signed" )
94
		m_bSigned = true;
95
	else if ( first == "ScriptType:" )
96
		m_sScriptType = rest;
97
	else if ( first == "ScriptTypeNew:" )
98
		m_iScriptType = rest.ToInt();
99
	else if ( first == "PackageType:" )
100
		m_iPackageType = rest.ToInt();
101
	else if ( first == "Ware:" )
102
		AddWare ( rest );
103
	else if ( (first == "WareText:") && (m_pLastWare) )
104
		AddWareText ( rest );
105
	else if ( first == "Setting:" )
106
	{
107
		SSettingType *t = AddSetting ( rest.GetToken ( 2, '|' ), rest.GetToken ( 1, '|' ).ToInt() );
108
		ConvertSetting ( t, rest.GetToken ( 3, -1, '|' ) );
109
	}
110
	else
111
		return CBaseFile::ParseValueLine ( line );
112
 
113
	return true;
114
}
115
 
116
/*
117
	Func:   CreateValuesLine
118
	Return: String - returns the full string for values
119
	Desc:   Creates a single string for all values, this is used when compressing to write to the spk file
120
*/
121
CyString CSpkFile::CreateValuesLine ()
122
{
123
	CyString values = CBaseFile::CreateValuesLine ();
124
	// combine all values together
125
	if ( (!m_sOtherAuthor.Empty()) && (!m_sOtherName.Empty()) )
126
		values += (CyString("AnotherMod: ") + m_sOtherAuthor + "|" + m_sOtherName + "\n");
127
	if ( m_bForceProfile )
128
		values += "ForceProfile\n";
129
	if ( !m_sScriptType.Empty() )
130
		values += (CyString("ScriptType: ") + m_sScriptType + "\n");
131
	values += (CyString("PackageType: ") + (long)m_iPackageType + "\n");
132
	values += (CyString("ScriptTypeNew: ") + (long)m_iScriptType + "\n");
133
 
134
	for ( SSettingType *st = m_lSettings.First(); st; st = m_lSettings.Next() )
135
		values += (CyString("Setting: ") + CyString::Number(st->iType) + "|" + st->sKey + "|" + GetSetting(st) + "\n");
136
 
137
	for ( SWares *ware = m_lWares.First(); ware; ware = m_lWares.Next() )
138
	{
139
		if ( ware->iTextID > 0 )
140
			values += CyString("Ware: ") + ware->cType + ":" + ware->iPrice + ":" + (long)ware->iSize + ":" + (long)ware->iVolumn + ":" + ware->sID + ":" + (long)ware->iNotority + ":" + (long)ware->iTextID + "," + (long)ware->iTextPage + "\n";
141
		else
142
			values += CyString("Ware: ") + ware->cType + ":" + ware->iPrice + ":" + (long)ware->iSize + ":" + (long)ware->iVolumn + ":" + ware->sID + ":" + (long)ware->iNotority + "\n";
143
		for ( SWaresText *wt = ware->lText.First(); wt; wt = ware->lText.Next() )
144
			values += CyString("WareText: ") + (long)wt->iLang + " " + wt->sName + "|" + wt->sDesc + "\n";
145
	}
146
 
147
	return values;
148
}
149
 
150
CyString CSpkFile::GetCustomScriptType (int lang)
151
{
152
	if ( !m_sScriptType.Empty() )
153
	{
154
		int max;
155
		CyString *split = m_sScriptType.SplitToken("<br>", &max);
156
		if ( max && split )
157
		{
158
			for ( int i = 1; i < max; i++ )
159
			{
160
				CyString str = split[i];
161
				int num = str.GetToken(":", 1, 1).ToInt();
162
				CyString name = str.GetToken(":", 2);
163
 
164
				if ( num == lang )
165
				{
166
					CLEANSPLIT(split, max)
167
					return name;
168
				}
169
			}
170
 
171
			CyString ret = split[0];
172
			CLEANSPLIT(split, max)
173
 
174
			return ret;
175
		}
176
		CLEANSPLIT(split, max)
177
	}
178
	return m_sScriptType;
179
}
180
 
181
bool CSpkFile::WriteHeader(FILE *id, int valueheader, int valueComprLen)
182
{
183
	fprintf ( id, "SPKCycrow;%.2f;%d;%d\n", FILEVERSION, valueheader, valueComprLen );
184
	if ( ferror(id) )
185
		return false;
186
	return true;
187
}
188
 
189
void CSpkFile::AddWareText ( CyString rest )
190
{
191
	if ( !m_pLastWare )
192
		return;
193
 
194
	SWaresText *wt = new SWaresText;
195
	wt->iLang = rest.GetToken ( 1, ' ' ).ToInt();
196
	wt->sName = rest.GetToken ( 2, -1, ' ' ).GetToken ( 1, '|' );
197
	wt->sDesc = rest.GetToken ( 2, -1, ' ' ).GetToken ( 2, -1, '|' );
198
	m_pLastWare->lText.push_back ( wt );
199
 
200
	m_bChanged = true;
201
}
202
 
203
void CSpkFile::AddWare ( CyString rest )
204
{
205
	SWares *ware = new SWares;
206
	ware->iTextID = -1;
207
	ware->iTextPage = 0;
208
	ware->cType = rest.GetToken ( 1, ':' )[0];
209
	ware->iPrice = rest.GetToken ( 2, ':' ).ToLong();
210
	ware->iSize = rest.GetToken ( 3, ':' ).ToInt();
211
	ware->iVolumn = rest.GetToken ( 4, ':' ).ToInt();
212
	ware->sID = rest.GetToken ( 5, ':' );
213
	ware->iNotority = rest.GetToken ( 6, ':' ).ToInt();
214
	if ( !rest.GetToken( 7, ':' ).Empty() )
215
	{
216
		CyString r = rest.GetToken ( 7, ':' );
217
		ware->iTextID = r.GetToken(",", 1, 1).ToInt();
218
		ware->iTextPage = r.GetToken(",", 2, 2).ToInt();
219
	}
220
	m_lWares.push_back ( ware );
221
	m_pLastWare = ware;
222
 
223
	m_bChanged = true;
224
}
225
 
226
 
227
 
228
bool CSpkFile::ReadFileToMemory ( C_File *file )
229
{
230
	if ( !file )
231
		return false;
232
 
233
	// check if data is already extracted
234
	if ( (file->GetDataSize ()) && (file->GetData()) )
235
		return true;
236
 
237
	// no file to read from
238
	if ( m_sFilename.Empty() )
239
		return false;
240
 
241
	// now open the file
242
	FILE *id = fopen ( m_sFilename.c_str(), "rb" );
243
	if ( !id )
244
		return false;
245
 
246
	// read the header
247
	GetEndOfLine ( id, NULL, false );
248
	// skip past values
249
	fseek ( id, m_SHeader.lValueCompressSize, SEEK_CUR );
250
 
251
	// read the next header
252
	GetEndOfLine ( id, NULL, false );
253
	// skip past files
254
	fseek ( id, 4, SEEK_CUR );
255
	fseek ( id, m_SHeader2.lSize, SEEK_CUR );
256
 
257
	// skip the icon file
258
	if ( m_pIconFile )
259
	{
260
		fseek ( id, 4, SEEK_CUR );
261
		fseek ( id, m_pIconFile->GetDataSize (), SEEK_CUR );
262
	}
263
 
264
	// now were in the file section
265
	// skip past each one
266
	for ( CListNode<C_File> *node = m_lFiles.Front(); node; node = node->next() )
267
	{
268
		C_File *fit = node->Data();
269
		if ( fit == file )
270
			break;
271
 
272
		fseek ( id, 4, SEEK_CUR );
273
		fseek ( id, fit->GetDataSize(), SEEK_CUR );
274
	}
275
 
276
	// now we should be at the start of the file
277
	// read the data into memory
278
	if ( !file->ReadFromFile ( id, file->GetDataSize() ) )
279
	{
280
		fclose ( id );
281
		return false;
282
	}
283
	fclose ( id );
284
 
285
	return true;
286
}
287
 
288
bool CSpkFile::CheckValidReadmes ()
289
{
290
	for ( CListNode<C_File> *node = m_lFiles.Front(); node; node = node->next() )
291
	{
292
		C_File *file = node->Data();
293
		if ( file->GetFileType() != FILETYPE_README )
294
			continue;
295
		if ( !file->CheckValidFilePointer() )
296
			continue;
297
		return true;
298
	}
299
 
300
	return false;
301
}
302
 
303
 
304
 
305
void CSpkFile::ClearWares()
306
{
307
	for ( CListNode<SWares> *node = m_lWares.Front(); node; node = node->next() )
308
	{
309
		node->Data()->lText.clear(true);
310
		node->DeleteData();
311
	}
312
	m_bChanged = true;
313
	m_lWares.clear(true);
314
}
315
 
316
SWares *CSpkFile::FindWare ( CyString id )
317
{
318
	for ( SWares *w = m_lWares.First(); w; w = m_lWares.Next() )
319
	{
320
		if ( w->sID.ToUpper() == id.ToUpper() )
321
			return w;
322
	}
323
	return NULL;
324
}
325
 
326
void CSpkFile::RemoveWare ( CyString id )
327
{
328
	for ( SWares *w = m_lWares.First(); w; w = m_lWares.Next() )
329
	{
330
		if ( w->sID.ToUpper() == id.ToUpper() )
331
		{
332
			m_lWares.RemoveCurrent ();
333
			delete w;
334
			m_bChanged = true;
335
			return;
336
		}
337
	}
338
}
339
 
340
void CSpkFile::AddWare ( SWares *ware )
341
{
342
	ware->sID.RemoveChar ( ' ' );
343
	ware->sID = ware->sID.ToUpper();
344
 
345
	SWares *newware = FindWare ( ware->sID );
346
	if ( newware )
347
		m_lWares.remove ( newware );
348
 
349
	m_lWares.push_back ( ware );
350
	m_bChanged = true;
351
}
352
 
353
void CSpkFile::AddWareText ( SWares *w, int lang, CyString name, CyString desc )
354
{
355
	SWaresText *wt;
356
	for ( wt = w->lText.First(); wt; wt = w->lText.Next() )
357
	{
358
		if ( wt->iLang == lang )
359
		{
360
			wt->sDesc = desc;
361
			wt->sName = name;
362
			return;
363
		}
364
	}
365
 
366
	wt = new SWaresText;
367
	wt->iLang = lang;
368
	wt->sName = name;
369
	wt->sDesc = desc;
370
 
371
	w->lText.push_back ( wt );
372
	m_bChanged = true;
373
}
374
 
375
 
376
void CSpkFile::ClearWareText ( CyString id )
377
{
378
	SWares *w = FindWare ( id );
379
	ClearWareText ( w );
380
}
381
 
382
void CSpkFile::ClearWareText ( SWares *w )
383
{
384
	if ( !w ) return;
385
 
386
	w->lText.clear(true);
387
	m_bChanged = true;
388
}
389
 
390
void CSpkFile::RemoveWareText ( CyString wid, int lang )
391
{
392
	SWares *w = FindWare ( wid );
393
	if ( w )
394
	{
395
		for ( SWaresText *wt = w->lText.First(); wt; wt = w->lText.Next() )
396
		{
397
			if ( wt->iLang == lang )
398
			{
399
				w->lText.RemoveCurrent();
400
				m_bChanged = true;
401
				delete wt;
402
				break;
403
			}
404
		}
405
	}
406
}
407
 
408
int CSpkFile::CheckValidCustomStart ()
409
{
410
 
411
	for ( CListNode<C_File> *node = m_lFiles.Front(); node; node = node->next() )
412
	{
413
		C_File *file = node->Data();
414
		if ( file->GetFileType() != FILETYPE_SCRIPT )
415
			continue;
416
 
417
		CyString basename = file->GetName().GetToken ( 1, file->GetName().NumToken('.') - 1, '.' );
418
		if ( basename.ToLower().Right(15) == ".initplayership" )
419
			return 0;
420
	}
421
	if ( !IsAnotherMod() )
422
		return 1;
423
	else
424
		return 2;
425
}
426
 
427
bool CSpkFile::UpdateSigned (bool updateFiles)
428
{
429
	// check for any custom wares
430
	// patch mods and custom starts are also not signed
431
	if ( (!m_lWares.empty()) || (this->IsPatch()) || (this->IsCustomStart()) )
432
	{
433
		m_bSigned = false;
434
		return false;
435
	}
436
 
437
	return CBaseFile::UpdateSigned(updateFiles);
438
}
439
 
440
SSettingType *CSpkFile::AddSetting ( CyString key, int type )
441
{
442
	key.RemoveChar ( '|' );
443
	SSettingType *t;
444
	for ( t = m_lSettings.First(); t; t = m_lSettings.Next() )
445
	{
446
		if ( t->sKey.upper() == key.lower() )
447
			return NULL;
448
	}
449
 
450
	switch ( type )
451
	{
452
		case SETTING_STRING:
453
			t = new SSettingString;
454
			break;
455
		case SETTING_INTEGER:
456
			t = new SSettingInteger;
457
			break;
458
		case SETTING_CHECK:
459
			t = new SSettingCheck;
460
			break;
461
	}
462
 
463
	if ( !t )
464
		return NULL;
465
 
466
	t->sKey = key;
467
	t->iType = type;
468
 
469
	m_lSettings.push_back ( t );
470
	m_bChanged = true;
471
 
472
	return t;
473
}
474
 
475
void CSpkFile::ConvertSetting ( SSettingType *t, CyString set )
476
{
477
	if ( !t )
478
		return;
479
 
480
	switch ( t->iType )
481
	{
482
		case SETTING_STRING:
483
			((SSettingString *)t)->sValue = set;
484
			break;
485
		case SETTING_INTEGER:
486
			((SSettingInteger *)t)->iValue = set.ToInt();
487
			break;
488
		case SETTING_CHECK:
489
			((SSettingCheck *)t)->bValue = set.ToBool();
490
			break;
491
	}
492
}
493
CyString CSpkFile::GetSetting ( SSettingType *t )
494
{
495
	if ( !t )
496
		return "";
497
 
498
	switch ( t->iType )
499
	{
500
		case SETTING_STRING:
501
			return ((SSettingString *)t)->sValue;
502
		case SETTING_INTEGER:
503
			return CyString::Number(((SSettingInteger *)t)->iValue);
504
		case SETTING_CHECK:
505
			return (((SSettingInteger *)t)->iValue) ? "1" : "0";
506
	}
507
 
508
	return "";
509
}
510
 
511
void CSpkFile::ClearSettings ()
512
{
513
	m_lSettings.clear(true);
514
	m_bChanged = true;
515
}
516
 
517
 
518
bool CSpkFile::IsMatchingMod ( CyString mod )
519
{
520
	for ( CListNode<C_File> *node = m_lFiles.Front(); node; node = node->next() )
521
	{
522
		C_File *file = node->Data();
523
		if ( file->GetFileType() != FILETYPE_MOD )
524
			continue;
525
 
526
		if ( file->IsFakePatch() )
527
			continue;
528
 
529
		CyString filename = file->GetBaseName();
530
		if ( filename.lower() == mod.lower() )
531
			return true;
532
	}
533
	return false;
534
}
535
 
536
CyString CSpkFile::GetScriptTypeString(int lang)
537
{
538
	int iType = m_iScriptType;
539
 
540
	if ( this->IsLibrary() )
541
		return "Library";
542
	else if ( this->IsPackageUpdate() )
543
		return "Package Update";
544
	else if ( this->IsCustomStart() )
545
		return "Custom Start";
546
	else if ( this->IsPatch() )
547
		return "Patch";
548
	else if ( m_iScriptType == SCRIPTTYPE_CUSTOM )
549
	{
550
		CyString type = this->GetCustomScriptType(lang);
551
		if ( !type.Empty() )
552
			return type;
553
		iType = -1;
554
	}
555
 
556
	if (iType == -1)  // no script type
557
	{
558
		if ( this->IsFakePatch() )
559
			return "Fake Patch";
560
	}
561
 
562
	CyString sType = CSpkFile::GetScriptTypeStringStatic(m_iScriptType);
563
 
564
	if ( sType.Empty() )
565
		return "Other";
566
 
567
	return sType;	
568
}
569
 
570
int CSpkFile::ConvertScriptType(CyString sType)
571
{
572
	for ( int i = 0; i < SCRIPTTYPE_MAX; i++ )
573
	{
574
		if ( sType.Compare(CSpkFile::GetScriptTypeStringStatic(i)) )
575
			return i;
576
	}
577
 
578
	return -1;
579
}
580
 
581
CyString CSpkFile::GetScriptTypeStringStatic(int type)
582
{
583
	switch ( type )
584
	{
585
		case SCRIPTTYPE_CUSTOM:
586
			return "Custom";
587
		case SCRIPTTYPE_NAVIGATION:
588
			return "Navigation";
589
		case SCRIPTTYPE_COMBAT:
590
			return "Combat";
591
		case SCRIPTTYPE_MISSION:
592
			return "Mission";
593
		case SCRIPTTYPE_ALPLUGIN:
594
			return "AL Plugin";
595
		case SCRIPTTYPE_HOTKEY:
596
			return "Hotkey";
597
		case SCRIPTTYPE_SHIPUPGRADE:
598
			return "Ship Upgrade";
599
		case SCRIPTTYPE_SHIPCOMMAND:
600
			return "Ship Command";
601
		case SCRIPTTYPE_STATIONCOMMAND:
602
			return "Station Command";
603
		case SCRIPTTYPE_FLEET:
604
			return "Fleet Management";
605
		case SCRIPTTYPE_TRADE:
606
			return "Trade";
607
		case SCRIPTTYPE_PIRACY:
608
			return "Piracy";
609
		case SCRIPTTYPE_CHEAT:
610
			return "Cheat";
611
		case SCRIPTTYPE_EXTENSION:
612
			return "Extension Mods";
613
		case SCRIPTTYPE_REBALANCE:
614
			return "Rebalance";
615
		case SCRIPTTYPE_FIX:
616
			return "Vanilla Fix";
617
		case SCRIPTTYPE_GENERALMOD:
618
			return "General Mod";
619
		case SCRIPTTYPE_TOTAL:
620
			return "Totel Conversion";
621
		case SCRIPTTYPE_WINGCOMMAND:
622
			return "Wing Command";
623
	}
624
 
625
	return "Other";
626
}
627
 
628
bool CSpkFile::LoadPackageData(CyString first, CyString rest)
629
{
630
	if ( first.Compare("ScriptType") )
631
	{
632
		if ( rest.Compare("Library") || rest.Compare("Library Script") )
633
			this->SetLibrary();
634
		else if ( rest.Compare("Update") || rest.Compare("Package Update") || rest.Compare("Mod Update") )
635
			this->SetPackageUpdate();
636
		else if ( rest.Compare("Start") || rest.Compare("Custom Start") )
637
			this->SetCustomStart();
638
		else if ( rest.Compare("Patch") || rest.Compare("Patch Mod") )
639
			this->SetPatch();
640
		else
641
		{
642
			int check = rest.ToInt();
643
			if ( check || rest == "0" )
644
				m_iScriptType = check;
645
			else
646
			{
647
				m_iScriptType = CSpkFile::ConvertScriptType(rest);
648
				if ( m_iScriptType == -1 )
649
					m_sScriptType = rest;
650
			}
651
		}
652
	}
653
	else if ( first.Compare("AnotherMod") )
654
	{
655
		m_sOtherName = rest.GetToken("|", 1, 1);
656
		m_sOtherAuthor = rest.GetToken("|", 2);
657
	}
658
	else if ( first.Compare("WareName") || first.Compare("WareDesc") )
659
	{
660
		// find the ware to use
661
		SWares *useWare = m_pLastWare;
662
		CyString id = rest.GetToken(" ", 1, 1);
663
		for ( CListNode<SWares> *wNode = m_lWares.Front(); wNode; wNode = wNode->next() )
664
		{
665
			if ( wNode->Data()->sID.Compare(id) )
666
			{
667
				useWare = wNode->Data();
668
				break;
669
			}
670
		}
671
 
672
		// check if we have the id already
673
		if ( useWare )
674
		{
675
			int lang = rest.GetToken(" ", 2, 2).ToInt();
676
			SWaresText *wt = NULL;
677
			for ( CListNode<SWaresText> *tNode = useWare->lText.Front(); tNode; tNode = tNode->next() )
678
			{
679
				if ( tNode->Data()->iLang == lang )
680
				{
681
					wt = tNode->Data();
682
					break;
683
				}
684
			}
685
 
686
			if ( !wt )
687
			{
688
				wt = new SWaresText;
689
				wt->iLang = lang;
690
				useWare->lText.push_back(wt);
691
			}
692
 
693
			if ( first.Compare("WareName") )
694
				wt->sName = rest.GetToken(" ", 3);
695
			else
696
				wt->sDesc = rest.GetToken(" ", 3);
697
		}
698
	}
699
	else if ( first.Left(4).Compare("Ware") )
700
	{
701
		SWares *ware = new SWares;
702
		ware->iTextID = -1;
703
		ware->iTextPage = 0;
704
		ware->cType = first[4];
705
		ware->iPrice = rest.GetToken ( " ", 2, 2 ).ToLong();
706
		ware->iSize = rest.GetToken ( " ", 3, 3 ).ToInt();
707
		ware->iVolumn = rest.GetToken ( " ", 4, 4 ).ToInt();
708
		ware->sID = rest.GetToken ( " ", 1, 1 );
709
		ware->iNotority = rest.GetToken ( " ", 5, 5 ).ToInt();
710
		if ( !rest.GetToken(" ", 6, 6).Empty() )
711
		{
712
			ware->iTextID = rest.GetToken ( " ", 6, 6 ).GetToken(",", 2, 2).ToInt();
713
			ware->iTextPage = rest.GetToken ( " ", 6, 6 ).GetToken(",", 1, 1).ToInt();
714
		}
715
		m_lWares.push_back ( ware );
716
		m_pLastWare = ware;
717
	}
718
 
719
	else if ( CBaseFile::LoadPackageData(first, rest) )
720
		return true;
721
	else
722
		return false;
723
 
724
	return true;
725
}
726
 
727
bool CSpkFile::GeneratePackagerScript(bool wildcard, CyStringList *list, bool datafile)
728
{
729
	if ( !CBaseFile::GeneratePackagerScript(wildcard, list, datafile) )
730
		return false;
731
 
732
	list->PushBack("# Script Type, the type of package file, some are special types, others are just for show");
733
	if ( this->IsLibrary() )
734
		list->PushBack("ScriptType: Library");
735
	else if ( this->IsPackageUpdate() )
736
		list->PushBack("ScriptType: Package Update");
737
	else if ( this->IsCustomStart() )
738
		list->PushBack("ScriptType: Custom Start");
739
	else if ( this->IsPatch() )
740
		list->PushBack("ScriptType: Patch");
741
	else
742
		list->PushBack(CyString("ScriptType: ") + this->GetScriptTypeString(44));
743
	list->PushBack("");
744
 
745
	if ( this->IsAnotherMod() )
746
	{
747
		list->PushBack("# For another mod/package, this is a child package");
748
		list->PushBack(CyString("AnotherMod: ") + m_sOtherName + "|" + m_sOtherAuthor);
749
		list->PushBack("");
750
	}
751
 
752
	if ( !m_lWares.empty() )
753
	{
754
		list->PushBack("# Custom Wares, Ware<type>: <id> <price> <size> <volumn> <notority>");
755
		for ( CListNode<SWares> *node = m_lWares.Front(); node; node = node->next() )
756
		{
757
			SWares *w = node->Data();
758
			if ( w->iTextID > 0 )
759
				list->PushBack(CyString("Ware") + (char)w->cType + ": " + w->sID + " " + (long)w->iPrice + " " + (long)w->iSize + " " + (long)w->iVolumn + " " + (long)w->iNotority + " " + (long)w->iTextPage + "," + (long)w->iTextID);
760
			else
761
				list->PushBack(CyString("Ware") + (char)w->cType + ": " + w->sID + " " + (long)w->iPrice + " " + (long)w->iSize + " " + (long)w->iVolumn + " " + (long)w->iNotority);
762
			for ( CListNode<SWaresText> *wNode = w->lText.Front(); wNode; wNode = wNode->next() )
763
			{
764
				SWaresText *wt = wNode->Data();
765
				if ( !wt->sName.Empty() )
766
					list->PushBack(CyString("WareName: ") + w->sID + " " + (long)wt->iLang + " " + wt->sName);
767
				if ( !wt->sDesc.Empty() )
768
					list->PushBack(CyString("WareDesc: ") + w->sID + " " + (long)wt->iLang + " " + wt->sDesc);
769
			}
770
			list->PushBack("");
771
		}
772
	}
773
 
774
	if ( !datafile )
775
	{
776
		if ( !CBaseFile::GeneratePackagerScriptFile(wildcard, list) )
777
			return false;
778
	}
779
 
780
	return true;
781
 
782
}
783
 
784
CyString CSpkFile::GetWareText(SWares *w, int lang)
785
{
786
	// return the text page if being used
787
	if ( w->iTextID > 0 && w->iTextPage > 0 )
788
		return CyString("{") + (long)w->iTextPage + "," + (long)w->iTextID + "}";
789
 
790
	CyString name;
791
	for ( CListNode<SWaresText> *wt = w->lText.Front(); wt; wt = wt->next() )
792
	{
793
		if ( wt->Data()->sName.Empty() )
794
			continue;
795
		if ( wt->Data()->iLang == lang )
796
			name = wt->Data()->sName;
797
		else if ( name.Empty() && wt->Data()->iLang == 44 )
798
			name = wt->Data()->sName;
799
		else if ( name.Empty() )
800
			name = wt->Data()->sName;
801
	}
802
 
803
	return name;
804
}
805
CyString CSpkFile::GetWareDesc(SWares *w, int lang)
806
{
807
	// return the text page if being used
808
	if ( w->iTextID > 0 && w->iTextPage > 0 )
809
		return CyString("{") + (long)w->iTextPage + "," + ((long)w->iTextID + 1) + "}";
810
 
811
	CyString name;
812
	for ( CListNode<SWaresText> *wt = w->lText.Front(); wt; wt = wt->next() )
813
	{
814
		if ( wt->Data()->sDesc.Empty() )
815
			continue;
816
 
817
		if ( wt->Data()->iLang == lang )
818
			name = wt->Data()->sDesc;
819
		else if ( name.Empty() && wt->Data()->iLang == 44 )
820
			name = wt->Data()->sDesc;
821
		else if ( name.Empty() )
822
			name = wt->Data()->sDesc;
823
	}
824
 
825
	return name;
826
}
827
 
828
CyString CSpkFile::GetCustomStartName()
829
{
830
	if ( !this->IsCustomStart() )
831
		return NullString;
832
 
833
	// else find the custom start script
834
	C_File *file = NULL;
835
	for ( file = this->GetFirstFile(FILETYPE_SCRIPT); file; file = this->GetNextFile(file) )
836
	{
837
		if ( file->GetFilename().IsIn("initplayership")	&& file->GetFilename().GetToken(".", 1, 1).Compare("galaxy") )
838
			break;
839
	}
840
 
841
	if ( !file )
842
		return NullString;
843
 
844
	return file->GetFilename().GetToken(".", 2, 2);
845
}
846
 
847
void CSpkFile::MergePackage(CBaseFile *base)
848
{
849
	// update version information
850
	m_sVersion = base->GetVersion();
851
	m_sCreationDate = base->GetCreationDate();
852
	m_iPluginType = base->GetPluginType();
853
 
854
	// update possible changes
855
	if ( base->GetType() == TYPE_SPK )
856
	{
857
		CSpkFile *spk = (CSpkFile *)base;
858
		m_bForceProfile = spk->IsForceProfile();
859
 
860
		// add any new wares
861
		if ( spk->AnyWares() )
862
		{
863
			for ( CListNode<SWares> *node = spk->GetWaresList()->Front(); node; node = node->next() )
864
				this->AddWare(node->Data());
865
			spk->GetWaresList()->clear(); // remove wares so they aren't deleted
866
		}
867
 
868
		// add any settings
869
		if ( spk->AnySettings() )
870
		{
871
			for ( CListNode<SSettingType> *node = spk->GetSettingsList()->Front(); node; node = node->next() )
872
				this->AddSetting(node->Data()->sKey, node->Data()->iType);
873
		}
874
 
875
		if ( !spk->GetOtherName().Empty() )
876
		{
877
			m_sOtherName = spk->GetOtherName();
878
			m_sOtherAuthor = spk->GetOtherAuthor();
879
		}
880
	}
881
 
882
	// copy settings from base class
883
	m_iGameChanging = base->GetGameChanging();
884
	m_iRecommended = base->GetRecommended();
885
	m_iEaseOfUse = base->GetEaseOfUse();
886
 
887
	for ( CListNode<SGameCompat> *gNode = base->GetGameCompatabilityList()->Front(); gNode; gNode = gNode->next() ) {
888
		if ( !gNode->Data()->sVersion.Empty() )
889
			this->AddGameCompatability(gNode->Data()->iGame, gNode->Data()->sVersion);
890
		else
891
			this->AddGameCompatability(gNode->Data()->iGame, CyString::Number(gNode->Data()->iVersion));
892
	}
893
 
894
	if ( !base->GetWebAddress().Empty() )
895
		m_sWebAddress = base->GetWebAddress();
896
	if ( !base->GetWebSite().Empty() )
897
		m_sWebSite = base->GetWebSite();
898
	if ( !base->GetEmail().Empty() )
899
		m_sEmail = base->GetEmail();
900
	if ( !base->GetForumLink().Empty() )
901
		m_sForumLink = base->GetForumLink();
902
 
903
	m_sDescription = base->GetDescription();
904
 
905
	// copy over needed librarys
906
	for ( CListNode<SNeededLibrary> *lNode = base->GetNeededLibraries()->Front(); lNode; lNode = lNode->next() )
907
		this->AddNeededLibrary(lNode->Data()->sName, lNode->Data()->sAuthor, lNode->Data()->sMinVersion);
908
 
909
	// web mirror address, add any new ones
910
	for ( SStringList *str = base->GetWebMirrors()->Head(); str; str = str->next )
911
		this->AddWebMirror(str->str);
912
 
913
	// copy over any install text
914
	for ( CListNode<SInstallText> *iNode = base->GetInstallTextList()->Front(); iNode; iNode = iNode->next() )
915
	{
916
		if ( !iNode->Data()->sAfter.Empty() )
917
			this->AddInstallAfterText(iNode->Data()->iLanguage, iNode->Data()->sAfter);
918
		if ( !iNode->Data()->sBefore.Empty() )
919
			this->AddInstallBeforeText(iNode->Data()->iLanguage, iNode->Data()->sBefore);
920
	}
921
 
922
	for ( CListNode<SInstallText> *iNode = base->GetUninstallTextList()->Front(); iNode; iNode = iNode->next() )
923
	{
924
		if ( !iNode->Data()->sAfter.Empty() )
925
			this->AddUninstallAfterText(iNode->Data()->iLanguage, iNode->Data()->sAfter);
926
		if ( !iNode->Data()->sBefore.Empty() )
927
			this->AddUninstallBeforeText(iNode->Data()->iLanguage, iNode->Data()->sBefore);
928
	}
929
 
930
	// copy over package names
931
	for ( CListNode<SNames> *nNode = base->GetNamesList()->Front(); nNode; nNode = nNode->next() )
932
		this->AddLanguageName(nNode->Data()->iLanguage, nNode->Data()->sName);
933
 
934
	// finally do all the files
935
	for ( CListNode<C_File> *node = base->GetFileList()->Front(); node; node = node->next() )
936
	{
937
		C_File *f = node->Data();
938
		// if it exists, remove the old
939
		for ( CListNode<C_File> *thisNode = m_lFiles.Front(); thisNode; thisNode = thisNode->next() )
940
		{
941
			if ( thisNode->Data()->GetFileType() == f->GetFileType() && thisNode->Data()->GetFilename().Compare(f->GetFilename()) && thisNode->Data()->GetDir().Compare(f->GetDir()) )
942
			{
943
				m_lFiles.remove(thisNode);
944
				break;
945
			}
946
		}
947
 
948
		m_lFiles.push_back(f);
949
	}
950
 
951
	// clear the files so we dont delete them later
952
	base->GetFileList()->clear();
953
}
7 cycrow 954
 
8 cycrow 955
unsigned char *CSpkFile::_convert_uncompressFile(const Utils::String &sOldFilename, int *pLen)
7 cycrow 956
{
957
	// firstcheck if the file exists
8 cycrow 958
	FILE *id = fopen(sOldFilename.c_str(), "rb" );
7 cycrow 959
	if ( !id ) {
8 cycrow 960
		CLog::logf("Unable to open file: %s", ((CyString)sOldFilename).c_str());
7 cycrow 961
		return false;
962
	}
963
 
964
	// read the first 3 charaters to check if its using the original "HiP" compression
965
	CyString check = (char)fgetc ( id );
966
	check += (char)fgetc ( id );
967
	check += (char)fgetc ( id );
968
 
969
	CyString removeFile;
970
 
971
	unsigned char *uncomprData = NULL;
972
	unsigned char *data = NULL;
973
	long len = 0, newlen = 0;
974
 
975
	if ( check == "HiP" ) {
976
		fclose ( id );
977
		bool opened = false;
978
		if ( DecompressFile ( (char *)((CyString)sOldFilename).c_str(), "uncompr.tmp" ) ) {
979
			removeFile = "uncompr.tmp";
980
			id = fopen ( "uncompr.tmp", "r" );
981
			if ( id )
982
				opened = true;
983
		}
984
 
985
		if ( !opened ) {
8 cycrow 986
			CLog::log("Unable to uncompress file, exiting...");
7 cycrow 987
			return false;
988
		}
989
 
8 cycrow 990
		CLog::log("* Reading file into memory...");
7 cycrow 991
		// get file length
992
		fseek ( id, 0, SEEK_END );
993
		len = ftell ( id );
994
 
995
		// move back to beginning
996
		fseek ( id, 0, SEEK_SET );
997
 
998
		// read the data from file into memory
999
		uncomprData = new unsigned char[len + 1];
1000
		fread ( uncomprData, sizeof(unsigned char), len, id );
1001
 
1002
		newlen = len;
1003
	}
1004
	else
1005
	{
8 cycrow 1006
		CLog::log("* Reading file into memory...");
7 cycrow 1007
		// get file length
1008
		fseek ( id, 0, SEEK_END );
1009
		len = ftell ( id );
1010
 
1011
		// move back to beginning
1012
		fseek ( id, 0, SEEK_SET );
1013
 
1014
		// read the data from file into memory
1015
		data = new unsigned char[len + 1];
1016
		fread ( data, sizeof(unsigned char), len, id );
1017
 
1018
		// uncompress the file (currently only 7zip compression)
8 cycrow 1019
		CLog::log("* Uncompressing file...");
7 cycrow 1020
		newlen = len;
1021
	#ifdef _INCLUDE7ZIP
1022
		uncomprData = LZMADecodeData ( data, len, newlen, progress );
1023
	#else
1024
		uncomprData = LZMADecode_C ( (unsigned char *)data, len, (size_t*)&newlen, NULL );
1025
	#endif
1026
	}
1027
 
1028
	*pLen = newlen;
8 cycrow 1029
 
1030
	if ( removeFile.Empty() ) {
1031
		CFileIO(removeFile).Remove();
1032
	}
7 cycrow 1033
 
1034
	return uncomprData;
1035
}
1036
 
8 cycrow 1037
Utils::String CSpkFile::_convert_fileEndString(const Utils::String &sFile)
7 cycrow 1038
{
8 cycrow 1039
	if ( sFile.Compare("Text") )
7 cycrow 1040
		return "-- End of Script --";
8 cycrow 1041
	else if ( sFile.Compare("Uninstall") )
7 cycrow 1042
		return "-- End of Uninstall --";
8 cycrow 1043
	else if ( sFile.Compare("Readme") )
7 cycrow 1044
		return "-- End of Readme --";
8 cycrow 1045
	else if ( sFile.Compare("Map") )
7 cycrow 1046
		return "-- End of Map --";
8 cycrow 1047
	else if ( sFile.Compare("Mod") || sFile.Compare("Extra") || sFile.Compare("Screen") || sFile.Compare("Sound") )
7 cycrow 1048
		return "";
1049
	return "-- End of Script --";
1050
}
1051
 
8 cycrow 1052
int CSpkFile::_convert_fileType(const Utils::String &sFile)
7 cycrow 1053
{
8 cycrow 1054
	if ( sFile.Compare("Text") )
7 cycrow 1055
		return FILETYPE_TEXT;
8 cycrow 1056
	else if ( sFile.Compare("Uninstall") )
7 cycrow 1057
		return FILETYPE_UNINSTALL;
8 cycrow 1058
	else if ( sFile.Compare("Readme") )
7 cycrow 1059
		return FILETYPE_README;
8 cycrow 1060
	else if ( sFile.Compare("Map") )
7 cycrow 1061
		return FILETYPE_MAP;
8 cycrow 1062
	else if ( sFile.Compare("Mod") )
7 cycrow 1063
		return FILETYPE_MOD;
8 cycrow 1064
	else if ( sFile.Compare("Extra") )
7 cycrow 1065
		return FILETYPE_EXTRA;
8 cycrow 1066
	else if ( sFile.Compare("Screen") )
7 cycrow 1067
		return FILETYPE_SCREEN;
8 cycrow 1068
	else if ( sFile.Compare("Sound") )
7 cycrow 1069
		return FILETYPE_SOUND;
1070
 
1071
	return FILETYPE_SCRIPT;
1072
}
1073
 
8 cycrow 1074
void CSpkFile::_convert_parse(const Utils::String &sCmd, const Utils::String &sRest, bool bVerbose)
7 cycrow 1075
{
1076
	if ( sCmd == "Name:" )
1077
	{
1078
		this->SetName ( sRest );
8 cycrow 1079
		if ( bVerbose ) CLog::logf( "\tScript Name: %s", sRest.c_str() );
7 cycrow 1080
	}
1081
	else if ( sCmd == "Author:" )
1082
	{
1083
		this->SetAuthor ( sRest );
8 cycrow 1084
		if ( bVerbose ) CLog::logf( "\tScript Author: %s", sRest.c_str() );
7 cycrow 1085
	}
1086
	else if ( sCmd == "CustomStart" )
1087
	{
1088
		this->SetCustomStart();
8 cycrow 1089
		if ( bVerbose ) CLog::logf( "\tPackage is a custom start!!" );
7 cycrow 1090
	}
1091
	else if ( sCmd == "AnotherMod:" )
1092
	{
8 cycrow 1093
		this->SetAnotherMod(sRest.token("|", 1), sRest.tokens("|", 2));
1094
		if ( bVerbose ) CLog::logf( "\tFor another Mod, Name: %s, Author: %s", this->GetOtherName().c_str(), this->GetOtherAuthor().c_str() );
7 cycrow 1095
	}
1096
	else if ( sCmd == "PATCH" )
1097
	{
1098
		this->SetPatch();
8 cycrow 1099
		if ( bVerbose ) CLog::logf("\tPackage is a Patch Mod!!" );
7 cycrow 1100
	}
1101
	else if ( sCmd == "Version:" )
1102
	{
1103
		this->SetVersion ( sRest );
8 cycrow 1104
		if ( bVerbose ) CLog::logf("\tScript Version: %s", sRest.c_str() );
7 cycrow 1105
	}
1106
	else if ( sCmd == "Date:" )
1107
	{
1108
		this->SetCreationDate ( sRest );
8 cycrow 1109
		if ( bVerbose ) CLog::logf("\tScript Creation Date: %s", sRest.c_str() );
7 cycrow 1110
	}
1111
	else if ( sCmd == "Desc:" )
1112
	{
8 cycrow 1113
		this->SetDescription(sRest.findReplace("<br>", "\n") );
1114
		if ( bVerbose ) CLog::logf("\tScript Description: %s", this->GetDescription().c_str() );
7 cycrow 1115
	}
1116
	else if ( sCmd == "WebAddress:" )
1117
	{
1118
		this->SetWebAddress ( sRest );
8 cycrow 1119
		if ( bVerbose ) CLog::logf("\tWeb Address: %s", sRest.c_str() );
7 cycrow 1120
	}
1121
	else if ( sCmd == "WebMirror1:" )
1122
	{
1123
		this->AddWebMirror(sRest);
8 cycrow 1124
		if ( bVerbose ) CLog::logf("\tWeb Mirror Address: %s", sRest.c_str() );
7 cycrow 1125
	}
1126
	else if ( sCmd == "WebMirror2:" )
1127
	{
1128
		this->AddWebMirror(sRest);
8 cycrow 1129
		if ( bVerbose ) CLog::logf("\tWeb Mirror Address: %s", sRest.c_str() );
7 cycrow 1130
	}
1131
 
1132
	else if ( sCmd == "ScriptType:" )
8 cycrow 1133
		this->SetScriptType ( CyString(sRest) );
7 cycrow 1134
	else if ( sCmd == "WebSite:" )
1135
	{
1136
		this->SetWebSite ( sRest );
8 cycrow 1137
		if ( bVerbose ) CLog::logf("\tWeb Site: %s", sRest.c_str() );
7 cycrow 1138
	}
1139
	else if ( sCmd == "Email:" )
1140
	{
1141
		this->SetEmail ( sRest );
8 cycrow 1142
		if ( bVerbose ) CLog::logf("\tAuthor Email Address: %s", sRest.c_str() );
7 cycrow 1143
	}
1144
	else if ( sCmd == "GameVersion:" )
1145
	{
1146
		//TODO: fix this for new game version
1147
		/*
1148
		int version = sRest.ToInt();
1149
		if ( version == 0 )
1150
			this->SetGameVersion ( 1 );
1151
		else if (version == 1 )
1152
			this->SetGameVersion ( 0 );
1153
		else
1154
			this->SetGameVersion ( version );
8 cycrow 1155
		if ( bVerbose ) CLog::logf( "\tGame Version: %d", this->GetGameVersion () );
7 cycrow 1156
		*/
1157
	}
1158
 
1159
	else if ( sCmd == "Ware:" )
1160
	{
1161
		this->AddWare ( sRest );
8 cycrow 1162
		if ( bVerbose ) CLog::logf( "\tAdding Custom Ware" );
7 cycrow 1163
	}
1164
	else if ( sCmd == "WareText:" )
1165
		this->AddWareText ( sRest );
1166
	else if ( sCmd == "UninstallAfter:" )
8 cycrow 1167
		this->AddUninstallAfterText(sRest.token(" ", 1).toLong(), sRest.tokens(" ", 2));
7 cycrow 1168
	else if ( sCmd == "UninstallBefore:" )
8 cycrow 1169
		this->AddUninstallBeforeText(sRest.token(" ", 1).toLong(), sRest.tokens(" ", 2));
7 cycrow 1170
	else if ( sCmd == "InstallAfter:" )
8 cycrow 1171
		this->AddInstallAfterText(sRest.token(" ", 1).toLong(), sRest.tokens(" ", 2));
7 cycrow 1172
	else if ( sCmd == "InstallBefore:" )
8 cycrow 1173
		this->AddInstallBeforeText(sRest.token(" ", 1).toLong(), sRest.tokens(" ", 2));
7 cycrow 1174
	else if ( sCmd == "ScriptName:" )
1175
	{
8 cycrow 1176
		Utils::String lang = sRest.token(":", 1);
1177
		Utils::String name = sRest.tokens(":", 2);
1178
		this->AddLanguageName(lang.toLong(), name);
1179
		if ( bVerbose ) CLog::logf( "\tScript Name Language (%s) %s", lang.c_str(), name.c_str() );
7 cycrow 1180
	}
1181
}
1182
 
8 cycrow 1183
Utils::String CSpkFile::_convert_parseFilename(const Utils::String &sRest, float fVersion, Utils::String *pDir)
7 cycrow 1184
{
8 cycrow 1185
	Utils::String sFilename;
7 cycrow 1186
 
1187
	if ( fVersion >= 3.00f )
8 cycrow 1188
		sFilename = sRest.tokens(" ", 3);
7 cycrow 1189
	else if ( fVersion >= 2.00f )
8 cycrow 1190
		sFilename = sRest.tokens(" ", 2);
7 cycrow 1191
	else
1192
		sFilename = sRest;
1193
 
8 cycrow 1194
	if ( sFilename.isin("<br>") ) {
1195
		sFilename = sFilename.findReplace("<br>", "|");
7 cycrow 1196
		if ( sFilename[0] == '|' ) {
8 cycrow 1197
			sFilename = sFilename.token("|", 1);
7 cycrow 1198
		}
1199
		else {
8 cycrow 1200
			*pDir = sFilename.token("|", 1);
1201
			sFilename = sFilename.tokens("|", 2);
7 cycrow 1202
		}
1203
	}
1204
 
1205
	return sFilename;
1206
}
1207
 
8 cycrow 1208
unsigned char *CSpkFile::_convert_parseFile(const Utils::String &sCmd, const Utils::String &sRest, float fVersion, unsigned char *d, bool bVerbose )
7 cycrow 1209
{
8 cycrow 1210
	bool bShared = (sCmd.left(9) == "$$$Shared") ? true : false;
1211
	Utils::String sFile = sCmd.right(-3).left(-1);
1212
	Utils::String sEnd = this->_convert_fileEndString(sFile);
7 cycrow 1213
	int iType = this->_convert_fileType(sFile);
1214
 
1215
	// convert the filename and directory
8 cycrow 1216
	Utils::String dir, filename = _convert_parseFilename(sRest, fVersion, &dir);
7 cycrow 1217
 
1218
	// get the size and time
1219
	long time = 0, size = 0;
8 cycrow 1220
	if ( fVersion >= 2.00f ) time = sRest.token(" ", 1).toLong();
1221
	if ( fVersion >= 3.00f ) size = sRest.token(" ", 2).toLong();
7 cycrow 1222
	bool binaryRead = (CFileIO(filename).CheckFileExtension("PCK")) ? true : false;
8 cycrow 1223
	if ( sEnd.empty() ) binaryRead = true;
7 cycrow 1224
 
1225
	C_File *file = new C_File ();
1226
 
1227
	if ( bVerbose )
1228
	{
1229
		if ( bShared )
1230
			CLog::logf( "\tFound %s File (Shared): %s, Reading...", sFile.c_str(), filename.c_str() );
1231
		else
1232
			CLog::logf( "\tFound %s File: %s, Reading...", sFile.c_str(), filename.c_str() );
1233
	}
1234
 
1235
	// read the data
1236
	if ( binaryRead )
1237
	{
1238
		file->ReadFromData ( (char *)d, size );
1239
		d += size;
1240
	}
1241
	else
1242
	{
1243
		CyString readData;
1244
		d = LineByLineRead ( d, sEnd, &readData );
1245
		file->ReadFromData ( (char *)readData.c_str(), (long)readData.Length() );
1246
	}
1247
 
1248
	// setup the file
1249
	file->SetName ( filename );
1250
	file->SetFileType ( iType );
1251
	file->SetShared ( bShared );
1252
	file->SetCreationTime ( time );
8 cycrow 1253
	if ( !dir.empty() )
7 cycrow 1254
		file->SetDir ( dir );
1255
 
1256
	this->AddFile ( file );
1257
 
8 cycrow 1258
	CLog::logf( "Size: %s", file->GetDataSizeString().c_str() );
7 cycrow 1259
 
1260
	return d;
1261
}
1262
 
9 cycrow 1263
CSpkFile *CSpkFile::convertFromOld(const Utils::String &sOldFilename)
1264
{
1265
	// check if the old file is actually in an old format
1266
	int ret = CBaseFile::CheckFile ( sOldFilename );
1267
	if ( ret != SPKFILE_INVALID && ret != SPKFILE_OLD ) {
1268
		return NULL;
1269
 	}
1270
 
1271
	CSpkFile *pSpkFile = new CSpkFile();
1272
	if ( !pSpkFile->convertOld(sOldFilename) ) {
1273
		delete pSpkFile;
1274
		return NULL;
1275
	}
1276
 
1277
	return pSpkFile;
1278
}
1279
 
8 cycrow 1280
bool CSpkFile::convertOld(const Utils::String &sOldFilename)
7 cycrow 1281
{
1282
	// check if the old file is actually in an old format
1283
	int ret = CBaseFile::CheckFile ( sOldFilename );
1284
	if ( ret != SPKFILE_INVALID && ret != SPKFILE_OLD ) {
1285
		return false;
1286
 	}
1287
 
1288
	//uncomress the data
1289
	int len;
8 cycrow 1290
	unsigned char *uncomprData = this->_convert_uncompressFile(sOldFilename, &len);
7 cycrow 1291
 
1292
	// uncomressed failed
1293
	if ( !uncomprData ) {
8 cycrow 1294
		CLog::log("Error: Unable to uncompress the file");
7 cycrow 1295
		return false;
1296
	}
1297
 
1298
	// now we can read the data
1299
	unsigned char *d = uncomprData;
8 cycrow 1300
	Utils::String str;
7 cycrow 1301
 
1302
//	CMultiSpkFile *mspk = NULL;
1303
	//SMultiSpkFile *cur_mspk = NULL;
1304
 
1305
	int numscripts = 0, curscript = 0;
1306
	bool bVerbose = true;
1307
	float fVersion = 1;
1308
 
8 cycrow 1309
	CLog::log("* Reading spk data...");
7 cycrow 1310
	while ( d )
1311
	{
1312
		// read the next line
8 cycrow 1313
		d = str.readToEndOfLine(d);
7 cycrow 1314
		if ( !d || d[0] == 0 ) {
1315
			break;
1316
		}
8 cycrow 1317
		if ( str.empty() ) {
7 cycrow 1318
			continue;
1319
		}
1320
 
8 cycrow 1321
		Utils::String sCmd = str.token(" ", 1);
7 cycrow 1322
 
1323
		//TODO: split this into CMultiSpkFile
1324
		/*
1325
		if ( first == "MultiPackage:" )
1326
			mspk = new CMultiSpkFile;
1327
		else if ( (first == "SelectScript:") && (mspk) )
1328
		{
1329
			mspk->AddFileEntry ( rest.GetToken ( 2, -1, ' ' ) + ".spk" );
1330
			++numscripts;
1331
		}
1332
		else if ( (str == "AllowSelection") && (mspk) )
1333
			mspk->SetSelection ( true );
1334
		else if ( str == "-- Start New Script --" )
1335
		{
1336
			if ( !mspk )
1337
			{
1338
				printf ( "Invalid file format, seems to be multi package file but isn't\n" );
1339
				CLEANUP
1340
				exit ( 0 );
1341
			}
1342
			cur_mspk = mspk->GetFileList()->Get ( curscript );
1343
			++curscript;
1344
			cur_mspk->pFile = new CSpkFile;
1345
			spkfile = (CSpkFile *)cur_mspk->pFile;
1346
		}
1347
		*/
8 cycrow 1348
		Utils::String sRest = str.tokens(" ", 2);
7 cycrow 1349
		if ( sCmd == "Packager:" ) {
8 cycrow 1350
			fVersion = sRest;
1351
			if ( bVerbose ) CLog::logf( "\tPackager Version: %.2f", fVersion );
7 cycrow 1352
		}
1353
		else if ( sCmd == "Icon:" )
1354
		{
8 cycrow 1355
			long size = sRest.token(" ", 1);
1356
			Utils::String ext = sRest.token(" ", 2);
7 cycrow 1357
 
1358
			C_File *file = new C_File ();
1359
			file->ReadFromData ( (char *)d, size );
1360
 
1361
			d += size;
1362
 
8 cycrow 1363
			this->SetIcon(file, ext);
7 cycrow 1364
 
8 cycrow 1365
			if ( bVerbose ) CLog::logf( "\tIcon (%s) Size: %s", ext.c_str(), file->GetDataSizeString ().c_str() );
7 cycrow 1366
		}
8 cycrow 1367
		else if ( sCmd.left(3) == "$$$" )
7 cycrow 1368
			d = _convert_parseFile(sCmd, sRest, fVersion, d, bVerbose);
1369
		else {
1370
			this->_convert_parse(sCmd, sRest, bVerbose);
1371
		}
1372
	}
1373
 
8 cycrow 1374
	if ( bVerbose ) CLog::logf( "* Reading spk data..." );
7 cycrow 1375
 
1376
	return true;
1377
}