Subversion Repositories spk

Rev

Rev 126 | Rev 160 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 cycrow 1
#include "GameExe.h"
2
#include "File_IO.h"
3
#include "DirIO.h"
4
 
5
/**
6
 * Add Exe
7
 *
8
 * Adds an exe name available
9
 */
56 cycrow 10
int CGameExe::AddExe(const Utils::String &exe)
1 cycrow 11
{
12
	// search if it already exists
57 cycrow 13
	int iCount = this->_findExe(exe);
14
	if ( iCount != -1 ) return iCount;
1 cycrow 15
 
16
	// not found, we need to add
17
	SGameExe *sExe = new SGameExe;
18
	sExe->sExe = exe;
19
	sExe->iName = 0;
20
	sExe->iFlags = 0;
21
	sExe->iMaxPatch = 1;
22
	sExe->iAddonTo = 0;
57 cycrow 23
	sExe->iTextNum = 0;
1 cycrow 24
 
25
	m_lExe.push_back(sExe);
26
 
27
	return m_lExe.size() - 1;
28
}
29
 
30
/**
31
 * Find Exe
32
 *
33
 * Find an exe and return its position in the file
34
 *
35
 * Argument:	exe,	String - name of the exe file to find
36
 */
57 cycrow 37
int CGameExe::_findExe(const Utils::String &exe) const
1 cycrow 38
{
121 cycrow 39
	CFileIO File(exe);
40
	Utils::String e = File.filename();
41
 
1 cycrow 42
	int count = 0;
43
	for ( CListNode<SGameExe> *node = m_lExe.Front(); node; node = node->next() )
44
	{
121 cycrow 45
		if ( node->Data()->sExe.Compare(e) )
1 cycrow 46
			return count;
47
		++count;
48
	}
49
 
50
	return -1;
51
}
52
 
121 cycrow 53
SGameExe *CGameExe::gameExe(const Utils::String &exe) const
1 cycrow 54
{
57 cycrow 55
	int e = this->_findExe(exe);
1 cycrow 56
	if ( e < 0 ) return NULL;
121 cycrow 57
	return m_lExe.Get(e);
1 cycrow 58
}
59
 
121 cycrow 60
int CGameExe::_findVersion(int exe, int size, Utils::String *fVersion) const
1 cycrow 61
{
57 cycrow 62
	if ( fVersion ) *fVersion = -1.0;
63
	if ( exe < 0 ) return -1;
1 cycrow 64
 
65
	SGameExe *gameExe = m_lExe[exe];
57 cycrow 66
	if ( !gameExe ) return -1;
1 cycrow 67
 
68
	int count = 0;
57 cycrow 69
	for ( CListNode<SGameExeVersion> *node = gameExe->lVersions.Front(); node; node = node->next() ) {
70
		for ( CListNode<int> *iNode = node->Data()->lSize.Front(); iNode; iNode = iNode->next() ) {
1 cycrow 71
			int checkSize = *iNode->Data();
57 cycrow 72
			if ( checkSize == size ) {
1 cycrow 73
				*fVersion = node->Data()->fVersion;
74
				return count;
75
			}
76
		}
77
 
78
		++count;
79
	}
80
 
81
	return -1;
82
}
83
 
56 cycrow 84
int CGameExe::FindVersion(const Utils::String &exe, int size, Utils::String *fVersion)
1 cycrow 85
{
57 cycrow 86
	int iExe = this->_findExe(exe);
1 cycrow 87
	if ( iExe < 0 )
88
		return -1;
89
 
57 cycrow 90
	int iVersion = this->_findVersion(iExe, size, fVersion);
1 cycrow 91
	if ( iVersion < 0 )
92
		return -2 - iExe;
93
 
94
	return -1;
95
}
96
 
56 cycrow 97
Utils::String CGameExe::GetModKey(int game)
1 cycrow 98
{
56 cycrow 99
	if ( game < 0 )	return "";
1 cycrow 100
	SGameExe *sExe = m_lExe[game];
56 cycrow 101
	if ( !sExe ) return "";
1 cycrow 102
 
103
	return sExe->sModKey;
104
}
105
 
