Example #1
0
/*
 * Set a new mapping scheme of property impact
 */
void CHarvestSource::setNewImpactScheme()
{
	H_AUTO(CHarvestSource_setNewImpactScheme);
	
	// Set mapping scheme of property impact
	if ( _IsInNewbieMode )
	{
		// Force "low dangers" for 1 newbie extractor
		_IImpactMappingScheme = (uint16)LowDangerMappings[RandomGenerator.rand( 1 )];
	}
	else
	{
		// Normal dangers
		if ( ForageForceImpactScheme.get() == -1 )
			_IImpactMappingScheme = (uint16)RandomGenerator.rand( 5 );
		else
			_IImpactMappingScheme = (uint16)ForageForceImpactScheme.get();
	}

	sendMessageToExtractors( "FORAGE_SOURCE_IMPACT_MODE", (sint32)_IImpactMappingScheme );

#ifdef NL_DEBUG
	nldebug( "FG: map scheme: %u", _IImpactMappingScheme );
#endif
}
// ----------------------------------------------------------------------------
void CMissionQueueManager::saveToFile()
{
	H_AUTO(CMissionQueueManagerSaveToFile);

	if( _InitOk )
	{
		string sFilename = MissionQueueFile.get();
		
		// save file via Backup Service (BS)
		try
		{
			static CPersistentDataRecordRyzomStore	pdr;
			pdr.clear();
			store(pdr);

			CBackupMsgSaveFile msg( sFilename, CBackupMsgSaveFile::SaveFile, Bsi );
			{
				std::string s;
				pdr.toString(s);
				msg.DataMsg.serialBuffer((uint8*)&s[0], (uint)s.size());
			}
			Bsi.sendFile( msg );
		}
		catch(const Exception &)
		{
			nlwarning("(EGS)<CMissionQueueManager::saveToFile>  :  Can't serial file %s (connection with BS service down ?)",sFilename.c_str());
			return;
		}
	}
}
/**
 * updateShardOpenFromFile()
 * Update ShardOpen from a file.
 * Read a line of text in the file, converts it to int (atoi), then casts into bool for ShardOpen.
 */
void	updateShardOpenFromFile(const std::string& filename)
{
	CIFile	f;

	if (!f.open(filename))
	{
		nlwarning("Failed to update ShardOpen from file '%s', couldn't open file", filename.c_str());
		return;
	}

	try
	{
		char	readBuffer[256];
		f.getline(readBuffer, 256);
		sint state;
		NLMISC::fromString(std::string(readBuffer), state);

		setShardOpenState((TShardOpenState)state);

		nlinfo("Updated ShardOpen state to '%u' from file '%s'", ShardOpen.get(), filename.c_str());
	}
	catch (const Exception& e)
	{
		nlwarning("Failed to update ShardOpen from file '%s', exception raised while getline() '%s'", filename.c_str(), e.what());
	}
}
static void cbGetFileClass( CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId )
{
	if (!BSReadState.get())
		return;

	CMessage msgOut = getFileClassImp(msgin);

	// send the output message
	CUnifiedNetwork::getInstance()->send(serviceId, msgOut);
}
static void cbSyncGetFileClass( CMessage& msgin, TSockId from, CCallbackNetBase &netbase)
{
	if (!BSReadState.get())
		return;

	CMessage msgOut = getFileClassImp(msgin);

	// send the output message
	netbase.send(msgOut, from);
}
static void cbReadMode( CMessage& msgin, TSockId from, CCallbackNetBase &netbase)
{
	// encode the read mode and return
	CMessage msgout("BS_READ_MODE");
	bool readMode = BSReadState.get();
	nlWrite(msgout, serial, readMode);

	// send it back to sender
	netbase.send(msgout, from);
}
//-----------------------------------------------------------------------------
static void cbDisconnection( const string &serviceName, NLNET::TServiceId serviceId, void *arg )
{
	if (serviceName == "BS" && !MasterBSHost.get().empty())
	{
		nlwarning("SLAVE BS: MASTER BS IS DOWN!! File reading allowed!");
		MasterBSUp = false;
		BSReadState = true;

		IService::getInstance()->addStatusTag("MasterDown");
		IService::getInstance()->removeStatusTag("MasterRunning");
	}
} // cbDisconnection //
void	CDirectoryRateStat::writeFile(const std::string& filename, uint32 filesize)
{
	NLMISC::TTime	now = NLMISC::CTime::getLocalTime();
	if (filename.find("www") != std::string::npos)
	{
		_DirectoryMap["www"].write(now, filesize);
	}
	else if (filename.find(StatDirFilter.get()) != std::string::npos)
	{
		_DirectoryMap[NLMISC::CFile::getPath(filename)].write(now, filesize);
	}
}
// a new front end connecting to me, add it
void cbFESConnection (const std::string &serviceName, TServiceId  sid, void *arg)
{
	FESList.push_back (CFES ((TServiceId)sid));
	nldebug("new FES connection: sid %u", sid.get());
	displayFES ();

	bool	dummy;
	FESList.back().reportStateToLS(dummy);

	if (!UsePatchMode.get())
	{
		FESList.back().setToAcceptClients();
	}
}
// ----------------------------------------------------------------------------
void CMissionQueueManager::init()
{
	string sFilename = MissionQueueFile.get();
	sFilename = Bsi.getLocalPath() + sFilename;
	
	if (CFile::fileExists(sFilename))
	{
		static CPersistentDataRecord	pdr;
		pdr.clear();
		pdr.readFromTxtFile(sFilename.c_str());
		apply(pdr);
	}
	_InitOk = true;
}
// ----------------------------------------------------------------------------
void CMissionQueueManager::tickUpdate()
{
	if( IsRingShard ) // Temporary Fix potential problem with multi shard instance Ring unification: 
		return;	// Mission saved tick must be adapted for have relative value saved

	H_AUTO(CMissionQueueManagerUpdate);

	for ( map<uint32,CMissionQueue>::iterator it = _Queues.begin() ; it != _Queues.end() ; ++it )
	{
		(*it).second.tickUpdate();
	}

	// save file when time has come
	if (CTickEventHandler::getGameCycle() % MissionQueueSavePeriod.get() == 0)
		saveToFile();
}
Example #12
0
/*
 * Update
 */
