Subversion Repositories spk

Rev

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