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
		}
1375
		else if ( errored )
1374
		else if ( errored )
1376
		{
1375
		{
1377
			m_lPackages.remove(p);
1376
			m_lPackages.remove(p);
1378
			errored->push_back(p);
1377
			errored->push_back(p);
1379
		}
1378
		}
1380
	}
1379
	}
1381
 
1380
 
1382
	m_lInstallList.clear();
1381
	m_lInstallList.clear();
1383
 
1382
 
1384
	this->WriteData();
1383
	this->WriteData();
Line 1417... Line 1416...
1417
 
1416
 
1418
	// first check if we are installed a mod
1417
	// first check if we are installed a mod
1419
	if ( package->IsMod() && m_pEnabledMod && !m_bForceModInstall ) {
1418
	if ( package->IsMod() && m_pEnabledMod && !m_bForceModInstall ) {
1420
		disabled = true;
1419
		disabled = true;
1421
		CLog::log(CLog::Log_Install, 2, "Package is a mod and another mod is already enabled, setting to disabled");
1420
		CLog::log(CLog::Log_Install, 2, "Package is a mod and another mod is already enabled, setting to disabled");
1422
	}
1421
	}
1423
	// if vanilla nad package aint signed
1422
	// if vanilla nad package aint signed
1424
	if ( m_bVanilla && !package->IsSigned() ) {
1423
	if ( m_bVanilla && !package->IsSigned() ) {
1425
		disabled = true;
1424
		disabled = true;
1426
		CLog::log(CLog::Log_Install, 2, "Package is a not signed and are we in vanilla mode, setting to disabled");
1425
		CLog::log(CLog::Log_Install, 2, "Package is a not signed and are we in vanilla mode, setting to disabled");
1427
	}
1426
	}
Line 1435... Line 1434...
1435
	// search for an old version
1434
	// search for an old version
1436
	if ( oldPackage && oldPackage == m_pEnabledMod && disabled )
1435
	if ( oldPackage && oldPackage == m_pEnabledMod && disabled )
1437
		disabled = prevDisabled;
1436
		disabled = prevDisabled;
1438
 
1437
 
1439
	return disabled;
1438
	return disabled;
1440
}
1439
}
1441
 
1440
 
1442
Utils::String CPackages::getCurrentDirectory() const
1441
Utils::String CPackages::getCurrentDirectory() const
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 1709... Line 1706...
1709
	}
1706
	}
1710
 
1707
 
1711
	// remove all data
1708
	// remove all data
1712
	CLog::log(CLog::Log_Install, 3, "Clearing all unneeded file data");
1709
	CLog::log(CLog::Log_Install, 3, "Clearing all unneeded file data");
1713
	package->ClearFileData();
1710
	package->ClearFileData();
1714
 
1711
 
1715
	// add to list
1712
	// add to list
1716
	if ( !dontAdd )
1713
	if ( !dontAdd )
1717
	{
1714
	{
1718
		CLog::log(CLog::Log_Install, 1, "Adding package into main list");
1715
		CLog::log(CLog::Log_Install, 1, "Adding package into main list");
1719
		if ( oldPackage )
1716
		if ( oldPackage )
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 1827... Line 1822...
1827
	CLinkList<C_File> fileList;
1822
	CLinkList<C_File> fileList;
1828
	bool readme = false, original = false, shuffle = false;
1823
	bool readme = false, original = false, shuffle = false;
1829
 
1824
 
1830
	// find all files that need to be removed
1825
	// find all files that need to be removed
1831
	int maxFiles = 0;
1826
	int maxFiles = 0;
1832
	for ( CListNode<CBaseFile> *node = m_lInstallList.Front(); node; node = node->next() )
1827
	for ( CListNode<CBaseFile> *node = m_lInstallList.Front(); node; node = node->next() )
1833
	{
1828
	{
1834
		CBaseFile *p = node->Data();
1829
		CBaseFile *p = node->Data();
1835
		maxFiles += this->GetAllPackageFiles(p, &fileList, true);
1830
		maxFiles += this->GetAllPackageFiles(p, &fileList, true);
1836
 
1831
 
1837
		// disable any dependants
1832
		// disable any dependants
1838
		if ( p->GetType() == TYPE_SPK && ((CSpkFile *)p)->IsLibrary() )
1833
		if ( p->GetType() == TYPE_SPK && ((CSpkFile *)p)->IsLibrary() )
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
 
-
 
2472
	Utils::CStringList lErrors;
-
 
2473
 
2466
 
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 2508... Line 2501...
2508
				{
2501
				{
2509
					CFileIO(fDat->filePointer()).copy(m_sCurrentDir + "/mods/PluginManager.dat");
2502
					CFileIO(fDat->filePointer()).copy(m_sCurrentDir + "/mods/PluginManager.dat");
2510
					CFileIO(fCat->filePointer()).copy(m_sCurrentDir + "/mods/PluginManager.cat");
2503
					CFileIO(fCat->filePointer()).copy(m_sCurrentDir + "/mods/PluginManager.cat");
2511
				}
2504
				}
2512
			}
2505
			}
2513
		}
2506
		}
