1#include "state_controller.h"
4namespace cavoke::server::controllers {
6using json = nlohmann::json;
8void StateController::send_move(
9 const drogon::HttpRequestPtr &req,
10 std::function<
void(
const drogon::HttpResponsePtr &)> &&callback,
11 const std::string &session_id) {
16 auto transaction = drogon::app().getDbClient()->newTransaction();
17 model::GameSessionAccessObject session_with_transaction;
19 session_with_transaction =
20 m_participation_storage->get_sessionAO(session_id, transaction);
21 }
catch (
const model::game_session_error &) {
22 transaction->rollback();
23 return CALLBACK_STATUS_CODE(k400BadRequest);
28 player_id = session_with_transaction.get_player_id(user_id);
29 }
catch (
const model::game_session_error &) {
30 transaction->rollback();
31 return CALLBACK_STATUS_CODE(k403Forbidden);
34 auto session_info = session_with_transaction.get_session_info();
36 if (session_info.status == model::GameSessionAccessObject::FINISHED) {
37 transaction->rollback();
38 return CALLBACK_STATUS_CODE(k403Forbidden);
40 if (session_info.status ==
41 model::GameSessionAccessObject::NOT_STARTED) {
42 transaction->rollback();
43 return CALLBACK_STATUS_CODE(k404NotFound);
48 json_body = json::parse(req->getBody());
49 }
catch (
const json::parse_error &) {
50 transaction->rollback();
51 return CALLBACK_STATUS_CODE(k400BadRequest);
53 if (!json_body.contains(
"move") || !json_body[
"move"].is_string()) {
54 transaction->rollback();
55 return CALLBACK_STATUS_CODE(k400BadRequest);
58 std::string move = json_body[
"move"];
60 model::GameStateStorage::GameState current_state;
63 m_game_state_storage->get_state(session_id, transaction);
64 }
catch (
const model::game_state_error &) {
65 transaction->rollback();
66 return CALLBACK_STATUS_CODE(k404NotFound);
69 auto next_state = m_game_logic_manager->send_move(
71 {player_id, move, current_state.global_state});
73 m_game_state_storage->save_state(session_id, next_state, transaction);
75 session_with_transaction.update_status(next_state.is_terminal);
76 if (next_state.is_terminal) {
77 LOG_INFO <<
"Session " << session_id
78 <<
" is being declared finished!";
81 transaction->setCommitCallback([next_state, player_id](
bool committed) {
82 LOG_TRACE <<
"State set (" << committed <<
") state: '"
83 << next_state.global_state <<
"' player_id=" << player_id;
87 auto resp = drogon::HttpResponse::newHttpResponse();
88 resp->setStatusCode(drogon::HttpStatusCode::k200OK);
92void StateController::get_state(
93 const drogon::HttpRequestPtr &req,
94 std::function<
void(
const drogon::HttpResponsePtr &)> &&callback,
95 const std::string &session_id) {
99 auto transaction = drogon::app().getDbClient()->newTransaction();
100 model::GameSessionAccessObject session_with_transaction;
102 session_with_transaction =
103 m_participation_storage->get_sessionAO(session_id, transaction);
104 }
catch (
const model::game_session_error &) {
105 transaction->rollback();
106 return CALLBACK_STATUS_CODE(k404NotFound);
111 player_id = session_with_transaction.get_player_id(user_id);
112 }
catch (
const model::game_session_error &) {
113 transaction->rollback();
114 return CALLBACK_STATUS_CODE(k403Forbidden);
117 auto session_info = session_with_transaction.get_session_info();
119 if (session_info.status == model::GameSessionAccessObject::NOT_STARTED) {
120 transaction->rollback();
121 return CALLBACK_STATUS_CODE(k404NotFound);
124 std::string player_state;
126 player_state = m_game_state_storage->get_player_state(
127 session_id, player_id, transaction);
128 }
catch (
const model::game_state_error &) {
132 resp_json[
"state"] = std::move(player_state);
133 auto game_state = m_game_state_storage->get_state(session_id, transaction);
134 resp_json[
"is_terminal"] = game_state.is_terminal;
135 if (game_state.is_terminal) {
136 std::vector<std::string> winners;
137 for (
const auto &e : game_state.winners) {
139 winners.push_back(session_with_transaction.get_user_id(e));
141 resp_json[
"winners"] = winners;
144 transaction->setCommitCallback(
145 [player_state = resp_json[
"state"].get<std::string>(),
146 player_id](
bool committed) {
147 LOG_TRACE <<
"Got state (" << committed <<
") state: '"
148 << player_state <<
"' player_id=" << player_id;
151 auto resp = newNlohmannJsonResponse(resp_json);
155StateController::StateController(
156 std::shared_ptr<model::GamesStorage> mGamesStorage,
157 std::shared_ptr<model::GameLogicManager> mGameLogicManager,
158 std::shared_ptr<model::GameStateStorage> mGameStateStorage,
159 std::shared_ptr<model::SessionsStorage> mParticipationStorage)
160 : m_games_storage(std::move(mGamesStorage)),
161 m_game_logic_manager(std::move(mGameLogicManager)),
162 m_game_state_storage(std::move(mGameStateStorage)),
163 m_participation_storage(std::move(mParticipationStorage)) {
static std::string get_user_id(const HttpRequestPtr &)
Acquires user_id parsed during AuthFilter's execution.