Subversion Repositories spk

Rev

Rev 227 | Rev 299 | 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);
231 cycrow 605
				if (m_iScriptType == -1)
606
				{
214 cycrow 607
					m_sScriptType = sRest;
231 cycrow 608
					m_iScriptType = SCRIPTTYPE_CUSTOM;
609
				}
1 cycrow 610
			}
611
		}
612
	}
197 cycrow 613
	else if (sFirst.Compare(L"AnotherMod"))
1 cycrow 614
	{
214 cycrow 615
		m_sOtherName = sRest.token(L"|", 1);
616
		m_sOtherAuthor = sRest.tokens(L"|", 2);
1 cycrow 617
	}
197 cycrow 618
	else if ( sFirst.Compare(L"WareName") || sFirst.Compare(L"WareDesc") )
1 cycrow 619
	{
620
		// find the ware to use
621
		SWares *useWare = m_pLastWare;
197 cycrow 622
		Utils::WString id = sRest.token(L" ", 1);
1 cycrow 623
		for ( CListNode<SWares> *wNode = m_lWares.Front(); wNode; wNode = wNode->next() )
624
		{
10 cycrow 625
			if ( wNode->Data()->sID.Compare(id.c_str()) )
1 cycrow 626
			{
627
				useWare = wNode->Data();
628
				break;
629
			}
630
		}
631
 
632
		// check if we have the id already
633
		if ( useWare )
634
		{
197 cycrow 635
			int lang = sRest.token(L" ", 2);
1 cycrow 636
			SWaresText *wt = NULL;
637
			for ( CListNode<SWaresText> *tNode = useWare->lText.Front(); tNode; tNode = tNode->next() )
638
			{
639
				if ( tNode->Data()->iLang == lang )
640
				{
641
					wt = tNode->Data();
642
					break;
643
				}
644
			}
645
 
646
			if ( !wt )
647
			{
648
				wt = new SWaresText;
649
				wt->iLang = lang;
650
				useWare->lText.push_back(wt);
651
			}
652
 
197 cycrow 653
			if ( sFirst.Compare(L"WareName") )
654
				wt->sName = sRest.tokens(L" ", 3);
1 cycrow 655
			else
197 cycrow 656
				wt->sDesc = sRest.tokens(L" ", 3);
1 cycrow 657
		}
658
	}
197 cycrow 659
	else if ( sFirst.left(4).Compare(L"Ware") )
1 cycrow 660
	{
661
		SWares *ware = new SWares;
662
		ware->iTextID = -1;
663
		ware->iTextPage = 0;
14 cycrow 664
		ware->cType = sFirst[4];
197 cycrow 665
		ware->iPrice = sRest.token(L" ", 2);
666
		ware->iSize = sRest.token(L" ", 3);
667
		ware->iVolumn = sRest.token(L" ", 4);
668
		ware->sID = sRest.token(L" ", 1);
669
		ware->iNotority = sRest.token(L" ", 5);
670
		if ( !sRest.token(L" ", 6).empty() )
1 cycrow 671
		{
197 cycrow 672
			ware->iTextID = sRest.token(L" ", 6).token(L",", 2);
673
			ware->iTextPage = sRest.token(L" ", 6).token(L",", 1);
1 cycrow 674
		}
675
		m_lWares.push_back ( ware );
676
		m_pLastWare = ware;
677
	}
678
 
197 cycrow 679
	else if ( CBaseFile::loadPackageData(sFirst, sRest, sMainGame, otherGames, gameAddons, progress) )
1 cycrow 680
		return true;
681
	else
682
		return false;
683
 
684
	return true;
685
}
686
 
