1#include "sessions_storage.h"
2#include <boost/uuid/uuid_generators.hpp>
3#include <boost/uuid/uuid_io.hpp>
5#include "sql-models/Globalstates.h"
6#include "sql-models/Rooms.h"
7#include "sql-models/Sessions.h"
8#include "sql-models/Statuses.h"
10namespace cavoke::server::model {
12using namespace drogon::orm;
23 const std::string &host_user_id,
24 const std::string &room_id) {
25 drogon_model::cavoke_orm::Users user =
26 MAPPER_FOR(drogon_model::cavoke_orm::Users)
27 .findByPrimaryKey(host_user_id);
29 auto session = drogon_model::cavoke_orm::Sessions();
31 session.setId(to_string(boost::uuids::random_generator()()));
32 session.setGameSettingsToNull();
33 session.setGameId(game_config.id);
35 auto session_status = drogon_model::cavoke_orm::Statuses();
37 session_status.setStatus(
38 GameSessionAccessObject::SessionStatus::NOT_STARTED);
39 session_status.setSessionId(session.getValueOfId());
41 auto host_player = drogon_model::cavoke_orm::Players();
44 host_player.setPlayerId(0);
45 host_player.setPlayerstate(
"");
46 host_player.setScoreToNull();
47 host_player.setSessionId(session.getValueOfId());
48 host_player.setUserId(host_user_id);
50 auto global_state = drogon_model::cavoke_orm::Globalstates();
52 global_state.setSessionId(session.getValueOfId());
53 global_state.setIsTerminal(
false);
54 global_state.setGlobalstateToNull();
58 auto transaction = drogon::app().getDbClient()->newTransaction();
59 auto mp_sessions = MAPPER_WITH_CLIENT_FOR(
60 drogon_model::cavoke_orm::Sessions, transaction);
61 mp_sessions.insert(session);
62 auto mp_statuses = MAPPER_WITH_CLIENT_FOR(
63 drogon_model::cavoke_orm::Statuses, transaction);
64 mp_statuses.insert(session_status);
65 auto mp_players = MAPPER_WITH_CLIENT_FOR(
66 drogon_model::cavoke_orm::Players, transaction);
67 mp_players.insert(host_player);
68 auto mp_globalstates = MAPPER_WITH_CLIENT_FOR(
69 drogon_model::cavoke_orm::Globalstates, transaction);
70 mp_globalstates.insert(global_state);
72 session.setHostId(host_user_id);
73 mp_sessions.update(session);
75 if (!room_id.empty()) {
76 auto mp_rooms = MAPPER_WITH_CLIENT_FOR(
77 drogon_model::cavoke_orm::Rooms, transaction);
80 {drogon_model::cavoke_orm::Rooms::Cols::_session_id},
81 Criteria(drogon_model::cavoke_orm::Rooms::Cols::_id,
82 CompareOperator::EQ, room_id),
83 session.getValueOfId());
84 }
catch (
const UnexpectedRows &) {
88 LOG_DEBUG <<
"Session created: " << session.getValueOfId();
91 session, session_status,
92 {{GameSessionAccessObject::UserInfo::from_user(user), 0}});
96 std::optional<json> game_settings) {
100 if (!validation_result.success) {
103 std::string game_id = session.get_session_info().game_id;
104 if (!game_settings.has_value()) {
105 game_settings = m_games_storage->get_game_by_id(game_id)
107 .config.default_settings;
110 session.start(game_settings.value());
111 LOG_DEBUG <<
"Session started: " << session_id;
113 m_game_state_storage->save_state(
115 m_game_logic_manager->init_state(game_id, game_settings.value(),
116 session.get_occupied_positions()),
117 drogon::app().getDbClient());
128 const std::string &session_id,
129 const std::string &user_id,
130 std::optional<int> player_id) {
133 sessionAO.add_user(user_id, player_id);
135 return sessionAO.get_session_info();
138SessionsStorage::SessionsStorage(
139 std::shared_ptr<GameLogicManager> mGameLogicManager,
140 std::shared_ptr<GamesStorage> mGamesStorage,
141 std::shared_ptr<GameStateStorage> mGameStateStorage)
142 : m_game_logic_manager(std::move(mGameLogicManager)),
143 m_games_storage(std::move(mGamesStorage)),
144 m_game_state_storage(std::move(mGameStateStorage)) {
147 const std::string &session_id,
148 std::optional<json> game_settings) {
151 std::string game_id = session.get_session_info().game_id;
152 if (!game_settings.has_value()) {
153 game_settings = m_games_storage->get_game_by_id(game_id)
155 .config.default_settings;
158 return m_game_logic_manager->validate_settings(
159 game_id, game_settings.value(),
160 session.get_occupied_positions());
170 const std::string &session_id,
171 drogon::orm::DbClientPtr dbClient) {
175 MAPPER_WITH_CLIENT_FOR(drogon_model::cavoke_orm::Sessions,
178 auto session = mp_sessions.findOne(
179 Criteria(drogon_model::cavoke_orm::Sessions::Cols::_id,
180 CompareOperator::EQ, session_id));
182 session.getValueOfId(),
183 m_games_storage->get_game_by_id(session.getValueOfGameId())->config,
185 }
catch (
const std::out_of_range &) {
cavoke::ValidationResult validate_session(const std::string &session_id, std::optional< json > game_settings)
Validates the settings for given session.
void start_session(const std::string &session_id, std::optional< json > game_settings)
Starts session with given settings.
GameSessionAccessObject::GameSessionInfo join_session(const std::string &invite_code, const std::string &user_id, std::optional< int > player_id={})
Tries to connect given user into a session.
GameSessionAccessObject::GameSessionInfo create_session(const GameConfig &game_config, const std::string &host_user_id, const std::string &room_id="")
Creates session for given user with given game_config.
GameSessionAccessObject get_sessionAO(const std::string &session_id, drogon::orm::DbClientPtr dbClient=drogon::app().getDbClient())
Gets an access object for given session.
Serializable representation of session for client.
static GameSessionInfo make_session_info(const drogon_model::cavoke_orm::Sessions &session, const drogon_model::cavoke_orm::Statuses &status, std::vector< PlayerInfo > players)
Builds a session info from a session.
exception for errors thrown during actions with sessions
is thrown when trying to start a new session with invalid config