Subversion Repositories spk

Rev

Rev 274 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 cycrow 1
 
2
#include "VirtualFileSystem.h"
3
#include "File_IO.h"
4
#include "CatFile.h"
35 cycrow 5
#include "XspFile.h"
94 cycrow 6
#include "TextDB.h"
1 cycrow 7
 
79 cycrow 8
#include "Packages.h"
9
 
112 cycrow 10
#define DELETELIST(list) if ( list ) { list->clear(); delete list; }
94 cycrow 11
 
35 cycrow 12
namespace SPK {
13
 
94 cycrow 14
CVirtualFileSystem::CVirtualFileSystem() : _lShields(NULL),
15
	_lLasers(NULL),
16
	_lMissiles(NULL),
17
	_lCockpits(NULL),
18
	_lComponentSections(NULL),
19
	_lDummySections(NULL),
101 cycrow 20
	_lBodiesSections(NULL),
21
	_lShips(NULL)
1 cycrow 22
{
23
	m_bLoaded = false;
35 cycrow 24
	m_pMap = new FileList;
25
	m_pModMap = new FileList;
26
 
27
	m_pTexts = new CTextDB();
28
	m_pModTexts = new CTextDB();
29
 
197 cycrow 30
	m_sAddon = L"";
35 cycrow 31
 
32
	m_iLang = 0;
274 cycrow 33
 
34
	_lAddons = new Utils::WStringList();
35
	_lAddons->pushBack("addon2");
36
	_lAddons->pushBack("addon");
1 cycrow 37
}
38
 
39
CVirtualFileSystem::~CVirtualFileSystem(void)
40
{
101 cycrow 41
	_clear();
35 cycrow 42
 
43
	if ( m_pTexts )		delete m_pTexts;
44
	if ( m_pModTexts )  delete m_pModTexts;
274 cycrow 45
	if (_lAddons) delete _lAddons;
101 cycrow 46
}
94 cycrow 47
 
197 cycrow 48
void CVirtualFileSystem::setAddon(const Utils::WString &addon)
101 cycrow 49
{ 
50
	m_sAddon = addon; 
1 cycrow 51
}
35 cycrow 52
void CVirtualFileSystem::setLanguage(int iLang)
1 cycrow 53
{
35 cycrow 54
	m_iLang = iLang;
55
}
56
 
197 cycrow 57
Utils::WString CVirtualFileSystem::firstShield()
94 cycrow 58
{
59
	if ( !_lShields || _lShields->empty() ) _updateShields();
112 cycrow 60
	return _returnText(_lShields->first());
94 cycrow 61
}
62
 
197 cycrow 63
Utils::WString CVirtualFileSystem::nextShield()
94 cycrow 64
{
112 cycrow 65
	return _returnText(_lShields->next());
94 cycrow 66
}
67
 
197 cycrow 68
Utils::WString CVirtualFileSystem::firstComponentSection()
94 cycrow 69
{
70
	if ( !_lComponentSections || _lComponentSections->empty() ) _updateComponentSections();
112 cycrow 71
	return _returnLine(_lComponentSections->first());
94 cycrow 72
}
73
 
197 cycrow 74
Utils::WString CVirtualFileSystem::nextComponentSection()
94 cycrow 75
{
112 cycrow 76
	return _returnLine(_lComponentSections->next());
94 cycrow 77
}
78
 
197 cycrow 79
Utils::WString CVirtualFileSystem::firstDummySection()
94 cycrow 80
{
81
	if ( !_lDummySections || _lDummySections->empty() ) _updateDummySections();
112 cycrow 82
	return _returnLine(_lDummySections->first());
94 cycrow 83
}
84
 
197 cycrow 85
Utils::WString CVirtualFileSystem::nextDummySection()
94 cycrow 86
{
112 cycrow 87
	return _returnLine(_lDummySections->next());
94 cycrow 88
}
89
 
197 cycrow 90
Utils::WString CVirtualFileSystem::firstBodiesSection()
94 cycrow 91
{
92
	if ( !_lBodiesSections || _lBodiesSections->empty() ) _updateBodiesSections();
112 cycrow 93
	return _returnLine(_lBodiesSections->first());
94 cycrow 94
}
95
 
197 cycrow 96
Utils::WString CVirtualFileSystem::nextBodiesSection()
94 cycrow 97
{
112 cycrow 98
	return _returnLine(_lBodiesSections->next());
94 cycrow 99
}
100
 
197 cycrow 101
std::pair<Utils::WString, Utils::WString> CVirtualFileSystem::nextLaser()
94 cycrow 102
{
112 cycrow 103
	return _returnPair(_lLasers->next());
94 cycrow 104
}
105
 
197 cycrow 106
std::pair<Utils::WString, Utils::WString>  CVirtualFileSystem::firstLaser()
94 cycrow 107
{
108
	if ( !_lLasers || _lLasers->empty() ) _updateLasers();
112 cycrow 109
	return _returnPair(_lLasers->first());
94 cycrow 110
}
111
 
197 cycrow 112
std::pair<Utils::WString, Utils::WString>  CVirtualFileSystem::firstMissile()
94 cycrow 113
{
114
	if ( !_lMissiles || _lMissiles->empty() ) _updateMissiles();
112 cycrow 115
	return _returnPair(_lMissiles->first());
94 cycrow 116
}
117
 
197 cycrow 118
std::pair<Utils::WString, Utils::WString> CVirtualFileSystem::nextMissile()
94 cycrow 119
{
112 cycrow 120
	return _returnPair(_lMissiles->next());
94 cycrow 121
}
122
 
197 cycrow 123
Utils::WString CVirtualFileSystem::firstCockpit()
94 cycrow 124
{
125
	if ( !_lCockpits || _lCockpits->empty() ) _updateCockpits();
112 cycrow 126
	return _returnID(_lCockpits->first());
94 cycrow 127
}
128
 
197 cycrow 129
Utils::WString CVirtualFileSystem::nextCockpit()
94 cycrow 130
{
112 cycrow 131
	return _returnID(_lCockpits->next());
94 cycrow 132
}
133
 
197 cycrow 134
std::pair<Utils::WString, Utils::WString> CVirtualFileSystem::_returnPair(Utils::WStringNode *s)
94 cycrow 135
{
197 cycrow 136
	if ( s && !s->data.empty() && !s->data.left(8).Compare(L"ReadText") ) return std::make_pair<Utils::WString, Utils::WString>(std::move(s->str), std::move(s->data));
137
	if ( s ) return std::make_pair<Utils::WString, Utils::WString>(std::move(s->str), s->str.token(L";", -2));
138
	return std::make_pair<Utils::WString, Utils::WString>(Utils::WString::Null(), Utils::WString::Null());
94 cycrow 139
}
140
 
197 cycrow 141
Utils::WString CVirtualFileSystem::_returnText(Utils::WStringNode *s)
94 cycrow 142
{
197 cycrow 143
	if ( s && !s->data.empty() && !s->data.left(8).Compare(L"ReadText") ) return s->data;
144
	if ( s ) return s->str.token(L";", -2);
145
	return Utils::WString::Null();
94 cycrow 146
}
147
 
197 cycrow 148
Utils::WString CVirtualFileSystem::_returnID(Utils::WStringNode *s)
94 cycrow 149
{
197 cycrow 150
	if ( s ) return s->str.token(L";", -2);
151
	return Utils::WString::Null();
94 cycrow 152
}
153
 
197 cycrow 154
Utils::WString CVirtualFileSystem::_returnLine(Utils::WStringNode *s)
94 cycrow 155
{
156
	if ( s ) return s->str;
197 cycrow 157
	return Utils::WString::Null();
94 cycrow 158
}
159
 
160
 
197 cycrow 161
bool CVirtualFileSystem::LoadFilesystem(const Utils::WString &dir, int maxPatch)
35 cycrow 162
{
197 cycrow 163
	return this->LoadFilesystem(dir, L"", maxPatch);
35 cycrow 164
}
165
 
197 cycrow 166
bool CVirtualFileSystem::LoadFilesystem(const Utils::WString &dir, const Utils::WString &mod, int maxPatch)
35 cycrow 167
{
197 cycrow 168
	m_sDir = dir.findReplace(L"\\", L"/");
1 cycrow 169
 
35 cycrow 170
	this->_clear();
1 cycrow 171
 
114 cycrow 172
	// if we are in the addon directory, then also read the previous directory
197 cycrow 173
	Utils::WString s = dir.token(L"/", -1);
174
	if ( !this->m_sAddon.empty() && dir.token(L"/", -1).Compare(this->m_sAddon) ) {
114 cycrow 175
		//LoadFilesystem(dir.tokens("/", 1, -2), "", 0);
176
	}
177
 
1 cycrow 178
	int number = 1;
197 cycrow 179
	while ( CFileIO::Exists(dir + L"/" + Utils::WString::PadNumber(number, 2) + L".cat") )
1 cycrow 180
	{
58 cycrow 181
		if ( maxPatch && maxPatch < number ) break;
197 cycrow 182
		Utils::WString file = dir + L"/" + Utils::WString::PadNumber(number, 2);
183
		if ( !CFileIO::Exists(file + L".dat") )
1 cycrow 184
			break;
185
 
186
		CCatFile cat;
197 cycrow 187
		if ( cat.open(file + L".cat", m_sAddon, CATREAD_JUSTCONTENTS, false) == CATERR_NONE)
1 cycrow 188
		{
124 cycrow 189
			for(auto itr = cat.GetFiles()->cbegin(); itr != cat.GetFiles()->cend(); itr++)
190
			{
197 cycrow 191
				this->_addModFile(CFileIO((*itr)->sFile).fullFilename(), file + L".cat", m_pMap);
1 cycrow 192
				m_bLoaded = true;
193
			}
194
		}
195
		++number;
196
	}
197
 
43 cycrow 198
	// add all the files from the mod
35 cycrow 199
	if ( !mod.empty() )
200
		this->addMod(mod);
201
 
43 cycrow 202
	// now add all the extracted data
197 cycrow 203
	this->_addDir(m_sDir, L"");
43 cycrow 204
 
1 cycrow 205
	return m_bLoaded;
206
}
207
 
43 cycrow 208
 
197 cycrow 209
void CVirtualFileSystem::_addDir(const Utils::WString &sStart, const Utils::WString &sDir)
43 cycrow 210
{
197 cycrow 211
	CDirIO Dir(sStart + L"/" + sDir);
196 cycrow 212
	Utils::WStringList list;
124 cycrow 213
	if (Dir.dirList(list))
214
	{
215
		for (auto itr = list.begin(); itr != list.end(); itr++)
216
		{
197 cycrow 217
			if (CDirIO(Dir.dir((*itr)->str)).isDir()) _addDir(sStart, sDir + L"/" + (*itr)->str);
196 cycrow 218
			else if (CFileIO((*itr)->str).isFileExtension(L"cat")) continue;
219
			else if (CFileIO((*itr)->str).isFileExtension(L"dat")) continue;
197 cycrow 220
			else this->_addFile(sDir + L"/" + (*itr)->str, Dir.file((*itr)->str), m_pMap);
43 cycrow 221
		}
222
	}
223
}
224
 
114 cycrow 225
 
197 cycrow 226
void CVirtualFileSystem::_removeSameFile(const Utils::WString &sFile, const Utils::WString &sDest, const Utils::WString &ext, FileList *pList)
114 cycrow 227
{
228
	CFileIO F(sFile);
229
 
197 cycrow 230
	Utils::WString newFile = F.changeFileExtension(ext);
114 cycrow 231
	newFile = newFile.lower();
232
 
233
	FileListItr itr = pList->find(newFile);
234
	if ( itr != pList->end() ) {
235
		if ( !CFileIO((*pList)[newFile]).dir().Compare(CFileIO(sDest).dir()) ) {
236
			pList->erase(newFile);
237
		}
238
	}
239
}
240
 
197 cycrow 241
void CVirtualFileSystem::_addFile(const Utils::WString &sFile, const Utils::WString &sDest, FileList *pList)
43 cycrow 242
{
197 cycrow 243
	Utils::WString file = sFile.asFilename().removeIf(0, '/');
114 cycrow 244
 
245
	// check file extension, remove any patching files in previous files
246
	CFileIO F(file);
196 cycrow 247
	Utils::WString ext = F.extension().toLower();
248
	if (ext.Compare(L"bob", true) || ext.Compare(L"pbd", true) || ext.Compare(L"bod", true) ) {
202 cycrow 249
		_removeSameFile(file, sDest, L"pbb", pList);
250
		_removeSameFile(file, sDest, L"bob", pList);
251
		_removeSameFile(file, sDest, L"pbd", pList);
114 cycrow 252
	}
196 cycrow 253
	else if (ext.Compare(L"xml", true) || ext.Compare(L"txt", true) )
202 cycrow 254
		_removeSameFile(file, sDest, L"pck", pList);
114 cycrow 255
 
202 cycrow 256
	(*pList)[file.lower()] = sDest.findReplace(L"\\", L"/").findReplace(L"//", L"/");
43 cycrow 257
}
197 cycrow 258
void CVirtualFileSystem::_addModFile(const Utils::WString &sFile, const Utils::WString &sMod, FileList *pList)
43 cycrow 259
{
197 cycrow 260
	this->_addFile(sFile, sMod + L"::" + sFile, pList);
43 cycrow 261
}
262
 
197 cycrow 263
bool CVirtualFileSystem::loadMod(const Utils::WString &mod)
1 cycrow 264
{
265
	bool loaded = false;
35 cycrow 266
 
267
	if ( !m_pModMap ) m_pModMap = new FileList;
268
 
1 cycrow 269
	CCatFile cat;
197 cycrow 270
	if ( CCatFile::Opened(cat.open(mod, m_sAddon, CATREAD_JUSTCONTENTS, false), false))
1 cycrow 271
	{
124 cycrow 272
		for (auto itr = cat.GetFiles()->cbegin(); itr != cat.GetFiles()->cend(); itr++) 
273
		{
197 cycrow 274
			this->_addModFile(CFileIO((*itr)->sFile).fullFilename(), mod, m_pModMap);
35 cycrow 275
			loaded = true;
276
		}
277
	}
278
 
279
	return loaded;
280
}
281
 
197 cycrow 282
bool CVirtualFileSystem::addMod(const Utils::WString &mod)
35 cycrow 283
{
284
	bool loaded = false;
285
 
286
	if ( !m_pMap ) m_pMap = new FileList;
287
 
288
	CCatFile cat;
197 cycrow 289
	if ( CCatFile::Opened(cat.open(mod, m_sAddon, CATREAD_JUSTCONTENTS, false), false))
35 cycrow 290
	{
124 cycrow 291
		for (auto itr = cat.GetFiles()->cbegin(); itr != cat.GetFiles()->cend(); itr++)
35 cycrow 292
		{
197 cycrow 293
			this->_addModFile(CFileIO((*itr)->sFile).fullFilename(), mod, m_pMap);
1 cycrow 294
			loaded = true;
295
		}
296
	}
297
 
298
	return loaded;
299
}
300
 
35 cycrow 301
bool CVirtualFileSystem::textExists(int iLang, int iPage, int iID) const
1 cycrow 302
{
94 cycrow 303
	if ( iLang <= 0 ) iLang = m_iLang;
304
 
35 cycrow 305
	if ( m_pTexts ) {
306
		if ( m_pTexts->exists(iLang, iPage, iID) ) return m_pTexts->exists(iLang, iPage, iID);
307
	}
308
	if ( m_pModTexts ) {
309
		if ( m_pModTexts->exists(iLang, iPage, iID) ) return m_pModTexts->exists(iLang, iPage, iID);
310
	}
311
 
312
	return false;
1 cycrow 313
}
314
 
197 cycrow 315
Utils::WString CVirtualFileSystem::findText(int iLang, int iPage, int iID) const
1 cycrow 316
{
94 cycrow 317
	if ( iLang <= 0 ) iLang = m_iLang;
318
 
35 cycrow 319
	if ( m_pTexts ) {
320
		if ( m_pTexts->exists(iLang, iPage, iID) ) return m_pTexts->get(iLang, iPage, iID);
321
	}
322
	if ( m_pModTexts ) {
323
		if ( m_pModTexts->exists(iLang, iPage, iID) ) return m_pModTexts->get(iLang, iPage, iID);
324
	}
1 cycrow 325
 
197 cycrow 326
	return Utils::WString(L"ReadText") + (long)iPage + L"-" + (long)iID;
35 cycrow 327
}
43 cycrow 328
 
197 cycrow 329
const Utils::WString &CVirtualFileSystem::directory() const
101 cycrow 330
{
331
	return m_sDir;
332
}
333
 
197 cycrow 334
bool CVirtualFileSystem::isFileAvailable(const Utils::WString &file) const
35 cycrow 335
{
43 cycrow 336
	return !this->_findFile(file).empty();
337
}
338
 
101 cycrow 339
bool CVirtualFileSystem::isTextUpdated() const
340
{
341
	if ( m_pTexts ) return m_pTexts->anyTextLoaded();
342
	return false;
343
}
344
 
197 cycrow 345
Utils::WString CVirtualFileSystem::_findFile(const Utils::WString &file) const
43 cycrow 346
{
197 cycrow 347
	Utils::WString toFile = file.findReplace(L"\\", L"/").lower();
43 cycrow 348
 
35 cycrow 349
	if ( m_pModMap && !m_pModMap->empty() ) {
350
		if ( !m_sAddon.empty() ) {
197 cycrow 351
			FileListItr aitr = m_pModMap->find(CFileIO(m_sAddon + L"/" + toFile).fullFilename().lower().c_str());
352
			if ( aitr == m_pModMap->end() ) aitr = m_pModMap->find(CFileIO(_convertExtension(m_sAddon + L"/" + toFile)).fullFilename().lower().c_str());
35 cycrow 353
			if ( aitr != m_pModMap->end() ) return aitr->second;
354
		}
197 cycrow 355
		FileListItr itr = m_pModMap->find(CFileIO(toFile).fullFilename().lower().c_str());
356
		if ( itr == m_pModMap->end() ) itr = m_pModMap->find(CFileIO(_convertExtension(toFile)).fullFilename().lower().c_str());
35 cycrow 357
		if ( itr != m_pModMap->end() ) return itr->second;
358
	}
114 cycrow 359
 
360
	if ( m_pMap && !m_pMap->empty() ) {
35 cycrow 361
		if ( !m_sAddon.empty() ) {
197 cycrow 362
			FileListItr aitr = m_pMap->find(CFileIO(m_sAddon + L"/" + toFile).fullFilename().lower().c_str());
363
			if ( aitr == m_pMap->end() ) aitr = m_pMap->find(CFileIO(_convertExtension(m_sAddon + L"/" + file)).fullFilename().lower().c_str());
35 cycrow 364
			if ( aitr != m_pMap->end() ) return aitr->second;
365
		}
197 cycrow 366
		FileListItr itr = m_pMap->find(CFileIO(file).fullFilename().lower().c_str());
367
		if ( itr == m_pMap->end() ) itr = m_pMap->find(CFileIO(_convertExtension(file)).fullFilename().lower().c_str());
35 cycrow 368
		if ( itr != m_pMap->end() ) return itr->second;
369
	}
197 cycrow 370
	return L"";
35 cycrow 371
}
372
 
197 cycrow 373
Utils::WString CVirtualFileSystem::_extractFromCat(const Utils::WString &sCat, const Utils::WString &sFile, const Utils::WString &sTo)
35 cycrow 374
{
58 cycrow 375
	CCatFile catFile;
197 cycrow 376
	if ( catFile.open(sCat, m_sAddon, CATREAD_CATDECRYPT, false) == CATERR_NONE)
58 cycrow 377
	{
378
		// check for the file
197 cycrow 379
		if ( catFile.extractFile(sFile, sTo)) return sTo;
124 cycrow 380
		if ( catFile.error() == CATERR_INVALIDDEST || catFile.error() == CATERR_CANTCREATEDIR ) {
181 cycrow 381
			if ( catFile.extractFile(sFile) ) return sFile;
58 cycrow 382
		}
383
	}
384
 
202 cycrow 385
	return L"";
58 cycrow 386
}
387
 
197 cycrow 388
Utils::WString CVirtualFileSystem::_extract(const Utils::WString &sFile, const Utils::WString &sTo)
58 cycrow 389
{
390
	// check if we need to unpack the file
391
	if ( CCatFile::CheckPackedExtension(sFile) ) {
392
		CFileIO File(sFile);
197 cycrow 393
		C_File f(File.fullFilename());
394
		if ( !f.readFromFile(File) ) return L"";
395
		if ( !f.UnPCKFile() ) return L"";
396
		if ( !f.writeToFile(sTo) ) return L"";
58 cycrow 397
		return sTo;
398
	}
399
	return sFile;
400
}
401
 
197 cycrow 402
Utils::WString CVirtualFileSystem::extractGameFile(const Utils::WString &file, const Utils::WString &to)
58 cycrow 403
{
274 cycrow 404
	Utils::WString sIn;
405
	Utils::WString sFile;
43 cycrow 406
 
274 cycrow 407
	if (!m_sAddon.empty())
408
	{
409
		sIn = _findFile(m_sAddon + L"\\" + file);
410
		sFile = m_sAddon + L"\\" + file;
411
		if (sIn.empty())
412
		{
413
			sIn = _findFile(file);
414
			sFile = file;
415
		}
416
	}
417
	else
418
	{
419
		sIn = _findFile(file);
420
		sFile = file;
421
	}
35 cycrow 422
 
274 cycrow 423
	if (sIn.empty() && _lAddons)
424
	{
425
		for (auto itr = _lAddons->begin(); itr != _lAddons->end(); itr++)
426
		{
427
			sIn = _findFile((*itr)->str + L"\\" + file);
428
			sFile = (*itr)->str + L"\\" + file;
429
			if (!sIn.empty())
430
				break;
431
		}
432
	}
433
 
434
	if (sIn.empty())
435
		return L"";
436
 
197 cycrow 437
	if (sIn.contains(L"::"))
438
	{
439
		sFile = sIn.token(L"::", 2);
440
		sIn = sIn.token(L"::", 1);
58 cycrow 441
		return _extractFromCat(sIn, sFile, to);
43 cycrow 442
	}
58 cycrow 443
 
444
	return _extract(sIn, to);
1 cycrow 445
}
446
 
197 cycrow 447
Utils::WString CVirtualFileSystem::_convertExtension(const Utils::WString &sFile) const
35 cycrow 448
{
449
	CFileIO File(sFile);
196 cycrow 450
	if ( File.isFileExtension(L"pck") ) {
197 cycrow 451
		return File.changeFileExtension(L"xml");
35 cycrow 452
	}
196 cycrow 453
	else if ( File.isFileExtension(L"xml") ) {
197 cycrow 454
		return File.changeFileExtension(L"pck");
35 cycrow 455
	}
196 cycrow 456
	else if ( File.isFileExtension(L"pbb") ) {
197 cycrow 457
		return File.changeFileExtension(L"bob");
35 cycrow 458
	}
196 cycrow 459
	else if ( File.isFileExtension(L"bob") ) {
197 cycrow 460
		return File.changeFileExtension(L"pbb");
35 cycrow 461
	}
196 cycrow 462
	else if ( File.isFileExtension(L"pbd") ) {
197 cycrow 463
		return File.changeFileExtension(L"bod");
35 cycrow 464
	}
196 cycrow 465
	else if ( File.isFileExtension(L"bod") ) {
197 cycrow 466
		return File.changeFileExtension(L"pbd");
35 cycrow 467
	}
468
 
469
	return sFile;
470
}
471
 
197 cycrow 472
Utils::WStringList *CVirtualFileSystem::getTShipsEntries()
35 cycrow 473
{
101 cycrow 474
	if ( !_lShips || _lShips->empty() ) _updateShips();
475
	return _lShips;
35 cycrow 476
}
477
 
197 cycrow 478
C_File *CVirtualFileSystem::extractGameFileToPackage(CBaseFile *pPackage, const Utils::WString &sFile, FileType iFileType)
35 cycrow 479
{
480
	return this->extractGameFileToPackage(pPackage, sFile, iFileType, sFile);
481
}
482
 
197 cycrow 483
C_File *CVirtualFileSystem::extractGameFileToPackage(CBaseFile *pPackage, const Utils::WString &sFile, FileType iFileType, const Utils::WString &sTo)
35 cycrow 484
{
264 cycrow 485
	Utils::WString to = this->extractGameFile(sFile, CPackages::tempDirectory() + L"/tmp.dat");
58 cycrow 486
	if ( !to.empty() ) {
487
		CFileIO File(to);
35 cycrow 488
 
197 cycrow 489
		C_File *f = pPackage->addFile(CFileIO(sTo).filename(), CFileIO(sTo).dir(), iFileType);
35 cycrow 490
		if ( f ) {
264 cycrow 491
			if ( f->readFromFile(CPackages::tempDirectory() + L"/tmp.dat") ) {
52 cycrow 492
				File.remove();
35 cycrow 493
				return f;
494
			}
495
		}
496
 
52 cycrow 497
		File.remove();
35 cycrow 498
	}
499
 
500
	return NULL;
501
}
502
 
197 cycrow 503
Utils::WString CVirtualFileSystem::getTShipsEntry(const Utils::WString &sId)
35 cycrow 504
{
101 cycrow 505
	if ( !_lShips || _lShips->empty() ) _updateShips();
506
	return _lShips->findData(sId, true);
35 cycrow 507
}
508
 
509
void CVirtualFileSystem::extractTexts(CXspFile *pPackage, int textId)
510
{
511
	//TODO: check for better finding of files in map
512
	for ( FileListItr itr = m_pMap->begin(); itr != m_pMap->end(); ++itr ) {
197 cycrow 513
		Utils::WString str = itr->first;
35 cycrow 514
 
515
		if ( !m_sAddon.empty() ) {
274 cycrow 516
			if ( !str.left(static_cast<long>(m_sAddon.length()) + 3).Compare(m_sAddon + L"/t/") && !str.left(static_cast<long>(m_sAddon.length()) + 3).Compare(m_sAddon + L"\\t\\") )
35 cycrow 517
				continue;
518
		}
519
		else {
197 cycrow 520
			if ( !str.left(2).Compare(L"t\\") && !str.left(2).Compare(L"t/") && !str.left(8).Compare(L"addon\t\\") && !str.left(8).Compare(L"addon/t/") )
35 cycrow 521
				continue;
522
		}
523
 
264 cycrow 524
		Utils::WString sTo = this->extractGameFile(str, CPackages::tempDirectory() + L"/tmp.dat");
58 cycrow 525
		if ( !sTo.empty() ) {
197 cycrow 526
			pPackage->addTextFromFile(sTo, textId);
58 cycrow 527
			CFileIO::Remove(sTo);
35 cycrow 528
		}
529
	}
530
}
531
 
532
void CVirtualFileSystem::updateTexts(int iFromPage, int iToPage)
533
{
534
	this->_updateTexts(iFromPage, iToPage, m_pMap, m_pTexts);
535
}
536
void CVirtualFileSystem::updateTexts(int iPage)
537
{
538
	this->_updateTexts(iPage, iPage, m_pMap, m_pTexts);
539
}
540
void CVirtualFileSystem::updateModTexts(int iFromPage, int iToPage)
541
{
542
	this->_updateTexts(iFromPage, iToPage, m_pModMap, m_pModTexts);
543
}
544
void CVirtualFileSystem::updateModTexts(int iPage)
545
{
546
	this->_updateTexts(iPage, iPage, m_pModMap, m_pModTexts);
547
}
548
 
549
void CVirtualFileSystem::_clear()
550
{
551
	m_bLoaded = false;
552
 
553
	if ( m_pMap ) delete m_pMap;
554
	m_pMap = new FileList;
555
	if ( m_pModMap ) delete m_pModMap;
556
	m_pModMap = new FileList;
101 cycrow 557
 
558
	DELETELIST(_lShields);
559
	DELETELIST(_lLasers);
560
	DELETELIST(_lMissiles);
561
	DELETELIST(_lCockpits);
562
	DELETELIST(_lComponentSections);
563
	DELETELIST(_lDummySections);
564
	DELETELIST(_lBodiesSections);
565
	DELETELIST(_lShips);
35 cycrow 566
}
567
 
568
void CVirtualFileSystem::_updateTexts(int iFromPage, int iToPage, FileList *pFileList, CTextDB *pTextList)
569
{
570
	// read all text files
571
	for ( FileListItr itr = pFileList->begin(); itr != pFileList->end(); ++itr ) {
197 cycrow 572
		Utils::WString str = itr->first;
35 cycrow 573
 
574
		if ( !m_sAddon.empty() ) {
274 cycrow 575
			if ( !str.left(static_cast<long>(m_sAddon.length()) + 3).Compare(m_sAddon + L"/t/") && !str.left(static_cast<long>(m_sAddon.length()) + 3).Compare(m_sAddon + L"\\t\\") )
35 cycrow 576
				continue;
577
		}
578
		else {
197 cycrow 579
			if ( !str.left(2).Compare(L"t\\") && !str.left(2).Compare(L"t/") )
35 cycrow 580
				continue;
581
		}
582
 
264 cycrow 583
		Utils::WString sTo = this->extractGameFile(str, CPackages::tempDirectory() + L"/tmp.dat");
58 cycrow 584
		if ( !sTo.empty() ) {
35 cycrow 585
			// add all texts into the map, id=(pageid, tid) data=text
196 cycrow 586
			Utils::WString baseFile = CFileIO(str).baseName();
587
			int lang = (baseFile.contains(L"-L")) ? baseFile.right(3) : baseFile.truncate(-4);
35 cycrow 588
 
589
			if ( m_iLang && lang != m_iLang ) continue;
590
			// open the text file to add
58 cycrow 591
			pTextList->parseTextFile(iFromPage, iToPage, sTo, lang);
35 cycrow 592
		}
593
	}
594
}
595
 
78 cycrow 596
void CVirtualFileSystem::clearMods(bool bIncludeStandard)
35 cycrow 597
{
78 cycrow 598
	if ( bIncludeStandard ) {
599
		if ( m_pTexts ) delete m_pTexts;
600
		m_pTexts = new CTextDB();
601
	}
602
 
35 cycrow 603
	if ( m_pModTexts ) delete m_pModTexts;
604
	m_pModTexts = new CTextDB();
605
}
606
 
197 cycrow 607
Utils::WStringList *CVirtualFileSystem::_updateList(const Utils::WString &typesFile, int iTextPos)
94 cycrow 608
{
197 cycrow 609
	Utils::WStringList *list = new Utils::WStringList();
35 cycrow 610
 
197 cycrow 611
	Utils::WString file = this->extractGameFile(L"types\\" + typesFile + L".pck", CPackages::tempDirectory() + L"/" + typesFile + L".txt");
94 cycrow 612
 
613
	CFileIO f(file);
614
 
615
	if ( f.exists() && f.startRead() ) {
616
		int itemsLeft = -1;
617
 
618
		while(!f.atEnd()) {
619
			// read the next line
197 cycrow 620
			Utils::WString line = f.readEndOfLineStr();
94 cycrow 621
 
622
			// remove the unneeded characters
623
			line.removeChar('\r');
624
			line.removeChar(9);
625
			line.removeFirstSpace();
626
 
627
			// blank line ? skip it
628
			if ( line.empty() ) continue;
629
			// skip anything starting with / as its a comment
630
			if ( line[0] == '/' ) continue;
631
 
632
			// first line is the count
633
			if ( itemsLeft == -1 )
197 cycrow 634
				itemsLeft = line.token(L";", 2);
94 cycrow 635
			else {
636
				if ( iTextPos == 0 )
637
					list->pushBack(line, line);
638
				else if ( iTextPos == -1 ) 
197 cycrow 639
					list->pushBack(line, line.token(L";", -2));
94 cycrow 640
				else
197 cycrow 641
					list->pushBack(line, this->findText(m_iLang, TEXTPAGE_OBJECTS, line.token(L";", iTextPos).toLong()));
94 cycrow 642
				--itemsLeft;
643
			}
644
		}
645
 
646
		f.close();
647
		f.remove();
648
	}
649
 
650
	return list;
651
}
652
 
653
void CVirtualFileSystem::_updateShields()
654
{
655
	DELETELIST(_lShields);
197 cycrow 656
	_lShields = _updateList(L"TShields", 7);
94 cycrow 657
}
658
 
659
void CVirtualFileSystem::_updateLasers()
660
{
661
	DELETELIST(_lLasers);
197 cycrow 662
	_lLasers = _updateList(L"TLaser", 7);
94 cycrow 663
}
664
 
665
void CVirtualFileSystem::_updateMissiles()
666
{
667
	DELETELIST(_lMissiles);
197 cycrow 668
	_lMissiles = _updateList(L"TMissiles", 7);
94 cycrow 669
}
670
 
671
void CVirtualFileSystem::_updateCockpits()
672
{
673
	DELETELIST(_lCockpits);
197 cycrow 674
	_lCockpits = _updateList(L"TCockpits", -1);
94 cycrow 675
}
676
 
101 cycrow 677
void CVirtualFileSystem::_updateShips()
678
{
679
	DELETELIST(_lShips);
197 cycrow 680
	_lShips = _updateList(L"TShips", -1);
101 cycrow 681
}
682
 
94 cycrow 683
void CVirtualFileSystem::_updateComponentSections()
684
{
685
	DELETELIST(_lComponentSections);
686
 
197 cycrow 687
	_lComponentSections = new Utils::WStringList();
94 cycrow 688
 
197 cycrow 689
	Utils::WString file = this->extractGameFile(L"types\\Components.pck", CPackages::tempDirectory() + L"/Components.txt");
94 cycrow 690
 
691
	CFileIO f(file);
692
 
693
	if ( f.exists() && f.startRead() ) {
694
		int sectionRemaining = 0;
695
		int itemsRemaining = 0;
696
 
697
		while(!f.atEnd()) {
698
			// read the next line
197 cycrow 699
			Utils::WString line = f.readEndOfLineStr();
94 cycrow 700
 
701
			// remove the unneeded characters
702
			line.removeChar('\r');
703
			line.removeChar(9);
704
			line.removeFirstSpace();
705
 
706
			// blank line ? skip it
707
			if ( line.empty() ) continue;
708
			// skip anything starting with / as its a comment
197 cycrow 709
			if ( line[0] == L'/' ) continue;
94 cycrow 710
 
711
			if ( itemsRemaining )
712
				--itemsRemaining;
713
			else if ( !sectionRemaining )
714
			{
197 cycrow 715
				sectionRemaining = line.token(L";", 2).toLong();
716
				Utils::WString section = line.token(L";", 1);
94 cycrow 717
				if ( !section.empty() )
718
					_lComponentSections->pushBack(section, section);
719
			}
720
			else if ( !itemsRemaining )
721
			{
197 cycrow 722
				itemsRemaining = line.token(L";", 2).toLong();
94 cycrow 723
				--sectionRemaining;
724
			}
725
		}
726
 
727
		f.close();
728
		f.remove();
729
	}
730
 
731
	if ( _lComponentSections->empty() )
732
	{
197 cycrow 733
		_lComponentSections->pushBack(L"SCTYPE_LASER", L"SCTYPE_LASER");
734
		_lComponentSections->pushBack(L"SCTYPE_COCKPIT", L"SCTYPE_COCKPIT");
735
		_lComponentSections->pushBack(L"SCTYPE_DOCKING", L"SCTYPE_DOCKING");
94 cycrow 736
	}
737
}
738
 
197 cycrow 739
Utils::WStringList *CVirtualFileSystem::_updateSectionList(const Utils::WString &sFile, bool singleEntry)
94 cycrow 740
{
197 cycrow 741
	Utils::WStringList *list = new Utils::WStringList();
94 cycrow 742
 
197 cycrow 743
	Utils::WString file = this->extractGameFile(L"types\\" + sFile + L".pck", CPackages::tempDirectory() + L"/" + sFile + L".txt");
94 cycrow 744
 
745
	CFileIO f(file);
746
 
747
	if ( f.exists() && f.startRead() ) {
748
		int sectionRemaining = 0;
749
 
750
		while(!f.atEnd()) {
751
			// read the next line
197 cycrow 752
			Utils::WString line = f.readEndOfLineStr();
94 cycrow 753
 
754
			// remove the unneeded characters
755
			line.removeChar('\r');
756
			line.removeChar(9);
757
			line.removeFirstSpace();
758
 
759
			// blank line ? skip it
760
			if ( line.empty() ) continue;
761
			// skip anything starting with / as its a comment
197 cycrow 762
			if ( line[0] == L'/' ) continue;
94 cycrow 763
 
764
			if ( !sectionRemaining )
765
			{
197 cycrow 766
				sectionRemaining = line.token(L";", 2).toLong();
767
				Utils::WString section = line.token(L";", 1);
94 cycrow 768
				if ( !section.empty() )
769
					list->pushBack(section, section);
770
			}
771
			else {
772
				if ( singleEntry )
197 cycrow 773
					sectionRemaining -= (line.countToken(L";") - 1);
94 cycrow 774
				else 
775
					--sectionRemaining;
776
			}
777
		}
778
 
779
		f.close();
780
		f.remove();
781
	}
782
 
783
	return list;
784
}
785
 
786
void CVirtualFileSystem::_updateDummySections()
787
{
788
	DELETELIST(_lDummySections);
789
 
197 cycrow 790
	_lDummySections = _updateSectionList(L"Dummies", false);
94 cycrow 791
 
792
	if ( _lDummySections->empty() )
793
	{
197 cycrow 794
		_lDummySections->pushBack(L"SDTYPE_ANIMATED", L"SDTYPE_ANIMATED");
795
		_lDummySections->pushBack(L"SDTYPE_DOCK", L"SDTYPE_DOCK");
796
		_lDummySections->pushBack(L"SDTYPE_DOORWAY", L"SDTYPE_DOORWAY");
797
		_lDummySections->pushBack(L"SDTYPE_GUN", L"SDTYPE_GUN");
798
		_lDummySections->pushBack(L"SDTYPE_CONNECTION", L"SDTYPE_CONNECTION");
94 cycrow 799
	}
800
}
801
 
802
void CVirtualFileSystem::_updateBodiesSections()
803
{
804
	DELETELIST(_lBodiesSections);
805
 
197 cycrow 806
	_lBodiesSections = _updateSectionList(L"Bodies", true);
94 cycrow 807
 
808
	if ( _lBodiesSections->empty() )
809
	{
197 cycrow 810
		_lBodiesSections->pushBack(L"SBTYPE_2D", L"SBTYPE_2D");
811
		_lBodiesSections->pushBack(L"SBTYPE_FACECAMERA", L"SBTYPE_FACECAMERA");
812
		_lBodiesSections->pushBack(L"SBTYPE_2D2", L"SBTYPE_2D2");
813
		_lBodiesSections->pushBack(L"SBTYPE_2DY", L"SBTYPE_2DY");
814
		_lBodiesSections->pushBack(L"SBTYPE_LOGO", L"SBTYPE_LOGO");
815
		_lBodiesSections->pushBack(L"SBTYPE_FC", L"SBTYPE_FC");
816
		_lBodiesSections->pushBack(L"SBTYPE_TURRET", L"SBTYPE_TURRET");
817
		_lBodiesSections->pushBack(L"SBTYPE_JET", L"SBTYPE_JET");
818
		_lBodiesSections->pushBack(L"SBTYPE_RADAR", L"SBTYPE_RADAR");
819
		_lBodiesSections->pushBack(L"SBTYPE_CONTAINER", L"SBTYPE_CONTAINER");
820
		_lBodiesSections->pushBack(L"SBTYPE_DISPLAY", L"SBTYPE_DISPLAY");
821
		_lBodiesSections->pushBack(L"SBTYPE_DOCKPOINT", L"SBTYPE_DOCKPOINT");
822
		_lBodiesSections->pushBack(L"SBTYPE_SMALLJET", L"SBTYPE_SMALLJET");
94 cycrow 823
	}
824
}
825
 
114 cycrow 826
 
827
/////////////////////////////////////////////////////////////////////////////////////////
828
//	DEBUG Functions
829
 
830
 
197 cycrow 831
void CVirtualFileSystem::DEBUG_LogContents(const Utils::WString &sFile)
114 cycrow 832
{
833
	CFileIO File(sFile);
834
 
835
	if ( File.startWrite() ) {
836
		if ( m_pMap ) {
837
			for(FileListItr itr = m_pMap->begin(); itr != m_pMap->end(); itr++) {
285 cycrow 838
				Utils::WString line = Utils::WString(itr->first) + L" => " + itr->second + L"\r\n";
839
				std::string str = line.toFileUTF8();
197 cycrow 840
				File.write(str.c_str(), str.length());
114 cycrow 841
			}
842
		}
843
 
844
		File.close();
845
	}
846
}
847
 
35 cycrow 848
} //NAMESPACE