210 cycrow 687
bool CSpkFile::GeneratePackagerScript(bool wildcard, Utils::WStringList *list, int game, const Utils::WStringList &gameAddons, bool datafile)
1 cycrow 688
{
127 cycrow 689
	if ( !CBaseFile::GeneratePackagerScript(wildcard, list, game, gameAddons, datafile) )
1 cycrow 690
		return false;
691
 
210 cycrow 692
	list->pushBack(L"# File Type, Script or Ship");
693
	list->pushBack(L"FileType: Script");
694
	list->pushBack(L"");
98 cycrow 695
 
210 cycrow 696
	list->pushBack(L"# Script Type, the type of package file, some are special types, others are just for show");
1 cycrow 697
	if ( this->IsLibrary() )
210 cycrow 698
		list->pushBack(L"ScriptType: Library");
1 cycrow 699
	else if ( this->IsPackageUpdate() )
210 cycrow 700
		list->pushBack(L"ScriptType: Package Update");
1 cycrow 701
	else if ( this->IsCustomStart() )
210 cycrow 702
		list->pushBack(L"ScriptType: Custom Start");
1 cycrow 703
	else if ( this->IsPatch() )
210 cycrow 704
		list->pushBack(L"ScriptType: Patch");
1 cycrow 705
	else
214 cycrow 706
		list->pushBack(L"ScriptType: " + this->scriptTypeString(44));
210 cycrow 707
	list->pushBack(L"");
1 cycrow 708
 
709
	if ( this->IsAnotherMod() )
710
	{
210 cycrow 711
		list->pushBack(L"# For another mod/package, this is a child package");
214 cycrow 712
		list->pushBack(L"AnotherMod: " + m_sOtherName + L"|" + m_sOtherAuthor);
210 cycrow 713
		list->pushBack(L"");
1 cycrow 714
	}
715
 
716
	if ( !m_lWares.empty() )
717
	{
210 cycrow 718
		list->pushBack(L"# Custom Wares, Ware<type>: <id> <price> <size> <volumn> <notority>");
1 cycrow 719
		for ( CListNode<SWares> *node = m_lWares.Front(); node; node = node->next() )
720
		{
721
			SWares *w = node->Data();
722
			if ( w->iTextID > 0 )
210 cycrow 723
				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 724
			else
210 cycrow 725
				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 726
			for ( CListNode<SWaresText> *wNode = w->lText.Front(); wNode; wNode = wNode->next() )
727
			{
728
				SWaresText *wt = wNode->Data();
10 cycrow 729
				if ( !wt->sName.empty() )
210 cycrow 730
					list->pushBack(L"WareName: " + w->sID + L" " + (long)wt->iLang + L" " + wt->sName);
10 cycrow 731
				if ( !wt->sDesc.empty() )
210 cycrow 732
					list->pushBack(L"WareDesc: " + w->sID + L" " + (long)wt->iLang + L" " + wt->sDesc);
1 cycrow 733
			}
210 cycrow 734
			list->pushBack(L"");
1 cycrow 735
		}
736
	}
737
 
738
	if ( !datafile )
739
	{
127 cycrow 740
		if ( !CBaseFile::GeneratePackagerScriptFile(wildcard, list, game, gameAddons) )
1 cycrow 741
			return false;
742
	}
743
 
744
	return true;
745
 
746
}
747
 
197 cycrow 748
Utils::WString CSpkFile::GetWareText(SWares *w, int lang)
1 cycrow 749
{
750
	// return the text page if being used
751
	if ( w->iTextID > 0 && w->iTextPage > 0 )
197 cycrow 752
		return Utils::WString(L"{") + (long)w->iTextPage + L"," + (long)w->iTextID + L"}";
1 cycrow 753
 
197 cycrow 754
	Utils::WString name;
1 cycrow 755
	for ( CListNode<SWaresText> *wt = w->lText.Front(); wt; wt = wt->next() )
756
	{
10 cycrow 757
		if ( wt->Data()->sName.empty() )
1 cycrow 758
			continue;
759
		if ( wt->Data()->iLang == lang )
760
			name = wt->Data()->sName;
10 cycrow 761
		else if ( name.empty() && wt->Data()->iLang == 44 )
1 cycrow 762
			name = wt->Data()->sName;
10 cycrow 763
		else if ( name.empty() )
1 cycrow 764
			name = wt->Data()->sName;
765
	}
766
 
767
	return name;
768
}
197 cycrow 769
Utils::WString CSpkFile::GetWareDesc(SWares *w, int lang)
1 cycrow 770
{
771
	// return the text page if being used
772
	if ( w->iTextID > 0 && w->iTextPage > 0 )
197 cycrow 773
		return Utils::WString(L"{") + (long)w->iTextPage + L"," + ((long)w->iTextID + 1) + L"}";
1 cycrow 774
 
197 cycrow 775
	Utils::WString name;
1 cycrow 776
	for ( CListNode<SWaresText> *wt = w->lText.Front(); wt; wt = wt->next() )
777
	{
10 cycrow 778
		if ( wt->Data()->sDesc.empty() )
1 cycrow 779
			continue;
780
 
781
		if ( wt->Data()->iLang == lang )
782
			name = wt->Data()->sDesc;
10 cycrow 783
		else if ( name.empty() && wt->Data()->iLang == 44 )
1 cycrow 784
			name = wt->Data()->sDesc;
10 cycrow 785
		else if ( name.empty() )
1 cycrow 786
			name = wt->Data()->sDesc;
787
	}
788
 
789
	return name;
790
}
791
 