2514
		else if ( m_iGame == GAME_X3 && !m_sSetMod.empty() && CFileIO::Exists(m_sCurrentDir + "/mods/" + m_sSetMod + ".cat") && CFileIO::Exists(m_sCurrentDir + "/mods/" + m_sSetMod + ".dat"))
2507
		else if ( m_iGame == GAME_X3 && !m_sSetMod.empty() && CFileIO::Exists(m_sCurrentDir + "/mods/" + m_sSetMod + ".cat") && CFileIO::Exists(m_sCurrentDir + "/mods/" + m_sSetMod + ".dat"))
2515
		{
2508
		{
2516
			CLog::log(CLog::Log_Directory, 2, "Copying mod file: " + m_sSetMod + ", to PluginManager.cat");
2509
			CLog::log(CLog::Log_Directory, 2, "Copying mod file: " + m_sSetMod + ", to PluginManager.cat");
2517
			CFileIO(m_sCurrentDir + "/mods/" + m_sSetMod + ".dat").copy(m_sCurrentDir + "/mods/PluginManager.dat");
2510
			CFileIO(m_sCurrentDir + "/mods/" + m_sSetMod + ".dat").copy(m_sCurrentDir + "/mods/PluginManager.dat");
2518
			CFileIO(m_sCurrentDir + "/mods/" + m_sSetMod + ".cat").copy(m_sCurrentDir + "/mods/PluginManager.cat");
2511
			CFileIO(m_sCurrentDir + "/mods/" + m_sSetMod + ".cat").copy(m_sCurrentDir + "/mods/PluginManager.cat");
2519
		}
2512
		}
2520
 
2513
 
2521
		if ( !CDirIO(m_sCurrentDir).exists("mods") )
2514
		if ( !CDirIO(m_sCurrentDir).exists("mods") )
2522
			CDirIO(m_sCurrentDir).create("mods");
2515
			CDirIO(m_sCurrentDir).create("mods");
2523
 
2516
 
2524
		SetupWares();
2517
		SetupWares();
2525
		SetupShips();
2518
		SetupShips();
2526
		createEMPFile();
2519
		createEMPFile();
2527
		CreateWareFiles();
2520
		CreateWareFiles();
2528
		CreateDummies();
2521
		CreateDummies();
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;
3017
	int maxFiles = this->GetAllPackageFiles(&m_lEnableList, &fileList, false);
2997
	int maxFiles = this->GetAllPackageFiles(&m_lEnableList, &fileList, false);
3018
 
2998
 
3019
	int fileCount = 0;
2999
	int fileCount = 0;
3020
	// we use this list to match cat and dat files
3000
	// we use this list to match cat and dat files
3021
	Utils::CStringList fakePatches;
3001
	Utils::CStringList fakePatches;
3022
	for ( CListNode<C_File> *node = fileList.Front(); node; node = node->next() )
3002
	for ( CListNode<C_File> *node = fileList.Front(); node; node = node->next() )
