Subversion Repositories spk

Rev

Rev 197 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
93 cycrow 1
 
2
#include "OriginalFiles.h"
3
#include "File.h"
4
#include "Logging/Log.h"
5
#include "BaseFile.h"
6
#include "spk.h"
7
//#include "ProgressInfo.h"
8
 
9
namespace SPK {
10
 
197 cycrow 11
	void addLogEntry(int type, const Utils::WString &args, Utils::WStringList* errors)
170 cycrow 12
	{
13
		if (errors) errors->pushBack(args, ERRORLOG(type));
14
	}
93 cycrow 15
 
16
 
197 cycrow 17
COriginalFiles::COriginalFiles(const Utils::WString &dir) : _sDir(dir)
93 cycrow 18
{
19
}
20
 
21
COriginalFiles::~COriginalFiles(void)
22
{
23
	reset();
24
}
25
 
26
int COriginalFiles::count() const
27
{
28
	return _lFiles.size();
29
}
30
 
31
/**
32
 * Check for original file
33
 *
34
 * Checks if the file is an original file or not
35
 */
36
bool COriginalFiles::isOriginal(C_File *f) const
37
{
38
	if ( _getFile(f) )
39
		return true;
40
	return false;
41
}
42
 
105 cycrow 43
void COriginalFiles::installed(CBaseFile *package)
44
{
45
	for ( CListNode<C_File> *oNode = _lFiles.Front(); oNode; oNode = oNode->next() )
46
	{
47
		C_File *of = oNode->Data();
170 cycrow 48
		for ( CListNode<C_File> *checkNode = package->fileList().Front(); checkNode; checkNode = checkNode->next() )
105 cycrow 49
		{
50
			C_File *f = checkNode->Data();
51
 
52
			// match the same filetype
53
			if ( of->GetFileType() != f->GetFileType() )
54
				continue;
55
 
56
			// same file
158 cycrow 57
			if ( of->filename().Compare(f->filename()) )
105 cycrow 58
				_storeOverride(f);
59
		}
60
	}
61
}
62
 
197 cycrow 63
void COriginalFiles::backup(CBaseFile *package, Utils::WStringList *errors)
93 cycrow 64
{
65
	// backup any original files before installing
202 cycrow 66
	CLog::log(CLog::Log_Install, 3, L"Checking for any original files to backup");
67
	CDirIO oDir(_sDir + L"/PluginManager/Original");
93 cycrow 68
	for ( CListNode<C_File> *oNode = _lFiles.Front(); oNode; oNode = oNode->next() )
69
	{
70
		C_File *of = oNode->Data();
170 cycrow 71
		for ( CListNode<C_File> *checkNode = package->fileList().Front(); checkNode; checkNode = checkNode->next() )
93 cycrow 72
		{
73
			C_File *f = checkNode->Data();
74
 
75
			// match the same filetype
76
			if ( of->GetFileType() != f->GetFileType() )
77
				continue;
78
 
79
			// same file
158 cycrow 80
			if ( of->filename().Compare(f->filename()) )
93 cycrow 81
			{
82
				// check if original file already exists (assume already backed up)
83
				if ( !backupFile(of, errors) )
84
					continue;
85
				break;
86
			}
87
		}
88
	}
89
}
90
 
197 cycrow 91
bool COriginalFiles::backupFile(C_File *f, Utils::WStringList *errors)
93 cycrow 92
{
197 cycrow 93
	Utils::WString newDir = L"PluginManager/Original/" + f->getDirectory(NULL);
93 cycrow 94
	CDirIO oDir(_sDir);
197 cycrow 95
	if ( oDir.exists(newDir + L"/" + f->filename()) )
93 cycrow 96
		return true;
97
 
98
	// make sure the directory exissts
121 cycrow 99
	if ( !oDir.exists(newDir) )
93 cycrow 100
	{
160 cycrow 101
		if ( !oDir.create(newDir) )
93 cycrow 102
		{
103
			CLog::logf(CLog::Log_Install, 2, "Unable to create directory to backup original files, %s", newDir.c_str());
197 cycrow 104
			addLogEntry(SPKINSTALL_CREATEDIRECTORY_FAIL, newDir, errors);
93 cycrow 105
			return false;
106
		}
107
 
108
		CLog::logf(CLog::Log_Install, 2, "Created new directory, %s", newDir.c_str());
197 cycrow 109
		addLogEntry(SPKINSTALL_CREATEDIRECTORY, newDir, errors);
93 cycrow 110
	}
111
 
112
	// now lets copy the file
130 cycrow 113
	CFileIO CopyFile(f->filePointer());
197 cycrow 114
	if(CopyFile.copy(oDir.file(newDir + L"/" + f->filename())))
93 cycrow 115
	{
178 cycrow 116
		CLog::logf(CLog::Log_Install, 2, "Original file: %s has been backed up", f->getNameDirectory(NULL).c_str());
183 cycrow 117
		addLogEntry(SPKINSTALL_ORIGINAL_BACKUP, f->getNameDirectory(NULL), errors);
93 cycrow 118
		return true;
119
	}
120
	else
121
	{
178 cycrow 122
		CLog::logf(CLog::Log_Install, 2, "Failed to backup the original file: %s", f->getNameDirectory(NULL).c_str());
183 cycrow 123
		addLogEntry(SPKINSTALL_ORIGINAL_BACKUP_FAIL, f->getNameDirectory(NULL), errors);
93 cycrow 124
		return false;
125
	}
126
}
127
 
197 cycrow 128
bool COriginalFiles::doBackup(C_File *f, Utils::WStringList *errors)
93 cycrow 129
{
130
	bool backed = false;
131
 
132
	C_File *of = this->_getFile(f);
133
	if ( of ) {
134
		// check if the orignal file is already backed up
197 cycrow 135
		if ( !CFileIO::Exists(_sDir + L"/PluginManager/Original/" + f->getNameDirectory(NULL)) )
93 cycrow 136
		{
137
			// lets back up the file now
138
			backed = this->backupFile(of, errors);
139
		}
140
	}
141
 
142
	return backed;
143
}
144
 
145
 
146
int COriginalFiles::restoreAll(CProgressInfo *info, int files, int max)
147
{
148
	for ( CListNode<C_File> *oNode = _lFiles.Front(); oNode; oNode = oNode->next() )
149
	{
150
		// update the progress
151
		if ( info ) info->UpdateProgress(files, max);
152
		++files;
153
 
154
		C_File *f = oNode->Data();
197 cycrow 155
		CFileIO of(_sDir + L"/PluginManager/Original/" + f->getNameDirectory(NULL));
93 cycrow 156
 
157
		if ( of.exists() )
197 cycrow 158
			of.Rename(_sDir + L"/" + f->getNameDirectory(NULL));
93 cycrow 159
 
160
		delete oNode->Data();
161
	}
162
 
163
	_lFiles.clear();
164
 
165
	return files;
166
}
167
 
197 cycrow 168
bool COriginalFiles::restoreFile(C_File *f, Utils::WStringList *errors)
93 cycrow 169
{
170
	bool original = false;
171
 
172
	// check if its an original file and restore
173
	if ( this->isOriginal(f) )
174
	{
197 cycrow 175
		CFileIO of(_sDir + L"/PluginManager/Original/" + f->getNameDirectory(NULL));
93 cycrow 176
		if ( of.exists() )
177
		{
178
			original = true;
197 cycrow 179
			if ( of.Rename(_sDir + L"/" + f->getNameDirectory(NULL)) )
183 cycrow 180
				addLogEntry(SPKINSTALL_ORIGINAL_RESTORE, f->getNameDirectory(NULL), errors);
93 cycrow 181
			else
183 cycrow 182
				addLogEntry(SPKINSTALL_ORIGINAL_RESTORE_FAIL, f->getNameDirectory(NULL), errors);
105 cycrow 183
 
197 cycrow 184
			CFileIO backupFile(_sDir + L"/PluginManager/Original/Replacements/" + f->getNameDirectory(NULL));
105 cycrow 185
			if ( backupFile.exists() ) backupFile.remove();
186
 
93 cycrow 187
		}
188
	}
189
 
190
	return original;
191
}
192
 
193
 
197 cycrow 194
void COriginalFiles::parse(const Utils::WString &data)
93 cycrow 195
{
196
	C_File *uf = new C_File();
197
 
197 cycrow 198
	uf->setFileType((FileType)data.token(L" ", 1).toLong());
93 cycrow 199
 
200
	// Extra files also contain a directory, so make sure we split that up
127 cycrow 201
	if (uf->fileType() == FILETYPE_EXTRA )
93 cycrow 202
	{
197 cycrow 203
		uf->setDir(data.tokens(L" ", 2).tokens(L":", 2));
204
		uf->setFilename(data.tokens(L" ", 2).token(L":", 1));
93 cycrow 205
	}
206
	else
197 cycrow 207
		uf->setFilename(data.tokens(L" ", 2));
93 cycrow 208
 
209
	// set the complete filename, GetNameDirectory returns the directory based on the file type
197 cycrow 210
	uf->setFilename(_sDir + L"/" + uf->getNameDirectory(NULL));
93 cycrow 211
 
212
	_lFiles.push_back(uf);
213
}
214
 
215
void COriginalFiles::update(bool bForce, const CLinkList<C_File> *pFiles)
216
{
217
	if ( _lFiles.empty() || bForce )
218
	{
197 cycrow 219
		_storeFiles(FILETYPE_SCRIPT, L"scripts", pFiles);
220
		_storeFiles(FILETYPE_TEXT, L"t", pFiles);
221
		_storeFiles(FILETYPE_SOUND, L"soundtrack", pFiles);
222
		_storeFiles(FILETYPE_EXTRA, L"mov", pFiles);
93 cycrow 223
	}
224
}
225
 
197 cycrow 226
bool COriginalFiles::writeData(Utils::WStringList &lines)
93 cycrow 227
{
228
	bool addAny = false;
229
 
230
	if ( !_lFiles.empty() )
231
	{
232
		for ( CListNode<C_File> *node = _lFiles.Front(); node; node = node->next() )
233
		{
234
			C_File *uf = node->Data();
197 cycrow 235
			Utils::WString uString = L"Original: ";
236
			uString += Utils::WString::Number((long)uf->GetFileType()) + L" ";
158 cycrow 237
			uString += uf->filename();
93 cycrow 238
 
239
			// add the directory for Extra files
178 cycrow 240
			if ( uf->GetFileType() == FILETYPE_EXTRA && !uf->dir().empty())
93 cycrow 241
			{
197 cycrow 242
				uString += L":";
160 cycrow 243
				uString += uf->dir();
93 cycrow 244
			}
245
 
160 cycrow 246
			lines.pushBack(uString);
93 cycrow 247
			addAny = true;
248
		}
249
	}
250
 
251
	return addAny;
252
}
253
 
254
 
255
void COriginalFiles::reset()
256
{
257
	_lFiles.MemoryClear();
258
}
259
 
260
 
261
/**
262
 * Update original files list
263
 *
264
 * Scan the current directory for any fiels that are already there, ie ones that have not been installed
265
 * Original files should be all the scripts/sounds, etc that are in an unmodified game directory
266
 *
267
 * Save list of files and check if any packages overright these files
268
 * Any file that gets overrighten from this list will automatically be backed up, and restored once the packages are removed
269
 */
197 cycrow 270
void COriginalFiles::_storeFiles(FileType filetype, const Utils::WString &searchPath, const CLinkList<C_File> *pFiles)
93 cycrow 271
{
197 cycrow 272
	Utils::WString ext = L"pck";
93 cycrow 273
	switch ( filetype )
274
	{
275
		case FILETYPE_SOUND:
197 cycrow 276
			ext = L"mp3";
93 cycrow 277
			break;
278
	}
279
 
197 cycrow 280
	CDirIO Dir(_sDir + L"/" + searchPath);
93 cycrow 281
 
197 cycrow 282
	Utils::WStringList files;
160 cycrow 283
	Dir.dirList(files);
284
	if (files.empty())
93 cycrow 285
		return;
286
 
160 cycrow 287
	for(auto itr = files.begin(); itr != files.end(); itr++)
93 cycrow 288
	{
160 cycrow 289
		CFileIO File(Dir.file((*itr)->str));
93 cycrow 290
 
291
		if ( File.extension().Compare(ext) )
197 cycrow 292
			_add(filetype, File.filename(), searchPath, pFiles);
93 cycrow 293
	}
294
}
295
 
296
/**
297
 * Get original file
298
 *
299
 * Finds a matching original file entry and returns it
300
 */
301
C_File *COriginalFiles::_getFile(C_File *file) const
302
{
303
	if ( !file ) return NULL;
304
 
305
	for ( CListNode<C_File> *node = _lFiles.Front(); node; node = node->next() )
306
	{
307
		C_File *of = node->Data();
308
 
309
		// not of the same file type
310
		if ( of->GetFileType() != file->GetFileType() )
311
			continue;
312
 
313
		// same file name, must be the same file
158 cycrow 314
		if ( of->filename().Compare(file->filename()) )
93 cycrow 315
			return of;
316
	}
317
 
318
	return NULL;
319
}
320
 
321
 
322
/**
323
 * Adds a file onto the original files list
324
 *
325
 * Checks if it already exists so we dont create multiples
326
 */
197 cycrow 327
void COriginalFiles::_add(FileType filetype, const Utils::WString &filename, const Utils::WString &searchPath, const CLinkList<C_File> *pFiles)
93 cycrow 328
{
329
	// dont add plugin manager as original files
197 cycrow 330
	if ( filetype == FILETYPE_SCRIPT && filename.contains(L"!init.pmanager") )
93 cycrow 331
		return;
332
 
333
	// first check if a matching one exists
334
	for ( CListNode<C_File> *node = _lFiles.Front(); node; node = node->next() )
335
	{
336
		C_File *file = node->Data();
337
		if ( file->GetFileType() != filetype )
338
			continue;
339
 
158 cycrow 340
		if ( file->filename().Compare(filename) )
93 cycrow 341
			return;
342
	}
343
 
344
	// check that no packages are currently using them either, not original if being used already
345
	for ( CListNode<C_File> *node = pFiles->Front(); node; node = node->next() )
346
	{
347
		C_File *file = node->Data();
348
		if ( file->GetFileType() != filetype )
349
			continue;
350
 
158 cycrow 351
		if ( file->filename().Compare(filename) )
93 cycrow 352
			return;
353
	}
354
 
355
	// add the file entry to the list
127 cycrow 356
	C_File *of = new C_File(filename);
357
	of->setFileType(filetype);
358
	if (filetype == FILETYPE_EXTRA)
160 cycrow 359
		of->setDir(searchPath);
197 cycrow 360
	of->setFilename(_sDir + L"/" + of->getNameDirectory(NULL));
93 cycrow 361
 
362
	_lFiles.push_back(of);
363
}
364
 
105 cycrow 365
void COriginalFiles::_storeOverride(C_File *f)
366
{
197 cycrow 367
	CDirIO oDir(_sDir + L"/PluginManager/Original/Replacements");
160 cycrow 368
	if ( !oDir.exists() ) oDir.create();
369
	CFileIO file(oDir.file(f->getNameDirectory(NULL)));
370
	if ( !file.GetDirIO().exists() ) file.GetDirIO().create();
371
	CFileIO fromFile(f->filePointer());
105 cycrow 372
	fromFile.copy(file.fullFilename(), true);
93 cycrow 373
}
105 cycrow 374
 
375
}