Subversion Repositories spk

Rev

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

Rev 196 Rev 197
Line 39... Line 39...
39
	}
39
	}
40
 
40
 
41
	_lFiles->clear();
41
	_lFiles->clear();
42
}
42
}
43
 
43
 
44
bool CCatFile::IsAddonDir(const Utils::String &dir)
44
bool CCatFile::IsAddonDir(const Utils::WString &dir)
45
{
45
{
46
	Utils::String d = dir.findReplace("\\", "/");
46
	Utils::WString d = dir.findReplace(L"\\", L"/");
47
	d = d.token("/", 1);
47
	d = d.token(L"/", 1);
48
 
48
 
49
	if (d.Compare("types"))
49
	if (d.Compare(L"types"))
50
		return true;
50
		return true;
51
	if (d.Compare("scripts"))
51
	if (d.Compare(L"scripts"))
52
		return true;
52
		return true;
53
	if (d.Compare("t"))
53
	if (d.Compare(L"t"))
54
		return true;
54
		return true;
55
	if (d.Compare("mov"))
55
	if (d.Compare(L"mov"))
56
		return true;
56
		return true;
57
	if (d.Compare("loadscr"))
57
	if (d.Compare(L"loadscr"))
58
		return true;
58
		return true;
59
	if (d.Compare("l"))
59
	if (d.Compare(L"l"))
60
		return true;
60
		return true;
61
	if ( d.Compare("maps") )
61
	if ( d.Compare(L"maps") )
62
		return true;
62
		return true;
63
	if ( d.Compare("director") )
63
	if ( d.Compare(L"director") )
64
		return true;
64
		return true;
65
	if ( d.Compare("cutscenes") )
65
	if ( d.Compare(L"cutscenes") )
66
		return true;
66
		return true;
67
	return false;
67
	return false;
68
}
68
}
69
 
69
 
70
bool CCatFile::Opened(int error, bool allowCreate) 
70
bool CCatFile::Opened(int error, bool allowCreate) 
71
{
71
{
72
	if ( error == CATERR_NONE ) return true;
72
	if ( error == CATERR_NONE ) return true;
73
	if ( allowCreate && error == CATERR_CREATED ) return true;
73
	if ( allowCreate && error == CATERR_CREATED ) return true;
74
	return false;
74
	return false;
75
}
75
}
76
int CCatFile::open(const Utils::String &sCatfile, const Utils::String &addon, int readtype, bool create)
76
int CCatFile::open(const Utils::WString &sCatfile, const Utils::WString &addon, int readtype, bool create)
77
{
77
{
78
	Utils::String catfile = sCatfile;
78
	Utils::WString catfile = sCatfile;
79
 
79
 
80
	m_bCreate = false;
80
	m_bCreate = false;
81
	Utils::String datfile;
81
	Utils::WString datfile;
82
	if ( !catfile.right(4).Compare(".cat") ) {
82
	if ( !catfile.right(4).Compare(L".cat") ) {
83
		datfile = catfile + ".dat";
83
		datfile = catfile + L".dat";
84
		catfile += ".cat";
84
		catfile += L".cat";
85
	}
85
	}
86
	else datfile = catfile.left(-4) + ".dat";
86
	else datfile = CFileIO(catfile).changeFileExtension(L"dat");
87
 
87
 
88
	if ( readtype == CATREAD_JUSTCONTENTS ) create = false;
88
	if ( readtype == CATREAD_JUSTCONTENTS ) create = false;
89
 
89
 
90
	// first check if the dat file exists and opens
90
	// first check if the dat file exists and opens
91
	bool created = false;
91
	bool created = false;
Line 161... Line 161...
161
		if ( m_fDatFile.startRead() ) {
161
		if ( m_fDatFile.startRead() ) {
162
			compare = m_fDatFile.fileSize();
162
			compare = m_fDatFile.fileSize();
163
			m_fDatFile.close();
163
			m_fDatFile.close();
164
		}
164
		}
165
		
165
		
-
 
166
		if (!_lFiles->empty())
-
 
167
		{
166
		SInCatFile *c = _lFiles->back();
168
			SInCatFile* c = _lFiles->back();
167
		if (c && (c->lSize + c->lOffset) != compare ) {
169
			if (c && (c->lSize + c->lOffset) != compare) {
168
//			return CATERR_MISMATCH;
170
				//			return CATERR_MISMATCH;
-
 
171
			}
169
		}
172
		}
170
	}
173
	}
171
 
174
 
172
	if ( readtype >= CATREAD_DAT ) LoadDatFile ();
175
	if ( readtype >= CATREAD_DAT ) LoadDatFile ();
173
 
176
 
174
	return CATERR_NONE;
177
	return CATERR_NONE;
175
}
178
}
176
 
179
 
