Subversion Repositories spk

Rev

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

Rev 57 Rev 58
Line 1... Line 1...
1
 
1
 
2
#include "ModDiff.h"
2
#include "ModDiff.h"
3
#include "File_IO.h"
3
#include "File_IO.h"
4
#include "CatFile.h"
4
#include "CatFile.h"
5
 
5
 
6
CModDiff::CModDiff(CyString &dir, int maxPatch)
6
CModDiff::CModDiff(const Utils::String &dir, const Utils::String &sAddon, int maxPatch) : m_pCatFile(NULL), m_sAddon(sAddon), m_sTempDir("."), m_iMaxPatch(maxPatch)
7
{
7
{
8
	m_bLoaded = LoadDirectory(dir);
8
	m_bLoaded = this->LoadDirectory(dir);
9
	m_sTempDir = ".";
-
 
10
	m_iMaxPatch = maxPatch;
-
 
11
}
9
}
12
 
10
 
13
CModDiff::~CModDiff(void)
11
CModDiff::~CModDiff(void)
14
{
12
{
-
 
13
	delete m_pCatFile;
15
}
14
}
16
 
15
 
17
bool CModDiff::LoadDirectory(CyString &dir)
16
bool CModDiff::LoadDirectory(const Utils::String &dir)
18
{
17
{
19
	m_sCurrentDir = dir;
18
	m_sCurrentDir = dir;
-
 
19
	m_fileSystem.SetAddon(m_sAddon);
20
	return m_fileSystem.LoadFilesystem(dir.ToString(), m_iMaxPatch);
20
	return m_fileSystem.LoadFilesystem(dir, m_iMaxPatch);
21
}
21
}
22
 
22
 
-
 
23
bool CModDiff::startDiff(const Utils::String &sModFile)
-
 
24
{
-
 
25
	ClearError();
-
 
26
	if ( !CFileIO::Exists(sModFile) ) { m_iError = MDERR_FILENOTFOUND; return false; }
-
 
27
 
-
 
28
	delete m_pCatFile;
-
 
29
	m_pCatFile = new CCatFile;
-
 
30
 
-
 
31
	if ( m_pCatFile->Open(sModFile, m_sAddon, CATREAD_CATDECRYPT, false) != CATERR_NONE ) { 
-
 
32
		delete m_pCatFile;
-
 
33
		m_pCatFile = NULL;
-
 
34
		m_iError = MDERR_CANTOPENMOD; 
-
 
35
		return false; 
-
 
36
	}
-
 
37
 
-
 
38
	return true;
-
 
39
}
-
 
40
 
-
 
41
Utils::String CModDiff::_extractFile(const Utils::String &sFile, const Utils::String &sTo)
-
 
42
{
-
 
43
	SInCatFile *c = m_pCatFile->FindData(sFile);
-
 
44
	if ( !c ) c = m_pCatFile->FindData(m_sAddon + "/" + sFile);
-
 
45
	if ( !c ) return m_fileSystem.ExtractGameFile(sFile, sTo);
-
 
46
	if ( m_pCatFile->ExtractFile(c, sTo) ) return sTo;
-
 
47
	return "";
-
 
48
}
-
 
49
 
-
 
50
bool CModDiff::doDiff(const Utils::String &sModFile)
-
 
51
{
-
 
52
	// find the file in the loaded cat
-
 
53
	SInCatFile *c = m_pCatFile->FindData(sModFile);
-
 
54
	if ( !c ) c = m_pCatFile->FindData(m_sAddon + "/" + sModFile);
-
 
55
	if ( !c ) return false;
-
 
56
 
-
 
57
	// extract the matching file
-
 
58
	Utils::String sToFile = CFileIO(m_sTempDir + "/" + CFileIO(c->sFile).filename()).fullFilename();
-
 
59
	if ( !m_pCatFile->ExtractFile(sModFile, sToFile) ) return false;
-
 
60
 
-
 
61
	// create a diff
-
 
62
	Utils::String to = m_fileSystem.ExtractGameFile(c->sFile.ToString(), sToFile + ".compare");
-
 
63
	if ( !to.empty() ) {
-
 
64
		SDiffFile *diff = diffFile(to, sToFile, c->sFile.ToString());
-
 
65
		if ( diff ) { 
-
 
66
			this->_adjustFile(sModFile, diff, false);
-
 
67
		}
-
 
68
		CFileIO::Remove(to);
-
 
69
	}
-
 
70
 
-
 
71
	CFileIO::Remove(sToFile);
-
 
72
 
-
 
73
	return true;
-
 
74
}
-
 
