Subversion Repositories spk

Rev

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

Rev 182 Rev 183
Line 671... Line 671...
671
					long time = rest.toLong();
671
					long time = rest.toLong();
672
					if ( time == m_iLastUpdated )
672
					if ( time == m_iLastUpdated )
673
					{
673
					{
674
						this->PurgeWares();
674
						this->PurgeWares();
675
						this->PurgeShips();
675
						this->PurgeShips();
676
						this->RemoveUninstallScripts();
676
						this->removeUninstallScripts();
677
					}
677
					}
678
				}
678
				}
679
			}
679
			}
680
 
680
 
681
			delete lines;
681
			delete lines;
Line 1328... Line 1328...
1328
	this->ConvertOldPackage (installFile);
1328
	this->ConvertOldPackage (installFile);
1329
 
1329
 
1330
	return installFile;
1330
	return installFile;
1331
}
1331
}
1332
 
1332
 
1333
void CPackages::PurgeUninstallScripts(CBaseFile *package, CyStringList *errors)
1333
void CPackages::purgeUninstallScripts(CBaseFile *package, Utils::CStringList *errors)
1334
{
1334
{
1335
	for ( CListNode<C_File> *fNode = m_lUninstallFiles.Front(); fNode; fNode = fNode->next() )
1335
	for ( CListNode<C_File> *fNode = m_lUninstallFiles.Front(); fNode; fNode = fNode->next() )
1336
	{
1336
	{
1337
		C_File *uf = fNode->Data();
1337
		C_File *uf = fNode->Data();
1338
		// check against any script files
1338
		// check against any script files
Line 1344... Line 1344...
1344
			if ( checkFile->GetFileType() != FILETYPE_UNINSTALL && checkFile->GetFileType() != FILETYPE_SCRIPT )
1344
			if ( checkFile->GetFileType() != FILETYPE_UNINSTALL && checkFile->GetFileType() != FILETYPE_SCRIPT )
1345
				continue;
1345
				continue;
1346
 
1346
 
1347
			if ( uf->filename().Compare(checkFile->filename()) )
1347
			if ( uf->filename().Compare(checkFile->filename()) )
1348
			{
1348
			{
1349
				if ( RemoveUninstallFile(uf, errors) )
1349
				if (removeUninstallFile(uf, errors) )
1350
					fNode->DeleteData();
1350
					fNode->DeleteData();
1351
				break;
1351
				break;
1352
			}
1352
			}
1353
		}
1353
		}
1354
	}
1354
	}
Line 1356... Line 1356...
1356
	m_lUninstallFiles.RemoveEmpty();
1356
	m_lUninstallFiles.RemoveEmpty();
1357
 
1357
 
1358
	this->WriteData();
1358
	this->WriteData();
1359
}
1359
}
1360
 
1360
 
1361
int CPackages::InstallPreparedPackages(CyStringList *errors, CProgressInfo *progress, CLinkList<CBaseFile> *errored, CLinkList<CBaseFile> *installedList)
1361
int CPackages::installPreparedPackages(Utils::CStringList *errors, CProgressInfo *progress, CLinkList<CBaseFile> *errored, CLinkList<CBaseFile> *installedList)
1362
{
1362
{
1363
	if ( m_lInstallList.empty() ) return false;
1363
	if ( m_lInstallList.empty() ) return false;
1364
 
-
 
1365
	int installed = 0;
1364
	int installed = 0;
1366
	for ( CListNode<CBaseFile> *node = m_lInstallList.Front(); node; node = node->next() )
1365
	for ( CListNode<CBaseFile> *node = m_lInstallList.Front(); node; node = node->next() )
1367
	{
1366
	{
1368
		CBaseFile *p = node->Data();
1367
		CBaseFile *p = node->Data();
1369
		if ( this->InstallPackage(p, errors, progress, !p->IsEnabled()) )
1368
		if ( this->installPackage(p, errors, progress, !p->IsEnabled()) )
1370
		{
1369
		{
1371
			++installed;
1370
			++installed;
1372
			if ( installedList )
1371
			if ( installedList )
1373
				installedList->push_back(p);
1372
				installedList->push_back(p);
1374
		}
1373
		}
Line 1443... Line 1442...
1443
{ 
1442
{ 
1444
	return (_pCurrentDir) ? _pCurrentDir->dir : Utils::String::Null(); 
1443
	return (_pCurrentDir) ? _pCurrentDir->dir : Utils::String::Null(); 
1445
}
1444
}
1446
 
1445
 
1447
 
1446
 
1448
bool CPackages::InstallPackage ( CBaseFile *package, CyStringList *errors, CProgressInfo *progress, bool disabled )
1447
bool CPackages::installPackage(CBaseFile *package, Utils::CStringList *errors, CProgressInfo *progress, bool disabled)
1449
{
1448
{
1450
	CLog::logf(CLog::Log_Install, 1, "Starting to install new package, %s by %s (Version: %s)", package->name().c_str(), package->author().c_str(), package->version().c_str());
1449
	CLog::logf(CLog::Log_Install, 1, "Starting to install new package, %s by %s (Version: %s)", package->name().c_str(), package->author().c_str(), package->version().c_str());
1451
	
1450
	
1452
	Utils::CStringList lErrors;
-
 
1453
 
-
 
1454
	CBaseFile *oldPackage = findPackage(package);
1451
	CBaseFile *oldPackage = findPackage(package);
1455
	disabled = _checkForDisable(package, disabled, oldPackage);
1452
	disabled = _checkForDisable(package, disabled, oldPackage);
1456
 
1453
 
1457
	// update packages must have an old package installed already (should have been checked for already)
1454
	// update packages must have an old package installed already (should have been checked for already)
1458
	if ( package->GetType() == TYPE_SPK )
1455
	if ( package->GetType() == TYPE_SPK )
Line 1482... Line 1479...
1482
	// no need to backup if we're disabling them
1479
	// no need to backup if we're disabling them
1483
	if ( !disabled )
1480
	if ( !disabled )
1484
	{
1481
	{
1485
		// find any uninstall files and remove them
1482
		// find any uninstall files and remove them
1486
		CLog::log(CLog::Log_Install, 3, "Purging uninstall scripts");
1483
		CLog::log(CLog::Log_Install, 3, "Purging uninstall scripts");
1487
		this->PurgeUninstallScripts(package, errors);
1484
		this->purgeUninstallScripts(package, errors);
1488
 
1485
 
1489
		// backup any original files before installing
1486
		// backup any original files before installing
1490
		_pOriginalFiles->backup(package, errors);
1487
		_pOriginalFiles->backup(package, errors);
1491
	}
1488
	}
1492
 
1489
 
Line 1504... Line 1501...
1504
 
1501
 
1505
	CLog::log(CLog::Log_Install, 3, "Reading all files into memory");
1502
	CLog::log(CLog::Log_Install, 3, "Reading all files into memory");
1506
	package->ReadAllFilesToMemory();
1503
	package->ReadAllFilesToMemory();
1507
 
1504
 
1508
	CLog::log(CLog::Log_Install, 3, "Starting to install files");
1505
	CLog::log(CLog::Log_Install, 3, "Starting to install files");
1509
	if ( !package->installFiles (m_sCurrentDir, progress, &m_lFiles, &lErrors, !disabled, this) )
1506
	if ( !package->installFiles (m_sCurrentDir, progress, &m_lFiles, errors, !disabled, this) )
1510
	{
1507
	{
1511
		CLog::log(CLog::Log_Install, 2, "There was an error installing files!!");
1508
		CLog::log(CLog::Log_Install, 2, "There was an error installing files!!");
1512
 
1509
 
1513
		// TODO: clear up installed files
1510
		// TODO: clear up installed files
1514
		return false;
1511
		return false;
Line 1595... Line 1592...
1595
						}
1592
						}
1596
					}
1593
					}
1597
 
1594
 
1598
					// now remove the files
1595
					// now remove the files
1599
					C_File *m = package->findMatchingMod(f->Data());
1596
					C_File *m = package->findMatchingMod(f->Data());
1600
					RemoveFile(f->Data(), errors);
1597
					removeFile(f->Data(), errors);
1601
					m_lFiles.remove(f->Data());
1598
					m_lFiles.remove(f->Data());
1602
					f->ChangeData(NULL);
1599
					f->ChangeData(NULL);
1603
					if ( m )
1600
					if ( m )
1604
					{
1601
					{
1605
						int pos = package->GetFileList()->FindPos(m);
1602
						int pos = package->GetFileList()->FindPos(m);
1606
						RemoveFile(m, errors);
1603
						removeFile(m, errors);
1607
						m_lFiles.remove(m);
1604
						m_lFiles.remove(m);
1608
						if ( pos != -1 )
1605
						if ( pos != -1 )
1609
							package->GetFileList()->GetNode(pos)->ChangeData(NULL);
1606
							package->GetFileList()->GetNode(pos)->ChangeData(NULL);
1610
					}
1607
					}
1611
				}
1608
				}
Line 1760... Line 1757...
1760
					if ( package->findFile(f->filename(), FILETYPE_README) )
1757
					if ( package->findFile(f->filename(), FILETYPE_README) )
1761
						dontRemove = true;
1758
						dontRemove = true;
1762
				}
1759
				}