bool	CLogAnalyserService::update()
{
	updateWebConnection();

	// erase queries that have timed out
	NLMISC::TTime	ctime = NLMISC::CTime::getLocalTime();
	std::deque<CQuery*>::iterator	it;
	for (it=_Finished.begin(); it!=_Finished.end(); )
	{
		if (ctime - (*it)->Timeout > QueryTimeout.get() * 1000)
		{
			delete (*it);
			it = _Finished.erase(it);
		}
		else
		{
			++it;
		}
	}

	// current query finished? move to finished, destroy thread
	if (_Current != NULL && _Current->Finished)
	{
		_Finished.push_front(_Current);
		_Current = NULL;

		_Thread->wait();
		delete _Thread;
		_Thread = NULL;
	}

	// no current running task? create new thread, start query
	_Mutex.enter();
	if (_Current == NULL && !_Requests.empty())
	{
		_Current = _Requests.back();
		_Requests.pop_back();

		LogTask.Query = _Current;

		_Thread = IThread::create(&LogTask);
		_Thread->start();
	}
	_Mutex.leave();

	return true;
}
//-----------------------------------------------------------------------------
void CBackupService::init()
{
	FileManager.init();

	setUpdateTimeout(100);
	_SaveStall = false;

	// set the connection and disconnection callbacks
	CUnifiedNetwork::getInstance()->setServiceUpCallback( string("*"), cbConnection, 0);
	CUnifiedNetwork::getInstance()->setServiceDownCallback( string("*"), cbDisconnection, 0);

	CUnifiedNetwork::getInstance()->setServiceUpCallback( string("BS"), cbConnection, 0);
	CUnifiedNetwork::getInstance()->setServiceDownCallback( string("BS"), cbDisconnection, 0);

	// Init the sheet Id 
	CSheetId::init(false);

	if (!MasterBSHost.get().empty())
	{
		IService::getInstance()->addStatusTag("SlaveMode");
		IService::getInstance()->setCurrentStatus("WaitingMaster");

		BSIsSlave = true;
		FileManager.forbidStall();
		// I'm a slave, try to contact master
		string	host = MasterBSHost;
		if (host.find (":") == string::npos)
			host += ":49990";

		CUnifiedNetwork::getInstance()->addService ("BS", CInetAddress(host));
	}

	// set the initial read state from the config file
	CConfigFile::CVar *readState = ConfigFile.getVarPtr("BSReadState");
	if (readState != NULL)
		BSReadState = readState->asBool();


	initWebConnection();

	_CallbackServer = new NLNET::CCallbackServer;
	_CallbackServer->addCallbackArray(cbSyncArray, sizeofarray(cbSyncArray));
	// open the layer 3 callback server if required
	if (L3ListeningPort != 0)
		_CallbackServer->init(L3ListeningPort);
}
// connection to the LS, send the identification message
void cbLSConnection (const std::string &serviceName, TServiceId  sid, void *arg)
{
	sint32 shardId;

	if (IService::getInstance()->haveArg('S'))
	{
		// use the command line param if set
		NLMISC::fromString(IService::getInstance()->getArg('S'), shardId);
	}
	else if (IService::getInstance()->ConfigFile.exists ("ShardId"))
	{
		// use the config file param if set
		shardId = IService::getInstance()->ConfigFile.getVar ("ShardId").asInt();
	}
	else
	{
		shardId = -1;
	}

	if (shardId == -1)
	{
		nlerror ("ShardId variable must be valid (>0)");
	}

	CMessage	msgout ("WS_IDENT");
	msgout.serial (shardId);
	CUnifiedNetwork::getInstance()->send (sid, msgout);

	nlinfo ("Connected to %s-%hu and sent identification with shardId '%d'", serviceName.c_str(), sid.get(), shardId);

	// send state to LS
	setShardOpenState((TShardOpenState)(ShardOpen.get()), false);

	//
	if (!DontUseLS)
	{
		CMessage	msgrpn("REPORT_NO_PATCH");
		CUnifiedNetwork::getInstance()->send("LS", msgrpn);
	}

	bool	reportPatching = false;
	list<CFES>::iterator	itfs;
	for (itfs=FESList.begin(); itfs!=FESList.end(); ++itfs)
		(*itfs).reportStateToLS(reportPatching);
}
/**
 * cbUsePatchMode()
 * Callback for UsePatchMode
 */
