Subversion Repositories spk

Rev

Rev 1 | Rev 43 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1 Rev 35
Line 4... Line 4...
4
#include "CatFile.h"
4
#include "CatFile.h"
-
 
5
#include "XspFile.h"
-
 
6
 
-
 
7
namespace SPK {
5
 
8
 
6
CVirtualFileSystem::CVirtualFileSystem()
9
CVirtualFileSystem::CVirtualFileSystem()
7
{
10
{
8
	m_bLoaded = false;
11
	m_bLoaded = false;
9
	m_pMap = NULL;
12
	m_pMap = new FileList;
-
 
13
	m_pModMap = new FileList;
-
 
14
 
-
 
15
	m_pTexts = new CTextDB();
-
 
16
	m_pModTexts = new CTextDB();
-
 
17
 
10
	m_sAddon = "";
18
	m_sAddon = "";
-
 
19
 
-
 
20
	m_iLang = 0;
11
}
21
}
12
 
22
 
13
CVirtualFileSystem::~CVirtualFileSystem(void)
23
CVirtualFileSystem::~CVirtualFileSystem(void)
14
{
24
{
15
	if ( m_pMap )
25
	if ( m_pMap )		delete m_pMap;
16
		delete m_pMap;
26
	if ( m_pModMap )	delete m_pModMap;
-
 
27
 
-
 
28
	if ( m_pTexts )		delete m_pTexts;
-
 
29
	if ( m_pModTexts )  delete m_pModTexts;
-
 
30
}
-
 
31
 
-
 
32
void CVirtualFileSystem::setLanguage(int iLang)
-
 
33
{
-
 
34
	m_iLang = iLang;
-
 
35
}
-
 
36
 
-
 
37
bool CVirtualFileSystem::LoadFilesystem(const Utils::String &dir, int maxPatch)
-
 
38
{
-
 
39
	return this->LoadFilesystem(dir, "", maxPatch);
17
}
40
}
18
 
41
 
19
bool CVirtualFileSystem::LoadFilesystem(CyString &dir, CyString &mod, int maxPatch)
42
bool CVirtualFileSystem::LoadFilesystem(const Utils::String &dir, const Utils::String &mod, int maxPatch)
20
{
43
{
21
	m_sDir = dir;
44
	m_sDir = dir;
22
	m_bLoaded = false;
-
 
23
 
45
 
24
	if ( m_pMap ) delete m_pMap;
-
 
25
	m_pMap = new MAP;
46
	this->_clear();
26
 
47
 
27
	int number = 1;
48
	int number = 1;
28
	while ( CFileIO(dir + "/" + CyString::Number(number).PadNumber(2) + ".cat").Exists() )
49
	while ( CFileIO(CyString(dir) + "/" + CyString::Number(number).PadNumber(2) + ".cat").Exists() )
29
	{
50
	{
30
		if ( maxPatch && maxPatch > number ) break;
51
		if ( maxPatch && maxPatch > number ) break;
31
		CyString file = dir + "/" + CyString::Number(number).PadNumber(2);
52
		CyString file = CyString(dir) + "/" + CyString::Number(number).PadNumber(2);
32
		if ( !CFileIO(file + ".dat").Exists() )
53
		if ( !CFileIO(file + ".dat").Exists() )
33
			break;
54
			break;
34
 
55
 
35
		CCatFile cat;
56
		CCatFile cat;
36
		if ( cat.Open(file + ".cat", m_sAddon, CATREAD_JUSTCONTENTS, false) == CATERR_NONE )
57
		if ( cat.Open(file + ".cat", m_sAddon, CATREAD_JUSTCONTENTS, false) == CATERR_NONE )
37
		{
58
		{
38
			for ( CListNode<SInCatFile> *c = cat.GetFiles()->Front(); c; c = c->next() )
59
			for ( CListNode<SInCatFile> *c = cat.GetFiles()->Front(); c; c = c->next() )
39
			{
60
			{
40
				(*m_pMap)[CFileIO(c->Data()->sFile).GetFullFilename().ToLower().c_str()] = CyString(file + ".cat").c_str();
61
				(*m_pMap)[CFileIO(c->Data()->sFile).GetFullFilename().ToLower().c_str()] = CyString(file + ".cat").c_str();
41
				m_bLoaded = true;
62
				m_bLoaded = true;
42
			}
63
			}
43
		}
64
		}
44
		++number;
65
		++number;
45
	}
66
	}
46
 
67
 
-
 
68
	// now add all the extracted data
-
 
69
 
47
	if ( !mod.Empty() )
70
	if ( !mod.empty() )
48
		LoadMod(mod);
71
		this->addMod(mod);
49
 
72
 
50
	return m_bLoaded;
73
	return m_bLoaded;
51
}
74
}
52
 
75
 
53
bool CVirtualFileSystem::LoadMod(CyString &mod)
76
bool CVirtualFileSystem::loadMod(const Utils::String &mod)
54
{
77
{
55
	bool loaded = false;
78
	bool loaded = false;
-
 
79
 
-
 
80
	if ( !m_pModMap ) m_pModMap = new FileList;
-
 
81
 
-
 
82
	CCatFile cat;
-
 
83
	if ( CCatFile::Opened(cat.Open(mod, m_sAddon, CATREAD_JUSTCONTENTS, false), false) )
-
 
84
	{
-
 
85
		for ( CListNode<SInCatFile> *c = cat.GetFiles()->Front(); c; c = c->next() )
-
 
86
		{
-
 
87
			(*m_pModMap)[CFileIO(c->Data()->sFile).GetFullFilename().ToLower().c_str()] = mod.c_str();
-
 
88
			loaded = true;
-
 
89
		}
-
 
90
	}
-
 
91
 
-
 
92
	return loaded;
-
 
93
}
-
 
94
 
-
 
95
bool CVirtualFileSystem::addMod(const Utils::String &mod)
-
 
96
{
-
 
97
	bool loaded = false;
-
 
98
 
-
 
99
	if ( !m_pMap ) m_pMap = new FileList;
-
 
100
 
56
	CCatFile cat;
101
	CCatFile cat;
57
	if ( CCatFile::Opened(cat.Open(mod, m_sAddon, CATREAD_JUSTCONTENTS, false), false) )
102
	if ( CCatFile::Opened(cat.Open(mod, m_sAddon, CATREAD_JUSTCONTENTS, false), false) )
58
	{
103
	{
59
		for ( CListNode<SInCatFile> *c = cat.GetFiles()->Front(); c; c = c->next() )
104
		for ( CListNode<SInCatFile> *c = cat.GetFiles()->Front(); c; c = c->next() )
60
		{
105
		{
61
			(*m_pMap)[CFileIO(c->Data()->sFile).GetFullFilename().ToLower().c_str()] = mod.c_str();
106
			(*m_pMap)[CFileIO(c->Data()->sFile).GetFullFilename().ToLower().c_str()] = mod.c_str();
62
			loaded = true;
107
			loaded = true;
63
		}
108
		}
64
	}
109
	}
65
 
110
 
66
	return loaded;
111
	return loaded;
67
}
112
}
68
 
113
 
69
CyString CVirtualFileSystem::GetFile(CyString &file)
-
 
70
{
-
 
71
	if ( !m_pMap ) return NullString;
-
 
72
	MAP::iterator itr = m_pMap->find(CFileIO(file).GetFullFilename().ToLower().c_str());
-
 
73
	if ( itr == m_pMap->end() ) return NullString;
-
 
74
	return itr->second;
-
 
75
}
-
 
76
 
-
 
77
bool CVirtualFileSystem::ExtractGameFile(CyString &file, CyString &to)
114
bool CVirtualFileSystem::textExists(int iLang, int iPage, int iID) const
78
{
115
{
-
 
116
	if ( m_pTexts ) {
-
 
117
		if ( m_pTexts->exists(iLang, iPage, iID) ) return m_pTexts->exists(iLang, iPage, iID);
-
 
118
	}
-
 
119
	if ( m_pModTexts ) {
-
 
120
		if ( m_pModTexts->exists(iLang, iPage, iID) ) return m_pModTexts->exists(iLang, iPage, iID);
-
 
121
	}
-
 
122
 
-
 
123
	return false;
-
 
124
}
-
 
125
 
-
 
126
Utils::String CVirtualFileSystem::findText(int iLang, int iPage, int iID) const
-
 
127
{
-
 
128
	if ( m_pTexts ) {
-
 
129
		if ( m_pTexts->exists(iLang, iPage, iID) ) return m_pTexts->get(iLang, iPage, iID);
-
 
130
	}
-
 
131
	if ( m_pModTexts ) {
-
 
132
		if ( m_pModTexts->exists(iLang, iPage, iID) ) return m_pModTexts->get(iLang, iPage, iID);
-
 
133
	}
-
 
134
 
-
 
135
	return Utils::String("ReadText") + (long)iPage + "-" + (long)iID;
-
 
136
}
-
 
137
Utils::String CVirtualFileSystem::findFile(const Utils::String &file)
-
 
138
{
-
 
139
	if ( m_pModMap && !m_pModMap->empty() ) {
-
 
140
		if ( !m_sAddon.empty() ) {
-
 
141
			FileListItr aitr = m_pModMap->find(CFileIO(m_sAddon + "/" + file).GetFullFilename().ToLower().c_str());
-
 
142
			if ( aitr == m_pModMap->end() ) aitr = m_pModMap->find(CFileIO(_convertExtension(m_sAddon + "/" + file)).GetFullFilename().ToLower().c_str());
-
 
143
			if ( aitr != m_pModMap->end() ) return aitr->second;
-
 
144
		}
-
 
145
		FileListItr itr = m_pModMap->find(CFileIO(file).GetFullFilename().ToLower().c_str());
-
 
146
		if ( itr == m_pModMap->end() ) itr = m_pModMap->find(CFileIO(_convertExtension(file)).GetFullFilename().ToLower().c_str());
-
 
147
		if ( itr != m_pModMap->end() ) return itr->second;
-
 
148
	}
-
 
149
	else if ( m_pMap && !m_pMap->empty() ) {
-
 
150
		if ( !m_sAddon.empty() ) {
-
 
151
			FileListItr aitr = m_pMap->find(CFileIO(m_sAddon + "/" + file).GetFullFilename().ToLower().c_str());
-
 
152
			if ( aitr == m_pMap->end() ) aitr = m_pMap->find(CFileIO(_convertExtension(m_sAddon + "/" + file)).GetFullFilename().ToLower().c_str());
-
 
153
			if ( aitr != m_pMap->end() ) return aitr->second;
-
 
154
		}
-
 
155
		FileListItr itr = m_pMap->find(CFileIO(file).GetFullFilename().ToLower().c_str());
-
 
156
		if ( itr == m_pMap->end() ) itr = m_pMap->find(CFileIO(_convertExtension(file)).GetFullFilename().ToLower().c_str());
-
 
157
		if ( itr != m_pMap->end() ) return itr->second;
-
 
158
	}
-
 
159
	return "";
-
 
160
}
-
 
161
 
-
 
162
bool CVirtualFileSystem::ExtractGameFile(const Utils::String &file, const Utils::String &to)
-
 
163
{
79
	CyString sIn = GetFile(file);
164
	Utils::String sIn = findFile(file);
80
	if ( sIn.Empty() ) return false;
165
	if ( sIn.empty() ) return false;
81
 
166
 
82
	CCatFile catFile;
167
	CCatFile catFile;
83
	if ( catFile.Open(sIn, m_sAddon, CATREAD_CATDECRYPT, false) == CATERR_NONE )
168
	if ( catFile.Open(sIn, m_sAddon, CATREAD_CATDECRYPT, false) == CATERR_NONE )
84
	{
169
	{
85
		// check for the file
170
		// check for the file
Line 92... Line 177...
92
		}
177
		}
93
	}
178
	}
94
	return false;
179
	return false;
95
}
180
}
96
 
