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 &e) {
345
				c->sData[c->lSize] = '\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 371... Line 362...
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 448... Line 437...
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;
461
		return false;
-
 
462
 
-
 
463
	CyString cat = m_fCatFile.GetFilename() + "\n";
-
 
464
 
450
 
-
 
451
	Utils::String cat = m_fCatFile.filename() + "\n";
465
	for ( SInCatFile *f = m_lFiles.First(); f; f = m_lFiles.Next() )
452
	for ( CListNode<SInCatFile> *node = m_lFiles.Front(); node; node = node->next() ) {
466
	{
-
 
467
		if ( f->sFile.Empty() )
453
		if ( !node->Data() ) continue;
468
			continue;
454
		if ( node->Data()->sFile.Empty() ) continue;
-
 
455
		Utils::String str = node->Data()->sFile.ToString();
469
		cat += f->sFile.findreplace("/", "\\") + " " + (long)f->lSize + "\n";
456
		cat += str.findReplace("/", "\\").findReplace("\\\\", "\\") + " " + (long)node->Data()->lSize + "\n";
470
	}
457
	}
471
 
458
 
472
	if ( !cat.Length() )
459
	if ( !cat.length() ) return false;
473
		return false;
-
 
474
 
460
 
475
	size_t len = cat.Length();
461
	// make sure the len is in multiples of 5, otherwise decryptData could cause heap problems
476
//	if ( len % 5)
-
 
477
//		len += (5 - (len % 5));
462
	size_t len = cat.length() + ((cat.length() % 5) ? 5 - (cat.length() % 5) : 0);
478
 
463
 
-
 
464
	bool ret = false;
-
 
465
	try {
479
	unsigned char *data = new unsigned char[len + 1];
466
		unsigned char *data = new unsigned char[len + 1];
480
	memcpy ( data, cat.c_str(), cat.Length() );
467
		memcpy(data, cat.c_str(), cat.length() * sizeof(unsigned char));
481
 
-
 
482
	for ( size_t i = len; i > cat.Length(); i-- )
468
		for ( size_t i = len; i >= cat.length(); i-- ) data[i] = '\0';
483
		data[i] = '\0';
-
 
484
 
-
 
485
	DecryptData ( data, len );
469
		this->DecryptData(data, len);
486
 
470
 
487
	m_fCatFile.WriteData ( (const char *)data, len );
471
		bool ret = m_fCatFile.write(data, cat.length());
-
 
472
		delete []data;
-
 
473
	}
-
 
474
	catch(std::exception &e) {
-
 
475
		CLog::logf(CLog::Log_IO, 2, "CCatFile::WriteCatFile() unable to malloc, %d (%s)", len + 1, e.what());
-
 
476
		return false;
-
 
477
	}
488
 
478
 
-
 
479
	m_fCatFile.close();
-
 
480
	m_bCatChanged = false;
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();
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 617... Line 609...
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;
621
 
613
 
-
 
614
	m_fDatFile.close();
-
 
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 );
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 1059... Line 1054...
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 1128... Line 1122...
1128
{
1122
{
1129
	f->bDelete = true;
1123
	f->bDelete = true;
1130
	return true;
1124
	return true;
1131
}
1125
}
1132
 
1126
 
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
}
-
 
1171
 
-
 
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") )
1175
	{
1130
	{
1176
		CFileIO TShips("tships.txt");
1131
		CFileIO TShips("tships.txt");