1763
 
1760
 
1764
				// remove from hard drive
1761
				// remove from hard drive
1765
				if ( !dontRemove && RemoveFile(f, errors) )
1762
				if ( !dontRemove && removeFile(f, errors) )
1766
				{
1763
				{
1767
					CLog::logf(CLog::Log_Install, 1, "Removed unused file: %s", f->filePointer().c_str());
1764
					CLog::logf(CLog::Log_Install, 1, "Removed unused file: %s", f->filePointer().c_str());
1768
					// if a fake patch, we need to shufle
1765
					// if a fake patch, we need to shufle
1769
					if ( f->IsFakePatch() )
1766
					if ( f->IsFakePatch() )
1770
						shuffle = true;
1767
						shuffle = true;
Line 1779... Line 1776...
1779
	}
1776
	}
1780
 
1777
 
1781
	if ( shuffle )
1778
	if ( shuffle )
1782
	{
1779
	{
1783
		CLog::log(CLog::Log_Install, 2, "Shuffling Fake patches");
1780
		CLog::log(CLog::Log_Install, 2, "Shuffling Fake patches");
1784
		ShuffleFakePatches(errors);
1781
		shuffleFakePatches(errors);
1785
		CLog::log(CLog::Log_Install, 2, "Shuffling Text Files");
1782
		CLog::log(CLog::Log_Install, 2, "Shuffling Text Files");
1786
		ShuffleTextFiles(errors);
1783
		shuffleTextFiles(errors);
1787
	}
1784
	}
1788
 
1785
 
1789
	// now we need to link any child/parent packages
1786
	// now we need to link any child/parent packages
1790
	if ( package->GetType() == TYPE_SPK )
1787
	if ( package->GetType() == TYPE_SPK )
1791
	{
1788
	{
Line 1811... Line 1808...
1811
 
1808
 
1812
	CLog::log(CLog::Log_Install, 1, "Installation Finished");
1809
	CLog::log(CLog::Log_Install, 1, "Installation Finished");
1813
	return true;
1810
	return true;
1814
}
1811
}
1815
 
1812
 
1816
bool CPackages::UninstallPreparedPackages(CyStringList *errors, CProgressInfo *progress, CLinkList<CBaseFile> *uninstalledPackages, CLinkList<CBaseFile> *disabledPackages)
1813
bool CPackages::uninstallPreparedPackages(Utils::CStringList *errors, CProgressInfo *progress, CLinkList<CBaseFile> *uninstalledPackages, CLinkList<CBaseFile> *disabledPackages)
1817
{
1814
{
1818
	Utils::CStringList lErrors;
-
 
1819
 
-
 
1820
	if ( m_lInstallList.empty() ) return false;
1815
	if ( m_lInstallList.empty() ) return false;
1821
 
1816
 
1822
	// update the used status, excluding all packages we are about to remove
1817
	// update the used status, excluding all packages we are about to remove
1823
	UpdateUsedFiles(&m_lInstallList);
1818
	UpdateUsedFiles(&m_lInstallList);
1824
 
1819
 
Line 1845... Line 1840...
1845
					if ( depP->IsEnabled() )
1840
					if ( depP->IsEnabled() )
1846
						this->PrepareDisablePackage(depP);
1841
						this->PrepareDisablePackage(depP);
1847
				}
1842
				}
1848
 
1843
 
1849
				if ( m_lDisableList.size() )
1844
				if ( m_lDisableList.size() )
1850
					this->DisablePreparedPackages(errors, progress, disabledPackages);
1845
					this->disablePreparedPackages(errors, progress, disabledPackages);
1851
			}
1846
			}
1852
		}
1847
		}
1853
	}
1848
	}
1854
 
1849
 
1855
	// interate through all the files in the package
1850
	// interate through all the files in the package
Line 1900... Line 1895...
1900
		{
1895
		{
1901
			if (!removeDirs.contains("Extras"))
1896
			if (!removeDirs.contains("Extras"))
1902
				removeDirs.pushBack("Extras");
1897
				removeDirs.pushBack("Extras");
1903
		}
1898
		}
1904
 
1899
 
1905
		if ( RemoveFile(f, errors) )
1900
		if (removeFile(f, errors))
1906
			original = _pOriginalFiles->restoreFile(f, errors);
1901
			original = _pOriginalFiles->restoreFile(f, errors);
1907
		else // problem removeing (try when the program closes)
1902
		else // problem removeing (try when the program closes)
1908
			m_lNonRemovedFiles.pushBack(f->filePointer());
1903
			m_lNonRemovedFiles.pushBack(f->filePointer());
1909
 
1904
 
1910
		// check for fake patchs
1905
		// check for fake patchs
Line 1944... Line 1939...
1944
		// make sure the scripts directory is created, even thou it should always be there anyways
1939
		// make sure the scripts directory is created, even thou it should always be there anyways
1945
		CDirIO scriptDir(m_sCurrentDir);
1940
		CDirIO scriptDir(m_sCurrentDir);
1946
		if ( !scriptDir.exists("scripts") )
1941
		if ( !scriptDir.exists("scripts") )
1947
		{
1942
		{
1948
			if ( scriptDir.create("Scripts") )
1943
			if ( scriptDir.create("Scripts") )
1949
				this->AddLogEntry(SPKINSTALL_CREATEDIRECTORY, "Scripts", errors);
1944
				this->addLogEntry(SPKINSTALL_CREATEDIRECTORY, "Scripts", errors);
1950
			else
1945
			else
1951
				this->AddLogEntry(SPKINSTALL_CREATEDIRECTORY_FAIL, "Scripts", errors);
1946
				this->addLogEntry(SPKINSTALL_CREATEDIRECTORY_FAIL, "Scripts", errors);
1952
		}
1947
		}
1953
 
1948
 
1954
		for ( C_File *uf = uninstallFiles.First(); uf; uf = uninstallFiles.Next() )
1949
		for ( C_File *uf = uninstallFiles.First(); uf; uf = uninstallFiles.Next() )