3023
	{
3003
	{
3024
		C_File *f = node->Data();
3004
		C_File *f = node->Data();
3025
		if (!f->isForGame(m_iGame))
3005
		if (!f->isForGame(m_iGame))
3026
			continue;
3006
			continue;
3027
		CBaseFile *package = NULL;
3007
		CBaseFile *package = NULL;
3028
		for ( CListNode<CBaseFile> *node = m_lEnableList.Front(); node; node = node->next() )
3008
		for ( CListNode<CBaseFile> *node = m_lEnableList.Front(); node; node = node->next() )
3029
		{
3009
		{
3030
			CBaseFile *p = node->Data();
3010
			CBaseFile *p = node->Data();
3031
			if ( p->IsFileAdded(f) )
3011
			if ( p->IsFileAdded(f) )
3032
			{
3012
			{
3033
				package = p;
3013
				package = p;
3034
				break;
3014
				break;
3035
			}
3015
			}
3036
		}
3016
		}
3037
 
3017
 
3038
		if ( progress )
3018
		if ( progress )
3039
		{
3019
		{
3040
			progress->UpdateProgress(fileCount++, maxFiles);
3020
			progress->UpdateProgress(fileCount++, maxFiles);
3041
			progress->UpdateFile(f);
3021
			progress->UpdateFile(f);
3042
		}
3022
		}
Line 3052... Line 3032...
3052
		if ( !f->IsFakePatch() )
3032
		if ( !f->IsFakePatch() )
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 3229... Line 3209...
3229
 
3209
 
3230
		if ( f->GetFileType() == FILETYPE_MOD && !f->IsFakePatch() && f->checkFileExt("cat") )
3210
		if ( f->GetFileType() == FILETYPE_MOD && !f->IsFakePatch() && f->checkFileExt("cat") )
3231
		{
3211
		{
3232
			if ( f->baseName().Compare(m_sSetMod) )
3212
			if ( f->baseName().Compare(m_sSetMod) )
3233
				m_sSetMod = Utils::String::Null();
3213
				m_sSetMod = Utils::String::Null();
3234
		}
3214
		}
3235
 
3215
 
3236
		// file is not being used by any enabled package
3216
		// file is not being used by any enabled package
3237
		// set disabled and move to disabled directory
3217
		// set disabled and move to disabled directory
3238
		CDirIO Dir(m_sCurrentDir);
3218
		CDirIO Dir(m_sCurrentDir);
3239
		Utils::String newFilename = "PluginManager/Disabled/";
3219
		Utils::String newFilename = "PluginManager/Disabled/";
3240
 
3220
 
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
3316
		f->SetDisabled(true);
3299
		f->SetDisabled(true);
3317
	}
3300
	}
3318
 
3301
 
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 3494... Line 3477...
3494
	{
3477
	{
3495
		CBaseFile *file = node->Data();
3478
		CBaseFile *file = node->Data();
3496
 
3479
 
3497
		// only look for spk packages
3480
		// only look for spk packages
3498
		if ( file->GetType() != TYPE_SPK )
3481
		if ( file->GetType() != TYPE_SPK )
3499
			continue;
3482
			continue;
3500
 
3483
 
3501
		// now compare the name and author, "Compare" is a non case senseative check, opposed to ==.
3484
		// now compare the name and author, "Compare" is a non case senseative check, opposed to ==.
3502
		if ( file->name().Compare(name) && file->author().Compare(author) )
3485
		if ( file->name().Compare(name) && file->author().Compare(author) )
3503
			return file;
3486
			return file;
3504
	}
3487
	}
3505
 
3488
 
3506
	// nothing found
3489
	// nothing found
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 4178... Line 4142...
4178
 * Checks if theres any unused shared files available
4142
 * Checks if theres any unused shared files available
4179
 *
4143
 *
4180
 * Any file thats marked as shared, and is no longer connected to any installed package
4144
 * Any file thats marked as shared, and is no longer connected to any installed package
4181
 */
4145
 */
