Subversion Repositories spk

Rev

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

Rev 84 Rev 85
Line 20... Line 20...
20
	if ( m_bCatChanged ) {
20
	if ( m_bCatChanged ) {
21
		WriteCatFile ();
21
		WriteCatFile ();
22
		m_fCatFile.close();
22
		m_fCatFile.close();
23
	}
23
	}
24
 
24
 
-
 
25
	_clearFiles();
-
 
26
 
-
 
27
	if ( m_sData ) delete []m_sData;
-
 
28
}
-
 
29
 
-
 
30
void CCatFile::_clearFiles()
-
 
31
{
25
	for ( SInCatFile *c = m_lFiles.First(); c; c = m_lFiles.Next() )
32
	for ( SInCatFile *c = m_lFiles.First(); c; c = m_lFiles.Next() )
26
	{
33
	{
27
		if ( c->sData )
34
		if ( c->sData )
28
			delete []c->sData;
35
			delete []c->sData;
29
		delete c;
36
		delete c;
30
	}
37
	}
31
 
-
 
32
	if ( m_sData ) delete []m_sData;
-
 
33
 
38
 
34
	m_lFiles.clear();
39
	m_lFiles.clear();
35
}
40
}
36
 
41
 
37
bool CCatFile::IsAddonDir(CyString dir)
42
bool CCatFile::IsAddonDir(CyString dir)
38
{
43
{
39
	CyString d = dir;
44
	CyString d = dir;
40
	d = d.FindReplace("\\", "/");
45
	d = d.FindReplace("\\", "/");
41
	d = d.GetToken("/", 1, 1);
46
	d = d.GetToken("/", 1, 1);
42
 
47
 
43
	if ( d.Compare("types") )
48
	if ( d.Compare("types") )
Line 60... Line 65...
60
	return false;
65
	return false;
61
}
66
}
62
int CCatFile::Open ( CyString sCatfile, CyString addon, int readtype, bool create )
67
int CCatFile::Open ( CyString sCatfile, CyString addon, int readtype, bool create )
63
{
68
{
64
	Utils::String catfile = sCatfile.ToString();
69
	Utils::String catfile = sCatfile.ToString();
65
 
70
 
66
	m_bCreate = false;
71
	m_bCreate = false;
67
 
72
 
68
	Utils::String datfile;
73
	Utils::String datfile;
69
	if ( !catfile.right(4).Compare(".cat") ) {
74
	if ( !catfile.right(4).Compare(".cat") ) {
70
		datfile = catfile + ".dat";
75
		datfile = catfile + ".dat";
Line 75... Line 80...
75
	if ( readtype == CATREAD_JUSTCONTENTS ) create = false;
80
	if ( readtype == CATREAD_JUSTCONTENTS ) create = false;
76
 
81
 
77
	// first check if the dat file exists and opens
82
	// first check if the dat file exists and opens
78
	bool created = false;
83
	bool created = false;
79
	if ( readtype != CATREAD_JUSTCONTENTS ) {
84
	if ( readtype != CATREAD_JUSTCONTENTS ) {
80
		std::ifstream file(datfile);
-
 
81
		if ( !file.good() ) {
85
		if ( !CFileIO::Exists(datfile) ) {
82
			if ( create ) created = true;
86
			if ( create ) created = true;
83
			else		  return CATERR_NODATFILE;
87
			else		  return CATERR_NODATFILE;
84
		}
88
		}
85
 
-
 
86
		if ( file.is_open() ) file.close();
-
 
87
	}
89
	}
88
 
90
 
89
	// now open the cat file to read
91
	// now open the cat file to read
90
	CFileIO File(catfile);
92
	CFileIO File(catfile);
91
	if ( !File.startRead() ) {
93
	if ( !File.startRead() ) {
92
		if ( create ) created = true;
94
		if ( create ) created = true;
93
		else		  return CATERR_NOCATFILE;
95
		else		  return CATERR_NOCATFILE;
94
	}
96
	}
95
 
97
 
96
	if ( created ) {
98
	if ( created ) {
97
		m_fCatFile.Open(catfile);
99
		m_fCatFile.Open(catfile);
98
		m_fDatFile.Open(datfile);
100
		m_fDatFile.Open(datfile);
99
		m_bCreate = true;
101
		m_bCreate = true;
100
		return CATERR_CREATED;
102
		return CATERR_CREATED;
Line 102... Line 104...
102
 
104
 
103
	// find the file size
105
	// find the file size
104
	if ( !File.fileSize() ) {
106
	if ( !File.fileSize() ) {
105
		File.close();
107
		File.close();
106
		return CATERR_FILEEMPTY;
108
		return CATERR_FILEEMPTY;
107
	}
109
	}
108
 
110
 
109
	// size must be multiples of 5
111
	// size must be multiples of 5
110
	size_t size = File.fileSize() + ((File.fileSize() % 5) ? 5 - (File.fileSize() % 5) : 0);
112
	size_t size = File.fileSize() + ((File.fileSize() % 5) ? 5 - (File.fileSize() % 5) : 0);
111
 
113
 
112
	// read cat to buffer
114
	// read cat to buffer
113
	try {
115
	try {
Line 129... Line 131...
129
		return CATERR_READCAT;
131
		return CATERR_READCAT;
130
	}
132
	}
131
 
133
 
132
	m_sData[size] = 0;
134
	m_sData[size] = 0;
133
	m_iDataType = CATFILE_READ;
135
	m_iDataType = CATFILE_READ;
134
	File.close();
136
	File.close();
135
 
137
 
136
	if ( readtype != CATREAD_CAT ) {
138
	if ( readtype != CATREAD_CAT ) {
137
		if ( !DecryptData () ) return CATERR_DECRYPT;
139
		if ( !DecryptData () ) return CATERR_DECRYPT;
138
		m_sData[File.fileSize()] = 0;
140
		m_sData[File.fileSize()] = 0;
139
		ReadFiles ();
141
		readFiles ();
140
	}
142
	}
141
 
143
 
142
	m_sAddonDir = addon;
144
	m_sAddonDir = addon;
143
 
145
 
144
	m_fCatFile.Open ( catfile );
146
	m_fCatFile.Open ( catfile );
Line 151... Line 153...
151
		if ( m_fDatFile.startRead() ) {
153
		if ( m_fDatFile.startRead() ) {
152
			compare = m_fDatFile.fileSize();
154
			compare = m_fDatFile.fileSize();
153
			m_fDatFile.close();
155
			m_fDatFile.close();
154
		}
156
		}
155
		SInCatFile *c = m_lFiles.Back ()->Data();
157
		SInCatFile *c = m_lFiles.Back ()->Data();
156
		//if ( (c->lSize + c->lOffset) != compare ) return CATERR_MISMATCH;
158
		if ( (c->lSize + c->lOffset) != compare ) {
-
 
159
//			return CATERR_MISMATCH;
-
 
160
		}
157
	}
161
	}
158
 
162
 
159
	if ( readtype >= CATREAD_DAT ) LoadDatFile ();
163
	if ( readtype >= CATREAD_DAT ) LoadDatFile ();
160
 
164
 
161
	return CATERR_NONE;
165
	return CATERR_NONE;
162
}
166
}
163
 
167
 
164
bool CCatFile::RemoveFile ( CyString file )
168
bool CCatFile::RemoveFile ( CyString file )
165
{
169
{
166
	if ( !m_sAddonDir.Empty() ) {
170
	if ( !m_sAddonDir.Empty() ) {
167
		SInCatFile *f = FindData ( m_sAddonDir + "\\" + file );
171
		SInCatFile *f = FindData ( m_sAddonDir + "\\" + file );
168
		if ( f )
172
		if ( f )
169
			RemoveFile(f);
173
			RemoveFile(f);
170
	}
174
	}
171
	{
175
	{
172
		SInCatFile *f = FindData ( CyString("addon\\") + file );
176
		SInCatFile *f = FindData ( CyString("addon\\") + file );
173
		if ( f )
177
		if ( f )
174
			RemoveFile(f);
178
			RemoveFile(f);
Line 185... Line 189...
185
 
189
 
186
void CCatFile::LoadDatFile ()
190
void CCatFile::LoadDatFile ()
187
{
191
{
188
	if ( m_fDatFile.NoFile() )
192
	if ( m_fDatFile.NoFile() )
189
		return;
193
		return;
190
 
194
 
191
	if ( m_fDatFile.startRead() ) {
195
	if ( m_fDatFile.startRead() ) {
192
		for ( CListNode<SInCatFile> *node = m_lFiles.Front(); node; node = node->next() )
196
		for ( CListNode<SInCatFile> *node = m_lFiles.Front(); node; node = node->next() )
193
		{
197
		{
194
			SInCatFile *c = node->Data();
198
			SInCatFile *c = node->Data();
195
			if ( c->sData )	delete c->sData;
199
			if ( c->sData )	delete c->sData;
Line 214... Line 218...
214
		}
218
		}
215
		m_fDatFile.close();
219
		m_fDatFile.close();
216
	}
220
	}
217
}
221
}
218
 
222
 
219
bool CCatFile::ReadFiles ()
223
bool CCatFile::readFiles ()
220
{
224
{
221
	int num = 0;
-
 
222
 
-
 
223
	size_t offset = 0;
225
	size_t offset = 0;
-
 
226
	int max = 0;
-
 
227
 
-
 
228
	Utils::String *lines = Utils::String(m_sData).tokenise("\n", &max);
-
 
229
 
-
 
230
	_clearFiles();
-
 
231
 
-
 
232
	if ( lines && max ) {
-
 
233
		int start = 1;
-
 
234
		_sReadFilename = lines[0];
-
 
235
		if ( _sReadFilename.token(" ", -1).isNumber() ) {
-
 
236
			_sReadFilename.clear();
-
 
237
			start = 0;
-
 
238
		}
-
 
239
 
-
 
240
		for(int i = start; i < max; i++) {
-
 
241
			Utils::String l = lines[i];
-
 
242
 
-
 
243
			SInCatFile *catfile = new SInCatFile;
-
 
244
 
-
 
245
			catfile->lSize = static_cast<size_t>(l.token(" ", -1).toLong());
-
 
246
			catfile->sFile = l.tokens(" ", 1, -2);
-
 
247
			catfile->lOffset = offset;
-
 
248
			catfile->sData = 0;
-
 
249
 
-
 
250
			offset += catfile->lSize;
-
 
251
 
-
 
252
			m_lFiles.push_back ( catfile );
-
 
253
		}
-
 
254
	}
224
 
255
 
-
 
256
	CLEANSPLIT(lines, max);
-
 
257
/*
225
	unsigned char *data = m_sData;
258
	unsigned char *data = m_sData;
226
	int spacePos = -1;
259
	int spacePos = -1;
227
	while ( m_sData[num] != '\0' ) {
260
	while ( m_sData[num] != '\0' ) {
228
		if ( m_sData[num] == '\n' ) {
261
		if ( m_sData[num] == '\n' ) {
229
			m_sData[num] = 0;
262
			m_sData[num] = 0;
Line 259... Line 292...
259
		}
292
		}
260
		else if ( m_sData[num] == ' ' )
293
		else if ( m_sData[num] == ' ' )
261
			spacePos = num;
294
			spacePos = num;
262
		++num;
295
		++num;
263
	}
296
	}
264
 
297
*/
265
	return true;
298
	return true;
266
}
299
}
267
 
300
 
268
bool CCatFile::DecryptData ( unsigned char *data, size_t size )
301
bool CCatFile::DecryptData ( unsigned char *data, size_t size )
269
{
302
{
Line 304... Line 337...
304
{
337
{
305
	delete m_sData;
338
	delete m_sData;
306
	m_sData = NULL;
339
	m_sData = NULL;
307
	m_iDataType = CATFILE_NONE;
340
	m_iDataType = CATFILE_NONE;
308
	m_lSize = 0;
341
	m_lSize = 0;
309
}
342
}
310
 
343
 
311
bool CCatFile::ReadFileToData ( CyString filename )
344
bool CCatFile::ReadFileToData ( CyString filename )
312
{
345
{
313
	SInCatFile *c = FindData ( filename );
346
	SInCatFile *c = FindData ( filename );
314
	return ReadFileToData ( c );
347
	return ReadFileToData ( c );
Line 350... Line 383...
350
	if ( pFile->bDecrypted ) return;
383
	if ( pFile->bDecrypted ) return;
351
	pFile->bDecrypted = true;
384
	pFile->bDecrypted = true;
352
	this->DecryptDAT(pFile->sData, pFile->lSize);
385
	this->DecryptDAT(pFile->sData, pFile->lSize);
353
}
386
}
354
void CCatFile::DecryptDAT(unsigned char *buffer, size_t size)
387
void CCatFile::DecryptDAT(unsigned char *buffer, size_t size)
355
{
388
{
356
	for(unsigned char *pos=buffer, *end=buffer + size; pos < end; pos++){
389
	for(unsigned char *pos=buffer, *end=buffer + size; pos < end; pos++){
357
		*pos^=0x33;
390
		*pos^=0x33;
358
	}
391
	}
359
}
392
}
360
unsigned char *CCatFile::readData ( CyString filename, size_t *size )
393
unsigned char *CCatFile::readData ( CyString filename, size_t *size )
Line 391... Line 424...
391
	/*int iOffset = 0;
424
	/*int iOffset = 0;
392
	if ( iFiletype == FILETYPE_PCK ) {
425
	if ( iFiletype == FILETYPE_PCK ) {
393
		iOffset = 1;
426
		iOffset = 1;
394
		for(size_t i=0; i < c->lSize; i++){
427
		for(size_t i=0; i < c->lSize; i++){
395
			c->sData[i] ^= magic;
428
			c->sData[i] ^= magic;
396
		}
429
		}
397
	}
430
	}
398
	
431
	
399
 
432
 
400
	return UnPCKData ( c->sData + iOffset, c->lSize - iOffset, size );*/
433
	return UnPCKData ( c->sData + iOffset, c->lSize - iOffset, size );*/
401
	return UnPCKData(c->sData, c->lSize, size, (iFiletype == FILETYPE_PCK) ? true : false);
434
	return UnPCKData(c->sData, c->lSize, size, (iFiletype == FILETYPE_PCK) ? true : false);
Line 431... Line 464...
431
	}
464
	}
432
 
465
 
433
	// now just write the new cat file
466
	// now just write the new cat file
434
	m_lFiles.remove ( f );
467
	m_lFiles.remove ( f );
435
	m_bCatChanged = true;
468
	m_bCatChanged = true;
436
 
469
 
437
	return true;
470
	return true;
438
}
471
}
439
 
472
 
440
bool CCatFile::WriteCatFile ()
473
bool CCatFile::WriteCatFile ()
441
{
474
{
442
	if ( (m_bCreate) && (m_lFiles.empty()) ) return false;
475
	if ( (m_bCreate) && (m_lFiles.empty()) ) return false;
443
 
476
 
444
	Utils::String cat = m_fCatFile.filename() + "\n";
477
	Utils::String cat = m_fDatFile.filename() + "\n";
445
	for ( CListNode<SInCatFile> *node = m_lFiles.Front(); node; node = node->next() ) {
478
	for ( CListNode<SInCatFile> *node = m_lFiles.Front(); node; node = node->next() ) {
446
		if ( !node->Data() ) continue;
479
		if ( !node->Data() ) continue;
447
		if ( node->Data()->sFile.Empty() ) continue;
480
		if ( node->Data()->sFile.Empty() ) continue;
448
		Utils::String str = node->Data()->sFile.ToString();
481
		Utils::String str = node->Data()->sFile.ToString();
449
		cat += str.findReplace("/", "\\").findReplace("\\\\", "\\") + " " + (long)node->Data()->lSize + "\n";
482
		cat += str.findReplace("/", "\\").findReplace("\\\\", "\\") + " " + (long)node->Data()->lSize + "\n";
Line 458... Line 491...
458
	try {
491
	try {
459
		unsigned char *data = new unsigned char[len + 1];
492
		unsigned char *data = new unsigned char[len + 1];
460
		memcpy(data, cat.c_str(), cat.length() * sizeof(unsigned char));
493
		memcpy(data, cat.c_str(), cat.length() * sizeof(unsigned char));
461
		for ( size_t i = len; i >= cat.length(); i-- ) data[i] = '\0';
494
		for ( size_t i = len; i >= cat.length(); i-- ) data[i] = '\0';
462
		this->DecryptData(data, len);
495
		this->DecryptData(data, len);
463
 
496
 
464
		bool ret = m_fCatFile.write(data, cat.length());
497
		bool ret = m_fCatFile.write(data, cat.length());
465
		delete []data;
498
		delete []data;
466
	}
499
	}
467
	catch(std::exception &e) {
500
	catch(std::exception &e) {
468
		CLog::logf(CLog::Log_IO, 2, "CCatFile::WriteCatFile() unable to malloc, %d (%s)", len + 1, e.what());
501
		CLog::logf(CLog::Log_IO, 2, "CCatFile::WriteCatFile() unable to malloc, %d (%s)", len + 1, e.what());
469
		return false;
502
		return false;
470
	}
503
	}
471
 
504
 
472
	m_fCatFile.close();
505
	m_fCatFile.close();
473
	m_bCatChanged = false;
506
	m_bCatChanged = false;
474
	return ret;
507
	return ret;
475
}
508
}
476
 
509
 
477
bool CCatFile::CheckExtensionPck ( CyString filename )
510
bool CCatFile::CheckExtensionPck ( CyString filename )
478
{
511
{
479
	CyString ext = filename.GetToken ( ".", filename.NumToken  ( "." ) ).lower();
512
	CyString ext = filename.GetToken ( ".", filename.NumToken  ( "." ) ).lower();
480
 
513
 
481
	if ( ext == "xml" )
514
	if ( ext == "xml" )
482
		return true;
515
		return true;
483
	else if ( ext == "txt" )
516
	else if ( ext == "txt" )
484
		return true;
517
		return true;
485
	else if ( ext == "bob" )
518
	else if ( ext == "bob" )
486
		return true;
519
		return true;
487
	else if ( ext == "bod" )
520
	else if ( ext == "bod" )
488
		return true;
521
		return true;
489
 
522
 
490
	return false;
523
	return false;
491
}
524
}
492
 
525
 
493
bool CCatFile::CheckPackedExtension(const Utils::String &sFilename)
526
bool CCatFile::CheckPackedExtension(const Utils::String &sFilename)
Line 495... Line 528...
495
	Utils::String ext = CFileIO(sFilename).extension().lower();
528
	Utils::String ext = CFileIO(sFilename).extension().lower();
496
 
529
 
497
	if ( ext == "pck" )
530
	if ( ext == "pck" )
498
		return true;
531
		return true;
499
	else if ( ext == "pbb" )
532
	else if ( ext == "pbb" )
500
		return true;
533
		return true;
501
	else if ( ext == "pbd" )
534
	else if ( ext == "pbd" )
502
		return true;
535
		return true;
503
 
536
 
504
	return false;
537
	return false;
505
}
538
}
506
 
539
 
507
CyString CCatFile::PckChangeExtension ( CyString f )
540
CyString CCatFile::PckChangeExtension ( CyString f )
508
{
541
{
509
	CFileIO fo ( f );
542
	CFileIO fo ( f );
510
	CyString ext = fo.GetFileExtension ().lower();
543
	CyString ext = fo.GetFileExtension ().lower();
511
	if ( ext == "txt" )
544
	if ( ext == "txt" )
512
		return fo.ChangeFileExtension ( "pck" );
545
		return fo.ChangeFileExtension ( "pck" );
513
	else if ( ext == "xml" )
546
	else if ( ext == "xml" )
514
		return fo.ChangeFileExtension ( "pck" );
547
		return fo.ChangeFileExtension ( "pck" );
515
	else if ( ext == "bob" )
548
	else if ( ext == "bob" )
516
		return fo.ChangeFileExtension ( "pbb" );
549
		return fo.ChangeFileExtension ( "pbb" );
517
	else if ( ext == "bod" )
550
	else if ( ext == "bod" )
Line 531... Line 564...
531
	}
564
	}
532
	CyString to = sTo;
565
	CyString to = sTo;
533
	if ( !m_sAddonDir.Empty() && CCatFile::IsAddonDir(to) ) {
566
	if ( !m_sAddonDir.Empty() && CCatFile::IsAddonDir(to) ) {
534
		CLog::logf(CLog::Log_IO, 3, "CCatFile::AppendFile() changing destination to included addon fir, %s => %s", to, m_sAddonDir + "/" + to);
567
		CLog::logf(CLog::Log_IO, 3, "CCatFile::AppendFile() changing destination to included addon fir, %s => %s", to, m_sAddonDir + "/" + to);
535
		to = m_sAddonDir + "\\" + to;
568
		to = m_sAddonDir + "\\" + to;
536
	}
569
	}
537
 
570
 
538
	// change the file extension and remove the file again
571
	// change the file extension and remove the file again
539
	if ( pck && CheckExtensionPck(filename) ) {
572
	if ( pck && CheckExtensionPck(filename) ) {
540
		CLog::logf(CLog::Log_IO, 3, "CCatFile::AppendFile() changing file extension for packed file, %s => %s", to.c_str(), PckChangeExtension(to).ToString().c_str());
573
		CLog::logf(CLog::Log_IO, 3, "CCatFile::AppendFile() changing file extension for packed file, %s => %s", to.c_str(), PckChangeExtension(to).ToString().c_str());
541
		to = PckChangeExtension(to);
574
		to = PckChangeExtension(to);
542
	}
575
	}
Line 556... Line 589...
556
	bool append = false;
589
	bool append = false;
557
 
590
 
558
	SInCatFile *f = new SInCatFile;
591
	SInCatFile *f = new SInCatFile;
559
	f->sData = 0;
592
	f->sData = 0;
560
	f->lOffset = this->GetEndOffset();
593
	f->lOffset = this->GetEndOffset();
561
 
594
	
562
	bool dofile = true;
595
	bool dofile = true;
563
 
596
 
564
	if ( !m_lFiles.size() )	{
597
	if ( !m_lFiles.size() )	{
565
		CLog::logf(CLog::Log_IO, 3, "CCatFile::AppendFile() no existing files found, wipeing the existing dat file");
598
		CLog::logf(CLog::Log_IO, 3, "CCatFile::AppendFile() no existing files found, wipeing the existing dat file");
566
		m_fDatFile.WipeFile();
599
		m_fDatFile.WipeFile();
Line 674... Line 707...
674
	f->sData = 0;
707
	f->sData = 0;
675
	if ( m_lFiles.empty() )
708
	if ( m_lFiles.empty() )
676
		f->lOffset = 0;
709
		f->lOffset = 0;
677
	else
710
	else
678
		f->lOffset = m_fDatFile.GetFilesize();
711
		f->lOffset = m_fDatFile.GetFilesize();
679
 
712
 
680
	// if file extension is packed but not the file, then pack it, "pck" forces it to be packed unless it already is
713
	// if file extension is packed but not the file, then pack it, "pck" forces it to be packed unless it already is
681
 
714
 
682
	f->lSize = size;
715
	f->lSize = size;
683
	if ( (((pck) && (CheckExtensionPck (to.ToString()))) || ((CheckPackedExtension ( to.ToString() )))) && (!IsDataPCK ( data, size )) )
716
	if ( (((pck) && (CheckExtensionPck (to.ToString()))) || ((CheckPackedExtension ( to.ToString() )))) && (!IsDataPCK ( data, size )) )
684
	{
717
	{
Line 890... Line 923...
890
	f->sData = 0;
923
	f->sData = 0;
891
 
924
 
892
	if ( bWritten ) this->ClearError();
925
	if ( bWritten ) this->ClearError();
893
 
926
 
894
	return bWritten;
927
	return bWritten;
-
 
928
}
-
 
929
 
-
 
930
const Utils::String &CCatFile::internalDatFilename() const
-
 
931
{
-
 
932
	return _sReadFilename;
895
}
933
}
896
 
934
 
897
CyString CCatFile::GetErrorString ()
935
CyString CCatFile::GetErrorString ()
898
{
936
{
899
	switch ( m_iError )
937
	switch ( m_iError )