216 cycrow 792
Utils::WString CSpkFile::customStartName() const
1 cycrow 793
{
794
	if ( !this->IsCustomStart() )
216 cycrow 795
		return L"";
1 cycrow 796
 
797
	// else find the custom start script
798
	C_File *file = NULL;
799
	for ( file = this->GetFirstFile(FILETYPE_SCRIPT); file; file = this->GetNextFile(file) )
800
	{
197 cycrow 801
		if ( file->filename().contains(L"initplayership") && file->filename().token(L".", 1).Compare(L"galaxy") )
1 cycrow 802
			break;
803
	}
804
 
805
	if ( !file )
216 cycrow 806
		return L"";
1 cycrow 807
 
216 cycrow 808
	return file->filename().token(L".", 2);
1 cycrow 809
}
810
 
811
void CSpkFile::MergePackage(CBaseFile *base)
812
{
813
	// update possible changes
814
	if ( base->GetType() == TYPE_SPK )
815
	{
816
		CSpkFile *spk = (CSpkFile *)base;
817
		m_bForceProfile = spk->IsForceProfile();
818
 
819
		// add any new wares
216 cycrow 820
		if ( spk->anyWares() )
1 cycrow 821
		{
822
			for ( CListNode<SWares> *node = spk->GetWaresList()->Front(); node; node = node->next() )
216 cycrow 823
				this->addWare(node->Data());
1 cycrow 824
			spk->GetWaresList()->clear(); // remove wares so they aren't deleted
825
		}
826
 
827
		// add any settings
214 cycrow 828
		if ( spk->anySettings() )
1 cycrow 829
		{
214 cycrow 830
			for ( CListNode<SSettingType> *node = spk->settingsList()->Front(); node; node = node->next() )
831
				this->addSetting(node->Data()->sKey, node->Data()->iType);
1 cycrow 832
		}
833
 
214 cycrow 834
		if ( !spk->otherName().empty() )
1 cycrow 835
		{
214 cycrow 836
			m_sOtherName = spk->otherName();
837
			m_sOtherAuthor = spk->otherAuthor();
1 cycrow 838
		}
839
	}
840
 
841
	// copy settings from base class
46 cycrow 842
	_merge(base);
1 cycrow 843
 
844
	for ( CListNode<SGameCompat> *gNode = base->GetGameCompatabilityList()->Front(); gNode; gNode = gNode->next() ) {
46 cycrow 845
		if ( !gNode->Data()->sVersion.empty() )
216 cycrow 846
			this->AddGameCompatability(gNode->Data()->iGame, gNode->Data()->sVersion);
1 cycrow 847
		else
46 cycrow 848
			this->AddGameCompatability(gNode->Data()->iGame, (long)gNode->Data()->iVersion);
1 cycrow 849
	}
850
 
851
	// copy over needed librarys
852
	for ( CListNode<SNeededLibrary> *lNode = base->GetNeededLibraries()->Front(); lNode; lNode = lNode->next() )
203 cycrow 853
		this->addNeededLibrary(lNode->Data()->sName, lNode->Data()->sAuthor, lNode->Data()->sMinVersion);
1 cycrow 854
 
855
	// web mirror address, add any new ones
170 cycrow 856
	for(auto itr = base->webMirrors().begin(); itr != base->webMirrors().end(); itr++)
162 cycrow 857
		this->addWebMirror((*itr)->str);
1 cycrow 858
 
859
	// copy over package names
170 cycrow 860
	for(auto itr = base->namesList()->begin(); itr != base->namesList()->end(); itr++)
861
		this->addName((*itr)->iLanguage, (*itr)->sName);
1 cycrow 862
 
863
	// finally do all the files
170 cycrow 864
	for ( CListNode<C_File> *node = base->fileList().Front(); node; node = node->next() )
1 cycrow 865
	{
866
		C_File *f = node->Data();
867
		// if it exists, remove the old
868
		for ( CListNode<C_File> *thisNode = m_lFiles.Front(); thisNode; thisNode = thisNode->next() )
869
		{
158 cycrow 870
			if ( thisNode->Data()->GetFileType() == f->GetFileType() && thisNode->Data()->filename().Compare(f->filename()) && thisNode->Data()->dir().Compare(f->dir()) )
1 cycrow 871
			{
872
				m_lFiles.remove(thisNode);
873
				break;
874
			}
875
		}
876
 
877
		m_lFiles.push_back(f);
878
	}
879
 
880
	// clear the files so we dont delete them later
881
	base->GetFileList()->clear();
882
}
7 cycrow 883
 
