Subversion Repositories spk

Rev

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