181
 
-
 
182
Utils::String CVirtualFileSystem::_convertExtension(const Utils::String &sFile)
-
 
183
{
-
 
184
	CFileIO File(sFile);
-
 
185
	if ( File.CheckFileExtension("pck") ) {
-
 
186
		return File.ChangeFileExtension("xml").ToString();
-
 
187
	}
-
 
188
	else if ( File.CheckFileExtension("xml") ) {
-
 
189
		return File.ChangeFileExtension("pck").ToString();
-
 
190
	}
-
 
191
	else if ( File.CheckFileExtension("pbb") ) {
-
 
192
		return File.ChangeFileExtension("bob").ToString();
-
 
193
	}
-
 
194
	else if ( File.CheckFileExtension("bob") ) {
-
 
195
		return File.ChangeFileExtension("pbb").ToString();
-
 
196
	}
-
 
197
	else if ( File.CheckFileExtension("pbd") ) {
-
 
198
		return File.ChangeFileExtension("bod").ToString();
-
 
199
	}
-
 
200
	else if ( File.CheckFileExtension("bod") ) {
-
 
201
		return File.ChangeFileExtension("pbd").ToString();
-
 
202
	}
-
 
203
 
-
 
204
	return sFile;
-
 
205
}
-
 
206
 
-
 