1955
		{
1950
		{
1956
			C_File *newFile = new C_File();
1951
			C_File *newFile = new C_File();
Line 1963... Line 1958...
1963
			CFileIO file(uf->filePointer());
1958
			CFileIO file(uf->filePointer());
1964
 
1959
 
1965
			if ( uf->getUsed() )
1960
			if ( uf->getUsed() )
1966
			{
1961
			{
1967
				if ( file.copy(newFilename) )
1962
				if ( file.copy(newFilename) )
1968
					this->AddLogEntry(SPKINSTALL_UNINSTALL_COPY, newFile->getNameDirectory(NULL), errors);
1963
					this->addLogEntry(SPKINSTALL_UNINSTALL_COPY, newFile->getNameDirectory(NULL), errors);
1969
				else
1964
				else
1970
				{
1965
				{
1971
					this->AddLogEntry(SPKINSTALL_UNINSTALL_COPY_FAIL, newFile->getNameDirectory(NULL), errors);
1966
					this->addLogEntry(SPKINSTALL_UNINSTALL_COPY_FAIL, newFile->getNameDirectory(NULL), errors);
1972
					delete newFile;
1967
					delete newFile;
1973
					newFile = NULL;
1968
					newFile = NULL;
1974
				}
1969
				}
1975
			}
1970
			}
1976
			// otherwise just move it
1971
			// otherwise just move it
1977
			else
1972
			else
1978
			{
1973
			{
1979
				if ( file.Rename(newFilename) )
1974
				if ( file.Rename(newFilename) )
1980
					this->AddLogEntry(SPKINSTALL_UNINSTALL_MOVE, newFile->getNameDirectory(NULL), errors);
1975
					this->addLogEntry(SPKINSTALL_UNINSTALL_MOVE, newFile->getNameDirectory(NULL), errors);
1981
				else
1976
				else
1982
				{
1977
				{
1983
					this->AddLogEntry(SPKINSTALL_UNINSTALL_MOVE_FAIL, newFile->getNameDirectory(NULL), errors);
1978
					this->addLogEntry(SPKINSTALL_UNINSTALL_MOVE_FAIL, newFile->getNameDirectory(NULL), errors);
1984
					delete newFile;
1979
					delete newFile;
1985
					newFile = NULL;
1980
					newFile = NULL;
1986
				}
1981
				}
1987
 
1982
 
1988
				m_lFiles.remove(uf, false);
1983
				m_lFiles.remove(uf, false);
Line 2024... Line 2019...
2024
	if ( original ) {
2019
	if ( original ) {
2025
		removeDirs.pushBack("PluginManager/Original/Replacements");
2020
		removeDirs.pushBack("PluginManager/Original/Replacements");
2026
		removeDirs.pushBack("PluginManager/Original");
2021
		removeDirs.pushBack("PluginManager/Original");
2027
	}
2022
	}
2028
	removeDirs.pushBack("PluginManager/Disabled");
2023
	removeDirs.pushBack("PluginManager/Disabled");
2029
	removeUnusedDirectories(removeDirs, &lErrors);
2024
	removeUnusedDirectories(removeDirs, errors);
2030
 
2025
 
2031
	// finally lets shuffle any fake patchs to fill in gaps
2026
	// finally lets shuffle any fake patchs to fill in gaps
2032
	if ( shuffle )
2027
	if ( shuffle )
2033
	{
2028
	{
2034
		ShuffleFakePatches(errors);
2029
		shuffleFakePatches(errors);
2035
		ShuffleTextFiles(errors);
2030
		shuffleTextFiles(errors);
2036
	}
2031
	}
2037
 
2032
 
2038
	this->WriteData();
2033
	this->WriteData();
2039
 
2034
 
2040
	return true;
2035
	return true;
Line 2460... Line 2455...
2460
/**
2455
/**
2461
 * Closing the current directory
2456
 * Closing the current directory
2462
 *
2457
 *
2463
 * When existing, program needs to close the directory
2458
 * When existing, program needs to close the directory
2464
 */
2459
 */
2465
bool CPackages::CloseDir ( CyStringList *errors, CProgressInfo *progress, bool removedir )
2460
bool CPackages::closeDir(Utils::CStringList *errors, CProgressInfo *progress, bool removedir)
2466
{
2461
{
2467
	if ( m_sCurrentDir.empty() )
2462
	if ( m_sCurrentDir.empty() )
2468
		return true;
2463
		return true;
2469
	if ( !m_bLoaded )
2464
	if ( !m_bLoaded )
2470
		return true;
2465
		return true;
2471
 
2466
 
2472
	Utils::CStringList lErrors;
-
 
2473
 
-
 
2474
	CLog::log(CLog::Log_Directory, 1, "closing directory: " + m_sCurrentDir);
2467
	CLog::log(CLog::Log_Directory, 1, "closing directory: " + m_sCurrentDir);
2475
 
2468
 
2476
	if ( m_bRenameText ) {
2469
	if ( m_bRenameText ) {
2477
		CLog::log(CLog::Log_Directory, 2, "Creating other language files for game");
2470
		CLog::log(CLog::Log_Directory, 2, "Creating other language files for game");
2478
		CreateLanguageTextFiles(&lErrors);
2471
		CreateLanguageTextFiles(errors);
2479
	}
2472
	}
2480
 
2473
 
2481
	CLog::log(CLog::Log_Directory, 2, "Backing up save game files");
2474
	CLog::log(CLog::Log_Directory, 2, "Backing up save game files");
2482
 
2475
 
2483
	if ( CFileIO::Exists(m_sCurrentDir + "/mods/PluginManager.dat") ) {
2476
	if ( CFileIO::Exists(m_sCurrentDir + "/mods/PluginManager.dat") ) {
Line 2543... Line 2536...
2543
	if ( removedir && m_bRemoveDir )
2536
	if ( removedir && m_bRemoveDir )
2544
	{
2537
	{
2545
		m_bRemoveDir = false;
2538
		m_bRemoveDir = false;
2546
		Utils::CStringList removeDirs;
2539
		Utils::CStringList removeDirs;
2547
		removeDirs.pushBack(".");
2540
		removeDirs.pushBack(".");
2548
		removeUnusedDirectories(removeDirs, &lErrors);
2541
		removeUnusedDirectories(removeDirs, errors);
2549
	}
2542
	}
2550
 
2543
 
2551
	this->setCurrentDir("");
2544
	this->setCurrentDir("");
2552
		 
2545
		 
2553
	//TEMP: switch to errors
-
 
2554
	if (errors)
-
 
2555
	{
-
 
2556
		for (auto itr = lErrors.begin(); itr != lErrors.end(); itr++)
-
 
2557
			errors->PushBack(CyString((*itr)->str), CyString((*itr)->data));
-
 
2558
	}
-
 
2559
 
-
 
2560
	m_bLoaded = false;
2546
	m_bLoaded = false;
2561
	return true;
2547
	return true;
2562
}
2548
}
2563
 
2549
 
2564
Utils::String CPackages::getModKey() const
2550
Utils::String CPackages::getModKey() const
Line 2948... Line 2934...
2948
/**
2934
/**
2949
 * Add Log
2935
 * Add Log
2950
 *
2936
 *
2951
 * Adds a log entry to displayed at end
2937
 * Adds a log entry to displayed at end
2952
 */
2938
 */
2953
void CPackages::AddLogEntry(int type, CyString args, CyStringList* errors)
-
 
2954
{
-
 
2955
	if (!errors)
-
 
2956
		return;
-
 
2957
 
2939
 
2958
	errors->PushBack(args, ERRORLOG_OLD(type));
-
 
2959
}
-
 
2960
void CPackages::addLogEntry(int type, const Utils::String &args, Utils::CStringList *errors)
2940
void CPackages::addLogEntry(int type, const Utils::String &args, Utils::CStringList *errors)
2961
{
2941
{
2962
	if (!errors)
2942
	if (!errors)
2963
		return;
2943
		return;
2964
 
2944
 
Line 2979... Line 2959...
2979
 * param: errors		- The string list for all the status for debugging, ie has an entry for whats happened to every file
2959
 * param: errors		- The string list for all the status for debugging, ie has an entry for whats happened to every file
2980
 * param: progress		- The progress class, updates a progress screen of the derived class
2960
 * param: progress		- The progress class, updates a progress screen of the derived class
2981
 *
2961
 *
2982
 * return: boolen - Returns true if the package enabling was successful
2962
 * return: boolen - Returns true if the package enabling was successful
2983
 */
2963
 */
2984
bool CPackages::EnablePackage ( CBaseFile *package, CyStringList *errors, CProgressInfo *progress )
2964
bool CPackages::enablePackage(CBaseFile *package, Utils::CStringList *errors, CProgressInfo *progress )
2985
{
2965
{
2986
	ClearError();
2966
	ClearError();
2987
 
2967
 
2988
	// if already enabled, just skip
2968
	// if already enabled, just skip
2989
	if ( package->IsEnabled() )
2969
	if ( package->IsEnabled() )
Line 3002... Line 2982...
3002
		m_iError = PKERR_MODIFIED;
2982
		m_iError = PKERR_MODIFIED;
3003
		return false;
2983
		return false;
3004
	}
2984
	}
3005
 
2985
 
3006
	if ( this->PrepareEnablePackage(package) )
2986
	if ( this->PrepareEnablePackage(package) )
3007
		return this->EnablePreparedPackages(errors, progress);
2987
		return this->enablePreparedPackages(errors, progress);
3008
 
2988
 
3009
	return false;
2989
	return false;
3010
}
2990
}
3011
bool CPackages::EnablePreparedPackages ( CyStringList *errors, CProgressInfo *progress, CLinkList<CBaseFile> *enabledPackages )
2991
bool CPackages::enablePreparedPackages(Utils::CStringList *errors, CProgressInfo *progress, CLinkList<CBaseFile> *enabledPackages )
3012
{
2992
{
3013
	ClearError();
2993
	ClearError();
3014
 
2994
 
3015
	// get all files, including children
2995
	// get all files, including children
3016
	CLinkList<C_File> fileList;
2996
	CLinkList<C_File> fileList;
Line 3053... Line 3033...
3053
		{
3033
		{
3054
			if ( !Dir.exists(f->getDirectory(package)) )
3034
			if ( !Dir.exists(f->getDirectory(package)) )
3055
			{
3035
			{
3056
				if ( !Dir.create(f->getDirectory(package)) )
3036
				if ( !Dir.create(f->getDirectory(package)) )
3057
				{
3037
				{
3058
					this->AddLogEntry(SPKINSTALL_CREATEDIRECTORY_FAIL, f->getDirectory(package), errors);
3038
					this->addLogEntry(SPKINSTALL_CREATEDIRECTORY_FAIL, f->getDirectory(package), errors);
3059
					continue;
3039
					continue;
3060
				}
3040
				}
3061
				this->AddLogEntry(SPKINSTALL_CREATEDIRECTORY, f->getDirectory(package), errors);
3041
				this->addLogEntry(SPKINSTALL_CREATEDIRECTORY, f->getDirectory(package), errors);
3062
			}
3042
			}
3063
		}
3043
		}
3064
 
3044
 
3065
		// check if theres an original file to backup
3045
		// check if theres an original file to backup
3066
		_pOriginalFiles->doBackup(f, errors);
3046
		_pOriginalFiles->doBackup(f, errors);
Line 3090... Line 3070...
3090
		if ( !currentFile.exists() )
3070
		if ( !currentFile.exists() )
3091
		{
3071
		{
3092
			// missing file ??
3072
			// missing file ??
3093
			if ( !newFile.exists() )
3073
			if ( !newFile.exists() )
3094
			{
3074
			{
3095
				this->AddLogEntry(SPKINSTALL_MISSINGFILE, newFilename, errors);
3075
				this->addLogEntry(SPKINSTALL_MISSINGFILE, newFilename, errors);
3096
				continue;
3076
				continue;
3097
			}
3077
			}
3098
		}
3078
		}
3099
		// remove existing file
3079
		// remove existing file
3100
		// file exists, so lets try to move it
3080
		// file exists, so lets try to move it
Line 3103... Line 3083...
3103
			if ( newFile.exists() )
3083
			if ( newFile.exists() )
3104
				newFile.remove();
3084
				newFile.remove();
3105
 
3085
 
3106
			if ( !currentFile.Rename(newFile.fullFilename()) )
3086
			if ( !currentFile.Rename(newFile.fullFilename()) )
3107
			{
3087
			{
3108
				this->AddLogEntry(SPKINSTALL_ENABLEFILE_FAIL, newFilename, errors);
3088
				this->addLogEntry(SPKINSTALL_ENABLEFILE_FAIL, newFilename, errors);
3109
				continue;
3089
				continue;
3110
			}
3090
			}
3111
		}
3091
		}
3112
 
3092
 
3113
		this->AddLogEntry(SPKINSTALL_ENABLEFILE, newFilename, errors);
3093
		this->addLogEntry(SPKINSTALL_ENABLEFILE, newFilename, errors);
3114
 
3094
 
3115
		// adjust the internal name to match the new filename
3095
		// adjust the internal name to match the new filename
3116
		f->setFilename(m_sCurrentDir + "/" + newFilename);
3096
		f->setFilename(m_sCurrentDir + "/" + newFilename);
3117
		// no longer disabled, we need to remove the flag
3097
		// no longer disabled, we need to remove the flag
3118
		f->SetDisabled(false);
3098
		f->SetDisabled(false);
Line 3139... Line 3119...
3139
	if ( pMod )
3119
	if ( pMod )
3140
		m_pEnabledMod = pMod;
3120
		m_pEnabledMod = pMod;
3141
 
3121
 
3142
	// disabled the mod
3122
	// disabled the mod
3143
	if ( oldMod && oldMod != m_pEnabledMod && !m_bForceModInstall )
3123
	if ( oldMod && oldMod != m_pEnabledMod && !m_bForceModInstall )
3144
		this->DisablePackage(oldMod, errors, progress);
3124
		this->disablePackage(oldMod, errors, progress);
3145
 
3125
 
3146
	// lets remove all the directories we might have left empty
3126
	// lets remove all the directories we might have left empty
3147
	CyStringList removeDirs;
3127
	Utils::CStringList removeDirs;
3148
	removeDirs.PushBack(CyString("PluginManager/Disabled"));
3128
	removeDirs.pushBack("PluginManager/Disabled");
3149
	RemoveUnusedDirectories(removeDirs, errors);
3129
	removeUnusedDirectories(removeDirs, errors);
3150
 
3130
 
3151
	m_lEnableList.clear();
3131
	m_lEnableList.clear();
3152
 
3132
 
3153
	this->WriteData();
3133
	this->WriteData();
3154
 
3134
 
3155
	return true;
3135
	return true;
3156
}
3136
}
3157
 
3137
 
3158
 
3138
 
3159
bool CPackages::DisablePreparedPackages ( CyStringList *errors, CProgressInfo *progress, CLinkList<CBaseFile> *disabledPackages )
3139
bool CPackages::disablePreparedPackages(Utils::CStringList *errors, CProgressInfo *progress, CLinkList<CBaseFile> *disabledPackages )
3160
{
3140
{
3161
	if ( progress )
3141
	if ( progress )
3162
		progress->UpdateStatus(PROGRESS_DISABLEFILE);
3142
		progress->UpdateStatus(PROGRESS_DISABLEFILE);
3163
 
3143
 
3164
	UpdateUsedFiles(&m_lDisableList, false);
3144
	UpdateUsedFiles(&m_lDisableList, false);
3165
 
3145
 
3166
	// checks if there are any original files to restore and if any fake patches were disabled to reshuffle
3146
	// checks if there are any original files to restore and if any fake patches were disabled to reshuffle
3167
	bool original = false, shuffle = false;
3147
	bool original = false, shuffle = false;
3168
 
3148
 
3169
	// holds our list of directories that we might need to remove, only empty ones from this list will actually be removed
3149
	// holds our list of directories that we might need to remove, only empty ones from this list will actually be removed
3170
	CyStringList removeDirs;
3150
	Utils::CStringList removeDirs;
3171
 
3151
 
3172
	// get all files, including children
3152
	// get all files, including children
3173
	CLinkList<C_File> fileList;
3153
	CLinkList<C_File> fileList;
3174
	int maxFiles = this->GetAllPackageFiles(&m_lDisableList, &fileList, true);
3154
	int maxFiles = this->GetAllPackageFiles(&m_lDisableList, &fileList, true);
3175
 
3155
 
Line 3249... Line 3229...
3249
		if ( !Dir.exists(newFilename) )
3229
		if ( !Dir.exists(newFilename) )
3250
		{
3230
		{
3251
			// we couldn't create the directory for some reason, this is not good
3231
			// we couldn't create the directory for some reason, this is not good
3252
			if ( !Dir.create(newFilename) )
3232
			if ( !Dir.create(newFilename) )
3253
			{
3233
			{
3254
				this->AddLogEntry(SPKINSTALL_CREATEDIRECTORY_FAIL, newFilename, errors);
3234
				this->addLogEntry(SPKINSTALL_CREATEDIRECTORY_FAIL, newFilename, errors);
3255
				continue;
3235
				continue;
3256
			}
3236
			}
3257
			this->AddLogEntry(SPKINSTALL_CREATEDIRECTORY, newFilename, errors);
3237
			this->addLogEntry(SPKINSTALL_CREATEDIRECTORY, newFilename, errors);
3258
		}
3238
		}
3259
 
3239
 
3260
		// fake patches need a special directory and filename so they dont overright each other as thier filenames are always changes
3240
		// fake patches need a special directory and filename so they dont overright each other as thier filenames are always changes
3261
		// if a package with a fake patch is installed while another one is disabled, it will fill the gap left by the disabled one
3241
		// if a package with a fake patch is installed while another one is disabled, it will fill the gap left by the disabled one
3262
		// they will then end up with the same filename, if it gets disabled they would overright each other, so we change the filename to prevent that from happening
3242
		// they will then end up with the same filename, if it gets disabled they would overright each other, so we change the filename to prevent that from happening
Line 3287... Line 3267...
3287
		CFileIO currentFile(f->filePointer());
3267
		CFileIO currentFile(f->filePointer());
3288
		if ( !currentFile.exists() )
3268
		if ( !currentFile.exists() )
3289
		{
3269
		{
3290
			if ( !CFileIO(newFilename).exists() )
3270
			if ( !CFileIO(newFilename).exists() )
3291
			{
3271
			{
3292
				this->AddLogEntry(SPKINSTALL_MISSINGFILE, f->getNameDirectory(checkPackage), errors);
3272
				this->addLogEntry(SPKINSTALL_MISSINGFILE, f->getNameDirectory(checkPackage), errors);
3293
				continue;
3273
				continue;
3294
			}
3274
			}
3295
		}
3275
		}
3296
		// otherwise the file must exists, so lets move it
3276
		// otherwise the file must exists, so lets move it
3297
		else if ( !currentFile.Rename(newFilename) )
3277
		else if ( !currentFile.Rename(newFilename) )
3298
		{
3278
		{
3299
			this->AddLogEntry(SPKINSTALL_DISABLEFILE_FAIL, f->getNameDirectory(checkPackage), errors);
3279
			this->addLogEntry(SPKINSTALL_DISABLEFILE_FAIL, f->getNameDirectory(checkPackage), errors);
3300
			continue;
3280
			continue;
3301
		}
3281
		}
3302
 
3282
 
3303
		// must have been fine
3283
		// must have been fine
3304
		this->AddLogEntry(SPKINSTALL_DISABLEFILE, f->getNameDirectory(checkPackage), errors);
3284
		this->addLogEntry(SPKINSTALL_DISABLEFILE, f->getNameDirectory(checkPackage), errors);
3305
 
3285
 
3306
		original = _pOriginalFiles->restoreFile(f, errors);
3286
		original = _pOriginalFiles->restoreFile(f, errors);
3307
 
3287
 
3308
		// extra file thats not in the extras directory
3288
		// extra file thats not in the extras directory
3309
		if ( f->GetFileType() == FILETYPE_EXTRA || f->GetFileType() == FILETYPE_MAP || f->GetFileType() == FILETYPE_SOUND )
3289
		if (f->GetFileType() == FILETYPE_EXTRA || f->GetFileType() == FILETYPE_MAP || f->GetFileType() == FILETYPE_SOUND)
-
 
3290
		{
-
 
3291
			if(!removeDirs.contains(f->getDirectory(checkPackage)))
3310
			removeDirs.PushBack(CyString(f->getDirectory(checkPackage)), NullString, true);
3292
				removeDirs.pushBack(f->getDirectory(checkPackage));
-
 
3293
		}
3311
 
3294
 
3312
		// change the filename
3295
		// change the filename
3313
		f->setFilename(newFilename);
3296
		f->setFilename(newFilename);
3314
 
3297
 
3315
		// finally mark the file as disabled so we know not to try to move it again
3298
		// finally mark the file as disabled so we know not to try to move it again
Line 3319... Line 3302...
3319
	// a fake patch has been disabled, we need to reshuffle the rest to fill in any gaps
3302
	// a fake patch has been disabled, we need to reshuffle the rest to fill in any gaps
3320
	if ( shuffle )
3303
	if ( shuffle )
3321
	{
3304
	{
3322
		if ( progress )
3305
		if ( progress )
3323
			progress->UpdateStatus(PROGRESS_SHUFFLEFAKE);
3306
			progress->UpdateStatus(PROGRESS_SHUFFLEFAKE);
3324
		ShuffleFakePatches(errors);
3307
		shuffleFakePatches(errors);
3325
		ShuffleTextFiles(errors);
3308
		shuffleTextFiles(errors);
3326
	}
3309
	}
3327
 
3310
 
3328
	// original files were restored, check to remove the original file directory if its now empty
3311
	// original files were restored, check to remove the original file directory if its now empty
3329
	if ( original )
3312
	if ( original )
3330
		removeDirs.PushBack(CyString("PluginManager/Original"));
3313
		removeDirs.pushBack("PluginManager/Original");
3331
 
3314
 
3332
	// remove any empty directories that we might have left
3315
	// remove any empty directories that we might have left
3333
	if ( !removeDirs.Empty() )
3316
	if ( !removeDirs.empty() )
3334
		RemoveUnusedDirectories(removeDirs, errors);
3317
		removeUnusedDirectories(removeDirs, errors);
3335
 
3318
 
3336
	// finally mark the whole package as disabled
3319
	// finally mark the whole package as disabled
3337
	// recursive, we need to disable all children
3320
	// recursive, we need to disable all children
3338
	for ( CBaseFile *child = m_lDisableList.First(); child; child = m_lDisableList.Next() )
3321
	for ( CBaseFile *child = m_lDisableList.First(); child; child = m_lDisableList.Next() )
3339
	{
3322
	{
Line 3372... Line 3355...
3372
 * param: errors	- A string list used to add the status as it progresses, used in debugging output
3355
 * param: errors	- A string list used to add the status as it progresses, used in debugging output
3373
 * param: progress	- The progress class, updates the progress of the current disabling.  Needs a divered class to report the progress somewhere
3356
 * param: progress	- The progress class, updates the progress of the current disabling.  Needs a divered class to report the progress somewhere
3374
 *
3357
 *
3375
 * return: boolean, true if there was no errors, otherwise false
3358
 * return: boolean, true if there was no errors, otherwise false
3376
 */
3359
 */
3377
bool CPackages::DisablePackage ( CBaseFile *package, CyStringList *errors, CProgressInfo *progress )
3360
bool CPackages::disablePackage(CBaseFile *package, Utils::CStringList *errors, CProgressInfo *progress )
3378
{
3361
{
3379
	// if already disabled, just skip
3362
	// if already disabled, just skip
3380
	if ( !package->IsEnabled() )
3363
	if ( !package->IsEnabled() )
3381
		return true;
3364
		return true;
3382
 
3365
 
3383
	m_lDisableList.clear();
3366
	m_lDisableList.clear();
3384
	if ( this->PrepareDisablePackage(package) )
3367
	if ( this->PrepareDisablePackage(package) )
3385
		return this->DisablePreparedPackages(errors, progress);
3368
		return this->disablePreparedPackages(errors, progress);
3386
 
3369
 
3387
	return false;
3370
	return false;
3388
}
3371
}
3389
 
3372
 
3390
 
3373
 
Line 3582... Line 3565...
3582
}
3565
}
3583
 
3566
 
3584
/**
3567
/**
3585
 * Removes all empty directories that might have been created
3568
 * Removes all empty directories that might have been created
3586
 */
3569
 */
3587
void CPackages::RemoveUnusedDirectories(CyStringList& dirs, CyStringList* errors)
-
 
3588
{
-
 
3589
	CDirIO Dir(m_sCurrentDir);
-
 
3590
	for (SStringList* str = dirs.Head(); str; str = str->next)
-
 
3591
	{
-
 
3592
		CyString dir = str->str;
-
 
3593
 
-
 
3594
		CyStringList removedDir;
-
 
3595
		if (Dir.RemoveDir(dir, false, true, &removedDir) || !removedDir.Empty())
-
 
3596
		{
-
 
3597
			for (SStringList* node = removedDir.Head(); node; node = node->next)
-
 
3598
			{
-
 
3599
				CyString displayName = node->str;
-
 
3600
				displayName = displayName.Remove(m_sCurrentDir);
-
 
3601
				this->AddLogEntry(SPKINSTALL_REMOVEDIR, displayName, errors);
-
 
3602
			}
-
 
3603
		}
-
 
3604
	}
-
 
3605
}
-
 
3606
void CPackages::removeUnusedDirectories(const Utils::CStringList& dirs, Utils::CStringList* errors)
3570
void CPackages::removeUnusedDirectories(const Utils::CStringList& dirs, Utils::CStringList* errors)
3607
{
3571
{
3608
	CDirIO Dir(m_sCurrentDir);
3572
	CDirIO Dir(m_sCurrentDir);
3609
	for(auto itr = dirs.begin(); itr != dirs.end(); itr++)
3573
	for(auto itr = dirs.begin(); itr != dirs.end(); itr++)
3610
	{
3574
	{
Line 4041... Line 4005...
4041
/**
4005
/**
4042
 * Remove uninstall file
4006
 * Remove uninstall file
4043
 *
4007
 *
4044
 * Removes a single uninstall file
4008
 * Removes a single uninstall file
4045
 */
4009
 */
4046
bool CPackages::RemoveUninstallFile(C_File *file, CyStringList *errors)
4010
bool CPackages::removeUninstallFile(C_File *file, Utils::CStringList *errors)
4047
{
4011
{
4048
	CFileIO fio(file->filePointer());
4012
	CFileIO fio(file->filePointer());
4049
	if ( fio.exists() )
4013
	if ( fio.exists() )
4050
	{
4014
	{
4051
		if ( fio.remove() ) {
4015
		if ( fio.remove() ) {
4052
			this->AddLogEntry(SPKINSTALL_UNINSTALL_REMOVE, file->getNameDirectory(NULL), errors);
4016
			this->addLogEntry(SPKINSTALL_UNINSTALL_REMOVE, file->getNameDirectory(NULL), errors);
4053
			return true;
4017
			return true;
4054
		}
4018
		}
4055
		else if ( errors )
4019
		else if ( errors )
4056
			this->AddLogEntry(SPKINSTALL_UNINSTALL_REMOVE_FAIL, file->getNameDirectory(NULL), errors);
4020
			this->addLogEntry(SPKINSTALL_UNINSTALL_REMOVE_FAIL, file->getNameDirectory(NULL), errors);
4057
	}
4021
	}
4058
 
4022
 
4059
	return false;
4023
	return false;
4060
}
4024
}
4061
 
4025
 
Line 4063... Line 4027...
4063
 * Remove uninstall scripts
4027
 * Remove uninstall scripts
4064
 *
4028
 *
4065
 * Removes any unused unisntall scripts
4029
 * Removes any unused unisntall scripts
4066
 * Finds if any scripts are in the current package
4030
 * Finds if any scripts are in the current package
4067
 */
4031
 */
4068
int CPackages::RemoveUninstallScripts(CyStringList *errors, CProgressInfo *progress)
4032
int CPackages::removeUninstallScripts(Utils::CStringList *errors, CProgressInfo *progress)
4069
{
4033
{
4070
	if ( m_lUninstallFiles.empty() )
4034
	if ( m_lUninstallFiles.empty() )
4071
		return 0;
4035
		return 0;
4072
 
4036
 
4073
	UpdateUsedFiles();
4037
	UpdateUsedFiles();
Line 4097... Line 4061...
4097
		}
4061
		}
4098
 
4062
 
4099
		// not found a matching file, we can safetly remove it
4063
		// not found a matching file, we can safetly remove it
4100
		if ( !found )
4064
		if ( !found )
4101
		{
4065
		{
4102
			if ( RemoveUninstallFile(file) )
4066
			if (removeUninstallFile(file))
4103
				node->DeleteData();
4067
				node->DeleteData();
4104
		}
4068
		}
4105
	}
4069
	}
4106
 
4070
 
4107
	m_lUninstallFiles.RemoveEmpty();
4071
	m_lUninstallFiles.RemoveEmpty();
Line 4113... Line 4077...
4113
/**
4077
/**
4114
 * Remove unused shared file
4078
 * Remove unused shared file
4115
 *
4079
 *
4116
 * Removes a single file
4080
 * Removes a single file
4117
 */
4081
 */
4118
bool CPackages::RemoveSharedFile(C_File *file, CyStringList *errors)
4082
bool CPackages::removeSharedFile(C_File *file, Utils::CStringList *errors)
4119
{
4083
{
4120
	CFileIO fio(file->filePointer());
4084
	CFileIO fio(file->filePointer());
4121
	if ( fio.exists() )
4085
	if ( fio.exists() )
4122
	{
4086
	{
4123
		if ( fio.remove() ) {
4087
		if ( fio.remove() ) {
4124
			this->AddLogEntry(SPKINSTALL_SHARED, file->getNameDirectory(NULL), errors);
4088
			this->addLogEntry(SPKINSTALL_SHARED, file->getNameDirectory(NULL), errors);
4125
			delete file;
4089
			delete file;
4126
			return true;
4090
			return true;
4127
		}
4091
		}
4128
		else if ( errors )
4092
		else if ( errors )
4129
			this->AddLogEntry(SPKINSTALL_SHARED_FAIL, file->getNameDirectory(NULL), errors);
4093
			this->addLogEntry(SPKINSTALL_SHARED_FAIL, file->getNameDirectory(NULL), errors);
4130
	}
4094
	}
4131
 
4095
 
4132
	return false;
4096
	return false;
4133
}
4097
}
4134
 
4098
 
Line 4138... Line 4102...
4138
 * Files that have been marked as shared will not be removed or disabled when the last package is removed
4102
 * Files that have been marked as shared will not be removed or disabled when the last package is removed
4139
 * This function will remove any that are no longer connected with packages
4103
 * This function will remove any that are no longer connected with packages
4140
 *
4104
 *
4141
 * Marked shared fiels are mainly used for library scripts that arn't always added to packages
4105
 * Marked shared fiels are mainly used for library scripts that arn't always added to packages
4142
 */
4106
 */
4143
int CPackages::RemoveUnusedSharedFiles(CyStringList *errors, CProgressInfo *progress)
4107
int CPackages::removeUnusedSharedFiles(Utils::CStringList *errors, CProgressInfo *progress)
4144
{
4108
{
4145
	UpdateUsedFiles();
4109
	UpdateUsedFiles();
4146
	int files = 0;
4110
	int files = 0;
4147
	int done = 0;
4111
	int done = 0;
4148
 
4112
 
Line 4160... Line 4124...
4160
 
4124
 
4161
		// only do ones that are no longer needed
4125
		// only do ones that are no longer needed
4162
		if ( file->getUsed() )
4126
		if ( file->getUsed() )
4163
			continue;
4127
			continue;
4164
 
4128
 
4165
		if ( RemoveSharedFile(file, errors) )
4129
		if (removeSharedFile(file, errors) )
4166
			++done;
4130
			++done;
4167
		node->ChangeData(NULL);
4131
		node->ChangeData(NULL);
4168
	}
4132
	}
4169
 
4133
 
4170
	m_lFiles.RemoveEmpty();
4134
	m_lFiles.RemoveEmpty();
Line 4200... Line 4164...
4200
 
4164
 
4201
	return false;
4165
	return false;
4202
 
4166
 
4203
}
4167
}
4204
 
4168
 
4205
void CPackages::ShuffleTextFiles(CyStringList *errors)
4169
void CPackages::shuffleTextFiles(Utils::CStringList *errors)
4206
{
4170
{
4207
	for ( CListNode<C_File> *node = m_lFiles.Front(); node; node = node->next() )
4171
	for ( CListNode<C_File> *node = m_lFiles.Front(); node; node = node->next() )
4208
	{
4172
	{
4209
		C_File *f = node->Data();
4173
		C_File *f = node->Data();
4210
		// only do files that are enabled
4174
		// only do files that are enabled
Line 4225... Line 4189...
4225
			CFileIO moveFile(f->filePointer());
4189
			CFileIO moveFile(f->filePointer());
4226
	
4190
	
4227
			Utils::String newName = SPK::FormatTextName(current, m_iLanguage, (m_iGameFlags & EXEFLAG_TCTEXT)) + "." + moveFile.extension();
4191
			Utils::String newName = SPK::FormatTextName(current, m_iLanguage, (m_iGameFlags & EXEFLAG_TCTEXT)) + "." + moveFile.extension();
4228
			if ( moveFile.Rename(m_sCurrentDir + "/t/" + newName) )
4192
			if ( moveFile.Rename(m_sCurrentDir + "/t/" + newName) )
4229
			{
4193
			{
4230
				this->AddLogEntry(SPKINSTALL_AUTOTEXT, f->name() + "~" + newName, errors);
4194
				this->addLogEntry(SPKINSTALL_AUTOTEXT, f->name() + "~" + newName, errors);
4231
				f->setName(newName);
4195
				f->setName(newName);
4232
			}
4196
			}
4233
			else
4197
			else
4234
				this->AddLogEntry(SPKINSTALL_AUTOTEXT_FAIL, f->name() + "~" + newName, errors);
4198
				this->addLogEntry(SPKINSTALL_AUTOTEXT_FAIL, f->name() + "~" + newName, errors);
4235
		}
4199
		}
4236
	}
4200
	}
4237
}
4201
}
4238
 
4202
 
4239
/**
4203
/**
Line 4241... Line 4205...
4241
 *
4205
 *
4242
 * Rename the fake patches so they are always in sequence to be loaded into the game
4206
 * Rename the fake patches so they are always in sequence to be loaded into the game
4243
 *
4207
 *
4244
 * IE, when one is removed, the rest need to be shuffled down so theres no gaps
4208
 * IE, when one is removed, the rest need to be shuffled down so theres no gaps
4245
 */
4209
 */
4246
void CPackages::ShuffleFakePatches(CyStringList *errors)
4210
void CPackages::shuffleFakePatches(Utils::CStringList *errors)
4247
{
4211
{
4248
	int check = findNextFakePatch();
4212
	int check = findNextFakePatch();
4249
 
4213
 
4250
	// lets make sure our order is correct
4214
	// lets make sure our order is correct
4251
	// find Lowest Fake Patch Installed
4215
	// find Lowest Fake Patch Installed
Line 4405... Line 4369...
4405
			if (findItr == order.end())
4369
			if (findItr == order.end())
4406
				order.push_back(p);
4370
				order.push_back(p);
4407
		}
4371
		}
4408
	}
4372
	}
4409
 
4373
 
4410
	/*
-
 
4411
	// lets define the order
-
 
4412
 
-
 
4413
	// add any other packages that need to be ordered
-
 
4414
	// we need to work out the correct order
-
 
4415
	CLinkList<CBaseFile> packages;
-
 
4416
	for ( CListNode<CBaseFile> *pNode = m_lPackages.Front(); pNode; pNode = pNode->next() )
-
 
4417
	{
-
 
4418
		CBaseFile *p = pNode->Data();
-
 
4419
		// search for any fake patches in package
-
 
4420
		if ( !p->IsEnabled() ) continue;
-
 
4421
		if ( !p->AnyFileType(FILETYPE_MOD) ) continue;
-
 
4422
 
-
 
4423
		int existingPos = fakePatchOrder.findStringAndData(p->name(), p->author());
-
 
4424
 
-
 
4425
		if (p->AnyDependacies())
-
 
4426
		{
-
 
4427
			for (SNeededLibrary* nl = p->GetNeededLibraries()->First(); nl; nl = p->GetNeededLibraries()->Next())
-
 
4428
			{
-
 
4429
				int findPos = fakePatchOrder.findStringAndData(nl->sName, nl->sAuthor);
-
 
4430
				if (existingPos == -1)
-
 
4431
					fakePatchOrder.pushBack(nl->sName, nl->sAuthor);
-
 
4432
				else if (findPos == -1)
-
 
4433
					fakePatchOrder.insertAt(existingPos, nl->sName, nl->sAuthor);
-
 
4434
				else if (findPos > existingPos)
-
 
4435
				{
-
 
4436
					fakePatchOrder.removeAt(findPos);
-
 
4437
					fakePatchOrder.insertAt(existingPos, nl->sName, nl->sAuthor);
-
 
4438
				}
-
 
4439
			}
-
 
4440
		}
-
 
4441
 
-
 
4442
		CSpkFile* spk = dynamic_cast<CSpkFile*>(p);
-
 
4443
		if (spk)
-
 
4444
		{
-
 
4445
			if (spk->IsAnotherMod())
-
 
4446
			{
-
 
4447
				int findPos = fakePatchOrder.findStringAndData(spk->otherName(), spk->otherAuthor());
-
 
4448
				if (existingPos == -1)
-
 
4449
					fakePatchOrder.pushBack(spk->otherName(), spk->otherAuthor());
-
 
4450
				else if (findPos == -1)
-
 
4451
					fakePatchOrder.insertAt(existingPos, spk->otherName(), spk->otherAuthor());
-
 
4452
				else if (findPos > existingPos)
-
 
4453
				{
-
 
4454
					fakePatchOrder.removeAt(findPos);
-
 
4455
					fakePatchOrder.insertAt(existingPos, spk->otherName(), spk->otherAuthor());
-
 
4456
				}				
-
 
4457
			}
-
 
4458
		}
-
 
4459
 
-
 
4460
		// must have an order define
-
 
4461
		if (!p->anyFakePatchOrder())
-
 
4462
			continue;
-
 
4463
 
-
 
4464
		if (fakePatchOrder.findStringAndData(p->name(), p->author()) != -1)
-
 
4465
			continue;
-
 
4466
 
-
 
4467
		bool anyFound = false;
-
 
4468
		for ( C_File *file = p->GetFirstFile(FILETYPE_MOD); file; file = p->GetNextFile(file) )
-
 
4469
		{
-
 
4470
			if ( !file->IsFakePatch() ) continue;
-
 
4471
			if ( !file->CheckFileExt("cat") ) continue;
-
 
4472
			if ( doneList.FindData(file) ) 	continue;
-
 
4473
			anyFound = true;
-
 
4474
			break;
-
 
4475
		}
-
 
4476
 
-
 
4477
		// we have some fake patches that need to be shuffled
-
 
4478
		if ( anyFound )
-
 
4479
			packages.push_back(p);
-
 
4480
	}
-
 
4481
 
-
 
4482
	// lets adjust the order (only if theres more than 1
-
 
4483
	if ( packages.size() > 1 )
-
 
4484
	{
-
 
4485
		CLinkList<CBaseFile> sortedPackages;
-
 
4486
 
-
 
4487
		// first add all the packages that dont need to be installed after
-
 
4488
		for ( CListNode<CBaseFile> *pNode = packages.Front(); pNode; pNode = pNode->next() )
-
 
4489
		{
-
 
4490
			CBaseFile *p = pNode->Data();
-
 
4491
			// we have a before and not after
-
 
4492
			if ( !p->getFakePatchBeforeOrder().empty() && p->getFakePatchAfterOrder().empty() )
-
 
4493
			{
-
 
4494
				// if we have to install before, check if any on the list
-
 
4495
				int earliestPos = -1;
-
 
4496
				bool notAdded = true;
-
 
4497
				auto& list = p->getFakePatchBeforeOrder();
-
 
4498
				for(auto itr = list.begin(); itr != list.end(); itr++)
-
 
4499
				{
-
 
4500
					int pos = 0;
-
 
4501
					for ( CListNode<CBaseFile> *sNode = sortedPackages.Front(); sNode; sNode = sNode->next() )
-
 
4502
					{
-
 
4503
						if ((*itr)->str.Compare(sNode->Data()->name()) && (*itr)->data.Compare(sNode->Data()->author()) )
-
 
4504
						{
-
 
4505
							if ( earliestPos == -1 || pos < earliestPos )
-
 
4506
								earliestPos = pos;
-
 
4507
							break;
-
 
4508
						}
-
 
4509
						++pos;
-
 
4510
					}					
-
 
4511
				}
-
 
4512
 
-
 
4513
				if ( earliestPos > -1 )
-
 
4514
					sortedPackages.insert(earliestPos, p);
-
 
4515
				// otherwise just add it at the back
-
 
4516
				else
-
 
4517
					sortedPackages.push_back(p);
-
 
4518
 
-
 
4519
				// remove from the list
-
 
4520
				pNode->ChangeData(NULL);
-
 
4521
			}
-
 
4522
		}
-
 
4523
 
-
 
4524
		// now do the packages that have both before and after
-
 
4525
		packages.RemoveEmpty();
-
 
4526
		for ( CListNode<CBaseFile> *pNode = packages.Front(); pNode; pNode = pNode->next() )
-
 
4527
		{
-
 
4528
			CBaseFile *p = pNode->Data();
-
 
4529
			if ( !p->getFakePatchBeforeOrder().empty() && !p->getFakePatchAfterOrder().empty() )
-
 
4530
			{
-
 
4531
			}
-
 
4532
		}
-
 
4533
 
-
 
4534
		// add them onto the list
-
 
4535
		for ( CListNode<CBaseFile> *pNode = sortedPackages.Front(); pNode; pNode = pNode->next() )
-
 
4536
			fakePatchOrder.pushBack(pNode->Data()->name(), pNode->Data()->author());
-
 
4537
	}
-
 
4538
 
-
 
4539
	// now add to do list
-
 
4540
	for ( CListNode<CBaseFile> *pNode = packages.Front(); pNode; pNode = pNode->next() )
-
 
4541
		fakePatchOrder.pushBack(pNode->Data()->name(), pNode->Data()->author());
-
 
4542
		*/
-
 
4543
	for(auto itr = order.begin(); itr != order.end(); itr++)
4374
	for(auto itr = order.begin(); itr != order.end(); itr++)
4544
	{
4375
	{
4545
		CBaseFile *package = *itr;
4376
		CBaseFile *package = *itr;
4546
		if ( package )
4377
		if ( package )
4547
		{
4378
		{
Line 4581... Line 4412...
4581
							lowest++;
4412
							lowest++;
4582
							continue;
4413
							continue;
4583
						}
4414
						}
4584
 
4415
 
4585
						// now we can move the the cat/dat file elsewhere, lets shuffle it to the highest free number
4416
						// now we can move the the cat/dat file elsewhere, lets shuffle it to the highest free number
4586
						ShufflePatchTo(moveFile, findLastFakePatch(), errors);
4417
						shufflePatchTo(moveFile, findLastFakePatch(), errors);
4587
					}
4418
					}
4588
 
4419
 
4589
					// space should be free, now lets shuffle it
4420
					// space should be free, now lets shuffle it
4590
					ShufflePatchTo(lowestFile, lowest, errors);
4421
					shufflePatchTo(lowestFile, lowest, errors);
4591
				}
4422
				}
