Ejemplo n.º 1
0
//--------------------------------------
void ServerUpdate( float dt )
{
	NetClient client;
	uint32 commands_in;
	uint32 commands_out;
	Player* player;
	Bullet* b;

	// Advance time
	gClock->AdvanceTime( dt );

	// Update players
	UpdatePlayers( gPlayers, dt );

	// Update network
	gSession->OnUpdate();

	// Check packets
	while ( gServer.IsDataReady() )
	{
		// Get next packet
		gServer.ReceiveData( gReader, client );

		// Get player for this client
		player = GetPlayerByID( gPlayers, client.GetID() );

		// This client didn't connect correctly!
		if ( !player )
		{
			ConsolePrintf( CONSOLE_WARNING, "Server : Unknown client %u\n", client.GetID() );
			continue;
		}

		// Read commands
		commands_in = gReader.Read< uint32 >();
		commands_out = 0;

		// Client id message
		if ( commands_in & NC_HELLO )
		{
			commands_out |= NC_PLAYER_ID;
			commands_out |= NC_ADD;
		}

		// Client name message
		if ( commands_in & NC_NAME )
		{
			gReader.ReadString( player->name, MAX_NAME_LEN );
			ConsolePrintf( "Got name msg: %s\n", player->name );
		}

		// Client position update
		if ( commands_in & NC_LOCATION )
		{
			player->pos = gReader.Read< Vec2f >();
			player->rotation = gReader.Read< float >();
			
			// Replicate location message to other clients
			gWriter.Write( (uint32) NC_LOCATION );
			gWriter.Write( 1 );
			gWriter.Write( player->index );
			gWriter.Write( player->pos );
			gWriter.Write( player->rotation );
			for ( int i = 0; i < MAX_PLAYERS; ++i )
			{
				if ( gPlayers[i].active && i != player->index )
				{
					gServer.SendData( PacketWriter( gWriter ), gPlayers[i].address );
				}
			}
			gWriter.Clear();
		}

		// Client requesting to fire
		if ( commands_in & NC_FIRE )
		{
//			ConsolePrintf( "Server : Got fire command from %u\n", client.GetID() );
			b = ServerFire( player );
			if ( b )
			{
				// Replicate fire message to other clients
				gWriter.Write( (uint32) NC_FIRE );
				gWriter.Write( player->index );
				gWriter.Write( b->index );
				gWriter.Write( b->vel );
				for ( int i = 0; i < MAX_PLAYERS; ++i )
				{
					if ( gPlayers[i].active )
					{
						gServer.SendData( PacketWriter( gWriter ), gPlayers[i].address );
					}
				}
				gWriter.Clear();
			}
		}

		// Send commands back to client
		if ( commands_out )
		{
			gWriter.Write( commands_out );

			// ID the player
			if ( commands_out & NC_PLAYER_ID )
			{
				gWriter.Write( player->index );
			}

			// Tell the client about all clients (including them)
			if ( commands_out & NC_ADD )
			{
				gWriter.Write( GetNumActivePlayers( gPlayers ) );
				for ( int i = 0; i < MAX_PLAYERS; ++i )
				{
					if ( gPlayers[i].active )
					{
						SerializePlayer( &gPlayers[i], gWriter );
					}
				}
			}

			// Send command to client
			gServer.SendData( gWriter, client.Address, SENDOPT_RELIABLE );

			// Tell all other clients about the new player
			if ( commands_out & NC_ADD )
			{
				commands_out = NC_ADD;
				gWriter.Write( commands_out );
				gWriter.Write( 1 );

				SerializePlayer( player, gWriter );

				for ( int i = 0; i < MAX_PLAYERS; ++i )
				{
					if ( gPlayers[i].active && i != player->index )
					{
						gServer.SendData( PacketWriter( gWriter ), gPlayers[i].address, SENDOPT_RELIABLE );
					}
				}
				gWriter.Clear();
			}
		}
	}

	// Process kills
	commands_out = 0;
	for ( int i = 0; i < MAX_PLAYERS; ++i )
	{
		player = &gPlayers[i];
		if ( player->active && player->killedBy >= 0 )
		{
			if ( commands_out == 0 )
			{
				commands_out = NC_KILL;
				gWriter.Write( commands_out );
			}

			gWriter.Write( player->killedBy );
			gWriter.Write( player->index );

			player->killedBy = -1;
			player->alive = 0;

			Dictionary params;
			params.Set( "PlayerIndex", i );
			gClock->PostEventCallbackAfter( "RespawnPlayer", RESPAWN_TIME, params );
		}
	}
	if ( commands_out )
	{
		gServer.SendData( gWriter );
	}

	// Render
	ClearScreen();

	DrawTextFormat( 0, 0, "Time %s",
		Clock::GetStringFormatedTime( gClock->GetElapsedTime( Clock::TIME_SEC ) ).c_str() );

	DrawPlayerNames( gPlayers, 10, 28 );

	FlushRenderer();
}