207
CyStringList *CVirtualFileSystem::GetTShipsEntries()
-
 
208
{
-
 
209
	if ( this->ExtractGameFile("types/tships.pck", "tships.txt") ) {
-
 
210
		CFileIO TShips("tships.txt");
-
 
211
		if ( TShips.Exists() )
-
 
212
		{
-
 
213
			CyStringList *lines = TShips.ReadLinesStr();
-
 
214
			if ( lines )
-
 
215
			{
-
 
216
				// remove any commands, blank lines, and start
-
 
217
				// and put the id as the data
-
 
218
				int entries = -1;
-
 
219
				for ( SStringList *str = lines->Head(); str; str = str->next )
-
 
220
				{
-
 
221
					str->str.RemoveFirstSpace();
-
 
222
					str->str.RemoveChar(9);
-
 
223
					str->str.RemoveChar('\r');
-
 
224
					str->str.RemoveChar('\n');
-
 
225
					if ( str->str.Empty() )
-
 
226
					{
-
 
227
						str->remove = true;
-
 
228
						continue;
-
 
229
					}
-
 
230
 
-
 
231
					if ( str->str[0] == '/' )
-
 
232
					{
-
 
233
						str->remove = true;
-
 
234
						continue;
-
 
235
					}
-
 
236
 
-
 
237
					if ( entries == -1 )
-
 
238
					{
-
 
239
						entries = str->str.GetToken(";", 2, 2).ToInt();
-
 
240
						str->remove = true;
-
 
241
						continue;
-
 
242
					}
-
 
243
 
-
 
244
					// hopefully we now have a valid tships line
-
 
245
					int num = -1;
-
 
246
					while ( str->data.Empty() )
-
 
247
						str->data = str->str.GetToken(";", num--, (num + 2));
-
 
248
				}
-
 
249
			}
-
 
250
			// remove the tmp file
-
 
251
			TShips.Remove();
-
 
252
 
-
 
253
			if ( lines )
-
 
254
				lines->RemoveMarked();
-
 
255
			return lines;
-
 
256
		}
-
 
257
	}
-
 
258
 
-
 
259
	return NULL;
-
 
260
}
-
 