216 cycrow 884
unsigned char *CSpkFile::_convert_uncompressFile(const Utils::WString &sOldFilename, int *pLen)
7 cycrow 885
{
10 cycrow 886
	// firstcheck if the file exists
216 cycrow 887
	FILE *id = _wfopen(sOldFilename.c_str(), L"rb" );
10 cycrow 888
	if ( !id ) {
227 cycrow 889
		CLog::logf(CLog::Log_IO, 1, L"Unable to open file: %s", sOldFilename.c_str());
10 cycrow 890
		return false;
891
	}
7 cycrow 892
 
10 cycrow 893
	// read the first 3 charaters to check if its using the original "HiP" compression
14 cycrow 894
	Utils::String check((char)fgetc(id));
10 cycrow 895
	check += (char)fgetc ( id );
896
	check += (char)fgetc ( id );
7 cycrow 897
 
14 cycrow 898
	Utils::String removeFile;
7 cycrow 899
 
10 cycrow 900
	unsigned char *uncomprData = NULL;
901
	unsigned char *data = NULL;
902
	long len = 0, newlen = 0;
903
 
904
	if ( check == "HiP" ) {
905
		fclose ( id );
906
		bool opened = false;
907
		if ( DecompressFile ( (char *)sOldFilename.c_str(), "uncompr.tmp" ) ) {
908
			removeFile = "uncompr.tmp";
909
			id = fopen ( "uncompr.tmp", "r" );
910
			if ( id )
911
				opened = true;
912
		}
913
 
914
		if ( !opened ) {
213 cycrow 915
			CLog::log(CLog::Log_IO, 1, L"Unable to uncompress file, exiting...");
10 cycrow 916
			return false;
917
		}
918
 
213 cycrow 919
		CLog::log(CLog::Log_IO, 1, L"* Reading file into memory...");
10 cycrow 920
		// get file length
921
		fseek ( id, 0, SEEK_END );
922
		len = ftell ( id );
923
 
924
		// move back to beginning
925
		fseek ( id, 0, SEEK_SET );
926
 
927
		// read the data from file into memory
928
		uncomprData = new unsigned char[len + 1];
929
		fread ( uncomprData, sizeof(unsigned char), len, id );
930
 
931
		newlen = len;
932
	}
933
	else
934
	{
213 cycrow 935
		CLog::log(CLog::Log_IO, 1, L"* Reading file into memory...");
10 cycrow 936
		// get file length
937
		fseek ( id, 0, SEEK_END );
938
		len = ftell ( id );
939
 
940
		// move back to beginning
941
		fseek ( id, 0, SEEK_SET );
942
 
943
		// read the data from file into memory
944
		data = new unsigned char[len + 1];
945
		fread ( data, sizeof(unsigned char), len, id );
946
 
947
		// uncompress the file (currently only 7zip compression)
213 cycrow 948
		CLog::log(CLog::Log_IO, 1, L"* Uncompressing file...");
10 cycrow 949
		newlen = len;
950
	#ifdef _INCLUDE7ZIP
951
		uncomprData = LZMADecodeData ( data, len, newlen, progress );
952
	#else
953
		uncomprData = LZMADecode_C ( (unsigned char *)data, len, (size_t*)&newlen, NULL );
954
	#endif
955
	}
956
 
957
	*pLen = newlen;
958
 
14 cycrow 959
	if ( !removeFile.empty() ) {
52 cycrow 960
		CFileIO::Remove(removeFile);
10 cycrow 961
	}
962
 
7 cycrow 963
	return uncomprData;
964
}
965
 
216 cycrow 966
Utils::WString CSpkFile::_convert_fileEndString(const Utils::WString &sFile)
7 cycrow 967
{
216 cycrow 968
	if ( sFile.Compare(L"Text") )
969
		return L"-- End of Script --";
970
	else if ( sFile.Compare(L"Uninstall") )
971
		return L"-- End of Uninstall --";
972
	else if ( sFile.Compare(L"Readme") )
973
		return L"-- End of Readme --";
974
	else if ( sFile.Compare(L"Map") )
975
		return L"-- End of Map --";
976
	else if ( sFile.Compare(L"Mod") || sFile.Compare(L"Extra") || sFile.Compare(L"Screen") || sFile.Compare(L"Sound") )
977
		return L"";
978
	return L"-- End of Script --";
7 cycrow 979
}
980
 