75
 
-
 
76
 
-
 
77
bool CModDiff::_adjustTShips(SDiffFile *pDiff, bool bReverse)
-
 
78
{
-
 
79
	// need to read TCockpits
-
 
80
	Utils::String sTo = this->_extractFile("types/TCockpits.pck", "TCockpits.xml");
-
 
81
	if ( sTo.empty() ) return false;
-
 
82
	CFileIO TCockpits("TCockpits.xml");
-
 
83
	if ( !TCockpits.exists() ) return false;
-
 
84
	CyStringList *pFiles = TCockpits.ReadLinesStr();
-
 
85
	if ( !pFiles ) return false;
-
 
86
 
-
 
87
	// remove all the comments
-
 
88
	for ( SStringList *str = pFiles->Head(); str; str = str->next ) {
-
 
89
		if ( str->str[0] == '/' ) str->remove = true;
-
 
90
	}
-
 
91
	pFiles->RemoveMarked();
-
 
92
	pFiles->PopFront();
-
 
93
 
-
 
94
	std::map<std::string, int> fileSet;
-
 
95
	int iPos = 0;
-
 
96
	for ( SStringList *str = pFiles->Head(); str; str = str->next ) fileSet[Utils::String(str->str.ToString()).token(";", -2)] = iPos++;
-
 
97
 
-
 
98
	// now cycle through ships and adjust the cockpits
-
 
99
	int iCount = -1;
-
 
100
	for ( SDiffEntry *pEntry = pDiff->m_lEntries.First(); pEntry; pEntry = pDiff->m_lEntries.Next() ) {
-
 
101
		switch (pEntry->iType) {
-
 
102
			case DIFFTYPE_ADDITION:
-
 
103
				{
-
 
104
					SDiffEntryAddition *pAddition = static_cast<SDiffEntryAddition *>(pEntry);
-
 
105
					if ( pAddition ) {
-
 
106
						for ( int t = 0; t < 6; t++ ) {
-
 
107
							Utils::String sE = pAddition->sEntry.token(";", 32 + (t * 2));
-
 
108
							if ( !bReverse && sE.isNumber() ) {
-
 
109
								int iTurret = sE;
-
 
110
								if ( iTurret && iTurret < pFiles->Count() ) {
-
 
111
									Utils::String sCockpit = pFiles->GetAt(iTurret)->str.ToString();
-
 
112
									pAddition->sEntry = pAddition->sEntry.replaceToken(";", 32 + (t * 2), sCockpit.token(";", -2) + ":" + static_cast<long>(iTurret));
-
 
113
								}
-
 
114
							}
-
 
115
							else if ( bReverse && !sE.isNumber() ) {
-
 
116
								int iUnfound = 0;
-
 
117
								if ( sE.isin(":") ) {
-
 
118
									iUnfound = sE.token(":", 2);
-
 
119
									sE = sE.token(":", 1);
-
 
120
								}
-
 
121
								int iEntry = (fileSet.find(sE) == fileSet.end()) ? iUnfound : fileSet[sE];
-
 
122
								pAddition->sEntry = pAddition->sEntry.replaceToken(";", 32 + (t * 2), static_cast<long>(iEntry));
-
 
123
							}
-
 
124
						}
-
 
125
					}
-
 
126
				}
-
 
127
				break;
-
 
128
			case DIFFTYPE_CHANGE:
-
 
129
				{
-
 
130
					SDiffEntryChange *pChange = static_cast<SDiffEntryChange *>(pEntry);
-
 
131
					if ( pChange->iPos >= 32 && pChange->iPos <= 42 && (pChange->iPos % 2) && pChange->sEntry.isNumber() ) {
-
 
132
						Utils::String sCockpit = pFiles->GetAt(pChange->sEntry)->str.ToString();
-
 
133
						pChange->sEntry = sCockpit.token(";", -2) + ":" + pChange->sEntry;
-
 
134
					}
-
 
135
				}
-
 
136
				break;
-
 
137
		}
-
 
138
	}
-
 
139
 
-
 
140
	delete pFiles;
-
 
141
 
-
 
142
	return true;
-
 
143
}
-
 