4182
bool CPackages::AnyUnusedShared()
4146
bool CPackages::AnyUnusedShared()
4183
{
4147
{
4184
	UpdateUsedFiles();
4148
	UpdateUsedFiles();
4185
 
4149
 
4186
	for ( CListNode<C_File> *node = m_lFiles.Back(); node; node = node->prev() )
4150
	for ( CListNode<C_File> *node = m_lFiles.Back(); node; node = node->prev() )
4187
	{
4151
	{
4188
		C_File *file = node->Data();
4152
		C_File *file = node->Data();
4189
 
4153
 
4190
		// only do marked shared files
4154
		// only do marked shared files
4191
		if ( !file->IsShared() )
4155
		if ( !file->IsShared() )
4192
			continue;
4156
			continue;
4193
 
4157
 
4194
		// only do ones that are no longer needed
4158
		// only do ones that are no longer needed
4195
		if ( file->getUsed() )
4159
		if ( file->getUsed() )
4196
			continue;
4160
			continue;
4197
 
4161
 
4198
		return true;
4162
		return true;
4199
	}
4163
	}
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
/**
4240
 * Shuffle Fake Patches
4204
 * Shuffle Fake Patches
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 4266... Line 4230...
4266
		if (p->AnyDependacies())
4230
		if (p->AnyDependacies())
4267
		{
4231
		{
4268
			for (SNeededLibrary* nl = p->GetNeededLibraries()->First(); nl; nl = p->GetNeededLibraries()->Next())
4232
			for (SNeededLibrary* nl = p->GetNeededLibraries()->First(); nl; nl = p->GetNeededLibraries()->Next())
4269
			{
4233
			{
4270
				auto package = findPackage(nl->sName, nl->sAuthor);
4234
				auto package = findPackage(nl->sName, nl->sAuthor);
4271
				if (package)
4235
				if (package)
4272
				{
4236
				{
4273
					packagesBefore.insert(package);
4237
					packagesBefore.insert(package);
4274
					packagesAfter[p].insert(package);
4238
					packagesAfter[p].insert(package);
4275
				}
4239
				}
4276
			}
4240
			}
4277
		}
4241
		}
4278
		CSpkFile* spk = dynamic_cast<CSpkFile*>(p);
4242
		CSpkFile* spk = dynamic_cast<CSpkFile*>(p);
4279
		if (spk)
4243
		if (spk)
4280
		{
4244
		{
4281
			if (spk->IsAnotherMod())
4245
			if (spk->IsAnotherMod())
4282
			{
4246
			{
4283
				auto package = findPackage(spk->otherName(), spk->otherAuthor());
4247
				auto package = findPackage(spk->otherName(), spk->otherAuthor());
4284
				if (package)
4248
				if (package)
4285
				{
4249
				{
Line 4296... Line 4260...
4296
			for (auto itr = list.begin(); itr != list.end(); itr++)
4260
			for (auto itr = list.begin(); itr != list.end(); itr++)
4297
			{
4261
			{
4298
				auto package = findPackage((*itr)->str, (*itr)->data);
4262
				auto package = findPackage((*itr)->str, (*itr)->data);
4299
				if (package)				
4263
				if (package)				
4300
					packagesAfter[package].insert(p);
4264
					packagesAfter[package].insert(p);
4301
			}
4265
			}
4302
		}
4266
		}
4303
		if (!p->getFakePatchAfterOrder().empty())
4267
		if (!p->getFakePatchAfterOrder().empty())
4304
		{
4268
		{
4305
			auto& list = p->getFakePatchAfterOrder();
4269
			auto& list = p->getFakePatchAfterOrder();
4306
			for (auto itr = list.begin(); itr != list.end(); itr++)
4270
			for (auto itr = list.begin(); itr != list.end(); itr++)
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
		{
4548
			// might have more than 1 fake patch for the file, so we'll need the lowest
4379
			// might have more than 1 fake patch for the file, so we'll need the lowest
4549
			while ( true )
4380
			while ( true )
4550
			{
4381
			{
4551
				C_File *lowestFile = NULL;
4382
				C_File *lowestFile = NULL;
4552
				for ( C_File *file = package->GetFirstFile(FILETYPE_MOD); file; file = package->GetNextFile(file) )
4383
				for ( C_File *file = package->GetFirstFile(FILETYPE_MOD); file; file = package->GetNextFile(file) )
Line 4556... Line 4387...
4556
					if (doneList.FindData(file)) continue; // already done?
4387
					if (doneList.FindData(file)) continue; // already done?
4557
 
4388
 
4558
					if ( !lowestFile )
4389
					if ( !lowestFile )
4559
						lowestFile = file;
4390
						lowestFile = file;
4560
					else
4391
					else
4561
					{
4392
					{
4562
						if ( file->baseName().toInt() < lowestFile->baseName().toInt() )
4393
						if ( file->baseName().toInt() < lowestFile->baseName().toInt() )
4563
							lowestFile = file;
4394
							lowestFile = file;
4564
					}
4395
					}
4565
				}
4396
				}
4566
 
4397
 
4567
				if ( !lowestFile ) // no more files ?
4398
				if ( !lowestFile ) // no more files ?
4568
					break;
4399
					break;
4569
 
4400
 
4570
				// check its filename, it might already be in the correct place
4401
				// check its filename, it might already be in the correct place
4571
				if ( lowestFile->baseName().toInt() != lowest )
4402
				if ( lowestFile->baseName().toInt() != lowest )
4572
				{
4403
				{
4573
					// if the file already exists, we need to move it elsewhere
4404
					// if the file already exists, we need to move it elsewhere
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 4601... Line 4432...
4601
	for ( CListNode<C_File> *node = m_lFiles.Front(); node; node = node->next() )
4432
	for ( CListNode<C_File> *node = m_lFiles.Front(); node; node = node->next() )
4602
	{
4433
	{
4603
		C_File *f = node->Data();
4434
		C_File *f = node->Data();
4604
		// already done?
4435
		// already done?
4605
		if ( doneList.FindData(f) ) 
4436
		if ( doneList.FindData(f) ) 
4606
			continue;
4437
			continue;
4607
 
4438
 
4608
		// only do files that are enabled
4439
		// only do files that are enabled
4609
		if ( f->IsDisabled() )
4440
		if ( f->IsDisabled() )
4610
			continue;
4441
			continue;
4611
 
4442
 
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 4718... Line 4549...
4718
 * Find next fake patch
4549
 * Find next fake patch
4719
 *
4550
 *
4720
 * Searching for the next gap in patches, starting with 01.cat to 99.cat
4551
 * Searching for the next gap in patches, starting with 01.cat to 99.cat
4721
 */
4552
 */
4722
int CPackages::findNextFakePatch(int start, const Utils::String &dir) const
4553
int CPackages::findNextFakePatch(int start, const Utils::String &dir) const
4723
{
4554
{
4724
	CDirIO Dir((dir.empty()) ? m_sCurrentDir : dir);
4555
	CDirIO Dir((dir.empty()) ? m_sCurrentDir : dir);
4725
 
4556
 
4726
	int check = start;
4557
	int check = start;
4727
	while ( check < 99 )
4558
	while ( check < 99 )
4728
	{
4559
	{
4729
		++check;
4560
		++check;
4730
		Utils::String checkStr = Utils::String::PadNumber(check, 2);
4561
		Utils::String checkStr = Utils::String::PadNumber(check, 2);
4731
 
4562
 
Line 4734... Line 4565...
4734
		{
4565
		{
4735
			// it doen't, check if theres a dat file (incase of package error)
4566
			// it doen't, check if theres a dat file (incase of package error)
4736
			if ( !Dir.exists(checkStr + ".dat") )
4567
			if ( !Dir.exists(checkStr + ".dat") )
4737
				break;
4568
				break;
4738
		}
4569
		}
4739
	}
4570
	}
4740
 
4571
 
4741
	return check;
4572
	return check;
4742
}
4573
}
4743
 
4574
 
4744
/**
4575
/**
4745
 * Find next text file
4576
 * Find next text file
Line 4749... Line 4580...
4749
unsigned int CPackages::findNextTextFile(unsigned int start) const
4580
unsigned int CPackages::findNextTextFile(unsigned int start) const
4750
{
4581
{
4751
	return findNextTextFile(Utils::String::Null(), start);
4582
	return findNextTextFile(Utils::String::Null(), start);
4752
}
4583
}
4753
unsigned int CPackages::findNextTextFile(const Utils::String &dir, unsigned int start) const
4584
unsigned int CPackages::findNextTextFile(const Utils::String &dir, unsigned int start) const
4754
{
4585
{
4755
	int check = start;
4586
	int check = start;
4756
	if ( check < 2 ) check = 2;
4587
	if ( check < 2 ) check = 2;
4757
	while ( check < 9999 )
4588
	while ( check < 9999 )
4758
	{
4589
	{
4759
		++check;
4590
		++check;
4760
		Utils::String newFilename = SPK::FormatTextName(check, m_iLanguage, (m_iGameFlags & EXEFLAG_TCTEXT));
4591
		Utils::String newFilename = SPK::FormatTextName(check, m_iLanguage, (m_iGameFlags & EXEFLAG_TCTEXT));
4761
 
4592
 
4762
		// check the vfs
4593
		// check the vfs
4763
		if ( m_pGameVFS.isFileAvailable("t/" + newFilename + ".pck") ) continue;
4594
		if ( m_pGameVFS.isFileAvailable("t/" + newFilename + ".pck") ) continue;
4764
		if ( m_pGameVFS.isFileAvailable("t/" + newFilename + ".xml") ) continue;
4595
		if ( m_pGameVFS.isFileAvailable("t/" + newFilename + ".xml") ) continue;
4765
 
4596
 
4766
		break;
4597
		break;
4767
	}
4598
	}
4768
 
4599
 
4769
	return check;
4600
	return check;
4770
}
4601
}
4771
 
4602
 
4772
int CPackages::findLastTextFile(int start, const Utils::String& dir) const
4603
int CPackages::findLastTextFile(int start, const Utils::String& dir) const
4773
{
4604
{
Line 4777... Line 4608...
4777
	int check = start;
4608
	int check = start;
4778
	while ( check < 9999 )
4609
	while ( check < 9999 )
4779
	{
4610
	{
4780
		++check;
4611
		++check;
4781
		Utils::String newFilename = SPK::FormatTextName(check, m_iLanguage, (m_iGameFlags & EXEFLAG_TCTEXT));
4612
		Utils::String newFilename = SPK::FormatTextName(check, m_iLanguage, (m_iGameFlags & EXEFLAG_TCTEXT));
4782
 
4613
 
4783
		// check if a packed file exists
4614
		// check if a packed file exists
4784
		if ( !Dir.exists(newFilename + ".pck") )
4615
		if ( !Dir.exists(newFilename + ".pck") )
4785
		{
4616
		{
4786
			// it doen't, check if theres an unpacked file
4617
			// it doen't, check if theres an unpacked file
4787
			if ( !Dir.exists(newFilename + ".xml") )
4618
			if ( !Dir.exists(newFilename + ".xml") )
4788
				break;
4619
				break;
4789
		}
4620
		}
4790
	}
4621
	}
4791
 
4622
 
4792
	return check;
4623
	return check;
4793
}
4624
}
4794
 
4625
 
4795
/**
4626
/**
4796
 * Read game language
4627
 * Read game language
4797
 *
4628
 *
4798
 * Reads the lang.dat file from the game directory for the language id
4629
 * Reads the lang.dat file from the game directory for the language id
4799
 */
4630
 */
4800
void CPackages::ReadGameLanguage(bool force)
4631
void CPackages::ReadGameLanguage(bool force)
Line 4818... Line 4649...
4818
			Utils::String str(data);
4649
			Utils::String str(data);
4819
			m_iLanguage = str.token("\n", 1).token(" ", 1).toInt();
4650
			m_iLanguage = str.token("\n", 1).token(" ", 1).toInt();
4820
		}
4651
		}