216 cycrow 981
FileType CSpkFile::_convert_fileType(const Utils::WString &sFile)
7 cycrow 982
{
216 cycrow 983
	if ( sFile.Compare(L"Text") )
10 cycrow 984
		return FILETYPE_TEXT;
216 cycrow 985
	else if ( sFile.Compare(L"Uninstall") )
10 cycrow 986
		return FILETYPE_UNINSTALL;
216 cycrow 987
	else if ( sFile.Compare(L"Readme") )
10 cycrow 988
		return FILETYPE_README;
216 cycrow 989
	else if ( sFile.Compare(L"Map") )
10 cycrow 990
		return FILETYPE_MAP;
216 cycrow 991
	else if ( sFile.Compare(L"Mod") )
10 cycrow 992
		return FILETYPE_MOD;
216 cycrow 993
	else if ( sFile.Compare(L"Extra") )
10 cycrow 994
		return FILETYPE_EXTRA;
216 cycrow 995
	else if ( sFile.Compare(L"Screen") )
10 cycrow 996
		return FILETYPE_SCREEN;
216 cycrow 997
	else if ( sFile.Compare(L"Sound") )
10 cycrow 998
		return FILETYPE_SOUND;
999
 
1000
	return FILETYPE_SCRIPT;
7 cycrow 1001
}
1002
 