144
 
-
 
145
int CModDiff::_specialType(const Utils::String &sFile)
-
 
146
{
-
 
147
	if ( sFile.Compare("TShips") ) return MERGETYPE_TSHIPS;
-
 
148
	return MERGETYPE_NONE;
-
 
149
}
-
 
150
 
-
 
151
void CModDiff::_adjustFile(const Utils::String &sFile, SDiffFile *pDiff, bool bReverse)
-
 
152
{
-
 
153
	// check if we need to adjust the file
-
 
154
	CFileIO File(sFile);
-
 
155
	int iType = _specialType(File.baseName());
-
 
156
	if ( iType == MERGETYPE_NONE ) return;
-
 
157
 
-
 
158
	// read in the file data
-
 
159
	switch(iType) {
-
 
160
		case MERGETYPE_TSHIPS:
-
 
161
			this->_adjustTShips(pDiff, bReverse);
-
 
162
			break;
-
 
163
	}
-
 
164
}
-
 
165
 
23
bool CModDiff::CreateDiff(CyString &modfile)
166
bool CModDiff::CreateDiff(const Utils::String &modfile)
24
{
167
{
25
	ClearError();
168
	ClearError();
26
 
169
 
27
	//check for valid parameters
170
	//check for valid parameters
28
	if ( !CFileIO(modfile).ExistsOld() ) { m_iError = MDERR_FILENOTFOUND; return false; }
171
	if ( !CFileIO(modfile).ExistsOld() ) { m_iError = MDERR_FILENOTFOUND; return false; }
29
 
172
 
30
	CyString addonDir = "";
173
	Utils::String addonDir = "";
31
	int addonSize = addonDir.Length() + 1;
174
	int addonSize = addonDir.length() + 1;
32
 
175
 
33
	// try and open the mod file
176
	// try and open the mod file
34
	CCatFile cat;
177
	CCatFile cat;
35
	if ( cat.Open(modfile, addonDir, CATREAD_DAT, false) != CATERR_NONE ) { m_iError = MDERR_CANTOPENMOD; return false; }
178
	if ( cat.Open(modfile, addonDir, CATREAD_DAT, false) != CATERR_NONE ) { m_iError = MDERR_CANTOPENMOD; return false; }
36
 
179
 
37
	// we'll need to read in all the types/text files
180
	// we'll need to read in all the types/text files
38
	for ( int i = 0; i < cat.GetNumFiles(); i++ )
181
	for ( int i = 0; i < cat.GetNumFiles(); i++ )
39
	{
182
	{
40
		SInCatFile *f = cat.GetFile(i);
183
		SInCatFile *f = cat.GetFile(i);
41
		CyString checkFile = f->sFile.FindReplace("\\", "/");
184
		Utils::String checkFile = f->sFile.FindReplace("\\", "/").ToString();
42
		if ( (checkFile.Left(6).Compare("types/") || checkFile.Left(2).Compare("t/") || checkFile.Left(6 + addonSize).Compare(addonDir + "/types/") || checkFile.Left(2 + addonSize).Compare(addonDir + "/t/")) && ValidFile(checkFile) )
185
		if ( (checkFile.left(6).Compare("types/") || checkFile.left(2).Compare("t/") || checkFile.left(6 + addonSize).Compare(addonDir + "/types/") || checkFile.left(2 + addonSize).Compare(addonDir + "/t/")) && _validFile(checkFile) )
43
		{
186
		{
44
			// extract the file to the temp dir
187
			// extract the file to the temp dir
45
			CyString toFile = CFileIO(m_sTempDir + "/" + CFileIO(f->sFile).GetFilename()).GetFullFilename();
188
			Utils::String toFile = CFileIO(m_sTempDir + "/" + CFileIO(f->sFile).filename()).fullFilename();
46
			if ( cat.ExtractFile(f, toFile ) )
189
			if ( cat.ExtractFile(f, toFile ) )
47
			{
190
			{
48
				// now extract the matching file from the game dir
191
				// now extract the matching file from the game dir
49
				if ( m_fileSystem.ExtractGameFile(f->sFile.ToString(), (toFile + ".compare").ToString()) )
192
				if ( m_fileSystem.ExtractGameFile(f->sFile.ToString(), toFile + ".compare") )
50
				{
193
				{
51
					DiffFile(toFile + ".compare", toFile, f->sFile);
194
					diffFile(toFile + ".compare", toFile, f->sFile.ToString());
52
					CFileIO::Remove(toFile.ToString() + ".compare");
195
					CFileIO::Remove(toFile + ".compare");
53
				}
196
				}
54
				// make sure we clear up afterwards
197
				// make sure we clear up afterwards
55
				CFileIO::Remove(toFile.ToString());
198
				CFileIO::Remove(toFile);
56
			}
199
			}
57
		}
200
		}
58
	}
201
	}
59
 
202
 
60
	return true;
203
	return true;
61
}
204
}
62
 