void	cbUsePatchMode(IVariable &var)
{
	// if patch mode not set, set all fs in patching mode to accept clients now
	if (!UsePatchMode.get())
	{
		nlinfo("UsePatchMode disabled, switch all patching servers to actual frontends");

		list<CFES>::iterator	it;

		for (it=FESList.begin(); it!=FESList.end(); ++it)
		{
			if ((*it).State == PatchOnly)
			{
				(*it).setToAcceptClients();
			}
		}
	}
}
Example #16
0
void CGearLatency::setSlot( INVENTORIES::TInventory inventory, uint32 slot, const CStaticItem * form, CCharacter * user )
{
	static NLMISC::CSheetId equipSheet("big_equip_item.sbrick");
	
	// checks must be done by the caller
	nlassert(form);
	nlassert(user);
	// ignore instant equip items
	if ( form->TimeToEquip == 0)
		return;
	
	// build a new entry
	CGearSlot gear;
	if (inventory == INVENTORIES::equipment)
		gear.InHand = false;
	else if (inventory == INVENTORIES::handling)
		gear.InHand = true;
	else
		nlerror("setSlot : Invalid inventory %u ('%s') : must be handling or equipment ",inventory,INVENTORIES::toString(inventory).c_str() );
	gear.Slot = slot;
	gear.LatencyEndDate = (form->TimeToEquip * EquipTimeFactor.get()) + CTickEventHandler::getGameCycle();
	
	// add it in our sorted list
	std::list<CGearSlot>::iterator it = _GearLatencies.begin();
	for (; it != _GearLatencies.end(); ++it)
	{
		if ( (*it).LatencyEndDate >= gear.LatencyEndDate )
			break;
	}
	if ( it == _GearLatencies.end() )
	{
//		user->_PropertyDatabase.setProp( "USER:ACT_TSTART", CTickEventHandler::getGameCycle() );
		CBankAccessor_PLR::getUSER().setACT_TSTART(user->_PropertyDatabase, CTickEventHandler::getGameCycle() );
//		user->_PropertyDatabase.setProp( "USER:ACT_TEND", gear.LatencyEndDate );
		CBankAccessor_PLR::getUSER().setACT_TEND(user->_PropertyDatabase, gear.LatencyEndDate );
//		sint64 tmp = (sint64)user->actionCounter();
//		user->_PropertyDatabase.setProp( "USER:ACT_NUMBER", tmp );
//		user->_PropertyDatabase.setProp( "EXECUTE_PHRASE:SHEET", sint64(equipSheet.asInt()) );
		CBankAccessor_PLR::getEXECUTE_PHRASE().setSHEET(user->_PropertyDatabase, equipSheet);
//		user->_PropertyDatabase.setProp( "EXECUTE_PHRASE:PHRASE", 0 );
		CBankAccessor_PLR::getEXECUTE_PHRASE().setPHRASE(user->_PropertyDatabase, 0 );
	}
	_GearLatencies.insert( it, gear );
}// CGearLatency::setSlot
static void cbLoadFile( CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId )
{
	if (!BSReadState.get())
		return;

	try
	{
		CBackupMsgRequestFile	msg;
		msgin.serial(msg);

		CLoadFile*	access = new CLoadFile(msg.FileName, serviceId, msg.RequestId);

		CBackupService::getInstance()->FileManager.stackFileAccess(access);
	}
	catch (...)
	{
		nlwarning("WARNING: caught exception in cbLoadFile()");
	}
}
static void cbSyncLoadFile( CMessage& msgin, TSockId from, CCallbackNetBase &netbase)
{
	if (!BSReadState.get())
		return;

	try
	{
		CBackupMsgRequestFile	msg;
		msgin.serial(msg);

		CLoadFile*	access = new CLoadFile(msg.FileName, TRequester(from, &netbase), msg.RequestId);

		CBackupService::getInstance()->FileManager.stackFileAccess(access);
	}
	catch (...)
	{
		nlwarning("WARNING: caught exception in cbLoadFile()");
	}
}
Example #19
0
void	CMailForumService::checkMail()
{
	TTime	now = CTime::getLocalTime();
	if (now - LastCheckMail < 10*1000)
		return;

	LastCheckMail = now;
	string	dir = CPath::standardizePath(WebRootDirectory)+IncomingMailDirectory.get();

	// no path, no mails
	if (!CFile::isExists(dir))
		return;

	std::vector<std::string>	files;
	CPath::getPathContent(dir, false, false, true, files);

	if (files.empty())
		return;

	uint	i;
	for (i=0; i<files.size(); ++i)
		checkFile(files[i]);
}
// This function is called by FES to setup its PatchAddress
void	cbFESPatchAddress(CMessage &msgin, const std::string &serviceName, TServiceId  sid)
{
	std::string	address;
	msgin.serial(address);

	bool		acceptClients;
	msgin.serial(acceptClients);

	nldebug("Received patch server address '%s' from service %s %d", address.c_str(), serviceName.c_str(), sid.get());

	for (list<CFES>::iterator it = FESList.begin(); it != FESList.end(); it++)
	{
		if ((*it).SId == sid)
		{
			nldebug("Affected patch server address '%s' to frontend %s %d", address.c_str(), serviceName.c_str(), sid.get());

			if (!UsePatchMode.get() && !acceptClients)
			{
				// not in patch mode, force fs to accept clients
				acceptClients = true;
				(*it).setToAcceptClients();
			}

			(*it).PatchAddress = address;
			(*it).State = (acceptClients ? AcceptClientOnly : PatchOnly);
			if (acceptClients)
				nldebug("Frontend %s %d reported to accept client, patching unavailable for that server", address.c_str(), serviceName.c_str(), sid.get());
			else
				nldebug("Frontend %s %d reported to be in patching mode", address.c_str(), serviceName.c_str(), sid.get());

			bool	dummy;
			(*it).reportStateToLS(dummy);
			break;
		}
	}
}
//-----------------------------------------------------------------------------
void	cbReadState(IVariable& v)
{
	if (!BSIsSlave)
		return;
	CBackupService::getInstance()->FileManager.forbidStall(!BSReadState.get());
}
/*
 * Report the accumulated XP during an extraction session. Assumes extractor and source not null.
 */
