// decode a service in a form 'alias/shortname-sid'
void decodeUnifiedName(const string &unifiedName, string &alias, string &shortName, TServiceId &sid)
{
	size_t pos1 = 0, pos2 = 0;
	pos1 = unifiedName.find("/");
	if (pos1 != string::npos)
	{
		alias = unifiedName.substr(0, pos1);
		pos1++;
	}
	else
	{
		alias = "";
		pos1 = 0;
	}
	pos2 = unifiedName.find("-");
	if (pos2 != string::npos)
	{
		shortName = unifiedName.substr(pos1,pos2-pos1);
		sid.set(atoi(unifiedName.substr(pos2+1).c_str()));
	}
	else
	{
		shortName = unifiedName.substr(pos1);
		sid.set(0);
	}

	if (alias.empty())
	{
		alias = shortName;
	}
}
示例#2
0
文件: main.cpp 项目: sythaeryn/pndrpg
	static void cbPosition(CMessage &msgin, const std::string &serviceName, TServiceId sid)
	{
		// temp
		uint32 id;
		CVector position;
		msgin.serial(id);
		msgin.serial(position);
		nldebug("Received CLS_POSITION, %s %s", serviceName.c_str(), sid.toString().c_str());

		// Update position information in the player list
		_pmap::iterator ItPlayer;
		ItPlayer = playerList.find( id );
		if ( ItPlayer == playerList.end() )
		{
			nlwarning( "Player id %u not found !", id );
		}
		else
		{
			((*ItPlayer).second).position = position;
			//nldebug( "SB: Player position updated" );
		}

		CMessage msgout("ENTITY_TP");
		msgout.serial(id);
		msgout.serial(position);
		CUnifiedNetwork::getInstance()->send("FS", msgout);
	}
示例#3
0
/*
 * Supports any service id, even one not added before (ignored then)
 */