205
 
63
bool CModDiff::DiffFile(CyString &baseFile, CyString &modFile, CyString &fileType)
206
SDiffFile *CModDiff::diffFile(const Utils::String &baseFile, const Utils::String &modFile, const Utils::String &fileType)
64
{
207
{
65
	int type = 0;
208
	int type = 0;
66
 
209
 
67
	SDiffFile *diffFile = new SDiffFile;
210
	SDiffFile *diffFile = new SDiffFile;
68
	diffFile->sFile = fileType;
211
	diffFile->sFile = fileType;
Line 79... Line 222...
79
			int id = -1;
222
			int id = -1;
80
			SStringList *node[2];
223
			SStringList *node[2];
81
			node[0] = baseLines->Head();
224
			node[0] = baseLines->Head();
82
			node[1] = lines->Head();
225
			node[1] = lines->Head();
83
 
226
 
84
			CyString prev[2];
227
			Utils::String prev[2];
85
 
228
 
86
			while ( node[0] || node[1] )
229
			while ( node[0] || node[1] )
87
			{
230
			{
88
				CyString str[2];
231
				Utils::String str[2];
89
 
232
 
90
				for ( int i = 0; i < 2; i++ )
233
				for ( int i = 0; i < 2; i++ )
91
				{
234
				{
92
					while (node[i])
235
					while (node[i])
93
					{
236
					{
94
						CyString l = node[i]->str;
237
						Utils::String l = node[i]->str.ToString();
95
						node[i] = node[i]->next;
238
						node[i] = node[i]->next;
96
 
239
 
97
						l.RemoveFirstSpace();
240
						l.removeFirstSpace();
98
						l.RemoveChar('\r');
241
						l.removeChar('\r');
99
						if ( !l.Empty() && l.Left(1) != "/") 
242
						if ( !l.empty() && l.left(1) != "/") {
100
						{
-
 
101
							str[i] += l;
243
							str[i] += l;
102
							if ( IsLineComplete(str[i], fileType, (id == -1) ? true : false) ) 
244
							if ( _isLineComplete(str[i], fileType, (id == -1) ? true : false) ) 
103
								break;
245
								break;
104
						}
246
						}
105
					}
247
					}
106
				}
248
				}
107
 
249
 
108
				if ( id == -1 )
250
				if ( id == -1 )
109
					id = 0;
251
					id = 0;
110
				else
252
				else
111
				{
253
				{
112
					// first check for mismatch amount, one of the nodes will be empty
254
					// first check for mismatch amount, one of the nodes will be empty
113
					if ( str[0].Empty() && !str[1].Empty() ) // mod file has more entries (these must be additions)
255
					if ( str[0].empty() && !str[1].empty() ) // mod file has more entries (these must be additions)
114
					{
256
					{
115
						SDiffEntryAddition *entry = new SDiffEntryAddition;
257
						SDiffEntryAddition *entry = new SDiffEntryAddition;
116
						entry->iID = id;
258
						entry->iID = id;
117
						entry->sEntry = str[1];
259
						entry->sEntry = str[1];
118
						diffFile->m_lEntries.push_back(entry);
260
						diffFile->m_lEntries.push_back(entry);
119
					}
261
					}
120
					else if ( str[1].Empty() && !str[0].Empty() ) // mod file has less entries (must have removed some)
262
					else if ( str[1].empty() && !str[0].empty() ) // mod file has less entries (must have removed some)
121
					{
263
					{
122
						SDiffEntry *entry = new SDiffEntryRemoval;
264
						SDiffEntry *entry = new SDiffEntryRemoval;
123
						entry->iID = id;
265
						entry->iID = id;
124
						diffFile->m_lEntries.push_back(entry);
266
						diffFile->m_lEntries.push_back(entry);
125
					}
267
					}
126
					else // we have a line for both, we need to compare them
268
					else // we have a line for both, we need to compare them
127
					{
269
					{
128
						// we migth have multiple entries to add when changed
270
						// we migth have multiple entries to add when changed
129
						if ( str[0].Empty() || str[1].Empty() ) continue;
271
						if ( str[0].empty() || str[1].empty() ) continue;
130
						CompareLine(str[0], str[1], type, id, diffFile);						
272
						_compareLine(str[0], str[1], type, id, diffFile);						
131
					}
273
					}
132
 
274
 
133
					++id;
275
					++id;
134
				}
276
				}
135
			}
277
			}
Line 137... Line 279...
137
			delete lines;
279
			delete lines;
138
		}
280
		}