216 cycrow 1003
void CSpkFile::_convert_parse(const Utils::WString &sCmd, const Utils::WString &sRest)
7 cycrow 1004
{
216 cycrow 1005
	if ( sCmd == L"Name:" )
10 cycrow 1006
	{
216 cycrow 1007
		this->setName(sRest);
227 cycrow 1008
		CLog::logf(CLog::Log_EditPackage, 3, L"\tScript Name: %s", sRest.c_str() );
10 cycrow 1009
	}
216 cycrow 1010
	else if ( sCmd == L"Author:" )
10 cycrow 1011
	{
50 cycrow 1012
		this->setAuthor(sRest);
227 cycrow 1013
		CLog::logf(CLog::Log_EditPackage, 3, L"\tScript Author: %s", sRest.c_str() );
10 cycrow 1014
	}
216 cycrow 1015
	else if ( sCmd == L"CustomStart" )
10 cycrow 1016
	{
1017
		this->SetCustomStart();
227 cycrow 1018
		CLog::logf(CLog::Log_EditPackage, 3, L"\tPackage is a custom start!!" );
10 cycrow 1019
	}
216 cycrow 1020
	else if ( sCmd == L"AnotherMod:" )
10 cycrow 1021
	{
216 cycrow 1022
		this->setAnotherMod(sRest.token(L"|", 1), sRest.tokens(L"|", 2));
227 cycrow 1023
		CLog::logf(CLog::Log_EditPackage, 3, L"\tFor another Mod, Name: %s, Author: %s", this->otherName().c_str(), this->otherAuthor().c_str() );
10 cycrow 1024
	}
216 cycrow 1025
	else if ( sCmd == L"PATCH" )
10 cycrow 1026
	{
1027
		this->SetPatch();
227 cycrow 1028
		CLog::logf(CLog::Log_EditPackage, 3, L"\tPackage is a Patch Mod!!" );
10 cycrow 1029
	}
216 cycrow 1030
	else if ( sCmd == L"Version:" )
10 cycrow 1031
	{
50 cycrow 1032
		this->setVersion(sRest);
227 cycrow 1033
		CLog::logf(CLog::Log_EditPackage, 3, L"\tScript Version: %s", sRest.c_str() );
10 cycrow 1034
	}
216 cycrow 1035
	else if ( sCmd == L"Date:" )
10 cycrow 1036
	{
50 cycrow 1037
		this->setCreationDate ( sRest );
227 cycrow 1038
		CLog::logf(CLog::Log_EditPackage, 3, L"\tScript Creation Date: %s", sRest.c_str() );
10 cycrow 1039
	}
216 cycrow 1040
	else if ( sCmd == L"Desc:" ) {
1041
		this->setDescription(sRest.findReplace(L"<br>", L"\n") );
227 cycrow 1042
		CLog::logf(CLog::Log_EditPackage, 3, L"\tScript Description: %s", this->description().c_str() );
10 cycrow 1043
	}
216 cycrow 1044
	else if ( sCmd == L"WebAddress:" ) {
49 cycrow 1045
		this->setWebAddress(sRest);
227 cycrow 1046
		CLog::logf(CLog::Log_EditPackage, 3, L"\tWeb Address: %s", sRest.c_str() );
10 cycrow 1047
	}
216 cycrow 1048
	else if ( sCmd == L"WebMirror1:" )
10 cycrow 1049
	{
162 cycrow 1050
		this->addWebMirror(sRest);
227 cycrow 1051
		CLog::logf(CLog::Log_EditPackage, 3, L"\tWeb Mirror Address: %s", sRest.c_str() );
10 cycrow 1052
	}
216 cycrow 1053
	else if ( sCmd == L"WebMirror2:" )
10 cycrow 1054
	{
162 cycrow 1055
		this->addWebMirror(sRest);
227 cycrow 1056
		CLog::logf(CLog::Log_EditPackage, 3, L"\tWeb Mirror Address: %s", sRest.c_str() );
10 cycrow 1057
	}
1058
 
216 cycrow 1059
	else if ( sCmd == L"ScriptType:" )
1060
		this->setScriptType (sRest);
1061
	else if ( sCmd == L"WebSite:" ) {
49 cycrow 1062
		this->setWebSite ( sRest );
227 cycrow 1063
		CLog::logf(CLog::Log_EditPackage, 3, L"\tWeb Site: %s", sRest.c_str() );
10 cycrow 1064
	}
216 cycrow 1065
	else if ( sCmd == L"Email:" ) {
49 cycrow 1066
		this->setEmail(sRest);
227 cycrow 1067
		CLog::logf(CLog::Log_EditPackage, 3, L"\tAuthor Email Address: %s", sRest.c_str() );
10 cycrow 1068
	}
216 cycrow 1069
	else if ( sCmd == L"GameVersion:" )
10 cycrow 1070
	{
1071
		//TODO: fix this for new game version
1072
		/*
1073
		int version = sRest.ToInt();
1074
		if ( version == 0 )
1075
			this->SetGameVersion ( 1 );
1076
		else if (version == 1 )
1077
			this->SetGameVersion ( 0 );
1078
		else
1079
			this->SetGameVersion ( version );
1080
		CLog::logf(CLog::Log_EditPackage, "\tGame Version: %d", this->GetGameVersion () );
1081
		*/
1082
	}
1083
 
216 cycrow 1084
	else if ( sCmd == L"Ware:" )
10 cycrow 1085
	{
216 cycrow 1086
		this->addWare ( sRest );
227 cycrow 1087
		CLog::logf(CLog::Log_EditPackage, 3, L"\tAdding Custom Ware" );
10 cycrow 1088
	}
216 cycrow 1089
	else if ( sCmd == L"WareText:" )
197 cycrow 1090
		this->addWareText ( sRest );
216 cycrow 1091
	else if ( sCmd == L"UninstallAfter:" )	this->addUninstallText(sRest.token(L" ", 1).toLong(), false, sRest.tokens(L" ", 2));
1092
	else if ( sCmd == L"UninstallBefore:" )	this->addUninstallText(sRest.token(L" ", 1).toLong(), true, sRest.tokens(L" ", 2));
1093
	else if ( sCmd == L"InstallAfter:" )	this->addInstallText(sRest.token(L" ", 1).toLong(), false, sRest.tokens(L" ", 2));
1094
	else if ( sCmd == L"InstallBefore:" )	this->addInstallText(sRest.token(L" ", 1).toLong(), true, sRest.tokens(L" ", 2));
1095
	else if ( sCmd == L"ScriptName:" )
10 cycrow 1096
	{
216 cycrow 1097
		Utils::WString lang = sRest.token(L":", 1);
1098
		Utils::WString name = sRest.tokens(L":", 2);
170 cycrow 1099
		this->addName(lang.toLong(), name);
227 cycrow 1100
		CLog::logf(CLog::Log_EditPackage, 3, L"\tScript Name Language (%s) %s", lang.c_str(), name.c_str() );
10 cycrow 1101
	}
7 cycrow 1102
}
1103
 