125 cycrow 106
void CGameExe::GetDirectoryData(GameDirectory *gameDir) const
107
{
108
	if (!gameDir)
109
		return;
110
	if (CDirIO::Exists(gameDir->dir))
111
	{
112
		gameDir->exe = this->GetGameRunExe(gameDir->dir);
113
		if (CDirIO::Exists(gameDir->exe))
114
		{
115
			int id = _findExe(gameDir->exe);
116
			SGameExe *exe = m_lExe.Get(id);
117
			if (exe)
118
			{
119
				gameDir->addon = exe->sAddon;
120
				gameDir->name = exe->sName;
121
				if (exe->iFlags & EXEFLAG_MYDOCLOG)
122
					gameDir->logdir = exe->sMyDoc;
123
				else
124
					gameDir->logdir = gameDir->dir;
125
				gameDir->basename = exe->sName;
126
			}
127
 
128
			this->GetGameVersion(gameDir->exe, &gameDir->version);
129
			gameDir->name = this->GetGameName(gameDir->exe);
130
		}
131
	}
132
}
133
 
134
 
56 cycrow 135
void CGameExe::ParseExe(const Utils::String &line)
1 cycrow 136
{
137
	// get the exe file
56 cycrow 138
	Utils::String exe = line.token(":", 1);
139
	int iTextNum = -1;
58 cycrow 140
	if ( exe.isin("|") ) {
141
		iTextNum = exe.token("|", 2);
142
		exe = exe.token("|", 1);
56 cycrow 143
	}
144
 
1 cycrow 145
	int iExe = this->AddExe(exe);
146
 
147
	SGameExe *sExe = m_lExe[iExe];
56 cycrow 148
	sExe->iMaxPatch = line.token(":", 2);
149
	sExe->iFlags = this->ParseFlags(line.token(":", 3));
150
	sExe->sModKey = line.token(":", 4);
151
	sExe->iTextNum = iTextNum;
1 cycrow 152
 
153
	// get the name
56 cycrow 154
	Utils::String gameName = line.token(":", 5);
1 cycrow 155
	this->_SetExeName(&sExe->sName, &sExe->iName, gameName);
156
 
157
	// get mydocs
56 cycrow 158
	sExe->sMyDoc = line.token(":", 6);
1 cycrow 159
 
160
	// now get the versions
161
	int pos = EXE_VERSIONPOS;
162
	int namestart = EXE_VERSION_NAMESTART;
163
	int sizestart = EXE_VERSION_SIZESTART;
164
 
165
	if ( sExe->iFlags & EXEFLAG_ADDON ) {
166
		++pos;
167
		++namestart;
168
		++sizestart;
56 cycrow 169
		sExe->sAddon = line.token(":", EXE_VERSIONPOS);
170
		if ( sExe->sAddon.isin("!") ) {
57 cycrow 171
			sExe->iAddonTo = this->_findExe(sExe->sAddon.token("!", 2));
56 cycrow 172
			sExe->sAddon = sExe->sAddon.token("!", 1);
1 cycrow 173
		}
174
	}
175
 
56 cycrow 176
	int iVersions = line.token(":", pos);
1 cycrow 177
	int i;
178
 
179
	for ( i = 0; i < iVersions; i++ )
180
	{
181
		SGameExeVersion *sGameVersion = new SGameExeVersion;
182
		sGameVersion->iName = 0;
56 cycrow 183
		sGameVersion->fVersion = line.token(":", namestart + (i * 2)).token(" ", 1);
1 cycrow 184
 
56 cycrow 185
		Utils::String sSize = line.token(":", sizestart + (i * 2));
1 cycrow 186
		// multiple versions available, we need to split them up
56 cycrow 187
		if ( sSize.isin("!") ) {
1 cycrow 188
			int max = 0;
56 cycrow 189
			Utils::String *sizes = sSize.tokenise("!", &max);
190
			if ( sizes && max ) {
191
				for ( int j = 0; j < max; j++ ) {
1 cycrow 192
					int *size = new int;
56 cycrow 193
					(*size) = sizes[j];
194
					if ( *size ) sGameVersion->lSize.push_back(size);
1 cycrow 195
				}
196
				CLEANSPLIT(sizes, max);
197
			}
198
		}
56 cycrow 199
		else {
1 cycrow 200
			int *size = new int;
56 cycrow 201
			(*size) = sSize;
202
			if ( *size ) sGameVersion->lSize.push_back(size);
1 cycrow 203
		}
204
 
56 cycrow 205
		if ( !sGameVersion->lSize.empty() )	{
1 cycrow 206
			// finally, add the version names
56 cycrow 207
			this->_SetExeName(&sGameVersion->sName, &sGameVersion->iName, line.token(":", namestart + (i * 2)));
1 cycrow 208
			sExe->lVersions.push_back(sGameVersion);
209
		}
210
	}
211
}
212
 