void CTickProxy::removeService( TServiceId serviceId )
{
	vector<TServiceId>::iterator it = find( _Services.begin(), _Services.end(), serviceId );
	if ( it == _Services.end() )
		return; // ignore a service not registered
	
	_Services.erase( it );

	// Simulate Tock from leaving service if needed
	if ( State == ExpectingLocalTocks )
	{
		if ( find( _TockedServices.begin(), _TockedServices.end(), serviceId ) != _TockedServices.end() )
		{
			// The service already tocked and we are still in this state, it means we're waiting for another service to tock
			nlassert( _NbTocked != 0 );
			--_NbTocked; // decrement because _Service.size() is being decremented

			// If other tocks are coming, they will call doNextTask. However, it is possible that no
			// other tock is expected, if the tock did not triggered a master tock (changing State).
			if ( _NbTocked == _Services.size() )
				cbDoNextTask();
			else
				nldebug( "TCK- Service %hu already tocked, waiting for %u other tocks", serviceId.get(), _Services.size() - _NbTocked );
		}
		else
		{
			// The service didn't tock yet, interpret its quitting as a tock
			cbDoNextTask();
		}
	}
}
// This function is called by FES to setup the right number of players (if FES was already present before WS launching)
void	cbFESNbPlayers2(CMessage &msgin, const std::string &serviceName, TServiceId  sid)
{
	uint32	nbPlayers;
	uint32	nbPendingPlayers;
	msgin.serial(nbPlayers);
	msgin.serial(nbPendingPlayers);

	uint32 totalNbOnlineUsers = 0, totalNbPendingUsers = 0;
	for (list<CFES>::iterator it = FESList.begin(); it != FESList.end(); it++)
	{
		CFES &fes = *it;
		if (fes.SId == sid)
		{
			nldebug("Frontend '%d' reported %d online users", sid.get(), nbPlayers);
			fes.NbUser = nbPlayers;
			fes.NbPendingUsers = nbPendingPlayers;
			if (nbPlayers != 0 && fes.State == PatchOnly)
			{
				nlwarning("Frontend %d is in state PatchOnly, yet reports to have online %d players, state AcceptClientOnly is forced (FS_ACCEPT message sent)");
				(*it).setToAcceptClients();
			}
		}
		totalNbOnlineUsers += fes.NbUser;
		totalNbPendingUsers += fes.NbPendingUsers;
	}

	if (CWelcomeServiceMod::isInitialized())
		CWelcomeServiceMod::getInstance()->updateConnectedPlayerCount(totalNbOnlineUsers, totalNbPendingUsers);
}
// This function is called by FES to setup the right number of players (if FES was already present before WS launching)
void	cbFESNbPlayers(CMessage &msgin, const std::string &serviceName, TServiceId  sid)
{
	// *********** WARNING *******************
	// This version of the callback is deprecated, the system
	// now use cbFESNbPlayers2 that report the pending user count
	// as well as the number of connected players.
	// It is kept for backward compatibility only.
	// ***************************************

	uint32	nbPlayers;
	msgin.serial(nbPlayers);

	uint32 totalNbOnlineUsers = 0, totalNbPendingUsers = 0;
	for (list<CFES>::iterator it = FESList.begin(); it != FESList.end(); it++)
	{
		if ((*it).SId == sid)
		{
			nldebug("Frontend '%d' reported %d online users", sid.get(), nbPlayers);
			(*it).NbUser = nbPlayers;
			if (nbPlayers != 0 && (*it).State == PatchOnly)
			{
				nlwarning("Frontend %d is in state PatchOnly, yet reports to have online %d players, state AcceptClientOnly is forced (FS_ACCEPT message sent)");
				(*it).setToAcceptClients();
			}
		}
		totalNbOnlineUsers += (*it).NbUser;
		totalNbPendingUsers += (*it).NbPendingUsers;
	}

	if (CWelcomeServiceMod::isInitialized())
		CWelcomeServiceMod::getInstance()->updateConnectedPlayerCount(totalNbOnlineUsers, totalNbPendingUsers);
}
// This function is called when a FES rejected a client' cookie
void	cbFESRemovedPendingCookie(CMessage &msgin, const std::string &serviceName, TServiceId  sid)
{
	CLoginCookie	cookie;
	msgin.serial(cookie);
	nldebug( "ERLOG: RPC recvd from %s-%hu => %s removed", serviceName.c_str(), sid.get(), cookie.toString().c_str(), cookie.toString().c_str());


	// client' cookie rejected, no longer pending
	uint32 totalNbOnlineUsers = 0, totalNbPendingUsers = 0;
	for (list<CFES>::iterator it = FESList.begin(); it != FESList.end(); it++)
	{
		if ((*it).SId == sid)
		{
			if ((*it).NbPendingUsers > 0)
				--(*it).NbPendingUsers;
		}
		totalNbOnlineUsers += (*it).NbUser;
		totalNbPendingUsers += (*it).NbPendingUsers;
	}

	if (CWelcomeServiceMod::isInitialized())
	{
		CWelcomeServiceMod::getInstance()->pendingUserLost(cookie);
		CWelcomeServiceMod::getInstance()->updateConnectedPlayerCount(totalNbOnlineUsers, totalNbPendingUsers);
	}
}
示例#7
0
/*
 * Map Service Id
 */
bool	CDbManager::mapService(TServiceId serviceId, TDatabaseId databaseId)
{
	if (serviceId.get() > 256 || _ServiceMap[serviceId.get()] != INVALID_DATABASE_ID)
	{
		nlwarning("CDbManager::mapService(): failed, serviceId '%hu' not valid or service already mapped", serviceId.get());
		return false;
	}

	_ServiceMap[serviceId.get()] = databaseId;

	CDatabase*	database = getDatabase(databaseId);
	if (database != NULL)
		database->mapToService(serviceId);

	return true;
}
示例#8
0
文件: main.cpp 项目: sythaeryn/pndrpg
	/****************************************************************************
	 * Connection callback for the collision service
	 ****************************************************************************/
	static void cbCollisionServiceUp(const std::string &serviceName, TServiceId sid, void *arg)
	{
		nldebug("SB: Collision Service UP, %s %s", serviceName.c_str(), sid.toString().c_str());
		clear();
		msgRegister(sid);
		for (_pmap::iterator it = playerList.begin(); it != playerList.end(); it++)
			addEntity(it->second.id, it->second.position, 1.0f);
	}
