Subversion Repositories spk

Rev

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