56 cycrow 213
int CGameExe::ParseFlags(const Utils::String &flags)
1 cycrow 214
{
215
	int max;
56 cycrow 216
	Utils::String *sFlags = flags.tokenise("|", &max);
217
	if ( !sFlags || !max ) return EXEFLAG_NONE;
1 cycrow 218
 
219
	int f = 0;
56 cycrow 220
	for ( int i = 0; i < max; i++ ) {
221
		Utils::String str = sFlags[i];
1 cycrow 222
		if ( str.Compare("TC_TEXT") )
223
			f |= EXEFLAG_TCTEXT;
224
		else if ( str.Compare("NO_XOR") )
225
			f |= EXEFLAG_NOXOR;
226
		else if ( str.Compare("ADDON") )
227
			f |= EXEFLAG_ADDON;
228
		else if ( str.Compare("MYDOCLOG") )
229
			f |= EXEFLAG_MYDOCLOG;
230
		else if ( str.Compare("NOSAVESUBDIR") )
231
			f |= EXEFLAG_NOSAVESUBDIR;
56 cycrow 232
		else {
233
			if ( str.isNumber() )
234
				f |= (long)str;
1 cycrow 235
		}
236
	}
237
 
238
	CLEANSPLIT(sFlags, max);
239
 
240
	return f;
241
}
242
 
56 cycrow 243
void CGameExe::_SetExeName(Utils::String *sName, int *iName, const Utils::String &n)
1 cycrow 244
{
56 cycrow 245
	Utils::String str = n;
246
	if ( n.isin("!") )
1 cycrow 247
	{
56 cycrow 248
		Utils::String gameNum = str.token("!", 1);
249
		str = str.token("!", 2);
1 cycrow 250
 
56 cycrow 251
		if ( gameNum.isNumber() )
252
			*iName = gameNum;
1 cycrow 253
		else
254
			*sName = gameNum;
255
	}
256
 
56 cycrow 257
	if ( str.isNumber() )
258
		*iName = str;
1 cycrow 259
	else
56 cycrow 260
		*sName = str;
1 cycrow 261
}
262
 
263
void CGameExe::Reset()
264
{
265
	for ( CListNode<SGameExe> *node = m_lExe.Front(); node; node = node->next() )
266
	{
267
		for ( CListNode<SGameExeVersion> *vNode = node->Data()->lVersions.Front(); vNode; vNode = vNode->next() )
268
			vNode->Data()->lSize.MemoryClear();
269
		node->Data()->lVersions.MemoryClear();
270
	}
271
	m_lExe.MemoryClear();
272
}
273
 
56 cycrow 274
bool CGameExe::ReadFile(const Utils::String &file)
1 cycrow 275
{
56 cycrow 276
	CFileIO File(file);
277
	if ( !File.startRead() ) return false;
1 cycrow 278
 
56 cycrow 279
	while ( !File.atEnd() ) {
280
		Utils::String line = File.readEndOfLine();
281
		line.removeFirstSpace();
282
		if ( line.empty() ) continue;
283
		if ( line[0] == '/' ) continue;
1 cycrow 284
		this->ParseExe(line);
285
	}
56 cycrow 286
	File.close();
1 cycrow 287
	return true;
288
}
289
 