261
 
-
 
262
C_File *CVirtualFileSystem::extractGameFileToPackage(CBaseFile *pPackage, const Utils::String &sFile, FileType iFileType)
-
 
263
{
-
 
264
	return this->extractGameFileToPackage(pPackage, sFile, iFileType, sFile);
-
 
265
}
-
 
266
 
-
 
267
C_File *CVirtualFileSystem::extractGameFileToPackage(CBaseFile *pPackage, const Utils::String &sFile, FileType iFileType, const Utils::String &sTo)
-
 
268
{
-
 
269
 
-
 
270
	if ( this->ExtractGameFile(sFile, "tmp") ) {
-
 
271
		CFileIO File("tmp");
-
 
272
 
-
 
273
		C_File *f = pPackage->AddFile(CFileIO(sTo).GetFilename(), CFileIO(sTo).GetDir(), iFileType);
-
 
274
		if ( f ) {
-
 
275
			if ( f->ReadFromFile("tmp") ) {
-
 
276
				File.Remove();
-
 
277
				return f;
-
 
278
			}
-
 
279
		}
-
 
280
 
-
 
281
		File.Remove();
-
 
282
	}
-
 
283
 
-
 
284
	return NULL;
-
 
285
}
-
 
286
 
-
 
287
Utils::String CVirtualFileSystem::getTShipsEntry(const Utils::String &sId)
-
 