216 cycrow 1104
Utils::WString CSpkFile::_convert_parseFilename(const Utils::WString &sRest, float fVersion, Utils::WString *pDir)
7 cycrow 1105
{
216 cycrow 1106
	Utils::WString sFilename;
7 cycrow 1107
 
10 cycrow 1108
	if ( fVersion >= 3.00f )
216 cycrow 1109
		sFilename = sRest.tokens(L" ", 3);
10 cycrow 1110
	else if ( fVersion >= 2.00f )
216 cycrow 1111
		sFilename = sRest.tokens(L" ", 2);
10 cycrow 1112
	else
1113
		sFilename = sRest;
1114
 
216 cycrow 1115
	if ( sFilename.contains(L"<br>") ) {
1116
		sFilename = sFilename.findReplace(L"<br>", L"|");
1117
		if ( sFilename[0] == L'|' ) {
1118
			sFilename = sFilename.token(L"|", 1);
10 cycrow 1119
		}
1120
		else {
216 cycrow 1121
			*pDir = sFilename.token(L"|", 1);
1122
			sFilename = sFilename.tokens(L"|", 2);
10 cycrow 1123
		}
1124
	}
1125
 
1126
	return sFilename;
7 cycrow 1127
}
1128
 
216 cycrow 1129
unsigned char *CSpkFile::_convert_parseFile(const Utils::WString &sCmd, const Utils::WString &sRest, float fVersion, unsigned char *d)
7 cycrow 1130
{
216 cycrow 1131
	bool bShared = (sCmd.left(9) == L"$$$Shared") ? true : false;
1132
	Utils::WString sFile = sCmd.right(-3).left(-1);
1133
	Utils::WString sEnd = this->_convert_fileEndString(sFile);
127 cycrow 1134
	FileType iType = this->_convert_fileType(sFile);
10 cycrow 1135
 
1136
	// convert the filename and directory
216 cycrow 1137
	Utils::WString dir, filename = _convert_parseFilename(sRest, fVersion, &dir);
10 cycrow 1138
 
1139
	// get the size and time
1140
	long time = 0, size = 0;
216 cycrow 1141
	if ( fVersion >= 2.00f ) time = sRest.token(L" ", 1).toLong();
1142
	if ( fVersion >= 3.00f ) size = sRest.token(L" ", 2).toLong();
196 cycrow 1143
	bool binaryRead = (CFileIO(filename).isFileExtension(L"PCK")) ? true : false;
10 cycrow 1144
	if ( sEnd.empty() ) binaryRead = true;
1145
 
1146
	C_File *file = new C_File ();
1147
 
227 cycrow 1148
	if ( bShared )	CLog::logf(CLog::Log_File, 2, L"\tFound %s File (Shared): %s, Reading...", sFile.c_str(), filename.c_str() );
1149
	else			CLog::logf(CLog::Log_File, 2, L"\tFound %s File: %s, Reading...", sFile.c_str(), filename.c_str() );
10 cycrow 1150
 
1151
	// read the data
1152
	if ( binaryRead )
1153
	{
1154
		file->ReadFromData ( (char *)d, size );
1155
		d += size;
1156
	}
1157
	else
1158
	{
14 cycrow 1159
		Utils::String readData;
216 cycrow 1160
		d = LineByLineRead ( d, sEnd.toString(), &readData);
14 cycrow 1161
		file->ReadFromData ( (char *)readData.c_str(), (long)readData.length() );
10 cycrow 1162
	}
1163
 
1164
	// setup the file
178 cycrow 1165
	file->setName ( filename );
127 cycrow 1166
	file->setFileType(iType);
10 cycrow 1167
	file->SetShared ( bShared );
1168
	file->SetCreationTime ( time );
1169
	if ( !dir.empty() )
178 cycrow 1170
		file->setDir ( dir );
10 cycrow 1171
 
1172
	this->AddFile ( file );
1173
 
227 cycrow 1174
	CLog::logf(CLog::Log_File, 3, L"Size: %s", file->dataSizeString().c_str() );
10 cycrow 1175
 
1176
	return d;
7 cycrow 1177
}
1178
 
216 cycrow 1179
CSpkFile *CSpkFile::convertFromOld(const Utils::WString &sOldFilename)
9 cycrow 1180
{
1181
	// check if the old file is actually in an old format
10 cycrow 1182
	int ret = CBaseFile::CheckFile ( sOldFilename );
1183
	if ( ret != SPKFILE_INVALID && ret != SPKFILE_OLD ) {
1184
		return NULL;
1185
 	}
1186
 
1187
	CSpkFile *pSpkFile = new CSpkFile();
1188
	if ( !pSpkFile->convertOld(sOldFilename) ) {
1189
		delete pSpkFile;
1190
		return NULL;
1191
	}
1192
 
1193
	return pSpkFile;
9 cycrow 1194
}
1195
 