121 cycrow 290
Utils::String CGameExe::GetGameRunExe(const Utils::String &dir) const
1 cycrow 291
{
292
	CDirIO Dir(dir);
293
	int count = 0;
294
	for ( CListNode<SGameExe> *node = m_lExe.Front(); node; node = node->next() )
295
	{
296
		SGameExe *exe = node->Data();
121 cycrow 297
		if ( Dir.exists(exe->sExe) )
1 cycrow 298
			return dir + "/" + exe->sExe;
56 cycrow 299
		if ( !exe->sAddon.empty() ) {
121 cycrow 300
			if ( Dir.topDir().Compare(exe->sAddon) )
1 cycrow 301
				return this->GetGameDir(dir) + "/" + exe->sExe;
302
		}
303
		++count;
304
	}
305
 
56 cycrow 306
	return "";
1 cycrow 307
}
308
 
125 cycrow 309
Utils::String CGameExe::GetGameBaseName(const Utils::String &gameExe) const
1 cycrow 310
{
311
	int gameType = this->GetGameType(gameExe);
121 cycrow 312
	Utils::String gameDir = this->GetProperDir(gameExe);
313
	Utils::String gameName = this->ExtractGameName(gameDir);
125 cycrow 314
	if (gameName.empty())	gameName = this->GetGameNameFromType(gameType);
1 cycrow 315
 
125 cycrow 316
	return gameName;
317
}
318
 
319
Utils::String CGameExe::GetGameName(const Utils::String &gameExe) const
320
{
321
	Utils::String gameName = GetGameBaseName(gameExe);
322
	if (gameName.empty()) return "";
323
 
1 cycrow 324
	// no version
56 cycrow 325
	Utils::String fVersion;
326
	Utils::String versionName;
1 cycrow 327
 
125 cycrow 328
	if ( this->GetGameVersionName(gameExe, &versionName) ) 
329
	{
56 cycrow 330
		if ( !versionName.empty() )
1 cycrow 331
			return gameName + " V" + versionName;
332
		else
333
			return gameName;
334
	}
335
 
125 cycrow 336
	int gameType = this->GetGameType(gameExe);
56 cycrow 337
	Utils::String sGameVersion = this->GetGameVersionFromType(gameType, this->GetGameVersion(gameExe, &fVersion), fVersion);
338
	if ( sGameVersion.empty() )
1 cycrow 339
	{
56 cycrow 340
		if ( !fVersion.empty() )
1 cycrow 341
			return gameName + " V" + fVersion;
342
		else
343
			return gameName;
344
	}
345
 
346
	// return the name and the version
347
	return gameName + " " + sGameVersion;
348
}
349
 
350
 
121 cycrow 351
int CGameExe::GetGameAddons(const Utils::String &dir, Utils::CStringList &exes)
1 cycrow 352
{
353
	int count = 0;
354
 
355
	CDirIO Dir(dir);
356
 
357
	for ( CListNode<SGameExe> *node = m_lExe.Front(); node; node = node->next() )
358
	{
359
		SGameExe *exe = node->Data();
360
		if ( !(exe->iFlags & EXEFLAG_ADDON) )
361
			continue;
121 cycrow 362
		if ( Dir.exists(exe->sExe) ) {
363
			if ( Dir.exists(exe->sAddon) ) {			
364
				exes.pushBack(exe->sExe, exe->sAddon);
1 cycrow 365
				++count;
366
			}
367
		}
368
	}
369
 
370
	return count;
371
}
372
 
121 cycrow 373
Utils::String CGameExe::GetAddonDir(const Utils::String &dir) const
1 cycrow 374
{
375
	int gameType = this->GetGameType(dir);
376
	if ( gameType != -1 ) {
377
		return m_lExe[gameType]->sAddon;
378
	}
379
 
380
	return "";
381
}
382
 
121 cycrow 383
bool CGameExe::isAddon(const Utils::String &exe) const
1 cycrow 384
{
121 cycrow 385
	SGameExe *e = gameExe(exe);
386
	if (e && (e->iFlags & EXEFLAG_ADDON))
387
		return true;
388
 
389
	return false;
390
}
391
 