4592
 
4423
 
4593
				doneList.push_back(lowestFile); // we've done this file now
4424
				doneList.push_back(lowestFile); // we've done this file now
4594
				lowest++; // move up the lowest ready for the next patch
4425
				lowest++; // move up the lowest ready for the next patch
4595
			}
4426
			}
Line 4621... Line 4452...
4621
		int check = findNextFakePatch();
4452
		int check = findNextFakePatch();
4622
		int patchNum = f->filename().token(".", 1).toInt();
4453
		int patchNum = f->filename().token(".", 1).toInt();
4623
		if ( patchNum <= check )
4454
		if ( patchNum <= check )
4624
			continue;
4455
			continue;
4625
 
4456
 
4626
		ShufflePatchTo(f, check, errors);
4457
		shufflePatchTo(f, check, errors);
4627
	}
4458
	}
4628
}
4459
}
4629
 
4460
 
4630
void CPackages::ShufflePatchTo(C_File *file, int to, CyStringList *errors)
4461
void CPackages::shufflePatchTo(C_File *file, int to, Utils::CStringList *errors)
4631
{
4462
{
4632
	// it is, we need to shift this to fill the gap
4463
	// it is, we need to shift this to fill the gap
4633
	Utils::String newName = Utils::String::PadNumber(to, 2) + "." + file->fileExt();
4464
	Utils::String newName = Utils::String::PadNumber(to, 2) + "." + file->fileExt();
4634
 
4465
 
4635
	// now rename the file
4466
	// now rename the file
4636
	CFileIO moveFile(file->filePointer());
4467
	CFileIO moveFile(file->filePointer());
4637
	if ( moveFile.Rename(m_sCurrentDir + "/" + newName) )
4468
	if ( moveFile.Rename(m_sCurrentDir + "/" + newName) )
4638
	{
4469
	{
4639
		// display moveing
4470
		// display moveing
4640
		this->AddLogEntry(SPKINSTALL_FAKEPATCH, file->name() + "~" + newName, errors);
4471
		this->addLogEntry(SPKINSTALL_FAKEPATCH, file->name() + "~" + newName, errors);
4641
 
4472
 
4642
		// now find the matching pairing if it exists
4473
		// now find the matching pairing if it exists
4643
		for ( CListNode<C_File> *node2 = m_lFiles.Front(); node2; node2 = node2->next() )
4474
		for ( CListNode<C_File> *node2 = m_lFiles.Front(); node2; node2 = node2->next() )
4644
		{
4475
		{
4645
			C_File *f2 = node2->Data();
4476
			C_File *f2 = node2->Data();
Line 4653... Line 4484...
4653
 
4484
 
4654
			Utils::String newName2 = Utils::String::PadNumber(to, 2) + "." + f2->fileExt();
4485
			Utils::String newName2 = Utils::String::PadNumber(to, 2) + "." + f2->fileExt();
4655
			CFileIO moveFile(f2->filePointer());
4486
			CFileIO moveFile(f2->filePointer());
4656
			if ( moveFile.Rename(m_sCurrentDir + "/" + newName2) )
4487
			if ( moveFile.Rename(m_sCurrentDir + "/" + newName2) )
4657
			{
4488
			{
4658
				this->AddLogEntry(SPKINSTALL_FAKEPATCH, f2->name() + "~" + newName2, errors);
4489
				this->addLogEntry(SPKINSTALL_FAKEPATCH, f2->name() + "~" + newName2, errors);
4659
				f2->setName(newName2);
4490
				f2->setName(newName2);
4660
			}
4491
			}
4661
			else
4492
			else
4662
				this->AddLogEntry(SPKINSTALL_FAKEPATCH_FAIL, f2->name() + "~" + newName2, errors);
4493
				this->addLogEntry(SPKINSTALL_FAKEPATCH_FAIL, f2->name() + "~" + newName2, errors);
4663
		}
4494
		}
4664
 
4495
 
4665
		// finally make sure the internal name matches the new one
4496
		// finally make sure the internal name matches the new one
4666
		file->setName(newName);
4497
		file->setName(newName);
4667
	}
4498
	}
4668
	else
4499
	else
4669
		this->AddLogEntry(SPKINSTALL_FAKEPATCH_FAIL, file->name() + "~" + newName, errors);
4500
		this->addLogEntry(SPKINSTALL_FAKEPATCH_FAIL, file->name() + "~" + newName, errors);
4670
}
4501
}
4671
 
