1#include "game_session.h"
3namespace cavoke::server::model {
4using namespace drogon::orm;
6game_session_error::game_session_error(std::string message)
7 : cavoke_base_exception(std::move(message),
17void GameSessionAccessObject::add_user(
const std::string &user_id,
18 std::optional<int> player_id) {
19 auto session_snapshot = get_snapshot();
20 if (get_actual_status().getValueOfStatus() != NOT_STARTED) {
24 if (0 != default_mp_players.count(
25 Criteria(drogon_model::cavoke_orm::Players::Cols::_session_id,
26 CompareOperator::EQ,
id) &&
27 Criteria(drogon_model::cavoke_orm::Players::Cols::_user_id,
28 CompareOperator::EQ, user_id))) {
33 if (player_id.has_value()) {
34 pos = player_id.value();
36 if (!(0 <= pos && pos < m_game_config.players_num)) {
42 std::set<int> possible_positions;
43 for (
int candidate_pos = 0; candidate_pos < m_game_config.players_num;
45 possible_positions.insert(candidate_pos);
47 for (
int occupied_pos : get_occupied_positions()) {
48 possible_positions.erase(occupied_pos);
50 if (possible_positions.empty()) {
53 pos = *possible_positions.begin();
56 drogon_model::cavoke_orm::Players new_player;
57 new_player.setUserId(user_id);
58 new_player.setSessionId(
id);
59 new_player.setScoreToNull();
60 new_player.setPlayerId(pos);
61 new_player.setPlayerstate(
"");
62 default_mp_players.insert(new_player);
63 LOG_DEBUG <<
"Added: " << user_id <<
" with player_id=" << pos <<
" to "
65 }
catch (
const DrogonDbException &) {
74int GameSessionAccessObject::get_player_id(
const std::string &user_id)
const {
76 return default_mp_players
78 Criteria(drogon_model::cavoke_orm::Players::Cols::_session_id,
79 CompareOperator::EQ,
id) &&
80 Criteria(drogon_model::cavoke_orm::Players::Cols::_user_id,
81 CompareOperator::EQ, user_id))
82 .getValueOfPlayerId();
83 }
catch (
const UnexpectedRows &) {
92std::string GameSessionAccessObject::get_user_id(
int player_id)
const {
94 return default_mp_players
96 Criteria(drogon_model::cavoke_orm::Players::Cols::_session_id,
97 CompareOperator::EQ,
id) &&
98 Criteria(drogon_model::cavoke_orm::Players::Cols::_player_id,
99 CompareOperator::EQ, player_id))
101 }
catch (
const UnexpectedRows &) {
108GameSessionAccessObject::get_session_info()
const {
109 auto session_snapshot = get_snapshot();
110 return make_session_info(session_snapshot, get_actual_status(),
114std::vector<int> GameSessionAccessObject::get_occupied_positions()
const {
115 std::vector<int> result;
116 for (
const auto &player : default_mp_players.findBy(
117 Criteria(drogon_model::cavoke_orm::Players::Cols::_session_id,
118 CompareOperator::EQ,
id))) {
120 result.push_back(player.getValueOfPlayerId());
131std::vector<GameSessionAccessObject::PlayerInfo>
132GameSessionAccessObject::get_players()
const {
133 auto players = default_mp_players.findBy(
134 Criteria(drogon_model::cavoke_orm::Players::Cols::_session_id,
135 CompareOperator::EQ,
id));
136 auto users_in_session_result = drogon::app().getDbClient()->execSqlSync(
137 "select u.*, player_id from players join users u on players.user_id = "
138 "u.id and players.session_id = $1",
140 std::map<int, drogon_model::cavoke_orm::Users> users;
141 for (
auto &r : users_in_session_result) {
142 int player_id = r[
"player_id"].as<
int>();
143 users[player_id] = drogon_model::cavoke_orm::Users(r);
145 std::vector<PlayerInfo> result;
147 players.begin(), players.end(), std::back_inserter(result),
148 [&users](
const drogon_model::cavoke_orm::Players &player) {
149 int player_id = player.getValueOfPlayerId();
150 return PlayerInfo{UserInfo::from_user(users[player_id]), player_id};
155void GameSessionAccessObject::start(
const json &game_settings) {
156 auto session = default_mp_sessions.findOne(
157 Criteria(drogon_model::cavoke_orm::Sessions::Cols::_id,
158 CompareOperator::EQ,
id));
161 if (get_actual_status().getValueOfStatus() != NOT_STARTED) {
164 session.setGameSettings(game_settings.dump());
166 default_mp_sessions.update(session);
169bool GameSessionAccessObject::is_player(
const std::string &user_id)
const {
171 [[maybe_unused]]
int tmp = get_player_id(user_id);
173 }
catch (
const game_session_error &) {
178std::string GameSessionAccessObject::get_host()
const {
179 return get_snapshot().getValueOfHostId();
182bool GameSessionAccessObject::is_host(
const std::string &user_id)
const {
183 return get_host() == user_id;
186void GameSessionAccessObject::update_status(
bool is_terminal) {
187 set_status(is_terminal ? FINISHED : RUNNING);
190drogon_model::cavoke_orm::Sessions GameSessionAccessObject::get_snapshot()
192 return default_mp_sessions.findOne(
193 Criteria(drogon_model::cavoke_orm::Sessions::Cols::_id,
194 CompareOperator::EQ,
id));
196drogon_model::cavoke_orm::Sessions GameSessionAccessObject::get_snapshot(
197 const std::string &session_id) {
198 auto mp_sessions = MAPPER_FOR(drogon_model::cavoke_orm::Sessions);
199 return mp_sessions.findOne(
200 Criteria(drogon_model::cavoke_orm::Sessions::Cols::_id,
201 drogon::orm::CompareOperator::EQ, session_id));
205GameSessionAccessObject::make_session_info(
206 const drogon_model::cavoke_orm::Sessions &session,
207 const drogon_model::cavoke_orm::Statuses &status,
208 std::vector<PlayerInfo> players) {
209 return {session.getValueOfId(), session.getValueOfGameId(),
210 session.getValueOfHostId(),
211 static_cast<SessionStatus
>(status.getValueOfStatus()),
215void GameSessionAccessObject::remove_user(
const std::string &user_id) {
216 if (get_actual_status().getValueOfStatus() != NOT_STARTED) {
220 default_mp_players.deleteBy(
221 Criteria(drogon_model::cavoke_orm::Players::Cols::_user_id,
222 CompareOperator::EQ, user_id));
225void GameSessionAccessObject::set_role(
const std::string &user_id,
228 if (!(0 <= new_role && new_role < m_game_config.players_num)) {
234 default_mp_players.updateBy(
235 {drogon_model::cavoke_orm::Players::Cols::_player_id},
236 Criteria(drogon_model::cavoke_orm::Players::Cols::_user_id,
237 CompareOperator::EQ, user_id),
239 }
catch (
const std::exception &err) {
244void GameSessionAccessObject::delete_session() {
245 default_mp_sessions.deleteBy(
246 Criteria(drogon_model::cavoke_orm::Sessions::Cols::_id,
247 CompareOperator::EQ,
id));
250void GameSessionAccessObject::leave_session(
const std::string &user_id) {
251 drogon::app().getDbClient()->execSqlSync(
252 "select leave_session($1::uuid, $2::varchar);",
id, user_id);
255drogon_model::cavoke_orm::Statuses GameSessionAccessObject::get_actual_status()
257 return default_mp_statuses
258 .orderBy(drogon_model::cavoke::Statuses::Cols::_saved_on,
260 .findBy(Criteria(drogon_model::cavoke_orm::Statuses::Cols::_session_id,
261 CompareOperator::EQ,
id))[0];
264void GameSessionAccessObject::set_status(SessionStatus status) {
265 drogon_model::cavoke::Statuses status_record;
266 status_record.setSessionId(
id);
267 status_record.setStatus(status);
268 default_mp_statuses.insert(status_record);
Serializable representation of session for client.
exception for errors thrown during actions with sessions