392
int CGameExe::getTextID(const Utils::String &dir) const
393
{
394
	SGameExe *e = gameExe(dir);
395
	if (e)
396
		return e->iTextNum;
397
 
398
	e = gameExe(this->GetGameRunExe(dir));
399
	if (e)
400
		return e->iTextNum;
401
 
402
	return 0;
403
}
404
 
405
Utils::String CGameExe::GetProperDir(const Utils::String &dir) const
406
{
1 cycrow 407
	CDirIO Dir(dir);
121 cycrow 408
 
1 cycrow 409
	int gameType = this->GetGameType(dir);
410
	if ( gameType != -1 ) {
56 cycrow 411
		if ( !m_lExe[gameType]->sAddon.empty() ) {
125 cycrow 412
			if ( CDirIO(dir).isFile() ) return this->GetGameDir(dir) + "/" + m_lExe[gameType]->sAddon;
121 cycrow 413
			return CDirIO(this->GetGameDir(dir)).dir(m_lExe[gameType]->sAddon);
1 cycrow 414
		}
415
	}
416
 
125 cycrow 417
	return CDirIO(dir).isFile() ? CFileIO(dir).dir() : dir;
1 cycrow 418
}
419
 
420
int CGameExe::GetGameFlags(int game)
421
{
422
	if ( game == -1 )
423
		return 0;
424
 
425
	SGameExe *exe = m_lExe[game];
426
	if ( !exe )
427
		return 0;
428
 
429
	return exe->iFlags;
430
}
431
 
432
int CGameExe::GetMaxPatch(int game)
433
{
434
	if ( game == -1 )
435
		return 0;
436
 
437
	SGameExe *exe = m_lExe[game];
438
	if ( !exe )
439
		return 0;
440
 
441
	return exe->iMaxPatch;
442
}
443
 
121 cycrow 444
Utils::String CGameExe::GetGameNameFromType(int type) const
1 cycrow 445
{
56 cycrow 446
	if ( type == -1 ) return "";
1 cycrow 447
 
121 cycrow 448
	SGameExe *exe = m_lExe.Get(type);
56 cycrow 449
	if ( !exe ) return "";
1 cycrow 450
 
451
	return exe->sName;
452
}
453
 
121 cycrow 454
Utils::String CGameExe::GetGameVersionFromType(int game, int gameVersion, const Utils::String &fGameVersion) const
1 cycrow 455
{
456
	SGameExe *exe = m_lExe[game];
56 cycrow 457
	if ( !exe ) return "";
1 cycrow 458
 
459
	SGameExeVersion *version = exe->lVersions[gameVersion];
460
	if ( !version )
461
	{
56 cycrow 462
		if ( !fGameVersion.empty() ) return fGameVersion;
463
		return "";
1 cycrow 464
	}
465
 
466
	return version->sName;
467
}
468
 
121 cycrow 469
Utils::String CGameExe::GetGameDir(const Utils::String &dir) const
1 cycrow 470
{
471
	CDirIO Dir(dir);
472
 
473
	for ( CListNode<SGameExe> *node = m_lExe.Front(); node; node = node->next() )
474
	{
475
		SGameExe *exe = node->Data();
125 cycrow 476
		if ( CDirIO(dir).isFile() ) {
56 cycrow 477
			if ( CFileIO(dir).filename().Compare(exe->sExe) )
102 cycrow 478
				return CFileIO(dir).dir();
1 cycrow 479
		}
480
		else {
121 cycrow 481
			if ( Dir.exists(exe->sExe) ) return dir;
1 cycrow 482
			// check for addon dir
56 cycrow 483
			if ( !exe->sAddon.empty() ) {
121 cycrow 484
				if ( exe->sAddon.Compare(Dir.topDir()) )
125 cycrow 485
					return Dir.back();
1 cycrow 486
			}
487
		}
488
	}
489
 
490
	return dir;
491
}
126 cycrow 492
 
493
int CGameExe::findAddonType(const Utils::String &addon) const
494
{
495
	int i = 0;
496
	for (CListNode<SGameExe> *node = m_lExe.Front(); node; node = node->next())
497
	{
498
		SGameExe *exe = node->Data();
499
		if (exe->iFlags & EXEFLAG_ADDON)
500
		{
501
			if (exe->sAddon.Compare(addon))
502
				return i;
503
		}
504
		++i;
505
	}
506
 
507
	return -1;
508
}
509
 