177
bool CCatFile::removeFile(const Utils::String &file)
180
bool CCatFile::removeFile(const Utils::WString &file)
178
{
181
{
179
	if ( !_sAddonDir.empty() ) {
182
	if ( !_sAddonDir.empty() ) {
180
		SInCatFile *f = findData(_sAddonDir + "\\" + file);
183
		SInCatFile *f = findData(_sAddonDir + L"\\" + file);
181
		if ( f )
184
		if ( f )
182
			removeFile(f);
185
			removeFile(f);
183
	}
186
	}
184
	{
187
	{
185
		SInCatFile *f = findData("addon\\" + file);
188
		SInCatFile *f = findData(L"addon\\" + file);
186
		if ( f )
189
		if ( f )
187
			removeFile(f);
190
			removeFile(f);
188
	}
191
	}
189
	SInCatFile *f = findData(file);
192
	SInCatFile *f = findData(file);
190
	if ( !f )
193
	if ( !f )
Line 211... Line 214...
211
			try {
214
			try {
212
				c->sData = new unsigned char[c->lSize + 1];
215
				c->sData = new unsigned char[c->lSize + 1];
213
			}
216
			}
214
			catch (std::exception &e) {
217
			catch (std::exception &e) {
215
				CLog::logf(CLog::Log_IO, 2, "CCatFile::LoadDatFile() unable to malloc data storage: %s, %d (%s)", c->sFile.c_str(), c->lSize, e.what());
218
				CLog::logf(CLog::Log_IO, 2, "CCatFile::LoadDatFile() unable to malloc data storage: %s, %d (%s)", c->sFile.c_str(), c->lSize, e.what());
216
				continue;
219
				continue;
217
			}
220
			}
218
 
221
 
219
			try {
222
			try {
220
				m_fDatFile.read(c->sData, c->lSize);
223
				m_fDatFile.read(c->sData, c->lSize);
221
			}
224
			}
222
			catch(std::exception &e) {
225
			catch(std::exception &e) {
Line 231... Line 234...
231
}
234
}
232
 
235
 
233
bool CCatFile::readFiles ()
236
bool CCatFile::readFiles ()
234
{
237
{
235
	size_t offset = 0;
238
	size_t offset = 0;
236
	int max = 0;
-
 
237
 
239
 
-
 
240
	std::vector<Utils::WString> lines;
238
	Utils::String *lines = Utils::String(m_sData).tokenise(";\n", &max);
241
	Utils::WString(m_sData).tokenise(L";\n", lines);
239
 
242
 
240
	_clearFiles();
243
	_clearFiles();
241
 
244
 
242
	if ( lines && max ) {
245
	if (!lines.empty()) {
243
		int start = 1;
246
		size_t start = 1;
244
		_sReadFilename = lines[0];
247
		_sReadFilename = lines[0];
245
		if ( _sReadFilename.token(" ", -1).isNumber() ) {
248
		if ( _sReadFilename.token(L" ", -1).isNumber() ) {
246
			_sReadFilename.clear();
249
			_sReadFilename.clear();
247
			start = 0;
250
			start = 0;
248
		}
251
		}
249
 
252
 
250
		for(int i = start; i < max; i++) {
253
		for(size_t i = start; i < lines.size(); i++) {
251
			Utils::String l = lines[i];
254
			Utils::WString l = lines[i];
252
 
255
 
-
 
256
			if (!l.empty())
-
 
257
			{
253
			SInCatFile *catfile = new SInCatFile;
258
				SInCatFile* catfile = new SInCatFile;
-
 
259
 
-
 
260
				catfile->lSize = static_cast<size_t>(l.token(L" ", -1).toLong());
-
 
261
				catfile->sFile = l.tokens(L" ", 1, -2);
-
 
262
				catfile->lOffset = offset;
-
 
263
				catfile->sData = 0;
254
 
264
 
255
			catfile->lSize = static_cast<size_t>(l.token(" ", -1).toLong());
-
 
256
			catfile->sFile = l.tokens(" ", 1, -2);
-
 
257
			catfile->lOffset = offset;
-
 
258
			catfile->sData = 0;
265
				offset += catfile->lSize;
259
 
266
 
260
			offset += catfile->lSize;
-
 
261
 
-
 
262
			_lFiles->push_back(catfile);
267
				_lFiles->push_back(catfile);
-
 
268
			}
263
		}
269
		}
264
	}
270
	}
265
 
271
 
266
	CLEANSPLIT(lines, max);
-
 
267
/*
272
/*
268
	unsigned char *data = m_sData;
273
	unsigned char *data = m_sData;
269
	int spacePos = -1;
274
	int spacePos = -1;
270
	while ( m_sData[num] != '\0' ) {
275
	while ( m_sData[num] != '\0' ) {
271
		if ( m_sData[num] == '\n' ) {
276
		if ( m_sData[num] == '\n' ) {
Line 291... Line 296...
291
					catfile->sFile = file;
296
					catfile->sFile = file;
292
					catfile->lOffset = offset;
297
					catfile->lOffset = offset;
293
					catfile->sData = 0;
298
					catfile->sData = 0;
294
 
299
 
295
					offset += catfile->lSize;
300
					offset += catfile->lSize;
296
 
301
 
297
					m_lFiles.push_back ( catfile );
302
					m_lFiles.push_back ( catfile );
298
				}
303
				}
299
			}
304
			}
300
			data = (m_sData + (num + 1));
305
			data = (m_sData + (num + 1));
301
			spacePos = -1;
306
			spacePos = -1;
Line 327... Line 332...
327
		dh+=5;
332
		dh+=5;
328
		*(ptr + 1) ^= al;
333
		*(ptr + 1) ^= al;
329
		al=cl;
334
		al=cl;
330
		cl+=5;
335
		cl+=5;
331
		*(ptr + 0) ^= al;
336
		*(ptr + 0) ^= al;
332
	}
337
	}
333
 
338
 
334
	return true;
339
	return true;
335
}
340
}
336
 
341
 
337
bool CCatFile::DecryptData ()
342
bool CCatFile::DecryptData ()
Line 349... Line 354...
349
	m_sData = NULL;
354
	m_sData = NULL;
350
	m_iDataType = CATFILE_NONE;
355
	m_iDataType = CATFILE_NONE;
351
	m_lSize = 0;
356
	m_lSize = 0;
352
}
357
}
353
 
358
 
354
bool CCatFile::readFileToData(const Utils::String &filename)
359
bool CCatFile::readFileToData(const Utils::WString &filename)
355
{
360
{
356
	SInCatFile *c = findData(filename);
361
	SInCatFile *c = findData(filename);
357
	return readFileToData(c);
362
	return readFileToData(c);
358
}
363
}
359
 
364
 
Line 398... Line 403...
398
{
403
{
399
	for(unsigned char *pos=buffer, *end=buffer + size; pos < end; pos++){
404
	for(unsigned char *pos=buffer, *end=buffer + size; pos < end; pos++){
400
		*pos^=0x33;
405
		*pos^=0x33;
401
	}
406
	}
402
}
407
}
403
unsigned char *CCatFile::readData(const Utils::String &filename, size_t *size)
408
unsigned char *CCatFile::readData(const Utils::WString &filename, size_t *size)
404
{
409
{
405
	*size = 0;
410
	*size = 0;
406
 
411
 
407
	if ( !m_fDatFile.NoFile() ) {
412
	if ( !m_fDatFile.NoFile() ) {
408
		SInCatFile *c = findData(filename);
413
		SInCatFile *c = findData(filename);
Line 472... Line 477...
472
			iOffset = c->lOffset;
477
			iOffset = c->lOffset;
473
		}
478
		}
474
		else if ( iOffset >= 0 ) {
479
		else if ( iOffset >= 0 ) {
475
			c->lOffset = iOffset;
480
			c->lOffset = iOffset;
476
			iOffset += c->lSize;
481
			iOffset += c->lSize;
477
		}
482
		}
478
	}
483
	}
479
 
484
 
480
	// now just write the new cat file
485
	// now just write the new cat file
481
	auto findItr = std::find(_lFiles->begin(), _lFiles->end(), f);
486
	auto findItr = std::find(_lFiles->begin(), _lFiles->end(), f);
482
	if (findItr != _lFiles->end())
487
	if (findItr != _lFiles->end())
483
		_lFiles->erase(findItr);
488
		_lFiles->erase(findItr);
484
	m_bCatChanged = true;
489
	m_bCatChanged = true;
Line 488... Line 493...
488
 
493
 
489
bool CCatFile::WriteCatFile ()
494
bool CCatFile::WriteCatFile ()
490
{
495
{
491
	if ( (m_bCreate) && (_lFiles->empty()) ) return false;
496
	if ( (m_bCreate) && (_lFiles->empty()) ) return false;
492
 
497
 
493
	Utils::String cat = m_fDatFile.filename().toString() + "\n";
498
	Utils::WString cat = m_fDatFile.filename() + L"\n";
494
	for (auto itr = _lFiles->cbegin(); itr != _lFiles->cend(); ++itr)
499
	for (auto itr = _lFiles->cbegin(); itr != _lFiles->cend(); ++itr)
495
	{
500
	{
496
		SInCatFile *c = *itr;
501
		SInCatFile *c = *itr;
497
		if ( !c ) continue;
502
		if ( !c ) continue;
498
		if ( c->sFile.empty() ) continue;
503
		if ( c->sFile.empty() ) continue;
499
		Utils::String str = c->sFile;
504
		Utils::WString str = c->sFile;
500
		cat += str.findReplace("/", "\\").findReplace("\\\\", "\\") + " " + (long)c->lSize + "\n";
505
		cat += str.findReplace(L"/", L"\\").findReplace(L"\\\\", L"\\") + L" " + (long)c->lSize + L"\n";
501
	}
506
	}
502
 
507
 
503
	if ( !cat.length() ) return false;
508
	if ( !cat.length() ) return false;
504
 
509
 
505
	// make sure the len is in multiples of 5, otherwise decryptData could cause heap problems
510
	// make sure the len is in multiples of 5, otherwise decryptData could cause heap problems
Line 528... Line 533...
528
std::vector<SInCatFile *> *CCatFile::GetFiles() const
533
std::vector<SInCatFile *> *CCatFile::GetFiles() const
529
{
534
{
530
	return _lFiles;
535
	return _lFiles;
531
}
536
}
532
 
537
 
533
bool CCatFile::checkExtensionPck(const Utils::String &filename) const
538
bool CCatFile::checkExtensionPck(const Utils::WString &filename) const
534
{	
539
{	
535
	Utils::WString ext = CFileIO(filename).extension().lower();
540
	Utils::WString ext = CFileIO(filename).extension().lower();
536
	if ( ext == L"xml" )
541
	if ( ext == L"xml" )
537
		return true;
542
		return true;
538
	else if ( ext == L"txt" )
543
	else if ( ext == L"txt" )
Line 543... Line 548...
543
		return true;
548
		return true;
544
 
549
 
545
	return false;
550
	return false;
546
}
551
}
547
 
552
 
548
bool CCatFile::CheckPackedExtension(const Utils::String &sFilename)
553
bool CCatFile::CheckPackedExtension(const Utils::WString &sFilename)
549
{
554
{
550
	Utils::WString ext = CFileIO(sFilename).extension().lower();
555
	Utils::WString ext = CFileIO(sFilename).extension().lower();
551
 
556
 
552
	if ( ext == L"pck" )
557
	if ( ext == L"pck" )
553
		return true;
558
		return true;
Line 557... Line 562...
557
		return true;
562
		return true;
558
 
563
 
559
	return false;
564
	return false;
560
}
565
}
561
 
566
 
562
Utils::String CCatFile::PckChangeExtension(const Utils::String &f)
567
Utils::WString CCatFile::PckChangeExtension(const Utils::WString &f)
563
{
568
{
564
	CFileIO fo ( f );
569
	CFileIO fo ( f );
565
	Utils::WString ext = fo.extension ().lower();
570
	Utils::WString ext = fo.extension ().lower();
566
	if ( ext == L"txt" )
571
	if (ext == L"txt")
567
		return fo.changeFileExtension(L"pck").toString();
572
		return fo.changeFileExtension(L"pck");
568
	else if ( ext == L"xml" )
573
	else if (ext == L"xml")
569
		return fo.changeFileExtension(L"pck").toString();
574
		return fo.changeFileExtension(L"pck");
570
	else if ( ext == L"bob" )
575
	else if ( ext == L"bob" )
571
		return fo.changeFileExtension(L"pbb").toString();
576
		return fo.changeFileExtension(L"pbb");
572
	else if ( ext == L"bod" )
577
	else if ( ext == L"bod" )
573
		return fo.changeFileExtension(L"pbd").toString();
578
		return fo.changeFileExtension(L"pbd");
574
 
579
 
575
	return f;
580
	return f;
576
}
581
}
577
 
582
 
578
bool CCatFile::appendFile(const Utils::String &filename, const Utils::String &sTo, bool pck, bool bXor, Utils::String *sChangeTo)
583
bool CCatFile::appendFile(const Utils::WString &filename, const Utils::WString &sTo, bool pck, bool bXor, Utils::WString *sChangeTo)
579
{
584
{
580
	CLog::logf(CLog::Log_IO, 1, "CCatFile::AppendFile() Adding file, %s, into cat file, %s::%s [PCK:%s XOR:%s]", filename.c_str(), this->m_fCatFile.filename().c_str(), sTo.c_str(), (pck) ? "Yes" : "No", (bXor) ? "Yes" : "No");
585
	CLog::logf(CLog::Log_IO, 1, "CCatFile::AppendFile() Adding file, %s, into cat file, %s::%s [PCK:%s XOR:%s]", filename.c_str(), this->m_fCatFile.filename().c_str(), sTo.c_str(), (pck) ? "Yes" : "No", (bXor) ? "Yes" : "No");
581
 
586
 
582
	if ( filename.isin ( "::" ) ) return writeFromCat(filename.token("::", 1), filename.token("::", 2));
587
	if ( filename.isin (L"::" ) ) return writeFromCat(filename.token(L"::", 1), filename.token(L"::", 2));
583
	if ( (!m_bCreate) && (!m_fDatFile.exists ()) ) {
588
	if ( (!m_bCreate) && (!m_fDatFile.exists ()) ) {
584
		CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() Cat File: %s, doesn't exist, quitting...", m_fCatFile.fullFilename().c_str());
589
		CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() Cat File: %s, doesn't exist, quitting...", m_fCatFile.fullFilename().c_str());
585
		return false;
590
		return false;
586
	}
591
	}
587
	Utils::String to = sTo;
592
	Utils::WString to = sTo;
588
	if ( !_sAddonDir.empty() && CCatFile::IsAddonDir(to) ) {
593
	if ( !_sAddonDir.empty() && CCatFile::IsAddonDir(to) ) {
589
		CLog::logf(CLog::Log_IO, 3, "CCatFile::AppendFile() changing destination to included addon fir, %s => %s", to, _sAddonDir + "/" + to);
594
		CLog::logf(CLog::Log_IO, 3, "CCatFile::AppendFile() changing destination to included addon fir, %s => %s", to, _sAddonDir + L"/" + to);
590
		to = _sAddonDir + "\\" + to;
595
		to = _sAddonDir + L"\\" + to;
591
	}
596
	}
592
 
597
 
593
	// change the file extension and remove the file again
598
	// change the file extension and remove the file again
594
	if ( pck && checkExtensionPck(filename) ) {
599
	if ( pck && checkExtensionPck(filename) ) {
595
		CLog::logf(CLog::Log_IO, 3, "CCatFile::AppendFile() changing file extension for packed file, %s => %s", to.c_str(), PckChangeExtension(to).c_str());
600
		CLog::logf(CLog::Log_IO, 3, "CCatFile::AppendFile() changing file extension for packed file, %s => %s", to.c_str(), PckChangeExtension(to).c_str());
Line 637... Line 642...
637
	if ( iFileType == FILETYPE_PLAIN && CheckPackedExtension(to) ) {
642
	if ( iFileType == FILETYPE_PLAIN && CheckPackedExtension(to) ) {
638
		CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() plain text file needs to packed");
643
		CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() plain text file needs to packed");
639
		size_t newsize = 0;
644
		size_t newsize = 0;
640
		unsigned char *newdata = PCKData(data, File.fileSize(), &newsize, bXor);
645
		unsigned char *newdata = PCKData(data, File.fileSize(), &newsize, bXor);
641
		CLog::logf(CLog::Log_IO, 1, "CCatFile::AppendFile() file has been packed, %d => %d", File.fileSize(), newsize);
646
		CLog::logf(CLog::Log_IO, 1, "CCatFile::AppendFile() file has been packed, %d => %d", File.fileSize(), newsize);
642
 
647
 
643
		f->lSize = newsize;
648
		f->lSize = newsize;
644
		CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() Decrypting data");
649
		CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() Decrypting data");
645
		this->DecryptDAT(newdata, f->lSize);
650
		this->DecryptDAT(newdata, f->lSize);
646
		CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() appending data to Dat file, Offset:%d", f->lOffset);
651
		CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() appending data to Dat file, Offset:%d", f->lOffset);
647
		append = m_fDatFile.AppendDataToPos ( (const char *)newdata, newsize, f->lOffset );
652
		append = m_fDatFile.AppendDataToPos ( (const char *)newdata, newsize, f->lOffset );
648
 
653
 
649
		delete [] newdata;
654
		delete [] newdata;
650
	}
655
	}
651
	else  {
656
	else  {
652
		CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() Decrypting data");
657
		CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() Decrypting data");
653
		this->DecryptDAT(data, File.fileSize());
658
		this->DecryptDAT(data, File.fileSize());
654
		f->lSize = File.fileSize();
659
		f->lSize = File.fileSize();
655
		CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() appending data to Dat file, Offset:%d", f->lOffset);
660
		CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() appending data to Dat file, Offset:%d", f->lOffset);
Line 670... Line 675...
670
		m_bCatChanged = true;
675
		m_bCatChanged = true;
671
	}
676
	}
672
	else {
677
	else {
673
		CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() appending failed, cleaning up file data");
678
		CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() appending failed, cleaning up file data");
674
		delete f;
679
		delete f;
675
	}
680
	}
676
 
681
 
677
	CLog::logf(CLog::Log_IO, 4, "CCatFile::AppendFile() function complete");
682
	CLog::logf(CLog::Log_IO, 4, "CCatFile::AppendFile() function complete");
678
 
683
 
679
	return append;
684
	return append;
680
}
685
}
681
 
686
 
682
bool CCatFile::addData(const Utils::String &catfile, unsigned char *data, size_t size, const Utils::String &to, bool pck, bool create)
687
bool CCatFile::addData(const Utils::WString &catfile, unsigned char *data, size_t size, const Utils::WString &to, bool pck, bool create)
683
{
688
{
684
	int err = open(catfile, "", CATREAD_CATDECRYPT, create);
689
	int err = open(catfile, L"", CATREAD_CATDECRYPT, create);
685
	if ( (err != CATERR_NONE) && (err != CATERR_CREATED) )
690
	if ( (err != CATERR_NONE) && (err != CATERR_CREATED) )
686
		return false;
691
		return false;
687
 
692
 
688
	return appendData(data, size, to, pck);
693
	return appendData(data, size, to, pck);
689
}
694
}
Line 705... Line 710...
705
SInCatFile *CCatFile::GetFile(unsigned int num) const 
710
SInCatFile *CCatFile::GetFile(unsigned int num) const 
706
{ 
711
{ 
707
	return (num >= 0 && num < _lFiles->size()) ? _lFiles->at(num) : NULL; 
712
	return (num >= 0 && num < _lFiles->size()) ? _lFiles->at(num) : NULL; 
708
}
713
}
709
 
714
 
710
bool CCatFile::appendData(unsigned char *data, size_t size, const Utils::String &aTo, bool pck, bool bXor)
715
bool CCatFile::appendData(unsigned char *data, size_t size, const Utils::WString &aTo, bool pck, bool bXor)
711
{
716
{
712
	if ( (!m_bCreate) && (!m_fCatFile.exists ()) )
717
	if ( (!m_bCreate) && (!m_fCatFile.exists ()) )
713
		return false;
718
		return false;
714
 
719
 
715
	if ( (size <= 0) || (!data) )
720
	if ( (size <= 0) || (!data) )
716
		return false;
721
		return false;
717
 
722
 
718
	Utils::String to = aTo;
723
	Utils::WString to = aTo;
719
 
724
 
720
	// then check if the file already exists
725
	// then check if the file already exists
721
	if ( !_lFiles->empty() )
726
	if ( !_lFiles->empty() )
722
	{
727
	{
723
		SInCatFile *f = findData(to);
728
		SInCatFile *f = findData(to);
724
		if ( f )
729
		if ( f )
725
		{
730
		{
726
			if (!removeFile ( f ))
731
			if (!removeFile ( f ))
727
				return false;
732
				return false;
728
		}
733
		}
729
	}
734
	}
730
 
735
 
731
	bool append = false;
736
	bool append = false;
732
 
737
 
733
	if (_lFiles->empty())
738
	if (_lFiles->empty())
Line 777... Line 782...
777
		_lFiles->push_back(f);
782
		_lFiles->push_back(f);
778
		m_bCatChanged = true;
783
		m_bCatChanged = true;
779
	}
784
	}
780
	else
785
	else
781
		delete f;
786
		delete f;
782
 
787
 
783
	return true;
788
	return true;
784
}
789
}
785
 
790
 
786
Utils::String CCatFile::RenameFileExtension(SInCatFile *f)
791
Utils::WString CCatFile::RenameFileExtension(SInCatFile *f)
787
{
792
{
788
	CFileIO fo(f->sFile);
793
	CFileIO fo(f->sFile);
789
	Utils::WString ext = fo.extension().lower();
794
	Utils::WString ext = fo.extension().lower();
790
	if ( ext == "pck" )
795
	if ( ext == L"pck" )
791
	{
796
	{
792
		Utils::String firstDir = f->sFile.findReplace("/", "\\").token("\\", 1).lower();
797
		Utils::WString firstDir = f->sFile.findReplace(L"/", L"\\").token(L"\\", 1).lower();
793
 
798
 
794
		if ( firstDir == "t" )
799
		if ( firstDir == L"t" )
795
			return fo.changeFileExtension(L"xml").toString();
800
			return fo.changeFileExtension(L"xml");
796
		else if ( firstDir == "director" )
801
		else if ( firstDir == L"director" )
797
			return fo.changeFileExtension(L"xml").toString();
802
			return fo.changeFileExtension(L"xml");
798
		return fo.changeFileExtension(L"txt").toString();
803
		return fo.changeFileExtension(L"txt");
799
	}
804
	}
800
	else if ( ext == "pbb" )
805
	else if ( ext == L"pbb" )
801
		return fo.changeFileExtension(L"bob").toString();
806
		return fo.changeFileExtension(L"bob");
802
	else if ( ext == "pbd" )
807
	else if ( ext == L"pbd" )
803
		return fo.changeFileExtension(L"bod").toString();
808
		return fo.changeFileExtension(L"bod");
804
	return f->sFile;
809
	return f->sFile;
805
}
810
}
806
 
811
 
807
void CCatFile::findFiles(Utils::CStringList &files, const Utils::String &filemask) const
812
void CCatFile::findFiles(Utils::WStringList &files, const Utils::WString &filemask) const
808
{
813
{
809
	if (_lFiles->empty())
814
	if (_lFiles->empty())
810
		return;
815
		return;
811
 
816
 
812
	for (auto itr = _lFiles->cbegin(); itr != _lFiles->cend(); ++itr)
817
	for (auto itr = _lFiles->cbegin(); itr != _lFiles->cend(); ++itr)
Line 814... Line 819...
814
		if (filemask.match((*itr)->sFile))
819
		if (filemask.match((*itr)->sFile))
815
			files.pushBack((*itr)->sFile);
820
			files.pushBack((*itr)->sFile);
816
	}
821
	}
817
}
822
}
818
 
823
 
819
bool CCatFile::extractAll(const Utils::String &dir)
824
bool CCatFile::extractAll(const Utils::WString &dir)
820
{
825
{
821
	if (_lFiles->empty())
826
	if (_lFiles->empty())
822
		return false;
827
		return false;
823
 
828
 
824
	for (auto itr = _lFiles->cbegin(); itr != _lFiles->cend(); ++itr)
829
	for (auto itr = _lFiles->cbegin(); itr != _lFiles->cend(); ++itr)
Line 827... Line 832...
827
			return false;
832
			return false;
828
	}
833
	}
829
 
834
 
830
	return true;
835
	return true;
831
}
836
}
832
bool CCatFile::extractFile(const Utils::String &filename, const Utils::String &to, bool preserve)
837
bool CCatFile::extractFile(const Utils::WString &filename, const Utils::WString &to, bool preserve)
833
{
838
{
834
	if (_lFiles->empty())
839
	if (_lFiles->empty())
835
		return false;
840
		return false;
836
 
841
 
837
	// check if file exists
842
	// check if file exists
838
	if ( !_sAddonDir.empty() ) {
843
	if ( !_sAddonDir.empty() ) {
839
		SInCatFile *f = findData(_sAddonDir + "\\" + filename);
844
		SInCatFile *f = findData(_sAddonDir + L"\\" + filename);
840
		if ( f )
845
		if ( f )
841
			return extractFile(f, to, preserve);
846
			return extractFile(f, to, preserve);
842
	}
847
	}
843
	{
848
	{
844
		SInCatFile *f = findData("addon\\" + filename);
849
		SInCatFile *f = findData(L"addon\\" + filename);
845
		if ( f )
850
		if ( f )
846
			return extractFile(f, to, preserve);
851
			return extractFile(f, to, preserve);
847
	}
852
	}
848
 
853
 
849
	SInCatFile *f = findData(filename);
854
	SInCatFile *f = findData(filename);
Line 870... Line 875...
870
	}	
875
	}	
871
 
876
 
872
	return FILETYPE_PLAIN;
877
	return FILETYPE_PLAIN;
873
}
878
}
874
 
879
 
875
bool CCatFile::extractFile(SInCatFile* f, const Utils::String &to, bool preserve)
880
bool CCatFile::extractFile(SInCatFile* f, const Utils::WString &to, bool preserve)
876
{
881
{
877
	unsigned char *data = 0;
882
	unsigned char *data = 0;
878
	size_t size = 0;
883
	size_t size = 0;
879
 
884
 
880
	// load the data from file
885
	// load the data from file
Line 886... Line 891...
886
		return false;
891
		return false;
887
	}
892
	}
888
 
893
 
889
	CFileIO fo(CCatFile::RenameFileExtension(f));
894
	CFileIO fo(CCatFile::RenameFileExtension(f));
890
	// check for a file name
895
	// check for a file name
891
	Utils::String checkFile = to;
896
	Utils::WString checkFile = to;
892
	Utils::String todir, tofile = to;
897
	Utils::WString todir, tofile = to;
893
	if ( checkFile.containsAny("\\/") )
898
	if ( checkFile.containsAny(L"\\/") )
894
	{
899
	{
895
		checkFile = checkFile.findReplace ( "\\", "/" );
900
		checkFile = checkFile.findReplace (L"\\", L"/" );
896
		checkFile = checkFile.findReplace ( "//", "/" );
901
		checkFile = checkFile.findReplace (L"//", L"/" );
897
		tofile = checkFile.token("/", checkFile.countToken("/"));
902
		tofile = checkFile.token(L"/", checkFile.countToken(L"/"));
898
 
903
 
899
		if ( !checkFile.contains(".") || preserve )
904
		if ( !checkFile.contains(L".") || preserve )
900
		{
905
		{
901
			tofile = fo.filenameStr();
906
			tofile = fo.filename();
902
			todir = checkFile;
907
			todir = checkFile;
903
		}
908
		}
904
		else
909
		else
905
		{
910
		{
906
			todir = CFileIO(checkFile).dirStr();
911
			todir = CFileIO(checkFile).dir();
907
			tofile = CFileIO(checkFile).filenameStr();
912
			tofile = CFileIO(checkFile).filename();
908
		}
913
		}
909
	}
914
	}
910
 
915
 
911
	if ( tofile.empty() )
916
	if ( tofile.empty() )
912
	{
917
	{
913
		if ( !tofile.empty() )
918
		if ( !tofile.empty() )
914
			tofile += "/";
919
			tofile += L"/";
915
		tofile += fo.filenameStr();
920
		tofile += fo.filename();
916
		todir = CFileIO(tofile).dirStr();
921
		todir = CFileIO(tofile).dir();
917
		tofile = CFileIO(tofile).filenameStr();
922
		tofile = CFileIO(tofile).filename();
918
	}
923
	}
919
	
924
	
920
	if ( preserve )
925
	if ( preserve )
921
	{
926
	{
922
		if ( !fo.dir().Compare(todir.right(- (int)fo.dir().length())) )
927
		if ( !fo.dir().Compare(todir.right(- (int)fo.dir().length())) )
923
		{
928
		{
924
			if ( !todir.empty() && todir.right(1) != "/" )
929
			if ( !todir.empty() && todir.right(1) != L"/" )
925
				todir += "/";
930
				todir += L"/";
926
			todir += fo.dirStr();
931
			todir += fo.dir();
927
		}
932
		}
928
	}
933
	}
929
 
934
 
930
	if ( tofile.empty() )
935
	if ( tofile.empty() )
931
		tofile = fo.filenameStr();
936
		tofile = fo.filename();
932
 
937
 
933
	bool bWritten = false;
938
	bool bWritten = false;
934
 
939
 
935
	// create the directory to extract to
940
	// create the directory to extract to
936
	if ( !todir.empty() && !CDirIO(todir).create() )
941
	if ( !todir.empty() && !CDirIO(todir).create() )
Line 938... Line 943...
938
	else
943
	else
939
	{
944
	{
940
		Utils::WString file = todir;
945
		Utils::WString file = todir;
941
		if ( !file.empty() )
946
		if ( !file.empty() )
942
			file += L"/";
947
			file += L"/";
943
		file += tofile.toWString();
948
		file += tofile;
944
		file = file.findReplace(L"/", L"\\");
949
		file = file.findReplace(L"/", L"\\");
945
		file = file.findReplace(L"\\\\", L"\\");
950
		file = file.findReplace(L"\\\\", L"\\");
946
 
951
 
947
		CFileIO File(file);
952
		CFileIO File(file);
948
		if ( !File.startWrite() ) m_iError = CATERR_INVALIDDEST;
953
		if ( !File.startWrite() ) m_iError = CATERR_INVALIDDEST;
Line 955... Line 960...
955
	if ( bWritten ) this->clearError();
960
	if ( bWritten ) this->clearError();
956
 
961
 
957
	return bWritten;
962
	return bWritten;
958
}
963
}
959
 
964
 
960
const Utils::String &CCatFile::internalDatFilename() const
965
const Utils::WString &CCatFile::internalDatFilename() const
961
{
966
{
962
	return _sReadFilename;
967
	return _sReadFilename;
963
}
968
}
964
 
969
 
965
Utils::String CCatFile::getErrorString () const
970
Utils::WString CCatFile::getErrorString () const
966
{
971
{
967
	switch ( m_iError )
972
	switch ( m_iError )
968
	{
973
	{
969
		case CATERR_NONE:
974
		case CATERR_NONE:
970
			return Utils::String::Null();
975
			return Utils::WString::Null();
971
		case CATERR_NODATFILE:
976
		case CATERR_NODATFILE:
972
			return "Unable to open Dat file";
977
			return L"Unable to open Dat file";
973
		case CATERR_NOCATFILE:
978
		case CATERR_NOCATFILE:
974
			return "Unable to open Cat file";
979
			return L"Unable to open Cat file";
975
		case CATERR_FILEEMPTY:
980
		case CATERR_FILEEMPTY:
976
			return "Cat file is empty";
981
			return L"Cat file is empty";
977
		case CATERR_READCAT:
982
		case CATERR_READCAT:
978
			return "Unable to read from cat file";
983
			return L"Unable to read from cat file";
979
		case CATERR_DECRYPT:
984
		case CATERR_DECRYPT:
980
			return "Unable to decrypt cat file";
985
			return L"Unable to decrypt cat file";
981
		case CATERR_MISMATCH:
986
		case CATERR_MISMATCH:
982
			return "File size mismatch with Dat file";
987
			return L"File size mismatch with Dat file";
983
		case CATERR_NOFILE:
988
		case CATERR_NOFILE:
984
			return "Unable to find file in archive";
989
			return L"Unable to find file in archive";
985
		case CATERR_CANTREAD:
990
		case CATERR_CANTREAD:
986
			return "Unable to read file in archive";
991
			return L"Unable to read file in archive";
987
		case CATERR_CANTCREATEDIR:
992
		case CATERR_CANTCREATEDIR:
988
			return "Unable to create destiantion directory";
993
			return L"Unable to create destiantion directory";
989
		case CATERR_INVALIDDEST:
994
		case CATERR_INVALIDDEST:
990
			return "Unable to write to destiantion file";
995
			return L"Unable to write to destiantion file";
991
	}
996
	}
992
 
997
 
993
	return "Invalid";
998
	return L"Invalid";
994
}
999
}
995
 
1000
 
996
 
1001
 
997
unsigned char *CompressPCKData ( unsigned char *buffer, size_t size, size_t *retsize, time_t mtime )
1002
unsigned char *CompressPCKData ( unsigned char *buffer, size_t size, size_t *retsize, time_t mtime )
998
{
1003
{
Line 1109... Line 1114...
1109
	}
1114
	}
1110
 
1115
 
1111
	return NULL;
1116
	return NULL;
1112
}
1117
}
1113
 
1118
 
1114
bool CCatFile::writeFromCat(CCatFile *fcat, const Utils::String &file)
1119
bool CCatFile::writeFromCat(CCatFile *fcat, const Utils::WString &file)
1115
{
1120
{
1116
	// now find the file in the cat file
1121
	// now find the file in the cat file
1117
	SInCatFile *getfile = fcat->findData(file);
1122
	SInCatFile *getfile = fcat->findData(file);
1118
	if ( !getfile )
1123
	if ( !getfile )
1119
		return false;
1124
		return false;
Line 1147... Line 1152...
1147
	m_bCatChanged = true;
1152
	m_bCatChanged = true;
1148
 
1153
 
1149
	return true;
1154
	return true;
1150
}
1155
}
1151
 
1156
 
1152
bool CCatFile::writeFromCat(const Utils::String &catfile, const Utils::String &file)
1157
bool CCatFile::writeFromCat(const Utils::WString &catfile, const Utils::WString &file)
1153
{
1158
{
1154
	CCatFile fcat;
1159
	CCatFile fcat;
1155
	if ( fcat.open(catfile, "", CATREAD_CATDECRYPT, false) )
1160
	if ( fcat.open(catfile, L"", CATREAD_CATDECRYPT, false) )
1156
		return false;
1161
		return false;
1157
 
1162
 
1158
	return this->writeFromCat(&fcat, file);
1163
	return this->writeFromCat(&fcat, file);
1159
}
1164
}
1160
SInCatFile *CCatFile::findData(const Utils::String &filename) const
1165
SInCatFile *CCatFile::findData(const Utils::WString &filename) const
1161
{
1166
{
1162
	if (_lFiles->empty())
1167
	if (_lFiles->empty())
1163
		return NULL;
1168
		return NULL;
1164
 
1169
 
1165
	Utils::String check = filename;
1170
	Utils::WString check = filename;
1166
	check = check.findReplace("\\", "/");
1171
	check = check.findReplace(L"\\", L"/");
1167
	for (auto itr = _lFiles->cbegin(); itr != _lFiles->cend(); ++itr)
1172
	for (auto itr = _lFiles->cbegin(); itr != _lFiles->cend(); ++itr)
1168
	{
1173
	{
1169
		Utils::String f = (*itr)->sFile;
1174
		Utils::WString f = (*itr)->sFile;
1170
		f = f.findReplace("\\", "/");
1175
		f = f.findReplace(L"\\", L"/");
1171
		if (f.Compare(check))
1176
		if (f.Compare(check))
1172
			return *itr;
1177
			return *itr;
1173
	}
1178
	}
1174
	return NULL;
1179
	return NULL;
1175
}
1180
}
1176
 
1181
 
1177
bool CCatFile::markRemoveFile(const Utils::String &file)
1182
bool CCatFile::markRemoveFile(const Utils::WString &file)
1178
{
1183
{
1179
	SInCatFile *f = findData(file);
1184
	SInCatFile *f = findData(file);
1180
	if ( !f )
1185
	if ( !f )
1181
	{
1186
	{
1182
		m_iError = CATERR_NOFILE;
1187
		m_iError = CATERR_NOFILE;