4821
	}
4652
	}
4822
}
4653
}
4823
 
4654
 
4824
/**
4655
/**
4825
 * Create Language Text File
4656
 * Create Language Text File
4826
 *
4657
 *
4827
 * Creates text files for all packages into the correct language
4658
 * Creates text files for all packages into the correct language
4828
 */
4659
 */
Line 4832... Line 4663...
4832
	if ( !m_iLanguage )
4663
	if ( !m_iLanguage )
4833
		return;
4664
		return;
4834
 
4665
 
4835
	// find all text files
4666
	// find all text files
4836
	Utils::CStringList ids;
4667
	Utils::CStringList ids;
4837
 
4668
 
4838
	for ( CListNode<C_File> *node = m_lFiles.Front(); node; node = node->next() )
4669
	for ( CListNode<C_File> *node = m_lFiles.Front(); node; node = node->next() )
4839
	{
4670
	{
4840
		C_File *f = node->Data();
4671
		C_File *f = node->Data();
4841
		// only do text fiels
4672
		// only do text fiels
4842
		if ( f->GetFileType() != FILETYPE_TEXT )
4673
		if ( f->GetFileType() != FILETYPE_TEXT )
4843
			continue;
4674
			continue;
4844
 
4675
 
4845
		Utils::String id, lang;
4676
		Utils::String id, lang;
4846
		if ( m_iGameFlags & EXEFLAG_TCTEXT )
4677
		if ( m_iGameFlags & EXEFLAG_TCTEXT )
4847
		{
4678
		{
4848
			id = f->baseName().token("-", 1);
4679
			id = f->baseName().token("-", 1);
4849
			lang = f->baseName().token("-", 2);
4680
			lang = f->baseName().token("-", 2);
4850
			if ( lang.empty() )
4681
			if ( lang.empty() )
4851
				lang = "NULL";
4682
				lang = "NULL";
4852
			else
4683
			else
4853
				lang = lang.erase(0, 1);  // remove the "L"
4684
				lang = lang.erase(0, 1);  // remove the "L"
4854
		}
4685
		}
4855
		else
4686
		else
4856
		{
4687
		{
4857
			lang = Utils::String::PadNumber(f->baseName().left((int)f->baseName().length() - 4), 3);
4688
			lang = Utils::String::PadNumber(f->baseName().left((int)f->baseName().length() - 4), 3);
4858
			id = f->baseName().mid(((int)f->baseName().length() - 4) + 1, 4);
4689
			id = f->baseName().mid(((int)f->baseName().length() - 4) + 1, 4);
4859
		}
4690
		}
4860
 
4691
 
4861
 
4692
 
4862
		// not added, add a new one
4693
		// not added, add a new one
4863
		if (!ids.contains(id))
4694
		if (!ids.contains(id))
4864
			ids.pushBack(id, lang);
4695
			ids.pushBack(id, lang);
4865
		else
4696
		else
4866
		{
4697
		{
Line 4891... Line 4722...
4891
		bool found = false;
4722
		bool found = false;
4892
		for ( int i = 0; i < size; i++ )
4723
		for ( int i = 0; i < size; i++ )
4893
		{
4724
		{
4894
			if ( data[i] == "NULL" )
4725
			if ( data[i] == "NULL" )
4895
				useId = -1;
4726
				useId = -1;
4896
			else
4727
			else
4897
			{
4728
			{
4898
				int num = data[i].toInt();
4729
				int num = data[i].toInt();
4899
				if ( num == m_iLanguage )
4730
				if ( num == m_iLanguage )
4900
				{
4731
				{
4901
					found = true;
4732
					found = true;
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();
5069
	remFileStr.findReplace(m_sCurrentDir, "");
4900
	remFileStr.findReplace(m_sCurrentDir, "");
5070
 
4901
 
5071
	if ( file->filePointer().contains("::")) {
4902
	if ( file->filePointer().contains("::")) {
5072
		CFileIO CatFile(file->filePointer().token("::", 1));
4903
		CFileIO CatFile(file->filePointer().token("::", 1));
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();