void serviceConnection(const std::string &serviceName, TServiceId sid, void *arg)
{
	// don't add AS
	if (serviceName == "AS")
		return;

	if (sid.get() >= Services.size())
	{
		Services.resize(sid.get()+1);
	}

	Services[sid.get()].init(serviceName, sid);

	sendInformation(sid);

	nlinfo("%s-%hu connected", Services[sid.get()].ShortName.c_str(), Services[sid.get()].ServiceId.get());

}
示例#10
0
// a front end closes the connection, deconnect him
void cbFESDisconnection (const std::string &serviceName, TServiceId  sid, void *arg)
{
	nldebug("new FES disconnection: sid %u", sid.get());

	for (list<CFES>::iterator it = FESList.begin(); it != FESList.end(); it++)
	{
		if ((*it).SId == sid)
		{
			// send a message to the LS to say that all players from this FES are offline
			map<uint32, TServiceId>::iterator itc = UserIdSockAssociations.begin();
			map<uint32, TServiceId>::iterator nitc = itc;
			while (itc != UserIdSockAssociations.end())
			{
				nitc++;
				if ((*itc).second == sid)
				{
					// bye bye little player
					uint32 userid = (*itc).first;
					nlinfo ("Due to a frontend crash, removed the player %d", userid);
					if (!DontUseLS)
					{
						CMessage msgout ("CC");
						msgout.serial (userid);
						uint8 con = 0;
						msgout.serial (con);
						CUnifiedNetwork::getInstance()->send ("LS", msgout);
					}
					UserIdSockAssociations.erase (itc);
				}
				itc = nitc;
			}

			bool	dummy;
			(*it).reportStateToLS(dummy, false);

			// remove the FES
			FESList.erase (it);

			break;
		}
	}

	// Update the welcome service client with the new count of connection

	uint32 totalNbOnlineUsers =0, totalNbPendingUsers = 0;
	for (list<CFES>::iterator it = FESList.begin(); it != FESList.end(); it++)
	{
		const CFES &fes = *it;
		totalNbOnlineUsers += fes.NbUser;
		totalNbPendingUsers += fes.NbPendingUsers;
	}

	if (CWelcomeServiceMod::isInitialized())
		CWelcomeServiceMod::getInstance()->updateConnectedPlayerCount(totalNbOnlineUsers, totalNbPendingUsers);

	displayFES ();
}
示例#11
0
void cbUpService(const std::string &serviceName, TServiceId sid, void *arg)
{
	nlinfo("Service %s %d is up", serviceName.c_str(), sid.get());

	CMessage msgout("TOTO");
	uint32 i = 10;
	msgout.serial(i);
	CUnifiedNetwork::getInstance()->send(sid, msgout);
}
示例#12
0
// 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 reset()
	{
		AliasName.clear();
		ShortName.clear();
		LongName.clear();
		ServiceId.set(0);
		Ready = false;
		Connected = false;
		Commands.clear();
		AutoReconnect = false;
		PId = 0;
		Relaunch = false;
		LastPing = 0;
		WaitingRequestId.clear();
	}
