Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/App/gameServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ void GameServer::handleNetworkEvent(Player player, const gameNet::ClientResign&)
}

void GameServer::handleNetworkEvent(Player player, const gameNet::ClientChat& event) {
m_server.broadcast(gameNet::ServerChat{.seat = (player == Player::Black ? gameNet::Seat::Black : gameNet::Seat::White), .message = event.message});
m_chatHistory.emplace_back(ChatEntry{player, event.message});
m_server.broadcast(gameNet::ServerChat{player, static_cast<unsigned>(m_chatHistory.size()), event.message});
}

} // namespace go::app
8 changes: 8 additions & 0 deletions src/App/include/app/gameServer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "core/IGameStateListener.hpp"
#include "core/game.hpp"
#include "data/player.hpp"
#include "gameNet/server.hpp"

#include <array>
Expand All @@ -15,6 +16,7 @@
namespace go {
namespace app {


class GameServer : public gameNet::IServerHandler, public IGameStateListener {
public:
explicit GameServer(std::size_t boardSize = 9u);
Expand All @@ -38,11 +40,17 @@ class GameServer : public gameNet::IServerHandler, public IGameStateListener {
void handleNetworkEvent(Player player, const gameNet::ClientResign& event);
void handleNetworkEvent(Player player, const gameNet::ClientChat& event);

struct ChatEntry {
Player player;
std::string message;
};

private:
Game m_game;
std::thread m_gameThread; //!< Runs the game loop.

std::unordered_map<Player, gameNet::SessionId> m_players;
std::vector<ChatEntry> m_chatHistory;

gameNet::Server m_server{};
};
Expand Down
12 changes: 4 additions & 8 deletions src/App/include/app/position.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ namespace go::app {

class Position {
public:
Position(EventHub& hub); //!< Hub allows to signal listeners on interesting updates.
Position() = default;

void reset(std::size_t boardSize); //!< Reset the position to some default data.
void init(const gameNet::ServerGameConfig& event); //!< Initialize the given position.
void apply(const gameNet::ServerDelta& delta); //!< Apply a delta to the current position if ok.
bool init(const gameNet::ServerGameConfig& event); //!< Initialize the given position. Returns true if it changed state.
bool apply(const gameNet::ServerDelta& delta); //!< Apply a delta to the current position if ok.
void setStatus(GameStatus status); //!< Update the status.

const Board& getBoard() const;
Expand All @@ -23,16 +23,12 @@ class Position {

private:
bool isDeltaApplicable(const gameNet::ServerDelta& delta); //!< Check if the delta is ok to use for the position update.
void updatePosition(const gameNet::ServerDelta& delta); //!< Update the position based on a server delta.
void signalOnAction(gameNet::ServerAction action); //!< Signal listeners. Call after applyDelta.

private:
unsigned m_moveId{0}; //!< Last move id in game.
GameStatus m_status{GameStatus::Idle}; //!< Current status of the game.
Player m_player{Player::Black};
Board m_board{9u};

EventHub& m_eventHub; //!< Send events when position changes.
};

} // namespace go::app
} // namespace go::app
15 changes: 13 additions & 2 deletions src/App/include/app/sessionManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,18 @@
#include <memory>
#include <mutex>
#include <string>
#include <unordered_map>
#include <vector>

namespace go::app {
class GameServer;

struct ChatEntry {
Player player;
unsigned messageId;
std::string message;
};

//! Gets game stat delta and constructs a local representation of the game.
//! Listeners can subscribe to certain signals, get notification when happens.
//! Listeners then check which signal and query the updated data from this SessionManager.
Expand Down Expand Up @@ -43,6 +50,7 @@ class SessionManager : public gameNet::IClientHandler {
GameStatus status() const;
Board board() const;
Player currentPlayer() const;
std::vector<ChatEntry> getChatSince(unsigned messageId) const;

public: // Client listener handlers
void onGameUpdate(const gameNet::ServerDelta& event) override;
Expand All @@ -53,9 +61,12 @@ class SessionManager : public gameNet::IClientHandler {
private:
gameNet::Client m_network;
EventHub m_eventHub;
Position m_position;
Position m_position{};

unsigned m_expectedMessageId{1u}; //!< Next expected chat message id.
std::vector<ChatEntry> m_chatHistory{}; //!< Chat history.
std::unordered_map<unsigned, ChatEntry> m_pendingChat{}; //!< Messages received out of order.

std::vector<std::string> m_chatHistory;
std::unique_ptr<GameServer> m_localServer;
mutable std::mutex m_stateMutex;
};
Expand Down
80 changes: 23 additions & 57 deletions src/App/position.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,46 +5,50 @@

namespace go::app {

Position::Position(EventHub& hub) : m_eventHub{hub} {
}

void Position::reset(const std::size_t boardSize) {
m_moveId = 0u;
m_status = GameStatus::Idle;
m_player = Player::Black;
m_board = Board{boardSize};

m_eventHub.signal(AS_BoardChange);
m_eventHub.signal(AS_PlayerChange);
m_eventHub.signal(AS_StateChange);
}

void Position::init(const gameNet::ServerGameConfig& event) {
bool Position::init(const gameNet::ServerGameConfig& event) {
if (m_status == GameStatus::Active) {
return;
return false;
}

// TODO: Komi and timer not yet implemented.
m_moveId = 0u;
m_status = GameStatus::Active;
m_player = Player::Black;
m_board = Board{event.boardSize};

m_eventHub.signal(AS_BoardChange);
m_eventHub.signal(AS_PlayerChange);
m_eventHub.signal(AS_StateChange);
return true;
}

void Position::apply(const gameNet::ServerDelta& delta) {
if (isDeltaApplicable(delta)) {
updatePosition(delta);
signalOnAction(delta.action);
bool Position::apply(const gameNet::ServerDelta& delta) {
if (!isDeltaApplicable(delta)) {
return false;
}

m_moveId = delta.turn;
m_status = delta.status == gameNet::GameStatus::Active ? GameStatus::Active : GameStatus::Done;
m_player = delta.next == gameNet::Seat::Black ? Player::Black : Player::White;

if (delta.action == gameNet::ServerAction::Place) {
if (delta.coord) {
m_board.place(Coord{delta.coord->x, delta.coord->y}, delta.seat == gameNet::Seat::Black ? Board::Stone::Black : Board::Stone::White);
for (const auto c: delta.captures) {
m_board.remove({c.x, c.y});
}
} else {
Logger().Log(Logging::LogLevel::Warning, "Game delta missing place coordinate; skipping board update.");
}
}
return true;
}

void Position::setStatus(GameStatus status) {
m_status = status;
m_eventHub.signal(AS_StateChange);
}


Expand Down Expand Up @@ -85,42 +89,4 @@ bool Position::isDeltaApplicable(const gameNet::ServerDelta& delta) {
return true;
}

void Position::updatePosition(const gameNet::ServerDelta& delta) {
m_moveId = delta.turn;
m_status = delta.status == gameNet::GameStatus::Active ? GameStatus::Active : GameStatus::Done;
m_player = delta.next == gameNet::Seat::Black ? Player::Black : Player::White;

if (delta.action == gameNet::ServerAction::Place) {
if (delta.coord) {
m_board.place(Coord{delta.coord->x, delta.coord->y}, delta.seat == gameNet::Seat::Black ? Board::Stone::Black : Board::Stone::White);
for (const auto c: delta.captures) {
m_board.place({c.x, c.y}, Board::Stone::Empty);
}
} else {
Logger().Log(Logging::LogLevel::Warning, "Game delta missing place coordinate; skipping board update.");
}
}
}

void Position::signalOnAction(gameNet::ServerAction action) {
switch (action) {
case gameNet::ServerAction::Place:
m_eventHub.signal(AS_BoardChange);
m_eventHub.signal(AS_PlayerChange);
break;
case gameNet::ServerAction::Pass:
m_eventHub.signal(AS_PlayerChange);
if (m_status != GameStatus::Active) {
m_eventHub.signal(AS_StateChange);
}
break;
case gameNet::ServerAction::Resign:
m_eventHub.signal(AS_StateChange);
break;
case gameNet::ServerAction::Count:
assert(false); //!< This should already be prohibited by libGameNet.
break;
};
}

} // namespace go::app
} // namespace go::app
Loading