Subversion Repositories spk

Rev

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