4502
 
4672
int CPackages::FindLowestFakePatchInstalled()
4503
int CPackages::FindLowestFakePatchInstalled()
4673
{
4504
{
4674
	int lowest = 99;
4505
	int lowest = 99;
Line 5058... Line 4889...
5058
		if ( found )
4889
		if ( found )
5059
			package->GetFileList()->push_back(file);
4890
			package->GetFileList()->push_back(file);
5060
	}
4891
	}
5061
}
4892
}
5062
 
4893
 
5063
bool CPackages::RemoveFile(C_File *file, CyStringList *errors)
4894
bool CPackages::removeFile(C_File *file, Utils::CStringList *errors)
5064
{
4895
{
5065
	if ( !file )
4896
	if ( !file )
5066
		return true;
4897
		return true;
5067
 
4898
 
5068
	Utils::String remFileStr = file->filePointer();
4899
	Utils::String remFileStr = file->filePointer();
Line 5074... Line 4905...
5074
			CCatFile cat;
4905
			CCatFile cat;
5075
			if ( cat.open(CatFile.fullFilename(), this->getAddonDir(), CATREAD_DAT, false) == CATERR_NONE ) {
4906
			if ( cat.open(CatFile.fullFilename(), this->getAddonDir(), CATREAD_DAT, false) == CATERR_NONE ) {
5076
				Utils::String fileName = file->filePointer().token("::", 2);
4907
				Utils::String fileName = file->filePointer().token("::", 2);
5077
				if ( cat.findData(fileName) ) {
4908
				if ( cat.findData(fileName) ) {
5078
					if ( cat.removeFile(fileName) ) {
4909
					if ( cat.removeFile(fileName) ) {
5079
						this->AddLogEntry(SPKINSTALL_DELETEFILE, remFileStr, errors);
4910
						this->addLogEntry(SPKINSTALL_DELETEFILE, remFileStr, errors);
5080
					}
4911
					}
5081
					else {
4912
					else {
5082
						this->AddLogEntry(SPKINSTALL_DELETEFILE_FAIL, remFileStr, errors);
4913
						this->addLogEntry(SPKINSTALL_DELETEFILE_FAIL, remFileStr, errors);
5083
						return false;
4914
						return false;
5084
					}
4915
					}
5085
				}
4916
				}
5086
			}
4917
			}
5087
		}
4918
		}
