| 1 | cycrow | 1 |   | 
        
           |  |  | 2 | #include "ModDiff.h"
 | 
        
           |  |  | 3 | #include "File_IO.h"
 | 
        
           |  |  | 4 | #include "CatFile.h"
 | 
        
           |  |  | 5 |   | 
        
           |  |  | 6 | CModDiff::CModDiff(CyString &dir, int maxPatch)
 | 
        
           |  |  | 7 | {
 | 
        
           |  |  | 8 | 	m_bLoaded = LoadDirectory(dir);
 | 
        
           |  |  | 9 | 	m_sTempDir = ".";
 | 
        
           |  |  | 10 | 	m_iMaxPatch = maxPatch;
 | 
        
           |  |  | 11 | }
 | 
        
           |  |  | 12 |   | 
        
           |  |  | 13 | CModDiff::~CModDiff(void)
 | 
        
           |  |  | 14 | {
 | 
        
           |  |  | 15 | }
 | 
        
           |  |  | 16 |   | 
        
           |  |  | 17 | bool CModDiff::LoadDirectory(CyString &dir)
 | 
        
           |  |  | 18 | {
 | 
        
           |  |  | 19 | 	m_sCurrentDir = dir;
 | 
        
           |  |  | 20 | 	return m_fileSystem.LoadFilesystem(dir, NullString, m_iMaxPatch);
 | 
        
           |  |  | 21 | }
 | 
        
           |  |  | 22 |   | 
        
           |  |  | 23 | bool CModDiff::CreateDiff(CyString &modfile)
 | 
        
           |  |  | 24 | {
 | 
        
           |  |  | 25 | 	ClearError();
 | 
        
           |  |  | 26 |   | 
        
           |  |  | 27 | 	//check for valid parameters
 | 
        
           |  |  | 28 | 	if ( !CFileIO(modfile).Exists() ) { m_iError = MDERR_FILENOTFOUND; return false; }
 | 
        
           |  |  | 29 |   | 
        
           |  |  | 30 | 	CyString addonDir = "";
 | 
        
           |  |  | 31 | 	int addonSize = addonDir.Length() + 1;
 | 
        
           |  |  | 32 |   | 
        
           |  |  | 33 | 	// try and open the mod file
 | 
        
           |  |  | 34 | 	CCatFile cat;
 | 
        
           |  |  | 35 | 	if ( cat.Open(modfile, addonDir, CATREAD_DAT, false) != CATERR_NONE ) { m_iError = MDERR_CANTOPENMOD; return false; }
 | 
        
           |  |  | 36 |   | 
        
           |  |  | 37 | 	// we'll need to read in all the types/text files
 | 
        
           |  |  | 38 | 	for ( int i = 0; i < cat.GetNumFiles(); i++ )
 | 
        
           |  |  | 39 | 	{
 | 
        
           |  |  | 40 | 		SInCatFile *f = cat.GetFile(i);
 | 
        
           |  |  | 41 | 		CyString checkFile = f->sFile.FindReplace("\\", "/");
 | 
        
           |  |  | 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) )
 | 
        
           |  |  | 43 | 		{
 | 
        
           |  |  | 44 | 			// extract the file to the temp dir
 | 
        
           |  |  | 45 | 			CyString toFile = CFileIO(m_sTempDir + "/" + CFileIO(f->sFile).GetFilename()).GetFullFilename();
 | 
        
           |  |  | 46 | 			if ( cat.ExtractFile(f, toFile ) )
 | 
        
           |  |  | 47 | 			{
 | 
        
           |  |  | 48 | 				// now extract the matching file from the game dir
 | 
        
           |  |  | 49 | 				if ( m_fileSystem.ExtractGameFile(f->sFile, toFile + ".compare") )
 | 
        
           |  |  | 50 | 				{
 | 
        
           |  |  | 51 | 					DiffFile(toFile + ".compare", toFile, f->sFile);
 | 
        
           |  |  | 52 | 					CFileIO(toFile + ".compare").Remove();
 | 
        
           |  |  | 53 | 				}
 | 
        
           |  |  | 54 | 				// make sure we clear up afterwards
 | 
        
           |  |  | 55 | 				CFileIO(toFile).Remove();
 | 
        
           |  |  | 56 | 			}
 | 
        
           |  |  | 57 | 		}
 | 
        
           |  |  | 58 | 	}
 | 
        
           |  |  | 59 |   | 
        
           |  |  | 60 | 	return true;
 | 
        
           |  |  | 61 | }
 | 
        
           |  |  | 62 |   | 
        
           |  |  | 63 | bool CModDiff::DiffFile(CyString &baseFile, CyString &modFile, CyString &fileType)
 | 
        
           |  |  | 64 | {
 | 
        
           |  |  | 65 | 	int type = 0;
 | 
        
           |  |  | 66 |   | 
        
           |  |  | 67 | 	SDiffFile *diffFile = new SDiffFile;
 | 
        
           |  |  | 68 | 	diffFile->sFile = fileType;
 | 
        
           |  |  | 69 |   | 
        
           |  |  | 70 | 	// read both files and compare them
 | 
        
           |  |  | 71 | 	CFileIO Base(baseFile);
 | 
        
           |  |  | 72 | 	CyStringList *baseLines = Base.ReadLinesStr();
 | 
        
           |  |  | 73 | 	if ( baseLines )
 | 
        
           |  |  | 74 | 	{
 | 
        
           |  |  | 75 | 		CFileIO Mod(modFile);
 | 
        
           |  |  | 76 | 		CyStringList *lines = Mod.ReadLinesStr();
 | 
        
           |  |  | 77 | 		if ( lines )
 | 
        
           |  |  | 78 | 		{
 | 
        
           |  |  | 79 | 			int id = -1;
 | 
        
           |  |  | 80 | 			SStringList *node[2];
 | 
        
           |  |  | 81 | 			node[0] = baseLines->Head();
 | 
        
           |  |  | 82 | 			node[1] = lines->Head();
 | 
        
           |  |  | 83 |   | 
        
           |  |  | 84 | 			CyString prev[2];
 | 
        
           |  |  | 85 |   | 
        
           |  |  | 86 | 			while ( node[0] || node[1] )
 | 
        
           |  |  | 87 | 			{
 | 
        
           |  |  | 88 | 				CyString str[2];
 | 
        
           |  |  | 89 |   | 
        
           |  |  | 90 | 				for ( int i = 0; i < 2; i++ )
 | 
        
           |  |  | 91 | 				{
 | 
        
           |  |  | 92 | 					while (node[i])
 | 
        
           |  |  | 93 | 					{
 | 
        
           |  |  | 94 | 						CyString l = node[i]->str;
 | 
        
           |  |  | 95 | 						node[i] = node[i]->next;
 | 
        
           |  |  | 96 |   | 
        
           |  |  | 97 | 						l.RemoveFirstSpace();
 | 
        
           |  |  | 98 | 						l.RemoveChar('\r');
 | 
        
           |  |  | 99 | 						if ( !l.Empty() && l.Left(1) != "/") 
 | 
        
           |  |  | 100 | 						{
 | 
        
           |  |  | 101 | 							str[i] += l;
 | 
        
           |  |  | 102 | 							if ( IsLineComplete(str[i], fileType, (id == -1) ? true : false) ) 
 | 
        
           |  |  | 103 | 								break;
 | 
        
           |  |  | 104 | 						}
 | 
        
           |  |  | 105 | 					}
 | 
        
           |  |  | 106 | 				}
 | 
        
           |  |  | 107 |   | 
        
           |  |  | 108 | 				if ( id == -1 )
 | 
        
           |  |  | 109 | 					id = 0;
 | 
        
           |  |  | 110 | 				else
 | 
        
           |  |  | 111 | 				{
 | 
        
           |  |  | 112 | 					// 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)
 | 
        
           |  |  | 114 | 					{
 | 
        
           |  |  | 115 | 						SDiffEntryAddition *entry = new SDiffEntryAddition;
 | 
        
           |  |  | 116 | 						entry->iID = id;
 | 
        
           |  |  | 117 | 						entry->sEntry = str[1];
 | 
        
           |  |  | 118 | 						diffFile->m_lEntries.push_back(entry);
 | 
        
           |  |  | 119 | 					}
 | 
        
           |  |  | 120 | 					else if ( str[1].Empty() && !str[0].Empty() ) // mod file has less entries (must have removed some)
 | 
        
           |  |  | 121 | 					{
 | 
        
           |  |  | 122 | 						SDiffEntry *entry = new SDiffEntryRemoval;
 | 
        
           |  |  | 123 | 						entry->iID = id;
 | 
        
           |  |  | 124 | 						diffFile->m_lEntries.push_back(entry);
 | 
        
           |  |  | 125 | 					}
 | 
        
           |  |  | 126 | 					else // we have a line for both, we need to compare them
 | 
        
           |  |  | 127 | 					{
 | 
        
           |  |  | 128 | 						// we migth have multiple entries to add when changed
 | 
        
           |  |  | 129 | 						if ( str[0].Empty() || str[1].Empty() ) continue;
 | 
        
           |  |  | 130 | 						CompareLine(str[0], str[1], type, id, diffFile);						
 | 
        
           |  |  | 131 | 					}
 | 
        
           |  |  | 132 |   | 
        
           |  |  | 133 | 					++id;
 | 
        
           |  |  | 134 | 				}
 | 
        
           |  |  | 135 | 			}
 | 
        
           |  |  | 136 |   | 
        
           |  |  | 137 | 			delete lines;
 | 
        
           |  |  | 138 | 		}
 | 
        
           |  |  | 139 | 		delete baseLines;
 | 
        
           |  |  | 140 | 	}
 | 
        
           |  |  | 141 |   | 
        
           |  |  | 142 | 	if ( diffFile->m_lEntries.empty() )
 | 
        
           |  |  | 143 | 		delete diffFile;
 | 
        
           |  |  | 144 | 	else
 | 
        
           |  |  | 145 | 		m_lFiles.push_back(diffFile);
 | 
        
           |  |  | 146 |   | 
        
           |  |  | 147 | 	return true;
 | 
        
           |  |  | 148 | }
 | 
        
           |  |  | 149 |   | 
        
           |  |  | 150 | int CModDiff::GetAmountPosition(const CyString &fileType)
 | 
        
           |  |  | 151 | {
 | 
        
           |  |  | 152 | 	return 2;
 | 
        
           |  |  | 153 | }
 | 
        
           |  |  | 154 |   | 
        
           |  |  | 155 | bool CModDiff::IsLineComplete(CyString &line, CyString &fileType, bool first)
 | 
        
           |  |  | 156 | {
 | 
        
           |  |  | 157 | 	if ( first )
 | 
        
           |  |  | 158 | 	{
 | 
        
           |  |  | 159 | 		if ( line.NumToken(";") > GetAmountPosition(fileType) ) return true;
 | 
        
           |  |  | 160 | 		return false;
 | 
        
           |  |  | 161 | 	}
 | 
        
           |  |  | 162 |   | 
        
           |  |  | 163 | 	return true;
 | 
        
           |  |  | 164 | }
 | 
        
           |  |  | 165 |   | 
        
           |  |  | 166 | void CModDiff::CompareLine(CyString &line1, CyString &line2, int type, int id, SDiffFile *diffFile)
 | 
        
           |  |  | 167 | {
 | 
        
           |  |  | 168 | 	int max1, max2;
 | 
        
           |  |  | 169 | 	CyString *str1 = line1.SplitToken(";", &max1);
 | 
        
           |  |  | 170 | 	CyString *str2 = line2.SplitToken(";", &max2);
 | 
        
           |  |  | 171 |   | 
        
           |  |  | 172 | 	if ( !str1 || !str2 ) return;
 | 
        
           |  |  | 173 |   | 
        
           |  |  | 174 | 	int max = ((max1 > max2) ? max2 : max1);
 | 
        
           |  |  | 175 | 	for ( int i = 0; i < max; i++ )
 | 
        
           |  |  | 176 | 	{
 | 
        
           |  |  | 177 | 		if ( str1[i] == str2[i] ) continue;
 | 
        
           |  |  | 178 | 		if ( str1[i].Compare(str2[i]) ) continue;
 | 
        
           |  |  | 179 | 		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;
 | 
        
           |  |  | 181 | 		SDiffEntryChange *diff = new SDiffEntryChange;
 | 
        
           |  |  | 182 | 		diff->iID = id;
 | 
        
           |  |  | 183 | 		diff->iPos = i;
 | 
        
           |  |  | 184 | 		diff->sEntry = str2[i];
 | 
        
           |  |  | 185 | 		diff->sFrom = str1[i];
 | 
        
           |  |  | 186 | 		diffFile->m_lEntries.push_back(diff);
 | 
        
           |  |  | 187 | 	}
 | 
        
           |  |  | 188 | }
 | 
        
           |  |  | 189 |   | 
        
           |  |  | 190 | void CModDiff::Clean()
 | 
        
           |  |  | 191 | {
 | 
        
           |  |  | 192 | 	for ( CListNode<SDiffFile> *node = m_lFiles.Front(); node; node = node->next() )
 | 
        
           |  |  | 193 | 	{
 | 
        
           |  |  | 194 | 		node->Data()->m_lEntries.clear();
 | 
        
           |  |  | 195 | 		node->DeleteData();
 | 
        
           |  |  | 196 | 	}
 | 
        
           |  |  | 197 | 	m_lFiles.clear();
 | 
        
           |  |  | 198 | }
 | 
        
           |  |  | 199 |   | 
        
           |  |  | 200 | bool CModDiff::WriteDiff(CyString &file)
 | 
        
           |  |  | 201 | {
 | 
        
           |  |  | 202 | 	if ( m_lFiles.empty() ) return false;
 | 
        
           |  |  | 203 |   | 
        
           |  |  | 204 | 	CyStringList lines;
 | 
        
           |  |  | 205 |   | 
        
           |  |  | 206 | 	for ( CListNode<SDiffFile> *node = m_lFiles.Front(); node; node = node->next() )
 | 
        
           |  |  | 207 | 	{
 | 
        
           |  |  | 208 | 		lines.PushBack(CyString("$$") + node->Data()->sFile);
 | 
        
           |  |  | 209 | 		for ( CListNode<SDiffEntry> *node2 = node->Data()->m_lEntries.Front(); node2; node2 = node2->next() )
 | 
        
           |  |  | 210 | 		{
 | 
        
           |  |  | 211 | 			switch(node2->Data()->iType)
 | 
        
           |  |  | 212 | 			{
 | 
        
           |  |  | 213 | 				case DIFFTYPE_ADDITION:
 | 
        
           |  |  | 214 | 					lines.PushBack(CyString("+++:") + (long)node2->Data()->iID + ":" + ((SDiffEntryAddition *)node2->Data())->sEntry);
 | 
        
           |  |  | 215 | 					break;
 | 
        
           |  |  | 216 | 				case DIFFTYPE_REMOVAL:
 | 
        
           |  |  | 217 | 					lines.PushBack(CyString("---:") + (long)node2->Data()->iID);
 | 
        
           |  |  | 218 | 					break;
 | 
        
           |  |  | 219 | 				case DIFFTYPE_CHANGE:
 | 
        
           |  |  | 220 | 					lines.PushBack(CyString("///:") + (long)node2->Data()->iID + ":" + (long)((SDiffEntryChange *)node2->Data())->iPos + ":" + ((SDiffEntryChange *)node2->Data())->sEntry);
 | 
        
           |  |  | 221 | 					break;
 | 
        
           |  |  | 222 | 			}
 | 
        
           |  |  | 223 | 		}
 | 
        
           |  |  | 224 | 	}
 | 
        
           |  |  | 225 |   | 
        
           |  |  | 226 |   | 
        
           |  |  | 227 | 	CFileIO File(file);
 | 
        
           |  |  | 228 | 	return File.WriteFile(&lines);
 | 
        
           |  |  | 229 | }
 | 
        
           |  |  | 230 |   | 
        
           |  |  | 231 | bool CModDiff::ReadDiff(CyString &file)
 | 
        
           |  |  | 232 | {
 | 
        
           |  |  | 233 | 	Clean();
 | 
        
           |  |  | 234 |   | 
        
           |  |  | 235 | 	CFileIO File(file);
 | 
        
           |  |  | 236 | 	if ( !File.Exists() ) return false;
 | 
        
           |  |  | 237 |   | 
        
           |  |  | 238 | 	CyStringList *lines = File.ReadLinesStr();
 | 
        
           |  |  | 239 |   | 
        
           |  |  | 240 | 	if ( lines )
 | 
        
           |  |  | 241 | 	{
 | 
        
           |  |  | 242 | 		SDiffFile *diffFile = NULL;
 | 
        
           |  |  | 243 | 		for ( SStringList *str = lines->Head(); str; str = str->next )
 | 
        
           |  |  | 244 | 		{
 | 
        
           |  |  | 245 | 			if ( str->str.Left(2).Compare("$$") )
 | 
        
           |  |  | 246 | 			{
 | 
        
           |  |  | 247 | 				diffFile = new SDiffFile;
 | 
        
           |  |  | 248 | 				m_lFiles.push_back(diffFile);
 | 
        
           |  |  | 249 | 				diffFile->sFile = str->str.Right(-2);
 | 
        
           |  |  | 250 | 			}
 | 
        
           |  |  | 251 | 			else if ( diffFile )
 | 
        
           |  |  | 252 | 			{
 | 
        
           |  |  | 253 | 				if ( str->str.Left(4).Compare("+++:") )
 | 
        
           |  |  | 254 | 				{
 | 
        
           |  |  | 255 | 					SDiffEntryAddition *addition = new SDiffEntryAddition;
 | 
        
           |  |  | 256 | 					addition->iID = str->str.GetToken(":", 2, 2).ToInt();
 | 
        
           |  |  | 257 | 					addition->sEntry = str->str.GetToken(":", 3);
 | 
        
           |  |  | 258 | 					diffFile->m_lEntries.push_back(addition);
 | 
        
           |  |  | 259 | 				}
 | 
        
           |  |  | 260 | 				else if ( str->str.Left(4).Compare("---:") )
 | 
        
           |  |  | 261 | 				{
 | 
        
           |  |  | 262 | 					SDiffEntryRemoval *entry = new SDiffEntryRemoval;
 | 
        
           |  |  | 263 | 					entry->iID = str->str.GetToken(":", 2, 2).ToInt();
 | 
        
           |  |  | 264 | 					diffFile->m_lEntries.push_back(entry);
 | 
        
           |  |  | 265 | 				}
 | 
        
           |  |  | 266 | 				else if ( str->str.Left(4).Compare("///:") )
 | 
        
           |  |  | 267 | 				{
 | 
        
           |  |  | 268 | 					SDiffEntryChange *entry = new SDiffEntryChange;
 | 
        
           |  |  | 269 | 					entry->iID = str->str.GetToken(":", 2, 2).ToInt();
 | 
        
           |  |  | 270 | 					entry->iPos = str->str.GetToken(":", 3, 3).ToInt();
 | 
        
           |  |  | 271 | 					entry->sEntry = str->str.GetToken(":", 4);
 | 
        
           |  |  | 272 | 					diffFile->m_lEntries.push_back(entry);
 | 
        
           |  |  | 273 | 				}
 | 
        
           |  |  | 274 | 			}
 | 
        
           |  |  | 275 | 		}
 | 
        
           |  |  | 276 |   | 
        
           |  |  | 277 | 		delete lines;
 | 
        
           |  |  | 278 |   | 
        
           |  |  | 279 | 		return true;
 | 
        
           |  |  | 280 | 	}
 | 
        
           |  |  | 281 |   | 
        
           |  |  | 282 | 	return false;
 | 
        
           |  |  | 283 | }
 | 
        
           |  |  | 284 |   | 
        
           |  |  | 285 | bool CModDiff::ApplyMod(CyString &mod)
 | 
        
           |  |  | 286 | {
 | 
        
           |  |  | 287 | 	return m_fileSystem.LoadMod(mod);
 | 
        
           |  |  | 288 | }
 | 
        
           |  |  | 289 |   | 
        
           |  |  | 290 | bool CModDiff::ApplyDiff(CyString &mod)
 | 
        
           |  |  | 291 | {
 | 
        
           |  |  | 292 | 	if ( m_lFiles.empty() ) return false;
 | 
        
           |  |  | 293 |   | 
        
           |  |  | 294 | 	bool ret = false;
 | 
        
           |  |  | 295 |   | 
        
           |  |  | 296 | 	CyString addonDir = "";
 | 
        
           |  |  | 297 |   | 
        
           |  |  | 298 | 	CCatFile cat;
 | 
        
           |  |  | 299 | 	if ( !CCatFile::Opened(cat.Open(mod, addonDir, CATREAD_DAT, true)) )
 | 
        
           |  |  | 300 | 		return false;
 | 
        
           |  |  | 301 |   | 
        
           |  |  | 302 | 	for ( CListNode<SDiffFile> *node = m_lFiles.Front(); node; node = node->next() )
 | 
        
           |  |  | 303 | 	{
 | 
        
           |  |  | 304 | 		// extract the file from the game
 | 
        
           |  |  | 305 | 		SDiffFile *f = node->Data();
 | 
        
           |  |  | 306 |   | 
        
           |  |  | 307 | 		CyStringList writeLines;
 | 
        
           |  |  | 308 | 		int id;
 | 
        
           |  |  | 309 | 		if ( ReadGameFile(f->sFile, &writeLines, &id) )
 | 
        
           |  |  | 310 | 		{
 | 
        
           |  |  | 311 | 			// now apply the diff
 | 
        
           |  |  | 312 | 			for ( CListNode<SDiffEntry> *eNode = f->m_lEntries.Front(); eNode; eNode = eNode->next() )
 | 
        
           |  |  | 313 | 			{
 | 
        
           |  |  | 314 | 				switch ( eNode->Data()->iType )
 | 
        
           |  |  | 315 | 				{
 | 
        
           |  |  | 316 | 					case DIFFTYPE_ADDITION:
 | 
        
           |  |  | 317 | 						writeLines.PushBack(((SDiffEntryAddition *)eNode->Data())->sEntry);
 | 
        
           |  |  | 318 | 						break;
 | 
        
           |  |  | 319 | 					case DIFFTYPE_REMOVAL:
 | 
        
           |  |  | 320 | 						writeLines.GetAt(eNode->Data()->iID)->remove = true;
 | 
        
           |  |  | 321 | 						break;
 | 
        
           |  |  | 322 | 					case DIFFTYPE_CHANGE:
 | 
        
           |  |  | 323 | 						{
 | 
        
           |  |  | 324 | 							SStringList *strAt = writeLines.GetAt(eNode->Data()->iID);
 | 
        
           |  |  | 325 | 							if ( strAt )
 | 
        
           |  |  | 326 | 								strAt->str.RepToken(";", ((SDiffEntryChange *)eNode->Data())->iPos, ((SDiffEntryChange *)eNode->Data())->sEntry);
 | 
        
           |  |  | 327 | 						}
 | 
        
           |  |  | 328 | 						break;
 | 
        
           |  |  | 329 | 				}
 | 
        
           |  |  | 330 | 			}
 | 
        
           |  |  | 331 |   | 
        
           |  |  | 332 | 			// add our comments and info
 | 
        
           |  |  | 333 | 			writeLines.PushFront(CyString((long)id) + ";" + (long)writeLines.Count() + ";");
 | 
        
           |  |  | 334 | 			writeLines.PushFront(CyString("// Generated by ModDiff (SPK Version: ") + CyString::CreateFromFloat(GetLibraryVersion(), 2) + ")");
 | 
        
           |  |  | 335 |   | 
        
           |  |  | 336 | 			// now write the file
 | 
        
           |  |  | 337 | 			CFileIO WriteFile(m_sTempDir + "/" + CFileIO(f->sFile).GetFilename());
 | 
        
           |  |  | 338 | 			if ( WriteFile.WriteFile(&writeLines) )
 | 
        
           |  |  | 339 | 			{
 | 
        
           |  |  | 340 | 				if ( cat.AppendFile(m_sTempDir + "/" + CFileIO(f->sFile).GetFilename(), f->sFile) )
 | 
        
           |  |  | 341 | 				{
 | 
        
           |  |  | 342 | 					ret = true;
 | 
        
           |  |  | 343 | 				}
 | 
        
           |  |  | 344 | 			}
 | 
        
           |  |  | 345 | 		}
 | 
        
           |  |  | 346 | 	}
 | 
        
           |  |  | 347 |   | 
        
           |  |  | 348 | 	if ( ret )
 | 
        
           |  |  | 349 | 		cat.WriteCatFile();
 | 
        
           |  |  | 350 |   | 
        
           |  |  | 351 | 	return ret;
 | 
        
           |  |  | 352 | }
 | 
        
           |  |  | 353 |   | 
        
           |  |  | 354 | bool CModDiff::ReadGameFile(CyString &file, CyStringList *writeLines, int *id)
 | 
        
           |  |  | 355 | {
 | 
        
           |  |  | 356 | 	bool ret = false;
 | 
        
           |  |  | 357 |   | 
        
           |  |  | 358 | 	if ( m_fileSystem.ExtractGameFile(file, m_sTempDir + "/" + CFileIO(file).GetFilename()) )
 | 
        
           |  |  | 359 | 	{
 | 
        
           |  |  | 360 | 		CFileIO File(m_sTempDir + "/" + CFileIO(file).GetFilename());
 | 
        
           |  |  | 361 |   | 
        
           |  |  | 362 | 		CyStringList *lines = File.ReadLinesStr();
 | 
        
           |  |  | 363 | 		if ( lines )
 | 
        
           |  |  | 364 | 		{
 | 
        
           |  |  | 365 | 			int entries = -1;
 | 
        
           |  |  | 366 | 			for ( SStringList *str = lines->Head(); str; str = str->next )
 | 
        
           |  |  | 367 | 			{
 | 
        
           |  |  | 368 | 				CyString l = str->str;
 | 
        
           |  |  | 369 | 				l.RemoveFirstSpace();
 | 
        
           |  |  | 370 | 				if ( l.Empty() ) continue;
 | 
        
           |  |  | 371 | 				if ( l.Left(1) == "/" ) continue;
 | 
        
           |  |  | 372 |   | 
        
           |  |  | 373 | 				if ( entries == -1 )
 | 
        
           |  |  | 374 | 				{
 | 
        
           |  |  | 375 | 					entries = l.GetToken(":", 2, 2).ToInt();
 | 
        
           |  |  | 376 | 					if ( id )
 | 
        
           |  |  | 377 | 						(*id) = l.GetToken(":", 1, 1).ToInt();
 | 
        
           |  |  | 378 | 				}
 | 
        
           |  |  | 379 | 				else
 | 
        
           |  |  | 380 | 					writeLines->PushBack(l);
 | 
        
           |  |  | 381 | 			}
 | 
        
           |  |  | 382 | 			delete lines;
 | 
        
           |  |  | 383 | 			ret = true;
 | 
        
           |  |  | 384 | 		}
 | 
        
           |  |  | 385 | 		File.Remove();
 | 
        
           |  |  | 386 | 	}
 | 
        
           |  |  | 387 |   | 
        
           |  |  | 388 | 	return ret;
 | 
        
           |  |  | 389 | }
 | 
        
           |  |  | 390 |   | 
        
           |  |  | 391 |   | 
        
           |  |  | 392 | bool CModDiff::ValidFile(CyString &file)
 | 
        
           |  |  | 393 | {
 | 
        
           |  |  | 394 | 	return CModDiff::CanBeDiffed(file);
 | 
        
           |  |  | 395 | }
 | 
        
           |  |  | 396 |   | 
        
           |  |  | 397 | bool CModDiff::CanBeDiffed(const CyString &file)
 | 
        
           |  |  | 398 | {
 | 
        
           |  |  | 399 | 	CyString checkFile = file;
 | 
        
           |  |  | 400 | 	checkFile = CFileIO(file).GetDir() + "/" + CFileIO(file).GetBaseName();
 | 
        
           |  |  | 401 |   | 
        
           |  |  | 402 | 	// all t files are the same format
 | 
        
           |  |  | 403 | 	if ( checkFile.Left(7).Compare("types/T") )
 | 
        
           |  |  | 404 | 		return true;
 | 
        
           |  |  | 405 |   | 
        
           |  |  | 406 | 	return false;
 | 
        
           |  |  | 407 | }
 |