Connection disconnects now working

This commit is contained in:
xethm55 2012-10-01 21:17:49 -04:00
parent f173281614
commit efe25fe610
8 changed files with 291 additions and 105 deletions

View File

@ -15,8 +15,12 @@ Client::Client()
Client::~Client() Client::~Client()
{ {
// Send disconnect message // Send disconnect message
bool connection_closed = false;
double close_timer;
sf::Packet client_packet; sf::Packet client_packet;
sf::Uint8 packet_type = PLAYER_DISCONNECT; sf::Uint8 packet_type = PLAYER_DISCONNECT;
Timer client_timer;
client_timer.Init();
client_packet.clear(); client_packet.clear();
client_packet << packet_type; client_packet << packet_type;
client_packet << current_player; client_packet << current_player;
@ -25,16 +29,52 @@ Client::~Client()
// No time out needed here, since the // No time out needed here, since the
// message will timeout after a couple of attempts // message will timeout after a couple of attempts
// then exit anyway. // then exit anyway.
while(m_net_client->pendingMessages()) close_timer = Timer::GetTimeDouble();
while(!connection_closed)
{ {
// Time must be updated before any messages are sent
// Especially guaranteed messages, since the time needs to be
// non zero.
client_timer.Update();
m_net_client->Receive(); m_net_client->Receive();
while(m_net_client->getData(client_packet))
{
sf::Uint8 packet_type;
client_packet >> packet_type;
switch(packet_type)
{
case PLAYER_DISCONNECT:
{
sf::Uint8 player_index;
// This completely removes the player from the game
// Deletes member from the player list
client_packet >> player_index;
if(player_index == current_player)
{
connection_closed = true;
}
break;
}
}
}
m_net_client->Transmit(); m_net_client->Transmit();
// temporary for now. otherwise this thread consumed way too processing // temporary for now. otherwise this thread consumed way too processing
sf::sleep(sf::seconds(0.005)); // 5 milli-seconds sf::sleep(sf::seconds(0.005)); // 5 milli-seconds
// If the server does not respond within one second just close
// and the server can deal with the problems.
if((Timer::GetTimeDouble() - close_timer) > 1.0)
{
connection_closed = true;
}
} }
m_net_client->Destroy(); m_net_client->Destroy();
m_players.clear();
} }
@ -120,15 +160,16 @@ void Client::update(double elapsed_time)
{ {
case PLAYER_CONNECT: case PLAYER_CONNECT:
{ {
sf::Uint32 players_address = 0u; sf::Uint16 players_port = sf::Socket::AnyPort;
sf::Uint8 pindex; sf::Uint8 pindex;
std::string name = ""; std::string name = "";
client_packet >> pindex; client_packet >> pindex;
client_packet >> name; client_packet >> name;
client_packet >> players_address; client_packet >> players_port;
// Should be a much better way of doing this. // Should be a much better way of doing this.
// Perhaps generate a random number // Perhaps generate a random number
if((sf::Uint32)((sf::Uint64)(&m_players)) == players_address) if((name == current_player_name) &&
(m_net_client->getLocalPort() == players_port))
{ {
current_player = pindex; current_player = pindex;
} }
@ -245,16 +286,16 @@ void Client::update(double elapsed_time)
else if(!registered_player) else if(!registered_player)
{ {
// Needs to be 32 bit so that the packet << overload will work. // Needs to be 32 bit so that the packet << overload will work.
sf::Uint32 players_address = (sf::Uint32)((sf::Uint64)(&m_players)); sf::Uint16 players_port = m_net_client->getLocalPort();
sf::Uint8 packet_type = PLAYER_CONNECT; sf::Uint8 packet_type = PLAYER_CONNECT;
client_packet.clear(); client_packet.clear();
client_packet << packet_type; client_packet << packet_type;
client_packet << current_player; client_packet << current_player;
client_packet << current_player_name; client_packet << current_player_name;
// Send the address of the players map. This will server as a unique // Send the players port. This will server as a unique
// identifier and prevent users with the same name from controlling // identifier and prevent users with the same name from controlling
// each other. // each other.
client_packet << players_address; client_packet << players_port;
m_net_client->sendData(client_packet, true); m_net_client->sendData(client_packet, true);
registered_player = true; registered_player = true;
} }

View File

@ -33,6 +33,7 @@ void Network::Create(sf::Uint16 port, sf::IpAddress address )
{ {
tmpclient.addr = address; tmpclient.addr = address;
tmpclient.port = port; tmpclient.port = port;
tmpclient.disconnect = DISCONNECTED;
numclients = addClients(&tmpclient, &current_client); numclients = addClients(&tmpclient, &current_client);
net_socket.bind( sf::Socket::AnyPort ); net_socket.bind( sf::Socket::AnyPort );
@ -48,10 +49,11 @@ void Network::Create(sf::Uint16 port, sf::IpAddress address )
void Network::Destroy( void ) void Network::Destroy( void )
{ {
/* Clean and exit */ /* Clean and exit */
Reset();
net_socket.unbind(); net_socket.unbind();
} }
bool Network::getData(sf::Packet& p) bool Network::getData(sf::Packet& p, sf::Uint8* sending_client)
{ {
bool rtn = false; bool rtn = false;
sf::Uint16 curcl; sf::Uint16 curcl;
@ -64,6 +66,10 @@ bool Network::getData(sf::Packet& p)
{ {
p = clients[curcl].receive.front(); p = clients[curcl].receive.front();
clients[curcl].receive.pop(); clients[curcl].receive.pop();
if(sending_client != NULL)
{
*sending_client = curcl;
}
rtn = true; rtn = true;
break; break;
} }
@ -75,26 +81,33 @@ bool Network::getData(sf::Packet& p)
bool Network::queueTransmitMessage(Network_Messages_T msg_type , sf::Packet p, Client_t * dest) bool Network::queueTransmitMessage(Network_Messages_T msg_type , sf::Packet p, Client_t * dest)
{ {
sf::Packet packet; bool added_message_to_queue = false;
sf::Uint8 type = (sf::Uint8)msg_type; // Only queue a message if there are clients to receive it
sf::Uint32 uid = UNIQUE_ID; if(numclients > 0)
sf::Uint32 msg_id = getUniqueMessageId(); {
Transmit_Message_t* message = new Transmit_Message_t(); sf::Packet packet;
sf::Uint8 type = (sf::Uint8)msg_type;
sf::Uint32 uid = UNIQUE_ID;
sf::Uint32 msg_id = getUniqueMessageId();
Transmit_Message_t* message = new Transmit_Message_t();
// Add this to the list of packets expecting a response // Add this to the list of packets expecting a response
packet << uid; packet << uid;
packet << type; packet << type;
packet << msg_id; packet << msg_id;
packet.append(p.getData(), p.getDataSize()); packet.append(p.getData(), p.getDataSize());
message->msg_type = msg_type; message->msg_type = msg_type;
message->Data = packet; message->Data = packet;
message->TimeStarted = 0.0; message->TimeStarted = 0.0;
message->dest = dest; message->dest = dest;
transmit_queue[msg_id] = message; transmit_queue[msg_id] = message;
return true; added_message_to_queue = true;
}
return added_message_to_queue;
} }
bool Network::sendData(sf::Packet& p, bool guaranteed) bool Network::sendData(sf::Packet& p, bool guaranteed)
@ -131,6 +144,8 @@ int Network::addClients(Client_t *client, sf::Uint16 *curcl)
{ {
clients[i].addr = client->addr; clients[i].addr = client->addr;
clients[i].port = client->port; clients[i].port = client->port;
// Set that a client is now connected
clients[i].disconnect = CONNECTED;
*curcl = i; *curcl = i;
i++; i++;
} }
@ -202,6 +217,11 @@ void Network::Receive()
if(MAX_NUM_CLIENTS > client_id) if(MAX_NUM_CLIENTS > client_id)
{ {
clients[client_id].ping = Timer::GetTimeDouble() - transmit_queue[msg_id]->TimeStarted; clients[client_id].ping = Timer::GetTimeDouble() - transmit_queue[msg_id]->TimeStarted;
// Need to also register that a ping message was received.
transmit_queue[msg_id]->Responses[&clients[client_id]] = Timer::GetTimeDouble();
// Received a response, so reset send attempts.
clients[client_id].num_send_attempts = 0u;
} }
break; break;
} }
@ -212,6 +232,9 @@ void Network::Receive()
if(MAX_NUM_CLIENTS > client_id) if(MAX_NUM_CLIENTS > client_id)
{ {
transmit_queue[msg_id]->Responses[&clients[client_id]] = Timer::GetTimeDouble(); transmit_queue[msg_id]->Responses[&clients[client_id]] = Timer::GetTimeDouble();
// Received a response, so reset send attempts.
clients[client_id].num_send_attempts = 0u;
} }
break; break;
} }
@ -262,16 +285,31 @@ void Network::Transmit()
// Broadcast the mesages to all clients // Broadcast the mesages to all clients
sf::Uint32 msg_id = 0; sf::Uint32 msg_id = 0;
static double ping_timer = Timer::GetTimeDouble(); static double ping_timer = Timer::GetTimeDouble();
double current_time = Timer::GetTimeDouble();
// Once per second, send ping messages ( just for fun ) // Every five seconds, send ping messages
if((Timer::GetTimeDouble() - ping_timer) > 1000.0) // Note this time must be longer than the combined
// timeout and retry count, otherwise a client will never
// be removed.
if((current_time - ping_timer) > 1.0)
{ {
ping_timer = Timer::GetTimeDouble(); ping_timer = current_time;
sf::Packet response; sf::Packet response;
response.clear(); response.clear();
queueTransmitMessage(NETWORK_PING, response); queueTransmitMessage(NETWORK_PING, response);
} }
// Set any clients waiting to be removed to the
// do removal state. This will get changed in the
// Transmit loop below if there are any pending messages
for(int client_ndx = 0; client_ndx < MAX_NUM_CLIENTS; client_ndx++)
{
if(clients[client_ndx].disconnect == WAIT_DISCONNECT)
{
clients[client_ndx].disconnect = DO_DISCONNECT;
}
}
// Send any pending messages // Send any pending messages
while(transmit_queue.find(msg_id) != transmit_queue.end()) while(transmit_queue.find(msg_id) != transmit_queue.end())
{ {
@ -306,7 +344,7 @@ void Network::Transmit()
for ( std::map<Client_t*, double>::iterator iter = message->ClientTimeSent.begin(); iter != message->ClientTimeSent.end(); ++iter ) for ( std::map<Client_t*, double>::iterator iter = message->ClientTimeSent.begin(); iter != message->ClientTimeSent.end(); ++iter )
{ {
// Determine if enough time has elapsed to try and re-send // Determine if enough time has elapsed to try and re-send
if((curTime - iter->second) >= 0.5) if((curTime - iter->second) >= NETWORK_TIMEOUT)
{ {
// Determine if a response was already received from this client // Determine if a response was already received from this client
if(message->Responses.find(iter->first) == message->Responses.end()) if(message->Responses.find(iter->first) == message->Responses.end())
@ -314,8 +352,26 @@ void Network::Transmit()
// Resend the message to the client // Resend the message to the client
net_socket.send(message->Data, iter->first->addr, iter->first->port); net_socket.send(message->Data, iter->first->addr, iter->first->port);
message->ClientTimeSent[iter->first] = curTime; message->ClientTimeSent[iter->first] = curTime;
// Keep track of the number of attempts
// if the number of attempts is exceeded, fake a receive message
// and set a timeout disconnect state
iter->first->num_send_attempts++;
if(MAX_NUM_SEND_ATTEMPTS < iter->first->num_send_attempts)
{
// Fake a receive message so that it will complete and be removed from the queue
message->Responses[iter->first] = Timer::GetTimeDouble();
iter->first->disconnect = TIMEOUT_DISCONNECT;
}
} }
} }
// There are still pending messages for this client
// Move back to wait state.
if(iter->first->disconnect == DO_DISCONNECT)
{
iter->first->disconnect = WAIT_DISCONNECT;
}
} }
} }
else else
@ -356,6 +412,28 @@ void Network::Transmit()
} }
msg_id++; msg_id++;
} }
// Any clients that still have the disconnect action
// are now safe to remove (i.e. no longer have pending messages)
for(int client_ndx = 0; client_ndx < MAX_NUM_CLIENTS; client_ndx++)
{
if(clients[client_ndx].disconnect == DO_DISCONNECT)
{
// Reset all client information.
clients[client_ndx].addr = sf::IpAddress();
clients[client_ndx].port = 0;
clients[client_ndx].disconnect = DISCONNECTED;
while(!clients[client_ndx].receive.empty())
{
clients[client_ndx].receive.pop();
}
// Decrement the number of connected clients.
if(numclients > 0)
{
numclients--;
}
}
}
} }
int Network::getNumConnected( void ) int Network::getNumConnected( void )
@ -370,6 +448,7 @@ void Network::Reset()
{ {
clients[i].addr = sf::IpAddress(); clients[i].addr = sf::IpAddress();
clients[i].port = 0; clients[i].port = 0;
clients[i].disconnect = DISCONNECTED;
while(!clients[i].receive.empty()) while(!clients[i].receive.empty())
{ {
clients[i].receive.pop(); clients[i].receive.pop();
@ -393,6 +472,28 @@ bool Network::pendingMessages()
return (transmit_queue.size() > 0); return (transmit_queue.size() > 0);
} }
sf::Uint16 Network::getLocalPort()
{
return net_socket.getLocalPort();
}
void Network::disconnectClient(Client_t* player_client)
{
clients[findClient(player_client)].disconnect = WAIT_DISCONNECT;
}
Client_t* Network::getClient( sf::Uint8 client_ndx )
{
Client_t* tmp_client = NULL;
if(client_ndx < MAX_NUM_CLIENTS)
{
tmp_client = &clients[client_ndx];
}
return tmp_client;
}
sf::Packet& operator <<(sf::Packet& Packet, const Network_Messages_T& NMT) sf::Packet& operator <<(sf::Packet& Packet, const Network_Messages_T& NMT)
{ {
sf::Uint8 net_msg_t = (sf::Uint8)NMT; sf::Uint8 net_msg_t = (sf::Uint8)NMT;

View File

@ -14,10 +14,10 @@
#define UNIQUE_ID 0xDEADBEEF #define UNIQUE_ID 0xDEADBEEF
#define RECEIVE_BUFFER_SIZE 1024 #define RECEIVE_BUFFER_SIZE 1024
// In milliseconds // In seconds
#define NETWORK_TIMEOUT 5000 #define NETWORK_TIMEOUT 1
#define MAX_NUM_SEND_ATTEMPTS 3
// The bit indicating if the message requires a response // The bit indicating if the message requires a response
#define MSG_REQUIRES_RESPONSE_BIT ((sf::Uint16)1 << 15) #define MSG_REQUIRES_RESPONSE_BIT ((sf::Uint16)1 << 15)
@ -35,11 +35,20 @@ typedef enum{
NETWORK_GUARANTEED NETWORK_GUARANTEED
}Network_Messages_T; }Network_Messages_T;
typedef enum{
DISCONNECTED,
CONNECTED,
TIMEOUT_DISCONNECT,
WAIT_DISCONNECT,
DO_DISCONNECT
}Disconnect_States_t;
typedef struct{ typedef struct{
sf::IpAddress addr; sf::IpAddress addr;
unsigned short port; unsigned short port;
double ping; double ping;
Disconnect_States_t disconnect;
sf::Uint8 num_send_attempts;
std::queue<sf::Packet> receive; std::queue<sf::Packet> receive;
}Client_t; }Client_t;
@ -72,22 +81,25 @@ class Network{
static std::map<sf::Uint32, Transmit_Message_t*> transmit_queue; static std::map<sf::Uint32, Transmit_Message_t*> transmit_queue;
static char rxbuff[RECEIVE_BUFFER_SIZE]; static char rxbuff[RECEIVE_BUFFER_SIZE];
static sf::Clock message_timer; static sf::Clock message_timer;
static sf::Uint32 getUniqueMessageId( void ); static sf::Uint32 getUniqueMessageId();
static int addClients(Client_t *client, sf::Uint16 *curcl); static int addClients(Client_t *client, sf::Uint16 *curcl);
static int findClient(Client_t *client); static int findClient(Client_t *client);
static bool queueTransmitMessage(Network_Messages_T msg_type , sf::Packet p, Client_t * dest = NULL); static bool queueTransmitMessage(Network_Messages_T msg_type , sf::Packet p, Client_t * dest = NULL);
static Client_t clients[MAX_NUM_CLIENTS];
public: public:
static Client_t clients[MAX_NUM_CLIENTS];
static void Create( sf::Uint16 port, sf::IpAddress address ); static void Create( sf::Uint16 port, sf::IpAddress address );
static void Destroy( void ); static void Destroy();
static bool getData(sf::Packet& p); static bool getData(sf::Packet& p, sf::Uint8* sending_client = NULL);
static bool sendData(sf::Packet& p, bool guaranteed = false); static bool sendData(sf::Packet& p, bool guaranteed = false);
static int getNumConnected( void ); static int getNumConnected();
static void Transmit(); static void Transmit();
static void Receive(); static void Receive();
static void Reset(); static void Reset();
static bool pendingMessages(); static bool pendingMessages();
static sf::Uint16 getLocalPort();
static void disconnectClient(Client_t* player_client);
static Client_t* getClient( sf::Uint8 client_ndx );
}; };
sf::Packet& operator <<(sf::Packet& Packet, const Network_Messages_T& NMT); sf::Packet& operator <<(sf::Packet& Packet, const Network_Messages_T& NMT);

View File

@ -14,4 +14,5 @@ Player::Player()
d_pressed = KEY_NOT_PRESSED; d_pressed = KEY_NOT_PRESSED;
rel_mouse_movement = 0; rel_mouse_movement = 0;
updated = false; updated = false;
m_client = NULL;
} }