5088
	}
4919
	}
5089
	else {
4920
	else {
5090
		CFileIO f(file->filePointer());
4921
		CFileIO f(file->filePointer());
5091
		if ( f.exists() )
4922
		if ( f.exists() )
5092
		{
4923
		{
5093
			if ( f.remove() ) this->AddLogEntry(SPKINSTALL_DELETEFILE, remFileStr, errors);
4924
			if ( f.remove() ) this->addLogEntry(SPKINSTALL_DELETEFILE, remFileStr, errors);
5094
			else if ( errors )
4925
			else if ( errors )
5095
			{
4926
			{
5096
				this->AddLogEntry(SPKINSTALL_DELETEFILE_FAIL, remFileStr, errors);
4927
				this->addLogEntry(SPKINSTALL_DELETEFILE_FAIL, remFileStr, errors);
5097
				return false;
4928
				return false;
5098
			}
4929
			}
5099
			else
4930
			else
5100
				return false;
4931
				return false;
5101
		}
4932
		}
5102
	}
4933
	}
5103
 
4934
 
5104
	return true;
4935
	return true;
5105
}
4936
}
5106
 
4937
 
5107
int CPackages::RemoveAllPackages(CyStringList *errors, CProgressInfo *progress)
4938
int CPackages::removeAllPackages(Utils::CStringList *errors, CProgressInfo *progress)
5108
{
4939
{
5109
	int files = 0;
4940
	int files = 0;
5110
 
4941
 
5111
	// remove all files
4942
	// remove all files
5112
	int max = m_lFiles.size() + _pOriginalFiles->count() + m_lUninstallFiles.size();
4943
	int max = m_lFiles.size() + _pOriginalFiles->count() + m_lUninstallFiles.size();
Line 5115... Line 4946...
5115
		// update the progress
4946
		// update the progress
5116
		if ( progress )
4947
		if ( progress )
5117
			progress->UpdateProgress(files, max);
4948
			progress->UpdateProgress(files, max);
5118
		++files;
4949
		++files;
5119
 
4950
 
5120
		RemoveFile(node->Data());
4951
		removeFile(node->Data());
5121
		delete node->Data();
4952
		delete node->Data();
5122
	}
4953
	}