121 cycrow 510
int CGameExe::GetGameType(const Utils::String &gameExe) const
1 cycrow 511
{
95 cycrow 512
	CDirIO Dir (gameExe);
1 cycrow 513
	int count = 0;
514
 
515
	for ( CListNode<SGameExe> *node = m_lExe.Front(); node; node = node->next() )
516
	{
517
		SGameExe *exe = node->Data();
125 cycrow 518
		if ( CDirIO(gameExe).isFile() ) {
56 cycrow 519
			if ( CFileIO(gameExe).filename().Compare(exe->sExe) )
1 cycrow 520
				return count;
521
		}
522
		else {
121 cycrow 523
			if ( Dir.exists(exe->sExe) )
1 cycrow 524
				return count;
525
			// check for addon dir
56 cycrow 526
			if ( !exe->sAddon.empty() ) {
121 cycrow 527
				if ( exe->sAddon.Compare(Dir.topDir()) )
1 cycrow 528
					return count;
529
			}
530
		}
531
		++count;
532
	}
533
 
534
	return -1;
535
}
536
 
121 cycrow 537
Utils::String CGameExe::ExtractGameName(const Utils::String &gameDir) const
1 cycrow 538
{
121 cycrow 539
	Utils::String dir = this->GetProperDir(gameDir);
540
	CDirIO Dir(dir);
1 cycrow 541
 
121 cycrow 542
	Utils::String sText = this->_extractTextData(this->_readTextFile(dir), 1910, 1216, this->getTextID(gameDir));
56 cycrow 543
	if ( sText.empty() ) return "";
544
	int end = sText.findPos("\\n");
545
	if ( end >= 0 ) return sText.left(end);
1 cycrow 546
 
56 cycrow 547
	return "";
548
}
549
 
121 cycrow 550
Utils::String CGameExe::_textFileName(const Utils::String &sGameDir) const
56 cycrow 551
{
121 cycrow 552
	int lang = 44;
553
 
56 cycrow 554
	CDirIO Dir(sGameDir);
121 cycrow 555
	if (Dir.exists("t"))
556
	{
557
		if (Dir.exists("t/0002.pck")) return "t/0002.pck";
558
		else if (Dir.exists("t/0002.xml")) return "t/0002.xml";
559
		else if (Dir.exists(Utils::String::Format("t/%d0002.pck", lang))) return Utils::String::Format("t/%d0002.pck", lang);
560
		else if (Dir.exists(Utils::String::Format("t/%d0002.xml", lang))) return Utils::String::Format("t/%d0002.xml", lang);
561
		else if (Dir.exists(Utils::String::Format("t/0002-L%03d.pck", lang))) return Utils::String::Format("t/0002-L%03d.pck", lang);
562
		else if (Dir.exists(Utils::String::Format("t/0002-L%03d.xml", lang))) return Utils::String::Format("t/0002-L%03d.xml", lang);
563
	}
56 cycrow 564
	return "";
565
}
566
 
121 cycrow 567
Utils::String CGameExe::_readTextFile(const Utils::String &sGameDir) const
56 cycrow 568
{
121 cycrow 569
	Utils::String textFileName = _textFileName(sGameDir);
570
	if ( !textFileName.empty() )
571
	{
56 cycrow 572
		Utils::String sVersion;
573
 
574
		CDirIO Dir(sGameDir);
1 cycrow 575
		CFileIO File(Dir.File(textFileName));
576
		size_t fileSize;
56 cycrow 577
		unsigned char *fileData = File.readAll(&fileSize);
121 cycrow 578
		if ( fileData && fileSize) 
579
		{
580
			if (CFileIO(textFileName).isFileExtension("pck"))
581
			{
582
				size_t newFileSize;
583
				unsigned char *pckData = UnPCKData((unsigned char *)fileData, fileSize, &newFileSize);
584
				delete fileData;
585
				pckData[newFileSize - 1] = '\0';
586
				Utils::String Data((char *)pckData);
587
				delete pckData;
588
				return Data;
589
			}
590
			else if (CFileIO(textFileName).isFileExtension("xml"))
591
			{
592
				Utils::String Data((char *)fileData);
593
				delete fileData;
594
				return Data;
595
			}
56 cycrow 596
		}
597
	}
1 cycrow 598
 
56 cycrow 599
	return "";
600
}
1 cycrow 601
 
