- Server can handle multiple clients simultaneously. - Client can see other players in the game. - Server broadcasts the game state to all clients. - Client receives the game state and renders the other players. - Server assigns a unique ID to each player. - Client receives its player ID form the server. - Server handles client disconnections.. Kinda... Server is ignoring SIGPIPE signal. - Server and client signals are non-blocking. - Moved player objects off the stack and onto the heap.
67 lines
2.1 KiB
C++
67 lines
2.1 KiB
C++
#include <algorithm>
|
|
|
|
#include "game.h"
|
|
#include "network/game_state_message.h"
|
|
#include "network/socket.h"
|
|
#include "network/message.h"
|
|
|
|
Player* Game::add_player(BettolaLib::Network::Socket* socket) {
|
|
_players.push_back(new Player(socket));
|
|
return _players.back();
|
|
}
|
|
|
|
void Game::remove_player(unsigned int player_id) {
|
|
_players.erase(
|
|
std::remove_if(_players.begin(), _players.end(),
|
|
[player_id](const Player* player) {
|
|
return player->get_id() == player_id;
|
|
}),
|
|
_players.end());
|
|
}
|
|
|
|
void Game::update_player_pos(unsigned int player_id, float x, float y) {
|
|
auto it = std::find_if(_players.begin(), _players.end(),
|
|
[player_id](const Player* player) {
|
|
return player->get_id() == player_id;
|
|
});
|
|
if(it != _players.end()) {
|
|
(*it)->set_position(x, y);
|
|
}
|
|
}
|
|
|
|
void Game::broadcast_game_state(void) {
|
|
BettolaLib::Network::GameStateMessage msg;
|
|
msg.num_players = _players.size();
|
|
|
|
for(size_t i = 0; i < _players.size(); ++i) {
|
|
msg.players[i].player_id = _players[i]->get_id();
|
|
msg.players[i].x = _players[i]->get_x();
|
|
msg.players[i].y = _players[i]->get_y();
|
|
}
|
|
|
|
BettolaLib::Network::MessageHeader header;
|
|
header.type = BettolaLib::Network::MessageType::GameState;
|
|
header.size = sizeof(msg);
|
|
|
|
for(const auto& player : _players) {
|
|
BettolaLib::Network::Socket& socket = player->get_socket();
|
|
/* Just quick fix the server crash for now. */
|
|
if(socket.send(&header, sizeof(header)) <= 0) {
|
|
/* TODO: Probably should handle this error by removing player.. */
|
|
}
|
|
if(socket.send(&msg, sizeof(msg)) <= 0) {
|
|
/* TODO: Probably should handle this error by removing player.. */
|
|
}
|
|
}
|
|
}
|
|
|
|
Player* Game::get_player_by_socket(BettolaLib::Network::Socket* socket) {
|
|
auto it = std::find_if(_players.begin(), _players.end(),
|
|
[socket](const Player* player) {
|
|
return &player->get_socket() == socket;
|
|
});
|
|
|
|
return(it != _players.end() ? *it : nullptr);
|
|
}
|
|
|