diff --git a/common/rng_sfmt.cpp b/common/rng_sfmt.cpp index 48a2a5e6..9dff7448 100644 --- a/common/rng_sfmt.cpp +++ b/common/rng_sfmt.cpp @@ -17,6 +17,9 @@ RNG_SFMT::RNG_SFMT(QObject *parent) unsigned int RNG_SFMT::getNumber(unsigned int min, unsigned int max) { + mutex.lock(); uint64_t r = gen_rand64(); + mutex.unlock(); + return min + (unsigned int) (((double) (max + 1 - min)) * r / (18446744073709551616.0 + 1.0)); } diff --git a/common/rng_sfmt.h b/common/rng_sfmt.h index 964eaa59..4d131b38 100644 --- a/common/rng_sfmt.h +++ b/common/rng_sfmt.h @@ -2,9 +2,12 @@ #define RNG_SFMT_H #include "rng_abstract.h" +#include class RNG_SFMT : public RNG_Abstract { Q_OBJECT +private: + QMutex mutex; public: RNG_SFMT(QObject *parent = 0); unsigned int getNumber(unsigned int min, unsigned int max); diff --git a/common/server.h b/common/server.h index 41467625..aec64aee 100644 --- a/common/server.h +++ b/common/server.h @@ -21,6 +21,7 @@ class Response; class SessionEvent; class GameEventContainer; class RoomEvent; +class DeckList; enum AuthenticationResult { NotLoggedIn = 0, PasswordRight = 1, UnknownUser = 2, WouldOverwriteOldSession = 3, UserIsBanned = 4 }; @@ -60,7 +61,8 @@ public: virtual bool isInIgnoreList(const QString &whoseList, const QString &who) { return false; } virtual void storeGameInformation(int secondsElapsed, const QSet &allPlayersEver, const QSet &allSpectatorsEver, const QList &replays) { } - + virtual DeckList *getDeckFromDatabase(int deckId, const QString &userName) = 0; + void sendIslMessage(const Response &item, int serverId = -1); void sendIslMessage(const SessionEvent &item, int serverId = -1); void sendIslMessage(const GameEventContainer &item, int serverId = -1); diff --git a/common/server_game.h b/common/server_game.h index 166e1b9b..be3c1c6e 100644 --- a/common/server_game.h +++ b/common/server_game.h @@ -75,6 +75,7 @@ public: mutable QMutex gameMutex; Server_Game(Server_ProtocolHandler *_creator, int _gameId, const QString &_description, const QString &_password, int _maxPlayers, const QList &_gameTypes, bool _onlyBuddies, bool _onlyRegistered, bool _spectatorsAllowed, bool _spectatorsNeedPassword, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, Server_Room *parent); ~Server_Game(); + Server_Room *getRoom() const { return room; } ServerInfo_Game getInfo() const; int getHostId() const { return hostId; } ServerInfo_User *getCreatorInfo() const { return creatorInfo; } diff --git a/common/server_player.cpp b/common/server_player.cpp index 6cbeb896..7d341227 100644 --- a/common/server_player.cpp +++ b/common/server_player.cpp @@ -4,21 +4,76 @@ #include "server_arrow.h" #include "server_cardzone.h" #include "server_game.h" +#include "server_room.h" #include "server_protocolhandler.h" #include "decklist.h" #include "color.h" +#include "rng_abstract.h" +#include "get_pb_extension.h" + #include "pb/response.pb.h" +#include "pb/response_deck_download.pb.h" +#include "pb/response_dump_zone.pb.h" +#include "pb/command_attach_card.pb.h" +#include "pb/command_concede.pb.h" +#include "pb/command_create_arrow.pb.h" +#include "pb/command_create_counter.pb.h" +#include "pb/command_create_token.pb.h" +#include "pb/command_deck_select.pb.h" +#include "pb/command_del_counter.pb.h" +#include "pb/command_delete_arrow.pb.h" +#include "pb/command_draw_cards.pb.h" +#include "pb/command_dump_zone.pb.h" +#include "pb/command_flip_card.pb.h" +#include "pb/command_game_say.pb.h" +#include "pb/command_inc_card_counter.pb.h" +#include "pb/command_inc_counter.pb.h" +#include "pb/command_kick_from_game.pb.h" +#include "pb/command_leave_game.pb.h" #include "pb/command_move_card.pb.h" +#include "pb/command_mulligan.pb.h" +#include "pb/command_next_turn.pb.h" +#include "pb/command_ready_start.pb.h" +#include "pb/command_reveal_cards.pb.h" +#include "pb/command_roll_die.pb.h" +#include "pb/command_set_active_phase.pb.h" +#include "pb/command_set_card_attr.pb.h" +#include "pb/command_set_card_counter.pb.h" +#include "pb/command_set_counter.pb.h" +#include "pb/command_set_sideboard_plan.pb.h" +#include "pb/command_shuffle.pb.h" +#include "pb/command_stop_dump_zone.pb.h" +#include "pb/command_undo_draw.pb.h" #include "pb/serverinfo_user.pb.h" #include "pb/event_attach_card.pb.h" +#include "pb/event_create_arrow.pb.h" +#include "pb/event_create_counter.pb.h" +#include "pb/event_create_token.pb.h" +#include "pb/event_delete_arrow.pb.h" +#include "pb/event_del_counter.pb.h" #include "pb/event_draw_cards.pb.h" #include "pb/event_destroy_card.pb.h" +#include "pb/event_dump_zone.pb.h" +#include "pb/event_flip_card.pb.h" +#include "pb/event_game_say.pb.h" #include "pb/event_move_card.pb.h" #include "pb/event_player_properties_changed.pb.h" #include "pb/event_set_card_attr.pb.h" +#include "pb/event_shuffle.pb.h" +#include "pb/event_roll_die.pb.h" +#include "pb/event_set_card_counter.pb.h" +#include "pb/event_set_counter.pb.h" +#include "pb/event_stop_dump_zone.pb.h" +#include "pb/event_reveal_cards.pb.h" + #include "pb/context_connection_state_changed.pb.h" +#include "pb/context_concede.pb.h" +#include "pb/context_deck_select.pb.h" #include "pb/context_move_card.pb.h" +#include "pb/context_mulligan.pb.h" #include "pb/context_undo_draw.pb.h" +#include "pb/context_ready_start.pb.h" + #include Server_Player::Server_Player(Server_Game *_game, int _playerId, const ServerInfo_User &_userInfo, bool _spectator, Server_ProtocolHandler *_handler) @@ -209,14 +264,6 @@ ServerInfo_PlayerProperties Server_Player::getProperties(bool withUserInfo) return result; } -void Server_Player::setDeck(DeckList *_deck) -{ - QMutexLocker locker(&game->gameMutex); - - delete deck; - deck = _deck; -} - void Server_Player::addZone(Server_CardZone *zone) { QMutexLocker locker(&game->gameMutex); @@ -250,18 +297,6 @@ void Server_Player::addCounter(Server_Counter *counter) counters.insert(counter->getId(), counter); } -bool Server_Player::deleteCounter(int counterId) -{ - QMutexLocker locker(&game->gameMutex); - - Server_Counter *counter = counters.value(counterId, 0); - if (!counter) - return false; - counters.remove(counterId); - delete counter; - return true; -} - Response::ResponseCode Server_Player::drawCards(GameEventStorage &ges, int number) { QMutexLocker locker(&game->gameMutex); @@ -582,6 +617,939 @@ Response::ResponseCode Server_Player::setCardAttrHelper(GameEventStorage &ges, c return Response::RespOk; } +Response::ResponseCode Server_Player::cmdLeaveGame(const Command_LeaveGame & /*cmd*/, ResponseContainer & /*rc*/, GameEventStorage & /*ges*/) +{ + game->removePlayer(this); + return Response::RespOk; +} + +Response::ResponseCode Server_Player::cmdKickFromGame(const Command_KickFromGame &cmd, ResponseContainer & /*rc*/, GameEventStorage & /*ges*/) +{ + if ((game->getHostId() != playerId) && !(userInfo->user_level() & ServerInfo_User::IsModerator)) + return Response::RespFunctionNotAllowed; + + if (!game->kickPlayer(cmd.player_id())) + return Response::RespNameNotFound; + + return Response::RespOk; +} + +Response::ResponseCode Server_Player::cmdDeckSelect(const Command_DeckSelect &cmd, ResponseContainer &rc, GameEventStorage &ges) +{ + if (spectator) + return Response::RespFunctionNotAllowed; + + DeckList *newDeck; + if (cmd.has_deck_id()) { + try { + newDeck = game->getRoom()->getServer()->getDeckFromDatabase(cmd.deck_id(), QString::fromStdString(userInfo->name())); + } catch(Response::ResponseCode r) { + return r; + } + } else + newDeck = new DeckList(QString::fromStdString(cmd.deck())); + + delete deck; + deck = newDeck; + + Event_PlayerPropertiesChanged event; + event.mutable_player_properties()->set_deck_hash(deck->getDeckHash().toStdString()); + ges.enqueueGameEvent(event, playerId); + + Context_DeckSelect context; + context.set_deck_hash(deck->getDeckHash().toStdString()); + ges.setGameEventContext(context); + + Response_DeckDownload *re = new Response_DeckDownload; + re->set_deck(deck->writeToString_Native().toStdString()); + + rc.setResponseExtension(re); + return Response::RespOk; +} + +Response::ResponseCode Server_Player::cmdSetSideboardPlan(const Command_SetSideboardPlan &cmd, ResponseContainer & /*rc*/, GameEventStorage & /*ges*/) +{ + if (spectator) + return Response::RespFunctionNotAllowed; + if (readyStart) + return Response::RespContextError; + if (!deck) + return Response::RespContextError; + + QList sideboardPlan; + for (int i = 0; i < cmd.move_list_size(); ++i) + sideboardPlan.append(cmd.move_list(i)); + deck->setCurrentSideboardPlan(sideboardPlan); + + return Response::RespOk; +} + +Response::ResponseCode Server_Player::cmdConcede(const Command_Concede & /*cmd*/, ResponseContainer & /*rc*/, GameEventStorage &ges) +{ + if (spectator) + return Response::RespFunctionNotAllowed; + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + setConceded(true); + game->removeArrowsToPlayer(ges, this); + game->unattachCards(ges, this); + clearZones(); + + Event_PlayerPropertiesChanged event; + event.mutable_player_properties()->set_conceded(true); + ges.enqueueGameEvent(event, playerId); + ges.setGameEventContext(Context_Concede()); + + game->stopGameIfFinished(); + if (game->getGameStarted() && (game->getActivePlayer() == playerId)) + game->nextTurn(); + + return Response::RespOk; +} + +Response::ResponseCode Server_Player::cmdReadyStart(const Command_ReadyStart &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) +{ + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!deck || game->getGameStarted()) + return Response::RespContextError; + + if (readyStart == cmd.ready()) + return Response::RespContextError; + + setReadyStart(cmd.ready()); + + Event_PlayerPropertiesChanged event; + event.mutable_player_properties()->set_ready_start(cmd.ready()); + ges.enqueueGameEvent(event, playerId); + ges.setGameEventContext(Context_ReadyStart()); + + if (cmd.ready()) + game->startGameIfReady(); + + return Response::RespOk; +} + +Response::ResponseCode Server_Player::cmdGameSay(const Command_GameSay &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) +{ + if (spectator && !game->getSpectatorsCanTalk() && !(userInfo->user_level() & ServerInfo_User::IsModerator)) + return Response::RespFunctionNotAllowed; + + Event_GameSay event; + event.set_message(cmd.message()); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; +} + +Response::ResponseCode Server_Player::cmdShuffle(const Command_Shuffle & /*cmd*/, ResponseContainer & /*rc*/, GameEventStorage &ges) +{ + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + zones.value("deck")->shuffle(); + + Event_Shuffle event; + event.set_zone_name("deck"); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; +} + +Response::ResponseCode Server_Player::cmdMulligan(const Command_Mulligan & /*cmd*/, ResponseContainer & /*rc*/, GameEventStorage &ges) +{ + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_CardZone *hand = zones.value("hand"); + int number = (hand->cards.size() <= 1) ? initialCards : hand->cards.size() - 1; + + Server_CardZone *deck = zones.value("deck"); + while (!hand->cards.isEmpty()) { + CardToMove *cardToMove = new CardToMove; + cardToMove->set_card_id(hand->cards.first()->getId()); + moveCard(ges, hand, QList() << cardToMove, deck, 0, 0, false); + delete cardToMove; + } + + deck->shuffle(); + ges.enqueueGameEvent(Event_Shuffle(), playerId); + + drawCards(ges, number); + + if (number == initialCards) + number = -1; + + Context_Mulligan context; + context.set_number(number); + ges.setGameEventContext(context); + + return Response::RespOk; +} + +Response::ResponseCode Server_Player::cmdRollDie(const Command_RollDie &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) +{ + if (spectator) + return Response::RespFunctionNotAllowed; + if (conceded) + return Response::RespContextError; + + Event_RollDie event; + event.set_sides(cmd.sides()); + event.set_value(rng->getNumber(1, cmd.sides())); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; +} + +Response::ResponseCode Server_Player::cmdDrawCards(const Command_DrawCards &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) +{ + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + return drawCards(ges, cmd.number()); +} + +Response::ResponseCode Server_Player::cmdUndoDraw(const Command_UndoDraw & /*cmd*/, ResponseContainer & /*rc*/, GameEventStorage &ges) +{ + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + return undoDraw(ges); +} + +Response::ResponseCode Server_Player::cmdMoveCard(const Command_MoveCard &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) +{ + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + QList cardsToMove; + for (int i = 0; i < cmd.cards_to_move().card_size(); ++i) + cardsToMove.append(&cmd.cards_to_move().card(i)); + + return moveCard(ges, QString::fromStdString(cmd.start_zone()), cardsToMove, cmd.target_player_id(), QString::fromStdString(cmd.target_zone()), cmd.x(), cmd.y()); +} + +Response::ResponseCode Server_Player::cmdFlipCard(const Command_FlipCard &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) +{ + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_CardZone *zone = zones.value(QString::fromStdString(cmd.zone())); + if (!zone) + return Response::RespNameNotFound; + if (!zone->hasCoords()) + return Response::RespContextError; + + Server_Card *card = zone->getCard(cmd.card_id()); + if (!card) + return Response::RespNameNotFound; + + const bool faceDown = cmd.face_down(); + if (faceDown == card->getFaceDown()) + return Response::RespContextError; + + card->setFaceDown(faceDown); + + Event_FlipCard event; + event.set_zone_name(zone->getName().toStdString()); + event.set_card_id(card->getId()); + event.set_card_name(card->getName().toStdString()); + event.set_face_down(faceDown); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; +} + +Response::ResponseCode Server_Player::cmdAttachCard(const Command_AttachCard &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) +{ + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_CardZone *startzone = zones.value(QString::fromStdString(cmd.start_zone())); + if (!startzone) + return Response::RespNameNotFound; + + Server_Card *card = startzone->getCard(cmd.card_id()); + if (!card) + return Response::RespNameNotFound; + + Server_Player *targetPlayer = 0; + Server_CardZone *targetzone = 0; + Server_Card *targetCard = 0; + + if (cmd.has_target_player_id()) { + targetPlayer = game->getPlayer(cmd.target_player_id()); + if (!targetPlayer) + return Response::RespNameNotFound; + } else if (!card->getParentCard()) + return Response::RespContextError; + if (targetPlayer) + targetzone = targetPlayer->getZones().value(QString::fromStdString(cmd.target_zone())); + if (targetzone) { + // This is currently enough to make sure cards don't get attached to a card that is not on the table. + // Possibly a flag will have to be introduced for this sometime. + if (!targetzone->hasCoords()) + return Response::RespContextError; + if (cmd.has_target_card_id()) + targetCard = targetzone->getCard(cmd.target_card_id()); + if (targetCard) + if (targetCard->getParentCard()) + return Response::RespContextError; + } + if (!startzone->hasCoords()) + return Response::RespContextError; + + // Get all arrows pointing to or originating from the card being attached and delete them. + QMapIterator playerIterator(game->getPlayers()); + while (playerIterator.hasNext()) { + Server_Player *p = playerIterator.next().value(); + QList arrows = p->getArrows().values(); + QList toDelete; + for (int i = 0; i < arrows.size(); ++i) { + Server_Arrow *a = arrows[i]; + Server_Card *tCard = qobject_cast(a->getTargetItem()); + if ((tCard == card) || (a->getStartCard() == card)) + toDelete.append(a); + } + for (int i = 0; i < toDelete.size(); ++i) { + Event_DeleteArrow event; + event.set_arrow_id(toDelete[i]->getId()); + ges.enqueueGameEvent(event, p->getPlayerId()); + p->deleteArrow(toDelete[i]->getId()); + } + } + + if (targetCard) { + // Unattach all cards attached to the card being attached. + // Make a copy of the list because its contents change during the loop otherwise. + QList attachedList = card->getAttachedCards(); + for (int i = 0; i < attachedList.size(); ++i) + attachedList[i]->getZone()->getPlayer()->unattachCard(ges, attachedList[i]); + + if (targetzone->isColumnStacked(targetCard->getX(), targetCard->getY())) { + CardToMove *cardToMove = new CardToMove; + cardToMove->set_card_id(targetCard->getId()); + targetPlayer->moveCard(ges, targetzone, QList() << cardToMove, targetzone, targetzone->getFreeGridColumn(-2, targetCard->getY(), targetCard->getName()), targetCard->getY(), targetCard->getFaceDown()); + delete cardToMove; + } + + card->setParentCard(targetCard); + card->setCoords(-1, card->getY()); + + Event_AttachCard event; + event.set_start_zone(startzone->getName().toStdString()); + event.set_card_id(card->getId()); + event.set_target_player_id(targetPlayer->getPlayerId()); + event.set_target_zone(targetzone->getName().toStdString()); + event.set_target_card_id(targetCard->getId()); + ges.enqueueGameEvent(event, playerId); + + startzone->fixFreeSpaces(ges); + } else + unattachCard(ges, card); + + return Response::RespOk; +} + +Response::ResponseCode Server_Player::cmdCreateToken(const Command_CreateToken &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) +{ + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_CardZone *zone = zones.value(QString::fromStdString(cmd.zone())); + if (!zone) + return Response::RespNameNotFound; + + QString cardName = QString::fromStdString(cmd.card_name()); + int x = cmd.x(); + int y = cmd.y(); + if (zone->hasCoords()) + x = zone->getFreeGridColumn(x, y, cardName); + if (x < 0) + x = 0; + if (y < 0) + y = 0; + + Server_Card *card = new Server_Card(cardName, newCardId(), x, y); + card->moveToThread(thread()); + card->setPT(QString::fromStdString(cmd.pt())); + card->setColor(QString::fromStdString(cmd.color())); + card->setAnnotation(QString::fromStdString(cmd.annotation())); + card->setDestroyOnZoneChange(cmd.destroy_on_zone_change()); + + zone->insertCard(card, x, y); + + Event_CreateToken event; + event.set_zone_name(zone->getName().toStdString()); + event.set_card_id(card->getId()); + event.set_card_name(card->getName().toStdString()); + event.set_color(card->getColor().toStdString()); + event.set_pt(card->getPT().toStdString()); + event.set_annotation(card->getAnnotation().toStdString()); + event.set_destroy_on_zone_change(card->getDestroyOnZoneChange()); + event.set_x(x); + event.set_y(y); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; +} + +Response::ResponseCode Server_Player::cmdCreateArrow(const Command_CreateArrow &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) +{ + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_Player *startPlayer = game->getPlayer(cmd.start_player_id()); + Server_Player *targetPlayer = game->getPlayer(cmd.target_player_id()); + if (!startPlayer || !targetPlayer) + return Response::RespNameNotFound; + QString startZoneName = QString::fromStdString(cmd.start_zone()); + Server_CardZone *startZone = startPlayer->getZones().value(startZoneName); + bool playerTarget = !cmd.has_target_zone(); + Server_CardZone *targetZone = 0; + if (!playerTarget) + targetZone = targetPlayer->getZones().value(QString::fromStdString(cmd.target_zone())); + if (!startZone || (!targetZone && !playerTarget)) + return Response::RespNameNotFound; + if (startZone->getType() != ServerInfo_Zone::PublicZone) + return Response::RespContextError; + Server_Card *startCard = startZone->getCard(cmd.start_card_id()); + if (!startCard) + return Response::RespNameNotFound; + Server_Card *targetCard = 0; + if (!playerTarget) { + if (targetZone->getType() != ServerInfo_Zone::PublicZone) + return Response::RespContextError; + targetCard = targetZone->getCard(cmd.target_card_id()); + } + + Server_ArrowTarget *targetItem; + if (playerTarget) + targetItem = targetPlayer; + else + targetItem = targetCard; + if (!targetItem) + return Response::RespNameNotFound; + + QMapIterator arrowIterator(arrows); + while (arrowIterator.hasNext()) { + Server_Arrow *temp = arrowIterator.next().value(); + if ((temp->getStartCard() == startCard) && (temp->getTargetItem() == targetItem)) + return Response::RespContextError; + } + + Server_Arrow *arrow = new Server_Arrow(newArrowId(), startCard, targetItem, cmd.arrow_color()); + addArrow(arrow); + + Event_CreateArrow event; + ServerInfo_Arrow *arrowInfo = event.mutable_arrow_info(); + arrowInfo->set_id(arrow->getId()); + arrowInfo->set_start_player_id(startPlayer->getPlayerId()); + arrowInfo->set_start_zone(startZoneName.toStdString()); + arrowInfo->set_start_card_id(startCard->getId()); + arrowInfo->set_target_player_id(targetPlayer->getPlayerId()); + if (!playerTarget) { + arrowInfo->set_target_zone(cmd.target_zone()); + arrowInfo->set_target_card_id(cmd.target_card_id()); + } + arrowInfo->mutable_arrow_color()->CopyFrom(cmd.arrow_color()); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; +} + +Response::ResponseCode Server_Player::cmdDeleteArrow(const Command_DeleteArrow &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) +{ + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + if (!deleteArrow(cmd.arrow_id())) + return Response::RespNameNotFound; + + Event_DeleteArrow event; + event.set_arrow_id(cmd.arrow_id()); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; +} + +Response::ResponseCode Server_Player::cmdSetCardAttr(const Command_SetCardAttr &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) +{ + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + return setCardAttrHelper(ges, QString::fromStdString(cmd.zone()), cmd.card_id(), cmd.attribute(), QString::fromStdString(cmd.attr_value())); +} + +Response::ResponseCode Server_Player::cmdSetCardCounter(const Command_SetCardCounter &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) +{ + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_CardZone *zone = zones.value(QString::fromStdString(cmd.zone())); + if (!zone) + return Response::RespNameNotFound; + if (!zone->hasCoords()) + return Response::RespContextError; + + Server_Card *card = zone->getCard(cmd.card_id()); + if (!card) + return Response::RespNameNotFound; + + card->setCounter(cmd.counter_id(), cmd.counter_value()); + + Event_SetCardCounter event; + event.set_zone_name(zone->getName().toStdString()); + event.set_card_id(card->getId()); + event.set_counter_id(cmd.counter_id()); + event.set_counter_value(cmd.counter_value()); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; +} + +Response::ResponseCode Server_Player::cmdIncCardCounter(const Command_IncCardCounter &cmd, ResponseContainer &/*rc*/, GameEventStorage &ges) +{ + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_CardZone *zone = zones.value(QString::fromStdString(cmd.zone())); + if (!zone) + return Response::RespNameNotFound; + if (!zone->hasCoords()) + return Response::RespContextError; + + Server_Card *card = zone->getCard(cmd.card_id()); + if (!card) + return Response::RespNameNotFound; + + int newValue = card->getCounter(cmd.counter_id()) + cmd.counter_delta(); + card->setCounter(cmd.counter_id(), newValue); + + Event_SetCardCounter event; + event.set_zone_name(zone->getName().toStdString()); + event.set_card_id(card->getId()); + event.set_counter_id(cmd.counter_id()); + event.set_counter_value(newValue); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; +} + +Response::ResponseCode Server_Player::cmdIncCounter(const Command_IncCounter &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) +{ + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_Counter *c = counters.value(cmd.counter_id(), 0); + if (!c) + return Response::RespNameNotFound; + + c->setCount(c->getCount() + cmd.delta()); + + Event_SetCounter event; + event.set_counter_id(c->getId()); + event.set_value(c->getCount()); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; +} + +Response::ResponseCode Server_Player::cmdCreateCounter(const Command_CreateCounter &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) +{ + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_Counter *c = new Server_Counter(newCounterId(), QString::fromStdString(cmd.counter_name()), cmd.counter_color(), cmd.radius(), cmd.value()); + addCounter(c); + + Event_CreateCounter event; + ServerInfo_Counter *counterInfo = event.mutable_counter_info(); + counterInfo->set_id(c->getId()); + counterInfo->set_name(c->getName().toStdString()); + counterInfo->mutable_counter_color()->CopyFrom(cmd.counter_color()); + counterInfo->set_radius(c->getRadius()); + counterInfo->set_count(c->getCount()); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; +} + +Response::ResponseCode Server_Player::cmdSetCounter(const Command_SetCounter &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) +{ + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_Counter *c = counters.value(cmd.counter_id(), 0);; + if (!c) + return Response::RespNameNotFound; + + c->setCount(cmd.value()); + + Event_SetCounter event; + event.set_counter_id(c->getId()); + event.set_value(c->getCount()); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; +} + +Response::ResponseCode Server_Player::cmdDelCounter(const Command_DelCounter &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) +{ + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_Counter *counter = counters.value(cmd.counter_id(), 0); + if (!counter) + return Response::RespNameNotFound; + counters.remove(cmd.counter_id()); + delete counter; + + Event_DelCounter event; + event.set_counter_id(cmd.counter_id()); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; +} + +Response::ResponseCode Server_Player::cmdNextTurn(const Command_NextTurn & /*cmd*/, ResponseContainer & /*rc*/, GameEventStorage & /*ges*/) +{ + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + game->nextTurn(); + return Response::RespOk; +} + +Response::ResponseCode Server_Player::cmdSetActivePhase(const Command_SetActivePhase &cmd, ResponseContainer & /*rc*/, GameEventStorage & /*ges*/) +{ + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + if (game->getActivePlayer() != playerId) + return Response::RespContextError; + game->setActivePhase(cmd.phase()); + + return Response::RespOk; +} + +Response::ResponseCode Server_Player::cmdDumpZone(const Command_DumpZone &cmd, ResponseContainer &rc, GameEventStorage &ges) +{ + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + + Server_Player *otherPlayer = game->getPlayer(cmd.player_id()); + if (!otherPlayer) + return Response::RespNameNotFound; + Server_CardZone *zone = otherPlayer->getZones().value(QString::fromStdString(cmd.zone_name())); + if (!zone) + return Response::RespNameNotFound; + if (!((zone->getType() == ServerInfo_Zone::PublicZone) || (this == otherPlayer))) + return Response::RespContextError; + + int numberCards = cmd.number_cards(); + + Response_DumpZone *re = new Response_DumpZone; + ServerInfo_Zone *zoneInfo = re->mutable_zone_info(); + zoneInfo->set_name(zone->getName().toStdString()); + zoneInfo->set_type(zone->getType()); + zoneInfo->set_with_coords(zone->hasCoords()); + zoneInfo->set_card_count(numberCards < zone->cards.size() ? zone->cards.size() : numberCards); + + for (int i = 0; (i < zone->cards.size()) && (i < numberCards || numberCards == -1); ++i) { + Server_Card *card = zone->cards[i]; + QString displayedName = card->getFaceDown() ? QString() : card->getName(); + ServerInfo_Card *cardInfo = zoneInfo->add_card_list(); + cardInfo->set_name(displayedName.toStdString()); + if (zone->getType() == ServerInfo_Zone::HiddenZone) + cardInfo->set_id(i); + else { + cardInfo->set_id(card->getId()); + cardInfo->set_x(card->getX()); + cardInfo->set_y(card->getY()); + cardInfo->set_face_down(card->getFaceDown()); + cardInfo->set_tapped(card->getTapped()); + cardInfo->set_attacking(card->getAttacking()); + cardInfo->set_color(card->getColor().toStdString()); + cardInfo->set_pt(card->getPT().toStdString()); + cardInfo->set_annotation(card->getAnnotation().toStdString()); + cardInfo->set_destroy_on_zone_change(card->getDestroyOnZoneChange()); + cardInfo->set_doesnt_untap(card->getDoesntUntap()); + + QMapIterator cardCounterIterator(card->getCounters()); + while (cardCounterIterator.hasNext()) { + cardCounterIterator.next(); + ServerInfo_CardCounter *counterInfo = cardInfo->add_counter_list(); + counterInfo->set_id(cardCounterIterator.key()); + counterInfo->set_value(cardCounterIterator.value()); + } + + if (card->getParentCard()) { + cardInfo->set_attach_player_id(card->getParentCard()->getZone()->getPlayer()->getPlayerId()); + cardInfo->set_attach_zone(card->getParentCard()->getZone()->getName().toStdString()); + cardInfo->set_attach_card_id(card->getParentCard()->getId()); + } + } + } + if (zone->getType() == ServerInfo_Zone::HiddenZone) { + zone->setCardsBeingLookedAt(numberCards); + + Event_DumpZone event; + event.set_zone_owner_id(otherPlayer->getPlayerId()); + event.set_zone_name(zone->getName().toStdString()); + event.set_number_cards(numberCards); + ges.enqueueGameEvent(event, playerId); + } + rc.setResponseExtension(re); + return Response::RespOk; +} + +Response::ResponseCode Server_Player::cmdStopDumpZone(const Command_StopDumpZone &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) +{ + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_Player *otherPlayer = game->getPlayer(cmd.player_id()); + if (!otherPlayer) + return Response::RespNameNotFound; + Server_CardZone *zone = otherPlayer->getZones().value(QString::fromStdString(cmd.zone_name())); + if (!zone) + return Response::RespNameNotFound; + + if (zone->getType() == ServerInfo_Zone::HiddenZone) { + zone->setCardsBeingLookedAt(0); + + Event_StopDumpZone event; + event.set_zone_owner_id(cmd.player_id()); + event.set_zone_name(zone->getName().toStdString()); + ges.enqueueGameEvent(event, playerId); + } + return Response::RespOk; +} + +Response::ResponseCode Server_Player::cmdRevealCards(const Command_RevealCards &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) +{ + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_Player *otherPlayer = 0; + if (cmd.has_player_id()) { + otherPlayer = game->getPlayer(cmd.player_id()); + if (!otherPlayer) + return Response::RespNameNotFound; + } + Server_CardZone *zone = zones.value(QString::fromStdString(cmd.zone_name())); + if (!zone) + return Response::RespNameNotFound; + + QList cardsToReveal; + if (!cmd.has_card_id()) + cardsToReveal = zone->cards; + else if (cmd.card_id() == -2) { + if (zone->cards.isEmpty()) + return Response::RespContextError; + cardsToReveal.append(zone->cards.at(rng->getNumber(0, zone->cards.size() - 1))); + } else { + Server_Card *card = zone->getCard(cmd.card_id()); + if (!card) + return Response::RespNameNotFound; + cardsToReveal.append(card); + } + + Event_RevealCards eventOthers; + eventOthers.set_zone_name(zone->getName().toStdString()); + if (cmd.has_card_id()) + eventOthers.set_card_id(cmd.card_id()); + if (cmd.has_player_id()) + eventOthers.set_other_player_id(cmd.player_id()); + + Event_RevealCards eventPrivate(eventOthers); + + for (int i = 0; i < cardsToReveal.size(); ++i) { + Server_Card *card = cardsToReveal[i]; + ServerInfo_Card *cardInfo = eventPrivate.add_cards(); + + cardInfo->set_id(card->getId()); + cardInfo->set_name(card->getName().toStdString()); + cardInfo->set_x(card->getX()); + cardInfo->set_y(card->getY()); + cardInfo->set_face_down(card->getFaceDown()); + cardInfo->set_tapped(card->getTapped()); + cardInfo->set_attacking(card->getAttacking()); + cardInfo->set_color(card->getColor().toStdString()); + cardInfo->set_pt(card->getPT().toStdString()); + cardInfo->set_annotation(card->getAnnotation().toStdString()); + cardInfo->set_destroy_on_zone_change(card->getDestroyOnZoneChange()); + cardInfo->set_doesnt_untap(card->getDoesntUntap()); + + QMapIterator cardCounterIterator(card->getCounters()); + while (cardCounterIterator.hasNext()) { + cardCounterIterator.next(); + ServerInfo_CardCounter *counterInfo = cardInfo->add_counter_list(); + counterInfo->set_id(cardCounterIterator.key()); + counterInfo->set_value(cardCounterIterator.value()); + } + + if (card->getParentCard()) { + cardInfo->set_attach_player_id(card->getParentCard()->getZone()->getPlayer()->getPlayerId()); + cardInfo->set_attach_zone(card->getParentCard()->getZone()->getName().toStdString()); + cardInfo->set_attach_card_id(card->getParentCard()->getId()); + } + } + + if (cmd.has_player_id()) { + ges.enqueueGameEvent(eventPrivate, playerId, GameEventStorageItem::SendToPrivate, cmd.player_id()); + ges.enqueueGameEvent(eventOthers, playerId, GameEventStorageItem::SendToOthers); + } else + ges.enqueueGameEvent(eventPrivate, playerId); + + return Response::RespOk; +} + +Response::ResponseCode Server_Player::processGameCommand(const GameCommand &command, ResponseContainer &rc, GameEventStorage &ges) +{ + switch ((GameCommand::GameCommandType) getPbExtension(command)) { + case GameCommand::KICK_FROM_GAME: return cmdKickFromGame(command.GetExtension(Command_KickFromGame::ext), rc, ges); break; + case GameCommand::LEAVE_GAME: return cmdLeaveGame(command.GetExtension(Command_LeaveGame::ext), rc, ges); break; + case GameCommand::GAME_SAY: return cmdGameSay(command.GetExtension(Command_GameSay::ext), rc, ges); break; + case GameCommand::SHUFFLE: return cmdShuffle(command.GetExtension(Command_Shuffle::ext), rc, ges); break; + case GameCommand::MULLIGAN: return cmdMulligan(command.GetExtension(Command_Mulligan::ext), rc, ges); break; + case GameCommand::ROLL_DIE: return cmdRollDie(command.GetExtension(Command_RollDie::ext), rc, ges); break; + case GameCommand::DRAW_CARDS: return cmdDrawCards(command.GetExtension(Command_DrawCards::ext), rc, ges); break; + case GameCommand::UNDO_DRAW: return cmdUndoDraw(command.GetExtension(Command_UndoDraw::ext), rc, ges); break; + case GameCommand::FLIP_CARD: return cmdFlipCard(command.GetExtension(Command_FlipCard::ext), rc, ges); break; + case GameCommand::ATTACH_CARD: return cmdAttachCard(command.GetExtension(Command_AttachCard::ext), rc, ges); break; + case GameCommand::CREATE_TOKEN: return cmdCreateToken(command.GetExtension(Command_CreateToken::ext), rc, ges); break; + case GameCommand::CREATE_ARROW: return cmdCreateArrow(command.GetExtension(Command_CreateArrow::ext), rc, ges); break; + case GameCommand::DELETE_ARROW: return cmdDeleteArrow(command.GetExtension(Command_DeleteArrow::ext), rc, ges); break; + case GameCommand::SET_CARD_ATTR: return cmdSetCardAttr(command.GetExtension(Command_SetCardAttr::ext), rc, ges); break; + case GameCommand::SET_CARD_COUNTER: return cmdSetCardCounter(command.GetExtension(Command_SetCardCounter::ext), rc, ges); break; + case GameCommand::INC_CARD_COUNTER: return cmdIncCardCounter(command.GetExtension(Command_IncCardCounter::ext), rc, ges); break; + case GameCommand::READY_START: return cmdReadyStart(command.GetExtension(Command_ReadyStart::ext), rc, ges); break; + case GameCommand::CONCEDE: return cmdConcede(command.GetExtension(Command_Concede::ext), rc, ges); break; + case GameCommand::INC_COUNTER: return cmdIncCounter(command.GetExtension(Command_IncCounter::ext), rc, ges); break; + case GameCommand::CREATE_COUNTER: return cmdCreateCounter(command.GetExtension(Command_CreateCounter::ext), rc, ges); break; + case GameCommand::SET_COUNTER: return cmdSetCounter(command.GetExtension(Command_SetCounter::ext), rc, ges); break; + case GameCommand::DEL_COUNTER: return cmdDelCounter(command.GetExtension(Command_DelCounter::ext), rc, ges); break; + case GameCommand::NEXT_TURN: return cmdNextTurn(command.GetExtension(Command_NextTurn::ext), rc, ges); break; + case GameCommand::SET_ACTIVE_PHASE: return cmdSetActivePhase(command.GetExtension(Command_SetActivePhase::ext), rc, ges); break; + case GameCommand::DUMP_ZONE: return cmdDumpZone(command.GetExtension(Command_DumpZone::ext), rc, ges); break; + case GameCommand::STOP_DUMP_ZONE: return cmdStopDumpZone(command.GetExtension(Command_StopDumpZone::ext), rc, ges); break; + case GameCommand::REVEAL_CARDS: return cmdRevealCards(command.GetExtension(Command_RevealCards::ext), rc, ges); break; + case GameCommand::MOVE_CARD: return cmdMoveCard(command.GetExtension(Command_MoveCard::ext), rc, ges); break; + case GameCommand::SET_SIDEBOARD_PLAN: return cmdSetSideboardPlan(command.GetExtension(Command_SetSideboardPlan::ext), rc, ges); break; + case GameCommand::DECK_SELECT: return cmdDeckSelect(command.GetExtension(Command_DeckSelect::ext), rc, ges); break; + default: return Response::RespInvalidCommand; + } +} + void Server_Player::sendGameEvent(const GameEventContainer &cont) { QMutexLocker locker(&playerMutex); diff --git a/common/server_player.h b/common/server_player.h index 5f4bcadf..dd831f05 100644 --- a/common/server_player.h +++ b/common/server_player.h @@ -23,6 +23,39 @@ class CommandContainer; class CardToMove; class GameEventContainer; class GameEventStorage; +class ResponseContainer; +class GameCommand; + +class Command_KickFromGame; +class Command_LeaveGame; +class Command_GameSay; +class Command_Shuffle; +class Command_Mulligan; +class Command_RollDie; +class Command_DrawCards; +class Command_UndoDraw; +class Command_FlipCard; +class Command_AttachCard; +class Command_CreateToken; +class Command_CreateArrow; +class Command_DeleteArrow; +class Command_SetCardAttr; +class Command_SetCardCounter; +class Command_IncCardCounter; +class Command_ReadyStart; +class Command_Concede; +class Command_IncCounter; +class Command_CreateCounter; +class Command_SetCounter; +class Command_DelCounter; +class Command_NextTurn; +class Command_SetActivePhase; +class Command_DumpZone; +class Command_StopDumpZone; +class Command_RevealCards; +class Command_MoveCard; +class Command_SetSideboardPlan; +class Command_DeckSelect; class Server_Player : public Server_ArrowTarget { Q_OBJECT @@ -52,8 +85,6 @@ public: void setProtocolHandler(Server_ProtocolHandler *_handler); void setPlayerId(int _id) { playerId = _id; } - int getInitialCards() const { return initialCards; } - void setInitialCards(int _initialCards) { initialCards = _initialCards; } bool getReadyStart() const { return readyStart; } void setReadyStart(bool _readyStart) { readyStart = _readyStart; } int getPlayerId() const { return playerId; } @@ -61,7 +92,6 @@ public: bool getConceded() const { return conceded; } void setConceded(bool _conceded) { conceded = _conceded; } ServerInfo_User *getUserInfo() const { return userInfo; } - void setDeck(DeckList *_deck); DeckList *getDeck() const { return deck; } Server_Game *getGame() const { return game; } const QMap &getZones() const { return zones; } @@ -80,7 +110,6 @@ public: void addArrow(Server_Arrow *arrow); bool deleteArrow(int arrowId); void addCounter(Server_Counter *counter); - bool deleteCounter(int counterId); void clearZones(); void setupZones(); @@ -92,6 +121,38 @@ public: void unattachCard(GameEventStorage &ges, Server_Card *card); Response::ResponseCode setCardAttrHelper(GameEventStorage &ges, const QString &zone, int cardId, CardAttribute attribute, const QString &attrValue); + Response::ResponseCode cmdLeaveGame(const Command_LeaveGame &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdKickFromGame(const Command_KickFromGame &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdConcede(const Command_Concede &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdReadyStart(const Command_ReadyStart &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdDeckSelect(const Command_DeckSelect &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdSetSideboardPlan(const Command_SetSideboardPlan &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdGameSay(const Command_GameSay &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdShuffle(const Command_Shuffle &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdMulligan(const Command_Mulligan &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdRollDie(const Command_RollDie &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdDrawCards(const Command_DrawCards &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdUndoDraw(const Command_UndoDraw &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdMoveCard(const Command_MoveCard &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdFlipCard(const Command_FlipCard &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdAttachCard(const Command_AttachCard &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdCreateToken(const Command_CreateToken &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdCreateArrow(const Command_CreateArrow &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdDeleteArrow(const Command_DeleteArrow &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdSetCardAttr(const Command_SetCardAttr &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdSetCardCounter(const Command_SetCardCounter &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdIncCardCounter(const Command_IncCardCounter &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdIncCounter(const Command_IncCounter &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdCreateCounter(const Command_CreateCounter &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdSetCounter(const Command_SetCounter &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdDelCounter(const Command_DelCounter &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdNextTurn(const Command_NextTurn &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdSetActivePhase(const Command_SetActivePhase &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdDumpZone(const Command_DumpZone &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdStopDumpZone(const Command_StopDumpZone &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdRevealCards(const Command_RevealCards &cmd, ResponseContainer &rc, GameEventStorage &ges); + + Response::ResponseCode processGameCommand(const GameCommand &command, ResponseContainer &rc, GameEventStorage &ges); void sendGameEvent(const GameEventContainer &event); }; diff --git a/common/server_protocolhandler.cpp b/common/server_protocolhandler.cpp index afa61d51..aff33445 100644 --- a/common/server_protocolhandler.cpp +++ b/common/server_protocolhandler.cpp @@ -1,5 +1,4 @@ #include -#include "rng_abstract.h" #include "server_protocolhandler.h" #include "server_room.h" #include "server_card.h" @@ -13,36 +12,6 @@ #include #include "pb/serverinfo_zone.pb.h" #include "pb/commands.pb.h" -#include "pb/command_attach_card.pb.h" -#include "pb/command_concede.pb.h" -#include "pb/command_create_arrow.pb.h" -#include "pb/command_create_counter.pb.h" -#include "pb/command_create_token.pb.h" -#include "pb/command_deck_select.pb.h" -#include "pb/command_del_counter.pb.h" -#include "pb/command_delete_arrow.pb.h" -#include "pb/command_draw_cards.pb.h" -#include "pb/command_dump_zone.pb.h" -#include "pb/command_flip_card.pb.h" -#include "pb/command_game_say.pb.h" -#include "pb/command_inc_card_counter.pb.h" -#include "pb/command_inc_counter.pb.h" -#include "pb/command_kick_from_game.pb.h" -#include "pb/command_leave_game.pb.h" -#include "pb/command_move_card.pb.h" -#include "pb/command_mulligan.pb.h" -#include "pb/command_next_turn.pb.h" -#include "pb/command_ready_start.pb.h" -#include "pb/command_reveal_cards.pb.h" -#include "pb/command_roll_die.pb.h" -#include "pb/command_set_active_phase.pb.h" -#include "pb/command_set_card_attr.pb.h" -#include "pb/command_set_card_counter.pb.h" -#include "pb/command_set_counter.pb.h" -#include "pb/command_set_sideboard_plan.pb.h" -#include "pb/command_shuffle.pb.h" -#include "pb/command_stop_dump_zone.pb.h" -#include "pb/command_undo_draw.pb.h" #include "pb/command_deck_list.pb.h" #include "pb/command_deck_upload.pb.h" #include "pb/command_deck_download.pb.h" @@ -58,34 +27,12 @@ #include "pb/response_get_games_of_user.pb.h" #include "pb/response_get_user_info.pb.h" #include "pb/response_join_room.pb.h" -#include "pb/response_deck_download.pb.h" -#include "pb/response_dump_zone.pb.h" #include "pb/event_list_rooms.pb.h" #include "pb/event_server_message.pb.h" #include "pb/event_user_message.pb.h" -#include "pb/event_game_say.pb.h" #include "pb/event_game_joined.pb.h" #include "pb/event_game_state_changed.pb.h" -#include "pb/event_shuffle.pb.h" -#include "pb/event_roll_die.pb.h" -#include "pb/event_player_properties_changed.pb.h" -#include "pb/event_create_arrow.pb.h" -#include "pb/event_delete_arrow.pb.h" -#include "pb/event_set_card_counter.pb.h" -#include "pb/event_flip_card.pb.h" -#include "pb/event_attach_card.pb.h" -#include "pb/event_create_token.pb.h" #include "pb/event_room_say.pb.h" -#include "pb/event_create_counter.pb.h" -#include "pb/event_del_counter.pb.h" -#include "pb/event_set_counter.pb.h" -#include "pb/event_dump_zone.pb.h" -#include "pb/event_stop_dump_zone.pb.h" -#include "pb/event_reveal_cards.pb.h" -#include "pb/context_deck_select.pb.h" -#include "pb/context_concede.pb.h" -#include "pb/context_ready_start.pb.h" -#include "pb/context_mulligan.pb.h" #include Server_ProtocolHandler::Server_ProtocolHandler(Server *_server, QObject *parent) @@ -293,42 +240,11 @@ Response::ResponseCode Server_ProtocolHandler::processGameCommandContainer(const GameEventStorage ges; Response::ResponseCode finalResponseCode = Response::RespOk; for (int i = cont.game_command_size() - 1; i >= 0; --i) { - Response::ResponseCode resp = Response::RespInvalidCommand; const GameCommand &sc = cont.game_command(i); - const int num = getPbExtension(sc); emit logDebugMessage(QString::fromStdString(sc.ShortDebugString()), this); - switch ((GameCommand::GameCommandType) num) { - case GameCommand::KICK_FROM_GAME: resp = cmdKickFromGame(sc.GetExtension(Command_KickFromGame::ext), game, player, rc, ges); break; - case GameCommand::LEAVE_GAME: resp = cmdLeaveGame(sc.GetExtension(Command_LeaveGame::ext), game, player, rc, ges); break; - case GameCommand::GAME_SAY: resp = cmdGameSay(sc.GetExtension(Command_GameSay::ext), game, player, rc, ges); break; - case GameCommand::SHUFFLE: resp = cmdShuffle(sc.GetExtension(Command_Shuffle::ext), game, player, rc, ges); break; - case GameCommand::MULLIGAN: resp = cmdMulligan(sc.GetExtension(Command_Mulligan::ext), game, player, rc, ges); break; - case GameCommand::ROLL_DIE: resp = cmdRollDie(sc.GetExtension(Command_RollDie::ext), game, player, rc, ges); break; - case GameCommand::DRAW_CARDS: resp = cmdDrawCards(sc.GetExtension(Command_DrawCards::ext), game, player, rc, ges); break; - case GameCommand::UNDO_DRAW: resp = cmdUndoDraw(sc.GetExtension(Command_UndoDraw::ext), game, player, rc, ges); break; - case GameCommand::FLIP_CARD: resp = cmdFlipCard(sc.GetExtension(Command_FlipCard::ext), game, player, rc, ges); break; - case GameCommand::ATTACH_CARD: resp = cmdAttachCard(sc.GetExtension(Command_AttachCard::ext), game, player, rc, ges); break; - case GameCommand::CREATE_TOKEN: resp = cmdCreateToken(sc.GetExtension(Command_CreateToken::ext), game, player, rc, ges); break; - case GameCommand::CREATE_ARROW: resp = cmdCreateArrow(sc.GetExtension(Command_CreateArrow::ext), game, player, rc, ges); break; - case GameCommand::DELETE_ARROW: resp = cmdDeleteArrow(sc.GetExtension(Command_DeleteArrow::ext), game, player, rc, ges); break; - case GameCommand::SET_CARD_ATTR: resp = cmdSetCardAttr(sc.GetExtension(Command_SetCardAttr::ext), game, player, rc, ges); break; - case GameCommand::SET_CARD_COUNTER: resp = cmdSetCardCounter(sc.GetExtension(Command_SetCardCounter::ext), game, player, rc, ges); break; - case GameCommand::INC_CARD_COUNTER: resp = cmdIncCardCounter(sc.GetExtension(Command_IncCardCounter::ext), game, player, rc, ges); break; - case GameCommand::READY_START: resp = cmdReadyStart(sc.GetExtension(Command_ReadyStart::ext), game, player, rc, ges); break; - case GameCommand::CONCEDE: resp = cmdConcede(sc.GetExtension(Command_Concede::ext), game, player, rc, ges); break; - case GameCommand::INC_COUNTER: resp = cmdIncCounter(sc.GetExtension(Command_IncCounter::ext), game, player, rc, ges); break; - case GameCommand::CREATE_COUNTER: resp = cmdCreateCounter(sc.GetExtension(Command_CreateCounter::ext), game, player, rc, ges); break; - case GameCommand::SET_COUNTER: resp = cmdSetCounter(sc.GetExtension(Command_SetCounter::ext), game, player, rc, ges); break; - case GameCommand::DEL_COUNTER: resp = cmdDelCounter(sc.GetExtension(Command_DelCounter::ext), game, player, rc, ges); break; - case GameCommand::NEXT_TURN: resp = cmdNextTurn(sc.GetExtension(Command_NextTurn::ext), game, player, rc, ges); break; - case GameCommand::SET_ACTIVE_PHASE: resp = cmdSetActivePhase(sc.GetExtension(Command_SetActivePhase::ext), game, player, rc, ges); break; - case GameCommand::DUMP_ZONE: resp = cmdDumpZone(sc.GetExtension(Command_DumpZone::ext), game, player, rc, ges); break; - case GameCommand::STOP_DUMP_ZONE: resp = cmdStopDumpZone(sc.GetExtension(Command_StopDumpZone::ext), game, player, rc, ges); break; - case GameCommand::REVEAL_CARDS: resp = cmdRevealCards(sc.GetExtension(Command_RevealCards::ext), game, player, rc, ges); break; - case GameCommand::MOVE_CARD: resp = cmdMoveCard(sc.GetExtension(Command_MoveCard::ext), game, player, rc, ges); break; - case GameCommand::SET_SIDEBOARD_PLAN: resp = cmdSetSideboardPlan(sc.GetExtension(Command_SetSideboardPlan::ext), game, player, rc, ges); break; - case GameCommand::DECK_SELECT: resp = cmdDeckSelect(sc.GetExtension(Command_DeckSelect::ext), game, player, rc, ges); break; - } + + Response::ResponseCode resp = player->processGameCommand(sc, rc, ges); + if ((resp != Response::RespOk) && (resp != Response::RespNothing)) finalResponseCode = resp; } @@ -821,898 +737,3 @@ Response::ResponseCode Server_ProtocolHandler::cmdJoinGame(const Command_JoinGam return result; } - -Response::ResponseCode Server_ProtocolHandler::cmdLeaveGame(const Command_LeaveGame & /*cmd*/, Server_Game *game, Server_Player *player, ResponseContainer & /*rc*/, GameEventStorage & /*ges*/) -{ - game->removePlayer(player); - return Response::RespOk; -} - -Response::ResponseCode Server_ProtocolHandler::cmdKickFromGame(const Command_KickFromGame &cmd, Server_Game *game, Server_Player *player, ResponseContainer & /*rc*/, GameEventStorage & /*ges*/) -{ - if ((game->getHostId() != player->getPlayerId()) && !(userInfo->user_level() & ServerInfo_User::IsModerator)) - return Response::RespFunctionNotAllowed; - - if (!game->kickPlayer(cmd.player_id())) - return Response::RespNameNotFound; - - return Response::RespOk; -} - -Response::ResponseCode Server_ProtocolHandler::cmdDeckSelect(const Command_DeckSelect &cmd, Server_Game * /*game*/, Server_Player *player, ResponseContainer &rc, GameEventStorage &ges) -{ - if (player->getSpectator()) - return Response::RespFunctionNotAllowed; - - DeckList *deck; - if (cmd.has_deck_id()) { - try { - deck = getDeckFromDatabase(cmd.deck_id()); - } catch(Response::ResponseCode r) { - return r; - } - } else - deck = new DeckList(QString::fromStdString(cmd.deck())); - - player->setDeck(deck); - - Event_PlayerPropertiesChanged event; - event.mutable_player_properties()->set_deck_hash(deck->getDeckHash().toStdString()); - ges.enqueueGameEvent(event, player->getPlayerId()); - - Context_DeckSelect context; - context.set_deck_hash(deck->getDeckHash().toStdString()); - ges.setGameEventContext(context); - - Response_DeckDownload *re = new Response_DeckDownload; - re->set_deck(deck->writeToString_Native().toStdString()); - - rc.setResponseExtension(re); - return Response::RespOk; -} - -Response::ResponseCode Server_ProtocolHandler::cmdSetSideboardPlan(const Command_SetSideboardPlan &cmd, Server_Game * /*game*/, Server_Player *player, ResponseContainer & /*rc*/, GameEventStorage & /*ges*/) -{ - if (player->getSpectator()) - return Response::RespFunctionNotAllowed; - if (player->getReadyStart()) - return Response::RespContextError; - - DeckList *deck = player->getDeck(); - if (!deck) - return Response::RespContextError; - - QList sideboardPlan; - for (int i = 0; i < cmd.move_list_size(); ++i) - sideboardPlan.append(cmd.move_list(i)); - deck->setCurrentSideboardPlan(sideboardPlan); - - return Response::RespOk; -} - -Response::ResponseCode Server_ProtocolHandler::cmdConcede(const Command_Concede & /*cmd*/, Server_Game *game, Server_Player *player, ResponseContainer & /*rc*/, GameEventStorage &ges) -{ - if (player->getSpectator()) - return Response::RespFunctionNotAllowed; - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (player->getConceded()) - return Response::RespContextError; - - player->setConceded(true); - game->removeArrowsToPlayer(ges, player); - game->unattachCards(ges, player); - player->clearZones(); - - Event_PlayerPropertiesChanged event; - event.mutable_player_properties()->set_conceded(true); - ges.enqueueGameEvent(event, player->getPlayerId()); - ges.setGameEventContext(Context_Concede()); - - game->stopGameIfFinished(); - if (game->getGameStarted() && (game->getActivePlayer() == player->getPlayerId())) - game->nextTurn(); - - return Response::RespOk; -} - -Response::ResponseCode Server_ProtocolHandler::cmdReadyStart(const Command_ReadyStart &cmd, Server_Game *game, Server_Player *player, ResponseContainer & /*rc*/, GameEventStorage &ges) -{ - if (player->getSpectator()) - return Response::RespFunctionNotAllowed; - - if (!player->getDeck() || game->getGameStarted()) - return Response::RespContextError; - - if (player->getReadyStart() == cmd.ready()) - return Response::RespContextError; - - player->setReadyStart(cmd.ready()); - - Event_PlayerPropertiesChanged event; - event.mutable_player_properties()->set_ready_start(cmd.ready()); - ges.enqueueGameEvent(event, player->getPlayerId()); - ges.setGameEventContext(Context_ReadyStart()); - - if (cmd.ready()) - game->startGameIfReady(); - - return Response::RespOk; -} - -Response::ResponseCode Server_ProtocolHandler::cmdGameSay(const Command_GameSay &cmd, Server_Game *game, Server_Player *player, ResponseContainer & /*rc*/, GameEventStorage &ges) -{ - if (player->getSpectator() && !game->getSpectatorsCanTalk() && !(userInfo->user_level() & ServerInfo_User::IsModerator)) - return Response::RespFunctionNotAllowed; - - Event_GameSay event; - event.set_message(cmd.message()); - ges.enqueueGameEvent(event, player->getPlayerId()); - - return Response::RespOk; -} - -Response::ResponseCode Server_ProtocolHandler::cmdShuffle(const Command_Shuffle & /*cmd*/, Server_Game *game, Server_Player *player, ResponseContainer & /*rc*/, GameEventStorage &ges) -{ - if (player->getSpectator()) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (player->getConceded()) - return Response::RespContextError; - - player->getZones().value("deck")->shuffle(); - - Event_Shuffle event; - event.set_zone_name("deck"); - ges.enqueueGameEvent(event, player->getPlayerId()); - - return Response::RespOk; -} - -Response::ResponseCode Server_ProtocolHandler::cmdMulligan(const Command_Mulligan & /*cmd*/, Server_Game *game, Server_Player *player, ResponseContainer & /*rc*/, GameEventStorage &ges) -{ - if (player->getSpectator()) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (player->getConceded()) - return Response::RespContextError; - - Server_CardZone *hand = player->getZones().value("hand"); - int number = (hand->cards.size() <= 1) ? player->getInitialCards() : hand->cards.size() - 1; - - Server_CardZone *deck = player->getZones().value("deck"); - while (!hand->cards.isEmpty()) { - CardToMove *cardToMove = new CardToMove; - cardToMove->set_card_id(hand->cards.first()->getId()); - player->moveCard(ges, hand, QList() << cardToMove, deck, 0, 0, false); - delete cardToMove; - } - - deck->shuffle(); - ges.enqueueGameEvent(Event_Shuffle(), player->getPlayerId()); - - player->drawCards(ges, number); - - if (number == player->getInitialCards()) - number = -1; - - Context_Mulligan context; - context.set_number(number); - ges.setGameEventContext(context); - - return Response::RespOk; -} - -Response::ResponseCode Server_ProtocolHandler::cmdRollDie(const Command_RollDie &cmd, Server_Game * /*game*/, Server_Player *player, ResponseContainer & /*rc*/, GameEventStorage &ges) -{ - if (player->getSpectator()) - return Response::RespFunctionNotAllowed; - if (player->getConceded()) - return Response::RespContextError; - - Event_RollDie event; - event.set_sides(cmd.sides()); - event.set_value(rng->getNumber(1, cmd.sides())); - ges.enqueueGameEvent(event, player->getPlayerId()); - - return Response::RespOk; -} - -Response::ResponseCode Server_ProtocolHandler::cmdDrawCards(const Command_DrawCards &cmd, Server_Game *game, Server_Player *player, ResponseContainer & /*rc*/, GameEventStorage &ges) -{ - if (player->getSpectator()) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (player->getConceded()) - return Response::RespContextError; - - return player->drawCards(ges, cmd.number()); -} - -Response::ResponseCode Server_ProtocolHandler::cmdUndoDraw(const Command_UndoDraw & /*cmd*/, Server_Game *game, Server_Player *player, ResponseContainer & /*rc*/, GameEventStorage &ges) -{ - if (player->getSpectator()) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (player->getConceded()) - return Response::RespContextError; - - return player->undoDraw(ges); -} - -Response::ResponseCode Server_ProtocolHandler::cmdMoveCard(const Command_MoveCard &cmd, Server_Game *game, Server_Player *player, ResponseContainer & /*rc*/, GameEventStorage &ges) -{ - if (player->getSpectator()) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (player->getConceded()) - return Response::RespContextError; - - QList cardsToMove; - for (int i = 0; i < cmd.cards_to_move().card_size(); ++i) - cardsToMove.append(&cmd.cards_to_move().card(i)); - - return player->moveCard(ges, QString::fromStdString(cmd.start_zone()), cardsToMove, cmd.target_player_id(), QString::fromStdString(cmd.target_zone()), cmd.x(), cmd.y()); -} - -Response::ResponseCode Server_ProtocolHandler::cmdFlipCard(const Command_FlipCard &cmd, Server_Game *game, Server_Player *player, ResponseContainer & /*rc*/, GameEventStorage &ges) -{ - if (player->getSpectator()) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (player->getConceded()) - return Response::RespContextError; - - Server_CardZone *zone = player->getZones().value(QString::fromStdString(cmd.zone())); - if (!zone) - return Response::RespNameNotFound; - if (!zone->hasCoords()) - return Response::RespContextError; - - Server_Card *card = zone->getCard(cmd.card_id()); - if (!card) - return Response::RespNameNotFound; - - const bool faceDown = cmd.face_down(); - if (faceDown == card->getFaceDown()) - return Response::RespContextError; - - card->setFaceDown(faceDown); - - Event_FlipCard event; - event.set_zone_name(zone->getName().toStdString()); - event.set_card_id(card->getId()); - event.set_card_name(card->getName().toStdString()); - event.set_face_down(faceDown); - ges.enqueueGameEvent(event, player->getPlayerId()); - - return Response::RespOk; -} - -Response::ResponseCode Server_ProtocolHandler::cmdAttachCard(const Command_AttachCard &cmd, Server_Game *game, Server_Player *player, ResponseContainer & /*rc*/, GameEventStorage &ges) -{ - if (player->getSpectator()) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (player->getConceded()) - return Response::RespContextError; - - Server_CardZone *startzone = player->getZones().value(QString::fromStdString(cmd.start_zone())); - if (!startzone) - return Response::RespNameNotFound; - - Server_Card *card = startzone->getCard(cmd.card_id()); - if (!card) - return Response::RespNameNotFound; - - Server_Player *targetPlayer = 0; - Server_CardZone *targetzone = 0; - Server_Card *targetCard = 0; - - if (cmd.has_target_player_id()) { - targetPlayer = game->getPlayer(cmd.target_player_id()); - if (!targetPlayer) - return Response::RespNameNotFound; - } else if (!card->getParentCard()) - return Response::RespContextError; - if (targetPlayer) - targetzone = targetPlayer->getZones().value(QString::fromStdString(cmd.target_zone())); - if (targetzone) { - // This is currently enough to make sure cards don't get attached to a card that is not on the table. - // Possibly a flag will have to be introduced for this sometime. - if (!targetzone->hasCoords()) - return Response::RespContextError; - if (cmd.has_target_card_id()) - targetCard = targetzone->getCard(cmd.target_card_id()); - if (targetCard) - if (targetCard->getParentCard()) - return Response::RespContextError; - } - if (!startzone->hasCoords()) - return Response::RespContextError; - - // Get all arrows pointing to or originating from the card being attached and delete them. - QMapIterator playerIterator(game->getPlayers()); - while (playerIterator.hasNext()) { - Server_Player *p = playerIterator.next().value(); - QList arrows = p->getArrows().values(); - QList toDelete; - for (int i = 0; i < arrows.size(); ++i) { - Server_Arrow *a = arrows[i]; - Server_Card *tCard = qobject_cast(a->getTargetItem()); - if ((tCard == card) || (a->getStartCard() == card)) - toDelete.append(a); - } - for (int i = 0; i < toDelete.size(); ++i) { - Event_DeleteArrow event; - event.set_arrow_id(toDelete[i]->getId()); - ges.enqueueGameEvent(event, p->getPlayerId()); - p->deleteArrow(toDelete[i]->getId()); - } - } - - if (targetCard) { - // Unattach all cards attached to the card being attached. - // Make a copy of the list because its contents change during the loop otherwise. - QList attachedList = card->getAttachedCards(); - for (int i = 0; i < attachedList.size(); ++i) - attachedList[i]->getZone()->getPlayer()->unattachCard(ges, attachedList[i]); - - if (targetzone->isColumnStacked(targetCard->getX(), targetCard->getY())) { - CardToMove *cardToMove = new CardToMove; - cardToMove->set_card_id(targetCard->getId()); - targetPlayer->moveCard(ges, targetzone, QList() << cardToMove, targetzone, targetzone->getFreeGridColumn(-2, targetCard->getY(), targetCard->getName()), targetCard->getY(), targetCard->getFaceDown()); - delete cardToMove; - } - - card->setParentCard(targetCard); - card->setCoords(-1, card->getY()); - - Event_AttachCard event; - event.set_start_zone(startzone->getName().toStdString()); - event.set_card_id(card->getId()); - event.set_target_player_id(targetPlayer->getPlayerId()); - event.set_target_zone(targetzone->getName().toStdString()); - event.set_target_card_id(targetCard->getId()); - ges.enqueueGameEvent(event, player->getPlayerId()); - - startzone->fixFreeSpaces(ges); - } else - player->unattachCard(ges, card); - - return Response::RespOk; -} - -Response::ResponseCode Server_ProtocolHandler::cmdCreateToken(const Command_CreateToken &cmd, Server_Game *game, Server_Player *player, ResponseContainer & /*rc*/, GameEventStorage &ges) -{ - if (player->getSpectator()) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (player->getConceded()) - return Response::RespContextError; - - Server_CardZone *zone = player->getZones().value(QString::fromStdString(cmd.zone())); - if (!zone) - return Response::RespNameNotFound; - - QString cardName = QString::fromStdString(cmd.card_name()); - int x = cmd.x(); - int y = cmd.y(); - if (zone->hasCoords()) - x = zone->getFreeGridColumn(x, y, cardName); - if (x < 0) - x = 0; - if (y < 0) - y = 0; - - Server_Card *card = new Server_Card(cardName, player->newCardId(), x, y); - card->moveToThread(player->thread()); - card->setPT(QString::fromStdString(cmd.pt())); - card->setColor(QString::fromStdString(cmd.color())); - card->setAnnotation(QString::fromStdString(cmd.annotation())); - card->setDestroyOnZoneChange(cmd.destroy_on_zone_change()); - - zone->insertCard(card, x, y); - - Event_CreateToken event; - event.set_zone_name(zone->getName().toStdString()); - event.set_card_id(card->getId()); - event.set_card_name(card->getName().toStdString()); - event.set_color(card->getColor().toStdString()); - event.set_pt(card->getPT().toStdString()); - event.set_annotation(card->getAnnotation().toStdString()); - event.set_destroy_on_zone_change(card->getDestroyOnZoneChange()); - event.set_x(x); - event.set_y(y); - ges.enqueueGameEvent(event, player->getPlayerId()); - - return Response::RespOk; -} - -Response::ResponseCode Server_ProtocolHandler::cmdCreateArrow(const Command_CreateArrow &cmd, Server_Game *game, Server_Player *player, ResponseContainer & /*rc*/, GameEventStorage &ges) -{ - if (player->getSpectator()) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (player->getConceded()) - return Response::RespContextError; - - Server_Player *startPlayer = game->getPlayer(cmd.start_player_id()); - Server_Player *targetPlayer = game->getPlayer(cmd.target_player_id()); - if (!startPlayer || !targetPlayer) - return Response::RespNameNotFound; - QString startZoneName = QString::fromStdString(cmd.start_zone()); - Server_CardZone *startZone = startPlayer->getZones().value(startZoneName); - bool playerTarget = !cmd.has_target_zone(); - Server_CardZone *targetZone = 0; - if (!playerTarget) - targetZone = targetPlayer->getZones().value(QString::fromStdString(cmd.target_zone())); - if (!startZone || (!targetZone && !playerTarget)) - return Response::RespNameNotFound; - if (startZone->getType() != ServerInfo_Zone::PublicZone) - return Response::RespContextError; - Server_Card *startCard = startZone->getCard(cmd.start_card_id()); - if (!startCard) - return Response::RespNameNotFound; - Server_Card *targetCard = 0; - if (!playerTarget) { - if (targetZone->getType() != ServerInfo_Zone::PublicZone) - return Response::RespContextError; - targetCard = targetZone->getCard(cmd.target_card_id()); - } - - Server_ArrowTarget *targetItem; - if (playerTarget) - targetItem = targetPlayer; - else - targetItem = targetCard; - if (!targetItem) - return Response::RespNameNotFound; - - QMapIterator arrowIterator(player->getArrows()); - while (arrowIterator.hasNext()) { - Server_Arrow *temp = arrowIterator.next().value(); - if ((temp->getStartCard() == startCard) && (temp->getTargetItem() == targetItem)) - return Response::RespContextError; - } - - Server_Arrow *arrow = new Server_Arrow(player->newArrowId(), startCard, targetItem, cmd.arrow_color()); - player->addArrow(arrow); - - Event_CreateArrow event; - ServerInfo_Arrow *arrowInfo = event.mutable_arrow_info(); - arrowInfo->set_id(arrow->getId()); - arrowInfo->set_start_player_id(startPlayer->getPlayerId()); - arrowInfo->set_start_zone(startZoneName.toStdString()); - arrowInfo->set_start_card_id(startCard->getId()); - arrowInfo->set_target_player_id(targetPlayer->getPlayerId()); - if (!playerTarget) { - arrowInfo->set_target_zone(cmd.target_zone()); - arrowInfo->set_target_card_id(cmd.target_card_id()); - } - arrowInfo->mutable_arrow_color()->CopyFrom(cmd.arrow_color()); - ges.enqueueGameEvent(event, player->getPlayerId()); - - return Response::RespOk; -} - -Response::ResponseCode Server_ProtocolHandler::cmdDeleteArrow(const Command_DeleteArrow &cmd, Server_Game *game, Server_Player *player, ResponseContainer & /*rc*/, GameEventStorage &ges) -{ - if (player->getSpectator()) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (player->getConceded()) - return Response::RespContextError; - - if (!player->deleteArrow(cmd.arrow_id())) - return Response::RespNameNotFound; - - Event_DeleteArrow event; - event.set_arrow_id(cmd.arrow_id()); - ges.enqueueGameEvent(event, player->getPlayerId()); - - return Response::RespOk; -} - -Response::ResponseCode Server_ProtocolHandler::cmdSetCardAttr(const Command_SetCardAttr &cmd, Server_Game *game, Server_Player *player, ResponseContainer & /*rc*/, GameEventStorage &ges) -{ - if (player->getSpectator()) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (player->getConceded()) - return Response::RespContextError; - - return player->setCardAttrHelper(ges, QString::fromStdString(cmd.zone()), cmd.card_id(), cmd.attribute(), QString::fromStdString(cmd.attr_value())); -} - -Response::ResponseCode Server_ProtocolHandler::cmdSetCardCounter(const Command_SetCardCounter &cmd, Server_Game *game, Server_Player *player, ResponseContainer & /*rc*/, GameEventStorage &ges) -{ - if (player->getSpectator()) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (player->getConceded()) - return Response::RespContextError; - - Server_CardZone *zone = player->getZones().value(QString::fromStdString(cmd.zone())); - if (!zone) - return Response::RespNameNotFound; - if (!zone->hasCoords()) - return Response::RespContextError; - - Server_Card *card = zone->getCard(cmd.card_id()); - if (!card) - return Response::RespNameNotFound; - - card->setCounter(cmd.counter_id(), cmd.counter_value()); - - Event_SetCardCounter event; - event.set_zone_name(zone->getName().toStdString()); - event.set_card_id(card->getId()); - event.set_counter_id(cmd.counter_id()); - event.set_counter_value(cmd.counter_value()); - ges.enqueueGameEvent(event, player->getPlayerId()); - - return Response::RespOk; -} - -Response::ResponseCode Server_ProtocolHandler::cmdIncCardCounter(const Command_IncCardCounter &cmd, Server_Game *game, Server_Player *player, ResponseContainer &/*rc*/, GameEventStorage &ges) -{ - if (player->getSpectator()) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (player->getConceded()) - return Response::RespContextError; - - Server_CardZone *zone = player->getZones().value(QString::fromStdString(cmd.zone())); - if (!zone) - return Response::RespNameNotFound; - if (!zone->hasCoords()) - return Response::RespContextError; - - Server_Card *card = zone->getCard(cmd.card_id()); - if (!card) - return Response::RespNameNotFound; - - int newValue = card->getCounter(cmd.counter_id()) + cmd.counter_delta(); - card->setCounter(cmd.counter_id(), newValue); - - Event_SetCardCounter event; - event.set_zone_name(zone->getName().toStdString()); - event.set_card_id(card->getId()); - event.set_counter_id(cmd.counter_id()); - event.set_counter_value(newValue); - ges.enqueueGameEvent(event, player->getPlayerId()); - - return Response::RespOk; -} - -Response::ResponseCode Server_ProtocolHandler::cmdIncCounter(const Command_IncCounter &cmd, Server_Game *game, Server_Player *player, ResponseContainer & /*rc*/, GameEventStorage &ges) -{ - if (player->getSpectator()) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (player->getConceded()) - return Response::RespContextError; - - const QMap counters = player->getCounters(); - Server_Counter *c = counters.value(cmd.counter_id(), 0); - if (!c) - return Response::RespNameNotFound; - - c->setCount(c->getCount() + cmd.delta()); - - Event_SetCounter event; - event.set_counter_id(c->getId()); - event.set_value(c->getCount()); - ges.enqueueGameEvent(event, player->getPlayerId()); - - return Response::RespOk; -} - -Response::ResponseCode Server_ProtocolHandler::cmdCreateCounter(const Command_CreateCounter &cmd, Server_Game *game, Server_Player *player, ResponseContainer & /*rc*/, GameEventStorage &ges) -{ - if (player->getSpectator()) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (player->getConceded()) - return Response::RespContextError; - - Server_Counter *c = new Server_Counter(player->newCounterId(), QString::fromStdString(cmd.counter_name()), cmd.counter_color(), cmd.radius(), cmd.value()); - player->addCounter(c); - - Event_CreateCounter event; - ServerInfo_Counter *counterInfo = event.mutable_counter_info(); - counterInfo->set_id(c->getId()); - counterInfo->set_name(c->getName().toStdString()); - counterInfo->mutable_counter_color()->CopyFrom(cmd.counter_color()); - counterInfo->set_radius(c->getRadius()); - counterInfo->set_count(c->getCount()); - ges.enqueueGameEvent(event, player->getPlayerId()); - - return Response::RespOk; -} - -Response::ResponseCode Server_ProtocolHandler::cmdSetCounter(const Command_SetCounter &cmd, Server_Game *game, Server_Player *player, ResponseContainer & /*rc*/, GameEventStorage &ges) -{ - if (player->getSpectator()) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (player->getConceded()) - return Response::RespContextError; - - Server_Counter *c = player->getCounters().value(cmd.counter_id(), 0);; - if (!c) - return Response::RespNameNotFound; - - c->setCount(cmd.value()); - - Event_SetCounter event; - event.set_counter_id(c->getId()); - event.set_value(c->getCount()); - ges.enqueueGameEvent(event, player->getPlayerId()); - - return Response::RespOk; -} - -Response::ResponseCode Server_ProtocolHandler::cmdDelCounter(const Command_DelCounter &cmd, Server_Game *game, Server_Player *player, ResponseContainer & /*rc*/, GameEventStorage &ges) -{ - if (player->getSpectator()) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (player->getConceded()) - return Response::RespContextError; - - if (!player->deleteCounter(cmd.counter_id())) - return Response::RespNameNotFound; - - Event_DelCounter event; - event.set_counter_id(cmd.counter_id()); - ges.enqueueGameEvent(event, player->getPlayerId()); - - return Response::RespOk; -} - -Response::ResponseCode Server_ProtocolHandler::cmdNextTurn(const Command_NextTurn & /*cmd*/, Server_Game *game, Server_Player *player, ResponseContainer & /*rc*/, GameEventStorage & /*ges*/) -{ - if (player->getSpectator()) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (player->getConceded()) - return Response::RespContextError; - - game->nextTurn(); - return Response::RespOk; -} - -Response::ResponseCode Server_ProtocolHandler::cmdSetActivePhase(const Command_SetActivePhase &cmd, Server_Game *game, Server_Player *player, ResponseContainer & /*rc*/, GameEventStorage & /*ges*/) -{ - if (player->getSpectator()) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (player->getConceded()) - return Response::RespContextError; - - if (game->getActivePlayer() != player->getPlayerId()) - return Response::RespContextError; - game->setActivePhase(cmd.phase()); - - return Response::RespOk; -} - -Response::ResponseCode Server_ProtocolHandler::cmdDumpZone(const Command_DumpZone &cmd, Server_Game *game, Server_Player *player, ResponseContainer &rc, GameEventStorage &ges) -{ - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - - Server_Player *otherPlayer = game->getPlayer(cmd.player_id()); - if (!otherPlayer) - return Response::RespNameNotFound; - Server_CardZone *zone = otherPlayer->getZones().value(QString::fromStdString(cmd.zone_name())); - if (!zone) - return Response::RespNameNotFound; - if (!((zone->getType() == ServerInfo_Zone::PublicZone) || (player == otherPlayer))) - return Response::RespContextError; - - int numberCards = cmd.number_cards(); - - Response_DumpZone *re = new Response_DumpZone; - ServerInfo_Zone *zoneInfo = re->mutable_zone_info(); - zoneInfo->set_name(zone->getName().toStdString()); - zoneInfo->set_type(zone->getType()); - zoneInfo->set_with_coords(zone->hasCoords()); - zoneInfo->set_card_count(numberCards < zone->cards.size() ? zone->cards.size() : numberCards); - - for (int i = 0; (i < zone->cards.size()) && (i < numberCards || numberCards == -1); ++i) { - Server_Card *card = zone->cards[i]; - QString displayedName = card->getFaceDown() ? QString() : card->getName(); - ServerInfo_Card *cardInfo = zoneInfo->add_card_list(); - cardInfo->set_name(displayedName.toStdString()); - if (zone->getType() == ServerInfo_Zone::HiddenZone) - cardInfo->set_id(i); - else { - cardInfo->set_id(card->getId()); - cardInfo->set_x(card->getX()); - cardInfo->set_y(card->getY()); - cardInfo->set_face_down(card->getFaceDown()); - cardInfo->set_tapped(card->getTapped()); - cardInfo->set_attacking(card->getAttacking()); - cardInfo->set_color(card->getColor().toStdString()); - cardInfo->set_pt(card->getPT().toStdString()); - cardInfo->set_annotation(card->getAnnotation().toStdString()); - cardInfo->set_destroy_on_zone_change(card->getDestroyOnZoneChange()); - cardInfo->set_doesnt_untap(card->getDoesntUntap()); - - QMapIterator cardCounterIterator(card->getCounters()); - while (cardCounterIterator.hasNext()) { - cardCounterIterator.next(); - ServerInfo_CardCounter *counterInfo = cardInfo->add_counter_list(); - counterInfo->set_id(cardCounterIterator.key()); - counterInfo->set_value(cardCounterIterator.value()); - } - - if (card->getParentCard()) { - cardInfo->set_attach_player_id(card->getParentCard()->getZone()->getPlayer()->getPlayerId()); - cardInfo->set_attach_zone(card->getParentCard()->getZone()->getName().toStdString()); - cardInfo->set_attach_card_id(card->getParentCard()->getId()); - } - } - } - if (zone->getType() == ServerInfo_Zone::HiddenZone) { - zone->setCardsBeingLookedAt(numberCards); - - Event_DumpZone event; - event.set_zone_owner_id(otherPlayer->getPlayerId()); - event.set_zone_name(zone->getName().toStdString()); - event.set_number_cards(numberCards); - ges.enqueueGameEvent(event, player->getPlayerId()); - } - rc.setResponseExtension(re); - return Response::RespOk; -} - -Response::ResponseCode Server_ProtocolHandler::cmdStopDumpZone(const Command_StopDumpZone &cmd, Server_Game *game, Server_Player *player, ResponseContainer & /*rc*/, GameEventStorage &ges) -{ - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (player->getConceded()) - return Response::RespContextError; - - Server_Player *otherPlayer = game->getPlayer(cmd.player_id()); - if (!otherPlayer) - return Response::RespNameNotFound; - Server_CardZone *zone = otherPlayer->getZones().value(QString::fromStdString(cmd.zone_name())); - if (!zone) - return Response::RespNameNotFound; - - if (zone->getType() == ServerInfo_Zone::HiddenZone) { - zone->setCardsBeingLookedAt(0); - - Event_StopDumpZone event; - event.set_zone_owner_id(cmd.player_id()); - event.set_zone_name(zone->getName().toStdString()); - ges.enqueueGameEvent(event, player->getPlayerId()); - } - return Response::RespOk; -} - -Response::ResponseCode Server_ProtocolHandler::cmdRevealCards(const Command_RevealCards &cmd, Server_Game *game, Server_Player *player, ResponseContainer & /*rc*/, GameEventStorage &ges) -{ - if (player->getSpectator()) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (player->getConceded()) - return Response::RespContextError; - - Server_Player *otherPlayer = 0; - if (cmd.has_player_id()) { - otherPlayer = game->getPlayer(cmd.player_id()); - if (!otherPlayer) - return Response::RespNameNotFound; - } - Server_CardZone *zone = player->getZones().value(QString::fromStdString(cmd.zone_name())); - if (!zone) - return Response::RespNameNotFound; - - QList cardsToReveal; - if (!cmd.has_card_id()) - cardsToReveal = zone->cards; - else if (cmd.card_id() == -2) { - if (zone->cards.isEmpty()) - return Response::RespContextError; - cardsToReveal.append(zone->cards.at(rng->getNumber(0, zone->cards.size() - 1))); - } else { - Server_Card *card = zone->getCard(cmd.card_id()); - if (!card) - return Response::RespNameNotFound; - cardsToReveal.append(card); - } - - Event_RevealCards eventOthers; - eventOthers.set_zone_name(zone->getName().toStdString()); - if (cmd.has_card_id()) - eventOthers.set_card_id(cmd.card_id()); - if (cmd.has_player_id()) - eventOthers.set_other_player_id(cmd.player_id()); - - Event_RevealCards eventPrivate(eventOthers); - - for (int i = 0; i < cardsToReveal.size(); ++i) { - Server_Card *card = cardsToReveal[i]; - ServerInfo_Card *cardInfo = eventPrivate.add_cards(); - - cardInfo->set_id(card->getId()); - cardInfo->set_name(card->getName().toStdString()); - cardInfo->set_x(card->getX()); - cardInfo->set_y(card->getY()); - cardInfo->set_face_down(card->getFaceDown()); - cardInfo->set_tapped(card->getTapped()); - cardInfo->set_attacking(card->getAttacking()); - cardInfo->set_color(card->getColor().toStdString()); - cardInfo->set_pt(card->getPT().toStdString()); - cardInfo->set_annotation(card->getAnnotation().toStdString()); - cardInfo->set_destroy_on_zone_change(card->getDestroyOnZoneChange()); - cardInfo->set_doesnt_untap(card->getDoesntUntap()); - - QMapIterator cardCounterIterator(card->getCounters()); - while (cardCounterIterator.hasNext()) { - cardCounterIterator.next(); - ServerInfo_CardCounter *counterInfo = cardInfo->add_counter_list(); - counterInfo->set_id(cardCounterIterator.key()); - counterInfo->set_value(cardCounterIterator.value()); - } - - if (card->getParentCard()) { - cardInfo->set_attach_player_id(card->getParentCard()->getZone()->getPlayer()->getPlayerId()); - cardInfo->set_attach_zone(card->getParentCard()->getZone()->getName().toStdString()); - cardInfo->set_attach_card_id(card->getParentCard()->getId()); - } - } - - if (cmd.has_player_id()) { - ges.enqueueGameEvent(eventPrivate, player->getPlayerId(), GameEventStorageItem::SendToPrivate, cmd.player_id()); - ges.enqueueGameEvent(eventOthers, player->getPlayerId(), GameEventStorageItem::SendToOthers); - } else - ges.enqueueGameEvent(eventPrivate, player->getPlayerId()); - - return Response::RespOk; -} diff --git a/common/server_protocolhandler.h b/common/server_protocolhandler.h index 20a7a022..91ae69de 100644 --- a/common/server_protocolhandler.h +++ b/common/server_protocolhandler.h @@ -50,37 +50,6 @@ class Command_RoomSay; class Command_CreateGame; class Command_JoinGame; -class Command_KickFromGame; -class Command_LeaveGame; -class Command_GameSay; -class Command_Shuffle; -class Command_Mulligan; -class Command_RollDie; -class Command_DrawCards; -class Command_UndoDraw; -class Command_FlipCard; -class Command_AttachCard; -class Command_CreateToken; -class Command_CreateArrow; -class Command_DeleteArrow; -class Command_SetCardAttr; -class Command_SetCardCounter; -class Command_IncCardCounter; -class Command_ReadyStart; -class Command_Concede; -class Command_IncCounter; -class Command_CreateCounter; -class Command_SetCounter; -class Command_DelCounter; -class Command_NextTurn; -class Command_SetActivePhase; -class Command_DumpZone; -class Command_StopDumpZone; -class Command_RevealCards; -class Command_MoveCard; -class Command_SetSideboardPlan; -class Command_DeckSelect; - class Command_BanFromServer; class Command_UpdateServerMessage; class Command_ShutdownServer; @@ -105,8 +74,6 @@ private: virtual void transmitProtocolItem(const ServerMessage &item) = 0; - virtual DeckList *getDeckFromDatabase(int deckId) = 0; - Response::ResponseCode cmdPing(const Command_Ping &cmd, ResponseContainer &rc); Response::ResponseCode cmdLogin(const Command_Login &cmd, ResponseContainer &rc); Response::ResponseCode cmdMessage(const Command_Message &cmd, ResponseContainer &rc); @@ -130,36 +97,6 @@ private: Response::ResponseCode cmdRoomSay(const Command_RoomSay &cmd, Server_Room *room, ResponseContainer &rc); Response::ResponseCode cmdCreateGame(const Command_CreateGame &cmd, Server_Room *room, ResponseContainer &rc); Response::ResponseCode cmdJoinGame(const Command_JoinGame &cmd, Server_Room *room, ResponseContainer &rc); - Response::ResponseCode cmdLeaveGame(const Command_LeaveGame &cmd, Server_Game *game, Server_Player *player, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdKickFromGame(const Command_KickFromGame &cmd, Server_Game *game, Server_Player *player, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdConcede(const Command_Concede &cmd, Server_Game *game, Server_Player *player, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdReadyStart(const Command_ReadyStart &cmd, Server_Game *game, Server_Player *player, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdDeckSelect(const Command_DeckSelect &cmd, Server_Game *game, Server_Player *player, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdSetSideboardPlan(const Command_SetSideboardPlan &cmd, Server_Game *game, Server_Player *player, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdGameSay(const Command_GameSay &cmd, Server_Game *game, Server_Player *player, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdShuffle(const Command_Shuffle &cmd, Server_Game *game, Server_Player *player, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdMulligan(const Command_Mulligan &cmd, Server_Game *game, Server_Player *player, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdRollDie(const Command_RollDie &cmd, Server_Game *game, Server_Player *player, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdDrawCards(const Command_DrawCards &cmd, Server_Game *game, Server_Player *player, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdUndoDraw(const Command_UndoDraw &cmd, Server_Game *game, Server_Player *player, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdMoveCard(const Command_MoveCard &cmd, Server_Game *game, Server_Player *player, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdFlipCard(const Command_FlipCard &cmd, Server_Game *game, Server_Player *player, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdAttachCard(const Command_AttachCard &cmd, Server_Game *game, Server_Player *player, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdCreateToken(const Command_CreateToken &cmd, Server_Game *game, Server_Player *player, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdCreateArrow(const Command_CreateArrow &cmd, Server_Game *game, Server_Player *player, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdDeleteArrow(const Command_DeleteArrow &cmd, Server_Game *game, Server_Player *player, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdSetCardAttr(const Command_SetCardAttr &cmd, Server_Game *game, Server_Player *player, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdSetCardCounter(const Command_SetCardCounter &cmd, Server_Game *game, Server_Player *player, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdIncCardCounter(const Command_IncCardCounter &cmd, Server_Game *game, Server_Player *player, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdIncCounter(const Command_IncCounter &cmd, Server_Game *game, Server_Player *player, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdCreateCounter(const Command_CreateCounter &cmd, Server_Game *game, Server_Player *player, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdSetCounter(const Command_SetCounter &cmd, Server_Game *game, Server_Player *player, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdDelCounter(const Command_DelCounter &cmd, Server_Game *game, Server_Player *player, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdNextTurn(const Command_NextTurn &cmd, Server_Game *game, Server_Player *player, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdSetActivePhase(const Command_SetActivePhase &cmd, Server_Game *game, Server_Player *player, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdDumpZone(const Command_DumpZone &cmd, Server_Game *game, Server_Player *player, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdStopDumpZone(const Command_StopDumpZone &cmd, Server_Game *game, Server_Player *player, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdRevealCards(const Command_RevealCards &cmd, Server_Game *game, Server_Player *player, ResponseContainer &rc, GameEventStorage &ges); virtual Response::ResponseCode cmdBanFromServer(const Command_BanFromServer &cmd, ResponseContainer &rc) = 0; virtual Response::ResponseCode cmdShutdownServer(const Command_ShutdownServer &cmd, ResponseContainer &rc) = 0; virtual Response::ResponseCode cmdUpdateServerMessage(const Command_UpdateServerMessage &cmd, ResponseContainer &rc) = 0; diff --git a/servatrice/src/servatrice.cpp b/servatrice/src/servatrice.cpp index 1abcbcf3..401eb021 100644 --- a/servatrice/src/servatrice.cpp +++ b/servatrice/src/servatrice.cpp @@ -29,6 +29,7 @@ #include "server_logger.h" #include "main.h" #include "passwordhasher.h" +#include "decklist.h" #include "pb/game_replay.pb.h" #include "pb/event_replay_added.pb.h" #include "pb/event_server_message.pb.h" @@ -815,6 +816,27 @@ void Servatrice::storeGameInformation(int secondsElapsed, const QSet &a query3.execBatch(); } +DeckList *Servatrice::getDeckFromDatabase(int deckId, const QString &userName) +{ + checkSql(); + + QMutexLocker locker(&dbMutex); + QSqlQuery query; + + query.prepare("select content from " + dbPrefix + "_decklist_files where id = :id and user = :user"); + query.bindValue(":id", deckId); + query.bindValue(":user", userName); + execSqlQuery(query); + if (!query.next()) + throw Response::RespNameNotFound; + + QXmlStreamReader deckReader(query.value(0).toString()); + DeckList *deck = new DeckList; + deck->loadFromXml(&deckReader); + + return deck; +} + void Servatrice::scheduleShutdown(const QString &reason, int minutes) { shutdownReason = reason; diff --git a/servatrice/src/servatrice.h b/servatrice/src/servatrice.h index 26b9c665..b6a6d827 100644 --- a/servatrice/src/servatrice.h +++ b/servatrice/src/servatrice.h @@ -116,6 +116,7 @@ public: void incRxBytes(quint64 num); int getUserIdInDB(const QString &name); void storeGameInformation(int secondsElapsed, const QSet &allPlayersEver, const QSet &allSpectatorsEver, const QList &replays); + DeckList *getDeckFromDatabase(int deckId, const QString &userName); bool islConnectionExists(int serverId) const; void addIslInterface(int serverId, IslInterface *interface); diff --git a/servatrice/src/serversocketinterface.cpp b/servatrice/src/serversocketinterface.cpp index 3634f862..523a676d 100644 --- a/servatrice/src/serversocketinterface.cpp +++ b/servatrice/src/serversocketinterface.cpp @@ -451,27 +451,6 @@ Response::ResponseCode ServerSocketInterface::cmdDeckUpload(const Command_DeckUp return Response::RespOk; } -DeckList *ServerSocketInterface::getDeckFromDatabase(int deckId) -{ - servatrice->checkSql(); - - QMutexLocker locker(&servatrice->dbMutex); - QSqlQuery query; - - query.prepare("select content from " + servatrice->getDbPrefix() + "_decklist_files where id = :id and user = :user"); - query.bindValue(":id", deckId); - query.bindValue(":user", QString::fromStdString(userInfo->name())); - servatrice->execSqlQuery(query); - if (!query.next()) - throw Response::RespNameNotFound; - - QXmlStreamReader deckReader(query.value(0).toString()); - DeckList *deck = new DeckList; - deck->loadFromXml(&deckReader); - - return deck; -} - Response::ResponseCode ServerSocketInterface::cmdDeckDownload(const Command_DeckDownload &cmd, ResponseContainer &rc) { if (authState != PasswordRight) @@ -479,7 +458,7 @@ Response::ResponseCode ServerSocketInterface::cmdDeckDownload(const Command_Deck DeckList *deck; try { - deck = getDeckFromDatabase(cmd.deck_id()); + deck = servatrice->getDeckFromDatabase(cmd.deck_id(), QString::fromStdString(userInfo->name())); } catch(Response::ResponseCode r) { return r; }