288
{
-
 
289
	CyStringList *ships = this->GetTShipsEntries();
-
 
290
	if ( ships )
-
 
291
	{
-
 
292
		SStringList *node = ships->FindData(CyString(sId).upper());
-
 
293
		if ( node )
-
 
294
			return node->str.ToString();
-
 
295
	}
-
 
296
	return "";
-
 
297
}
-
 
298
 
-
 
299
void CVirtualFileSystem::extractTexts(CXspFile *pPackage, int textId)
-
 
300
{
-
 
301
	//TODO: check for better finding of files in map
-
 
302
	for ( FileListItr itr = m_pMap->begin(); itr != m_pMap->end(); ++itr ) {
-
 
303
		Utils::String str = itr->first;
-
 
304
 
-
 
305
		if ( !m_sAddon.empty() ) {
-
 
306
			if ( !str.left(m_sAddon.length() + 3).Compare(m_sAddon + "/t/") && !str.left(m_sAddon.length() + 3).Compare(m_sAddon + "\\t\\") )
-
 
307
				continue;
-
 
308
		}
-
 
309
		else {
-
 
310
			if ( !str.left(2).Compare("t\\") && !str.left(2).Compare("t/") && !str.left(8).Compare("addon\t\\") && !str.left(8).Compare("addon/t/") )
-
 
311
				continue;
-
 
312
		}
-
 
313
 
-
 
314
		if ( this->ExtractGameFile(str, "tmp") ) {
-
 
315
			pPackage->AddTextFromFile("tmp", textId);
-
 
316
			CFileIO("tmp").Remove();
-
 
317
		}
-
 
318
	}
-
 
319
}
-
 
320
 
-
 
321
void CVirtualFileSystem::updateTexts(int iFromPage, int iToPage)
-
 
322
{
-
 
323
	this->_updateTexts(iFromPage, iToPage, m_pMap, m_pTexts);
-
 
324
}
-
 
325
void CVirtualFileSystem::updateTexts(int iPage)
-
 
326
{
-
 
327
	this->_updateTexts(iPage, iPage, m_pMap, m_pTexts);
-
 
328
}
-
 
329
void CVirtualFileSystem::updateModTexts(int iFromPage, int iToPage)
-
 
330
{
-
 
331
	this->_updateTexts(iFromPage, iToPage, m_pModMap, m_pModTexts);
-
 
332
}
-
 
333
void CVirtualFileSystem::updateModTexts(int iPage)
-
 
334
{
-
 
335
	this->_updateTexts(iPage, iPage, m_pModMap, m_pModTexts);
-
 
336
}
-
 
337
 
-
 
338
void CVirtualFileSystem::_clear()
-
 