216 cycrow 1196
bool CSpkFile::convertOld(const Utils::WString &sOldFilename)
7 cycrow 1197
{
1198
	// check if the old file is actually in an old format
10 cycrow 1199
	int ret = CBaseFile::CheckFile ( sOldFilename );
1200
	if ( ret != SPKFILE_INVALID && ret != SPKFILE_OLD ) {
1201
		return false;
1202
 	}
1203
 
1204
	//uncomress the data
1205
	int len;
1206
	unsigned char *uncomprData = this->_convert_uncompressFile(sOldFilename, &len);
1207
 
1208
	// uncomressed failed
1209
	if ( !uncomprData ) {
213 cycrow 1210
		CLog::log(CLog::Log_IO, 1, L"Error: Unable to uncompress the file");
10 cycrow 1211
		return false;
1212
	}
1213
 
1214
	// now we can read the data
1215
	unsigned char *d = uncomprData;
1216
	Utils::String str;
1217
 
1218
//	CMultiSpkFile *mspk = NULL;
1219
	//SMultiSpkFile *cur_mspk = NULL;
1220
 
1221
	int numscripts = 0, curscript = 0;
1222
	float fVersion = 1;
1223
 
213 cycrow 1224
	CLog::log(CLog::Log_IO, 1, L"* Reading spk data...");
10 cycrow 1225
	while ( d )
1226
	{
1227
		// read the next line
1228
		d = str.readToEndOfLine(d);
1229
		if ( !d || d[0] == 0 ) {
1230
			break;
1231
		}
1232
		if ( str.empty() ) {
1233
			continue;
1234
		}
1235
 
1236
		Utils::String sCmd = str.token(" ", 1);
1237
 
1238
		//TODO: split this into CMultiSpkFile
1239
		/*
1240
		if ( first == "MultiPackage:" )
1241
			mspk = new CMultiSpkFile;
1242
		else if ( (first == "SelectScript:") && (mspk) )
1243
		{
1244
			mspk->AddFileEntry ( rest.GetToken ( 2, -1, ' ' ) + ".spk" );
1245
			++numscripts;
1246
		}
1247
		else if ( (str == "AllowSelection") && (mspk) )
1248
			mspk->SetSelection ( true );
1249
		else if ( str == "-- Start New Script --" )
1250
		{
1251
			if ( !mspk )
1252
			{
1253
				printf ( "Invalid file format, seems to be multi package file but isn't\n" );
1254
				CLEANUP
1255
				exit ( 0 );
1256
			}
1257
			cur_mspk = mspk->GetFileList()->Get ( curscript );
1258
			++curscript;
1259
			cur_mspk->pFile = new CSpkFile;
1260
			spkfile = (CSpkFile *)cur_mspk->pFile;
1261
		}
1262
		*/
1263
		Utils::String sRest = str.tokens(" ", 2);
1264
		if ( sCmd == "Packager:" ) {
1265
			fVersion = sRest;
227 cycrow 1266
			CLog::logf(CLog::Log_Read, 3, L"\tPackager Version: %.2f", fVersion );
10 cycrow 1267
		}
1268
		else if ( sCmd == "Icon:" )
1269
		{
1270
			long size = sRest.token(" ", 1);
1271
			Utils::String ext = sRest.token(" ", 2);
1272
 
1273
			C_File *file = new C_File ();
1274
			file->ReadFromData ( (char *)d, size );
1275
 
1276
			d += size;
1277
 
170 cycrow 1278
			this->setIcon(file, ext);
10 cycrow 1279
 
227 cycrow 1280
			CLog::logf(CLog::Log_File, 3, L"\tIcon (%s) Size: %s", ext.c_str(), file->dataSizeString ().c_str() );
10 cycrow 1281
		}
1282
		else if ( sCmd.left(3) == "$$$" )
1283
			d = _convert_parseFile(sCmd, sRest, fVersion, d);
1284
		else {
1285
			this->_convert_parse(sCmd, sRest);
1286
		}
1287
	}
1288
 
227 cycrow 1289
	CLog::logf(CLog::Log_IO, 1, L"* Reading spk data..." );
10 cycrow 1290
 
7 cycrow 1291
	return true;
1292
}