Subversion Repositories spk

Rev

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