feat(server): Implement server-side game state.

* Added Player class to represent players on the server.
* Added Game class to manage the overall game state.
* Server now adds new players to the game state when they connect.
* Server now updates the players position in the game state on receiving
  a PlayerPosMessage.
This commit is contained in:
Ritchie Cunningham 2025-09-13 17:10:55 +01:00
parent d21a0df285
commit bd6281c9bc
6 changed files with 80 additions and 1 deletions

View File

@ -24,5 +24,6 @@ add_executable(bettola ${SOURCES})
target_link_libraries(bettola PRIVATE bettola_lib SDL3::SDL3 GLEW::glew OpenGL::GL)
# Server executable.
add_executable(bettola_server srv/main.cpp)
file(GLOB_RECURSE SERVER_SOURCES "srv/*.cpp")
add_executable(bettola_server ${SERVER_SOURCES})
target_link_libraries(bettola_server PRIVATE bettola_lib)

33
srv/game/game.cpp Normal file
View File

@ -0,0 +1,33 @@
#include <algorithm>
#include "game.h"
#include "network/socket.h"
void Game::add_player(BettolaLib::Network::Socket* socket) {
_players.emplace_back(socket);
}
void Game::remove_player(BettolaLib::Network::Socket* socket) {
/*
* TODO: We'll need a better way to ident players other than
* their socket. We'll match sockets for now though.. -- Falco
*/
_players.erase(
std::remove_if(_players.begin(), _players.end(),
[socket](const Player& player) {
/* this is a sh.t way to compare players. */
return &player.get_socket() == socket;
}),
_players.end());
}
void Game::update_player_pos(BettolaLib::Network::Socket* socket, float x, float y) {
auto it = std::find_if(_players.begin(), _players.end(),
[socket](const Player& player) {
return &player.get_socket() == socket;
});
if(it != _players.end()) {
it->set_position(x, y);
}
}

15
srv/game/game.h Normal file
View File

@ -0,0 +1,15 @@
#pragma once
#include <vector>
#include "bettola/network/socket.h"
#include "player.h"
class Game {
public:
void add_player(BettolaLib::Network::Socket* socket);
void remove_player(BettolaLib::Network::Socket* socket);
void update_player_pos(BettolaLib::Network::Socket* socket, float x, float y);
private:
std::vector<Player> _players;
};

6
srv/game/player.cpp Normal file
View File

@ -0,0 +1,6 @@
#include "player.h"
#include "network/socket.h"
Player::Player(BettolaLib::Network::Socket* socket) :
_x(0.0f), _y(0.0f), _socket(socket) {}

17
srv/game/player.h Normal file
View File

@ -0,0 +1,17 @@
#pragma once
#include "bettola/network/socket.h"
class Player {
public:
Player(BettolaLib::Network::Socket* socket);
void set_position(float x, float y) { _x = x; _y = y; }
BettolaLib::Network::Socket& get_socket(void) const { return *_socket; }
private:
float _x;
float _y;
BettolaLib::Network::Socket* _socket;
};

View File

@ -4,8 +4,11 @@
#include "bettola/network/net_common.h"
#include "bettola/network/message.h"
#include "bettola/network/player_pos_message.h"
#include "game/game.h"
int main(void) {
Game game;
printf("=== Bettola Server: Starting ===\n");
BettolaLib::Network::Socket server_socket;
@ -39,6 +42,8 @@ int main(void) {
continue; /* try accepting again. */
}
game.add_player(client_socket);
printf("Bettola Server: Client connected!\n");
while(true) {
@ -46,6 +51,7 @@ int main(void) {
ssize_t bytes_received = client_socket->recv(&header, sizeof(header));
if(bytes_received <= 0) {
game.remove_player(client_socket);
break;
}
@ -55,6 +61,7 @@ int main(void) {
if(bytes_received > 0) {
printf("Bettola Server: Received PlayerPosition messgae: x=%.2f, y=%.2f\n",
msg.x, msg.y);
game.update_player_pos(client_socket, msg.x, msg.y);
}
}
}