void CForageProgress::reportXP( CCharacter *extractor, const CHarvestSource *source )
{
	H_AUTO(CForageProgress_reportXP);
	
#if !FINAL_VERSION
	nlassert(extractor);
	nlassert(source);
#endif

	// Don't earn any XP for anyone if the quantity is 0
	if ( amount() == 0 )
		return;

	// Count XP depending on class
	float xpBonusFactor = 0.9f - ForageProspectionXPBonusRatio.get() +
		((((float)(source->getStatQuality()))-5.0f)/(75.0f*5.0f)); // basic gives -10%, supreme gives +10% bonus (5 -> 0.0, 80 -> 0.2)
	float nbParticipants = 1.0f; // at least the extractor

	// Count XP for prospection (if there was one)
	const TDataSetRow& prospectorDataSetRow = source->getProspectorDataSetRow(); // can be invalid (auto-spawned source)
	CCharacter *prospector = PlayerManager.getChar( prospectorDataSetRow ); // checks isAccessible()
	if ( prospector )
	{
		xpBonusFactor += ForageProspectionXPBonusRatio.get();
		if ( prospector != extractor )
			++nbParticipants;
	}

	// Find out how many care casters were useful
	vector<CCharacter*> usefulCareCasters;
	const CHarvestSource::CForagers& foragers = source->foragers();
	CHarvestSource::CForagers::const_iterator itf = foragers.begin(); // the first one is the only one able to extract
	for ( ++itf; itf!=foragers.end(); ++itf )
	{
		const TDataSetRow& ccRowId = (*itf);
		CCharacter *careCaster = PlayerManager.getChar( ccRowId );
		if ( careCaster && careCaster->forageProgress() )
		{
			// Check if this care caster has not changed his target
			if ( careCaster->forageProgress()->sourceRowId() == source->rowId() )
			{
				// Check if this care caster has teamed up with the extractor!
				if ( (careCaster->getTeamId() != CTEAM::InvalidTeamId) && (careCaster->getTeamId() == extractor->getTeamId()) )
				{
					// Check if he casted some useful care
					if ( careCaster->forageProgress()->hasCastedUsefulCare() )
					{
						usefulCareCasters.push_back( careCaster );
						if ( careCaster != prospector ) // don't count the prospector twice
							++nbParticipants;
					}
				}
				else
				{
					PHRASE_UTILITIES::sendDynamicSystemMessage( careCaster->getEntityRowId(), "FORAGE_CARE_XP_NEEDS_TEAM" );
				}
			}
		}
	}

	// Count XP for number of participants and nasty events
	xpBonusFactor += (nbParticipants-1.0f) * ForageExtractionNbParticipantsXPBonusRatio.get(); // everyone gets 10% more per additional forager
	float nbNastyEvents = (float)(source->nbEventTriggered());
	xpBonusFactor -= nbNastyEvents * ForageExtractionNastyEventXPMalusRatio.get();

	// Count XP per participant
	float xpPerParticipant = ForageExtractionXPFactor.get() * xpBonusFactor / nbParticipants;

	// Give XP to extractor
	reportXPTo( extractor, xpPerParticipant, extractor->getRightHandItem() );
	bool isProspectorCredited = false;
	if ( extractor == prospector )
	{
		SM_STATIC_PARAMS_1(params, STRING_MANAGER::integer);
		params[0].Int = 0;
		PHRASE_UTILITIES::sendDynamicSystemMessage( prospector->getEntityRowId(), "FORAGE_XP_PROSPECTION", params );
		isProspectorCredited = true;
	}
	if ( source->wasProspected() )
	{
		// Give energy back!
		SCharacteristicsAndScores& focus = extractor->getScores()._PhysicalScores[SCORES::focus];
		if ( focus.Current < initialFocus() )
			focus.Current = focus.Current() + (sint32)(ForageFocusAutoRegenRatio.get() * (float)(initialFocus()-focus.Current));
	}

	// Give XP to care casters
	for ( vector<CCharacter*>::iterator icc=usefulCareCasters.begin(); icc!=usefulCareCasters.end(); ++icc )
	{
		CCharacter *careCaster = (*icc);
		reportXPTo( careCaster, xpPerParticipant, careCaster->getRightHandItem() );
		if ( prospector == careCaster )
		{
			SM_STATIC_PARAMS_1(params, STRING_MANAGER::integer);
			params[0].Int = 0;
			PHRASE_UTILITIES::sendDynamicSystemMessage( prospector->getEntityRowId(), "FORAGE_XP_PROSPECTION", params );
			isProspectorCredited = true;
		}
		if ( source->wasProspected() && careCaster->forageProgress() )
		{
			// Give energy back!
			SCharacteristicsAndScores& focus = careCaster->getScores()._PhysicalScores[SCORES::focus];
			if ( focus.Current < careCaster->forageProgress()->initialFocus() )
				focus.Current = focus.Current() + (sint32)(ForageFocusAutoRegenRatio.get() * (float)(careCaster->forageProgress()->initialFocus()-focus.Current));
		}
	}

	// Give XP to "standalone" prospector (if any)
	if ( prospector && (! isProspectorCredited) )
	{
		reportXPTo( prospector, xpPerParticipant, NULL );
		SM_STATIC_PARAMS_1(params, STRING_MANAGER::integer);
		params[0].Int = 1;
		PHRASE_UTILITIES::sendDynamicSystemMessage( prospector->getEntityRowId(), "FORAGE_XP_PROSPECTION", params );
	}
}
//----------------------------------------------------------------------------
void COutpostManager::loadOutpostSaveFiles()
{
	if (!LoadOutposts.get())
		return;

	// only once
	if (_OutpostSaveFilesLoaded)
		return;

	// check preconditions
	nlassert(_OutpostPrimitivesLoaded);
	nlassert(CGuildManager::getInstance()->loadedGuilds());

	OUTPOST_DBG("Applying outpost save files...");
	// all outposts where parsed. Let's try to load their saved files to init the dynamic data.
	string path = /*Bsi.getLocalPath() +*/ string("outposts");
	// create the saved file directory, if needed
//	CFile::createDirectory(path);
	
	// get all the outpost files
	TOupostFileClassCallback *ccb = new TOupostFileClassCallback;
	OutpostFiles.clear();
	vector<CBackupFileClass> outpostClasses(1);
	outpostClasses[0].Patterns.push_back("outpost*.bin");
	Bsi.syncLoadFileClass("outposts", outpostClasses, ccb);

	// load all the outpost file
	loadedOutposts.clear();
	TOupostFileCallback *cb = new TOupostFileCallback;
	Bsi.syncLoadFiles(OutpostFiles, cb);

//	CPath::getPathContent (path, false, false, true,files ,NULL);

//	vector<COutpost*> loadedOutposts;
//	for (uint i = 0; i < files.size(); i++)
//	{
//		string file = files[i].substr( path.size() + 1);
//		// check if we have an outpost file
//		if ( file.find( "outpost_" ) == 0 &&
//			file.find( ".bin" ) == file.length() - 4 )
//		{
//			// get the corresponding outpost
//			string aliasStr = file;
//			aliasStr.resize( file.length() - 4 );
//			aliasStr = aliasStr.substr( 8, file.length() - 8 );
//
//			TAIAlias alias;
//			NLMISC::fromString(aliasStr, alias);
//			COutpost * outpost = getOutpostFromAlias( alias );
//			if ( !outpost )
//				OUTPOST_WRN("Invalid outpost file '%s' ('%u') : not found in the primitive", file.c_str(), alias);
//			else
//			{
//				// load dynamic data
//				static CPersistentDataRecord	pdr;
//				pdr.clear();
//				pdr.readFromBinFile(files[i].c_str());
//				outpost->apply( pdr );
//				loadedOutposts.push_back( outpost );
//			}
//		}
//	}
	OUTPOST_DBG("Outpost save files applied.");
	
	OUTPOST_DBG("Initializing unsaved outposts...");
	// Init new outpost that have never been saved
	uint nbNewOutposts = 0;
	for (vector<NLMISC::CSmartPtr<COutpost> >::const_iterator it = _Outposts.begin(); it != _Outposts.end(); ++it)
	{
		if ( std::find( loadedOutposts.begin(), loadedOutposts.end(), *it ) == loadedOutposts.end() )
		{
			COutpost *newOutpost = (*it);
			newOutpost->initNewOutpost();
			++nbNewOutposts;
		}
	}
	if ( nbNewOutposts != 0 )
	{
		OUTPOST_INF( "Created default squads for %u new outposts", nbNewOutposts );
	}
	OUTPOST_DBG("Unsaved outposts initialized.");

	OUTPOST_DBG("Registering outposts in guilds...");
	// register outposts in guilds
	for (uint i = 0; i < _Outposts.size(); i++)
	{
		_Outposts[i]->registerOutpostInGuilds();
	}
	OUTPOST_DBG("Outposts registered in guilds.");

	// array of callback items
	NLNET::TUnifiedCallbackItem _cbArray[] =
	{
		{ "OUTPOST_SQUAD_CREATED",		cbOutpostSquadCreated		},
		{ "OUTPOST_SQUAD_SPAWNED",		cbOutpostSquadSpawned		},
		{ "OUTPOST_SQUAD_DESPAWNED",	cbOutpostSquadDespawned		},
		{ "OUTPOST_SQUAD_DIED",			cbOutpostSquadDied			},
		{ "OUTPOST_SQUAD_LEADER_DIED",	cbOutpostSquadLeaderDied	},
	};
	// register call back for outpost manager
	CUnifiedNetwork::getInstance()->addCallbackArray( _cbArray, sizeof(_cbArray) / sizeof(_cbArray[0]) );

	// outpost save files now are loaded
	_OutpostSaveFilesLoaded = true;

	// trigger pending ready AI instance events
	for (	std::set<uint32>::const_iterator it = _PendingReadyAIInstances.begin();
			it != _PendingReadyAIInstances.end();
			++it)
	{
		onAIInstanceReadyOrDown(*it, true);
	}
	_PendingReadyAIInstances.clear();
}
/**
 * cbShardOpen()
 * Callback for ShardOpen
 */