示例#14
0
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////// CONNECTION TO THE LOGIN SERVICE ///////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void cbLSChooseShard (CMessage &msgin, const std::string &serviceName, TServiceId  sid)
{
	// the LS warns me that a new client want to come in my shard

	nldebug( "ERLOG: CS recvd from %s-%hu", serviceName.c_str(), sid.get());

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

	CLoginCookie cookie;
	msgin.serial (cookie);
	string userName, userPriv, userExtended;
	msgin.serial (userName);

	try
	{
		msgin.serial (userPriv);
	}
	catch (const Exception &)
	{
		nlwarning ("LS didn't give me the user privilege for user '%s', set to empty", userName.c_str());
	}

	try
	{
		msgin.serial (userExtended);
	}
	catch (const Exception &)
	{
		nlwarning ("LS didn't give me the extended data for user '%s', set to empty", userName.c_str());
	}


	string ret = lsChooseShard(userName, cookie, userPriv, userExtended, WS::TUserRole::ur_player, 0xffffffff, ~0);

	if (!ret.empty())
	{
		// send back an error message to LS
		CMessage msgout ("SCS");
		msgout.serial (ret);
		msgout.serial (cookie);
		CUnifiedNetwork::getInstance()->send(sid, msgout);
	}
}
	std::string getServiceUnifiedName() const
	{
		nlassert(!ShortName.empty());
		string res;
		if(!AliasName.empty())
		{
			res = AliasName+"/";
		}
		res += ShortName;
		if(ServiceId.get() != 0)
		{
			res += "-";
			res += NLMISC::toString(ServiceId);
		}
		if(res.empty())
			res = "???";
		return res;
	}
