Subversion Repositories spk

Rev

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

Rev 52 Rev 53
Line 2... Line 2...
2
#include <time.h>
2
#include <time.h>
3
#include "File.h"
3
#include "File.h"
4
#include "DirIO.h"
4
#include "DirIO.h"
5
#include "Logging/Log.h"
5
#include "Logging/Log.h"
6
 
6
 
7
CCatFile::CCatFile ()
7
CCatFile::CCatFile () : m_bCatChanged(false)
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;
Line 14... Line 14...
14
 
14
 
15
CCatFile::~CCatFile ()
15
CCatFile::~CCatFile ()
16
{
16
{
17
	m_fDatFile.close();
17
	m_fDatFile.close();
18
	m_fCatFile.close();
18
	m_fCatFile.close();
-
 
19
 
-
 
20
	if ( m_bCatChanged ) {
-
 
21
		WriteCatFile ();
-
 
22
		m_fCatFile.close();
-
 
23
	}
-
 
24
 
19
	for ( SInCatFile *c = m_lFiles.First(); c; c = m_lFiles.Next() )
25
	for ( SInCatFile *c = m_lFiles.First(); c; c = m_lFiles.Next() )
20
	{
26
	{
21
		if ( c->sData )
27
		if ( c->sData )
22
			delete c->sData;
28
			delete []c->sData;
23
		delete c;
29
		delete c;
24
	}
30
	}
-
 
31
 
-
 
32
	if ( m_sData ) delete []m_sData;
-
 
33
 
25
	m_lFiles.clear();
34
	m_lFiles.clear();
26
}
35
}
27
 
36
 