void	cbShardOpen(IVariable &var)
{
	setShardOpenState((TShardOpenState)(ShardOpen.get()), false);
}
//void cbLSChooseShard (CMessage &msgin, const std::string &serviceName, uint16 sid)
std::string lsChooseShard (const std::string &userName,
					const CLoginCookie &cookie,
					const std::string &userPriv,
					const std::string &userExtended,
					WS::TUserRole userRole,
					uint32 instanceId,
					uint32 charSlot)
{
	// the LS warns me that a new client want to come in my shard

	//
	// S07: receive the "CS" message from LS and send the "CS" message to the selected FES
	//

/*
	uint totalNbUsers;
	CFES *best = findBestFES( totalNbUsers );
	if (best == NULL)
	{
		// answer the LS that we can't accept the user
		CMessage msgout ("SCS");
		string reason = "No front-end server available";
		msgout.serial (reason);
		msgout.serial (cookie);
		CUnifiedNetwork::getInstance()->send(sid, msgout);
		return;
	}
*/

	uint	totalNbUsers;
	CFES*	best = findBestFES( totalNbUsers );

	// could not find a good FES or best FES has more players than balance limit
	if (best == NULL || best->getUsersCountHeuristic() >= OpenFrontEndThreshold)
	{
		// open a new frontend
		openNewFES();

		// reselect best FES (will return newly open FES, or previous if no more FES available)
		best = findBestFES(totalNbUsers);

		// check there is a FES available
		if (best == NULL)
		{
			// answer the LS that we can't accept the user
			return "No front-end server available";
		}
	}


	bool	authorizeUser = false;
	bool	forceAuthorize = false;

	if (userPriv == ":DEV:")
	{
		// devs have all privileges
		authorizeUser = true;
		forceAuthorize = true;
	}
	else if (ShardOpen != ClosedForAll)
	{
		const std::string&	allowedGroups = OpenGroups;
		bool				userInOpenGroups = (!userPriv.empty() && !allowedGroups.empty() && allowedGroups.find(userPriv) != std::string::npos);

		// open for all or user is privileged
		authorizeUser = (ShardOpen == OpenForAll || userInOpenGroups);
		// let authorized users to force access even if limit is reached
		forceAuthorize = userInOpenGroups;
	}

	bool	shardLimitReached = ( (PlayerLimit.get() != -1) && (totalNbUsers >= (uint)PlayerLimit.get()) );

	if (!forceAuthorize && (!authorizeUser || shardLimitReached))
	{
		// answer the LS that we can't accept the user
		CMessage msgout ("SCS");
		string reason;
		if (shardLimitReached)
			return "The shard is currently full, please try again in 5 minutes.";
		else
			return "The shard is closed.";
	}


	CMessage msgout ("CS");
	msgout.serial (const_cast<CLoginCookie&>(cookie));
	msgout.serial (const_cast<string&>(userName), const_cast<string&>(userPriv), const_cast<string&>(userExtended));
	msgout.serial (instanceId);
	msgout.serial (charSlot);

	CUnifiedNetwork::getInstance()->send (best->SId, msgout);
	best->NbPendingUsers++;

	// Update counts
	uint32 totalNbOnlineUsers = 0, totalNbPendingUsers = 0;
	for (list<CFES>::iterator it=FESList.begin(); it!=FESList.end(); ++it)
	{
		totalNbOnlineUsers += (*it).NbUser;
		totalNbPendingUsers += (*it).NbPendingUsers;
	}
	if (CWelcomeServiceMod::isInitialized())
		CWelcomeServiceMod::getInstance()->updateConnectedPlayerCount(totalNbOnlineUsers, totalNbPendingUsers);

	return "";
}
Example #26
0
/*
 * Update the source state with an extraction (see doc in .h).
 */