121 cycrow 602
Utils::String CGameExe::_extractTextData(const Utils::String &sData, long iPage, long iID, int iGameID) const
56 cycrow 603
{
604
	Utils::String sID = Utils::String("<t id=\"") + iID + "\">";
605
 
121 cycrow 606
	if (iGameID > 0)
607
	{
608
		Utils::String sPage = Utils::String("<page id=\"") + Utils::String::Number(iGameID) + iPage + "\"";
609
 
610
		int startpage = sData.findPos(sPage);
611
		if (startpage >= 0) {
612
			int start = sData.findPos(sID, startpage);
613
			if (start >= 0) {
614
				start += sID.length();
615
				int end = sData.findPos("</t>", start);
616
				return sData.mid(start, end);
617
			}
1 cycrow 618
		}
619
	}
56 cycrow 620
 
121 cycrow 621
	{
622
		Utils::String sPage = Utils::String("<page id=\"") + iPage + "\"";
623
 
624
		int startpage = sData.findPos(sPage);
625
		if (startpage >= 0) {
626
			int start = sData.findPos(sID, startpage);
627
			if (start >= 0) {
628
				start += sID.length();
629
				int end = sData.findPos("</t>", start);
630
				return sData.mid(start, end);
631
			}
632
		}
633
	}
634
 
56 cycrow 635
	return "";
1 cycrow 636
}
637
 
121 cycrow 638
bool CGameExe::GetGameVersionName(const Utils::String &sGameExe, Utils::String *versionName) const
1 cycrow 639
{
56 cycrow 640
	int gameType = this->GetGameType(sGameExe);
1 cycrow 641
 
642
	if ( gameType == -1 )
643
		return false;
644
 
56 cycrow 645
	Utils::String gameExe = this->GetGameDir(sGameExe) + "/" + m_lExe[gameType]->sExe;
121 cycrow 646
	Utils::String gameDir = this->GetProperDir(gameExe);
1 cycrow 647
	int size = (int)CFileIO(gameExe).GetFilesize();
648
 
56 cycrow 649
	Utils::String fVersion;
57 cycrow 650
	int version = this->_findVersion(gameType, size, &fVersion);
1 cycrow 651
	// not matched version
652
	// lets read the text file
653
 
56 cycrow 654
	if ( version != -1 ) {
1 cycrow 655
		(*versionName) = this->GetGameVersionFromType(gameType, version, fVersion);
656
		return true;
657
	}
658
 
121 cycrow 659
	Utils::String sText = this->_extractTextData(this->_readTextFile(gameDir), 1910, 1216, this->getTextID(gameExe));
56 cycrow 660
	Utils::String sVersion = sText.between("Version ", ", ");
661
	if ( sVersion.empty() ) sVersion = sText.between("ver=", "&amp");
1 cycrow 662
 
56 cycrow 663
	if ( !sVersion.empty() ) {
664
		// lets match the version
665
		(*versionName) = sVersion;
666
		float fVersion = sVersion;
667
		SGameExe *gameExe = m_lExe[gameType];
668
		if ( gameExe )
1 cycrow 669
		{
56 cycrow 670
			int count = 0;
671
			int lower = -1;
672
			for ( CListNode<SGameExeVersion> *node = gameExe->lVersions.Front(); node; node = node->next() )
1 cycrow 673
			{
56 cycrow 674
				if ( (float)node->Data()->fVersion == fVersion )
1 cycrow 675
				{
56 cycrow 676
					(*versionName) = node->Data()->sName;
677
					return true;
1 cycrow 678
				}
56 cycrow 679
				++count;
1 cycrow 680
			}
681
 
56 cycrow 682
			version = lower;
683
		}				
1 cycrow 684
	}
685
 
686
	return true;
687
}
688
 