139
		delete baseLines;
281
		delete baseLines;
140
	}
282
	}
141
 
283
 
142
	if ( diffFile->m_lEntries.empty() )
284
	if ( diffFile->m_lEntries.empty() ) {
143
		delete diffFile;
285
		delete diffFile;
-
 
286
		return NULL;
-
 
287
	}
144
	else
288
	else {
145
		m_lFiles.push_back(diffFile);
289
		m_lFiles.push_back(diffFile);
146
 
-
 
147
	return true;
290
		return diffFile;
-
 
291
	}
148
}
292
}
149
 
293
 
150
int CModDiff::GetAmountPosition(const CyString &fileType)
294
int CModDiff::_amountPosition(const Utils::String &fileType)
151
{
295
{
152
	return 2;
296
	return 2;
153
}
297
}
154
 
298
 
155
bool CModDiff::IsLineComplete(CyString &line, CyString &fileType, bool first)
299
bool CModDiff::_isLineComplete(const Utils::String &line, const Utils::String &fileType, bool first)
156
{
300
{
157
	if ( first )
301
	if ( first )
158
	{
302
	{
159
		if ( line.NumToken(";") > GetAmountPosition(fileType) ) return true;
303
		if ( line.countToken(";") > _amountPosition(fileType) ) return true;
160
		return false;
304
		return false;
161
	}
305
	}
162
 
306
 
163
	return true;
307
	return true;
164
}
308
}
165
 
309
 
166
void CModDiff::CompareLine(CyString &line1, CyString &line2, int type, int id, SDiffFile *diffFile)
310
void CModDiff::_compareLine(const Utils::String &line1, const Utils::String &line2, int type, int id, SDiffFile *diffFile)
167
{
311
{
168
	int max1, max2;
312
	int max1, max2;
169
	CyString *str1 = line1.SplitToken(";", &max1);
313
	Utils::String *str1 = line1.tokenise(";", &max1);
170
	CyString *str2 = line2.SplitToken(";", &max2);
314
	Utils::String *str2 = line2.tokenise(";", &max2);
171
 
315
 
172
	if ( !str1 || !str2 ) return;
316
	if ( !str1 || !str2 ) return;
173
 
317
 
174
	int max = ((max1 > max2) ? max2 : max1);
318
	int max = ((max1 > max2) ? max2 : max1);
175
	for ( int i = 0; i < max; i++ )
319
	for ( int i = 0; i < max; i++ )
176
	{
320
	{
177
		if ( str1[i] == str2[i] ) continue;
321
		if ( str1[i] == str2[i] ) continue;
178
		if ( str1[i].Compare(str2[i]) ) continue;
322
		if ( str1[i].Compare(str2[i]) ) continue;
179
		if ( str1[i].Empty() && str2[i].Empty() ) continue;
323
		if ( str1[i].empty() && str2[i].empty() ) continue;
180
		if ( str1[i].Length() && str1[i][0] == '\0' && str2[i].Length() && str2[i][0] == '\0' ) continue;
324
		if ( str1[i].length() && str1[i][0] == '\0' && str2[i].length() && str2[i][0] == '\0' ) continue;
181
		SDiffEntryChange *diff = new SDiffEntryChange;
325
		SDiffEntryChange *diff = new SDiffEntryChange;
182
		diff->iID = id;
326
		diff->iID = id;
183
		diff->iPos = i;
327
		diff->iPos = i;
184
		diff->sEntry = str2[i];
328
		diff->sEntry = str2[i];
185
		diff->sFrom = str1[i];
329
		diff->sFrom = str1[i];
186
		diffFile->m_lEntries.push_back(diff);
330
		diffFile->m_lEntries.push_back(diff);
187
	}
331
	}
188
}
332
}
189
 