void CHarvestSource::extractMaterial( float *reqPosProps, float *absPosProps, float qualityCeilingFactor, float qualitySlowFactor, float *results, float successFactor, uint8 lifeAbsorberRatio, const TDataSetRow& extractingEntityRow, CHarvestSource::TRealTimeProp& propDrop )
{
	H_AUTO(CHarvestSource_extractMaterial);

	CCharacter* player = PlayerManager.getChar( extractingEntityRow );
	
	++_NbExtractions; // it's 1 at the first call, so that the initial value is used
	float nbe = (float)_NbExtractions;

	if ( (successFactor < 0.1f) || ForceDropProp )
	{
		if ( _NbExtractions < 6 )
			propDrop = Q; // don't drop A at the beginning (wait to reach 1 (cumulated) would be better)
		else
			propDrop = (TRealTimeProp)(RandomGenerator.rand(1)+1);
		nldebug( "Prop drop %u", propDrop );
	}

	// Aperture: converges towards the requested value, except when a drop occurs (0 at this step)
//	if ( reqPosProps[A] > 0 )
	{
		float obtainedQuantity = (propDrop == A) ? 0.0f : (results[A]*ForageQuantitySlowFactor.get() + reqPosProps[A]) / (ForageQuantitySlowFactor.get()+1);

		// Apply possible aperture bonus
		if ( _BonusForAPct != 0 )
		{
			obtainedQuantity += obtainedQuantity * (float)((uint)_BonusForAPct) * 0.01f;
		}
		
		// Extract material
		if ( _ForageSite )
			obtainedQuantity = _ForageSite->consume( obtainedQuantity ); // consume (and limit) in forage site & deposit
		if ( obtainedQuantity > _N ) // should not occur because _N uses the deposit quantity
			obtainedQuantity = _N;
		_N -= obtainedQuantity;
		_A = (_A*nbe + obtainedQuantity) / (nbe + 1.0f); // average per source
		_DepositForK->incKamiAnger( obtainedQuantity, _Foragers );
		if ( (obtainedQuantity == 0) && (results[A] != 0) && (! (propDrop == A)) )
			PHRASE_UTILITIES::sendDynamicSystemMessage( _Foragers[0], "FORAGE_DEPOSIT_IS_EMPTY" );
		results[A] = obtainedQuantity;
		
		// add spire effect ( quantity )
		if ( player )
		{
			const CSEffect* pEffect = player->lookForActiveEffect( EFFECT_FAMILIES::TotemHarvestQty );
			if ( pEffect != NULL )
			{
				results[A] *= ( 1.0f + pEffect->getParamValue() / 100.0f );
			}
		}
		// add item special effect
		if ( player )
		{
			std::vector<SItemSpecialEffect> effects = player->lookForSpecialItemEffects(ITEM_SPECIAL_EFFECT::ISE_FORAGE_ADD_RM);
			std::vector<SItemSpecialEffect>::const_iterator it, itEnd;
			double addedQty = 0.;
			for (it=effects.begin(), itEnd=effects.end(); it!=itEnd; ++it)
			{
				float rnd = RandomGenerator.frand();
				if (rnd<it->EffectArgFloat[0])
				{
					addedQty += it->EffectArgFloat[1];
					PHRASE_UTILITIES::sendItemSpecialEffectProcMessage(ITEM_SPECIAL_EFFECT::ISE_FORAGE_ADD_RM, player, NULL, (sint32)(it->EffectArgFloat[1]*100.));
				}
			}
			results[A] *= 1.0f + (float)addedQty;
		}
	}
//	else
//	{
//		results[A] = 0;
//	}

	// Speed: always the requested speed (otherwise, looks like a bug for the player when it's the speed of the action)
	results[S] = reqPosProps[S];
	_S = (_S*nbe + results[S]) / (nbe + 1.0f); // average per source

	// Quality: converges towards the requested value, except when a drop occurs (0 at this step)
	float usedReqQ = (propDrop == Q) ? 0.0f : reqPosProps[Q] * qualityCeilingFactor;
	float resQ = (results[Q]*qualitySlowFactor + usedReqQ) / (qualitySlowFactor+1);
	float maxQOfSource = (float)_MaxQuality;
	if ( resQ > maxQOfSource )
	{
		resQ = maxQOfSource;
		//if ( results[Q] < (float)_MaxQuality )
		//	nldebug( "Quality limited by source to %hu", _MaxQuality ); // TODO: tell the player(s)
	}
	if ( (resQ < _Q) || (resQ < reqPosProps[Q]) || (! ForageQualityCeilingClamp.get()) )
	{
		// Set Q only if not increasing and exceeding requested quality
		results[Q] = resQ;
	}
	else
	{
		// Clamp Q to the max required by the player
		results[Q] = reqPosProps[Q];
	}
	float prevQ = _Q;
	_Q = results[Q]; // now there is only one extractor => the Q of the source is the resulting Q
	if ( ((prevQ < reqPosProps[Q]) && (_Q == reqPosProps[Q])) || ((prevQ < maxQOfSource) && (_Q == maxQOfSource)) )
	{
		setNewImpactScheme(); // we just reached the max quality
	}

	// Calc impact of the new average values

	// Previously, the impact depended on the level of the extraction:
	// float quantityBaseImpact = _A * _S * ForageQuantityImpactFactor.get();
	// float qualityBaseImpact = (_Q - oldQ) * ForageQualityImpactFactor.get();
	//
	// Now it's constant (=max), but the amount of damage depends on the level of the extraction:
	float quantityBaseImpact = MaxAS * ForageQuantityImpactFactor.get();
	float qualityBaseImpact = MaxDeltaQ * ForageQualityImpactFactor.get();
	uint impactScheme = _IImpactMappingScheme;
	if ( impactScheme >= SpecialNewbieImpactSchemeD)
	{
		// Lower impacts for newbies
		impactScheme -= SpecialNewbieImpactSchemeD;
		quantityBaseImpact *= 0.5f;
		qualityBaseImpact *= 0.5f;
	}
	if ( ForceAbsorption.get() != 0 )
	{
		absPosProps[A] = ForceAbsorption.get();
		absPosProps[Q] = ForceAbsorption.get();
		absPosProps[S] = ForceAbsorption.get();
	}
	for ( uint i=D; i!=NbRTProps; ++i )
	{
		if (i==E && _SafeSource)
			break;
		uint impactType = ImpactSchemes[impactScheme][i-NbPosRTProps];
		float impact;
		switch ( impactType )
		{
		case 0 : impact = quantityBaseImpact * (1.0f - absPosProps[A]); break;
		case 1 : impact = qualityBaseImpact * (1.0f - absPosProps[Q]); break;
		default: impact = (quantityBaseImpact + qualityBaseImpact) / 2.0f * (1.0f - absPosProps[S]); break; // bound on the average of both, absorption of S
		}

		impact += RandomGenerator.frandPlusMinus( impact ); // result impact from 0 to impact*2
		
		// add spire effect ( aggressivity )
		if ( player )
		{
			const CSEffect* pEffect = player->lookForActiveEffect( EFFECT_FAMILIES::TotemHarvestAgg );
			if ( pEffect != NULL )
			{
				impact *= ( 1.0f - pEffect->getParamValue() / 100.0f );
			}
		}

		if ( impact < 0 ) impact = 0; // impact can't be negative
		if ( (i==D) && (lifeAbsorberRatio != 0) )
		{
			// Damage the life absorber, instead of impacting D
			CEntityBase *entity = CEntityBaseManager::getEntityBasePtr( extractingEntityRow ); // getEntityBasePtr() tests TheDataset.isAccessible( extractingEntity )
			if ( entity )
			{
				float impactOnHP = ((float)lifeAbsorberRatio) * impact * 0.01f;
				impact -= impactOnHP;
				float dmgRatio = impactOnHP * ForageHPRatioPerSourceLifeImpact.get();
				sint32 dmg = (sint32)((float)entity->maxHp() * dmgRatio);
				if ( dmg != 0 )
					CHarvestSource::hitEntity( RYZOMID::forageSource, entity, dmg, dmg, true );
			}
		}
		if ( (_TargetRTProps[i-D] < CommonRiskThreshold*0.90f) && (_TargetRTProps[i-D] + impact > CommonRiskThreshold) )
		{
			// Avoid a brutal unnatural end, make a step just before reaching threshold
			impactRTProp( (TTargetRTProp)(i-D), CommonRiskThreshold - 2.0f );
		}
		else
		{
			// Normal impact
			impactRTProp( (TTargetRTProp)(i-D), _TargetRTProps[i-D] + impact );
		}
	}
}
//----------------------------------------------------------------------------
void COutpostManager::loadOutpostPrimitives()
{
	if (!LoadOutposts.get())
		return;

	// only once
	if (_OutpostPrimitivesLoaded)
		return;

	const CPrimitivesParser::TPrimitivesList & primsList = CPrimitivesParser::getInstance().getPrimitives();
	string value;
	CPrimitivesParser::TPrimitivesList::const_iterator first, last;

	OUTPOST_DBG("Loading squad templates...");
	// *** Squad templates ***
	// get the primitive list and parse each primitive
	for ( first = primsList.begin(), last = primsList.end(); first != last; ++first )
	{
		// get the squad_template nodes
		for ( uint i = 0; i < first->Primitive.RootNode->getNumChildren(); ++i )	
		{
			const NLLIGO::IPrimitive* stNode = NULL;
			if ( first->Primitive.RootNode->getChild( stNode, i ) && stNode != NULL )
			{
				const char *parentClass = "squad_template";
				if (stNode->getPropertyByName("class",value) && !nlstricmp(value.c_str(),parentClass) )
				{
					string path = first->FileName;
					CSquadTemplate squadTemplate;
					squadTemplate.SquadName = readProperty( stNode, "name", parentClass, path, false, true );
					
					// get the squad_template variants
					for ( uint j = 0; j < stNode->getNumChildren(); ++j )	
					{
						const NLLIGO::IPrimitive* stvNode = NULL;
						if ( stNode->getChild( stvNode, j ) && stvNode != NULL )
						{
							parentClass = "squad_template_variant";
							if (stvNode->getPropertyByName("class",value) && !nlstricmp(value.c_str(),parentClass) )
							{
								path = first->FileName+"."+squadTemplate.SquadName;
								CSquadTemplate::CSquadTemplateVariant variant;

								// alias
								variant.Alias = 0;
								nlverify( CPrimitivesParser::getAlias(stvNode, variant.Alias) );

								// 'name' -> continent or tribe name
								variant.VariantName = readProperty( stvNode, "name", parentClass, path, false, true );
								path += "."+variant.VariantName;

								// 'is tribe'
								value = readProperty( stvNode, "is tribe", parentClass, path, true, false, true );
								variant.IsTribe = (value == "true");

								// 'squad sheet'
								value = readProperty( stvNode, "squad sheet", parentClass, path );
								if ( value.find( ".outpost_squad" ) == string::npos )
									value += ".outpost_squad";
								variant.SquadSheet = CSheetId(value);
								if ( variant.SquadSheet == CSheetId::Unknown )
									OUTPOST_WRN("PRIM_ERROR : invalid squad sheet '%s' (not in sheet_id.bin) in '%s'", value.c_str(), path.c_str() );
								//if ( ! CSheets::getOutpostSquadForm( variant.SquadSheet ) ) // already done when loading outpost
								//	OUTPOST_WRN("PRIM_ERROR : invalid squad sheet '%s' (error in georges form) in %s", value.c_str(), path.c_str() );

								// squad members are handled by the AIS
								if ( stvNode->getNumChildren() == 0 )
									OUTPOST_WRN("PRIM_ERROR : '%s' in '%s' has no members", parentClass, path.c_str() );

								squadTemplate.Variants.push_back( variant );
							}
						}
					}
					{
						std::string str;
						str += "Adding Squad template '" + squadTemplate.SquadName + "' (";
						std::vector<CSquadTemplate::CSquadTemplateVariant>::const_iterator it, itEnd;
						it=squadTemplate.Variants.begin(), itEnd=squadTemplate.Variants.end();
						if (it!=itEnd)
							str += it->VariantName;
						for (++it ; it!=itEnd; ++it)
							str += ", " + it->VariantName;
						str += ")";
						OUTPOST_DBG("%s", str.c_str());
					}
					addSquadTemplate( squadTemplate );
				}
			}
		}
	}
	OUTPOST_DBG("Squad templates loaded.");
	
	OUTPOST_DBG("Loading outposts...");
	// *** Outposts (must be done after squad templates) ***
	// get the primitive list and parse each primitive
	for ( first = primsList.begin(), last = primsList.end(); first != last; ++first )
	{
		// get the dynamic_system nodes
		for ( uint i = 0; i < first->Primitive.RootNode->getNumChildren(); ++i )	
		{
			const NLLIGO::IPrimitive* dynSystemNode = NULL;
			if ( first->Primitive.RootNode->getChild( dynSystemNode,i ) && dynSystemNode != NULL )
			{
				if (dynSystemNode->getPropertyByName("class",value) && !nlstricmp(value.c_str(),"dynamic_system") )
				{
					// get the continent, as outpost need a continent to be built. We get this value from the dynamic system node
					string dynSystemName;
					nlverify( dynSystemNode->getPropertyByName("name",dynSystemName) );
					nlverify( dynSystemNode->getPropertyByName("continent_name",value) );
					CONTINENT::TContinent continent = CONTINENT::toContinent( value );
					if ( continent == CONTINENT::UNKNOWN )
					{
						OUTPOST_WRN("Invalid continent '%s' in dynamic system '%s' of primitive file '%s'", 
						value.c_str(), dynSystemName.c_str(), first->FileName.c_str() );
						break;
					}
					// parse all the outpost within this dynamic system.
					for ( uint j = 0; j < dynSystemNode->getNumChildren(); ++j )	
					{
						const NLLIGO::IPrimitive* outpostNode = NULL;
						if ( dynSystemNode->getChild( outpostNode,j ) && outpostNode != NULL )
						{
							if (outpostNode->getPropertyByName("class",value) && !nlstricmp(value.c_str(),"outpost") )
							{
								CSmartPtr<COutpost> outpost = CSmartPtr<COutpost>(new COutpost());
								if ( outpost->build( outpostNode, first->FileName,dynSystemName, continent ) )
								{
									bool multiple = false;
									for (vector<NLMISC::CSmartPtr<COutpost> >::const_iterator it = _Outposts.begin(); it != _Outposts.end(); ++it)
									{
										if ( (*it)->getAlias() == outpost->getAlias() )
										{
											OUTPOST_WRN( "PRIM_ERROR : multiple outpost alias %s %s %s", CPrimitivesParser::aliasToString( outpost->getAlias() ).c_str(), (*it)->getName().c_str(), outpost->getName().c_str() );
											multiple = true;
										}
										if ( (*it)->getSheet() == outpost->getSheet() )
										{
											OUTPOST_WRN( "PRIM_ERROR : multiple outpost sheet %s %s %s", outpost->getSheet().toString().c_str(), (*it)->getName().c_str(), outpost->getName().c_str() );
											multiple = true;
										}
									}
									if( !multiple )
									{
										_Outposts.push_back(outpost);
										_OutpostsByAlias.insert( make_pair( outpost->getAlias(), outpost ) );
										_OutpostsBySheet.insert( make_pair( outpost->getSheet(), outpost ) );
										OUTPOST_INF("Outpost '%s' was successfully parsed", outpost->getName().c_str());
									
										// nb : short id starts at 1, 0 is used for invalid
										_OutpostAliasToShortId.insert( make_pair( outpost->getAlias(), (uint16)_Outposts.size()) );
									}
								}
							}
						}
					}
				}
			}
		}
	}
	OUTPOST_DBG("Outposts loaded.");
	
	OUTPOST_DBG("Clearing squad templates...");
	// No more need of squad templates
	_SquadTemplates.clear();
	OUTPOST_DBG("Squad templates cleared.");

	// outpost primitives now are loaded
	_OutpostPrimitivesLoaded = true;
}