339
{
-
 
340
	m_bLoaded = false;
-
 
341
 
-
 
342
	if ( m_pMap ) delete m_pMap;
-
 
343
	m_pMap = new FileList;
-
 
344
	if ( m_pModMap ) delete m_pModMap;
-
 
345
	m_pModMap = new FileList;
-
 
346
}
-
 
347
 
-
 
348
void CVirtualFileSystem::_updateTexts(int iFromPage, int iToPage, FileList *pFileList, CTextDB *pTextList)
-
 
349
{
-
 
350
	// read all text files
-
 
351
	for ( FileListItr itr = pFileList->begin(); itr != pFileList->end(); ++itr ) {
-
 
352
		Utils::String str = itr->first;
-
 
353
 
-
 
354
		if ( !m_sAddon.empty() ) {
-
 
355
			if ( !str.left(m_sAddon.length() + 3).Compare(m_sAddon + "/t/") && !str.left(m_sAddon.length() + 3).Compare(m_sAddon + "\\t\\") )
-
 
356
				continue;
-
 
357
		}
-
 
358
		else {
-
 
359
			if ( !str.left(2).Compare("t\\") && !str.left(2).Compare("t/") )
-
 
360
				continue;
-
 
361
		}
-
 
362
 
-
 
363
		if ( this->ExtractGameFile(str, "tmp") ) {
-
 
364
			// add all texts into the map, id=(pageid, tid) data=text
-
 
365
			Utils::String baseFile = CFileIO(str).GetBaseName().ToString();
-
 
366
			int lang = (baseFile.isin("-L")) ? baseFile.right(3) : baseFile.truncate(-4);
-
 
367
 
-
 
368
			if ( m_iLang && lang != m_iLang ) continue;
-
 
369
			// open the text file to add
-
 
370
			pTextList->parseTextFile(iFromPage, iToPage, "tmp", lang);
-
 
371
		}
-
 
372
	}
-
 
373
}
-
 
374
 
-
 
375
void CVirtualFileSystem::clearMods()
-
 
376
{
-
 
377
	if ( m_pTexts ) delete m_pTexts;
-
 
378
	m_pTexts = new CTextDB();
-
 
379
	if ( m_pModTexts ) delete m_pModTexts;
-
 
380
	m_pModTexts = new CTextDB();
-
 
381
}
-
 
382
 
-
 
383
bool CVirtualFileSystem::loadShipData(CyStringList *list)
-
 
384
{
-
 
385
	bool ret = false;
-
 
386
 
-
 
387
	if ( this->ExtractGameFile("types/TShips.pck", "tmp") ) {
-
 
388
		CFileIO File("tmp");
-
 
389
		CyStringList *lines = File.ReadLinesStr();
-
 
390
		if ( lines )
-
 
391
		{
-
 
392
			bool readFirst = false;
-
 
393
			for ( SStringList *str = lines->Head(); str; str = str->next )
-
 
394
			{
-
 
395
				if ( str->str.Empty() )
-
 
396
					continue;
-
 
397
				str->str.RemoveChar('\r');
-
 
398
				str->str.RemoveChar(9);
-
 
399
				str->str.RemoveFirstSpace();
-
 
400
				if ( str->str.Empty() )
-
 
401
					continue;
-
 
402
				if ( str->str[0] == '/' || str->str[0] == '#' )
-
 
403
					continue;
-
 
404
 
-
 
405
				if ( !readFirst )
-
 
406
					readFirst = true;
-
 
407
				else
-
 
408
				{
-
 
409
					CyString t = str->str.GetToken(";", -2);
-
 
410
					while ( t.Right(1) == ";" )
-
 
411
						t.Truncate((int)t.Length() - 1);
-
 
412
					list->PushBack(t, str->str);
-
 
413
				}
-
 
414
			}
-
 
415
 
-
 
416
			delete lines;
-
 
417
			ret = true;
-
 
418
		}
-
 
419
 
-
 
420
		File.Remove();
-
 
421
	}
-
 
422
 
-
 
423
	return ret;
-
 
424
}
-
 
425
 
-
 
426
 
-
 
427
} //NAMESPACE