333
 
190
void CModDiff::Clean()
334
void CModDiff::Clean()
191
{
335
{
192
	for ( CListNode<SDiffFile> *node = m_lFiles.Front(); node; node = node->next() )
336
	for ( CListNode<SDiffFile> *node = m_lFiles.Front(); node; node = node->next() )
193
	{
337
	{
194
		node->Data()->m_lEntries.clear();
338
		node->Data()->m_lEntries.clear();
195
		node->DeleteData();
339
		node->DeleteData();
196
	}
340
	}
197
	m_lFiles.clear();
341
	m_lFiles.clear();
198
}
342
}
199
 
343
 
200
bool CModDiff::WriteDiff(CyString &file)
344
bool CModDiff::WriteDiff(const Utils::String &file)
201
{
345
{
202
	if ( m_lFiles.empty() ) return false;
346
	if ( m_lFiles.empty() ) return false;
203
 
347
 
204
	CyStringList lines;
348
	CyStringList lines;
205
	
349
	
206
	for ( CListNode<SDiffFile> *node = m_lFiles.Front(); node; node = node->next() )
350
	for ( CListNode<SDiffFile> *node = m_lFiles.Front(); node; node = node->next() )
Line 226... Line 370...
226
 
370
 
227
	CFileIO File(file);
371
	CFileIO File(file);
228
	return File.WriteFile(&lines);
372
	return File.WriteFile(&lines);
229
}
373
}
230
 
374
 
231
bool CModDiff::ReadDiff(CyString &file)
375
bool CModDiff::ReadDiff(const Utils::String &file)
232
{
376
{
233
	Clean();
377
	Clean();
234
 
378
 
235
	CFileIO File(file);
379
	CFileIO File(file);
236
	if ( !File.exists() ) return false;
380
	if ( !File.exists() ) return false;
Line 244... Line 388...
244
		{
388
		{
245
			if ( str->str.Left(2).Compare("$$") )
389
			if ( str->str.Left(2).Compare("$$") )
246
			{
390
			{
247
				diffFile = new SDiffFile;
391
				diffFile = new SDiffFile;
248
				m_lFiles.push_back(diffFile);
392
				m_lFiles.push_back(diffFile);
249
				diffFile->sFile = str->str.Right(-2);
393
				diffFile->sFile = str->str.Right(-2).ToString();
250
			}
394
			}
251
			else if ( diffFile )
395
			else if ( diffFile )
252
			{
396
			{
253
				if ( str->str.Left(4).Compare("+++:") )
397
				if ( str->str.Left(4).Compare("+++:") )
254
				{
398
				{
255
					SDiffEntryAddition *addition = new SDiffEntryAddition;
399
					SDiffEntryAddition *addition = new SDiffEntryAddition;
256
					addition->iID = str->str.GetToken(":", 2, 2).ToInt();
400
					addition->iID = str->str.GetToken(":", 2, 2).ToInt();
257
					addition->sEntry = str->str.GetToken(":", 3);
401
					addition->sEntry = str->str.GetToken(":", 3).ToString();
258
					diffFile->m_lEntries.push_back(addition);
402
					diffFile->m_lEntries.push_back(addition);
259
				}
403
				}
260
				else if ( str->str.Left(4).Compare("---:") )
404
				else if ( str->str.Left(4).Compare("---:") )
261
				{
405
				{
262
					SDiffEntryRemoval *entry = new SDiffEntryRemoval;
406
					SDiffEntryRemoval *entry = new SDiffEntryRemoval;
Line 266... Line 410...
266
				else if ( str->str.Left(4).Compare("///:") )
410
				else if ( str->str.Left(4).Compare("///:") )
267
				{
411
				{
268
					SDiffEntryChange *entry = new SDiffEntryChange;
412
					SDiffEntryChange *entry = new SDiffEntryChange;
269
					entry->iID = str->str.GetToken(":", 2, 2).ToInt();
413
					entry->iID = str->str.GetToken(":", 2, 2).ToInt();
270
					entry->iPos = str->str.GetToken(":", 3, 3).ToInt();
414
					entry->iPos = str->str.GetToken(":", 3, 3).ToInt();
271
					entry->sEntry = str->str.GetToken(":", 4);
415
					entry->sEntry = str->str.GetToken(":", 4).ToString();
272
					diffFile->m_lEntries.push_back(entry);
416
					diffFile->m_lEntries.push_back(entry);
273
				}
417
				}
274
			}
418
			}
275
		}
419
		}
276
 
420
 
277
		delete lines;
421
		delete lines;
278
 
422
 
279
		return true;
423
		return true;
280
	}
424
	}
281
 
425
 
282
	return false;
426
	return false;
283
}
427
}
284
 