121 cycrow 689
int CGameExe::GetGameVersion(const Utils::String &sGameExe, Utils::String *a_fVersion) const
1 cycrow 690
{
56 cycrow 691
	Utils::String gameExe = sGameExe;
692
 
1 cycrow 693
	int gameType = this->GetGameType(gameExe);
694
 
695
	if ( gameType == -1 )
696
		return -1;
697
 
56 cycrow 698
	Utils::String gameDir = gameExe;
699
	if ( !m_lExe[gameType]->sAddon.empty() )
125 cycrow 700
		gameExe = CDirIO(gameExe).back() + "/" + m_lExe[gameType]->sExe;
1 cycrow 701
	else
702
		gameExe = gameExe + "/" + m_lExe[gameType]->sExe;
703
	int size = (int)CFileIO(gameExe).GetFilesize();
704
 
57 cycrow 705
	int version = this->_findVersion(gameType, size, a_fVersion);
1 cycrow 706
 
121 cycrow 707
	Utils::String sText = this->_extractTextData(this->_readTextFile(gameDir), 1910, 10000, this->getTextID(gameExe));
56 cycrow 708
	Utils::String sVersion = sText.between("ver=", "&amp");
1 cycrow 709
 
56 cycrow 710
	if ( !sVersion.empty() )
711
	{
712
		// lets match the version
713
		Utils::String fVersion = sVersion;
714
		if ( a_fVersion ) *a_fVersion = fVersion;
715
		SGameExe *gameExe = m_lExe[gameType];
716
		if ( gameExe ) {
717
			int count = 0;
718
			int lower = -1;
719
			for ( CListNode<SGameExeVersion> *node = gameExe->lVersions.Front(); node; node = node->next() )
1 cycrow 720
			{
56 cycrow 721
				if ( fVersion.compareVersion(node->Data()->fVersion) == COMPARE_OLDER )
722
					lower = count;
723
				if (  fVersion.compareVersion(node->Data()->fVersion) == COMPARE_SAME )
724
					return count;
725
				++count;
1 cycrow 726
			}
727
 
56 cycrow 728
			version = lower;
729
		}				
1 cycrow 730
	}
56 cycrow 731
 
1 cycrow 732
	return version;
733
}
734
 
735
int CGameExe::ConvertGameType(int gametype, int *version)
736
{
737
	int count = 0, game = 0;
738
 
739
	switch ( gametype )
740
	{
741
		case 1:
742
			*version = 0;
743
			return 1;
744
		case 2:
745
			*version = 0;
746
			return 2;
747
		case 3:
748
			*version = 1;
749
			return 2;
750
		case 4:
751
			*version = 0;
752
			return 3;
753
		case 5:
754
			*version = 1;
755
			return 3;
756
		case 6:
757
			*version = 2;
758
			return 3;
759
	}
760
 
761
	for ( CListNode<SGameExe> *node = m_lExe.Front(); node; node = node->next() )
762
	{
763
		++count;
764
		++game;
765
		SGameExe *exe = node->Data();
766
 
767
		// found the game type, the version is 0, which is any version
768
		if ( count == gametype )
769
		{
770
			*version = 0;
771
			return game;
772
		}
773
 
774
		int v = 0;
775
		for ( CListNode<SGameExeVersion> *vNode = exe->lVersions.Front(); vNode; vNode = vNode->next() )
776
		{
777
			++count;
778
			++v;
779
			if ( count == gametype )
780
			{
781
				*version = v;
782
				return game;
783
			}
784
		}
785
	}
786
 
787
	// not found ?? just set to all versions
788
	*version = 0;
789
	return 0;
126 cycrow 790
}
791
 
792
SGameExe *CGameExe::GetGame(int game) const
793
{ 
794
	if (game >= 0 && game < m_lExe.size()) 
795
		return m_lExe.Get(game); 
796
	return NULL; 
797
}
127 cycrow 798
 
799
unsigned int CGameExe::gameCount() const
800
{
801
	return static_cast<unsigned int>(m_lExe.size());
802
}