y//this file is part of NeoMule
//Copyright (C)2006 David Xanatos ( Xanatos@Lycos.at / http://neomule.sourceforge.net )
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either
//version 2 of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

#include "stdafx.h"
#ifdef _DEBUG
#include "DebugHelpers.h"
#endif

#include <io.h>
#include "FilePreferences.h"
#include "Preferences.h"
#include "PartFile.h"
#include "SafeFile.h"
#include "Packets.h"
#include "emule.h"
#include "Log.h"
#include "emuledlg.h"
#include "Neo/Defaults.h"
#include "Neo/NeoOpCodes.h"
#include "Neo/Functions.h"
#include "KnownFileList.h"
#include "Neo/EMBackup.h" // NEO: NB - [NeoBackup]
#ifdef VOODOO // NEO: VOODOO - [UniversalPartfileInterface] -- Xanatos -->
#include "Neo/voodoo.h"
#endif // VOODOO // NEO: VOODOO END <-- Xanatos --

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

// NEO: FCFG - [FileConfiguration] -- Xanatos -->

#define KNOWNPREFS_MET_FILENAME	_T("KnownPrefs.met")

bool CPartFile::SaveNeoFile()
{
	CString strNeoFile(m_fullname);
	strNeoFile += PARTNEO_EXT;

	CString strTmpFile(strNeoFile);
	strTmpFile += PARTNEO_TMP_EXT;

	// save tweak to part.neo file
	CSafeBufferedFile file;
	CFileException fexp;
	if (!file.Open(strTmpFile, CFile::modeWrite|CFile::modeCreate|CFile::typeBinary|CFile::shareDenyWrite, &fexp)){
		CString strError;
		strError.Format(GetResString(IDS_X_ERR_SAVENEO), strNeoFile, GetFileName());
		TCHAR szError[MAX_CFEXP_ERRORMSG];
		if (fexp.GetErrorMessage(szError, ARRSIZE(szError))){
			strError += _T(" - ");
			strError += szError;
		}
		ModLogError(LOG_STATUSBAR, _T("%s"), strError);
		return false;
	}
	setvbuf(file.m_pStream, NULL, _IOFBF, 16384);

	try{
		//version
		file.WriteUInt8(NEOFILE_VERSION);

		/*
		* Save All Neo File settings here
		*/
		PartPrefs.SavePartPrefs(&file);
		KnownPrefs.SaveKnownPrefs(&file);

		// NEO: NPT - [NeoPartTraffic]
		if(statistic.HasTraffic() /* && thePrefs.UsePartTraffic()*/){
			file.WriteUInt8(TRAFFICFILE_VERSION);
			statistic.SaveTraffic(&file);
		}else
			file.WriteUInt8(NULL);
		// NEO: NPT END

		// NEO: XC - [ExtendedComments]
		if(HasComments() /* && thePrefs.UseSaveComments()*/){
			file.WriteUInt8(COMMENTSFILE_VERSION);
			SaveComments(&file);
		}else
			file.WriteUInt8(NULL);
		// NEO: XC END

		if (thePrefs.GetCommitFiles() >= 2 || (thePrefs.GetCommitFiles() >= 1 && !theApp.emuledlg->IsRunning())){
			file.Flush(); // flush file stream buffers to disk buffers
			if (_commit(_fileno(file.m_pStream)) != 0) // commit disk buffers to disk
				AfxThrowFileException(CFileException::hardIO, GetLastError(), file.GetFileName());
		}
		file.Close();
	}
	catch(CFileException* error){
		CString strError;
		strError.Format(GetResString(IDS_X_ERR_SAVENEO), strNeoFile, GetFileName());
		TCHAR szError[MAX_CFEXP_ERRORMSG];
		if (error->GetErrorMessage(szError, ARRSIZE(szError))){
			strError += _T(" - ");
			strError += szError;
		}
		ModLogError(LOG_STATUSBAR, _T("%s"), strError);
		error->Delete();

		// remove the partially written or otherwise damaged temporary file
		file.Abort(); // need to close the file before removing it. call 'Abort' instead of 'Close', just to avoid an ASSERT.
		(void)_tremove(strTmpFile);
		return false;
	}

	// after successfully writing the temporary part.neo file...
	if (_tremove(strNeoFile) != 0 && errno != ENOENT){
		if (thePrefs.GetVerbose())
			DebugLogError(_T("Failed to remove \"%s\" - %s"), strNeoFile, _tcserror(errno));
	}

	if (_trename(strTmpFile, strNeoFile) != 0){
		int iErrno = errno;
		if (thePrefs.GetVerbose())
			DebugLogError(_T("Failed to move temporary part.met.neo file \"%s\" to \"%s\" - %s"), strTmpFile, strNeoFile, _tcserror(iErrno));

		CString strError;
		strError.Format(GetResString(IDS_X_ERR_SAVENEO), strNeoFile, GetFileName());
		strError += _T(" - ");
		strError += strerror(iErrno);
		ModLogError(_T("%s"), strError);
		return false;
	}

	// create a backup of the successfully written part.met file
	CString BAKName(strNeoFile);
	BAKName.Append(PARTNEO_BAK_EXT);
	if (!::CopyFile(strNeoFile, BAKName, FALSE)){
		if (thePrefs.GetVerbose())
			DebugLogError(_T("Failed to create backup of %s (%s) - %s"), strNeoFile, GetFileName(), GetErrorMessage(GetLastError()));
	}

	return true;
}

bool CPartFile::LoadNeoFile()
{
	CString strNeoFile(m_fullname);
	strNeoFile += PARTNEO_EXT;

	uint8 version;
	
	// readfile tweaks form part.neo file
	CSafeBufferedFile file;
	CFileException fexpMet;
	if (!file.Open(strNeoFile, CFile::modeRead|CFile::osSequentialScan|CFile::typeBinary|CFile::shareDenyWrite, &fexpMet)){
		if (fexpMet.m_cause != CFileException::fileNotFound){
			CString strError;
			strError.Format(GetResString(IDS_X_ERR_OPENNEO), strNeoFile, _T(""));
			TCHAR szError[MAX_CFEXP_ERRORMSG];
			if (fexpMet.GetErrorMessage(szError, ARRSIZE(szError))){
				strError += _T(" - ");
				strError += szError;
			}
			ModLogError(LOG_STATUSBAR, _T("%s"), strError);
			theApp.BackupEngine->SetLastErrorState(EMB_ERROR_STATE_UNRECOVERABLE); // NEO: NB - [NeoBackup]
			return false;
		}
		theApp.BackupEngine->SetLastErrorState(EMB_ERROR_STATE_RECOVERABLE); // NEO: NB - [NeoBackup]
		return false;
	}
	setvbuf(file.m_pStream, NULL, _IOFBF, 16384);

	try{
		version = file.ReadUInt8();
		
		if (version > NEOFILE_VERSION || version <= NEOFILE_VERSION_OLD){
			ModLogError(LOG_STATUSBAR, GetResString(IDS_X_ERR_BADNEOVERSION), strNeoFile, GetFileName());
			file.Close();
			theApp.BackupEngine->SetLastErrorState(EMB_ERROR_STATE_RECOVERABLE); // NEO: NB - [NeoBackup]
			return false;
		}
		
		/*
		* Load All Neo File settings here
		*/
		PartPrefs.LoadPartPrefs(&file);
		KnownPrefs.LoadKnownPrefs(&file);

		// NEO: NPT - [NeoPartTraffic]
		uint8 TrafficVersion = file.ReadUInt8();
		if(TrafficVersion){
			if (TrafficVersion < TRAFFICFILE_VERSION_OLD || TrafficVersion > TRAFFICFILE_VERSION){
				ModLogError(LOG_STATUSBAR, GetResString(IDS_X_ERR_TRAFFICMET_NEO_UNKNOWN_VERSION), strNeoFile, GetFileName());
				file.Close();
				theApp.BackupEngine->SetLastErrorState(EMB_ERROR_STATE_RECOVERABLE); // NEO: NB - [NeoBackup]
				return false;
			}
			if(version < TRAFFICFILE_VERSION_400) // X! backwards compatybility
				statistic.LoadOldTraffic(&file);
			else
				statistic.LoadTraffic(&file);
		}
		// NEO: NPT END

		// NEO: XC - [ExtendedComments]
		uint8 CommentsVersion = file.ReadUInt8();
		if(CommentsVersion){
			if (CommentsVersion < COMMENTSFILE_VERSION_OLD || CommentsVersion > COMMENTSFILE_VERSION){
				ModLogError(LOG_STATUSBAR, GetResString(IDS_X_ERR_COMMENTSMET_NEO_UNKNOWN_VERSION), strNeoFile, GetFileName());
				file.Close();
				theApp.BackupEngine->SetLastErrorState(EMB_ERROR_STATE_RECOVERABLE); // NEO: NB - [NeoBackup]
				return false;
			}
			LoadComments(&file);
		}
		// NEO: XC END

		file.Close();
	}
	catch(CFileException* error){
		if (error->m_cause == CFileException::endOfFile){
			ModLogError(LOG_STATUSBAR, GetResString(IDS_X_ERR_NEOMEOCORRUPT), strNeoFile, GetFileName());
			theApp.BackupEngine->SetLastErrorState(EMB_ERROR_STATE_RECOVERABLE); // NEO: NB - [NeoBackup]
		}else{
			TCHAR buffer[MAX_CFEXP_ERRORMSG];
			error->GetErrorMessage(buffer,ARRSIZE(buffer));
			ModLogError(LOG_STATUSBAR, GetResString(IDS_X_ERR_FILEERROR), strNeoFile, GetFileName(), buffer);
			theApp.BackupEngine->SetLastErrorState(EMB_ERROR_STATE_UNRECOVERABLE); // NEO: NB - [NeoBackup]
		}
		error->Delete();
		return false;
	}
	catch(...){
		ModLogError(LOG_STATUSBAR, GetResString(IDS_ERR_METCORRUPT), strNeoFile, GetFileName());
		theApp.BackupEngine->SetLastErrorState(EMB_ERROR_STATE_UNRECOVERABLE); // NEO: NB - [NeoBackup]
		ASSERT(0);
		return false;
	}

	theApp.BackupEngine->SetLastErrorState(EMB_ERROR_STATE_CORRECT); // NEO: NB - [NeoBackup]
	return true;
}

bool CKnownFileList::LoadKnownPreferences()
{
	CString fullpath=thePrefs.GetConfigDir();
	fullpath.Append(KNOWNPREFS_MET_FILENAME);
	CSafeBufferedFile file;
	CFileException fexp;
	if (!file.Open(fullpath,CFile::modeRead|CFile::osSequentialScan|CFile::typeBinary|CFile::shareDenyWrite, &fexp)){
		if (fexp.m_cause != CFileException::fileNotFound){
			CString strError(_T("Failed to load ") KNOWNPREFS_MET_FILENAME _T(" file"));
			TCHAR szError[MAX_CFEXP_ERRORMSG];
			if (fexp.GetErrorMessage(szError, ARRSIZE(szError))){
				strError += _T(" - ");
				strError += szError;
			}
			ModLogError(LOG_STATUSBAR, _T("%s"), strError);
			theApp.BackupEngine->SetLastErrorState(EMB_ERROR_STATE_UNRECOVERABLE); // NEO: NB - [NeoBackup]
			return false;
		}
		theApp.BackupEngine->SetLastErrorState(EMB_ERROR_STATE_RECOVERABLE); // NEO: NB - [NeoBackup]
		return false;
	}
	setvbuf(file.m_pStream, NULL, _IOFBF, 16384);

	try {
		uint8 version = file.ReadUInt8();
		if (version > KNOWNPREFSFILE_VERSION || version <= KNOWNPREFSFILE_VERSION_OLD){
			ModLogError(LOG_STATUSBAR, GetResString(IDS_X_ERR_KNOWNPREFSMET_UNKNOWN_VERSION));
			file.Close();
			theApp.BackupEngine->SetLastErrorState(EMB_ERROR_STATE_RECOVERABLE); // NEO: NB - [NeoBackup]
			return false;
		}
		
		const uint32 dwExpired = time(NULL) - 1296000; // NEO: MKN - [MergeKnown]
		UINT RecordsNumber = file.ReadUInt32();
		uchar cur_hash[16];
		CKnownFile* cuf_file=NULL;
		for (UINT i = 0; i < RecordsNumber; i++) {
			file.ReadHash16(cur_hash);
			if((cuf_file = FindKnownFileByID(cur_hash)) != NULL){
				// NEO: MKN - [MergeKnown]
				if (cuf_file->GetLastSeen() < dwExpired){
					ModLogError(GetResString(IDS_X_ERR_KNOWNPREFSCLEANUP), cuf_file->GetFileName()); 
					ClearPreferencesEntry(&file);
					continue;
				}
				// NEO: MKN END
				if(!cuf_file->KnownPrefs.LoadKnownPrefs(&file)){
					ModLogError(GetResString(IDS_X_ERR_KNOWNPREFSMET_ENTRY_CORRUPT), cuf_file->GetFileName());
				}
			}else{
				ModLogError(GetResString(IDS_X_ERR_KNOWNPREFSASYNCHRONIZED), md4str(cur_hash)); 
				ClearPreferencesEntry(&file);
			}
		}
		file.Close();
	}
	catch(CFileException* error){
		if (error->m_cause == CFileException::endOfFile){
			ModLogError(LOG_STATUSBAR, GetResString(IDS_X_ERR_KNOWNPREFSMET_BAD));
			theApp.BackupEngine->SetLastErrorState(EMB_ERROR_STATE_RECOVERABLE); // NEO: NB - [NeoBackup]
		}else{
			TCHAR buffer[MAX_CFEXP_ERRORMSG];
			error->GetErrorMessage(buffer,MAX_CFEXP_ERRORMSG);
			ModLogError(LOG_STATUSBAR, GetResString(IDS_X_ERR_KNOWNPREFSMET_UNKNOWN),buffer);
			theApp.BackupEngine->SetLastErrorState(EMB_ERROR_STATE_UNRECOVERABLE); // NEO: NB - [NeoBackup]
		}
		error->Delete();
		return false;
	}

	theApp.BackupEngine->SetLastErrorState(EMB_ERROR_STATE_CORRECT); // NEO: NB - [NeoBackup]
	return true;
}

bool CKnownFileList::ClearPreferencesEntry(CFileDataIO* file)
{
	UINT tagcount = file->ReadUInt32();
	for (UINT j = 0; j < tagcount; j++){
		CTag* newtag = new CTag(file, false);
        delete newtag;
	}
	return true;
}

bool CKnownFileList::SaveKnownPreferences()
{
	if (thePrefs.GetLogFileSaving())
		AddDebugLogLine(false,_T("Saving KnownPrefs files list file \"%s\""), KNOWNPREFS_MET_FILENAME);
	CString fullpath=thePrefs.GetConfigDir();
	fullpath += KNOWNPREFS_MET_FILENAME;
	CSafeBufferedFile file;
	CFileException fexp;
	if (!file.Open(fullpath, CFile::modeWrite|CFile::modeCreate|CFile::typeBinary|CFile::shareDenyWrite, &fexp)){
		CString strError(_T("Failed to save ") KNOWNPREFS_MET_FILENAME _T(" file"));
		TCHAR szError[MAX_CFEXP_ERRORMSG];
		if (fexp.GetErrorMessage(szError, ARRSIZE(szError))){
			strError += _T(" - ");
			strError += szError;
		}
		ModLogError(LOG_STATUSBAR, _T("%s"), strError);
		return false;
	}
	setvbuf(file.m_pStream, NULL, _IOFBF, 16384);

	try{
		file.WriteUInt8(KNOWNPREFSFILE_VERSION);

		uint32 uTagCount = 0;
		ULONG uTagCountFilePos = (ULONG)file.GetPosition();
		file.WriteUInt32(uTagCount);

		POSITION pos = m_Files_map.GetStartPosition();
		while( pos != NULL )
		{
			CKnownFile* pFile;
			CCKey key;
			m_Files_map.GetNextAssoc( pos, key, pFile );
			if(pFile->KnownPrefs.HasPreferences()){
				file.WriteHash16(pFile->GetFileHash());
				pFile->KnownPrefs.SaveKnownPrefs(&file);
				uTagCount++;
			}
		}

		file.Seek(uTagCountFilePos, CFile::begin);
		file.WriteUInt32(uTagCount);
		file.Seek(0, CFile::end);

		if (thePrefs.GetCommitFiles() >= 2 || (thePrefs.GetCommitFiles() >= 1 && !theApp.emuledlg->IsRunning())){
			file.Flush(); // flush file stream buffers to disk buffers
			if (_commit(_fileno(file.m_pStream)) != 0) // commit disk buffers to disk
				AfxThrowFileException(CFileException::hardIO, GetLastError(), file.GetFileName());
		}
		file.Close();
	}
	catch(CFileException* error){
		CString strError(_T("Failed to save ") KNOWNPREFS_MET_FILENAME _T(" file"));
		TCHAR szError[MAX_CFEXP_ERRORMSG];
		if (error->GetErrorMessage(szError, ARRSIZE(szError))){
			strError += _T(" - ");
			strError += szError;
		}
		ModLogError(LOG_STATUSBAR, _T("%s"), strError);
		error->Delete();
	}

	return true;
}


CKnownPreferences::CKnownPreferences(){
	KnownFile = NULL;

	ResetTweaks();
}

void CKnownPreferences::ResetTweaks(){
	// NEO: IPS - [InteligentPartSharing]
	m_iMaxProzentToHide = 0;

	m_iHideOverAvaliblyParts = 0;
	m_iHideOverAvaliblyMode = 0;
	m_fHideOverAvaliblyValue = 0;
	m_iHideOverAvaliblyCatch = 0;

	m_iHideOverSharedParts = 0;
	m_iHideOverSharedMode = 0;
	m_fHideOverSharedValue = 0;
	m_iHideOverSharedCalc = 0;
	
	m_iDontHideUnderAvaliblyParts = 0;
	m_iDontHideUnderAvaliblyMode = 0;
	m_fDontHideUnderAvaliblyValue = 0;

	m_iBlockHighOverAvaliblyParts = 0;
	m_fBlockHighOverAvaliblyFactor = 0;

	m_iBlockHighOverSharedParts = 0;
	m_fBlockHighOverSharedFactor = 0;

	m_iShowAlwaysNeeded = 0;
	m_iShowAlwaysParts = 0;

	m_iShowAlwaysIncomplete = 0;
	// NEO: IPS END

	// NEO: RT - [ReleaseTweaks]
	m_iReleaseLevel = 0;
	m_iReleaseMode = 0;

	m_iReleaseLimitMode = 0;
	m_iReleaseLimitUnion = 0;
	m_iReleaseLimitCompleteMode = 0;

	m_iReleaseLimit = 0;
	m_iReleaseLimitHigh = 0;
	m_iReleaseLimitLow = 0;

	m_iReleaseLimitComplete = 0;
	m_iReleaseLimitCompleteHigh = 0;
	m_iReleaseLimitCompleteLow = 0;

	m_iLimitUnion = 0;

	m_iSourceLimitMode = 0;
	m_iSourceLimitUnion = 0;
	m_iSourceLimitCompleteMode = 0;

	m_iSourceLimit = 0;
	m_iSourceLimitHigh = 0;
	m_iSourceLimitLow = 0;

	m_iSourceLimitComplete = 0;
	m_iSourceLimitCompleteHigh = 0;
	m_iSourceLimitCompleteLow = 0;

	m_iReleaseDisableNeedComplete = 0;
	// NEO: RT END

	// NEO: RP - [RestrictivPublishing]
#ifdef LANCAST // NEO: NLC - [NeoLanCast]
	m_bDisableSendLAN = false;
#endif //LANCAST // NEO: NLC END
#ifdef VOODOO // NEO: VOODOO - [UniversalPartfileInterface]
	m_bDisableVoodoo = false;
#endif // VOODOO
	// NEO: RP END

	// NEO: NST - [NeoSourceTweaks]
	m_iXSAnswerLimit = 0;
	m_bEnableSendXS = false;
	// NEO: NST END

	// NEO: NCAP - [NeoCustomAutoPriority]
	m_iDynamicAutoUpPriority = 0;
	m_fDynamicUpPriorityFactor = 0;
	m_iLowUpPrioThreshold = 0;
	m_iHighUpPrioThreshold = 0;
	// NEO: NCAP END

	m_ManagedParts.RemoveAll();// NEO: MCS - [ManualChunkSelection]
}

CKnownPreferences::~CKnownPreferences(){
	ClearTags();
}

bool CKnownPreferences::HasPreferences(){
	return (
		// NEO: IPS - [InteligentPartSharing]
		m_iMaxProzentToHide ||

		m_iHideOverAvaliblyParts ||
		m_iHideOverAvaliblyMode ||
		m_fHideOverAvaliblyValue ||
		m_iHideOverAvaliblyCatch ||

		m_iHideOverSharedParts ||
		m_iHideOverSharedMode ||
		m_fHideOverSharedValue ||
		m_iHideOverSharedCalc ||
	
		m_iDontHideUnderAvaliblyParts ||
		m_iDontHideUnderAvaliblyMode ||
		m_fDontHideUnderAvaliblyValue ||

		m_iBlockHighOverAvaliblyParts ||
		m_fBlockHighOverAvaliblyFactor ||

		m_iBlockHighOverSharedParts ||
		m_fBlockHighOverSharedFactor ||

		m_iShowAlwaysNeeded ||
		m_iShowAlwaysParts ||

		m_iShowAlwaysIncomplete ||
		// NEO: IPS END
		// NEO: RT - [ReleaseTweaks]
		m_iReleaseLevel ||
		m_iReleaseMode ||

		m_iReleaseLimitMode ||
		m_iReleaseLimitUnion ||
		m_iReleaseLimitCompleteMode ||

		m_iReleaseLimit ||
		m_iReleaseLimitHigh ||
		m_iReleaseLimitLow ||

		m_iLimitUnion ||

		m_iReleaseLimitComplete ||
		m_iReleaseLimitCompleteHigh ||
		m_iReleaseLimitCompleteLow ||

		m_iSourceLimitMode ||
		m_iSourceLimitUnion ||
		m_iSourceLimitCompleteMode ||

		m_iSourceLimit ||
		m_iSourceLimitHigh ||
		m_iSourceLimitLow ||

		m_iSourceLimitComplete ||
		m_iSourceLimitCompleteHigh ||
		m_iSourceLimitCompleteLow ||

		m_iReleaseDisableNeedComplete ||
		// NEO: RT END
		// NEO: RP - [RestrictivPublishing]
#ifdef LANCAST // NEO: NLC - [NeoLanCast]
		m_bDisableSendLAN || 
#endif //LANCAST // NEO: NLC END
#ifdef VOODOO // NEO: VOODOO - [UniversalPartfileInterface]
		m_bDisableVoodoo ||
#endif // VOODOO
		// NEO: RP END
		// NEO: NCAP - [NeoCustomAutoPriority]
		m_iDynamicAutoUpPriority || 
		m_fDynamicUpPriorityFactor || 
		m_iLowUpPrioThreshold || 
		m_iHighUpPrioThreshold ||
		// NEO: NCAP END
		// NEO: NST - [NeoSourceTweaks]
		m_iXSAnswerLimit ||
		m_bEnableSendXS ||
		// NEO: NST END
		HasManagedParts()
		);
}

