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