Example #1
0
void xrServer::Update	()
{
	NET_Packet		Packet;
	u32				position;

	csPlayers.Enter	();

	VERIFY						(verify_entities());

	// game update
	game->ProcessDelayedEvent();
	game->Update	();

	// spawn queue
	u32 svT				= Device.TimerAsync();
	while (!(q_respawn.empty() || (svT<q_respawn.begin()->timestamp)))
	{
		// get
		svs_respawn	R		= *q_respawn.begin();
		q_respawn.erase		(q_respawn.begin());

		// 
		CSE_Abstract* E	= ID_to_entity(R.phantom);
		E->Spawn_Write		(Packet,FALSE);
		u16					ID;
		Packet.r_begin		(ID);	R_ASSERT(M_SPAWN==ID);
		ClientID clientID; clientID.set(0xffff);
		Process_spawn		(Packet,clientID);
	}

	// 
	for (u32 client=0; client<net_Players.size(); ++client)
	{
		// Initialize process and check for available bandwidth
		xrClientData*	Client		= (xrClientData*) net_Players	[client];
		if (!Client->net_Ready)		continue;		
		if (!HasBandwidth(Client) 
#ifdef DEBUG
			&& !g_sv_SendUpdate
#endif
			)	continue;		

		// Send relevant entities to client
		// CSE_Abstract*	Base	= Client->owner;
		u16 PacketType = M_UPDATE;
		Packet.w_begin	(PacketType);

		// GameUpdate
		++(Client->game_replicate_id);
		u32		g_it				= (Client->game_replicate_id % client_Count());
//		u32		g_id				= net_Players[g_it]->ID;
		ClientID g_id 				= net_Players[g_it]->ID;
		game->net_Export_Update		(Packet,Client->ID,g_id);

//		if (!Client->flags.bLocal)	
			game->net_Export_GameTime(Packet);

		if (!Client->flags.bLocal || client_Count() == 1)
		{
#ifdef DEBUG
			if (g_Dump_Update_Write) Msg("---- UPDATE_Write to %s --- ", *(Client->Name));
#endif					// Entities
			
			NET_Packet tmpPacket;
			xrS_entities::iterator	I=entities.begin(),E=entities.end();
			for (; I!=E; ++I)
			{
				CSE_Abstract&	Test = *(I->second);

				if (0==Test.owner)							continue;	// Phantom(?)
				if (!Test.net_Ready)						continue;
				if (Test.owner == Client && Client->flags.bLocal)					continue;	// Can't be relevant

				if (Test.s_flags.is(M_SPAWN_OBJECT_PHANTOM))	continue;	// Surely: phantom
				
				tmpPacket.B.count = 0;
				// write specific data
				{
					tmpPacket.w_u16			(Test.ID		);
					tmpPacket.w_chunk_open8	(position		);
					Test.UPDATE_Write		(tmpPacket			);
#ifdef DEBUG
					if (g_Dump_Update_Write) Msg("* %s : %d", Test.name(), u32(tmpPacket.w_tell()-position)-sizeof(u8));
#endif
					tmpPacket.w_chunk_close8	(position		);
					if (Packet.B.count + tmpPacket.B.count < NET_PacketSizeLimit)
					{
						Packet.w(tmpPacket.B.data, tmpPacket.B.count);
					}
					else
					{
						if (Packet.B.count > 2)	
						{
//							if (!Client->flags.bLocal)
//								Msg ("- Server Update[%d] to Client  : %d", PacketType, Packet.B.count);
							SendTo			(Client->ID,Packet,net_flags(FALSE,TRUE));
						}
						PacketType = M_UPDATE_OBJECTS;
						Packet.w_begin(PacketType);
					}
				}
			}
#ifdef DEBUG
			if (g_Dump_Update_Write) Msg("----------------------- ");
#endif			
		};

		if (Packet.B.count > 2)	
		{
//			if (!Client->flags.bLocal)
//				Msg ("- Server Update[%d] to Client  : %d", PacketType, Packet.B.count);
			SendTo			(Client->ID,Packet,net_flags(FALSE,TRUE));
		}
	}
#ifdef DEBUG
	g_sv_SendUpdate = 0;
#endif			

	if (game->sv_force_sync)	Perform_game_export();

	VERIFY						(verify_entities());
	//-----------------------------------------------------
	//Remove any of long time disconnected players
	for (u32 DI = 0; DI<net_Players_disconnected.size(); DI++)
	{
		IClient* CL = net_Players_disconnected[DI];
		if (CL->dwTime_LastUpdate+g_sv_Client_Reconnect_Time*60000<Device.dwTimeGlobal)
			client_Destroy(CL);
	}
	//-----------------------------------------------------
	csPlayers.Leave	();
}