Subversion Repositories spk

Rev

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

Rev 119 Rev 124
Line 8... Line 8...
8
{
8
{
9
	m_iDataType = CATFILE_NONE;
9
	m_iDataType = CATFILE_NONE;
10
	m_sData = NULL;
10
	m_sData = NULL;
11
	m_lSize = 0;
11
	m_lSize = 0;
12
	m_bCreate = false;
12
	m_bCreate = false;
-
 
13
	_lFiles = new std::vector<SInCatFile *>;
13
}
14
}
14
 
15
 
15
CCatFile::~CCatFile ()
16
CCatFile::~CCatFile ()
16
{
17
{
17
	m_fDatFile.close();
18
	m_fDatFile.close();
Line 21... Line 22...
21
		WriteCatFile ();
22
		WriteCatFile ();
22
		m_fCatFile.close();
23
		m_fCatFile.close();
23
	}
24
	}
24
 
25
 
25
	_clearFiles();
26
	_clearFiles();
-
 
27
	delete _lFiles;
26
 
28
 
27
	if ( m_sData ) delete []m_sData;
29
	if ( m_sData ) delete []m_sData;
28
}
30
}
29
 
31
 
30
void CCatFile::_clearFiles()
32
void CCatFile::_clearFiles()
31
{
33
{
32
	for ( SInCatFile *c = m_lFiles.First(); c; c = m_lFiles.Next() )
34
	for(auto itr = _lFiles->begin(); itr != _lFiles->end(); itr++)
33
	{
35
	{
34
		if ( c->sData )
36
		if ((*itr)->sData )
35
			delete []c->sData;
37
			delete [](*itr)->sData;
36
		delete c;
38
		delete (*itr);
37
	}
39
	}
38
 
40
 
39
	m_lFiles.clear();
41
	_lFiles->clear();
40
}
42
}
41
 
43
 
42
bool CCatFile::IsAddonDir(CyString dir)
44
bool CCatFile::IsAddonDir(CyString dir)
43
{
45
{
44
	CyString d = dir;
46
	CyString d = dir;
Line 139... Line 141...
139
		if ( !DecryptData () ) return CATERR_DECRYPT;
141
		if ( !DecryptData () ) return CATERR_DECRYPT;
140
		m_sData[File.fileSize()] = 0;
142
		m_sData[File.fileSize()] = 0;
141
		readFiles ();
143
		readFiles ();
142
	}
144
	}
143
 
145
 
144
	m_sAddonDir = addon;
146
	_sAddonDir = addon.ToString();
145
 
147
 
146
	m_fCatFile.open ( catfile );
148
	m_fCatFile.open ( catfile );
147
 
149
 
148
	if ( readtype != CATREAD_JUSTCONTENTS ) {
150
	if ( readtype != CATREAD_JUSTCONTENTS ) {
149
		m_fDatFile.open ( datfile );
151
		m_fDatFile.open ( datfile );
Line 152... Line 154...
152
		long compare = 0;
154
		long compare = 0;
153
		if ( m_fDatFile.startRead() ) {
155
		if ( m_fDatFile.startRead() ) {
154
			compare = m_fDatFile.fileSize();
156
			compare = m_fDatFile.fileSize();
155
			m_fDatFile.close();
157
			m_fDatFile.close();
156
		}
158
		}
-
 
159
		
157
		SInCatFile *c = m_lFiles.Back ()->Data();
160
		SInCatFile *c = _lFiles->back();
158
		if ( (c->lSize + c->lOffset) != compare ) {
161
		if (c && (c->lSize + c->lOffset) != compare ) {
159
//			return CATERR_MISMATCH;
162
//			return CATERR_MISMATCH;
160
		}
163
		}
161
	}
164
	}
162
 
165
 
163
	if ( readtype >= CATREAD_DAT ) LoadDatFile ();
166
	if ( readtype >= CATREAD_DAT ) LoadDatFile ();
164
 
167
 
165
	return CATERR_NONE;
168
	return CATERR_NONE;
166
}
169
}
167
 
170
 
168
bool CCatFile::RemoveFile ( CyString file )
171
bool CCatFile::removeFile(const Utils::String &file)
169
{
172
{
170
	if ( !m_sAddonDir.Empty() ) {
173
	if ( !_sAddonDir.empty() ) {
171
		SInCatFile *f = FindData ( m_sAddonDir + ";\\" + file );
174
		SInCatFile *f = findData(_sAddonDir + ";\\" + file);
172
		if ( f )
175
		if ( f )
173
			RemoveFile(f);
176
			removeFile(f);
174
	}
177
	}
175
	{
178
	{
176
		SInCatFile *f = FindData ( CyString(";addon\\") + file );
179
		SInCatFile *f = findData(";addon\\" + file);
177
		if ( f )
180
		if ( f )
178
			RemoveFile(f);
181
			removeFile(f);
179
	}
182
	}
180
	SInCatFile *f = FindData ( file );
183
	SInCatFile *f = findData(file);
181
	if ( !f )
184
	if ( !f )
182
	{
185
	{
183
		m_iError = CATERR_NOFILE;
186
		m_iError = CATERR_NOFILE;
184
		return false;
187
		return false;
185
	}
188
	}
186
 
189
 
187
	return RemoveFile ( f );
190
	return removeFile(f);
188
}
191
}
189
 
192
 