5123
	m_lFiles.clear();
4954
	m_lFiles.clear();
5124
 
4955
 
5125
	// restore any original files that are backed up
4956
	// restore any original files that are backed up
Line 5132... Line 4963...
5132
		// update the progress
4963
		// update the progress
5133
		if ( progress )
4964
		if ( progress )
5134
			progress->UpdateProgress(files, max);
4965
			progress->UpdateProgress(files, max);
5135
		++files;
4966
		++files;
5136
 
4967
 
5137
		RemoveFile(uNode->Data());
4968
		removeFile(uNode->Data());
5138
		delete uNode->Data();
4969
		delete uNode->Data();
5139
	}
4970
	}
5140
	m_lUninstallFiles.clear();
4971
	m_lUninstallFiles.clear();
5141
 
4972
 
5142
	// delete all packages
4973
	// delete all packages
Line 5240... Line 5071...
5240
void CPackages::startup(const Utils::String &dir, const Utils::String &tempDir, const Utils::String &myDoc, const Utils::String &mod)
5071
void CPackages::startup(const Utils::String &dir, const Utils::String &tempDir, const Utils::String &myDoc, const Utils::String &mod)
5241
{
5072
{
5242
	startup(dir, tempDir, myDoc);
5073
	startup(dir, tempDir, myDoc);
5243
	m_sSetMod = mod;
5074
	m_sSetMod = mod;
5244
}
5075
}
5245
/*
-
 
5246
void CPackages::Startup(CyString dir, CyString tempDir, CyString myDoc, CyString mod)
-
 
5247
{
-
 
5248
	startup(dir.ToString(), tempDir.ToString(), myDoc.ToString(), mod.ToString());
-
 
5249
}*/
-
 
5250
 
5076
 
5251
int CPackages::getGameLanguage() const
5077
int CPackages::getGameLanguage() const
5252
{
5078
{
5253
	return this->getGameLanguage(m_sCurrentDir);
5079
	return this->getGameLanguage(m_sCurrentDir);
5254
}
5080
}
Line 6353... Line 6179...
6353
{
6179
{
6354
	if ( !m_bLoaded )
6180
	if ( !m_bLoaded )
6355
		return false;
6181
		return false;
6356
 
6182
 
6357
	// remove all package files
6183
	// remove all package files
6358
	this->RemoveAllPackages();
6184
	this->removeAllPackages();
6359
 
6185
 
6360
	// remove all plugin manager files
6186
	// remove all plugin manager files
6361
	this->RemoveCreatedFiles();
6187
	this->RemoveCreatedFiles();
6362
 
6188
 
6363
	this->Reset();
6189
	this->Reset();