Subversion Repositories spk

Rev

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