bool CKnownPreferences::SaveKnownPrefs(CFileDataIO* file)
{
	UINT uTagCount = 0;
	ULONG uTagCountFilePos = (ULONG)file->GetPosition();
	file->WriteUInt32(uTagCount);

	// NEO: IPS - [InteligentPartSharing]
	if (m_iMaxProzentToHide){
		CTag tag(NFT_IPS_MAXIMUM, m_iMaxProzentToHide);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	if (m_iHideOverAvaliblyParts){
		CTag tag(NFT_IPS_HIDE_OA, m_iHideOverAvaliblyParts);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iHideOverAvaliblyMode){
		CTag tag(NFT_IPS_OA_MODE, m_iHideOverAvaliblyMode);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_fHideOverAvaliblyValue){
		CED2KTag tag(NFT_IPS_OA_VALUE, m_fHideOverAvaliblyValue);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iHideOverAvaliblyCatch){
		CTag tag(NFT_IPS_OA_CATCH, m_iHideOverAvaliblyCatch);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	if (m_iHideOverSharedParts){
		CTag tag(NFT_IPS_HIDE_OS, m_iHideOverSharedParts);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iHideOverSharedMode){
		CTag tag(NFT_IPS_OS_MODE, m_iHideOverSharedMode);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_fHideOverSharedValue){
		CED2KTag tag(NFT_IPS_OS_VALUE, m_fHideOverSharedValue);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iHideOverSharedCalc){
		CTag tag(NFT_IPS_OS_CALC, m_iHideOverSharedCalc);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	
	if (m_iDontHideUnderAvaliblyParts){
		CTag tag(NFT_IPS_SHOW_UA, m_iDontHideUnderAvaliblyParts);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iDontHideUnderAvaliblyMode){
		CTag tag(NFT_IPS_UA_MODE, m_iDontHideUnderAvaliblyMode);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_fDontHideUnderAvaliblyValue){
		CED2KTag tag(NFT_IPS_UA_VALUE, m_fDontHideUnderAvaliblyValue);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	if (m_iBlockHighOverAvaliblyParts){
		CTag tag(NFT_IPS_BLOCK_OA, m_iBlockHighOverAvaliblyParts);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_fBlockHighOverAvaliblyFactor){
		CED2KTag tag(NFT_IPS_OA_FACTOR, m_fBlockHighOverAvaliblyFactor);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	if (m_iBlockHighOverSharedParts){
		CTag tag(NFT_IPS_BLOCK_OS, m_iBlockHighOverSharedParts);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_fBlockHighOverSharedFactor){
		CED2KTag tag(NFT_IPS_OS_FACTOR, m_fBlockHighOverSharedFactor);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	if (m_iShowAlwaysNeeded){
		CTag tag(NFT_IPS_SHOW_ALWAYS_NEEDED, m_iShowAlwaysNeeded);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iShowAlwaysParts){
		CTag tag(NFT_IPS_SHOW_ALWAYS_PARTS, m_iShowAlwaysParts);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	if (m_iShowAlwaysIncomplete){
		CTag tag(NFT_IPS_SHOW_ALWAYS_INCOMPLETE, m_iShowAlwaysIncomplete);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	// NEO: IPS END

	// NEO: RT - [ReleaseTweaks]
	if (m_iReleaseLevel){
		CTag tag(NFT_RELEASE_LEVEL, m_iReleaseLevel);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iReleaseMode){
		CTag tag(NFT_RELEASE_MODE, m_iReleaseMode);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	if (m_iReleaseLimitMode){
		CTag tag(NFT_RELEASE_LIMIT_MODE, m_iReleaseLimitMode);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iReleaseLimitUnion){
		CTag tag(NFT_RELEASE_LIMIT_UNION, m_iReleaseLimitUnion);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iReleaseLimitCompleteMode){
		CTag tag(NFT_RELEASE_LIMIT_COMPLETE_MODE, m_iReleaseLimitCompleteMode);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	if (m_iReleaseLimit){
		CTag tag(NFT_RELEASE_LIMIT, m_iReleaseLimit);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iReleaseLimitHigh){
		CTag tag(NFT_RELEASE_LIMIT_HIGH, m_iReleaseLimitHigh);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iReleaseLimitLow){
		CTag tag(NFT_RELEASE_LIMIT_LOW, m_iReleaseLimitLow);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	if (m_iReleaseLimitComplete){
		CTag tag(NFT_RELEASE_LIMIT_COMPLETE, m_iReleaseLimitComplete);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iReleaseLimitCompleteHigh){
		CTag tag(NFT_RELEASE_LIMIT_COMPLETE_HIGH, m_iReleaseLimitCompleteHigh);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iReleaseLimitCompleteLow){
		CTag tag(NFT_RELEASE_LIMIT_COMPLETE_LOW, m_iReleaseLimitCompleteLow);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	if (m_iLimitUnion){
		CTag tag(NFT_LIMIT_UNION, m_iLimitUnion);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	if (m_iSourceLimitMode){
		CTag tag(NFT_SOURCE_LIMIT_MODE, m_iSourceLimitMode);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iSourceLimitUnion){
		CTag tag(NFT_SOURCE_LIMIT_UNION, m_iSourceLimitUnion);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iSourceLimitCompleteMode){
		CTag tag(NFT_SOURCE_LIMIT_COMPLETE_MODE, m_iSourceLimitCompleteMode);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	if (m_iSourceLimit){
		CTag tag(NFT_SOURCE_LIMIT, m_iSourceLimit);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iSourceLimitHigh){
		CTag tag(NFT_SOURCE_LIMIT_HIGH, m_iSourceLimitHigh);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iSourceLimitLow){
		CTag tag(NFT_SOURCE_LIMIT_LOW, m_iSourceLimitLow);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	if (m_iSourceLimitComplete){
		CTag tag(NFT_SOURCE_COMPLETE_LIMIT, m_iSourceLimitComplete);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iSourceLimitCompleteHigh){
		CTag tag(NFT_SOURCE_COMPLETE_LIMIT_HIGH, m_iSourceLimitCompleteHigh);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iSourceLimitCompleteLow){
		CTag tag(NFT_SOURCE_COMPLETE_LIMIT_LOW, m_iSourceLimitCompleteLow);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	if (m_iReleaseDisableNeedComplete){
		CTag tag(NFT_RELEASE_DISABLE_NEED_COMPLETE, m_iReleaseDisableNeedComplete);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	// NEO: RT END

	// NEO: RP - [RestrictivPublishing]
#ifdef LANCAST // NEO: NLC - [NeoLanCast]
	if (m_bDisableSendLAN){
		CTag tag(NFT_DISABLE_SEND_LAN, m_bDisableSendLAN ? TRUE : FALSE);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
#endif //LANCAST // NEO: NLC END
#ifdef VOODOO // NEO: VOODOO - [UniversalPartfileInterface]
	if (m_bDisableVoodoo){
		CTag tag(NFT_DISABLE_VOODOO, m_bDisableVoodoo);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
#endif // VOODOO
	// NEO: RP END

	// NEO: NCAP - [NeoCustomAutoPriority]
	if (m_iDynamicAutoUpPriority){
		CTag tag(NFT_DYNAMIC_AUTO_UP_PRIORITY, m_iDynamicAutoUpPriority);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_fDynamicUpPriorityFactor){
		CED2KTag tag(NFT_DYNAMIC_UP_PRIORITY_FACTOR, m_fDynamicUpPriorityFactor);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iLowUpPrioThreshold){
		CTag tag(NFT_LOW_UP_PRIO_THRESHOLD, m_iLowUpPrioThreshold);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iHighUpPrioThreshold){
		CTag tag(NFT_HIGH_UP_PRIO_THRESHOLD, m_iHighUpPrioThreshold);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	// NEO: NCAP END

	// NEO: NST - [NeoSourceTweaks]
	if (m_iXSAnswerLimit){
		CTag tag(NFT_XS_ANSWER_LIMIT, m_iXSAnswerLimit);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_bEnableSendXS){
		CTag tag(NFT_ENABLE_SEND_XS, m_bEnableSendXS);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	// NEO: NST END

	// NEO: MPS - [ManualPartSharing]
	if(HasManagedParts())
		for(uint16 part = 0; part < KnownFile->GetPartCount(); part++){
			uint8 status = GetManagedPart(part);
			if(status != PR_PART_NORMAL){
				uint8 TagID;
				switch(status){
				case PR_PART_ON: TagID = NFT_PR_PART_ON; break;
				case PR_PART_HIDEN: TagID = NFT_PR_PART_HIDEN; break;
				case PR_PART_OFF: TagID = NFT_PR_PART_OFF; break;
				default: ASSERT(0); TagID = NFT_PR_PART_NORMAL;
				}
				CTag tag(TagID, part);
				tag.WriteNewEd2kTag(file);
				uTagCount++;
			}
		}
	// NEO: MPS END

	for (int j = 0; j < taglist.GetCount(); j++){
		if (taglist[j]->IsStr() || taglist[j]->IsInt()){
			taglist[j]->WriteNewEd2kTag(file);
			uTagCount++;
		}
	}

	file->Seek(uTagCountFilePos, CFile::begin);
	file->WriteUInt32(uTagCount);
	file->Seek(0, CFile::end);

	return true;
}

void CKnownPreferences::ClearTags()
{
	for (int i = 0; i < taglist.GetSize(); i++)
		delete taglist[i];
	taglist.RemoveAll();
}

bool CKnownPreferences::LoadKnownPrefs(CFileDataIO* file)
{
	UINT tagcount = file->ReadUInt32();
	for (UINT j = 0; j < tagcount; j++){
		CTag* newtag = new CTag(file, false);
		switch (newtag->GetNameID()){
			// NEO: IPS - [InteligentPartSharing]
			case NFT_IPS_MAXIMUM:{
                ASSERT( newtag->IsInt() );
                m_iMaxProzentToHide = newtag->GetInt();
                delete newtag;
                break;
            }

			case NFT_IPS_HIDE_OA:{
                ASSERT( newtag->IsInt() );
                m_iHideOverAvaliblyParts = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_IPS_OA_MODE:{
                ASSERT( newtag->IsInt() );
                m_iHideOverAvaliblyMode = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_IPS_OA_VALUE:{
                ASSERT( newtag->IsFloat() );
                m_fHideOverAvaliblyValue = newtag->GetFloat();
                delete newtag;
                break;
            }
			case NFT_IPS_OA_CATCH:{
                ASSERT( newtag->IsInt() );
                m_iHideOverAvaliblyCatch = newtag->GetInt();
                delete newtag;
                break;
            }

			case NFT_IPS_HIDE_OS:{
                ASSERT( newtag->IsInt() );
                m_iHideOverSharedParts = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_IPS_OS_MODE:{
                ASSERT( newtag->IsInt() );
                m_iHideOverSharedMode = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_IPS_OS_VALUE:{
                ASSERT( newtag->IsFloat() );
                m_fHideOverSharedValue = newtag->GetFloat();
                delete newtag;
                break;
            }
			case NFT_IPS_OS_CALC:{
                ASSERT( newtag->IsInt() );
                m_iHideOverSharedCalc = newtag->GetInt();
                delete newtag;
                break;
            }

			case NFT_IPS_SHOW_UA:{
                ASSERT( newtag->IsInt() );
                m_iDontHideUnderAvaliblyParts = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_IPS_UA_MODE:{
                ASSERT( newtag->IsInt() );
                m_iDontHideUnderAvaliblyMode = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_IPS_UA_VALUE:{
                ASSERT( newtag->IsFloat() );
                m_fDontHideUnderAvaliblyValue = newtag->GetFloat();
                delete newtag;
                break;
            }

			case NFT_IPS_BLOCK_OA:{
                ASSERT( newtag->IsInt() );
                m_iBlockHighOverAvaliblyParts = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_IPS_OA_FACTOR:{
                ASSERT( newtag->IsFloat() );
                m_fBlockHighOverAvaliblyFactor = newtag->GetFloat();
                delete newtag;
                break;
            }

			case NFT_IPS_BLOCK_OS:{
                ASSERT( newtag->IsInt() );
                m_iBlockHighOverSharedParts = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_IPS_OS_FACTOR:{
                ASSERT( newtag->IsFloat() );
                m_fBlockHighOverSharedFactor = newtag->GetFloat();
                delete newtag;
                break;
            }

			case NFT_IPS_SHOW_ALWAYS_NEEDED:{
                ASSERT( newtag->IsInt() );
                m_iShowAlwaysNeeded = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_IPS_SHOW_ALWAYS_PARTS:{
                ASSERT( newtag->IsInt() );
                m_iShowAlwaysParts = newtag->GetInt();
                delete newtag;
                break;
            }

			case NFT_IPS_SHOW_ALWAYS_INCOMPLETE:{
                ASSERT( newtag->IsInt() );
                m_iShowAlwaysIncomplete = newtag->GetInt();
                delete newtag;
                break;
            }
			// NEO: IPS END

			// NEO: RT - [ReleaseTweaks]
			case NFT_RELEASE_LEVEL:{
                ASSERT( newtag->IsInt() );
                m_iReleaseLevel = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_RELEASE_MODE:{
                ASSERT( newtag->IsInt() );
                m_iReleaseMode = newtag->GetInt();
                delete newtag;
                break;
            }

			case NFT_RELEASE_LIMIT_MODE:{
                ASSERT( newtag->IsInt() );
                m_iReleaseLimitMode = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_RELEASE_LIMIT_UNION:{
                ASSERT( newtag->IsInt() );
                m_iReleaseLimitUnion= newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_RELEASE_LIMIT_COMPLETE_MODE:{
                ASSERT( newtag->IsInt() );
                m_iReleaseLimitCompleteMode = newtag->GetInt();
                delete newtag;
                break;
            }

			case NFT_RELEASE_LIMIT:{
                ASSERT( newtag->IsInt() );
                m_iReleaseLimit = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_RELEASE_LIMIT_HIGH:{
                ASSERT( newtag->IsInt() );
                m_iReleaseLimitHigh = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_RELEASE_LIMIT_LOW:{
                ASSERT( newtag->IsInt() );
                m_iReleaseLimitLow = newtag->GetInt();
                delete newtag;
                break;
            }

			case NFT_RELEASE_LIMIT_COMPLETE:{
                ASSERT( newtag->IsInt() );
                m_iReleaseLimitComplete = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_RELEASE_LIMIT_COMPLETE_HIGH:{
                ASSERT( newtag->IsInt() );
                m_iReleaseLimitCompleteHigh = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_RELEASE_LIMIT_COMPLETE_LOW:{
                ASSERT( newtag->IsInt() );
                m_iReleaseLimitCompleteLow = newtag->GetInt();
                delete newtag;
                break;
            }

			case NFT_LIMIT_UNION:{
                ASSERT( newtag->IsInt() );
                m_iLimitUnion= newtag->GetInt();
                delete newtag;
                break;
            }

			case NFT_SOURCE_LIMIT_MODE:{
                ASSERT( newtag->IsInt() );
                m_iSourceLimitMode = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_SOURCE_LIMIT_UNION:{
                ASSERT( newtag->IsInt() );
                m_iSourceLimitUnion= newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_SOURCE_LIMIT_COMPLETE_MODE:{
                ASSERT( newtag->IsInt() );
                m_iSourceLimitCompleteMode = newtag->GetInt();
                delete newtag;
                break;
            }

			case NFT_SOURCE_LIMIT:{
                ASSERT( newtag->IsInt() );
                m_iSourceLimit = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_SOURCE_LIMIT_HIGH:{
                ASSERT( newtag->IsInt() );
                m_iSourceLimitHigh = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_SOURCE_LIMIT_LOW:{
                ASSERT( newtag->IsInt() );
                m_iSourceLimitLow = newtag->GetInt();
                delete newtag;
                break;
            }

			case NFT_SOURCE_COMPLETE_LIMIT:{
                ASSERT( newtag->IsInt() );
                m_iSourceLimitComplete = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_SOURCE_COMPLETE_LIMIT_HIGH:{
                ASSERT( newtag->IsInt() );
                m_iSourceLimitCompleteHigh = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_SOURCE_COMPLETE_LIMIT_LOW:{
                ASSERT( newtag->IsInt() );
                m_iSourceLimitCompleteLow = newtag->GetInt();
                delete newtag;
                break;
            }

			case NFT_RELEASE_DISABLE_NEED_COMPLETE:{
                ASSERT( newtag->IsInt() );
                m_iReleaseDisableNeedComplete = newtag->GetInt();
                delete newtag;
                break;
            }
			// NEO: RT END

												   
			// NEO: RP - [RestrictivPublishing]
#ifdef LANCAST // NEO: NLC - [NeoLanCast]
			case NFT_DISABLE_SEND_LAN:{
                ASSERT( newtag->IsInt() );
				m_bDisableSendLAN = I2B(newtag->GetInt());
                delete newtag;
                break;
            }
#endif //LANCAST // NEO: NLC END
#ifdef VOODOO // NEO: VOODOO - [UniversalPartfileInterface]
			case NFT_DISABLE_VOODOO:{
                ASSERT( newtag->IsInt() );
				m_bDisableVoodoo = I2B(newtag->GetInt());
                delete newtag;
                break;
            }
#endif // VOODOO
			// NEO: RP END

			// NEO: NCAP - [NeoCustomAutoPriority]
			case NFT_DYNAMIC_AUTO_UP_PRIORITY:{
                ASSERT( newtag->IsInt() );
                m_iDynamicAutoUpPriority = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_DYNAMIC_UP_PRIORITY_FACTOR:{
                ASSERT( newtag->IsFloat() );
                m_fDynamicUpPriorityFactor = newtag->GetFloat();
                delete newtag;
                break;
            }
			case NFT_LOW_UP_PRIO_THRESHOLD:{
                ASSERT( newtag->IsInt() );
                m_iLowUpPrioThreshold = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_HIGH_UP_PRIO_THRESHOLD:{
                ASSERT( newtag->IsInt() );
                m_iHighUpPrioThreshold = newtag->GetInt();
                delete newtag;
                break;
            }
			// NEO: NCAP END

			// NEO: NST - [NeoSourceTweaks]
			case NFT_XS_ANSWER_LIMIT:{
                ASSERT( newtag->IsInt() );
                m_iXSAnswerLimit = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_ENABLE_SEND_XS:{
                ASSERT( newtag->IsInt() );
				m_bEnableSendXS = I2B(newtag->GetInt());
                delete newtag;
                break;
            }
			// NEO: NST END

			// NEO: MPS - [ManualPartSharing]
			case NFT_PR_PART_NORMAL:{
                ASSERT( newtag->IsInt() );
                delete newtag;
                break;
            }
			case NFT_PR_PART_ON:{
                ASSERT( newtag->IsInt() );
                SetManagedPart(newtag->GetInt(), PR_PART_ON);
                delete newtag;
                break;
            }
			case NFT_PR_PART_HIDEN:{
                ASSERT( newtag->IsInt() );
                SetManagedPart(newtag->GetInt(), PR_PART_HIDEN);
                delete newtag;
                break;
            }
			case NFT_PR_PART_OFF:{
                ASSERT( newtag->IsInt() );
                SetManagedPart(newtag->GetInt(), PR_PART_OFF);
                delete newtag;
                break;
            }
			// NEO: MPS END

			default:{
				taglist.Add(newtag);
			}
		}
	}

	CheckTweaks();

	KnownFile->SetReleaseModifyer((float)GetReleaseLevel()); // NEO: RT - [ReleaseTweaks]

	return true;
}

void CKnownPreferences::CheckTweaks(){
	// NEO: IPS - [InteligentPartSharing]
	if(m_iMaxProzentToHide) MinMax(&m_iMaxProzentToHide,VAL_IPS_MAX_MIN,VAL_IPS_MAX_MAX);

	if(m_fHideOverAvaliblyValue) MinMax(&m_fHideOverAvaliblyValue, m_iHideOverAvaliblyMode ? VAL_IPS_OA_MIN2 : VAL_IPS_OA_MIN1, m_iHideOverAvaliblyMode ? VAL_IPS_OA_MAX2 : VAL_IPS_OA_MAX1);
	if(m_fHideOverSharedValue) MinMax(&m_fHideOverSharedValue, m_iHideOverSharedMode ? VAL_IPS_OS_MIN2 : VAL_IPS_OS_MIN1, m_iHideOverSharedMode ? VAL_IPS_OS_MAX2 : VAL_IPS_OS_MAX1);

	if(m_fDontHideUnderAvaliblyValue) MinMax(&m_fDontHideUnderAvaliblyValue, m_iDontHideUnderAvaliblyMode ? VAL_IPS_UA_MIN2 : VAL_IPS_UA_MIN1, m_iDontHideUnderAvaliblyMode ? VAL_IPS_UA_MAX2 : VAL_IPS_UA_MAX1);

	if(m_fBlockHighOverAvaliblyFactor) MinMax(&m_fBlockHighOverAvaliblyFactor,VAL_IPS_OAF_MIN,VAL_IPS_OAF_MAX);
	if(m_fBlockHighOverSharedFactor) MinMax(&m_fBlockHighOverSharedFactor,VAL_IPS_OSF_MIN,VAL_IPS_OSF_MAX);

	if(m_iShowAlwaysParts) MinMax(&m_iShowAlwaysParts,VAL_SHOW_ALWAYS_PARTS_MIN,VAL_SHOW_ALWAYS_PARTS_MAX);
	// NEO: IPS END

	// NEO: RT - [ReleaseTweaks]
	if(m_iReleaseLevel) MinMax(&m_iReleaseLevel,VAL_RELEASE_LEVEL_MIN,VAL_RELEASE_LEVEL_MAX);
	if(m_iReleaseLimitHigh) MinMax(&m_iReleaseLimitHigh,VAL_RELEASE_LIMIT_MIN,VAL_RELEASE_LIMIT_MAX);
	if(m_iReleaseLimitLow) MinMax(&m_iReleaseLimitLow,VAL_RELEASE_LIMIT_MIN,VAL_RELEASE_LIMIT_MAX);
	if(m_iReleaseLimitLow) Minimal(&m_iReleaseLimitLow,m_iReleaseLimitHigh);
	if(m_iReleaseLimitCompleteHigh) MinMax(&m_iReleaseLimitCompleteHigh,VAL_RELEASE_CLIMIT_MIN,VAL_RELEASE_CLIMIT_MAX);
	if(m_iReleaseLimitCompleteLow) MinMax(&m_iReleaseLimitCompleteLow,VAL_RELEASE_CLIMIT_MIN,VAL_RELEASE_CLIMIT_MAX);
	if(m_iReleaseLimitCompleteLow) Minimal(&m_iReleaseLimitCompleteLow,m_iReleaseLimitCompleteHigh);
	if(m_iSourceLimitHigh) MinMax(&m_iSourceLimitHigh,VAL_SOURCE_LIMIT_MIN,VAL_SOURCE_LIMIT_MAX);
	if(m_iSourceLimitLow) MinMax(&m_iSourceLimitLow,VAL_SOURCE_LIMIT_MIN,VAL_SOURCE_LIMIT_MAX);
	if(m_iSourceLimitLow) Minimal(&m_iSourceLimitLow,m_iSourceLimitHigh);
	if(m_iSourceLimitCompleteHigh) MinMax(&m_iSourceLimitCompleteHigh,VAL_RELEASE_CLIMIT_MIN,VAL_RELEASE_CLIMIT_MAX);
	if(m_iSourceLimitCompleteLow) MinMax(&m_iSourceLimitCompleteLow,VAL_RELEASE_CLIMIT_MIN,VAL_RELEASE_CLIMIT_MAX);
	if(m_iSourceLimitCompleteLow) Minimal(&m_iSourceLimitCompleteLow,m_iSourceLimitCompleteHigh);
	// NEO: RT END

	// NEO: NCAP - [NeoCustomAutoPriority]
	if(m_iLowUpPrioThreshold) MinMax(&m_iLowUpPrioThreshold,VAL_LOW_UP_PRIO_THRESHOLD_MIN,VAL_LOW_UP_PRIO_THRESHOLD_MAX);
	if(m_iHighUpPrioThreshold) MinMax(&m_iHighUpPrioThreshold,VAL_HIGH_UP_PRIO_THRESHOLD_MIN,VAL_HIGH_UP_PRIO_THRESHOLD_MAX);
	if(m_iHighUpPrioThreshold) Maximal(&m_iHighUpPrioThreshold,m_iLowUpPrioThreshold);
	// NEO: NCAP END

	if(m_iXSAnswerLimit) MinMax(&m_iXSAnswerLimit,VAL_XS_ANSWER_LIMIT_MIN,VAL_XS_ANSWER_LIMIT_MAX); // NEO: NST - [NeoSourceTweaks]

#ifdef VOODOO // NEO: VOODOOn - [VoodooExtensionForNeo]
	if(thePrefs.IsVoodooNeoPreferences() && UseVoodoo())
		theApp.voodoo->ManifestFilePreferences(KnownFile);
#endif // VOODOO // NEO: VOODOOn END
}

// NEO: IPS - [InteligentPartSharing]
/* 
*     Global setting     File Setting
*     0 - Disable        0 - Default
*     1 - Enable KF	     1 - Enable
*     2 - Enable K/PF    2 - Disable
*     
*     for dan't hide
*     Global setting     File Setting
*     0 - Disable        0 - Default
*     1 - Enable PF	     1 - Enable
*     2 - Enable K/PF    2 - Disable
*/
bool CKnownPreferences::IsInteligentPartSharing(){
	if(!thePrefs.IsInteligentPartSharing())
		return false;
	return (IsHideOverAvaliblyParts() || IsHideOverSharedParts());
}
int CKnownPreferences::GetMaxProzentToHide(){
	return m_iMaxProzentToHide ? m_iMaxProzentToHide : thePrefs.GetMaxProzentToHide();
}

bool CKnownPreferences::IsHideOverAvaliblyParts(){
	if(m_iHideOverAvaliblyParts) 
		return m_iHideOverAvaliblyParts == 1 ? 1 : 0;

	int state = thePrefs.IsHideOverAvaliblyParts();
	if(state == 1)
		return !(KnownFile->IsPartFile());
	else if (state == 2)
		return true;
	else
		return false;
}
int CKnownPreferences::GetHideOverAvaliblyMode(){
	if(m_iHideOverAvaliblyMode) 
		return m_iHideOverAvaliblyMode == 1 ? 1 : 0;
	return thePrefs.GetHideOverAvaliblyMode();
}
float CKnownPreferences::GetHideOverAvaliblyValue(){
	return m_fHideOverAvaliblyValue ? m_fHideOverAvaliblyValue : thePrefs.GetHideOverAvaliblyValue();
}

// NEO: NPC - [NeoPartCatch]
int	CKnownPreferences::GetHideOverAvaliblyCatch(){
	if((m_iHideOverAvaliblyCatch == 0 && thePrefs.UseRealPartStatus() == 1 && thePrefs.UseAntiHideOS() == 1) 
	 || (m_iHideOverAvaliblyCatch == 2 && thePrefs.UseRealPartStatus() && thePrefs.UseAntiHideOS()))
		return PART_CATCH_REAL_HIDEN;
	else if((m_iHideOverAvaliblyCatch == 0 && thePrefs.UseRealPartStatus() == 1) 
	 || (m_iHideOverAvaliblyCatch == 1 && thePrefs.UseRealPartStatus()))
		return PART_CATCH_REAL;
	else if((m_iHideOverAvaliblyCatch == 0 && thePrefs.UseAntiHideOS() == 1) 
	 || (m_iHideOverAvaliblyCatch == 3 && thePrefs.UseAntiHideOS())) 
		return PART_CATCH_HIDEN;
	else 
		return PART_CATCH_DISABLED;
}
// NEO: NPC END

bool CKnownPreferences::IsHideOverSharedParts(){
	if(!thePrefs.UsePartTraffic())
		return false;

	if(m_iHideOverSharedParts) 
		return m_iHideOverSharedParts == 1 ? 1 : 0;

	int state = thePrefs.IsHideOverSharedParts();
	if(state == 1)
		return !(KnownFile->IsPartFile());
	else if (state == 2)
		return true;
	else
		return false;
}
int CKnownPreferences::GetHideOverSharedMode(){
	if(m_iHideOverSharedMode) 
		return m_iHideOverSharedMode == 1 ? 1 : 0;
	return thePrefs.GetHideOverSharedMode();
}
float CKnownPreferences::GetHideOverSharedValue(){
	return m_fHideOverSharedValue ? m_fHideOverSharedValue : thePrefs.GetHideOverSharedValue();
}
int CKnownPreferences::GetHideOverSharedCalc(){
	if(m_iHideOverSharedCalc) 
		return m_iHideOverSharedCalc == 2 ? 1 : 0;
	return thePrefs.GetHideOverSharedCalc();
}

bool CKnownPreferences::IsDontHideUnderAvaliblyParts(){
	if(m_iDontHideUnderAvaliblyParts) 
		return m_iDontHideUnderAvaliblyParts == 1 ? 1 : 0;

	int state = thePrefs.IsDontHideUnderAvaliblyParts();
	if(state == 1)
		return I2B(KnownFile->IsPartFile());
	else if (state == 2)
		return true;
	else
		return false;
}
int CKnownPreferences::GetDontHideUnderAvaliblyMode(){
	if(m_iDontHideUnderAvaliblyMode) 
		return m_iDontHideUnderAvaliblyMode == 1 ? 1 : 0;
	return thePrefs.GetDontHideUnderAvaliblyMode();
}
 float CKnownPreferences::GetDontHideUnderAvaliblyValue(){
	return m_fDontHideUnderAvaliblyValue ? m_fDontHideUnderAvaliblyValue : thePrefs.GetDontHideUnderAvaliblyValue();
}

bool CKnownPreferences::IsBlockHighOverAvaliblyParts(){
	if(!IsHideOverAvaliblyParts())
		return false;

	if(m_iBlockHighOverAvaliblyParts) 
		return m_iBlockHighOverAvaliblyParts == 1 ? 1 : 0;

	int state = thePrefs.IsBlockHighOverAvaliblyParts();
	if(state == 1)
		return !(KnownFile->IsPartFile());
	else if (state == 2)
		return true;
	else
		return false;
}
float CKnownPreferences::GetBlockHighOverAvaliblyFactor(){
	return m_fBlockHighOverAvaliblyFactor ? m_fBlockHighOverAvaliblyFactor : thePrefs.GetBlockHighOverAvaliblyFactor();
}

bool CKnownPreferences::IsBlockHighOverSharedParts(){
	if(!IsHideOverSharedParts())
		return false;

	if(m_iBlockHighOverSharedParts) 
		return m_iBlockHighOverSharedParts == 1 ? 1 : 0;

	int state = thePrefs.IsBlockHighOverSharedParts();
	if(state == 1)
		return !(KnownFile->IsPartFile());
	else if (state == 2)
		return true;
	else
		return false;
}
float CKnownPreferences::GetBlockHighOverSharedFactor(){
	return m_fBlockHighOverSharedFactor ? m_fBlockHighOverSharedFactor : thePrefs.GetBlockHighOverSharedFactor();
}

bool CKnownPreferences::IsShowAlwaysNeeded(){
	if(m_iShowAlwaysNeeded) 
		return m_iShowAlwaysNeeded == 1 ? 1 : 0;

	int state = thePrefs.IsShowAlwaysNeeded();
	if(state == 1)
		return KnownFile->IsPartFile();
	else if (state == 2)
		return true;
	else
		return false;
}
int CKnownPreferences::GetShowAlwaysParts(){
	return m_iShowAlwaysParts ? m_iShowAlwaysParts : thePrefs.GetShowAlwaysParts();
}

bool CKnownPreferences::IsShowAlwaysIncomplete(){
	if(m_iShowAlwaysIncomplete) 
		return m_iShowAlwaysIncomplete == 1 ? 1 : 0;

	int state = thePrefs.IsShowAlwaysIncomplete();
	if(state == 1)
		return KnownFile->IsPartFile();
	else if (state == 2)
		return true;
	else
		return false;
}
// NEO: IPS END

// NEO: RT - [ReleaseTweaks]
int CKnownPreferences::GetReleaseLevel(){
	return m_iReleaseLevel ? m_iReleaseLevel : thePrefs.GetReleaseLevel();
}
int CKnownPreferences::GetReleaseMode(){
	if(m_iReleaseMode)
		return m_iReleaseMode-1; // X!
	return (thePrefs.GetReleaseMode()); // X!
}

int CKnownPreferences::GetReleaseLimitMode(){
	if(m_iReleaseLimitMode)
		return m_iReleaseLimitMode-1;
	return (thePrefs.GetReleaseLimitMode());
}
bool CKnownPreferences::IsReleaseLimitUnion(){
	if(m_iReleaseLimitUnion) 
		return m_iReleaseLimitUnion == 1 ? 1 : 0;
	return thePrefs.IsReleaseLimitUnion();
}
int CKnownPreferences::GetReleaseLimitCompleteMode(){
	if(m_iReleaseLimitCompleteMode)
		return m_iReleaseLimitCompleteMode-1;
	return (thePrefs.GetReleaseLimitCompleteMode());
}

int CKnownPreferences::IsReleaseLimit(){
	if(m_iReleaseLimit) 
		return m_iReleaseLimit == 3 ? 0 : m_iReleaseLimit;
	return thePrefs.IsReleaseLimit();
}
int CKnownPreferences::GetReleaseLimitHigh(){
	return m_iReleaseLimitHigh ? m_iReleaseLimitHigh : thePrefs.GetReleaseLimitHigh();
}
int CKnownPreferences::GetReleaseLimitLow(){
	return m_iReleaseLimitLow ? m_iReleaseLimitLow : thePrefs.GetReleaseLimitLow();
}

int CKnownPreferences::IsReleaseLimitComplete(){
	if(m_iReleaseLimitComplete) 
		return m_iReleaseLimitComplete == 3 ? 0 : m_iReleaseLimitComplete;
	return thePrefs.IsReleaseLimitComplete();
}
int CKnownPreferences::GetReleaseLimitCompleteHigh(){
	return m_iReleaseLimitCompleteHigh ? m_iReleaseLimitCompleteHigh : thePrefs.GetReleaseLimitCompleteHigh();
}
int CKnownPreferences::GetReleaseLimitCompleteLow(){
	return m_iReleaseLimitCompleteLow ? m_iReleaseLimitCompleteLow : thePrefs.GetReleaseLimitCompleteLow();
}

bool CKnownPreferences::IsLimitUnion(){
	if(m_iLimitUnion) 
		return m_iLimitUnion == 1 ? 1 : 0;
	return thePrefs.IsLimitUnion();
}

int CKnownPreferences::GetSourceLimitMode(){
	if(m_iSourceLimitMode)
		return m_iSourceLimitMode-1;
	return (thePrefs.GetSourceLimitMode());
}
bool CKnownPreferences::IsSourceLimitUnion(){
	if(m_iSourceLimitUnion) 
		return m_iSourceLimitUnion == 1 ? 1 : 0;
	return thePrefs.IsSourceLimitUnion();
}
int CKnownPreferences::GetSourceLimitCompleteMode(){
	if(m_iSourceLimitCompleteMode)
		return m_iSourceLimitCompleteMode-1;
	return (thePrefs.GetSourceLimitCompleteMode());
}

int CKnownPreferences::IsSourceLimit(){
	if(m_iSourceLimit) 
		return m_iSourceLimit == 3 ? 0 : m_iSourceLimit;
	return thePrefs.IsSourceLimit();
}
int CKnownPreferences::GetSourceLimitHigh(){
	return m_iSourceLimitHigh ? m_iSourceLimitHigh : thePrefs.GetSourceLimitHigh();
}
int CKnownPreferences::GetSourceLimitLow(){
	return m_iSourceLimitLow ? m_iSourceLimitLow : thePrefs.GetSourceLimitLow();
}

int CKnownPreferences::IsSourceLimitComplete(){
	if(m_iSourceLimitComplete) 
		return m_iSourceLimitComplete == 3 ? 0 : m_iSourceLimitComplete;
	return thePrefs.IsSourceLimitComplete();
}
int CKnownPreferences::GetSourceLimitCompleteHigh(){
	return m_iSourceLimitCompleteHigh ? m_iSourceLimitCompleteHigh : thePrefs.GetSourceLimitCompleteHigh();
}
int CKnownPreferences::GetSourceLimitCompleteLow(){
	return m_iSourceLimitCompleteLow ? m_iSourceLimitCompleteLow : thePrefs.GetSourceLimitCompleteLow();
}

bool CKnownPreferences::IsReleaseNeedComplete(){
	if(m_iReleaseDisableNeedComplete) 
		return false;
	return thePrefs.IsReleaseNeedComplete();
}
int	CKnownPreferences::GetReleaseNeedCompleteLimit(){
	return thePrefs.GetReleaseNeedCompleteLimit();
}
// NEO: RT END - [ReleaseTweaks]

// NEO: NCAP - [NeoCustomAutoPriority]
bool CKnownPreferences::UseDynamicAutoUpPriority(){
	if(m_iDynamicAutoUpPriority) 
		return m_iDynamicAutoUpPriority == 1 ? 1 : 0;
	return thePrefs.UseDynamicAutoUpPriority();
}
float CKnownPreferences::GetDynamicUpPriorityFactor(){
	return m_fDynamicUpPriorityFactor ? m_fDynamicUpPriorityFactor : thePrefs.GetDynamicUpPriorityFactor();
}
int CKnownPreferences::GetLowUpPrioThreshold(){
	return m_iLowUpPrioThreshold ? m_iLowUpPrioThreshold : thePrefs.GetLowUpPrioThreshold();
}
int CKnownPreferences::GetHighUpPrioThreshold(){
	return m_iHighUpPrioThreshold ? m_iHighUpPrioThreshold : thePrefs.GetHighUpPrioThreshold();
}
// NEO: NCAP END

// NEO: NST - [NeoSourceTweaks]
bool CKnownPreferences::SendXS(){
	// NEO: RP - [RestrictivPublishing]
	if(m_bEnableSendXS)
		return true;
	// NEO: RP END

	if(KnownFile->IsPartFile())
		return ((CPartFile*)KnownFile)->PartPrefs.UseXS();

	return !thePrefs.IsXSDisable();
}
int CKnownPreferences::GetXSAnswerLimit(){
	return m_iXSAnswerLimit ? m_iXSAnswerLimit : thePrefs.GetXSAnswerLimit();
}
// NEO: NST END

// NEO: RP - [RestrictivPublishing]
#ifdef LANCAST // NEO: NLC - [NeoLanCast]
bool CKnownPreferences::SendLAN(){
	if(KnownFile->IsPartFile())
		return ((CPartFile*)KnownFile)->PartPrefs.UseLAN();

	return !m_bDisableSendLAN;
}
#endif //LANCAST // NEO: NLC END
#ifdef VOODOO // NEO: VOODOO - [UniversalPartfileInterface]
bool CKnownPreferences::UseVoodoo(bool bTotal){
	if(!(bTotal ? thePrefs.IsVoodooEnabled() : thePrefs.UseVoodooTransfer()))
		return false;
	return !m_bDisableVoodoo;
}
#endif // VOODOO
// NEO: RP END

// NEO: MPS - [ManualPartSharing]
uint8  CKnownPreferences::GetManagedPart(UINT part) const 
{ 
	uint8 status = PR_PART_NORMAL; 
	if(m_ManagedParts.Lookup(part, status)) 
		return status; 
	else 
		return PR_PART_NORMAL; 
}

bool  CKnownPreferences::HasManagedParts() const
{
	POSITION	pos = m_ManagedParts.GetStartPosition();
	UINT		part;
	uint8		status;
	while(pos)
	{
		m_ManagedParts.GetNextAssoc(pos, part, status);
		if(status != PR_PART_NORMAL)
			return true;
	}
	return false;
}
// NEO: MPS END

// NEO: NPC - [NeoPartCatch]
int	CKnownPreferences::UsePartCatch(){
	if(thePrefs.UseRealPartStatus() && thePrefs.UseAntiHideOS())
		return PART_CATCH_REAL_HIDEN;
	else if(thePrefs.UseRealPartStatus())
		return PART_CATCH_REAL;
	else if(thePrefs.UseAntiHideOS())
		return PART_CATCH_HIDEN;
	else 
		return PART_CATCH_DISABLED;
}
// NEO: NPC END

/////////////////////
CPartPreferences::CPartPreferences(){
	PartFile = NULL;

	ResetTweaks();
}

void CPartPreferences::ResetTweaks()
{
	m_iChunkSelectionMode = 0;

	// NEO: RC4 - [RareChunksV4]
	m_iRareChunkV4Orde = 0;
	m_bRareChunkV4SameBlock = false;
	// NEO: RC4 END

	m_iSubChunkTransfer = 0; // NEO: SCT - [SubChunkTransfer]

	m_iPartCatch = 0; // NEO: NPC - [NeoPartCatch]

#ifdef A4AF_CATS // NEO: MAC - [MorphA4AFCategories]
	m_iA4AFFlags = 0;
#endif // A4AF_CATS // NEO: MAC END

	// NEO: NST - [NeoSourceTweaks]
	m_iHardLimit = 0;
	m_iSwapLimit = 0;
	m_iCleanUpLimit = 0;
	m_iCalcStandardLimits = 0;

	m_iXSState = 0;
	m_iXSLimit = 0;
	m_iXSIntervals = 0;
	m_iXSDelayValue = 0;

	m_iSVRState = 0;
	m_iSVRLimit = 0;
	m_iSVRIntervals = 0;

	m_iKADState = 0;
	m_iKADLimit = 0;
	m_iKADIntervals = 0;
	m_iKADDelayValue = 0;

	m_iUDPState = 0;
	m_iUDPLimit = 0;
	m_iUDPIntervals = 0;
	// NEO: NST END

#ifdef LANCAST // NEO: NLC - [NeoLanCast]
	m_bDisableLAN = false;
	m_iLANIntervals = 0;

	m_iLanReaskIntervals = 0;
	m_iNnPLanReaskIntervals = 0;
#endif //LANCAST // NEO: NLC END

	// NEO: NSD - [NeoSourceDrop]
	m_iLow2LowCleanUpTime = 0;
#if defined(NEO_SK) || defined(NEO_SS) // NEO: NSK - [NeoSourceKeeper] // NEO: NSS - [NeoSourceStorage]
	m_iBadCleanUpTime = 0;
	m_iGoneCleanUpTime = 0;
	m_iSuspendCleanUpTime = 0;
#endif // NEO_SK // NEO_SS // NEO: NSK END // NEO: NSS END
	m_iNnPCleanUpTime = 0;
	m_iFullQCleanUpTime = 0;
	// NEO: NSD END

	// NEO: ASL - [AutoSoftLock]
	m_iAutoSoftLock = 0;
	m_iAutoSoftLockValue = 0;
	// NEO: ASL END

	// NEO: AHL - [AutoHardLimit]
	m_iAutoHardLimit = 0;
	m_iMinimalHardLimit = 0;
	m_iAutoHardLimitTimer = 0;
	// NEO: AHL END

	// NEO: XSC - [ExtremeSourceCache]
	m_iSourceCache = 0;
	m_iSourceCacheLimit = 0;
	m_iSourceCacheTime = 0;
	// NEO: XSC END

	// NEO: DR - [DownloadReask]
	m_iReaskIntervals = 0;

	m_iNnPReask = 0;
	m_iNnPReaskIntervals = 0;

	m_iFullQReask = 0;
	m_iFullQReaskIntervals = 0;
	// NEO: DR END

#ifdef NEO_SK // NEO: NSK - [NeoSourceKeeper]
	m_iEnableSourceKeeper = 0;
#endif // NEO_SK // NEO: NSK END
#ifdef NEO_SS // NEO: NSS - [NeoSourceStorage]
	m_iEnableSourceStorage = 0;
	m_iAutoSaveSources = 0;
	m_iAutoSaveSourcesIntervals = 0;
	m_iSourceStorageLimit = 0;
	m_iAutoLoadStoredSources = 0;
	m_iUseStorageBootstrap = 0;
	m_iStorageBootstrapTime = 0;
	m_iStorageBootstrapRequirement = 0;
	m_iStoreLowIDSources = 0;
	m_iStoreAlsoA4AFSources = 0;
	m_iStoreSourcesFileStatus = 0;

	m_iAutoReaskStoredSources = 0;
	m_iAutoReaskStoredSourcesLimit = 0;
	m_iTotalSourceRestore = 0;
	m_iUseAutoReaskStoredSourcesDelay = 0;
	m_iAutoReaskStoredSourcesDelay = 0;

	m_iAutoReaskLoadedSourcesDelay = 0;

	m_iGroupStoredSourceReask = 0;
	m_iStoredSourceGroupIntervals = 0;
	m_iStoredSourceGroupSize = 0;

	m_iUseSmoothOutOfDate = 0;
	m_iMaxStoredFaildCount = 0;
	m_iStoredOutOfDate = 0;
#endif // NEO_SS // NEO: NSS END
#ifdef NEO_SA // NEO: NSA - [NeoSourceAnaliser]
	m_iEnableSourceAnalizer = 0;

	m_iDontStoreTemporarySources = 0;

	m_iPropabilityMode = 0;
	m_fEnhancedFactor = 0;

	m_iReaskPropability = 0;
	m_iReservePropability = 0;

	m_iAutoReserveReask = 0;
	m_iReserveReaskPropability = 0;
	m_iUseReaskReserveSourcesDelay = 0;
	m_iReaskReserveSourcesDelay = 0;
	m_iReaskReserveSourcesLimit = 0;

	m_iAutoTemporaryReask = 0;
	m_iTemporaryReaskPropability = 0;
	m_iUseReaskTemporarySourcesDelay = 0;
	m_iReaskTemporarySourcesDelay = 0;
	m_iReaskTemporarySourcesLimit = 0;

	//m_iMinAnalisisQuality = 0;

	//m_iAutoUnsureReask = 0;
	//m_iUseReaskUnsureSourcesDelay = 0;
	//m_iReaskUnsureSourcesDelay = 0;
	//m_iReaskUnsureSourcesLimit = 0;

	m_iUseUnpredictedPropability = 0;
	m_iUnpredictedPropability = 0;
	m_iUseReaskUnpredictedSourcesDelay = 0;
	m_iReaskUnpredictedSourcesDelay = 0;
	m_iReaskUnpredictedSourcesLimit = 0;

	m_iRetryUnreachable = 0;
	m_iRetryUnreachableIntervals = 0;
	m_iFailTolerance = 0;
	m_iMaxFailTolerance = 0;
	m_iUnreachableReaskPropability = 0;
	m_iReaskUnreachableSourcesLimit = 0;
#endif // NEO_SA // NEO: NSA END

	// NEO: DS - [DropSources]
	m_iDropNnP = 0;
	m_iDropNnPLimit = 0;
	m_iDropNnPLimitMode = 0;
	m_iDropNnPTimer = 0;

	m_iDropFullQ = 0;
	m_iDropFullQLimit = 0;
	m_iDropFullQLimitMode = 0;
	m_iDropFullQTimer = 0;

	m_iDropHighQ = 0;
	m_iDropHighQValue = 0;
	m_iDropHighQLimit = 0;
	m_iDropHighQLimitMode = 0;
	m_iDropHighQTimer = 0;

	m_iUseDontAskThisIP = 0;
	m_iDontAskThisIPTime = 0;
	// NEO: DS END

	// NEO: NSD - [NeoSourceDrop]
#ifdef NEO_SK // NEO: NSK - [NeoSourceKeeper]
	m_iDropUnreachable = 0;
	m_iDropUnreachableLimit = 0;
	m_iDropUnreachableLimitMode = 0;
	m_iDropUnreachableTimer = 0;
#endif // NEO_SK // NEO: NSK END
#ifdef NEO_SS // NEO: NSS - [NeoSourceStorage]
	m_iDropOutOfDate = 0;
	m_iDropOutOfDateSmooth = 0;
	m_iDropOutOfDateFails = 0;
	m_iDropOutOfDateTime = 0;
	m_iDropOutOfDateLimit = 0;
	m_iDropOutOfDateLimitMode = 0;
	m_iDropOutOfDateTimer = 0;
#endif // NEO_SS // NEO: NSS END
#ifdef NEO_SA // NEO: NSA - [NeoSourceAnaliser]
	m_iDropRetired = 0;
	m_iDropRetiredLimit = 0;
	m_iDropRetiredLimitMode = 0;
	m_iDropRetiredTimer = 0;

	m_iDropLoaded = 0;
	m_iDropLoadedLimit = 0;
	m_iDropLoadedLimitMode = 0;
	m_iDropLoadedTimer = 0;
#endif // NEO_SA // NEO: NSA END
	// NEO: NSD END

	// NEO: NCAP - [NeoCustomAutoPriority]
	m_iDynamicAutoDownPriority = 0;
	m_fDynamicDownPriorityFactor = 0;
	m_iLowDownPrioThreshold = 0;
	m_iHighDownPrioThreshold = 0;
	// NEO: NCAP END

	m_WantedParts.RemoveAll(); // NEO: MCS - [ManualChunkSelection]
}

CPartPreferences::~CPartPreferences(){
	ClearTags();
}

bool CPartPreferences::SavePartPrefs(CFileDataIO* file)
{
	UINT uTagCount = 0;
	ULONG uTagCountFilePos = (ULONG)file->GetPosition();
	file->WriteUInt32(uTagCount);

	if (m_iChunkSelectionMode){
		CTag tag(NFT_CHUNK_MODE, m_iChunkSelectionMode);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	// NEO: RC4 - [RareChunksV4]
	if (m_iRareChunkV4Orde){
		CTag tag(NFT_RC_ORDER, m_iRareChunkV4Orde);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_bRareChunkV4SameBlock){
		CTag tag(NFT_RC_BLOCK, m_bRareChunkV4SameBlock);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	// NEO: RC4 END

	// NEO: SCT - [SubChunkTransfer]
	if (m_iSubChunkTransfer){
		CTag tag(NFT_SUB_CHUNK_TRANSFER, m_iSubChunkTransfer);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	// NEO: SCT END

	// NEO: NPC - [NeoPartCatch]
	if (m_iPartCatch){
		CTag tag(NFT_PART_CATCH, m_iPartCatch);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	// NEO: NPC END

#ifdef A4AF_CATS // NEO: MAC - [MorphA4AFCategories]
	if (m_iA4AFFlags){
		CTag tag(NFT_A4AF_FLAGS, m_iA4AFFlags);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
#endif // A4AF_CATS // NEO: MAC END

	// NEO: NST - [NeoSourceTweaks]
	if (m_iHardLimit){
		CTag tag(NFT_HARD_LIMIT, m_iHardLimit);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iSwapLimit){
		CTag tag(NFT_SWAP_LIMIT, m_iSwapLimit);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iCleanUpLimit){
		CTag tag(NFT_CLEANUP_LIMIT, m_iCleanUpLimit);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iCalcStandardLimits){
		CTag tag(NFT_CALC_LIMITS, m_iCalcStandardLimits);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	if (m_iXSState){
		CTag tag(NFT_XS_STATE, m_iXSState);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iXSLimit){
		CTag tag(NFT_XS_LIMIT, m_iXSState);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iXSIntervals){
		CTag tag(NFT_XS_INTERVALS, m_iXSIntervals);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iXSDelayValue){
		CTag tag(NFT_XS_DELAY_VALUE, m_iXSDelayValue);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	if (m_iSVRState){
		CTag tag(NFT_SVR_STATE, m_iSVRState);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iSVRLimit){
		CTag tag(NFT_SVR_LIMIT, m_iSVRState);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iSVRIntervals){
		CTag tag(NFT_SVR_INTERVALS, m_iSVRIntervals);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	if (m_iKADState){
		CTag tag(NFT_KAD_STATE, m_iKADState);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iKADLimit){
		CTag tag(NFT_KAD_LIMIT, m_iKADState);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iKADIntervals){
		CTag tag(NFT_KAD_INTERVALS, m_iKADIntervals);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iKADDelayValue){
		CTag tag(NFT_KAD_DELAY_VALUE, m_iKADDelayValue);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	if (m_iUDPState){
		CTag tag(NFT_UDP_STATE, m_iUDPState);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iUDPLimit){
		CTag tag(NFT_UDP_LIMIT, m_iUDPLimit);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iUDPIntervals){
		CTag tag(NFT_UDP_INTERVALS, m_iUDPIntervals);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	// NEO: NST END

#ifdef LANCAST // NEO: NLC - [NeoLanCast]
	if (m_bDisableLAN){
		CTag tag(NFT_LAN_STATE, m_bDisableLAN);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iLANIntervals){
		CTag tag(NFT_LAN_INTERVALS, m_iLANIntervals);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	if (m_iLanReaskIntervals){
		CTag tag(NFT_LAN_REASK_TIMER, m_iLanReaskIntervals);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iNnPLanReaskIntervals){
		CTag tag(NFT_NNP_LAN_REASK_TIMER, m_iNnPLanReaskIntervals);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
#endif //LANCAST // NEO: NLC END

	// NEO: NSD - [NeoSourceDrop]
	if (m_iLow2LowCleanUpTime){
		CTag tag(NFT_LOW2LOW_CLEANUP_TIME, m_iLow2LowCleanUpTime);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
#if defined(NEO_SK) || defined(NEO_SS) // NEO: NSK - [NeoSourceKeeper] // NEO: NSS - [NeoSourceStorage]
	if (m_iBadCleanUpTime){
		CTag tag(NFT_BAD_CLEANUP_TIME, m_iBadCleanUpTime);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iGoneCleanUpTime){
		CTag tag(NFT_GONE_CLEANUP_TIME, m_iGoneCleanUpTime);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iSuspendCleanUpTime){
		CTag tag(NFT_SUSPEND_CLEANUP_TIME, m_iSuspendCleanUpTime);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
#endif // NEO_SK // NEO_SS // NEO: NSK END // NEO: NSS END
	if (m_iNnPCleanUpTime){
		CTag tag(NFT_NNP_CLEANUP_TIME, m_iNnPCleanUpTime);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iFullQCleanUpTime){
		CTag tag(NFT_FULLQ_CLEANUP_TIME, m_iFullQCleanUpTime);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	// NEO: NSD END

	// NEO: ASL - [AutoSoftLock]
	if (m_iAutoSoftLock){
		CTag tag(NFT_ASL_ENABLE, m_iAutoSoftLock);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iAutoSoftLockValue){
		CTag tag(NFT_ASL_VALUE, m_iAutoSoftLockValue);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	// NEO: ASL END

	// NEO: AHL - [AutoHardLimit]
	if (m_iAutoHardLimit){
		CTag tag(NFT_AHL_MODE, m_iAutoHardLimit);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iMinimalHardLimit){
		CTag tag(NFT_AHL_MIN_SRC, m_iMinimalHardLimit);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iAutoHardLimitTimer){
		CTag tag(NFT_AHL_TIMER, m_iAutoHardLimitTimer);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	// NEO: AHL END

	// NEO: XSC - [ExtremeSourceCache]
	if (m_iSourceCache){
		CTag tag(NFT_USE_SOURCE_CACHE, m_iSourceCache);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iSourceCacheLimit){
		CTag tag(NFT_SOURCE_CACHE_LIMIT, m_iSourceCacheLimit);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iSourceCacheTime){
		CTag tag(NFT_SOURCE_CACHE_TIME, m_iSourceCacheTime);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	// NEO: XSC END

	// NEO: DR - [DownloadReask]
	if (m_iReaskIntervals){
		CTag tag(NFT_REASK_TIMER, m_iReaskIntervals);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	if (m_iNnPReask){
		CTag tag(NFT_NNP_REASK_ENABLE, m_iNnPReask);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iNnPReaskIntervals){
		CTag tag(NFT_NNP_REASK_TIMER, m_iNnPReaskIntervals);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	if (m_iFullQReask){
		CTag tag(NFT_FULLQ_REASK_ENABLE, m_iFullQReask);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iFullQReaskIntervals){
		CTag tag(NFT_FULLQ_REASK_TIMER, m_iFullQReaskIntervals);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	// NEO: DR END

#ifdef NEO_SK // NEO: NSK - [NeoSourceKeeper]
	if (m_iEnableSourceKeeper){
		CTag tag(NFT_SOURCE_KEEPER, m_iEnableSourceKeeper);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
#endif // NEO_SK // NEO: NSK END
#ifdef NEO_SS // NEO: NSS - [NeoSourceStorage]
	if (m_iEnableSourceStorage){
		CTag tag(NFT_SOURCE_STORAGE, m_iEnableSourceStorage);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iAutoSaveSources){
		CTag tag(NFT_AUTO_SAVE_SOURCES, m_iAutoSaveSources);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iAutoSaveSourcesIntervals){
		CTag tag(NFT_AUTO_SAVE_SOURCES_INTERVALS, m_iAutoSaveSourcesIntervals);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iSourceStorageLimit){
		CTag tag(NFT_SOURCE_STORAGE_LIMIT, m_iSourceStorageLimit);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iAutoLoadStoredSources){
		CTag tag(NFT_AUTO_LOAD_SOURCES, m_iAutoLoadStoredSources);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iUseStorageBootstrap){
		CTag tag(NFT_USE_STORAGE_BOOTSTRAP, m_iUseStorageBootstrap);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iStorageBootstrapTime){
		CTag tag(NFT_STORAGE_BOOTSTRAP_TIME, m_iStorageBootstrapTime);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iStorageBootstrapRequirement){
		CTag tag(NFT_STORAGE_BOOTSTRAP_REQUIREMENT, m_iStorageBootstrapRequirement);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iStoreLowIDSources){
		CTag tag(NFT_STORE_LOW_ID, m_iStoreLowIDSources);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iStoreAlsoA4AFSources){
		CTag tag(NFT_STORE_A4AF, m_iStoreAlsoA4AFSources);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iStoreSourcesFileStatus){
		CTag tag(NFT_STORE_FILE_STATUS, m_iStoreSourcesFileStatus);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	if (m_iAutoReaskStoredSources){
		CTag tag(NFT_AUTO_REASK_STORED_SOURCES, m_iAutoReaskStoredSources);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iAutoReaskStoredSourcesLimit){
		CTag tag(NFT_AUTO_REASK_STORED_SOURCES_LIMIT, m_iAutoReaskStoredSourcesLimit);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iTotalSourceRestore){
		CTag tag(NFT_TOTAL_SOURCE_RESTORE, m_iTotalSourceRestore);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iUseAutoReaskStoredSourcesDelay){
		CTag tag(NFT_USE_AUTO_REASK_STORED_SOURCES_DELAY, m_iUseAutoReaskStoredSourcesDelay);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iAutoReaskStoredSourcesDelay){
		CTag tag(NFT_AUTO_REASK_STORED_SOURCES_DELAY, m_iAutoReaskStoredSourcesDelay);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	if (m_iAutoReaskLoadedSourcesDelay){
		CTag tag(NFT_AUTO_REASK_LOADED_SOURCES_DELAY, m_iAutoReaskLoadedSourcesDelay);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	if (m_iGroupStoredSourceReask){
		CTag tag(NFT_GROUP_STORAGE, m_iGroupStoredSourceReask);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iStoredSourceGroupIntervals){
		CTag tag(NFT_GROUP_INTERVALS, m_iStoredSourceGroupIntervals);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iStoredSourceGroupSize){
		CTag tag(NFT_GROUP_SIZE, m_iStoredSourceGroupSize);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	if (m_iUseSmoothOutOfDate){
		CTag tag(NFT_USE_SMOOTH_OUTOFDATE, m_iUseSmoothOutOfDate);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iMaxStoredFaildCount){
		CTag tag(NFT_OUTOFDATE_MAXFAILS, m_iMaxStoredFaildCount);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iStoredOutOfDate){
		CTag tag(NFT_OUTOFDATE_MAXTIME, m_iStoredOutOfDate);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
#endif // NEO_SS // NEO: NSS END
#ifdef NEO_SA // NEO: NSA - [NeoSourceAnaliser]
	if (m_iEnableSourceAnalizer){
		CTag tag(NFT_SOURCE_ANALISER, m_iEnableSourceAnalizer);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	if (m_iDontStoreTemporarySources){
		CTag tag(NFT_DONT_STORE_TEMP_SOURCES, m_iDontStoreTemporarySources);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	if (m_iPropabilityMode){
		CTag tag(NFT_PROBABILITY_MODE, m_iPropabilityMode);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	if (m_fEnhancedFactor){
		CED2KTag tag(NFT_ENHANCED_FACTOR, m_fEnhancedFactor);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	if (m_iReaskPropability){
		CTag tag(NFT_REASK_PROPABILITY, m_iReaskPropability);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iReservePropability){
		CTag tag(NFT_RESERVE_PROPABILITY, m_iReservePropability);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	if (m_iAutoReserveReask){
		CTag tag(NFT_AUTO_RESERVE_REASK, m_iAutoReserveReask);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iReserveReaskPropability){
		CTag tag(NFT_RESERVE_REASK_PROPABILITY, m_iReserveReaskPropability);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iUseReaskReserveSourcesDelay){
		CTag tag(NFT_USE_RESERVE_REASK_DELAY, m_iUseReaskReserveSourcesDelay);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iReaskReserveSourcesDelay){
		CTag tag(NFT_RESERVE_REASK_DELAY, m_iReaskReserveSourcesDelay);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iReaskReserveSourcesLimit){
		CTag tag(NFT_RESERVE_REASK_LIMIT, m_iReaskReserveSourcesLimit);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	if (m_iAutoTemporaryReask){
		CTag tag(NFT_AUTO_TEMPORARY_REASK, m_iAutoTemporaryReask);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iTemporaryReaskPropability){
		CTag tag(NFT_TEMPORARY_REASK_PROPABILITY, m_iTemporaryReaskPropability);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iUseReaskTemporarySourcesDelay){
		CTag tag(NFT_USE_TEMPORARY_REASK_DELAY, m_iUseReaskTemporarySourcesDelay);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iReaskTemporarySourcesDelay){
		CTag tag(NFT_TEMPORARY_REASK_DELAY, m_iReaskTemporarySourcesDelay);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iReaskTemporarySourcesLimit){
		CTag tag(NFT_TEMPORARY_REASK_LIMIT, m_iReaskTemporarySourcesLimit);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	//if (m_iMinAnalisisQuality){
	//	CTag tag(NFT_MIN_ANALISIS_QUALITY, m_iMinAnalisisQuality);
	//	tag.WriteNewEd2kTag(file);
	//	uTagCount++;
	//}

	//if (m_iAutoUnsureReask){
	//	CTag tag(NFT_AUTO_UNSURE_REASK, m_iAutoUnsureReask);
	//	tag.WriteNewEd2kTag(file);
	//	uTagCount++;
	//}
	//if (m_iUseReaskUnsureSourcesDelay){
	//	CTag tag(NFT_USE_UNSURE_REASK_DELAY, m_iUseReaskUnsureSourcesDelay);
	//	tag.WriteNewEd2kTag(file);
	//	uTagCount++;
	//}
	//if (m_iReaskUnsureSourcesDelay){
	//	CTag tag(NFT_UNSURE_REASK_DELAY, m_iReaskUnsureSourcesDelay);
	//	tag.WriteNewEd2kTag(file);
	//	uTagCount++;
	//}
	//if (m_iReaskUnsureSourcesLimit){
	//	CTag tag(NFT_UNSURE_REASK_LIMIT, m_iReaskUnsureSourcesLimit);
	//	tag.WriteNewEd2kTag(file);
	//	uTagCount++;
	//}

	if (m_iUseUnpredictedPropability){
		CTag tag(NFT_USE_UNPREDICTED_PROPABILITY, m_iUseUnpredictedPropability);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iUnpredictedPropability){
		CTag tag(NFT_UNPREDICTED_PROPABILITY, m_iUnpredictedPropability);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iUseReaskUnpredictedSourcesDelay){
		CTag tag(NFT_USE_UNPREDICTED_REASK_DELAY, m_iUseReaskUnpredictedSourcesDelay);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iReaskUnpredictedSourcesDelay){
		CTag tag(NFT_UNPREDICTED_REASK_DELAY, m_iReaskUnpredictedSourcesDelay);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iReaskUnpredictedSourcesLimit){
		CTag tag(NFT_UNPREDICTED_REASK_LIMIT, m_iReaskUnpredictedSourcesLimit);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	if (m_iRetryUnreachable){
		CTag tag(NFT_RETRY_UNREAHABLE, m_iRetryUnreachable);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iRetryUnreachableIntervals){
		CTag tag(NFT_RETRY_UNREAHABLE_INTERVALS, m_iRetryUnreachableIntervals);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iFailTolerance){
		CTag tag(NFT_FAIL_TOLERANCE, m_iFailTolerance);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iMaxFailTolerance){
		CTag tag(NFT_MAX_FAIL_TOLERANCE, m_iMaxFailTolerance);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iUnreachableReaskPropability){
		CTag tag(NFT_UNREACHABLE_REASK_PROPABILITY, m_iUnreachableReaskPropability);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iReaskUnreachableSourcesLimit){
		CTag tag(NFT_UNREACHABLE_REASK_LIMIT, m_iReaskUnreachableSourcesLimit);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
#endif // NEO_SA // NEO: NSA END

	// NEO: DS - [DropSources]
	if (m_iDropNnP){
		CTag tag(NFT_DROP_NNP_ENABLE, m_iDropNnP);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iDropNnPLimit){
		CTag tag(NFT_DROP_NNP_LIMIT, m_iDropNnPLimit);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iDropNnPLimitMode){
		CTag tag(NFT_DROP_NNP_LIMIT_MODE, m_iDropNnPLimitMode);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iDropNnPTimer){
		CTag tag(NFT_DROP_NNP_TIMER, m_iDropNnPTimer);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	if (m_iDropFullQ){
		CTag tag(NFT_DROP_FULLQ_ENABLE, m_iDropFullQ);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iDropFullQLimit){
		CTag tag(NFT_DROP_FULLQ_LIMIT, m_iDropFullQLimit);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iDropFullQLimitMode){
		CTag tag(NFT_DROP_FULLQ_LIMIT_MODE, m_iDropFullQLimitMode);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iDropFullQTimer){
		CTag tag(NFT_DROP_FULLQ_TIMER, m_iDropFullQTimer);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	if (m_iDropHighQ){
		CTag tag(NFT_DROP_HIGHQ_ENABLE, m_iDropHighQ);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iDropHighQValue){
		CTag tag(NFT_DROP_HIGHQ_VALUE, m_iDropHighQValue);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iDropHighQLimit){
		CTag tag(NFT_DROP_HIGHQ_LIMIT, m_iDropHighQLimit);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iDropHighQLimitMode){
		CTag tag(NFT_DROP_HIGHQ_LIMIT_MODE, m_iDropHighQLimitMode);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iDropHighQTimer){
		CTag tag(NFT_DROP_HIGHQ_TIMER, m_iDropHighQTimer);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	if (m_iUseDontAskThisIP){
		CTag tag(NFT_USE_DONT_ASK_THIS_IP, m_iUseDontAskThisIP);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iDontAskThisIPTime){
		CTag tag(NFT_DONT_ASK_THIS_IP_TIME, m_iDontAskThisIPTime);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	// NEO: DS END

	// NEO: NSD - [NeoSourceDrop]
#ifdef NEO_SK // NEO: NSK - [NeoSourceKeeper]
	if (m_iDropUnreachable){
		CTag tag(NFT_DROP_UNREACHABLE_ENABLE, m_iDropUnreachable);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iDropUnreachableLimit){
		CTag tag(NFT_DROP_UNREACHABLE_LIMIT, m_iDropUnreachableLimit);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iDropUnreachableLimitMode){
		CTag tag(NFT_DROP_UNREACHABLE_LIMIT_MODE, m_iDropUnreachableLimitMode);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iDropUnreachableTimer){
		CTag tag(NFT_DROP_UNREACHABLE_TIMER, m_iDropUnreachableTimer);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
#endif // NEO_SK // NEO: NSK END
#ifdef NEO_SS // NEO: NSS - [NeoSourceStorage]
	if (m_iDropOutOfDate){
		CTag tag(NFT_DROP_OUTOFDATE_ENABLE, m_iDropOutOfDate);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iDropOutOfDateSmooth){
		CTag tag(NFT_DROP_OUTOFDATE_SMOOTH, m_iDropOutOfDateSmooth);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iDropOutOfDateFails){
		CTag tag(NFT_DROP_OUTOFDATE_FAILS, m_iDropOutOfDateFails);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iDropOutOfDateTime){
		CTag tag(NFT_DROP_OUTOFDATE_TIME, m_iDropOutOfDateTime);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iDropOutOfDateLimit){
		CTag tag(NFT_DROP_OUTOFDATE_LIMIT, m_iDropOutOfDateLimit);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iDropOutOfDateLimitMode){
		CTag tag(NFT_DROP_OUTOFDATE_LIMIT_MODE, m_iDropOutOfDateLimitMode);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iDropOutOfDateTimer){
		CTag tag(NFT_DROP_OUTOFDATE_TIMER, m_iDropOutOfDateTimer);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
#endif // NEO_SS // NEO: NSS END
#ifdef NEO_SA // NEO: NSA - [NeoSourceAnaliser]
	if (m_iDropRetired){
		CTag tag(NFT_DROP_RETIRED_ENABLE, m_iDropRetired);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iDropRetiredLimit){
		CTag tag(NFT_DROP_RETIRED_LIMIT, m_iDropRetiredLimit);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iDropRetiredLimitMode){
		CTag tag(NFT_DROP_RETIRED_LIMIT_MODE, m_iDropRetiredLimitMode);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iDropRetiredTimer){
		CTag tag(NFT_DROP_RETIRED_TIMER, m_iDropRetiredTimer);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}

	if (m_iDropLoaded){
		CTag tag(NFT_DROP_LOADED_ENABLE, m_iDropLoaded);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iDropLoadedLimit){
		CTag tag(NFT_DROP_LOADED_LIMIT, m_iDropLoadedLimit);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iDropLoadedLimitMode){
		CTag tag(NFT_DROP_LOADED_LIMIT_MODE, m_iDropLoadedLimitMode);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iDropLoadedTimer){
		CTag tag(NFT_DROP_LOADED_TIMER, m_iDropLoadedTimer);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
#endif // NEO_SA // NEO: NSA END
	// NEO: NSD END

	// NEO: NCAP - [NeoCustomAutoPriority]
	if (m_iDynamicAutoDownPriority){
		CTag tag(NFT_DYNAMIC_AUTO_DOWN_PRIORITY, m_iDynamicAutoDownPriority);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_fDynamicDownPriorityFactor){
		CED2KTag tag(NFT_DYNAMIC_DOWN_PRIORITY_FACTOR, m_fDynamicDownPriorityFactor);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iLowDownPrioThreshold){
		CTag tag(NFT_LOW_DOWN_PRIO_THRESHOLD, m_iLowDownPrioThreshold);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	if (m_iHighDownPrioThreshold){
		CTag tag(NFT_HIGH_DOWN_PRIO_THRESHOLD, m_iHighDownPrioThreshold);
		tag.WriteNewEd2kTag(file);
		uTagCount++;
	}
	// NEO: NCAP END

	// NEO: MCS - [ManualChunkSelection]
	if(HasWantedParts())
		for(uint16 part = 0; part < PartFile->GetPartCount(); part++){
			if(GetWantedPart(part) != PR_PART_NORMAL){
				CTag tag(NFT_PR_PART_WANTED, part);
				tag.WriteNewEd2kTag(file);
				uTagCount++;
			}
		}
	// NEO: MCS END

	for (int j = 0; j < taglist.GetCount(); j++){
		if (taglist[j]->IsStr() || taglist[j]->IsInt()){
			taglist[j]->WriteNewEd2kTag(file);
			uTagCount++;
		}
	}

	file->Seek(uTagCountFilePos, CFile::begin);
	file->WriteUInt32(uTagCount);
	file->Seek(0, CFile::end);

	return true;
}

void CPartPreferences::ClearTags()
{
	for (int i = 0; i < taglist.GetSize(); i++)
		delete taglist[i];
	taglist.RemoveAll();
}

bool CPartPreferences::LoadPartPrefs(CFileDataIO* file)
{
	UINT tagcount = file->ReadUInt32();
	for (UINT j = 0; j < tagcount; j++){
		CTag* newtag = new CTag(file, false);
		switch (newtag->GetNameID()){

			case NFT_CHUNK_MODE:{
                ASSERT( newtag->IsInt() );
                m_iChunkSelectionMode = newtag->GetInt();
                delete newtag;
                break;
            }

			// NEO: RC4 - [RareChunksV4]
			case NFT_RC_ORDER:{
                ASSERT( newtag->IsInt() );
                m_iRareChunkV4Orde = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_RC_BLOCK:{
                ASSERT( newtag->IsInt() );
				m_bRareChunkV4SameBlock = I2B(newtag->GetInt());
                delete newtag;
                break;
            }
			// NEO: RC4 END

			// NEO: SCT - [SubChunkTransfer]
			case NFT_SUB_CHUNK_TRANSFER:{
                ASSERT( newtag->IsInt() );
                m_iSubChunkTransfer = newtag->GetInt();
                delete newtag;
                break;
            }
			// NEO: SCT END

			// NEO: NPC - [NeoPartCatch]
			case NFT_PART_CATCH:{
                ASSERT( newtag->IsInt() );
                m_iPartCatch = newtag->GetInt();
                delete newtag;
                break;
            }
			// NEO: NPC END

#ifdef A4AF_CATS // NEO: MAC - [MorphA4AFCategories]
			case NFT_A4AF_FLAGS:{
                ASSERT( newtag->IsInt() );
                m_iA4AFFlags = newtag->GetInt();
                delete newtag;
                break;
            }
#endif // A4AF_CATS // NEO: MAC END

			// NEO: NST - [NeoSourceTweaks]
            case NFT_HARD_LIMIT:{
                ASSERT( newtag->IsInt() );
                m_iHardLimit = newtag->GetInt();
                delete newtag;
                break;
            }
            case NFT_SWAP_LIMIT:{
                ASSERT( newtag->IsInt() );
                m_iSwapLimit = newtag->GetInt();
                delete newtag;
                break;
            }
            case NFT_CLEANUP_LIMIT:{
                ASSERT( newtag->IsInt() );
                m_iCleanUpLimit = newtag->GetInt();
                delete newtag;
                break;
            }
            case NFT_CALC_LIMITS:{
                ASSERT( newtag->IsInt() );
                m_iCalcStandardLimits = newtag->GetInt();
                delete newtag;
                break;
            }

			case NFT_XS_STATE:{
                ASSERT( newtag->IsInt() );
                m_iXSState = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_XS_LIMIT:{
                ASSERT( newtag->IsInt() );
                m_iXSLimit = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_XS_INTERVALS:{
                ASSERT( newtag->IsInt() );
                m_iXSIntervals = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_XS_DELAY_VALUE:{ 
                ASSERT( newtag->IsInt() );
                m_iXSDelayValue = newtag->GetInt();
                delete newtag;
                break;
            }

			case NFT_SVR_STATE:{
                ASSERT( newtag->IsInt() );
                m_iSVRState = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_SVR_LIMIT:{
                ASSERT( newtag->IsInt() );
                m_iSVRLimit = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_SVR_INTERVALS:{
                ASSERT( newtag->IsInt() );
                m_iSVRIntervals = newtag->GetInt();
                delete newtag;
                break;
            }

			case NFT_KAD_STATE:{
                ASSERT( newtag->IsInt() );
                m_iKADState = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_KAD_LIMIT:{
                ASSERT( newtag->IsInt() );
                m_iKADLimit = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_KAD_INTERVALS:{
                ASSERT( newtag->IsInt() );
                m_iKADIntervals = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_KAD_DELAY_VALUE:{ 
                ASSERT( newtag->IsInt() );
                m_iKADDelayValue = newtag->GetInt();
                delete newtag;
                break;
            }

			case NFT_UDP_STATE:{
                ASSERT( newtag->IsInt() );
                m_iUDPState = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_UDP_LIMIT:{
                ASSERT( newtag->IsInt() );
                m_iUDPLimit = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_UDP_INTERVALS:{
                ASSERT( newtag->IsInt() );
                m_iUDPIntervals = newtag->GetInt();
                delete newtag;
                break;
            }
			// NEO: NST END

#ifdef LANCAST // NEO: NLC - [NeoLanCast]
			case NFT_LAN_STATE:{
                ASSERT( newtag->IsInt() );
                m_bDisableLAN = I2B(newtag->GetInt());
                delete newtag;
                break;
            }
			case NFT_LAN_INTERVALS:{
                ASSERT( newtag->IsInt() );
                m_iLANIntervals = newtag->GetInt();
                delete newtag;
                break;
            }

			case NFT_LAN_REASK_TIMER:{
                ASSERT( newtag->IsInt() );
                m_iLanReaskIntervals = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_NNP_LAN_REASK_TIMER:{
                ASSERT( newtag->IsInt() );
                m_iNnPLanReaskIntervals = newtag->GetInt();
                delete newtag;
                break;
            }
#endif //LANCAST // NEO: NLC END

			// NEO: NSD - [NeoSourceDrop]
			case NFT_LOW2LOW_CLEANUP_TIME:{
                ASSERT( newtag->IsInt() );
                m_iLow2LowCleanUpTime = newtag->GetInt();
                delete newtag;
                break;
            }
#if defined(NEO_SK) || defined(NEO_SS) // NEO: NSK - [NeoSourceKeeper] // NEO: NSS - [NeoSourceStorage]
			case NFT_BAD_CLEANUP_TIME:{
                ASSERT( newtag->IsInt() );
                m_iBadCleanUpTime = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_GONE_CLEANUP_TIME:{
                ASSERT( newtag->IsInt() );
                m_iGoneCleanUpTime = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_SUSPEND_CLEANUP_TIME:{
                ASSERT( newtag->IsInt() );
                m_iSuspendCleanUpTime = newtag->GetInt();
                delete newtag;
                break;
            }
#endif // NEO_SK // NEO_SS // NEO: NSK END // NEO: NSS END
			case NFT_NNP_CLEANUP_TIME:{
                ASSERT( newtag->IsInt() );
                m_iNnPCleanUpTime = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_FULLQ_CLEANUP_TIME:{
                ASSERT( newtag->IsInt() );
                m_iFullQCleanUpTime = newtag->GetInt();
                delete newtag;
                break;
            }
			// NEO: NSD END

			// NEO: ASL - [AutoSoftLock]
			case NFT_ASL_ENABLE:{
                ASSERT( newtag->IsInt() );
                m_iAutoSoftLock = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_ASL_VALUE:{
                ASSERT( newtag->IsInt() );
                m_iAutoSoftLockValue = newtag->GetInt();
                delete newtag;
                break;
            }
			// NEO: ASL END

			// NEO: AHL - [AutoHardLimit]
			case NFT_AHL_MODE:{
                ASSERT( newtag->IsInt() );
                m_iAutoHardLimit = newtag->GetInt();
                delete newtag;
                break;
            }
            case NFT_AHL_MIN_SRC:{
                ASSERT( newtag->IsInt() );
                m_iMinimalHardLimit = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_AHL_TIMER:{
                ASSERT( newtag->IsInt() );
                m_iAutoHardLimitTimer = newtag->GetInt();
                delete newtag;
                break;
            }
			// NEO: AHL END

			// NEO: XSC - [ExtremeSourceCache]
			case NFT_USE_SOURCE_CACHE:{
                ASSERT( newtag->IsInt() );
                m_iSourceCache = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_SOURCE_CACHE_LIMIT:{
                ASSERT( newtag->IsInt() );
                m_iSourceCacheLimit = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_SOURCE_CACHE_TIME:{
                ASSERT( newtag->IsInt() );
                m_iSourceCacheTime = newtag->GetInt();
                delete newtag;
                break;
            }
			// NEO: XSC END

			// NEO: DR - [DownloadReask]
			case NFT_REASK_TIMER:{
                ASSERT( newtag->IsInt() );
                m_iReaskIntervals = newtag->GetInt();
                delete newtag;
                break;
            }

			case NFT_NNP_REASK_ENABLE:{
                ASSERT( newtag->IsInt() );
                m_iNnPReask = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_NNP_REASK_TIMER:{
                ASSERT( newtag->IsInt() );
                m_iNnPReaskIntervals = newtag->GetInt();
                delete newtag;
                break;
            }

			case NFT_FULLQ_REASK_ENABLE:{
                ASSERT( newtag->IsInt() );
                m_iFullQReask = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_FULLQ_REASK_TIMER:{
                ASSERT( newtag->IsInt() );
                m_iFullQReaskIntervals = newtag->GetInt();
                delete newtag;
                break;
            }
			// NEO: DR END

#ifdef NEO_SK // NEO: NSK - [NeoSourceKeeper]
			case NFT_SOURCE_KEEPER:{
                ASSERT( newtag->IsInt() );
                m_iEnableSourceKeeper = newtag->GetInt();
                delete newtag;
                break;
            }
#endif // NEO_SK // NEO: NSK END
#ifdef NEO_SS // NEO: NSS - [NeoSourceStorage]
			case NFT_SOURCE_STORAGE:{
                ASSERT( newtag->IsInt() );
                m_iEnableSourceStorage = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_AUTO_SAVE_SOURCES:{
                ASSERT( newtag->IsInt() );
                m_iAutoSaveSources = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_AUTO_SAVE_SOURCES_INTERVALS:{
                ASSERT( newtag->IsInt() );
                m_iAutoSaveSourcesIntervals = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_SOURCE_STORAGE_LIMIT:{
                ASSERT( newtag->IsInt() );
                m_iSourceStorageLimit = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_AUTO_LOAD_SOURCES:{
                ASSERT( newtag->IsInt() );
                m_iAutoLoadStoredSources = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_USE_STORAGE_BOOTSTRAP:{
                ASSERT( newtag->IsInt() );
                m_iUseStorageBootstrap = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_STORAGE_BOOTSTRAP_TIME:{
                ASSERT( newtag->IsInt() );
                m_iStorageBootstrapTime = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_STORAGE_BOOTSTRAP_REQUIREMENT:{
                ASSERT( newtag->IsInt() );
                m_iStorageBootstrapRequirement = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_STORE_LOW_ID:{
                ASSERT( newtag->IsInt() );
                m_iStoreLowIDSources = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_STORE_A4AF:{
                ASSERT( newtag->IsInt() );
                m_iStoreAlsoA4AFSources = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_STORE_FILE_STATUS:{
                ASSERT( newtag->IsInt() );
                m_iStoreSourcesFileStatus = newtag->GetInt();
                delete newtag;
                break;
            }

			case NFT_AUTO_REASK_STORED_SOURCES:{
                ASSERT( newtag->IsInt() );
                m_iAutoReaskStoredSources = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_AUTO_REASK_STORED_SOURCES_LIMIT:{
                ASSERT( newtag->IsInt() );
                m_iAutoReaskStoredSourcesLimit = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_TOTAL_SOURCE_RESTORE:{
                ASSERT( newtag->IsInt() );
                m_iTotalSourceRestore = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_USE_AUTO_REASK_STORED_SOURCES_DELAY:{
                ASSERT( newtag->IsInt() );
                m_iUseAutoReaskStoredSourcesDelay = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_AUTO_REASK_STORED_SOURCES_DELAY:{
                ASSERT( newtag->IsInt() );
                m_iAutoReaskStoredSourcesDelay = newtag->GetInt();
                delete newtag;
                break;
            }

			case NFT_AUTO_REASK_LOADED_SOURCES_DELAY:{
                ASSERT( newtag->IsInt() );
                m_iAutoReaskLoadedSourcesDelay = newtag->GetInt();
                delete newtag;
                break;
            }

			case NFT_GROUP_STORAGE:{
                ASSERT( newtag->IsInt() );
                m_iGroupStoredSourceReask = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_GROUP_INTERVALS:{
                ASSERT( newtag->IsInt() );
                m_iStoredSourceGroupIntervals = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_GROUP_SIZE:{
                ASSERT( newtag->IsInt() );
                m_iStoredSourceGroupSize = newtag->GetInt();
                delete newtag;
                break;
            }

			case NFT_USE_SMOOTH_OUTOFDATE:{
                ASSERT( newtag->IsInt() );
                m_iUseSmoothOutOfDate = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_OUTOFDATE_MAXFAILS:{
                ASSERT( newtag->IsInt() );
                m_iMaxStoredFaildCount = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_OUTOFDATE_MAXTIME:{
                ASSERT( newtag->IsInt() );
                m_iStoredOutOfDate = newtag->GetInt();
                delete newtag;
                break;
            }
#endif // NEO_SS // NEO: NSS END
#ifdef NEO_SA // NEO: NSA - [NeoSourceAnaliser]
			case NFT_SOURCE_ANALISER:{
                ASSERT( newtag->IsInt() );
                m_iEnableSourceAnalizer = newtag->GetInt();
                delete newtag;
                break;
            }

			case NFT_DONT_STORE_TEMP_SOURCES:{
                ASSERT( newtag->IsInt() );
                m_iDontStoreTemporarySources = newtag->GetInt();
                delete newtag;
                break;
            }

			case NFT_PROBABILITY_MODE:{
                ASSERT( newtag->IsInt() );
                m_iPropabilityMode = newtag->GetInt();
                delete newtag;
                break;
            }

			case NFT_ENHANCED_FACTOR:{
                ASSERT( newtag->IsFloat() );
                m_fEnhancedFactor = newtag->GetFloat();
                delete newtag;
                break;
            }

			case NFT_REASK_PROPABILITY:{
                ASSERT( newtag->IsInt() );
                m_iReaskPropability = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_RESERVE_PROPABILITY:{
                ASSERT( newtag->IsInt() );
                m_iReservePropability = newtag->GetInt();
                delete newtag;
                break;
            }

			case NFT_AUTO_RESERVE_REASK:{
                ASSERT( newtag->IsInt() );
                m_iAutoReserveReask = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_RESERVE_REASK_PROPABILITY:{
                ASSERT( newtag->IsInt() );
                m_iReserveReaskPropability = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_USE_RESERVE_REASK_DELAY:{
                ASSERT( newtag->IsInt() );
                m_iUseReaskReserveSourcesDelay = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_RESERVE_REASK_DELAY:{
                ASSERT( newtag->IsInt() );
                m_iReaskReserveSourcesDelay = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_RESERVE_REASK_LIMIT:{
                ASSERT( newtag->IsInt() );
                m_iReaskReserveSourcesLimit = newtag->GetInt();
                delete newtag;
                break;
            }

			case NFT_AUTO_TEMPORARY_REASK:{
                ASSERT( newtag->IsInt() );
                m_iAutoTemporaryReask = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_TEMPORARY_REASK_PROPABILITY:{
                ASSERT( newtag->IsInt() );
                m_iTemporaryReaskPropability = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_USE_TEMPORARY_REASK_DELAY:{
                ASSERT( newtag->IsInt() );
                m_iUseReaskTemporarySourcesDelay = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_TEMPORARY_REASK_DELAY:{
                ASSERT( newtag->IsInt() );
                m_iReaskTemporarySourcesDelay = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_TEMPORARY_REASK_LIMIT:{
                ASSERT( newtag->IsInt() );
                m_iReaskTemporarySourcesLimit = newtag->GetInt();
                delete newtag;
                break;
            }

			//case NFT_MIN_ANALISIS_QUALITY:{
            //    ASSERT( newtag->IsInt() );
            //    m_iMinAnalisisQuality = newtag->GetInt();
            //    delete newtag;
            //    break;
            //}

			//case NFT_AUTO_UNSURE_REASK:{
            //    ASSERT( newtag->IsInt() );
            //    m_iAutoUnsureReask = newtag->GetInt();
            //    delete newtag;
            //    break;
            //}
			//case NFT_USE_UNSURE_REASK_DELAY:{
            //    ASSERT( newtag->IsInt() );
            //    m_iUseReaskUnsureSourcesDelay = newtag->GetInt();
            //    delete newtag;
            //    break;
            //}
			//case NFT_UNSURE_REASK_DELAY:{
            //    ASSERT( newtag->IsInt() );
            //    m_iReaskUnsureSourcesDelay = newtag->GetInt();
            //    delete newtag;
            //    break;
            //}
			//case NFT_UNSURE_REASK_LIMIT:{
            //    ASSERT( newtag->IsInt() );
            //    m_iReaskUnsureSourcesLimit = newtag->GetInt();
            //    delete newtag;
            //    break;
            //}

			case NFT_USE_UNPREDICTED_PROPABILITY:{
                ASSERT( newtag->IsInt() );
                m_iUseUnpredictedPropability = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_UNPREDICTED_PROPABILITY:{
                ASSERT( newtag->IsInt() );
                m_iUnpredictedPropability = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_USE_UNPREDICTED_REASK_DELAY:{
                ASSERT( newtag->IsInt() );
                m_iUseReaskUnpredictedSourcesDelay = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_UNPREDICTED_REASK_DELAY:{
                ASSERT( newtag->IsInt() );
                m_iReaskUnpredictedSourcesDelay = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_UNPREDICTED_REASK_LIMIT:{
                ASSERT( newtag->IsInt() );
                m_iReaskUnpredictedSourcesLimit = newtag->GetInt();
                delete newtag;
                break;
            }

			case NFT_RETRY_UNREAHABLE:{
                ASSERT( newtag->IsInt() );
                m_iRetryUnreachable = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_RETRY_UNREAHABLE_INTERVALS:{
                ASSERT( newtag->IsInt() );
                m_iRetryUnreachableIntervals = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_FAIL_TOLERANCE:{
                ASSERT( newtag->IsInt() );
                m_iFailTolerance = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_MAX_FAIL_TOLERANCE:{
                ASSERT( newtag->IsInt() );
                m_iMaxFailTolerance = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_UNREACHABLE_REASK_PROPABILITY:{
                ASSERT( newtag->IsInt() );
                m_iUnreachableReaskPropability = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_UNREACHABLE_REASK_LIMIT:{
                ASSERT( newtag->IsInt() );
                m_iReaskUnreachableSourcesLimit = newtag->GetInt();
                delete newtag;
                break;
            }
#endif // NEO_SA // NEO: NSA END

			// NEO: DS - [DropSources]
			case NFT_DROP_NNP_ENABLE:{
                ASSERT( newtag->IsInt() );
                m_iDropNnP = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_DROP_NNP_LIMIT:{
                ASSERT( newtag->IsInt() );
                m_iDropNnPLimit = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_DROP_NNP_LIMIT_MODE:{
                ASSERT( newtag->IsInt() );
                m_iDropNnPLimitMode = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_DROP_NNP_TIMER:{
                ASSERT( newtag->IsInt() );
                m_iDropNnPTimer = newtag->GetInt();
                delete newtag;
                break;
            }

			case NFT_DROP_FULLQ_ENABLE:{
                ASSERT( newtag->IsInt() );
                m_iDropFullQ = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_DROP_FULLQ_LIMIT:{
                ASSERT( newtag->IsInt() );
                m_iDropFullQLimit = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_DROP_FULLQ_LIMIT_MODE:{
                ASSERT( newtag->IsInt() );
                m_iDropFullQLimitMode = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_DROP_FULLQ_TIMER:{
                ASSERT( newtag->IsInt() );
                m_iDropFullQTimer = newtag->GetInt();
                delete newtag;
                break;
            }

			case NFT_DROP_HIGHQ_ENABLE:{
                ASSERT( newtag->IsInt() );
                m_iDropHighQ = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_DROP_HIGHQ_VALUE:{
                ASSERT( newtag->IsInt() );
                m_iDropHighQValue = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_DROP_HIGHQ_LIMIT:{
                ASSERT( newtag->IsInt() );
                m_iDropHighQLimit = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_DROP_HIGHQ_LIMIT_MODE:{
                ASSERT( newtag->IsInt() );
                m_iDropHighQLimitMode = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_DROP_HIGHQ_TIMER:{
                ASSERT( newtag->IsInt() );
                m_iDropHighQTimer = newtag->GetInt();
                delete newtag;
                break;
            }

			case NFT_USE_DONT_ASK_THIS_IP:{
                ASSERT( newtag->IsInt() );
                m_iUseDontAskThisIP = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_DONT_ASK_THIS_IP_TIME:{
                ASSERT( newtag->IsInt() );
                m_iDontAskThisIPTime = newtag->GetInt();
                delete newtag;
                break;
            }
			// NEO: DS END

			// NEO: NSD - [NeoSourceDrop]
#ifdef NEO_SK // NEO: NSK - [NeoSourceKeeper]
			case NFT_DROP_UNREACHABLE_ENABLE:{
                ASSERT( newtag->IsInt() );
                m_iDropUnreachable = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_DROP_UNREACHABLE_LIMIT:{
                ASSERT( newtag->IsInt() );
                m_iDropUnreachableLimit = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_DROP_UNREACHABLE_LIMIT_MODE:{
                ASSERT( newtag->IsInt() );
                m_iDropUnreachableLimitMode = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_DROP_UNREACHABLE_TIMER:{
                ASSERT( newtag->IsInt() );
                m_iDropUnreachableTimer = newtag->GetInt();
                delete newtag;
                break;
            }
#endif // NEO_SK // NEO: NSK END
#ifdef NEO_SS // NEO: NSS - [NeoSourceStorage]
			case NFT_DROP_OUTOFDATE_ENABLE:{
                ASSERT( newtag->IsInt() );
                m_iDropOutOfDate = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_DROP_OUTOFDATE_SMOOTH:{
                ASSERT( newtag->IsInt() );
                m_iDropOutOfDateSmooth = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_DROP_OUTOFDATE_FAILS:{
                ASSERT( newtag->IsInt() );
                m_iDropOutOfDateFails = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_DROP_OUTOFDATE_TIME:{
                ASSERT( newtag->IsInt() );
                m_iDropOutOfDateTime = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_DROP_OUTOFDATE_LIMIT:{
                ASSERT( newtag->IsInt() );
                m_iDropOutOfDateLimit = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_DROP_OUTOFDATE_LIMIT_MODE:{
                ASSERT( newtag->IsInt() );
                m_iDropOutOfDateLimitMode = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_DROP_OUTOFDATE_TIMER:{
                ASSERT( newtag->IsInt() );
                m_iDropOutOfDateTimer = newtag->GetInt();
                delete newtag;
                break;
            }
#endif // NEO_SS // NEO: NSS END
#ifdef NEO_SA // NEO: NSA - [NeoSourceAnaliser]
			case NFT_DROP_RETIRED_ENABLE:{
                ASSERT( newtag->IsInt() );
                m_iDropRetired = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_DROP_RETIRED_LIMIT:{
                ASSERT( newtag->IsInt() );
                m_iDropRetiredLimit = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_DROP_RETIRED_LIMIT_MODE:{
                ASSERT( newtag->IsInt() );
                m_iDropRetiredLimitMode = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_DROP_RETIRED_TIMER:{
                ASSERT( newtag->IsInt() );
                m_iDropRetiredTimer = newtag->GetInt();
                delete newtag;
                break;
            }

			case NFT_DROP_LOADED_ENABLE:{
                ASSERT( newtag->IsInt() );
                m_iDropLoaded = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_DROP_LOADED_LIMIT:{
                ASSERT( newtag->IsInt() );
                m_iDropLoadedLimit = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_DROP_LOADED_LIMIT_MODE:{
                ASSERT( newtag->IsInt() );
                m_iDropLoadedLimitMode = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_DROP_LOADED_TIMER:{
                ASSERT( newtag->IsInt() );
                m_iDropLoadedTimer = newtag->GetInt();
                delete newtag;
                break;
            }
#endif // NEO_SA // NEO: NSA END
			// NEO: NSD END

			// NEO: NCAP - [NeoCustomAutoPriority]
			case NFT_DYNAMIC_AUTO_DOWN_PRIORITY:{
                ASSERT( newtag->IsInt() );
                m_iDynamicAutoDownPriority = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_DYNAMIC_DOWN_PRIORITY_FACTOR:{
                ASSERT( newtag->IsFloat() );
                m_fDynamicDownPriorityFactor = newtag->GetFloat();
                delete newtag;
                break;
            }
			case NFT_LOW_DOWN_PRIO_THRESHOLD:{
                ASSERT( newtag->IsInt() );
                m_iLowDownPrioThreshold = newtag->GetInt();
                delete newtag;
                break;
            }
			case NFT_HIGH_DOWN_PRIO_THRESHOLD:{
                ASSERT( newtag->IsInt() );
                m_iHighDownPrioThreshold = newtag->GetInt();
                delete newtag;
                break;
            }
			// NEO: NCAP END

			// NEO: MCS - [ManualChunkSelection]
			/*case NFT_PR_PART_NORMAL:{
                ASSERT( newtag->IsInt() );
                delete newtag;
                break;
            }*/
			case NFT_PR_PART_WANTED:{
                ASSERT( newtag->IsInt() );
                SetWantedPart(newtag->GetInt(), PR_PART_WANTED);
                delete newtag;
                break;
            }
			// NEO: MCS END

			default:{
				taglist.Add(newtag);
			}
		}
	}

	CheckTweaks();

	PartFile->SetAutoHardLimit(GetMinimalHardLimit()); // NEO: AHL - [AutoHardLimit]

	return true;
}

void CPartPreferences::CheckTweaks(){
	// NEO: NST - [NeoSourceTweaks]
	if(m_iHardLimit) MinMax(&m_iHardLimit,VAL_HARD_LIMIT_MIN,VAL_HARD_LIMIT_MAX);
	if(m_iSwapLimit) MinMax(&m_iSwapLimit,VAL_SWAP_LIMIT_MIN,VAL_SWAP_LIMIT_MAX);
	if(m_iSwapLimit) Maximal(&m_iSwapLimit,GetHardLimit(true));
	if(m_iCleanUpLimit) MinMax(&m_iCleanUpLimit,VAL_CLEANUP_LIMIT_MIN,VAL_CLEANUP_LIMIT_MAX);
	if(m_iCleanUpLimit) Maximal(&m_iCleanUpLimit,GetHardLimit(true));

	if(m_iXSLimit) MinMax(&m_iXSLimit,VAL_XS_LIMIT_MIN,VAL_XS_LIMIT_MAX);
	if(m_iXSLimit) Maximal(&m_iXSLimit,GetHardLimit(true));
	if(m_iXSIntervals) MinMax(&m_iXSIntervals,TIM_XS_INTERVAL_MIN,TIM_XS_INTERVAL_MAX);
	if(m_iXSDelayValue) MinMax(&m_iXSDelayValue,VAL_XS_DELAY_MIN,VAL_XS_DELAY_MAX);

	if(m_iSVRLimit) MinMax(&m_iSVRLimit,VAL_SVR_LIMIT_MIN,VAL_SVR_LIMIT_MAX);
	if(m_iSVRLimit) Maximal(&m_iSVRLimit,GetXSLimit(true));
	if(m_iSVRIntervals) MinMax(&m_iSVRIntervals,TIM_SVR_INTERVAL_MIN,TIM_SVR_INTERVAL_MAX);

	if(m_iKADLimit) MinMax(&m_iKADLimit,VAL_KAD_LIMIT_MIN,VAL_KAD_LIMIT_MAX);
	if(m_iKADLimit) Maximal(&m_iKADLimit,GetSVRLimit(true));
	if(m_iKADIntervals) MinMax(&m_iKADIntervals,TIM_KAD_INTERVAL_MIN,TIM_KAD_INTERVAL_MAX);
	if(m_iKADDelayValue) MinMax(&m_iKADDelayValue,VAL_KAD_DELAY_MIN,VAL_KAD_DELAY_MAX);

	if(m_iUDPLimit) MinMax(&m_iUDPLimit,VAL_UDP_LIMIT_MIN,VAL_UDP_LIMIT_MAX);
	if(m_iUDPLimit) Maximal(&m_iUDPLimit,GetKADLimit(true));
	if(m_iUDPIntervals) MinMax(&m_iUDPIntervals,TIM_UDP_INTERVAL_MIN,TIM_UDP_INTERVAL_MAX);
	// NEO: NST END

#ifdef LANCAST // NEO: NLC - [NeoLanCast]
	if(m_iLANIntervals) MinMax(&m_iLANIntervals,TIM_LAN_INTERVAL_MIN,TIM_LAN_INTERVAL_MAX);
	
	if(m_iLanReaskIntervals) MinMax(&m_iLanReaskIntervals,TIM_REASK_LAN_MIN,TIM_REASK_LAN_MAX);

	if(m_iNnPLanReaskIntervals) MinMax(&m_iNnPLanReaskIntervals,TIM_REASK_NNP_LAN_MIN,TIM_REASK_NNP_LAN_MAX);
	if(m_iNnPLanReaskIntervals) Minimal(&m_iNnPLanReaskIntervals,m_iLanReaskIntervals);
#endif //LANCAST // NEO: NLC END

	// NEO: NSD - [NeoSourceDrop]
	if(m_iLow2LowCleanUpTime) MinMax(&m_iLow2LowCleanUpTime,VAL_CLEANUP_TIME_MIN,VAL_CLEANUP_TIME_MAX);
#if defined(NEO_SK) || defined(NEO_SS) // NEO: NSK - [NeoSourceKeeper] // NEO: NSS - [NeoSourceStorage]
	if(m_iBadCleanUpTime) MinMax(&m_iBadCleanUpTime,VAL_CLEANUP_TIME_MIN,VAL_CLEANUP_TIME_MAX);
	if(m_iGoneCleanUpTime) MinMax(&m_iGoneCleanUpTime,VAL_CLEANUP_TIME_MIN,VAL_CLEANUP_TIME_MAX);
	if(m_iSuspendCleanUpTime) MinMax(&m_iSuspendCleanUpTime,VAL_CLEANUP_TIME_MIN,VAL_CLEANUP_TIME_MAX);
#endif // NEO_SK // NEO_SS // NEO: NSK END // NEO: NSS END
	if(m_iNnPCleanUpTime) MinMax(&m_iNnPCleanUpTime,VAL_CLEANUP_TIME_MIN,VAL_CLEANUP_TIME_MAX);
	if(m_iFullQCleanUpTime) MinMax(&m_iFullQCleanUpTime,VAL_CLEANUP_TIME_MIN,VAL_CLEANUP_TIME_MAX);
	// NEO: NSD END

	if(m_iAutoSoftLockValue) MinMax(&m_iAutoSoftLockValue,VAL_ASL_MIN,VAL_ASL_MAX); // NEO: ASL - [AutoSoftLock]

	// NEO: AHL - [AutoHardLimit]
	if(m_iAutoHardLimitTimer) MinMax(&m_iAutoHardLimitTimer,TIM_AHL_MIN,TIM_AHL_MAX); 
	if(m_iMinimalHardLimit) MinMax(&m_iMinimalHardLimit,VAL_AHL_MIN_SRC_MIN,VAL_AHL_MIN_SRC_MAX); 
	if(m_iMinimalHardLimit) Maximal(&m_iMinimalHardLimit,m_iHardLimit);
	// NEO: AHL END

	// NEO: XSC - [ExtremeSourceCache]
	if(m_iSourceCacheLimit) MinMax(&m_iSourceCacheLimit,VAL_SOURCE_CACHE_LIMIT_MIN,VAL_SOURCE_CACHE_LIMIT_MAX); 
	if(m_iSourceCacheTime) MinMax(&m_iSourceCacheTime,TIM_SOURCE_CACHE_TIME_MIN,TIM_SOURCE_CACHE_TIME_MAX); 
	// NEO: XSC END

	// NEO: DR - [DownloadReask]
	if(m_iReaskIntervals) MinMax(&m_iReaskIntervals,TIM_REASK_MIN,TIM_REASK_MAX);
	if(m_iNnPReaskIntervals) MinMax(&m_iNnPReaskIntervals,TIM_REASK_NNP_MIN,TIM_REASK_NNP_MAX);
	if(m_iFullQReaskIntervals) MinMax(&m_iFullQReaskIntervals,TIM_REASK_FULLQ_MIN,TIM_REASK_FULLQ_MAX);
	// NEO: DR END

#ifdef NEO_SS // NEO: NSS - [NeoSourceStorage]
	if(m_iAutoSaveSourcesIntervals) MinMax(&m_iAutoSaveSourcesIntervals,TIM_AUTO_SAVE_SOURCES_INTERVALS_MIN,TIM_AUTO_SAVE_SOURCES_INTERVALS_MAX);
	if(m_iSourceStorageLimit) MinMax(&m_iSourceStorageLimit,SOURCE_STORAGE_LIMIT_MIN,SOURCE_STORAGE_LIMIT_MAX);

	if(m_iStorageBootstrapTime) MinMax(&m_iStorageBootstrapTime,STORAGE_BOOTSTRAP_TIME_MIN,STORAGE_BOOTSTRAP_TIME_MAX);
	if(m_iStorageBootstrapRequirement) MinMax(&m_iStorageBootstrapRequirement,STORAGE_BOOTSTRAP_REQUIREMENT_MIN,STORAGE_BOOTSTRAP_REQUIREMENT_MAX);

	if(m_iAutoReaskStoredSourcesLimit) MinMax(&m_iAutoReaskStoredSourcesLimit,AUTO_REASK_STORED_SOURCES_LIMIT_MIN,AUTO_REASK_STORED_SOURCES_LIMIT_MAX);
	if(m_iAutoReaskStoredSourcesDelay) MinMax(&m_iAutoReaskStoredSourcesDelay,AUTO_REASK_STORED_SOURCES_DELAY_MIN,AUTO_REASK_STORED_SOURCES_DELAY_MAX);

	if(m_iAutoReaskLoadedSourcesDelay) MinMax(&m_iAutoReaskLoadedSourcesDelay,AUTO_REASK_LOADED_SOURCES_DELAY_MIN,AUTO_REASK_LOADED_SOURCES_DELAY_MAX);

	if(m_iStoredSourceGroupIntervals) MinMax(&m_iStoredSourceGroupIntervals,GROUP_INTERVALS_MIN,GROUP_INTERVALS_MAX);
	if(m_iStoredSourceGroupSize) MinMax(&m_iStoredSourceGroupSize,GROUP_SIZE_MIN,GROUP_SIZE_MAX);

	if(m_iMaxStoredFaildCount) MinMax(&m_iMaxStoredFaildCount,OUTOFDATE_MAXFAILS_MIN,OUTOFDATE_MAXFAILS_MAX);
	if(m_iStoredOutOfDate) MinMax(&m_iStoredOutOfDate,OUTOFDATE_MAXTIME_MIN,OUTOFDATE_MAXTIME_MAX);
#endif // NEO_SS // NEO: NSS END
#ifdef NEO_SA // NEO: NSA - [NeoSourceAnaliser]
	if(m_fEnhancedFactor) MinMax(&m_fEnhancedFactor,VAL_ENHANCED_FACTOR_MIN,VAL_ENHANCED_FACTOR_MAX);

	if(m_iReaskPropability) MinMax(&m_iReaskPropability,REASK_PROPABILITY_MIN,REASK_PROPABILITY_MAX);
	if(m_iReservePropability) MinMax(&m_iReservePropability,RESERVE_PROPABILITY_MIN,RESERVE_PROPABILITY_MAX);
	if(m_iReservePropability) Minimal(&m_iReservePropability,GetReserveReaskPropability());

	if(m_iReserveReaskPropability) MinMax(&m_iReserveReaskPropability,RESERVE_REASK_PROPABILITY_MIN,RESERVE_REASK_PROPABILITY_MAX);
	if(m_iReserveReaskPropability) Minimal(&m_iReserveReaskPropability,GetReaskPropability());
	if(m_iReaskReserveSourcesDelay) MinMax(&m_iReaskReserveSourcesDelay,RESERVE_REASK_DELAY_MIN,RESERVE_REASK_DELAY_MAX);
	if(m_iReaskReserveSourcesLimit) MinMax(&m_iReaskReserveSourcesLimit,RESERVE_REASK_LIMIT_MIN,RESERVE_REASK_LIMIT_MAX);

	if(m_iTemporaryReaskPropability) MinMax(&m_iTemporaryReaskPropability,TEMPORARY_REASK_PROPABILITY_MIN,TEMPORARY_REASK_PROPABILITY_MAX);
	if(m_iTemporaryReaskPropability) Maximal(&m_iTemporaryReaskPropability,m_iReaskPropability);
	if(m_iReaskTemporarySourcesDelay) MinMax(&m_iReaskTemporarySourcesDelay,TEMPORARY_REASK_DELAY_MIN,TEMPORARY_REASK_DELAY_MAX);
	if(m_iReaskTemporarySourcesLimit) MinMax(&m_iReaskTemporarySourcesLimit,TEMPORARY_REASK_LIMIT_MIN,TEMPORARY_REASK_LIMIT_MAX);

	//if(m_iMinAnalisisQuality) MinMax(&m_iMinAnalisisQuality,MIN_ANALISIS_QUALITY_MIN,MIN_ANALISIS_QUALITY_MAX);

	//if(m_iReaskUnsureSourcesDelay) MinMax(&m_iReaskUnsureSourcesDelay,UNSURE_REASK_DELAY_MIN,UNSURE_REASK_DELAY_MAX);
	//if(m_iReaskUnsureSourcesLimit) MinMax(&m_iReaskUnsureSourcesLimit,UNSURE_REASK_LIMIT_MIN,UNSURE_REASK_LIMIT_MAX);

	if(m_iUnpredictedPropability) MinMax(&m_iUnpredictedPropability,UNPREDICTED_PROPABILITY_MIN,UNPREDICTED_PROPABILITY_MAX);
	if(m_iReaskUnpredictedSourcesDelay) MinMax(&m_iReaskUnpredictedSourcesDelay,UNPREDICTED_REASK_DELAY_MIN,UNPREDICTED_REASK_DELAY_MAX);
	if(m_iReaskUnpredictedSourcesLimit) MinMax(&m_iReaskUnpredictedSourcesLimit,UNPREDICTED_REASK_LIMIT_MIN,UNPREDICTED_REASK_LIMIT_MAX);

	if(m_iRetryUnreachableIntervals) MinMax(&m_iRetryUnreachableIntervals,RETRY_UNREAHABLE_INTERVALS_MIN,RETRY_UNREAHABLE_INTERVALS_MAX);
	if(m_iMaxFailTolerance) MinMax(&m_iMaxFailTolerance,FAIL_TOLERANCE_MIN,FAIL_TOLERANCE_MAX);
	if(m_iUnreachableReaskPropability) MinMax(&m_iUnreachableReaskPropability,UNREACHABLE_REASK_PROPABILITY_MIN,UNREACHABLE_REASK_PROPABILITY_MAX);
	if(m_iReaskUnreachableSourcesLimit) MinMax(&m_iReaskUnreachableSourcesLimit,UNREACHABLE_REASK_LIMIT_MIN,UNREACHABLE_REASK_LIMIT_MAX);
#endif // NEO_SA // NEO: NSA END

	// NEO: DS - [DropSources]
	if(m_iDropNnPTimer) MinMax(&m_iDropNnPTimer,TIM_DROP_MIN,TIM_DROP_MAX);
	if(m_iDropNnPLimit) MinMax(&m_iDropHighQLimit,VAL_DROP_LIMIT_MIN(m_iDropHighQLimitMode),VAL_DROP_LIMIT_MAX(m_iDropHighQLimitMode));

	if(m_iDropFullQTimer) MinMax(&m_iDropFullQTimer,TIM_DROP_MIN,TIM_DROP_MAX);
	if(m_iDropFullQLimit) MinMax(&m_iDropHighQLimit,VAL_DROP_LIMIT_MIN(m_iDropHighQLimitMode),VAL_DROP_LIMIT_MAX(m_iDropHighQLimitMode));

	if(m_iDropHighQValue) MinMax(&m_iDropHighQValue,VAL_DROP_HQ_VALUE_MIN,VAL_DROP_HQ_VALUE_MAX);
	if(m_iDropHighQLimit) MinMax(&m_iDropHighQLimit,VAL_DROP_LIMIT_MIN(m_iDropHighQLimitMode),VAL_DROP_LIMIT_MAX(m_iDropHighQLimitMode));
	if(m_iDropHighQTimer) MinMax(&m_iDropHighQTimer,TIM_DROP_MIN,TIM_DROP_MAX);

	if(m_iDontAskThisIPTime) MinMax(&m_iDontAskThisIPTime,VAL_DONT_ASK_THIS_IP_TIME_MIN,VAL_DONT_ASK_THIS_IP_TIME_MAX);
	// NEO: DS END

	// NEO: NSD - [NeoSourceDrop]
#ifdef NEO_SK // NEO: NSK - [NeoSourceKeeper]
	if(m_iDropUnreachableLimit) MinMax(&m_iDropUnreachableLimit,VAL_CLEAN_LIMIT_MIN(m_iDropUnreachableLimitMode),VAL_CLEAN_LIMIT_MAX(m_iDropUnreachableLimitMode));
	if(m_iDropUnreachableTimer) MinMax(&m_iDropUnreachableTimer,TIM_DROP_MIN,TIM_DROP_MAX);
#endif // NEO_SK // NEO: NSK END
#ifdef NEO_SS // NEO: NSS - [NeoSourceStorage]
	if(m_iDropOutOfDateFails) MinMax(&m_iDropOutOfDateFails,OUTOFDATE_MAXFAILS_MIN,OUTOFDATE_MAXFAILS_MAX);
	if(m_iDropOutOfDateTime) MinMax(&m_iDropOutOfDateTime,OUTOFDATE_MAXTIME_MIN,OUTOFDATE_MAXTIME_MAX);
	if(m_iDropOutOfDateLimit) MinMax(&m_iDropOutOfDateLimit,VAL_CLEAN_LIMIT_MIN(m_iDropOutOfDateLimitMode),VAL_CLEAN_LIMIT_MAX(m_iDropOutOfDateLimitMode));
	if(m_iDropOutOfDateTimer) MinMax(&m_iDropOutOfDateTimer,TIM_DROP_MIN,TIM_DROP_MAX);
#endif // NEO_SS // NEO: NSS END
#ifdef NEO_SA // NEO: NSA - [NeoSourceAnaliser]
	if(m_iDropRetiredLimit) MinMax(&m_iDropRetiredLimit,VAL_CLEAN_LIMIT_MIN(m_iDropRetiredLimitMode),VAL_CLEAN_LIMIT_MAX(m_iDropRetiredLimitMode));
	if(m_iDropRetiredTimer) MinMax(&m_iDropRetiredTimer,TIM_DROP_MIN,TIM_DROP_MAX);

	if(m_iDropLoadedLimit) MinMax(&m_iDropLoadedLimit,VAL_CLEAN_LIMIT_MIN(m_iDropLoadedLimitMode),VAL_CLEAN_LIMIT_MAX(m_iDropLoadedLimitMode));
	if(m_iDropLoadedTimer) MinMax(&m_iDropLoadedTimer,TIM_DROP_MIN,TIM_DROP_MAX);
#endif // NEO_SA // NEO: NSA END
	// NEO: NSD END

	// NEO: NCAP - [NeoCustomAutoPriority]
	if(m_iLowDownPrioThreshold) MinMax(&m_iLowDownPrioThreshold,VAL_LOW_DOWN_PRIO_THRESHOLD_MIN,VAL_LOW_DOWN_PRIO_THRESHOLD_MAX);
	if(m_iHighDownPrioThreshold) MinMax(&m_iHighDownPrioThreshold,VAL_HIGH_DOWN_PRIO_THRESHOLD_MIN,VAL_HIGH_DOWN_PRIO_THRESHOLD_MAX);
	if(m_iHighDownPrioThreshold) Maximal(&m_iHighDownPrioThreshold,m_iLowDownPrioThreshold);
	// NEO: NCAP END

#ifdef VOODOO // NEO: VOODOOn - [VoodooExtensionForNeo]
	if(thePrefs.IsVoodooNeoPreferences() && PartFile->KnownPrefs.UseVoodoo())
		theApp.voodoo->ManifestFilePreferences(PartFile);
#endif // VOODOO // NEO: VOODOOn END
}

// NEO: NST - [NeoSourceTweaks]
bool CPartPreferences::IsCalcStandardLimits(){
	if(m_iCalcStandardLimits) 
		return m_iCalcStandardLimits == 1 ? 1 : 0;
	return thePrefs.IsCalcStandardLimits();
}

int CPartPreferences::GetHardLimit(bool bIgnoreAuto){
	// NEO: AHL - [AutoHardLimit]
	if(UseAutoHardLimit() && !bIgnoreAuto)
		return PartFile->GetAutoHardLimit();
	// NEO: AHL END
	return m_iHardLimit ? m_iHardLimit : thePrefs.GetHardLimit();
}

int CPartPreferences::GetSwapLimit(){
	// NEO: AHL - [AutoHardLimit]
	if(IsCalcStandardLimits() || UseAutoHardLimit()){
		int Temp = (GetHardLimit() * 8L) / 10;
		if(!IsCalcStandardLimits()){
			int Limit = m_iSwapLimit ? m_iSwapLimit : thePrefs.GetSwapLimit();
			if (Temp > Limit)
				return Limit;
		}else{
			if (Temp > VAL_SWAP_LIMIT_MAX)
				return VAL_SWAP_LIMIT_MAX;
		}
		return Temp;
	}
	// NEO: AHL END

	return m_iSwapLimit ? m_iSwapLimit : thePrefs.GetSwapLimit();
}

int CPartPreferences::GetCleanUpLimit(){
	// NEO: AHL - [AutoHardLimit]
	if(IsCalcStandardLimits() || UseAutoHardLimit()){
		int Temp = (GetHardLimit() * 8L) / 10;
		if(!IsCalcStandardLimits()){
			int Limit = m_iCleanUpLimit ? m_iCleanUpLimit : thePrefs.GetCleanUpLimit();
			if (Temp > Limit)
				return Limit;
		}else{
			if (Temp > VAL_CLEANUP_LIMIT_MAX)
				return VAL_CLEANUP_LIMIT_MAX;
		}
		return Temp;
	}
	// NEO: AHL END

	return m_iCleanUpLimit ? m_iCleanUpLimit : thePrefs.GetCleanUpLimit();
}

bool CPartPreferences::UseXS(){
	if(PartFile->IsCollectingHalted()) // NEO: ASL - [AutoSoftLock]
		return false;
	if(m_iXSState) 
		return m_iXSState == 1 ? 1 : 0;
	return !thePrefs.IsXSDisable();
}
int CPartPreferences::GetXSLimit(bool bIgnoreAuto){
	// NEO: AHL - [AutoHardLimit]
	if((IsCalcStandardLimits() || UseAutoHardLimit()) && !bIgnoreAuto){
		int Temp = (GetHardLimit() * 9L) / 10;
		if(!IsCalcStandardLimits()){
			int Limit = m_iXSLimit ? m_iXSLimit : thePrefs.GetXSLimit();
			if (Temp > Limit)
				return Limit;
		}else{
			if (Temp > VAL_XS_LIMIT_MAX)
				return VAL_XS_LIMIT_MAX;
		}
		return Temp;
	}
	// NEO: AHL END

	return m_iXSLimit ? m_iXSLimit : thePrefs.GetXSLimit();

}
int CPartPreferences::GetXSIntervals(){
	return m_iXSIntervals ? m_iXSIntervals : thePrefs.GetXSIntervals();
}

int CPartPreferences::GetXSDelayValue(){
	return m_iXSDelayValue ? m_iXSDelayValue : thePrefs.GetXSDelayValue();
}


bool CPartPreferences::UseSVR(){
	if(PartFile->IsCollectingHalted()) // NEO: ASL - [AutoSoftLock]
		return false;
	if(m_iSVRState) 
		return m_iSVRState == 1 ? 1 : 0;
	return !thePrefs.IsSVRDisable();
}
int CPartPreferences::GetSVRLimit(bool bIgnoreAuto){
	// NEO: AHL - [AutoHardLimit]
	if((IsCalcStandardLimits() || UseAutoHardLimit()) && !bIgnoreAuto){
		int Temp = (GetHardLimit() * 8L) / 10;
		if(!IsCalcStandardLimits()){
			int Limit = m_iSVRLimit ? m_iSVRLimit : thePrefs.GetSVRLimit();
			if (Temp > Limit)
				return Limit;
		}else{
			if (Temp > VAL_SVR_LIMIT_MAX)
				return VAL_SVR_LIMIT_MAX;
		}
		return Temp;
	}
	// NEO: AHL END

	return m_iSVRLimit ? m_iSVRLimit : thePrefs.GetSVRLimit();
}
int CPartPreferences::GetSVRIntervals(){
	return m_iSVRIntervals ? m_iSVRIntervals : thePrefs.GetSVRIntervals();
}

bool CPartPreferences::UseKAD(){
	if(PartFile->IsCollectingHalted()) // NEO: ASL - [AutoSoftLock]
		return false;
	if(m_iKADState) 
		return m_iKADState == 1 ? 1 : 0;
	return !thePrefs.IsKADDisable();
}
int CPartPreferences::GetKADLimit(bool bIgnoreAuto){
	// NEO: AHL - [AutoHardLimit]
	if((IsCalcStandardLimits() || UseAutoHardLimit()) && !bIgnoreAuto){
		int Temp = (GetHardLimit() * 3L) / 4;
		if(!IsCalcStandardLimits()){
			int Limit = m_iKADLimit ? m_iKADLimit : thePrefs.GetKADLimit();
			if (Temp > Limit)
				return Limit;
		}else{
			if (Temp > VAL_KAD_LIMIT_MAX)
				return VAL_KAD_LIMIT_MAX;
		}
		return Temp;
	}
	// NEO: AHL END

	return m_iKADLimit ? m_iKADLimit : thePrefs.GetKADLimit();
}
int CPartPreferences::GetKADIntervals(){
	return m_iKADIntervals ? m_iKADIntervals : thePrefs.GetKADIntervals();
}

int CPartPreferences::GetKADDelayValue(){
	return m_iKADDelayValue ? m_iKADDelayValue : thePrefs.GetKADDelayValue();
}

bool CPartPreferences::UseUDP(){
	if(PartFile->IsCollectingHalted()) // NEO: ASL - [AutoSoftLock]
		return false;
	if(m_iUDPState) 
		return m_iUDPState == 1 ? 1 : 0;
	return !thePrefs.IsUDPDisable();
}
int CPartPreferences::GetUDPLimit(bool bIgnoreAuto){
	// NEO: AHL - [AutoHardLimit]
	if((IsCalcStandardLimits() || UseAutoHardLimit()) && !bIgnoreAuto){
		int Temp = (GetHardLimit() * 2L) / 4;
		if(!IsCalcStandardLimits()){
			int Limit = m_iUDPLimit ? m_iUDPLimit : thePrefs.GetUDPLimit();
			if (Temp > Limit)
				return Limit;
		}else{
			if (Temp > VAL_UDP_LIMIT_MAX)
				return VAL_UDP_LIMIT_MAX;
		}
		return Temp;
	}
	// NEO: AHL END
	return m_iUDPLimit ? m_iUDPLimit : thePrefs.GetUDPLimit();
}
int CPartPreferences::GetUDPIntervals(){
	return m_iUDPIntervals ? m_iUDPIntervals : thePrefs.GetUDPIntervals();
}

// NEO: NST END

#ifdef LANCAST // NEO: NLC - [NeoLanCast]
bool CPartPreferences::UseLAN(){
	return m_bDisableLAN == false;
}

int CPartPreferences::GetLANIntervals(){
	return m_iLANIntervals ? m_iLANIntervals : thePrefs.GetLANIntervals();
}

int CPartPreferences::GetLanReaskIntervals(){
	return m_iLanReaskIntervals ? m_iLanReaskIntervals : thePrefs.GetLanReaskIntervals();
}

int CPartPreferences::GetNnPLanReaskIntervals(){
	return m_iNnPLanReaskIntervals ? m_iNnPLanReaskIntervals : thePrefs.GetNnPLanReaskIntervals();
}
#endif //LANCAST // NEO: NLC END

// NEO: NSD - [NeoSourceDrop]
int CPartPreferences::GetLow2LowCleanUpTime(){
	return m_iLow2LowCleanUpTime ? m_iLow2LowCleanUpTime : thePrefs.GetLow2LowCleanUpTime();
}
#if defined(NEO_SK) || defined(NEO_SS) // NEO: NSK - [NeoSourceKeeper] // NEO: NSS - [NeoSourceStorage]
int CPartPreferences::GetBadCleanUpTime(){
	return m_iBadCleanUpTime ? m_iBadCleanUpTime : thePrefs.GetBadCleanUpTime();
}
int CPartPreferences::GetGoneCleanUpTime(){
	return m_iGoneCleanUpTime ? m_iGoneCleanUpTime : thePrefs.GetGoneCleanUpTime();
}
int CPartPreferences::GetSuspendCleanUpTime(){
	return m_iSuspendCleanUpTime ? m_iSuspendCleanUpTime : thePrefs.GetSuspendCleanUpTime();
}
#endif // NEO_SK // NEO_SS // NEO: NSK END // NEO: NSS END
int CPartPreferences::GetNnPCleanUpTime(){
	return m_iNnPCleanUpTime ? m_iNnPCleanUpTime : thePrefs.GetNnPCleanUpTime();
}
int CPartPreferences::GetFullQCleanUpTime(){
	return m_iFullQCleanUpTime ? m_iFullQCleanUpTime : thePrefs.GetFullQCleanUpTime();
}
// NEO: NSD END

// NEO: ASL - [AutoSoftLock]
bool CPartPreferences::UseAutoSoftLock(){
	if(m_iAutoSoftLock) 
		return m_iAutoSoftLock == 1 ? 1 : 0;
	return thePrefs.UseAutoSoftLock();
}
int CPartPreferences::GetAutoSoftLockValue(){
	return m_iAutoSoftLockValue ? m_iAutoSoftLockValue : thePrefs.GetAutoSoftLockValue();
}
// NEO: ASL END

// NEO: AHL - [AutoHardLimit]
/*
* 0 - default
* 1 - max
* 2 - new
* 3 - old
* 4 - disabled
*/
int CPartPreferences::UseAutoHardLimit(){
	if(m_iAutoHardLimit) 
		return m_iAutoHardLimit == 4 ? 0 : m_iAutoHardLimit;
	return thePrefs.UseAutoHardLimit();
}
int CPartPreferences::GetMinimalHardLimit(){
	return m_iMinimalHardLimit ? m_iMinimalHardLimit : thePrefs.GetMinimalHardLimit();
}
int CPartPreferences::GetAutoHardLimitTimer(){
	return m_iAutoHardLimitTimer ? m_iAutoHardLimitTimer : thePrefs.GetAutoHardLimitTimer();
}
// NEO: AHL END

// NEO: XSC - [ExtremeSourceCache]
bool CPartPreferences::UseSourceCache(){
	if(m_iSourceCache) 
		return m_iSourceCache == 1 ? 1 : 0;
	return thePrefs.UseSourceCache();
}
int CPartPreferences::GetSourceCacheLimit(){
	return m_iSourceCacheLimit ? m_iSourceCacheLimit : thePrefs.GetSourceCacheLimit();
}
int CPartPreferences::GetSourceCacheTime(){
	return m_iSourceCacheTime ? m_iSourceCacheTime : thePrefs.GetSourceCacheTime();
}
// NEO: XSC END

// NEO: DR - [DownloadReask]
int CPartPreferences::GetReaskIntervals(){
	return m_iReaskIntervals ? m_iReaskIntervals : thePrefs.GetReaskIntervals();
}

bool CPartPreferences::DontNnPReask(){
	if(m_iNnPReask) 
		return m_iNnPReask == 1 ? 0 : 1;
	return thePrefs.DontNnPReask();
}
int CPartPreferences::GetNnPReaskIntervals(){
	return m_iNnPReaskIntervals ? m_iNnPReaskIntervals : thePrefs.GetNnPReaskIntervals();
}

bool CPartPreferences::DontFullQReask(){
	if(m_iFullQReask) 
		return m_iFullQReask == 1 ? 0 : 1;
	return thePrefs.DontFullQReask();
}
int CPartPreferences::GetFullQReaskIntervals(){
	return m_iFullQReaskIntervals ? m_iFullQReaskIntervals : thePrefs.GetFullQReaskIntervals();
}
// NEO: DR END

#ifdef NEO_SK // NEO: NSK - [NeoSourceKeeper]
bool CPartPreferences::EnableSourceKeeper(){
	if(m_iEnableSourceKeeper) 
		return m_iEnableSourceKeeper == 1 ? 1 : 0;
	return thePrefs.EnableSourceKeeper();
}
#endif // NEO_SK // NEO: NSK END
#ifdef NEO_SS // NEO: NSS - [NeoSourceStorage]
bool CPartPreferences::EnableSourceStorage(){
	if(m_iEnableSourceStorage) 
		return m_iEnableSourceStorage == 1 ? 1 : 0;
	return thePrefs.EnableSourceStorage();
}
UINT CPartPreferences::AutoSaveSources(){
	if(!EnableSourceStorage())
		return false;
	if(m_iAutoSaveSources) 
		return m_iAutoSaveSources == 3 ? 0 : m_iAutoSaveSources;
	return thePrefs.AutoSaveSources();
}
int CPartPreferences::GetAutoSaveSourcesIntervals(){
	return m_iAutoSaveSourcesIntervals ? m_iAutoSaveSourcesIntervals : thePrefs.GetAutoSaveSourcesIntervals();
}
int CPartPreferences::GetSourceStorageLimit(){
	return m_iSourceStorageLimit ? m_iSourceStorageLimit : thePrefs.GetSourceStorageLimit();
}
UINT CPartPreferences::AutoLoadStoredSources(){
	if(!EnableSourceStorage())
		return false;
	if(m_iAutoLoadStoredSources) 
		return m_iAutoLoadStoredSources == 3 ? 0 : m_iAutoLoadStoredSources;
	return thePrefs.AutoLoadStoredSources();
}

bool CPartPreferences::UseStorageBootstrap(){
	if(!AutoReaskStoredSources())
		return false;
	if(m_iUseStorageBootstrap)
		return m_iUseStorageBootstrap == 1 ? 1 : 0;
	return thePrefs.UseStorageBootstrap();
}
int CPartPreferences::GetStorageBootstrapTime(){
	return m_iStorageBootstrapTime ? m_iStorageBootstrapTime : thePrefs.GetStorageBootstrapTime();
}
int CPartPreferences::GetStorageBootstrapRequirement(){
	return m_iStorageBootstrapRequirement ? m_iStorageBootstrapRequirement : thePrefs.GetStorageBootstrapRequirement();
}
bool CPartPreferences::StoreLowIDSources(){
	if(m_iStoreLowIDSources) 
		return m_iStoreLowIDSources == 1 ? 1 : 0;
	return thePrefs.StoreLowIDSources();
}
bool CPartPreferences::StoreAlsoA4AFSources(){
	if(m_iStoreAlsoA4AFSources) 
		return m_iStoreAlsoA4AFSources == 1 ? 1 : 0;
	return thePrefs.StoreAlsoA4AFSources();
}
UINT CPartPreferences::StoreSourcesFileStatus(){
	if(m_iStoreSourcesFileStatus) 
		return m_iStoreSourcesFileStatus == 3 ? 0 : m_iStoreSourcesFileStatus;
	return thePrefs.StoreSourcesFileStatus();
}

int CPartPreferences::AutoReaskStoredSources(){
	if(m_iAutoReaskStoredSources) 
		return m_iAutoReaskStoredSources == 1 ? 1 : 0;
	return thePrefs.AutoReaskStoredSources();
}
int CPartPreferences::GetAutoReaskStoredSourcesLimit(){
	if(!EnableSourceAnalizer())
		return min(AUTO_REASK_STORED_SOURCES_LIMIT_RAW,m_iAutoReaskStoredSourcesLimit ? m_iAutoReaskStoredSourcesLimit : thePrefs.GetAutoReaskStoredSourcesLimit());
	return m_iAutoReaskStoredSourcesLimit ? m_iAutoReaskStoredSourcesLimit : thePrefs.GetAutoReaskStoredSourcesLimit();
}
bool CPartPreferences::IsTotalSourceRestore(){
	if(m_iTotalSourceRestore) 
		return m_iTotalSourceRestore == 1 ? 1 : 0;
	return thePrefs.IsTotalSourceRestore();
}
bool CPartPreferences::UseAutoReaskStoredSourcesDelay(){
	if(m_iUseAutoReaskStoredSourcesDelay) 
		return m_iUseAutoReaskStoredSourcesDelay == 1 ? 1 : 0;
	return thePrefs.UseAutoReaskStoredSourcesDelay();
}
int CPartPreferences::GetAutoReaskStoredSourcesDelay(){
	return m_iAutoReaskStoredSourcesDelay ? m_iAutoReaskStoredSourcesDelay : thePrefs.GetAutoReaskStoredSourcesDelay();
}

int CPartPreferences::GetAutoReaskLoadedSourcesDelay(){
	return m_iAutoReaskLoadedSourcesDelay ? m_iAutoReaskLoadedSourcesDelay : thePrefs.GetAutoReaskLoadedSourcesDelay();
}

bool CPartPreferences::GroupStoredSourceReask(){
	if(m_iGroupStoredSourceReask) 
		return m_iGroupStoredSourceReask == 1 ? 1 : 0;
	return thePrefs.GroupStoredSourceReask();
}
int CPartPreferences::GetStoredSourceGroupIntervals(){
	return m_iStoredSourceGroupIntervals ? m_iStoredSourceGroupIntervals : thePrefs.GetStoredSourceGroupIntervals();
}
int CPartPreferences::GetStoredSourceGroupSize(){
	return m_iStoredSourceGroupSize ? m_iStoredSourceGroupSize : thePrefs.GetStoredSourceGroupSize();
}

bool CPartPreferences::UseSmoothOutOfDate(){
	if(m_iUseSmoothOutOfDate) 
		return m_iUseSmoothOutOfDate == 1 ? 1 : 0;
	return thePrefs.UseSmoothOutOfDate();
}
int CPartPreferences::GetMaxStoredFaildCount(){
	return m_iMaxStoredFaildCount ? m_iMaxStoredFaildCount : thePrefs.GetMaxStoredFaildCount();
}
int CPartPreferences::GetStoredOutOfDate(){
	return m_iStoredOutOfDate ? m_iStoredOutOfDate : thePrefs.GetStoredOutOfDate();
}
#endif // NEO_SS // NEO: NSS END
#ifdef NEO_SA // NEO: NSA - [NeoSourceAnaliser]
bool CPartPreferences::EnableSourceAnalizer(){
	if(!thePrefs.EnableSourceList()) // the Source list is nessesery, without it no analisiss can be done
		return false;
	if(m_iEnableSourceAnalizer) 
		return m_iEnableSourceAnalizer == 1 ? 1 : 0;
	return thePrefs.EnableSourceAnalizer();
}

bool CPartPreferences::DontStoreTemporarySources(){
	if(m_iDontStoreTemporarySources) 
		return m_iDontStoreTemporarySources == 1 ? 1 : 0;
	return thePrefs.DontStoreTemporarySources();
}

int CPartPreferences::GetPropabilityMode(){
	if(m_iPropabilityMode) 
		return m_iPropabilityMode - 1;
	return thePrefs.GetPropabilityMode();
}
float CPartPreferences::GetEnhancedFactor(){
	return m_fEnhancedFactor ? m_fEnhancedFactor : thePrefs.GetEnhancedFactor();
}

int CPartPreferences::GetReaskPropability(){
	return m_iReaskPropability ? m_iReaskPropability : thePrefs.GetReaskPropability();
}
int CPartPreferences::GetReservePropability(){
	return m_iReservePropability ? m_iReservePropability : thePrefs.GetReservePropability();
}

bool CPartPreferences::AutoReserveReask(){
	if(!AutoReaskStoredSources())
		return false;
	if(m_iAutoReserveReask) 
		return m_iAutoReserveReask == 1 ? 1 : 0;
	return thePrefs.AutoReserveReask();
}
int CPartPreferences::GetReserveReaskPropability(){
	return m_iReserveReaskPropability ? m_iReserveReaskPropability : thePrefs.GetReserveReaskPropability();
}
bool CPartPreferences::UseReaskReserveSourcesDelay(){
	if(m_iUseReaskReserveSourcesDelay) 
		return m_iUseReaskReserveSourcesDelay == 1 ? 1 : 0;
	return thePrefs.UseReaskReserveSourcesDelay();
}
int CPartPreferences::GetReaskReserveSourcesDelay(){
	return m_iReaskReserveSourcesDelay ? m_iReaskReserveSourcesDelay : thePrefs.GetReaskReserveSourcesDelay();
}
int CPartPreferences::GetReaskReserveSourcesLimit(){
	return m_iReaskReserveSourcesLimit ? m_iReaskReserveSourcesLimit : thePrefs.GetReaskReserveSourcesLimit();
}

bool CPartPreferences::AutoTemporaryReask(){
	if(!AutoReaskStoredSources() || DontStoreTemporarySources())
		return false;
	if(m_iAutoTemporaryReask) 
		return m_iAutoTemporaryReask == 1 ? 1 : 0;
	return thePrefs.AutoTemporaryReask();
}
int CPartPreferences::GetTemporaryReaskPropability(){
	return m_iTemporaryReaskPropability ? m_iTemporaryReaskPropability : thePrefs.GetTemporaryReaskPropability();
}
bool CPartPreferences::UseReaskTemporarySourcesDelay(){
	if(m_iUseReaskTemporarySourcesDelay) 
		return m_iUseReaskTemporarySourcesDelay == 1 ? 1 : 0;
	return thePrefs.UseReaskTemporarySourcesDelay();
}
int CPartPreferences::GetReaskTemporarySourcesDelay(){
	return m_iReaskTemporarySourcesDelay ? m_iReaskTemporarySourcesDelay : thePrefs.GetReaskTemporarySourcesDelay();
}
int CPartPreferences::GetReaskTemporarySourcesLimit(){
	return m_iReaskTemporarySourcesLimit ? m_iReaskTemporarySourcesLimit : thePrefs.GetReaskTemporarySourcesLimit();
}

//int CPartPreferences::GetMinAnalisisQuality(){
//	return m_iMinAnalisisQuality ? m_iMinAnalisisQuality : thePrefs.GetMinAnalisisQuality();
//}

//bool CPartPreferences::AutoUnsureReask(){
//	if(!AutoReaskStoredSources())
//		return false;
//	if(m_iAutoUnsureReask) 
//		return m_iAutoUnsureReask == 1 ? 1 : 0;
//	return thePrefs.AutoUnsureReask();
//}
//bool CPartPreferences::UseReaskUnsureSourcesDelay(){
//	if(m_iUseReaskUnsureSourcesDelay) 
//		return m_iUseReaskUnsureSourcesDelay == 1 ? 1 : 0;
//	return thePrefs.UseReaskUnsureSourcesDelay();
//}
//int CPartPreferences::GetReaskUnsureSourcesDelay(){
//	return m_iReaskUnsureSourcesDelay ? m_iReaskUnsureSourcesDelay : thePrefs.GetReaskUnsureSourcesDelay();
//}
//int CPartPreferences::GetReaskUnsureSourcesLimit(){
//	return m_iReaskUnsureSourcesLimit ? m_iReaskUnsureSourcesLimit : thePrefs.GetReaskUnsureSourcesLimit();
//}

bool CPartPreferences::UseUnpredictedPropability(){
	if(m_iUseUnpredictedPropability) 
		return m_iUseUnpredictedPropability == 1 ? 1 : 0;
	return thePrefs.UseUnpredictedPropability();
}
int CPartPreferences::GetUnpredictedPropability(){
	return m_iUnpredictedPropability ? m_iUnpredictedPropability : thePrefs.GetUnpredictedPropability();
}
bool CPartPreferences::UseReaskUnpredictedSourcesDelay(){
	if(m_iUseReaskUnpredictedSourcesDelay) 
		return m_iUseReaskUnpredictedSourcesDelay == 1 ? 1 : 0;
	return thePrefs.UseReaskUnpredictedSourcesDelay();
}
int CPartPreferences::GetReaskUnpredictedSourcesDelay(){
	return m_iReaskUnpredictedSourcesDelay ? m_iReaskUnpredictedSourcesDelay : thePrefs.GetReaskUnpredictedSourcesDelay();
}
int CPartPreferences::GetReaskUnpredictedSourcesLimit(){
	return m_iReaskUnpredictedSourcesLimit ? m_iReaskUnpredictedSourcesLimit : thePrefs.GetReaskUnpredictedSourcesLimit();
}

UINT CPartPreferences::RetryUnreachable(){
	if(!IsFailTolerance() || !EnableSourceStorage())
		return false;
	if(m_iRetryUnreachable) 
		return m_iRetryUnreachable == 3 ? 0 : m_iRetryUnreachable;
	return thePrefs.RetryUnreachable();
}
int CPartPreferences::GetRetryUnreachableIntervals(){
	return m_iRetryUnreachableIntervals ? m_iRetryUnreachableIntervals : thePrefs.GetRetryUnreachableIntervals();
}

UINT CPartPreferences::IsFailTolerance(){
	if(!EnableSourceAnalizer())
		return false;
	if(m_iFailTolerance) 
		return m_iFailTolerance == 3 ? 0 : m_iFailTolerance;
	return thePrefs.IsFailTolerance();
}
int CPartPreferences::GetMaxFailTolerance(){
	return m_iMaxFailTolerance ? m_iMaxFailTolerance : thePrefs.GetMaxFailTolerance();
}
int CPartPreferences::GetUnreachableReaskPropability(){
	return m_iUnreachableReaskPropability ? m_iUnreachableReaskPropability : thePrefs.GetUnreachableReaskPropability();
}
int CPartPreferences::GetReaskUnreachableSourcesLimit(){
	return m_iReaskUnreachableSourcesLimit ? m_iReaskUnreachableSourcesLimit : thePrefs.GetReaskUnreachableSourcesLimit();
}
#endif // NEO_SA // NEO: NSA END


// NEO: DS - [DropSources]
UINT CPartPreferences::UseDropNnP(){
	if(m_iDropNnP) 
		return m_iDropNnP == 3 ? 0 : m_iDropNnP;
	return thePrefs.UseDropNnP();
}
int CPartPreferences::GetDropNnPLimit(){
	return m_iDropNnPLimit ? m_iDropNnPLimit : thePrefs.GetDropNnPLimit();
}
int CPartPreferences::GetDropNnPLimitMode(){
	if(m_iDropNnPLimitMode) 
		return m_iDropNnPLimitMode == 4 ? 0 : m_iDropNnPLimitMode;
	return thePrefs.GetDropNnPLimitMode();
}
int CPartPreferences::GetDropNnPTimer(){
	return m_iDropNnPTimer ? m_iDropNnPTimer : thePrefs.GetDropNnPTimer();
}

UINT CPartPreferences::UseDropFullQ(){
	if(m_iDropFullQ) 
		return m_iDropFullQ == 3 ? 0 : m_iDropFullQ;
	return thePrefs.UseDropFullQ();
}
int CPartPreferences::GetDropFullQLimit(){
	return m_iDropFullQLimit ? m_iDropFullQLimit : thePrefs.GetDropFullQLimit();
}
int CPartPreferences::GetDropFullQLimitMode(){
	if(m_iDropFullQLimitMode) 
		return m_iDropFullQLimitMode == 4 ? 0 : m_iDropFullQLimitMode;
	return thePrefs.GetDropFullQLimitMode();
}
int CPartPreferences::GetDropFullQTimer(){
	return m_iDropFullQTimer ? m_iDropFullQTimer : thePrefs.GetDropFullQTimer();
}

UINT CPartPreferences::UseDropHighQ(){
	if(m_iDropHighQ) 
		return m_iDropHighQ == 3 ? 0 : m_iDropHighQ;
	return thePrefs.UseDropHighQ();
}
int CPartPreferences::GetDropHighQValue(){
	return m_iDropHighQValue ? m_iDropHighQValue : thePrefs.GetDropHighQValue();
}
int CPartPreferences::GetDropHighQLimit(){
	return m_iDropHighQLimit ? m_iDropHighQLimit : thePrefs.GetDropHighQLimit();
}
int CPartPreferences::GetDropHighQLimitMode(){
	if(m_iDropHighQLimitMode) 
		return m_iDropHighQLimitMode == 4 ? 0 : m_iDropHighQLimitMode;
	return thePrefs.GetDropHighQLimitMode();
}
int CPartPreferences::GetDropHighQTimer(){
	return m_iDropHighQTimer ? m_iDropHighQTimer : thePrefs.GetDropHighQTimer();
}

bool CPartPreferences::UseDontAskThisIPList(){
	if(m_iUseDontAskThisIP) 
		return m_iUseDontAskThisIP == 1 ? 1 : 0;
	return thePrefs.UseDontAskThisIPList();
}
int CPartPreferences::GetDontAskThisIPCleanUpTime(){
	return m_iDontAskThisIPTime ? m_iDontAskThisIPTime : thePrefs.GetDontAskThisIPCleanUpTime();
}
// NEO: DS END

	// NEO: NSD - [NeoSourceDrop]
#ifdef NEO_SK // NEO: NSK - [NeoSourceKeeper]
bool CPartPreferences::UseDropUnreachable(){
	if(m_iDropUnreachable) 
		return m_iDropUnreachable == 1 ? 1 : 0;
	return thePrefs.UseDropUnreachable();
}
int CPartPreferences::GetDropUnreachableLimit(){
	return m_iDropUnreachableLimit ? m_iDropUnreachableLimit : thePrefs.GetDropUnreachableLimit();
}
int CPartPreferences::GetDropUnreachableLimitMode(){
	if(m_iDropUnreachableLimitMode) 
		return m_iDropUnreachableLimitMode == 4 ? 0 : m_iDropUnreachableLimitMode;
	return thePrefs.GetDropUnreachableLimitMode();
}
int CPartPreferences::GetDropUnreachableTimer(){
	return m_iDropUnreachableTimer ? m_iDropUnreachableTimer : thePrefs.GetDropUnreachableTimer();
}

#endif // NEO_SK // NEO: NSK END
#ifdef NEO_SS // NEO: NSS - [NeoSourceStorage]
bool CPartPreferences::UseDropOutOfDate(){
	if(m_iDropOutOfDate) 
		return m_iDropOutOfDate == 1 ? 1 : 0;
	return thePrefs.UseDropOutOfDate();
}
bool CPartPreferences::UseDropOutOfDateSmooth(){
	if(m_iDropOutOfDateSmooth) 
		return m_iDropOutOfDateSmooth == 1 ? 1 : 0;
	return thePrefs.UseDropOutOfDateSmooth();
}
int CPartPreferences::GetDropOutOfDateFails(){
	return m_iDropOutOfDateFails ? m_iDropOutOfDateFails : thePrefs.GetDropOutOfDateFails();
}
int CPartPreferences::GetDropOutOfDateTime(){
	return m_iDropOutOfDateTime ? m_iDropOutOfDateTime : thePrefs.GetDropOutOfDateTime();
}
int CPartPreferences::GetDropOutOfDateLimit(){
	return m_iDropOutOfDateLimit ? m_iDropOutOfDateLimit : thePrefs.GetDropOutOfDateLimit();
}
int CPartPreferences::GetDropOutOfDateLimitMode(){
	if(m_iDropOutOfDateLimitMode) 
		return m_iDropOutOfDateLimitMode == 4 ? 0 : m_iDropOutOfDateLimitMode;
	return thePrefs.GetDropOutOfDateLimitMode();
}
int CPartPreferences::GetDropOutOfDateTimer(){
	return m_iDropOutOfDateTimer ? m_iDropOutOfDateTimer : thePrefs.GetDropOutOfDateTimer();
}
#endif // NEO_SS // NEO: NSS END
#ifdef NEO_SA // NEO: NSA - [NeoSourceAnaliser]
bool CPartPreferences::UseDropRetired(){
	if(m_iDropRetired) 
		return m_iDropRetired == 1 ? 1 : 0;
	return thePrefs.UseDropRetired();
}
int CPartPreferences::GetDropRetiredLimit(){
	return m_iDropRetiredLimit ? m_iDropRetiredLimit : thePrefs.GetDropRetiredLimit();
}
int CPartPreferences::GetDropRetiredLimitMode(){
	if(m_iDropRetiredLimitMode) 
		return m_iDropRetiredLimitMode == 4 ? 0 : m_iDropRetiredLimitMode;
	return thePrefs.GetDropRetiredLimitMode();
}
int CPartPreferences::GetDropRetiredTimer(){
	return m_iDropRetiredTimer ? m_iDropRetiredTimer : thePrefs.GetDropRetiredTimer();
}

bool CPartPreferences::UseDropLoaded(){
	if(m_iDropLoaded) 
		return m_iDropLoaded == 1 ? 1 : 0;
	return thePrefs.UseDropLoaded();
}
int CPartPreferences::GetDropLoadedLimit(){
	return m_iDropLoadedLimit ? m_iDropLoadedLimit : thePrefs.GetDropLoadedLimit();
}
int CPartPreferences::GetDropLoadedLimitMode(){
	if(m_iDropLoadedLimitMode) 
		return m_iDropLoadedLimitMode == 4 ? 0 : m_iDropLoadedLimitMode;
	return thePrefs.GetDropLoadedLimitMode();
}
int CPartPreferences::GetDropLoadedTimer(){
	return m_iDropLoadedTimer ? m_iDropLoadedTimer : thePrefs.GetDropLoadedTimer();
}
#endif // NEO_SA // NEO: NSA END
	// NEO: NSD END

// NEO: NCAP - [NeoCustomAutoPriority]
bool CPartPreferences::UseDynamicAutoDownPriority(){
	if(m_iDynamicAutoDownPriority) 
		return m_iDynamicAutoDownPriority == 1 ? 1 : 0;
	return thePrefs.UseDynamicAutoDownPriority();
}
float CPartPreferences::GetDynamicDownPriorityFactor(){
	return m_fDynamicDownPriorityFactor ? m_fDynamicDownPriorityFactor : thePrefs.GetDynamicDownPriorityFactor();
}
int CPartPreferences::GetLowDownPrioThreshold(){
	return m_iLowDownPrioThreshold ? m_iLowDownPrioThreshold : thePrefs.GetLowDownPrioThreshold();
}
int CPartPreferences::GetHighDownPrioThreshold(){
	return m_iHighDownPrioThreshold ? m_iHighDownPrioThreshold : thePrefs.GetHighDownPrioThreshold();
}
// NEO: NCAP END

// NEO: MCS - [ManualChunkSelection]
uint8 CPartPreferences::GetWantedPart(UINT part) const 
{ 
	uint8 status = PR_PART_NORMAL; 
	if(m_WantedParts.Lookup(part, status)) 
		return status; 
	else 
		return PR_PART_NORMAL; 
}

bool CPartPreferences::HasWantedParts() const
{
	POSITION	pos = m_WantedParts.GetStartPosition();
	UINT		part;
	uint8		status;
	while(pos)
	{
		m_WantedParts.GetNextAssoc(pos, part, status);
		if(status != PR_PART_NORMAL)
			return true;
	}
	return false;
}
// NEO: MCS END

// NEO: MOD - [ChunkSelection]
int	CPartPreferences::GetChunkSelectionMode()
{ 
	if ((m_iChunkSelectionMode == CS_DEFAULT && thePrefs.UseInteligentChunkSelection() == TRUE)
	 || m_iChunkSelectionMode == CS_ICS && thePrefs.UseInteligentChunkSelection())
		return CS_ICS;
	else if(m_iChunkSelectionMode == CS_RC4)
		return CS_RC4;
	else
		return CS_NORMAL;
}
// NEO: MOD END

// NEO: SCT - [SubChunkTransfer]
bool CPartPreferences::UseSubChunkTransfer(){
	if(thePrefs.UseSubChunkTransfer() == FALSE) // protocol dissabled
		return false;
	if (m_iSubChunkTransfer)
		return m_iSubChunkTransfer == 1 ? 1 : 0;
	return (thePrefs.UseSubChunkTransfer() == TRUE);
}
// NEO: SCT END

// NEO: NPC - [NeoPartCatch]
int	CPartPreferences::UsePartCatch(){
	if((m_iPartCatch == 0 && thePrefs.UseRealPartStatus() == 1 && thePrefs.UseAntiHideOS() == 1) 
	 || (m_iPartCatch == 2 && thePrefs.UseRealPartStatus() && thePrefs.UseAntiHideOS()))
		return PART_CATCH_REAL_HIDEN;
	else if((m_iPartCatch == 0 && thePrefs.UseRealPartStatus() == 1) 
	 || (m_iPartCatch == 1 && thePrefs.UseRealPartStatus()))
		return PART_CATCH_REAL;
	else if((m_iPartCatch == 0 && thePrefs.UseAntiHideOS() == 1) 
	 || (m_iPartCatch == 3 && thePrefs.UseAntiHideOS())) 
		return PART_CATCH_HIDEN;
	else 
		return PART_CATCH_DISABLED;
}
bool CPartPreferences::UseAntiHideOS()
{
	if(!thePrefs.UseAntiHideOS())
		return false;
	if(m_iPartCatch)
		return (m_iPartCatch == 3 || m_iPartCatch == 2);
	return thePrefs.UseAntiHideOS() == TRUE;
}
bool CPartPreferences::UseRealPartStatus()
{
	if(!thePrefs.UseRealPartStatus())
		return false;
	if(m_iPartCatch)
		return (m_iPartCatch == 1 || m_iPartCatch == 2);
	return thePrefs.UseRealPartStatus() == TRUE;
}
// NEO: NPC END

#ifdef A4AF_CATS // NEO: MAC - [MorphA4AFCategories]
bool CPartPreferences::ForceAllA4AF()
{
	return (m_iA4AFFlags == 1);
}

bool CPartPreferences::ForceA4AFOff()
{
	return (m_iA4AFFlags == 2);
}
#endif // A4AF_CATS // NEO: MAC END

// NEO: FCFG END <-- Xanatos --