428
 
285
bool CModDiff::ApplyMod(CyString &mod)
429
bool CModDiff::ApplyMod(const Utils::String &mod)
286
{
430
{
287
	return m_fileSystem.addMod(mod.ToString());
431
	return m_fileSystem.addMod(mod);
288
}
432
}
289
 
433
 
290
bool CModDiff::ApplyDiff(CyString &mod)
434
bool CModDiff::ApplyDiff(const Utils::String &mod)
291
{
435
{
292
	if ( m_lFiles.empty() ) return false;
436
	if ( m_lFiles.empty() ) return false;
-
 
437
 
-
 
438
	this->ApplyMod(mod);
293
 
439
 
294
	bool ret = false;
440
	bool ret = false;
295
 
441
 
296
	CyString addonDir = "";
442
	CyString addonDir = "";
297
 
443
 
298
	CCatFile cat;
444
	CCatFile cat;
299
	if ( !CCatFile::Opened(cat.Open(mod, addonDir, CATREAD_DAT, true)) )
445
	if ( !CCatFile::Opened(cat.Open(mod, addonDir, CATREAD_CATDECRYPT, true)) )
300
		return false;
446
		return false;
301
 
447
 
302
	for ( CListNode<SDiffFile> *node = m_lFiles.Front(); node; node = node->next() )
448
	for ( CListNode<SDiffFile> *node = m_lFiles.Front(); node; node = node->next() )
303
	{
449
	{
304
		// extract the file from the game
450
		// extract the file from the game
305
		SDiffFile *f = node->Data();
451
		SDiffFile *f = node->Data();
306
 
452
 
307
		CyStringList writeLines;
453
		CyStringList writeLines;
308
		int id;
454
		int id;
309
		if ( ReadGameFile(f->sFile, &writeLines, &id) )
455
		if ( _readGameFile(f->sFile, &writeLines, &id) )
310
		{
456
		{
311
			// now apply the diff
457
			// now apply the diff
-
 
458
			this->_adjustFile(f->sFile, f, true);
312
			for ( CListNode<SDiffEntry> *eNode = f->m_lEntries.Front(); eNode; eNode = eNode->next() )
459
			for ( CListNode<SDiffEntry> *eNode = f->m_lEntries.Front(); eNode; eNode = eNode->next() )
313
			{
460
			{
314
				switch ( eNode->Data()->iType )
461
				switch ( eNode->Data()->iType )
315
				{
462
				{
316
					case DIFFTYPE_ADDITION:
463
					case DIFFTYPE_ADDITION:
317
						writeLines.PushBack(((SDiffEntryAddition *)eNode->Data())->sEntry);
464
						writeLines.PushBack(CyString(((SDiffEntryAddition *)eNode->Data())->sEntry));
318
						break;
465
						break;
319
					case DIFFTYPE_REMOVAL:
466
					case DIFFTYPE_REMOVAL:
320
						writeLines.GetAt(eNode->Data()->iID)->remove = true;
467
						writeLines.GetAt(eNode->Data()->iID)->remove = true;
321
						break;
468
						break;
322
					case DIFFTYPE_CHANGE:
469
					case DIFFTYPE_CHANGE:
Line 332... Line 479...
332
			// add our comments and info
479
			// add our comments and info
333
			writeLines.PushFront(CyString((long)id) + ";" + (long)writeLines.Count() + ";");
480
			writeLines.PushFront(CyString((long)id) + ";" + (long)writeLines.Count() + ";");
334
			writeLines.PushFront(CyString("// Generated by ModDiff (SPK Version: ") + CyString::CreateFromFloat(GetLibraryVersion(), 2) + ")");
481
			writeLines.PushFront(CyString("// Generated by ModDiff (SPK Version: ") + CyString::CreateFromFloat(GetLibraryVersion(), 2) + ")");
335
 
482
 
336
			// now write the file
483
			// now write the file
337
			CFileIO WriteFile(m_sTempDir + "/" + CFileIO(f->sFile).GetFilename());
484
			CFileIO WriteFile(m_sTempDir + "/" + CFileIO(f->sFile).filename());
338
			if ( WriteFile.WriteFile(&writeLines) )
485
			if ( WriteFile.WriteFile(&writeLines) )
339
			{
486
			{
340
				if ( cat.AppendFile((m_sTempDir + "/&quot; + CFileIO(f->sFile).GetFilename()).ToString(), f->sFile.ToString()) )
487
				if ( cat.AppendFile(m_sTempDir + "/&quot; + CFileIO(f->sFile).filename(), f->sFile) )
341
				{
488
				{
342
					ret = true;
489
					ret = true;
343
				}
490
				}
-
 
491
				WriteFile.remove();
344
			}
492
			}
345
		}
493
		}
346
	}
494
	}
347
 
495
 
348
	if ( ret )
496
	if ( ret )
349
		cat.WriteCatFile();
497
		cat.WriteCatFile();
350
 
498
 
351
	return ret;
499
	return ret;
352
}
500
}
353
 
501
 
354
bool CModDiff::ReadGameFile(CyString &file, CyStringList *writeLines, int *id)
502
bool CModDiff::_readGameFile(const Utils::String &file, CyStringList *writeLines, int *id)
355
{
503
{
356
	bool ret = false;
504
	bool ret = false;
357
 
505
 
358
	if ( m_fileSystem.ExtractGameFile(file.ToString(), (m_sTempDir + &quot;/" + CFileIO(file).GetFilename()).ToString()) )
506
	Utils::String sTo = m_fileSystem.ExtractGameFile(file, m_sTempDir + &quot;/" + CFileIO(file).filename());
359
	{
507
	if ( !sTo.empty() ) {
360
		CFileIO File(m_sTempDir + "/" + CFileIO(file).GetFilename());
508
		CFileIO File(sTo);
361
 
509
 
362
		CyStringList *lines = File.ReadLinesStr();
510
		CyStringList *lines = File.ReadLinesStr();
363
		if ( lines )
511
		if ( lines )
364
		{
512
		{
365
			int entries = -1;
513
			int entries = -1;
Line 380... Line 528...
380
					writeLines->PushBack(l);
528
					writeLines->PushBack(l);
381
			}
529
			}
382
			delete lines;
530
			delete lines;
383
			ret = true;
531
			ret = true;
384
		}
532
		}
-
 
533
		File.close();
385
		File.remove();
534
		File.remove();
386
	}
535
	}
387
 
536
 
388
	return ret;
537
	return ret;
389
}
538
}
390
 
539
 
391
 
540
 
392
bool CModDiff::ValidFile(CyString &file)
541
bool CModDiff::_validFile(const Utils::String &file)
393
{
542
{
394
	return CModDiff::CanBeDiffed(file);
543
	return CModDiff::CanBeDiffed(file);
395
}
544
}
396
 
545
 
397
bool CModDiff::CanBeDiffed(const CyString &file)
546
bool CModDiff::CanBeDiffed(const Utils::String &file)
398
{
547
{
399
	CyString checkFile = file;
548
	Utils::String checkFile = file;
400
	checkFile = CFileIO(file.ToString()).GetDir() + &quot;/" + CFileIO(file.ToString()).baseName();
549
	checkFile = CFileIO(file).GetDir().ToString() + &quot;/" + CFileIO(file).baseName();
401
 
550
 
402
	// all t files are the same format
551
	// all t files are the same format
403
	if ( checkFile.Left(7).Compare("types/T") )
552
	if ( checkFile.left(7).Compare("types/T") )
404
		return true;
553
		return true;
405
 
554
 
406
	return false;
555
	return false;
407
}
556
}