View File

@ -4,6 +4,7 @@
#include <string> #include <string>
#include "Types.h" #include "Types.h"
#include "SFML/Config.hpp" #include "SFML/Config.hpp"
#include "Network.h"
class Player class Player
{ {
@ -19,6 +20,7 @@ class Player
sf::Uint8 d_pressed; sf::Uint8 d_pressed;
sf::Int32 rel_mouse_movement; sf::Int32 rel_mouse_movement;
bool updated; bool updated;
Client_t* m_client;
Player(); Player();
}; };

View File

@ -13,7 +13,7 @@ void Timer::Init(void)
myClock.restart(); myClock.restart();
// Set the time keepers to zero // Set the time keepers to zero
myTotalElapsedTime = 0; totalElapsedTime = 0;
// Reset the game speed // Reset the game speed
gameSpeed = 1.0f; gameSpeed = 1.0f;
@ -22,12 +22,11 @@ void Timer::Init(void)
void Timer::Update(void) void Timer::Update(void)
{ {
// Record the time step // Record the time step
stepTime = ((myClock.getElapsedTime().asSeconds() / 1000.0f) * gameSpeed); stepTime = (myClock.getElapsedTime().asSeconds() * gameSpeed);
myClock.restart(); myClock.restart();
// Add the time to the total time // Add the time to the total time
myTotalElapsedTime += stepTime; totalElapsedTime += stepTime;
totalElapsedTime = myTotalElapsedTime;
// Calculate the game step // Calculate the game step
curTimeStep = (sf::Uint32)(totalElapsedTime * STEPS_PER_SECOND); curTimeStep = (sf::Uint32)(totalElapsedTime * STEPS_PER_SECOND);
@ -45,7 +44,7 @@ float Timer::GetStepTime(void)
sf::Uint32 Timer::GetTotalTime(void) sf::Uint32 Timer::GetTotalTime(void)
{ {
return (sf::Uint32)(totalElapsedTime * 1000.0f); return (sf::Uint32)(totalElapsedTime);
} }
double Timer::GetTimeDouble(void) double Timer::GetTimeDouble(void)

View File

@ -35,9 +35,6 @@ private:
// The game speed // The game speed
float gameSpeed; float gameSpeed;
// The total elapsed time since the start of the game
double myTotalElapsedTime;
// The total elapsed time since the start of the game // The total elapsed time since the start of the game
static double totalElapsedTime; static double totalElapsedTime;

View File

@ -46,10 +46,11 @@ void Server::update( double elapsed_time )
static Player player_prev; static Player player_prev;
const double move_speed = 75.0; const double move_speed = 75.0;
sf::Packet server_packet; sf::Packet server_packet;
sf::Uint8 tmp_player_client;
m_net_server->Receive(); m_net_server->Receive();
// Handle all received data (only really want the latest) // Handle all received data (only really want the latest)
while(m_net_server->getData(server_packet)) while(m_net_server->getData(server_packet, &tmp_player_client))
{ {
sf::Uint8 ptype; sf::Uint8 ptype;
// Get packet type // Get packet type
@ -58,14 +59,14 @@ void Server::update( double elapsed_time )
{ {
case PLAYER_CONNECT: case PLAYER_CONNECT:
{ {
sf::Uint32 players_address = 0u; sf::Uint16 players_port = sf::Socket::AnyPort;
refptr<Player> p = new Player(); refptr<Player> p = new Player();
std::string pname; std::string pname;
sf::Uint8 pindex; sf::Uint8 pindex;
server_packet >> pindex; server_packet >> pindex;
server_packet >> pname; server_packet >> pname;
server_packet >> players_address; server_packet >> players_port;
// When a player connects, we need to associate // When a player connects, we need to associate
// that player with a new ID. find first unused id // that player with a new ID. find first unused id
// player zero means a player does not exist. // player zero means a player does not exist.
@ -79,17 +80,18 @@ void Server::update( double elapsed_time )
} }
} }
p->name = pname; p->name = pname;
p->m_client = m_net_server->getClient(tmp_player_client);
m_players[pindex] = p; m_players[pindex] = p;
// Alert all connected clients of all the connected players. // Alert all connected clients of all the connected players.
for(std::map<sf::Uint8, refptr<Player> >::iterator piter = m_players.begin(); piter != m_players.end(); piter++) for(std::map<sf::Uint8, refptr<Player> >::iterator piter = m_players.begin(); piter != m_players.end(); piter++)
{ {
sf::Uint32 paddress = ((piter->first == pindex) ? players_address : 0u); sf::Uint16 port = ((piter->first == pindex) ? players_port : 0u);
server_packet.clear(); server_packet.clear();
server_packet << ptype; server_packet << ptype;
server_packet << piter->first; server_packet << piter->first;
server_packet << piter->second->name; server_packet << piter->second->name;
server_packet << paddress; server_packet << port;
// Send correct starting locations so that they match // Send correct starting locations so that they match
// the other players screens. // the other players screens.
server_packet << piter->second->direction; server_packet << piter->second->direction;
@ -106,7 +108,8 @@ void Server::update( double elapsed_time )
// then update the stored contents. // then update the stored contents.
sf::Uint8 pindex; sf::Uint8 pindex;
server_packet >> pindex; server_packet >> pindex;
if(m_players.end() != m_players.find(pindex)) if((m_players.end() != m_players.find(pindex)) &&
(m_net_server->getClient(tmp_player_client) == m_players[pindex]->m_client))
{ {
server_packet >> m_players[pindex]->w_pressed; server_packet >> m_players[pindex]->w_pressed;
server_packet >> m_players[pindex]->a_pressed; server_packet >> m_players[pindex]->a_pressed;
@ -123,16 +126,21 @@ void Server::update( double elapsed_time )
// This completely removes the player from the game // This completely removes the player from the game
// Deletes member from the player list // Deletes member from the player list
server_packet >> pindex; server_packet >> pindex;
num_erased = m_players.erase(pindex); if((m_players.end() != m_players.find(pindex)) &&
if(1 == num_erased) (m_net_server->getClient(tmp_player_client) == m_players[pindex]->m_client))
{ {
// Player existed, alert all connected clients. // Tell networking code to remove the client.
server_packet.clear(); m_net_server->disconnectClient(m_players[pindex]->m_client);
server_packet << ptype; num_erased = m_players.erase(pindex);
server_packet << pindex; if(1 == num_erased)
m_net_server->sendData(server_packet, true); {
// Player exited, alert all connected clients.
server_packet.clear();
server_packet << ptype;
server_packet << pindex;
m_net_server->sendData(server_packet, true);
}
} }
break; break;
} }
case PLAYER_DEATH: case PLAYER_DEATH:
@ -149,57 +157,82 @@ void Server::update( double elapsed_time )
} }
} }
for(std::map<sf::Uint8, refptr<Player> >::iterator piter = m_players.begin(); piter != m_players.end(); piter++) for(std::map<sf::Uint8, refptr<Player> >::iterator piter = m_players.begin(); piter != m_players.end();)
{ {
sf::Uint8 pindex = piter->first; sf::Uint8 pindex = piter->first;
if (KEY_PRESSED == m_players[pindex]->a_pressed) // Increment to the next element. This is done in loop so that the
{ // erasing of players will not cause issues
double direction = m_players[pindex]->direction + M_PI_2; piter++;
m_players[pindex]->x += cos(direction) * move_speed * elapsed_time;
m_players[pindex]->y += sin(direction) * move_speed * elapsed_time;
m_players[pindex]->updated = true;
}
if (KEY_PRESSED == m_players[pindex]->d_pressed)
{
double direction = m_players[pindex]->direction - M_PI_2;
m_players[pindex]->x += cos(direction) * move_speed * elapsed_time;
m_players[pindex]->y += sin(direction) * move_speed * elapsed_time;
m_players[pindex]->updated = true;
}
if (KEY_PRESSED == m_players[pindex]->w_pressed)
{
double direction = m_players[pindex]->direction;
m_players[pindex]->x += cos(direction) * move_speed * elapsed_time;
m_players[pindex]->y += sin(direction) * move_speed * elapsed_time;
m_players[pindex]->updated = true;
}
if (KEY_PRESSED == m_players[pindex]->s_pressed)
{
double direction = m_players[pindex]->direction + M_PI;
m_players[pindex]->x += cos(direction) * move_speed * elapsed_time;
m_players[pindex]->y += sin(direction) * move_speed * elapsed_time;
m_players[pindex]->updated = true;
}
if(0 != m_players[pindex]->rel_mouse_movement)
{
m_players[pindex]->direction -= M_PI * 0.5 * m_players[pindex]->rel_mouse_movement / 1000;
m_players[pindex]->updated = true;
}
server_packet.clear(); if(m_players[pindex]->m_client->disconnect == CONNECTED)
// Send the player update if there were changes
if(m_players[pindex]->updated)
{ {
sf::Uint8 ptype = PLAYER_UPDATE; if (KEY_PRESSED == m_players[pindex]->a_pressed)
server_packet << ptype; {
server_packet << pindex; double direction = m_players[pindex]->direction + M_PI_2;
server_packet << m_players[pindex]->direction; m_players[pindex]->x += cos(direction) * move_speed * elapsed_time;
server_packet << m_players[pindex]->x; m_players[pindex]->y += sin(direction) * move_speed * elapsed_time;
server_packet << m_players[pindex]->y; m_players[pindex]->updated = true;
m_net_server->sendData(server_packet); }
m_players[pindex]->updated = false; if (KEY_PRESSED == m_players[pindex]->d_pressed)
} {
double direction = m_players[pindex]->direction - M_PI_2;
m_players[pindex]->x += cos(direction) * move_speed * elapsed_time;
m_players[pindex]->y += sin(direction) * move_speed * elapsed_time;
m_players[pindex]->updated = true;
}
if (KEY_PRESSED == m_players[pindex]->w_pressed)
{
double direction = m_players[pindex]->direction;
m_players[pindex]->x += cos(direction) * move_speed * elapsed_time;
m_players[pindex]->y += sin(direction) * move_speed * elapsed_time;
m_players[pindex]->updated = true;
}
if (KEY_PRESSED == m_players[pindex]->s_pressed)
{
double direction = m_players[pindex]->direction + M_PI;
m_players[pindex]->x += cos(direction) * move_speed * elapsed_time;
m_players[pindex]->y += sin(direction) * move_speed * elapsed_time;
m_players[pindex]->updated = true;
}
if(0 != m_players[pindex]->rel_mouse_movement)
{
m_players[pindex]->direction -= M_PI * 0.5 * m_players[pindex]->rel_mouse_movement / 1000;
m_players[pindex]->updated = true;
}
server_packet.clear();
// Send the player update if there were changes
if(m_players[pindex]->updated)
{
sf::Uint8 ptype = PLAYER_UPDATE;
server_packet << ptype;
server_packet << pindex;
server_packet << m_players[pindex]->direction;
server_packet << m_players[pindex]->x;
server_packet << m_players[pindex]->y;
m_net_server->sendData(server_packet);
m_players[pindex]->updated = false;
}
}
else
{
if(m_players[pindex]->m_client->disconnect == TIMEOUT_DISCONNECT)
{
// Tell networking code to remove the client.
m_net_server->disconnectClient(m_players[pindex]->m_client);
if(m_players.erase(pindex))
{
sf::Uint8 ptype = PLAYER_DISCONNECT;
// Player exited, alert all connected clients.
server_packet.clear();
server_packet << ptype;
server_packet << pindex;
m_net_server->sendData(server_packet, true);
}
}
}
} }
m_net_server->Transmit(); m_net_server->Transmit();
} }