28
bool CCatFile::IsAddonDir(CyString dir)
37
bool CCatFile::IsAddonDir(CyString dir)
29
{
38
{
Line 105... Line 114...
105
	// size must be multiples of 5
114
	// size must be multiples of 5
106
	size_t size = lFileSize + ((lFileSize % 5) ? 5 - (lFileSize % 5) : 0);
115
	size_t size = lFileSize + ((lFileSize % 5) ? 5 - (lFileSize % 5) : 0);
107
 
116
 
108
	// read cat to buffer
117
	// read cat to buffer
109
	try {
118
	try {
-
 
119
		if ( m_sData ) delete [] m_sData;
110
		m_sData = new unsigned char[size + 1];
120
		m_sData = new unsigned char[size + 1];
111
	}
121
	}
112
	catch (std::exception &e) {
122
	catch (std::exception &e) {
113
		CLog::logf(CLog::Log_IO, 2, "Memory Exception error, unable to alloc enough memory to store file data, %d (%s)", size + 1, e.what());
123
		CLog::logf(CLog::Log_IO, 2, "Memory Exception error, unable to alloc enough memory to store file data, %d (%s)", size + 1, e.what());
114
		return CATERR_MALLOC;
124
		return CATERR_MALLOC;
Line 219... Line 229...
219
 
229
 
220
	size_t offset = 0;
230
	size_t offset = 0;
221
 
231
 
222
	unsigned char *data = m_sData;
232
	unsigned char *data = m_sData;
223
	int spacePos = -1;
233
	int spacePos = -1;
224
	while ( m_sData[num] != '\0' )
234
	while ( m_sData[num] != '\0' ) {
225
	{
-
 
226
		if ( m_sData[num] == '\n' )
235
		if ( m_sData[num] == '\n' ) {
227
		{
-
 
228
			m_sData[num] = 0;
236
			m_sData[num] = 0;
229
			if ( spacePos != -1 )
237
			if ( spacePos != -1 )
230
			{
238
			{
231
				CyString file;
239
				CyString file;
232
				int size = 0;
240
				int size = 0;
Line 299... Line 307...
299
	return true;
307
	return true;
300
}
308
}
301
 
309
 
302
void CCatFile::RemoveData ()
310
void CCatFile::RemoveData ()
303
{
311
{
304
	if ( m_sData ) delete m_sData;
312
	delete m_sData;
305
	m_sData = NULL;
313
	m_sData = NULL;
306
	m_iDataType = CATFILE_NONE;
314
	m_iDataType = CATFILE_NONE;
307
	m_lSize = 0;
315
	m_lSize = 0;
308
}
316
}
309
 
317
 
Line 315... Line 323...
315
 
323
 
316
bool CCatFile::ReadFileToData ( SInCatFile *c )
324
bool CCatFile::ReadFileToData ( SInCatFile *c )
317
{
325
{
318
	if ( !c ) return false;
326
	if ( !c ) return false;
319
	size_t size = 0;
327
	size_t size = 0;
320
	if ( !c->sData ) c->sData = ReadData ( c, &size );
328
	if ( !c->sData ) c->sData = readData ( c, &size );
321
	if ( c->sData )	return true;
329
	if ( c->sData )	return true;
322
	return false;
330
	return false;
323
}
331
}
324
 
332
 
325
unsigned char *CCatFile::ReadData ( SInCatFile *c, size_t *size )
333
unsigned char *CCatFile::readData ( SInCatFile *c, size_t *size )
326
{
334
{
327
	*size = c->lSize;
335
	*size = c->lSize;
328
 
336
 
329
	std::fstream File(m_fDatFile.GetFullFilename().c_str(), std::ios::in | std::ios::binary);
-
 
330
	if ( File.is_open() ) {
337
	if ( !c->sData ) {
331
		File.seekg(c->lOffset, std::ios::beg);
338
		if ( m_fDatFile.startRead() ) {
332
		unsigned char *data;
339
			m_fDatFile.seek(c->lOffset);
333
		try {
-
 
334
			data = new unsigned char[c->lSize + 1];
340
			c->sData = m_fDatFile.read(c->lSize);
335
		}
-
 
336
		catch(std::exception &e) {
-
 
337
			CLog::logf(CLog::Log_IO, 2, "CCatFile::ReadData() unable to malloc data storage: %s, %d (%s)", c->sFile.c_str(), c->lSize, e.what());
-
 
338
			File.close();
341
			m_fDatFile.close();
339
			return NULL;
-
 
340
		}
-
 
341
 
342
 
342
		try {
-
 
343
			File.read((char *)data, c->lSize);
343
			if ( !c->sData ) (*size) = 0;
344
		}
344
			else {
345
		catch(std::exception &amp;e) {
345
				c->sData[c->lSize] = &apos;\0';
346
			CLog::logf(CLog::Log_IO, 2, "CCatFile::ReadData() unable to read file data: %s, %d (%s)", c->sFile.c_str(), c->lSize, e.what());
346
				DecryptDAT(c->sData, c->lSize);
347
			File.close();
347
				c->bDecrypted = true;
348
			return NULL;
348
			}
349
		}
349
		}
350
 
-
 
351
		File.close();
-
 
352
		*size = c->lSize;
-
 
353
		data[c->lSize] = '\0';
-
 
354
 
-
 
355
		DecryptDAT(data, c->lSize);
-
 
356
		c->bDecrypted = true;
-
 
357
 
-
 
358
		return data;
-
 
359
	}
350
	}
360
 
351
 
361
	return NULL;
352
	return c->sData;
362
}
353
}
363
 
354
 
364
void CCatFile::DecryptDAT(SInCatFile *pFile) 
355
void CCatFile::DecryptDAT(SInCatFile *pFile) 
365
{
356
{
366
	if ( pFile->bDecrypted ) return;
357
	if ( pFile->bDecrypted ) return;
Line 369... Line 360...
369
}
360
}
370
void CCatFile::DecryptDAT(unsigned char *buffer, size_t size)
361
void CCatFile::DecryptDAT(unsigned char *buffer, size_t size)
371
{
362
{
372
	for(unsigned char *pos=buffer, *end=buffer + size; pos < end; pos++){
363
	for(unsigned char *pos=buffer, *end=buffer + size; pos < end; pos++){
373
		*pos^=0x33;
364
		*pos^=0x33;
374
	}
365
	}
375
}
366
}
376
unsigned char *CCatFile::ReadData ( CyString filename, size_t *size )
367
unsigned char *CCatFile::readData ( CyString filename, size_t *size )
377
{
368
{
378
	*size = 0;
369
	*size = 0;
379
 
370
 
380
	if ( !m_fDatFile.NoFile() )
371
	if ( !m_fDatFile.NoFile() ) {
381
	{
-
 
382
		SInCatFile *c = FindData ( filename );
372
		SInCatFile *c = FindData ( filename );
383
		if ( c )
-
 
384
			return ReadData ( c, size );
373
		if ( c ) return readData ( c, size );
385
	}
374
	}
386
 
375
 
387
	return NULL;
376
	return NULL;
388
}
377
}
389
 
378
 
Line 399... Line 388...
399
 
388
 
400
	// plain file
389
	// plain file
401
	if ( iFiletype == FILETYPE_PLAIN ) {
390
	if ( iFiletype == FILETYPE_PLAIN ) {
402
		*size = c->lSize;
391
		*size = c->lSize;
403
		return c->sData;
392
		return c->sData;
404
	}
393
	}
405
 
394
 
406
	//otherwise unpack it
395
	//otherwise unpack it
407
 
396
 
408
//	if ( IsDataPCK ( (const unsigned char *)c->sData, c->lSize ) || forcepck )
397
//	if ( IsDataPCK ( (const unsigned char *)c->sData, c->lSize ) || forcepck )
409
	/*int iOffset = 0;
398
	/*int iOffset = 0;
410
	if ( iFiletype == FILETYPE_PCK ) {
399
	if ( iFiletype == FILETYPE_PCK ) {
Line 443... Line 432...
443
			iOffset = node->Data()->lOffset;
432
			iOffset = node->Data()->lOffset;
444
		}
433
		}
445
		else if ( iOffset >= 0 ) {
434
		else if ( iOffset >= 0 ) {
446
			node->Data()->lOffset = iOffset;
435
			node->Data()->lOffset = iOffset;
447
			iOffset += node->Data()->lSize;
436
			iOffset += node->Data()->lSize;
448
		}
437
		}
449
	}
438
	}
450
 
439
 
451
	// now just write the new cat file
440
	// now just write the new cat file
452
	m_lFiles.remove ( f );
441
	m_lFiles.remove ( f );
453
	WriteCatFile ();
442
	m_bCatChanged = true;
454
 
443
 
455
	return true;
444
	return true;
456
}
445
}
457
 
446
 
458
bool CCatFile::WriteCatFile ()
447
bool CCatFile::WriteCatFile ()
459
{
448
{
460
	if ( (m_bCreate) && (m_lFiles.empty()) )
449
	if ( (m_bCreate) && (m_lFiles.empty()) ) return false;
-
 
450
 
-
 
451
	Utils::String cat = m_fCatFile.filename() + "\n";
-
 
452
	for ( CListNode<SInCatFile> *node = m_lFiles.Front(); node; node = node->next() ) {
-
 
453
		if ( !node->Data() ) continue;
-
 
454
		if ( node->Data()->sFile.Empty() ) continue;
-
 
455
		Utils::String str = node->Data()->sFile.ToString();
-
 
456
		cat += str.findReplace("/", "\\").findReplace("\\\\", "\\") + " " + (long)node->Data()->lSize + "\n";
-
 
457
	}
-
 
458
 
461
		return false;
459
	if ( !cat.length() ) return false;
-
 
460
 
-
 
461
	// make sure the len is in multiples of 5, otherwise decryptData could cause heap problems
-
 
462
	size_t len = cat.length() + ((cat.length() % 5) ? 5 - (cat.length() % 5) : 0);
462
 
463
 
-
 
464
	bool ret = false;
-
 
465
	try {
463
	CyString cat = m_fCatFile.GetFilename() + "\n";
466
		unsigned char *data = new unsigned char[len + 1];
-
 
467
		memcpy(data, cat.c_str(), cat.length() * sizeof(unsigned char));
-
 
468
		for ( size_t i = len; i >= cat.length(); i-- ) data[i] = '\0';
-
 
469
		this->DecryptData(data, len);
464
 
470
 
465
	for ( SInCatFile *f = m_lFiles.First(); f; f = m_lFiles.Next() )
471
		bool ret = m_fCatFile.write(data, cat.length());
466
	{
-
 
467
		if ( f->sFile.Empty() )
-
 
468
			continue;
472
		delete []data;
469
		cat += f->sFile.findreplace("/", "\\") + " " + (long)f->lSize + "\n";
-
 
470
	}
473
	}
471
 
-
 
472
	if ( !cat.Length() )
474
	catch(std::exception &e) {
-
 
475
		CLog::logf(CLog::Log_IO, 2, "CCatFile::WriteCatFile() unable to malloc, %d (%s)", len + 1, e.what());
473
		return false;
476
		return false;
474
 
-
 
475
	size_t len = cat.Length();
-
 
476
//	if ( len % 5)
-
 
477
//		len += (5 - (len % 5));
-
 
478
 
477
	}
479
	unsigned char *data = new unsigned char[len + 1];
-
 
480
	memcpy ( data, cat.c_str(), cat.Length() );
-
 
481
 
478
 
482
	for ( size_t i = len; i > cat.Length(); i-- )
-
 
483
		data[i] = '\0';
479
	m_fCatFile.close();
484
 
-
 
485
	DecryptData ( data, len );
480
	m_bCatChanged = false;
486
 
-
 
487
	m_fCatFile.WriteData ( (const char *)data, len );
-
 
488
 
-
 
489
	return true;
481
	return ret;
490
}
482
}
491
 
483
 
492
bool CCatFile::CheckExtensionPck ( CyString filename )
484
bool CCatFile::CheckExtensionPck ( CyString filename )
493
{
485
{
494
	CyString ext = filename.GetToken ( ".", filename.NumToken  ( "." ) ).lower();
486
	CyString ext = filename.GetToken ( ".", filename.NumToken  ( "." ) ).lower();
495
 
487
 
496
	if ( ext == "xml" )
488
	if ( ext == "xml" )
497
		return true;
489
		return true;
498
	else if ( ext == "txt" )
490
	else if ( ext == "txt" )
499
		return true;
491
		return true;
500
	else if ( ext == "bob" )
492
	else if ( ext == "bob" )
501
		return true;
493
		return true;
502
	else if ( ext == "bod" )
494
	else if ( ext == "bod" )
503
		return true;
495
		return true;
504
 
496
 
Line 538... Line 530...
538
bool CCatFile::AppendFile(const Utils::String &filename, const Utils::String &sTo, bool pck, bool bXor, Utils::String *sChangeTo)
530
bool CCatFile::AppendFile(const Utils::String &filename, const Utils::String &sTo, bool pck, bool bXor, Utils::String *sChangeTo)
539
{
531
{
540
	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.GetFilename().ToString().c_str(), sTo.c_str(), (pck) ? "Yes" : "No", (bXor) ? "Yes" : "No");
532
	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.GetFilename().ToString().c_str(), sTo.c_str(), (pck) ? "Yes" : "No", (bXor) ? "Yes" : "No");
541
 
533
 
542
	if ( filename.isin ( "::" ) ) return WriteFromCat ( filename.token("::", 1), filename.token("::", 2));
534
	if ( filename.isin ( "::" ) ) return WriteFromCat ( filename.token("::", 1), filename.token("::", 2));
543
	if ( (!m_bCreate) && (!m_fCatFile.exists ()) ) {
535
	if ( (!m_bCreate) && (!m_fDatFile.exists ()) ) {
544
		CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() Cat File: %s, doesn't exist, quitting...", m_fCatFile.GetFullFilename().ToString().c_str());
536
		CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() Cat File: %s, doesn't exist, quitting...", m_fCatFile.GetFullFilename().ToString().c_str());
545
		return false;
537
		return false;
546
	}
538
	}
547
	CyString to = sTo;
539
	CyString to = sTo;
548
	if ( !m_sAddonDir.Empty() && CCatFile::IsAddonDir(to) ) {
540
	if ( !m_sAddonDir.Empty() && CCatFile::IsAddonDir(to) ) {
Line 577... Line 569...
577
	bool dofile = true;
569
	bool dofile = true;
578
 
570
 
579
	if ( !m_lFiles.size() )	{
571
	if ( !m_lFiles.size() )	{
580
		CLog::logf(CLog::Log_IO, 3, "CCatFile::AppendFile() no existing files found, wipeing the existing dat file");
572
		CLog::logf(CLog::Log_IO, 3, "CCatFile::AppendFile() no existing files found, wipeing the existing dat file");
581
		m_fDatFile.WipeFile();
573
		m_fDatFile.WipeFile();
582
	}
574
	}
583
 
575
 
584
	CFileIO File(filename);
576
	CFileIO File(filename);
585
	if ( !File.startRead() ) {
577
	if ( !File.startRead() ) {
586
		CLog::logf(CLog::Log_IO, 3, "CCatFile::AppendFile() unable to open file, %s, for reading", filename.c_str());
578
		CLog::logf(CLog::Log_IO, 3, "CCatFile::AppendFile() unable to open file, %s, for reading", filename.c_str());
587
		return false;
579
		return false;
588
	}
580
	}
Line 594... Line 586...
594
	// check if we need to pack the file
586
	// check if we need to pack the file
595
	int iFileType = this->_checkFiletype(data, 3);
587
	int iFileType = this->_checkFiletype(data, 3);
596
	CLog::logf(CLog::Log_IO, 3, "CCatFile::AppendFile() preparing to append file data, Type=%d", iFileType);
588
	CLog::logf(CLog::Log_IO, 3, "CCatFile::AppendFile() preparing to append file data, Type=%d", iFileType);
597
	if ( iFileType == FILETYPE_PLAIN && CheckPackedExtension(to) ) {
589
	if ( iFileType == FILETYPE_PLAIN && CheckPackedExtension(to) ) {
598
		CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() plain text file needs to packed");
590
		CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() plain text file needs to packed");
599
		size_t newsize = 0;
591
		size_t newsize = 0;
600
		unsigned char *newdata = PCKData(data, File.fileSize(), &newsize, bXor);
592
		unsigned char *newdata = PCKData(data, File.fileSize(), &newsize, bXor);
601
		CLog::logf(CLog::Log_IO, 1, "CCatFile::AppendFile() file has been packed, %d => %d", File.fileSize(), newsize);
593
		CLog::logf(CLog::Log_IO, 1, "CCatFile::AppendFile() file has been packed, %d => %d", File.fileSize(), newsize);
602
 
594
 
603
		f->lSize = newsize;
595
		f->lSize = newsize;
604
		CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() Decrypting data");
596
		CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() Decrypting data");
Line 616... Line 608...
616
		append = m_fDatFile.AppendDataToPos ( (const char *)data, f->lSize, f->lOffset );
608
		append = m_fDatFile.AppendDataToPos ( (const char *)data, f->lSize, f->lOffset );
617
	}
609
	}
618
 
610
 
619
	CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() cleaning up memory");
611
	CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() cleaning up memory");
620
	delete [] data;
612
	delete [] data;
-
 
613
 
-
 
614
	m_fDatFile.close();
621
 
615
 
622
	if ( append ) {
616
	if ( append ) {
623
		CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() append complete, adding file into cat list");
617
		CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() append complete, adding file into cat list");
624
		m_fDatFile.close();
-
 
625
		m_bCreate = false;
618
		m_bCreate = false;
626
		f->sFile = to;
619
		f->sFile = to;
627
		m_lFiles.push_back ( f );
620
		m_lFiles.push_back ( f );
628
		CLog::logf(CLog::Log_IO, 3, "CCatFile::AppendFile() writing the new cat file");
621
		CLog::logf(CLog::Log_IO, 3, "CCatFile::AppendFile() writing the new cat file");
629
		this->WriteCatFile ();
622
		m_bCatChanged = true;
630
	}
623
	}
631
	else {
624
	else {
632
		CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() appending failed, cleaning up file data");
625
		CLog::logf(CLog::Log_IO, 2, "CCatFile::AppendFile() appending failed, cleaning up file data");
633
		delete f;
626
		delete f;
634
	}
627
	}
635
 
628
 
-
 
629
	CLog::logf(CLog::Log_IO, 4, "CCatFile::AppendFile() function complete");
-
 
630
 
636
	return true;
631
	return append;
637
}
632
}
638
 
633
 
639
bool CCatFile::AddData ( CyString catfile, unsigned char *data, size_t size, CyString to, bool pck, bool create )
634
bool CCatFile::AddData ( CyString catfile, unsigned char *data, size_t size, CyString to, bool pck, bool create )
640
{
635
{
641
	int err = Open ( catfile, "", CATREAD_CATDECRYPT, create );
636
	int err = Open ( catfile, "", CATREAD_CATDECRYPT, create );
642
	if ( (err != CATERR_NONE) && (err != CATERR_CREATED) )
637
	if ( (err != CATERR_NONE) && (err != CATERR_CREATED) )
643
		return false;
638
		return false;
644
 
639
 
645
	return AppendData ( data, size, to, pck );
640
	return AppendData ( data, size, to, pck );
646
}
641
}
647
 
642
 
648
int CCatFile::GetEndOffset()
643
int CCatFile::GetEndOffset()
649
{
644
{
650
	if ( m_lFiles.empty() )
645
	if ( m_lFiles.empty() )
651
		return 0;
646
		return 0;
652
	else
647
	else
653
		return m_lFiles.Back()->Data()->lOffset + m_lFiles.Back()->Data()->lSize;
648
		return m_lFiles.Back()->Data()->lOffset + m_lFiles.Back()->Data()->lSize;
654
}
649
}
655
 
650
 
656
 
651
 
657
bool CCatFile::AppendData ( unsigned char *data, size_t size, CyString to, bool pck, bool bXor )
652
bool CCatFile::AppendData ( unsigned char *data, size_t size, CyString to, bool pck, bool bXor )
658
{
653
{
659
	if ( (!m_bCreate) && (!m_fCatFile.exists ()) )
654
	if ( (!m_bCreate) && (!m_fCatFile.exists ()) )
660
		return false;
655
		return false;
661
 
656
 
662
	if ( (size <= 0) || (!data) )
657
	if ( (size <= 0) || (!data) )
663
		return false;
658
		return false;
664
 
659
 
665
	// then check if the file already exists
660
	// then check if the file already exists
666
	if ( !m_lFiles.empty() )
661
	if ( !m_lFiles.empty() )
667
	{
662
	{
668
		SInCatFile *f = FindData ( to );
663
		SInCatFile *f = FindData ( to );
669
		if ( f )
664
		if ( f )
670
		{
665
		{
671
			if ( !RemoveFile ( f ) )
666
			if ( !RemoveFile ( f ) )
672
				return false;
667
				return false;
673
		}
668
		}
674
	}
669
	}
675
 
670
 
676
	bool append = false;
671
	bool append = false;
677
 
672
 
678
	if ( !m_lFiles.size() )
673
	if ( !m_lFiles.size() )
679
		m_fDatFile.WipeFile();
674
		m_fDatFile.WipeFile();
680
 
675
 
681
	SInCatFile *f = new SInCatFile;
676
	SInCatFile *f = new SInCatFile;
682
	f->sData = 0;
677
	f->sData = 0;
683
	if ( m_lFiles.empty() )
678
	if ( m_lFiles.empty() )
684
		f->lOffset = 0;
679
		f->lOffset = 0;
685
	else
680
	else
686
		f->lOffset = m_fDatFile.GetFilesize();
681
		f->lOffset = m_fDatFile.GetFilesize();
687
 
682
 
688
	// if file extension is packed but not the file, then pack it, "pck" forces it to be packed unless it already is
683
	// if file extension is packed but not the file, then pack it, "pck" forces it to be packed unless it already is
689
 
684
 
690
	f->lSize = size;
685
	f->lSize = size;
691
	if ( (((pck) && (CheckExtensionPck (to))) || ((CheckPackedExtension ( to )))) && (!IsDataPCK ( data, size )) )
686
	if ( (((pck) && (CheckExtensionPck (to))) || ((CheckPackedExtension ( to )))) && (!IsDataPCK ( data, size )) )
692
	{
687
	{
693
		to = PckChangeExtension ( to );
688
		to = PckChangeExtension ( to );
694
 
689
 
695
		if ( !m_lFiles.empty() )
690
		if ( !m_lFiles.empty() )
696
		{
691
		{
697
			SInCatFile *f = FindData ( to );
692
			SInCatFile *f = FindData ( to );
Line 719... Line 714...
719
	{
714
	{
720
		m_fDatFile.close();
715
		m_fDatFile.close();
721
		m_bCreate = false;
716
		m_bCreate = false;
722
		f->sFile = to;
717
		f->sFile = to;
723
		m_lFiles.push_back ( f );
718
		m_lFiles.push_back ( f );
724
		WriteCatFile ();
719
		m_bCatChanged = true;
725
	}
720
	}
726
	else
721
	else
727
		delete f;
722
		delete f;
728
 
723
 
729
	return true;
724
	return true;
Line 990... Line 985...
990
		zs.avail_out=(unsigned int)newsize - zs.total_out;
985
		zs.avail_out=(unsigned int)newsize - zs.total_out;
991
	}
986
	}
992
	pos += zs.total_out;
987
	pos += zs.total_out;
993
 
988
 
994
	deflateEnd(&zs);
989
	deflateEnd(&zs);
995
 
990
 
996
	unsigned long crc=crc32(0, NULL, 0);
991
	unsigned long crc=crc32(0, NULL, 0);
997
	crc=crc32(crc, buffer, (unsigned int)size);
992
	crc=crc32(crc, buffer, (unsigned int)size);
998
 
993
 
999
	int s = sizeof(crc) + sizeof(size);
994
	int s = sizeof(crc) + sizeof(size);
1000
	if ( newsize < (size_t)(s + pos) )
995
	if ( newsize < (size_t)(s + pos) )
1001
	{
996
	{
1002
		newsize += (s + pos) - newsize;
997
		newsize += (s + pos) - newsize;
1003
		data = (unsigned char *)realloc ( data, sizeof(unsigned char) * newsize );
998
		data = (unsigned char *)realloc ( data, sizeof(unsigned char) * newsize );
1004
	}
999
	}
1005
 
1000
 
1006
	memcpy(&data[pos], &crc, sizeof(crc));
1001
	memcpy(&data[pos], &crc, sizeof(crc));
1007
	pos += sizeof(crc);
1002
	pos += sizeof(crc);
1008
	memcpy(&data[pos], &size, sizeof(size));
1003
	memcpy(&data[pos], &size, sizeof(size));
1009
	pos += sizeof(size);
1004
	pos += sizeof(size);
1010
 
1005
 
1011
	newsize = pos;
1006
	newsize = pos;
1012
 
1007
 
1013
	unsigned char *retdata = NULL;
1008
	unsigned char *retdata = NULL;
1014
	if ( ret == Z_STREAM_END )
1009
	if ( ret == Z_STREAM_END )
1015
	{
1010
	{
1016
		*retsize = newsize;
1011
		*retsize = newsize;
1017
		retdata = new unsigned char[newsize];
1012
		retdata = new unsigned char[newsize];
Line 1055... Line 1050...
1055
bool CCatFile::WriteFromCat ( CCatFile *fcat, CyString file )
1050
bool CCatFile::WriteFromCat ( CCatFile *fcat, CyString file )
1056
{
1051
{
1057
	// now find the file in the cat file
1052
	// now find the file in the cat file
1058
	SInCatFile *getfile = fcat->FindData ( file );
1053
	SInCatFile *getfile = fcat->FindData ( file );
1059
	if ( !getfile )
1054
	if ( !getfile )
1060
		return false;
1055
		return false;
1061
 
1056
 
1062
	// read the dat from the cat file
1057
	// read the dat from the cat file
1063
	size_t size = 0;
1058
	size_t size = 0;
1064
	unsigned char *data = fcat->ReadData ( getfile, &size );
1059
	unsigned char *data = fcat->readData ( getfile, &size );
1065
	if ( !data )
1060
	if ( !data )
1066
		return false;
1061
		return false;
1067
 
1062
 
1068
	// now check if it exists in this file
1063
	// now check if it exists in this file
1069
	RemoveFile ( file );
1064
	RemoveFile ( file );
1070
 
1065
 
1071
	// now write to the new file
1066
	// now write to the new file
1072
	if ( !m_fDatFile.AppendData ( (const char *)data, size ) )
1067
	if ( !m_fDatFile.AppendData ( (const char *)data, size ) ) return false;
1073
		return false;
-
 
1074
 
1068
 
1075
	// finally add to the list
1069
	// finally add to the list
1076
	SInCatFile *f = new SInCatFile;
1070
	SInCatFile *f = new SInCatFile;
1077
	f->sData = 0;
1071
	f->sData = 0;
1078
	if ( m_lFiles.empty() )
1072
	if ( m_lFiles.empty() )
Line 1080... Line 1074...
1080
	else
1074
	else
1081
		f->lOffset = m_lFiles.Back()->Data()->lOffset + m_lFiles.Back()->Data()->lSize;
1075
		f->lOffset = m_lFiles.Back()->Data()->lOffset + m_lFiles.Back()->Data()->lSize;
1082
	f->sFile = file;
1076
	f->sFile = file;
1083
	f->lSize = size;
1077
	f->lSize = size;
1084
	m_lFiles.push_back ( f );
1078
	m_lFiles.push_back ( f );
1085
	WriteCatFile ();
1079
	m_bCatChanged = true;
1086
 
1080
 
1087
	return true;
1081
	return true;
1088
}
1082
}
1089
 
1083
 
1090
bool CCatFile::WriteFromCat ( CyString catfile, CyString file )
1084
bool CCatFile::WriteFromCat ( CyString catfile, CyString file )
Line 1092... Line 1086...
1092
	CCatFile fcat;
1086
	CCatFile fcat;
1093
	if ( fcat.Open ( catfile, "", CATREAD_CATDECRYPT, false ) )
1087
	if ( fcat.Open ( catfile, "", CATREAD_CATDECRYPT, false ) )
1094
		return false;
1088
		return false;
1095
 
1089
 
1096
	return this->WriteFromCat(&fcat, file);
1090
	return this->WriteFromCat(&fcat, file);
1097
}
1091
}
1098
 
1092
 
1099
SInCatFile *CCatFile::FindData ( CyString filename )
1093
SInCatFile *CCatFile::FindData ( CyString filename )
1100
{
1094
{
1101
	if ( m_lFiles.empty() )
1095
	if ( m_lFiles.empty() )
1102
		return NULL;
1096
		return NULL;
1103
 
1097
 
Line 1109... Line 1103...
1109
		f = f.FindReplace ( "\\", "/" );
1103
		f = f.FindReplace ( "\\", "/" );
1110
		if ( f.Compare(check) )
1104
		if ( f.Compare(check) )
1111
			return c;
1105
			return c;
1112
	}
1106
	}
1113
	return NULL;
1107
	return NULL;
1114
}
1108
}
1115
 
1109
 
1116
bool CCatFile::MarkRemoveFile( CyString file )
1110
bool CCatFile::MarkRemoveFile( CyString file )
1117
{
1111
{
1118
	SInCatFile *f = FindData ( file );
1112
	SInCatFile *f = FindData ( file );
1119
	if ( !f )
1113
	if ( !f )
1120
	{
1114
	{
1121
		m_iError = CATERR_NOFILE;
1115
		m_iError = CATERR_NOFILE;
1122
		return false;
1116
		return false;
1123
	}
1117
	}
1124
 
1118
 
1125
	return MarkRemoveFile ( f );
1119
	return MarkRemoveFile ( f );
1126
}
1120
}
1127
bool CCatFile::MarkRemoveFile ( SInCatFile *f )
1121
bool CCatFile::MarkRemoveFile ( SInCatFile *f )
1128
{
1122
{
1129
	f->bDelete = true;
1123
	f->bDelete = true;
1130
	return true;
1124
	return true;
1131
}
-
 
1132
 
-
 
1133
 
-
 
1134
void CCatFile::WriteFiles()
-
 
1135
{
-
 
1136
	int count = 0;
-
 
1137
	CListNode<SInCatFile> *node;
-
 
1138
	for ( node = m_lFiles.Front(); node; node = node->next() )
-
 
1139
	{
-
 
1140
		if ( node->Data()->bDelete )
-
 
1141
			++count;
-
 
1142
	}
-
 
1143
 
-
 
1144
	if ( !count )
-
 
1145
		return;
-
 
1146
 
-
 
1147
	size_t *offset = new size_t[count * 2];
-
 
1148
	count = 0;
-
 
1149
 
-
 
1150
	node = m_lFiles.Front();
-
 
1151
	while ( node )
-
 
1152
	{
-
 
1153
		CListNode<SInCatFile> *nextNode = node->next();
-
 
1154
 
-
 
1155
		SInCatFile *f = node->Data();
-
 
1156
		if ( f->bDelete )
-
 
1157
		{
-
 
1158
			offset[count++] = f->lOffset;
-
 
1159
			offset[count++] = f->lSize;
-
 
1160
 
-
 
1161
			m_lFiles.remove(node);
-
 
1162
			delete f;
-
 
1163
		}
-
 
1164
 
-
 
1165
		node = nextNode;
-
 
1166
	}
-
 
1167
 
-
 
1168
	if ( m_fDatFile.WritePartFile(offset, count) )
-
 
1169
		WriteCatFile();
-
 
1170
}
1125
}
1171
 
1126
 
1172
CyStringList *CCatFile::GetTShipsEntries()
1127
CyStringList *CCatFile::GetTShipsEntries()
1173
{
1128
{
1174
	if ( this->ExtractFile("types/tships.pck", "tships.txt") )
1129
	if ( this->ExtractFile("types/tships.pck", "tships.txt") )