static void cbServiceReady(CMessage &msgin, const std::string &serviceName, TServiceId sid)
{
	if (sid.get() >= Services.size())
	{
		nlwarning("Ready of an unknown service %s-%hu", serviceName.c_str(), sid.get());
		return;
	}

	if (!Services[sid.get()].Connected)
	{
		nlwarning("Ready of an unknown service %s-%hu", serviceName.c_str(), sid.get());
		return;
	}

	nlinfo("*:*:%d is ready '%s'", Services[sid.get()].ServiceId.get(), Services[sid.get()].getServiceUnifiedName().c_str());
	Services[sid.get()].Ready = true;
}
示例#17
0
static void cbExecCommandResult(CMessage &msgin, const std::string &serviceName, TServiceId sid)
{
	// treat the rely message sent back from a service whom we asked to execute a command
	NLMISC::InfoLog->displayNL("EXEC_COMMAND_RESULT' Received from: %3d: %s", sid.get() ,serviceName.c_str());

	// retrieve the text from the input message
	CSString txt;
	msgin.serial(txt);

	// divide the text into lines because NeL doesn't like long texts
	CVectorSString lines;
	txt.splitLines(lines);

	// display the lines of text
	for (uint32 i=0;i<lines.size();++i)
	{
		NLMISC::InfoLog->displayNL("%s",lines[i].c_str());
	}
}
bool writeServiceLaunchCtrl(TServiceId serviceId,bool delay,const std::string& txt)
{
	// run trough the services container looking for a match for the service id that we've been given
	for (TServices::iterator it= Services.begin(); it!=Services.end(); ++it)
	{
		if (it->ServiceId==serviceId)
		{
			// we found a match for the service id so try to do something sensible with it...

			// get hold of the different components of the command description...
			string alias, command, path, arg;
			bool ok= getServiceLaunchInfo(it->AliasName,alias,command,path,arg);
			if (!ok) return false;

			// go ahead and write the launch ctrl file...
			return writeServiceLaunchCtrl(alias,path,delay,txt);
		}
	}

	// we failed to find a match for the serviceId that we've been given so complain and return false
	nlwarning("Failed to write launch_ctrl file for unknown service: %u",serviceId.get());
	return false;
}
void addRequest(uint32 rid, const string &rawvarpath, TServiceId sid)
{
	nlinfo("REQUEST: addRequest from %hu: '%s'", sid.get(), rawvarpath.c_str());

	string str;
	CLog logDisplayVars;
	CMemDisplayer mdDisplayVars;
	logDisplayVars.addDisplayer(&mdDisplayVars);

	CVarPath varpath(rawvarpath);

	// add the request
	Requests.push_back(CRequest(rid, sid));

	// for each destination in the rawvarpath...
	for (uint i = 0; i < varpath.Destination.size(); i++)
	{
		CVarPath vp(varpath.Destination[i].first);
		for (uint t = 0; t < vp.Destination.size(); t++)
		{
			string service = vp.Destination[t].first;

			if (service == "*")
			{
				addRequestForOnlineServices(rid,varpath.Destination[i].second);
			}
			else if (service == "#")
			{
				addRequestForAllServices(rid,varpath.Destination[i].second);
			}
			else
			{
				addRequestForNamedService(rid,service,varpath.Destination[i].second);
			}
		}
	}
}
示例#20
0
文件: admin.cpp 项目: mixxit/solinia
static void cbStopService (CMessage &/* msgin */, const std::string &serviceName, TServiceId sid)
{
	nlinfo ("ADMIN: Receive a stop from service %s-%hu, need to quit", serviceName.c_str(), sid.get());
	IService::getInstance()->exit (0xFFFF);
}
示例#21
0
void CMirrorService::receiveDeltaFromRemoteMS( CMessage& msgin, TServiceId senderMSId )
{
	H_AUTO(receiveDeltaFromRemoteMS);

	// 2b. Receive delta updates from remote MSs => store them in pending deltas
	_PendingDeltas.push_back( make_pair( senderMSId, msgin ) ); // warning: msgin must be copied because below we advance the reading position of msgin
	//nldebug( "Received delta from %s", servStr(senderMSId).c_str() );

	// Get the "wait for" mode of this remote MS delta
	bool waitForIt;
	msgin.serial( waitForIt );
	if ( waitForIt ) // we assume it does not change during the lifetime of a particular remote MS
	{
		// Check if the sender is a new remote MS (search in the "delta update expectation list")
		std::list< TServiceId >::const_iterator it = find( _RemoteMSToWaitForDelta.begin(), _RemoteMSToWaitForDelta.end(), senderMSId );
		if ( it == _RemoteMSToWaitForDelta.end() )
		{
			_RemoteMSToWaitForDelta.push_back( senderMSId ); // _RemoteMSToWaitForDelta will not contain remote MSes for which we don't have to wait
			++_NbExpectedDeltaUpdates;
		}
	}

	TGameCycle gamecycle;
	msgin.serial( gamecycle );
	//nldebug( "%u: Rcvd Delta %u", CTickProxy::getGameCycle(), gamecycle );
	_QuickLog.displayNL( "TCK-%u: Rcvd Delta %u from MS-%hu (NbExpectedDelta=%hd)", CTickProxy::getGameCycle(), gamecycle, senderMSId.get(), _NbExpectedDeltaUpdates );

	// Count this delta update for the wait test only if its tick is the current tick or +1 (see explanation below)
	// Explanation: possibles cases:
	//
	//                  MS1                  MS2
	//                   |                    |
	//             Tick1>|              Tick1>|
	//             Delta>|>Delta <====> Delta>|>Delta
	//                   |>Tock1              |>Tock1
	//                   |                    |
	//                   |              Tick2>|
	//             Delta>|       <-----       |>Delta
	//             Tick2>|>Delta -----> Delta>|>Tock2
	//                   |>Tock2              |
	//
	if ( CTickProxy::State == ExpectingMasterTick )
	{
		// If sync not received yet, defer possible incrementation of _NbDeltaUpdatesReceived
		// because we can't compare now the gamecycle of the delta update with the current gamecycle
		// (see examineDeltaUpdatesReceivedBeforeSync() called when receiving the sync)
		if ( CTickProxy::getGameCycle() == 0 )
		{
			if ( waitForIt )
				_GameCyclesOfDeltaReceivedBeforeSync.push_back( gamecycle );
			return;
		}
		// Accept +1 only if received by advance (before the tick update)
		// Forbid >+1
		// Discard <=
		else if ( gamecycle > CTickProxy::getGameCycle() )
		{
			nlassert( gamecycle == CTickProxy::getGameCycle() + 1 );
			if ( waitForIt )
				++_NbDeltaUpdatesReceived;
		}
	}
	else
	{
		// Accept == if received in the same tick
		// Forbid >
		// Discard <
		if ( gamecycle >= CTickProxy::getGameCycle() )
		{
			nlassert( gamecycle == CTickProxy::getGameCycle() );
			if ( waitForIt )
				++_NbDeltaUpdatesReceived;
		}
	}

	doNextTask();
}
static void cbAdminPong(CMessage &msgin, const std::string &serviceName, TServiceId sid)
{
	for(uint i = 0; i < Services.size(); i++)
	{
		if(Services[i].ServiceId == sid)
		{
			nlinfo("receive pong");
			if(Services[i].LastPing == 0)
				nlwarning("Received a pong from service %s-%hu but we didn't expect a pong from it", serviceName.c_str(), sid.get());
			else
				Services[i].LastPing = 0;
			return;
		}
	}
	nlwarning("Received a pong from service %s-%hu that is not in my service list", serviceName.c_str(), sid.get());
}
示例#23
0
// 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;
		}
	}
}
示例#24
0
void cbDownService(const std::string &serviceName, TServiceId sid, void *arg)
{
	nlinfo("Service %s %d is down", serviceName.c_str(), sid.get());
}
static void ASDisconnection(const string &serviceName, TServiceId sid, void *arg)
{
	nlinfo("Disconnected to %s-%hu", serviceName.c_str(), sid.get());
}
示例#26
0
void CTickProxy::receiveTockFromClient( CMessage& msgin, TServiceId senderId, bool real )
{
	// Receive measures of client service
	TimeMeasures.ServiceMeasures.push_back( CServiceGameCycleTimeMeasure() );
	CServiceGameCycleTimeMeasure& stm = TimeMeasures.ServiceMeasures.back();
	stm.ClientServiceId = senderId;
	if ( real )
	{
		stm.ServiceMeasure[TickTockInterval] = accTimeToMs( getAccurateTime() - _BeginOfTickTime );
		msgin.serial( stm.ServiceMeasure[TickUpdateDuration] );
		msgin.serial( stm.ServiceMeasure[PrevProcessMirrorUpdateDuration] );
		msgin.serial( stm.ServiceMeasure[PrevReceiveMsgsViaMirrorDuration] );
		msgin.serial( stm.ServiceMeasure[PrevTotalGameCycleDuration] );
	}
	else
	{
		for ( uint i=0; i!=NbServiceTimeMeasureTypes; ++i )
			stm.ServiceMeasure[i] = 0;
	}
	
	//nldebug( "TCK-%u: %hu tocking", getGameCycle(), senderId );
	//time_t t; time( &t );
	_QuickLog.displayNL( "%"NL_I64"u: TCK-%u: %hu tocking", getPerfTime() /*IDisplayer::dateToHumanString( t )*/, getGameCycle(), senderId.get() );
	++_NbTocked;
	_TockedServices.push_back( senderId );

	cbDoNextTask();
}
void serviceDisconnection(const std::string &serviceName, TServiceId sid, void *arg)
{
	// don't remove AS
	if (serviceName == "AS")
		return;

	if (sid.get() >= Services.size())
	{
		nlwarning("Disconnection of an unknown service %s-%hu", serviceName.c_str(), sid.get());
		return;
	}

	if (!Services[sid.get()].Connected)
	{
		nlwarning("Disconnection of an unknown service %s-%hu", serviceName.c_str(), sid.get());
		return;
	}

	// we need to remove pending request

	for(uint i = 0; i < Services[sid.get()].WaitingRequestId.size(); i++)
	{
		subRequestWaitingNb(Services[sid.get()].WaitingRequestId[i]);
	}

	nlinfo("%s-%hu disconnected", Services[sid.get()].ShortName.c_str(), Services[sid.get()].ServiceId.get());

	if (Services[sid.get()].Relaunch)
	{
		// we have to relaunch it in time because ADMIN asked it
		sint32 delay = IService::getInstance()->ConfigFile.exists("RestartDelay")? IService::getInstance()->ConfigFile.getVar("RestartDelay").asInt(): 5;

		// must restart it so if delay is -1, set it by default to 5 seconds
		if (delay == -1) delay = 5;

		startService(delay, Services[sid.get()].getServiceUnifiedName());
	}
	else if (Services[sid.get()].AutoReconnect)
	{
		// we have to relaunch it
		sint32 delay = IService::getInstance()->ConfigFile.exists("RestartDelay")? IService::getInstance()->ConfigFile.getVar("RestartDelay").asInt(): 5;
		if (delay >= 0)
		{
			startService(delay, Services[sid.get()].getServiceUnifiedName());
		}
		else
			nlinfo("Don't restart the service because RestartDelay is %d", delay);

		sendAdminEmail("Server %s service '%s' : Stopped, auto reconnect in %d seconds", CInetAddress::localHost().hostName().c_str(), Services[sid.get()].getServiceUnifiedName().c_str(), delay);
	}

	// if the appropriate cfg file variable is set then we kill the service brutally on disconnection - this
	// allows one to fix a certain number of problem cases in program shut-down that would otherwise require
	// manual intervention on the machine
	if (KillServicesOnDisconnect)
	{
		killProgram(Services[sid.get()].PId);
	}

	Services[sid.get()].reset();
}
示例#28
0
void CTickProxy::sendSyncToClient( TServiceId serviceId )
{
	CMessage msgout( "REGISTERED" );
	msgout.serial( _GameTime );
	msgout.serial( _GameTimeStep );
	msgout.serial( _GameCycle );
	CUnifiedNetwork::getInstance()->send( serviceId, msgout );
	//nldebug( "TCK-%u: Sync %hu", getGameCycle(), serviceId );
	//time_t t; time( &t );
	_QuickLog.displayNL( "%"NL_I64"u: TCK-%u: Sync %hu", getPerfTime() /*IDisplayer::dateToHumanString( t )*/, getGameCycle(), serviceId.get() );
}
示例#29
0
文件: admin.cpp 项目: mixxit/solinia
static void cbAESDisconnection (const std::string &serviceName, TServiceId sid, void * /* arg */)
{
	nlinfo("Lost connection to the %s-%hu", serviceName.c_str(), sid.get());
}
static void cbServiceIdentification(CMessage &msgin, const std::string &serviceName, TServiceId sid)
{
	if (sid.get() >= Services.size())
	{
		nlwarning("Identification of an unknown service %s-%hu", serviceName.c_str(), sid.get());
		return;
	}

	if (!Services[sid.get()].Connected)
	{
		nlwarning("Identification of an unknown service %s-%hu", serviceName.c_str(), sid.get());
		return;
	}

	msgin.serial(Services[sid.get()].AliasName, Services[sid.get()].LongName, Services[sid.get()].PId);
	msgin.serialCont(Services[sid.get()].Commands);
	nlinfo("Received service identification: Sid=%-3i Alias='%s' LongName='%s' ShortName='%s' PId=%u",sid.get(),Services[sid.get()].AliasName.c_str(),Services[sid.get()].LongName.c_str(),serviceName.c_str(),Services[sid.get()].PId);

	// if there's an alias, it means that it s me that launch the services, autoreconnect it
	if (!Services[sid.get()].AliasName.empty())
		Services[sid.get()].AutoReconnect = true;

	nlinfo("*:*:%d is identified to be '%s' '%s' pid:%d", Services[sid.get()].ServiceId.get(), Services[sid.get()].getServiceUnifiedName().c_str(), Services[sid.get()].LongName.c_str(), Services[sid.get()].PId);
}