190
void CCatFile::LoadDatFile ()
193
void CCatFile::LoadDatFile ()
191
{
194
{
192
	if ( m_fDatFile.NoFile() )
195
	if ( m_fDatFile.NoFile() )
193
		return;
196
		return;
194
 
197
 
195
	if ( m_fDatFile.startRead() ) {
198
	if ( m_fDatFile.startRead() ) 
-
 
199
	{
196
		for ( CListNode<SInCatFile> *node = m_lFiles.Front(); node; node = node->next() )
200
		for(auto itr = _lFiles->cbegin(); itr != _lFiles->cend(); ++itr)
197
		{
201
		{
198
			SInCatFile *c = node->Data();
202
			SInCatFile *c = *itr;
199
			if ( c->sData )	delete c->sData;
203
			if ( c->sData )	delete c->sData;
200
 
204
 
201
			try {
205
			try {
202
				c->sData = new unsigned char[c->lSize + 1];
206
				c->sData = new unsigned char[c->lSize + 1];
203
			}
207
			}
204
			catch (std::exception &e) {
208
			catch (std::exception &e) {
205
				CLog::logf(CLog::Log_IO, 2, "CCatFile::LoadDatFile() unable to malloc data storage: %s, %d (%s)", c->sFile.c_str(), c->lSize, e.what());
209
				CLog::logf(CLog::Log_IO, 2, "CCatFile::LoadDatFile() unable to malloc data storage: %s, %d (%s)", c->sFile.c_str(), c->lSize, e.what());
206
				continue;
210
				continue;
207
			}
211
			}
208
 
212
 
209
			try {
213
			try {
210
				m_fDatFile.read(c->sData, c->lSize);
214
				m_fDatFile.read(c->sData, c->lSize);
211
			}
215
			}
212
			catch(std::exception &e) {
216
			catch(std::exception &e) {
213
				CLog::logf(CLog::Log_IO, 2, "CCatFile::LoadDatFile() unable to read file data: %s, %d (%s)", c->sFile.c_str(), c->lSize, e.what());
217
				CLog::logf(CLog::Log_IO, 2, "CCatFile::LoadDatFile() unable to read file data: %s, %d (%s)", c->sFile.c_str(), c->lSize, e.what());
214
				continue;
218
				continue;
215
			}
219
			}
216
			c->bDecrypted = false;
220
			c->bDecrypted = false;
Line 219... Line 223...
219
		m_fDatFile.close();
223
		m_fDatFile.close();
220
	}
224
	}
221
}
225
}
222
 
226
 
223
bool CCatFile::readFiles ()
227
bool CCatFile::readFiles ()
224
{
228
{
225
	size_t offset = 0;
229
	size_t offset = 0;
226
	int max = 0;
230
	int max = 0;
227
 
231
 
228
	Utils::String *lines = Utils::String(m_sData).tokenise("\n", &max);
232
	Utils::String *lines = Utils::String(m_sData).tokenise("\n", &max);
229
 
233
 
Line 233... Line 237...
233
		int start = 1;
237
		int start = 1;
234
		_sReadFilename = lines[0];
238
		_sReadFilename = lines[0];
235
		if ( _sReadFilename.token(" ", -1).isNumber() ) {
239
		if ( _sReadFilename.token(" ", -1).isNumber() ) {
236
			_sReadFilename.clear();
240
			_sReadFilename.clear();
237
			start = 0;
241
			start = 0;
238
		}
242
		}
239
 
243
 
240
		for(int i = start; i < max; i++) {
244
		for(int i = start; i < max; i++) {
241
			Utils::String l = lines[i];
245
			Utils::String l = lines[i];
242
 
246
 
243
			SInCatFile *catfile = new SInCatFile;
247
			SInCatFile *catfile = new SInCatFile;
244
 
248
 
245
			catfile->lSize = static_cast<size_t>(l.token(" ", -1).toLong());
249
			catfile->lSize = static_cast<size_t>(l.token(" ", -1).toLong());
246
			catfile->sFile = l.tokens(" ", 1, -2);
250
			catfile->sFile = l.tokens(" ", 1, -2);
247
			catfile->lOffset = offset;
251
			catfile->lOffset = offset;
248
			catfile->sData = 0;
252
			catfile->sData = 0;
249
 
253
 
250
			offset += catfile->lSize;
254
			offset += catfile->lSize;
251
 
255
 
252
			m_lFiles.push_back ( catfile );
256
			_lFiles->push_back(catfile);
253
		}
257
		}
254
	}
258
	}
255
 
259
 
256
	CLEANSPLIT(lines, max);
260
	CLEANSPLIT(lines, max);
257
/*
261
/*
Line 274... Line 278...
274
					size = atoi((const char *)data);
278
					size = atoi((const char *)data);
275
 
279
 
276
				if ( size )
280
				if ( size )
277
				{
281
				{
278
					SInCatFile *catfile = new SInCatFile;
282
					SInCatFile *catfile = new SInCatFile;
279
 
283
 
280
					catfile->lSize = size;
284
					catfile->lSize = size;
281
					catfile->sFile = file;
285
					catfile->sFile = file;
282
					catfile->lOffset = offset;
286
					catfile->lOffset = offset;
283
					catfile->sData = 0;
287
					catfile->sData = 0;
284
 
288
 
Line 301... Line 305...
301
bool CCatFile::DecryptData ( unsigned char *data, size_t size )
305
bool CCatFile::DecryptData ( unsigned char *data, size_t size )
302
{
306
{
303
	unsigned char cl=0xDB, dh=0xDC, dl=0xDD, ah=0xDE, ch=0xDF, al;
307
	unsigned char cl=0xDB, dh=0xDC, dl=0xDD, ah=0xDE, ch=0xDF, al;
304
	unsigned char *ptr = data, *end = data + size;
308
	unsigned char *ptr = data, *end = data + size;
305
	for ( ptr = data; ptr < end; ptr += 5)
309
	for ( ptr = data; ptr < end; ptr += 5)
306
	{
310
	{
307
		al=ch;
311
		al=ch;
308
		ch+=5;
312
		ch+=5;
309
		*(ptr + 4) ^= al;
313
		*(ptr + 4) ^= al;
310
		al=ah;
314
		al=ah;
311
		ah+=5;
315
		ah+=5;
Line 434... Line 438...
434
	unsigned char *data = UnPCKData(c->sData, c->lSize, size, false);
438
	unsigned char *data = UnPCKData(c->sData, c->lSize, size, false);
435
	if ( !data ) data = UnPCKData(c->sData, c->lSize, size, true);
439
	if ( !data ) data = UnPCKData(c->sData, c->lSize, size, true);
436
	return data;
440
	return data;
437
}
441
}
438
 
442
 
439
bool CCatFile::RemoveFile ( SInCatFile *f )
443
bool CCatFile::removeFile(SInCatFile *f)
440
{
444
{
441
	if ( (m_bCreate) || (m_lFiles.empty()) )
445
	if ( (m_bCreate) || (_lFiles->empty()) )
442
		return false;
446
		return false;
443
 
447
 
444
	if ( !f )
448
	if ( !f )
445
		return false;
449
		return false;
446
 
450
 
Line 453... Line 457...
453
	else if ( err != FILEERR_NONE )
457
	else if ( err != FILEERR_NONE )
454
		return false;
458
		return false;
455
 
459
 
456
	// adjust the file positions
460
	// adjust the file positions
457
	int iOffset = -1;
461
	int iOffset = -1;
458
	for ( CListNode<SInCatFile> *node = m_lFiles.Front(); node; node = node->next() ) {
462
	for (auto itr = _lFiles->cbegin(); itr != _lFiles->cend(); ++itr)
-
 
463
	{
-
 
464
		SInCatFile *c = *itr;
459
		if ( node->Data() == f ) {
465
		if (c == f) {
460
			iOffset = node->Data()->lOffset;
466
			iOffset = c->lOffset;
461
		}
467
		}
462
		else if ( iOffset >= 0 ) {
468
		else if ( iOffset >= 0 ) {
463
			node->Data()->lOffset = iOffset;
469
			c->lOffset = iOffset;
464
			iOffset += node->Data()->lSize;
470
			iOffset += c->lSize;
465
		}
471
		}
466
	}
472
	}
467
 
473
 
468
	// now just write the new cat file
474
	// now just write the new cat file
-
 
475
	auto findItr = std::find(_lFiles->begin(), _lFiles->end(), f);
-
 
476
	if (findItr != _lFiles->end())
469
	m_lFiles.remove ( f );
477
		_lFiles->erase(findItr);
470
	m_bCatChanged = true;
478
	m_bCatChanged = true;
471
 
479
 
472
	return true;
480
	return true;
473
}
481
}
474
 
482
 
475
bool CCatFile::WriteCatFile ()
483
bool CCatFile::WriteCatFile ()
476
{
484
{
477
	if ( (m_bCreate) && (m_lFiles.empty()) ) return false;
485
	if ( (m_bCreate) && (_lFiles->empty()) ) return false;
478
 
486
 
479
	Utils::String cat = m_fDatFile.filename() + "\n";
487
	Utils::String cat = m_fDatFile.filename() + "\n";
480
	for ( CListNode<SInCatFile> *node = m_lFiles.Front(); node; node = node->next() ) {
488
	for (auto itr = _lFiles->cbegin(); itr != _lFiles->cend(); ++itr)
-
 
489
	{
-
 
490
		SInCatFile *c = *itr;
481
		if ( !node->Data() ) continue;
491
		if ( !c ) continue;
482
		if ( node->Data()->sFile.Empty() ) continue;
492
		if ( c->sFile.empty() ) continue;
483
		Utils::String str = node->Data()->sFile.ToString();
493
		Utils::String str = c->sFile;
484
		cat += str.findReplace("/", "\\").findReplace("\\\\", "\\") + " " + (long)node->Data()->lSize + "\n";
494
		cat += str.findReplace("/", "\\").findReplace("\\\\", "\\") + " " + (long)c->lSize + "\n";
485
	}
495
	}
486
 
496
 
487
	if ( !cat.length() ) return false;
497
	if ( !cat.length() ) return false;
488
 
498
 
489
	// make sure the len is in multiples of 5, otherwise decryptData could cause heap problems
499
	// make sure the len is in multiples of 5, otherwise decryptData could cause heap problems
490
	size_t len = cat.length() + ((cat.length() % 5) ? 5 - (cat.length() % 5) : 0);
500
	size_t len = cat.length() + ((cat.length() % 5) ? 5 - (cat.length() % 5) : 0);
491
 
501
 
Line 505... Line 515...
505
	}
515
	}
506
 
516
 
507
	m_fCatFile.close();
517
	m_fCatFile.close();
508
	m_bCatChanged = false;
518
	m_bCatChanged = false;
509
	return ret;
519
	return ret;
510
}
520
}
511
 
521
 
512
bool CCatFile::CheckExtensionPck ( CyString filename )
522
std::vector<SInCatFile *> *CCatFile::GetFiles() const
513
{
523
{
514
	CyString ext = filename.GetToken ( ".", filename.NumToken  ( "." ) ).lower();
524
	return _lFiles;
-
 
525
}
515
 
526
 
-
 
527
bool CCatFile::checkExtensionPck(const Utils::String &filename) const
-
 
528
{	
-
 
529
	Utils::String ext = CFileIO(filename).extension().lower();
516
	if ( ext == "xml" )
530
	if ( ext == "xml" )
517
		return true;
531
		return true;
518
	else if ( ext == "txt" )
532
	else if ( ext == "txt" )
519
		return true;
533
		return true;
520
	else if ( ext == "bob" )
534
	else if ( ext == "bob" )
Line 531... Line 545...
531
 
545
 
532
	if ( ext == "pck" )
546
	if ( ext == "pck" )
533
		return true;
547
		return true;
534
	else if ( ext == "pbb" )
548
	else if ( ext == "pbb" )
535
		return true;
549
		return true;
536
	else if ( ext == "pbd" )
550
	else if ( ext == "pbd" )
537
		return true;
551
		return true;
538
 
552
 
539
	return false;
553
	return false;
540
}
554
}
541
 
555
 
542
CyString CCatFile::PckChangeExtension ( CyString f )
556
Utils::String CCatFile::PckChangeExtension(const Utils::String &f)
543
{
557
{
544
	CFileIO fo ( f );
558
	CFileIO fo ( f );
545
	Utils::String ext = fo.extension ().lower();
559
	Utils::String ext = fo.extension ().lower();
546
	if ( ext == "txt" )
560
	if ( ext == "txt" )
547
		return fo.ChangeFileExtension ( "pck" );
561
		return fo.changeFileExtension("pck");
548
	else if ( ext == "xml" )
562
	else if ( ext == "xml" )
549
		return fo.ChangeFileExtension ( "pck" );
563
		return fo.changeFileExtension("pck");
550
	else if ( ext == "bob" )
564
	else if ( ext == "bob" )
551
		return fo.ChangeFileExtension ( "pbb" );
565
		return fo.changeFileExtension("pbb");
552
	else if ( ext == "bod" )
566
	else if ( ext == "bod" )
553
		return fo.ChangeFileExtension ( "pbd" );
567
		return fo.changeFileExtension("pbd");
554
 
568
 
555
	return f;
569
	return f;
556
}
570
}
557
 
571
 
558
bool CCatFile::AppendFile(const Utils::String &filename, const Utils::String &sTo, bool pck, bool bXor, Utils::String *sChangeTo)
572
bool CCatFile::AppendFile(const Utils::String &filename, const Utils::String &sTo, bool pck, bool bXor, Utils::String *sChangeTo)
559
{
573
{
560
	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");
574
	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");
561
 
575
 
562
	if ( filename.isin ( "::" ) ) return WriteFromCat ( filename.token("::", 1), filename.token("::", 2));
576
	if ( filename.isin ( "::" ) ) return WriteFromCat ( filename.token("::", 1), filename.token("::", 2));
563
	if ( (!m_bCreate) && (!m_fDatFile.exists ()) ) {
577
	if ( (!m_bCreate) && (!m_fDatFile.exists ()) ) {
564
		CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() Cat File: %s, doesn't exist, quitting...", m_fCatFile.fullFilename().c_str());
578
		CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() Cat File: %s, doesn't exist, quitting...", m_fCatFile.fullFilename().c_str());
565
		return false;
579
		return false;
566
	}
580
	}
567
	CyString to = sTo;
581
	Utils::String to = sTo;
568
	if ( !m_sAddonDir.Empty() && CCatFile::IsAddonDir(to) ) {
582
	if ( !_sAddonDir.empty() && CCatFile::IsAddonDir(to) ) {
569
		CLog::logf(CLog::Log_IO, 3, "CCatFile::AppendFile() changing destination to included addon fir, %s => %s", to, m_sAddonDir + "/" + to);
583
		CLog::logf(CLog::Log_IO, 3, "CCatFile::AppendFile() changing destination to included addon fir, %s => %s", to, _sAddonDir + "/" + to);
570
		to = m_sAddonDir + "\\" + to;
584
		to = _sAddonDir + "\\" + to;
571
	}
585
	}
572
 
586
 
573
	// change the file extension and remove the file again
587
	// change the file extension and remove the file again
574
	if ( pck && CheckExtensionPck(filename) ) {
588
	if ( pck && checkExtensionPck(filename) ) {
575
		CLog::logf(CLog::Log_IO, 3, "CCatFile::AppendFile() changing file extension for packed file, %s => %s", to.c_str(), PckChangeExtension(to).ToString().c_str());
589
		CLog::logf(CLog::Log_IO, 3, "CCatFile::AppendFile() changing file extension for packed file, %s => %s", to.c_str(), PckChangeExtension(to).c_str());
576
		to = PckChangeExtension(to);
590
		to = PckChangeExtension(to);
577
	}
591
	}
578
	if ( sChangeTo ) *sChangeTo = to.ToString();
592
	if ( sChangeTo ) *sChangeTo = to;
579
 
593
 
580
	if ( !m_lFiles.empty() ) {
594
	if ( !_lFiles->empty() ) {
581
		SInCatFile *checkf = FindData ( to );
595
		SInCatFile *checkf = FindData ( to );
582
		if ( checkf ) {
596
		if ( checkf ) {
583
			CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() removing existing filechanging file extension for packed file, %s => %s", to.c_str(), PckChangeExtension(to).ToString().c_str());
597
			CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() removing existing filechanging file extension for packed file, %s => %s", to.c_str(), PckChangeExtension(to).c_str());
584
			if ( !RemoveFile(checkf) ) {
598
			if ( !removeFile(checkf) ) {
585
				CLog::logf(CLog::Log_IO, 1, "CCatFile::AppendFile() unable to remove existing file, quitting...");
599
				CLog::logf(CLog::Log_IO, 1, "CCatFile::AppendFile() unable to remove existing file, quitting...");
586
				return false;
600
				return false;
587
			}
601
			}
588
		}
602
		}
589
	}
603
	}
590
 
604
 
591
	bool append = false;
605
	bool append = false;
592
 
606
 
593
	SInCatFile *f = new SInCatFile;
607
	SInCatFile *f = new SInCatFile;
594
	f->sData = 0;
608
	f->sData = 0;
595
	f->lOffset = this->GetEndOffset();
609
	f->lOffset = this->GetEndOffset();
596
	
610
	
597
	bool dofile = true;
611
	bool dofile = true;
598
 
612
 
599
	if ( !m_lFiles.size() )	{
613
	if ( _lFiles->empty() )	{
600
		CLog::logf(CLog::Log_IO, 3, "CCatFile::AppendFile() no existing files found, wipeing the existing dat file");
614
		CLog::logf(CLog::Log_IO, 3, "CCatFile::AppendFile() no existing files found, wipeing the existing dat file");
601
		m_fDatFile.WipeFile();
615
		m_fDatFile.WipeFile();
602
	}
616
	}
603
 
617
 
604
	CFileIO File(filename);
618
	CFileIO File(filename);
Line 612... Line 626...
612
	File.close();
626
	File.close();
613
 
627
 
614
	// check if we need to pack the file
628
	// check if we need to pack the file
615
	int iFileType = this->_checkFiletype(data, 3);
629
	int iFileType = this->_checkFiletype(data, 3);
616
	CLog::logf(CLog::Log_IO, 3, "CCatFile::AppendFile() preparing to append file data, Type=%d", iFileType);
630
	CLog::logf(CLog::Log_IO, 3, "CCatFile::AppendFile() preparing to append file data, Type=%d", iFileType);
617
	if ( iFileType == FILETYPE_PLAIN && CheckPackedExtension(to.ToString()) ) {
631
	if ( iFileType == FILETYPE_PLAIN && CheckPackedExtension(to) ) {
618
		CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() plain text file needs to packed");
632
		CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() plain text file needs to packed");
619
		size_t newsize = 0;
633
		size_t newsize = 0;
620
		unsigned char *newdata = PCKData(data, File.fileSize(), &newsize, bXor);
634
		unsigned char *newdata = PCKData(data, File.fileSize(), &newsize, bXor);
621
		CLog::logf(CLog::Log_IO, 1, "CCatFile::AppendFile() file has been packed, %d => %d", File.fileSize(), newsize);
635
		CLog::logf(CLog::Log_IO, 1, "CCatFile::AppendFile() file has been packed, %d => %d", File.fileSize(), newsize);
622
 
636
 
Line 643... Line 657...
643
 
657
 
644
	if ( append ) {
658
	if ( append ) {
645
		CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() append complete, adding file into cat list");
659
		CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() append complete, adding file into cat list");
646
		m_bCreate = false;
660
		m_bCreate = false;
647
		f->sFile = to;
661
		f->sFile = to;
648
		m_lFiles.push_back ( f );
662
		_lFiles->push_back(f);
649
		CLog::logf(CLog::Log_IO, 3, "CCatFile::AppendFile() writing the new cat file");
663
		CLog::logf(CLog::Log_IO, 3, "CCatFile::AppendFile() writing the new cat file");
650
		m_bCatChanged = true;
664
		m_bCatChanged = true;
651
	}
665
	}
652
	else {
666
	else {
653
		CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() appending failed, cleaning up file data");
667
		CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() appending failed, cleaning up file data");
Line 655... Line 669...
655
	}
669
	}
656
 
670
 
657
	CLog::logf(CLog::Log_IO, 4, "CCatFile::AppendFile() function complete");
671
	CLog::logf(CLog::Log_IO, 4, "CCatFile::AppendFile() function complete");
658
 
672
 
659
	return append;
673
	return append;
660
}
674
}
661
 
675
 
662
bool CCatFile::AddData ( CyString catfile, unsigned char *data, size_t size, CyString to, bool pck, bool create )
676
bool CCatFile::AddData ( CyString catfile, unsigned char *data, size_t size, CyString to, bool pck, bool create )
663
{
677
{
664
	int err = Open ( catfile, "", CATREAD_CATDECRYPT, create );
678
	int err = Open ( catfile, "", CATREAD_CATDECRYPT, create );
665
	if ( (err != CATERR_NONE) && (err != CATERR_CREATED) )
679
	if ( (err != CATERR_NONE) && (err != CATERR_CREATED) )
666
		return false;
680
		return false;
667
 
681
 
668
	return AppendData ( data, size, to, pck );
682
	return AppendData ( data, size, to, pck );
669
}
683
}
670
 
684
 
671
int CCatFile::GetEndOffset()
685
int CCatFile::GetEndOffset()
672
{
686
{
673
	if ( m_lFiles.empty() )
687
	if ( _lFiles->empty() )
674
		return 0;
688
		return 0;
675
	else {
689
	else {
676
		for(SInCatFile *f = m_lFiles.First(); f; f = m_lFiles.Next()) {
-
 
677
			f->lOffset;
-
 
678
		}
-
 
679
		return m_lFiles.Back()->Data()->lOffset + m_lFiles.Back()->Data()->lSize;
690
		return _lFiles->back()->lOffset + _lFiles->back()->lSize;
680
	}
691
	}
681
}
692
}
682
 
693
 
-
 
694
size_t CCatFile::GetNumFiles() const 
-
 
695
{ 
-
 
696
	return _lFiles->size(); 
-
 
697
}
-
 
698
 
-
 
699
SInCatFile *CCatFile::GetFile(unsigned int num) const 
-
 
700
{ 
-
 
701
	return (num >= 0 && num < _lFiles->size()) ? _lFiles->at(num) : NULL; 
-
 
702
}
683
 
703
 
684
bool CCatFile::AppendData ( unsigned char *data, size_t size, CyString to, bool pck, bool bXor )
704
bool CCatFile::AppendData ( unsigned char *data, size_t size, CyString sTo, bool pck, bool bXor )
685
{
705
{
686
	if ( (!m_bCreate) && (!m_fCatFile.exists ()) )
706
	if ( (!m_bCreate) && (!m_fCatFile.exists ()) )
687
		return false;
707
		return false;
688
 
708
 
689
	if ( (size <= 0) || (!data) )
709
	if ( (size <= 0) || (!data) )
690
		return false;
710
		return false;
-
 
711
 
-
 
712
	Utils::String to = sTo.ToString();
691
 
713
 
692
	// then check if the file already exists
714
	// then check if the file already exists
693
	if ( !m_lFiles.empty() )
715
	if ( !_lFiles->empty() )
694
	{
716
	{
695
		SInCatFile *f = FindData ( to );
717
		SInCatFile *f = FindData ( to );
696
		if ( f )
718
		if ( f )
697
		{
719
		{
698
			if ( !RemoveFile ( f ) )
720
			if (!removeFile ( f ))
699
				return false;
721
				return false;
700
		}
722
		}
701
	}
723
	}
702
 
724
 
703
	bool append = false;
725
	bool append = false;
704
 
726
 
705
	if ( !m_lFiles.size() )
727
	if (_lFiles->empty())
706
		m_fDatFile.WipeFile();
728
		m_fDatFile.WipeFile();
707
 
729
 
708
	SInCatFile *f = new SInCatFile;
730
	SInCatFile *f = new SInCatFile;
709
	f->sData = 0;
731
	f->sData = 0;
710
	if ( m_lFiles.empty() )
732
	if (_lFiles->empty())
711
		f->lOffset = 0;
733
		f->lOffset = 0;
712
	else
734
	else
713
		f->lOffset = m_fDatFile.GetFilesize();
735
		f->lOffset = m_fDatFile.GetFilesize();
714
 
736
 
715
	// if file extension is packed but not the file, then pack it, "pck" forces it to be packed unless it already is
737
	// if file extension is packed but not the file, then pack it, "pck" forces it to be packed unless it already is
716
 
738
 
717
	f->lSize = size;
739
	f->lSize = size;
718
	if ( (((pck) && (CheckExtensionPck (to.ToString()))) || ((CheckPackedExtension ( to.ToString() )))) && (!IsDataPCK ( data, size )) )
740
	if ( (((pck) && (checkExtensionPck (to))) || ((CheckPackedExtension (to)))) && (!IsDataPCK ( data, size )) )
719
	{
741
	{
720
		to = PckChangeExtension ( to );
742
		to = PckChangeExtension ( to );
721
 
743
 
722
		if ( !m_lFiles.empty() )
744
		if (!_lFiles->empty())
723
		{
745
		{
724
			SInCatFile *f = FindData ( to );
746
			SInCatFile *f = FindData ( to );
725
			if ( f )
747
			if ( f )
726
			{
748
			{
727
				if ( !RemoveFile ( f ) )
749
				if (!removeFile(f))
728
					return false;
750
					return false;
729
			}
751
			}
730
		}
752
		}
731
		size_t newsize = 0;
753
		size_t newsize = 0;
732
		unsigned char *d = PCKData ( data, size, &newsize, bXor );
754
		unsigned char *d = PCKData ( data, size, &newsize, bXor );
Line 744... Line 766...
744
 
766
 
745
	m_fDatFile.close();
767
	m_fDatFile.close();
746
	if ( append ) {
768
	if ( append ) {
747
		m_bCreate = false;
769
		m_bCreate = false;
748
		f->sFile = to;
770
		f->sFile = to;
749
		m_lFiles.push_back ( f );
771
		_lFiles->push_back(f);
750
		m_bCatChanged = true;
772
		m_bCatChanged = true;
751
	}
773
	}
752
	else
774
	else
753
		delete f;
775
		delete f;
754
 
776
 
755
	return true;
777
	return true;
756
}
778
}
757
 
779
 
758
CyString CCatFile::RenameFileExtension(SInCatFile *f)
780
Utils::String CCatFile::RenameFileExtension(SInCatFile *f)
759
{
781
{
760
	CFileIO fo ( f->sFile );
782
	CFileIO fo(f->sFile);
761
	CyString ext = fo.GetFileExtension ().lower();
783
	Utils::String ext = fo.GetFileExtension ().lower().ToString();
762
	if ( ext == "pck" )
784
	if ( ext == "pck" )
763
	{
785
	{
764
		CyString firstDir = f->sFile.FindReplace("/", "\\").GetToken("\\", 1, 1).lower();
786
		Utils::String firstDir = f->sFile.findReplace("/", "\\").token("\\", 1).lower();
765
 
787
 
766
		if ( firstDir == "t" )
788
		if ( firstDir == "t" )
767
			return fo.ChangeFileExtension ( "xml" );
789
			return fo.changeFileExtension ( "xml" );
768
		else if ( firstDir == "director" )
790
		else if ( firstDir == "director" )
769
			return fo.ChangeFileExtension ( "xml" );
791
			return fo.changeFileExtension ( "xml" );
770
		return fo.ChangeFileExtension ( "txt" );
792
		return fo.changeFileExtension ( "txt" );
771
	}
793
	}
772
	else if ( ext == "pbb" )
794
	else if ( ext == "pbb" )
773
		return fo.ChangeFileExtension ( "bob" );
795
		return fo.changeFileExtension ( "bob" );
774
	else if ( ext == "pbd" )
796
	else if ( ext == "pbd" )
775
		return fo.ChangeFileExtension ( "bod" );
797
		return fo.changeFileExtension ( "bod" );
776
	return f->sFile;
798
	return f->sFile;
777
}
799
}
778
 
800
 
779
void CCatFile::FindFiles(CyStringList *files, CyString filemask)
801
void CCatFile::FindFiles(CyStringList *files, CyString filemask)
780
{
802
{
781
	if ( m_lFiles.empty() )
803
	if (_lFiles->empty())
782
		return;
804
		return;
783
 
805
 
784
	for ( SInCatFile *f = m_lFiles.First(); f; f = m_lFiles.Next() )
806
	for (auto itr = _lFiles->cbegin(); itr != _lFiles->cend(); ++itr)
785
	{
807
	{
786
		if ( filemask.WildMatch(f->sFile) )
808
		if ( filemask.WildMatch((*itr)->sFile) )
787
			files->PushBack(f->sFile);
809
			files->PushBack(CyString((*itr)->sFile));
788
	}
810
	}
789
}
811
}
790
 
812
 
791
bool CCatFile::ExtractAll(CyString dir)
813
bool CCatFile::ExtractAll(CyString dir)
792
{
814
{
793
	if ( m_lFiles.empty() )
815
	if (_lFiles->empty())
794
		return false;
816
		return false;
795
 
817
 
796
	for ( CListNode<SInCatFile> *node = m_lFiles.Front(); node; node = node->next() )
818
	for (auto itr = _lFiles->cbegin(); itr != _lFiles->cend(); ++itr)
797
	{
819
	{
798
		if ( !ExtractFile(node->Data(), dir, true) )
820
		if ( !ExtractFile(*itr, dir, true) )
799
			return false;
821
			return false;
800
	}
822
	}
801
 
823
 
802
	return true;
824
	return true;
803
}
825
}
804
bool CCatFile::ExtractFile ( CyString filename, CyString to, bool preserve )
826
bool CCatFile::ExtractFile ( CyString filename, CyString to, bool preserve )
805
{
827
{
806
	if ( m_lFiles.empty() )
828
	if (_lFiles->empty())
807
		return false;
829
		return false;
808
 
830
 
809
	// check if file exists
831
	// check if file exists
810
	if ( !m_sAddonDir.Empty() ) {
832
	if ( !_sAddonDir.empty() ) {
811
		SInCatFile *f = FindData ( m_sAddonDir + "\\" + filename );
833
		SInCatFile *f = FindData ( CyString(_sAddonDir) + "\\" + filename );
812
		if ( f )
834
		if ( f )
813
			return ExtractFile ( f, to, preserve );
835
			return ExtractFile ( f, to, preserve );
814
	}
836
	}
815
	{
837
	{
816
		SInCatFile *f = FindData ( CyString("addon\\") + filename );
838
		SInCatFile *f = FindData ( CyString("addon\\") + filename );
Line 922... Line 944...
922
	}
944
	}
923
 
945
 
924
	delete data;
946
	delete data;
925
	f->sData = 0;
947
	f->sData = 0;
926
 
948
 
927
	if ( bWritten ) this->ClearError();
949
	if ( bWritten ) this->clearError();
928
 
950
 
929
	return bWritten;
951
	return bWritten;
930
}
952
}
931
 
953
 
932
const Utils::String &CCatFile::internalDatFilename() const
954
const Utils::String &CCatFile::internalDatFilename() const
933
{
955
{
934
	return _sReadFilename;
956
	return _sReadFilename;
935
}
957
}
936
 
958
 
937
CyString CCatFile::GetErrorString ()
959
Utils::String CCatFile::getErrorString () const
938
{
960
{
939
	switch ( m_iError )
961
	switch ( m_iError )
940
	{
962
	{
941
		case CATERR_NONE:
963
		case CATERR_NONE:
942
			return NullString;
964
			return Utils::String::Null();
943
		case CATERR_NODATFILE:
965
		case CATERR_NODATFILE:
944
			return "Unable to open Dat file";
966
			return "Unable to open Dat file";
945
		case CATERR_NOCATFILE:
967
		case CATERR_NOCATFILE:
946
			return "Unable to open Cat file";
968
			return "Unable to open Cat file";
947
		case CATERR_FILEEMPTY:
969
		case CATERR_FILEEMPTY:
Line 1012... Line 1034...
1012
 
1034
 
1013
	zs.next_out=d;
1035
	zs.next_out=d;
1014
	zs.avail_out=(unsigned int)newsize - pos;
1036
	zs.avail_out=(unsigned int)newsize - pos;
1015
 
1037
 
1016
	while((ret=deflate(&zs, Z_FINISH))==Z_OK)
1038
	while((ret=deflate(&zs, Z_FINISH))==Z_OK)
1017
	{
1039
	{
1018
		newsize += 1024;
1040
		newsize += 1024;
1019
		data = (unsigned char *)realloc ( data, sizeof(unsigned char) * newsize );
1041
		data = (unsigned char *)realloc ( data, sizeof(unsigned char) * newsize );
1020
		zs.next_out=data + zs.total_out;
1042
		zs.next_out=data + zs.total_out;
1021
		zs.avail_out=(unsigned int)newsize - zs.total_out;
1043
		zs.avail_out=(unsigned int)newsize - zs.total_out;
1022
	}
1044
	}
Line 1079... Line 1101...
1079
		(*newsize)++;
1101
		(*newsize)++;
1080
		return finalData;
1102
		return finalData;
1081
	}
1103
	}
1082
 
1104
 
1083
	return NULL;
1105
	return NULL;
1084
}
1106
}
1085
 
1107
 
1086
bool CCatFile::WriteFromCat ( CCatFile *fcat, CyString file )
1108
bool CCatFile::WriteFromCat ( CCatFile *fcat, CyString file )
1087
{
1109
{
1088
	// now find the file in the cat file
1110
	// now find the file in the cat file
1089
	SInCatFile *getfile = fcat->FindData ( file );
1111
	SInCatFile *getfile = fcat->FindData ( file );
1090
	if ( !getfile )
1112
	if ( !getfile )
1091
		return false;
1113
		return false;
1092
 
1114
 
1093
	// read the dat from the cat file
1115
	// read the dat from the cat file
1094
	size_t size = 0;
1116
	size_t size = 0;
1095
	unsigned char *data = fcat->readData ( getfile, &size );
1117
	unsigned char *data = fcat->readData ( getfile, &size );
1096
	if ( !data )
1118
	if ( !data )
1097
		return false;
1119
		return false;
1098
 
1120
 
1099
	// now check if it exists in this file
1121
	// now check if it exists in this file
1100
	RemoveFile ( file );
1122
	removeFile(file.ToString());
1101
 
1123
 
1102
	int offset = (m_lFiles.empty()) ? 0 : (m_lFiles.Back()->Data()->lOffset + m_lFiles.Back()->Data()->lSize);
1124
	int offset = (_lFiles->empty()) ? 0 : (_lFiles->back()->lOffset + _lFiles->back()->lSize);
1103
	// now write to the new file
1125
	// now write to the new file
1104
	if ( getfile->bDecrypted ) this->DecryptDAT(getfile->sData, getfile->lSize);
1126
	if ( getfile->bDecrypted ) this->DecryptDAT(getfile->sData, getfile->lSize);
1105
	getfile->bDecrypted = false;
1127
	getfile->bDecrypted = false;
1106
	if ( !m_fDatFile.AppendDataToPos((const char *)getfile->sData, getfile->lSize, offset) ) return false;
1128
	if ( !m_fDatFile.AppendDataToPos((const char *)getfile->sData, getfile->lSize, offset) ) return false;
1107
    m_fDatFile.close();
1129
    m_fDatFile.close();
1108
 
1130
 
1109
	// finally add to the list
1131
	// finally add to the list
1110
	SInCatFile *f = new SInCatFile;
1132
	SInCatFile *f = new SInCatFile;
1111
	f->sData = 0;
1133
	f->sData = 0;
1112
	if ( m_lFiles.empty() )
1134
	if (_lFiles->empty())
1113
		f->lOffset = 0;
1135
		f->lOffset = 0;
1114
	else
1136
	else
1115
		f->lOffset = m_lFiles.Back()->Data()->lOffset + m_lFiles.Back()->Data()->lSize;
1137
		f->lOffset = _lFiles->back()->lOffset + _lFiles->back()->lSize;
1116
	f->sFile = file;
1138
	f->sFile = file.ToString();
1117
	f->lSize = size;
1139
	f->lSize = size;
1118
	m_lFiles.push_back ( f );
1140
	_lFiles->push_back(f);
1119
	m_bCatChanged = true;
1141
	m_bCatChanged = true;
1120
 
1142
 
1121
	return true;
1143
	return true;
1122
}
1144
}
1123
 
1145
 
Line 1128... Line 1150...
1128
		return false;
1150
		return false;
1129
 
1151
 
1130
	return this->WriteFromCat(&fcat, file);
1152
	return this->WriteFromCat(&fcat, file);
1131
}
1153
}
1132
 
1154
 
1133
SInCatFile *CCatFile::FindData ( CyString filename )
1155
SInCatFile *CCatFile::FindData(CyString filename)
-
 
1156
{
-
 
1157
	return findData(filename.ToString());
-
 
1158
}
-
 
1159
 
-
 
1160
SInCatFile *CCatFile::findData(const Utils::String &filename) const
1134
{
1161
{
1135
	if ( m_lFiles.empty() )
1162
	if (_lFiles->empty())
1136
		return NULL;
1163
		return NULL;
1137
 
1164
 
1138
	CyString check = filename;
1165
	Utils::String check = filename;
1139
	check = check.FindReplace ( ";\\";, "/" );
1166
	check = check.findReplace(";\\";, "/");
1140
	for ( SInCatFile *c = m_lFiles.First(); c; c = m_lFiles.Next() )
1167
	for (auto itr = _lFiles->cbegin(); itr != _lFiles->cend(); ++itr)
1141
	{
1168
	{
1142
		CyString f = c->sFile;
1169
		Utils::String f = (*itr)->sFile;
1143
		f = f.FindReplace ( ";\\";, "/" );
1170
		f = f.findReplace(";\\";, "/");
1144
		if ( f.Compare(check) )
1171
		if (f.Compare(check))
1145
			return c;
1172
			return *itr;
1146
	}
1173
	}
1147
	return NULL;
1174
	return NULL;
1148
}
1175
}
1149
 
1176
 
1150
bool CCatFile::MarkRemoveFile( CyString file )
1177
bool CCatFile::MarkRemoveFile( CyString file )