diff --git a/servatrice/servatrice.pro b/servatrice/servatrice.pro index 120d7a42..71dacbd9 100755 --- a/servatrice/servatrice.pro +++ b/servatrice/servatrice.pro @@ -17,6 +17,7 @@ QT -= gui HEADERS += src/server.h src/servergame.h src/serversocket.h \ src/playerzone.h \ src/card.h \ + src/arrow.h \ src/version.h \ src/counter.h \ src/abstractrng.h \ diff --git a/servatrice/src/arrow.h b/servatrice/src/arrow.h new file mode 100644 index 00000000..9b5c7e8c --- /dev/null +++ b/servatrice/src/arrow.h @@ -0,0 +1,18 @@ +#ifndef ARROW_H +#define ARROW_H + +class Card; + +class Arrow { +private: + Card *startCard, *targetCard; + int color; +public: + Arrow(Card *_startCard, Card *_targetCard, int _color) + : startCard(_startCard), targetCard(_targetCard), color(_color) { } + Card *getStartCard() const { return startCard; } + Card *getTargetCard() const { return targetCard; } + int getColor() const { return color; } +}; + +#endif \ No newline at end of file diff --git a/servatrice/src/card.h b/servatrice/src/card.h index 62233a0c..6ee3c88f 100644 --- a/servatrice/src/card.h +++ b/servatrice/src/card.h @@ -22,8 +22,11 @@ #include +class PlayerZone; + class Card { private: + PlayerZone *zone; int id; int coord_x, coord_y; QString name; @@ -37,6 +40,9 @@ public: Card(QString _name, int _id, int _coord_x, int _coord_y); ~Card(); + PlayerZone *getZone() const { return zone; } + void setZone(PlayerZone *_zone) { zone = _zone; } + int getId() const { return id; } int getX() const { return coord_x; } int getY() const { return coord_y; } diff --git a/servatrice/src/playerzone.cpp b/servatrice/src/playerzone.cpp index eb20f231..ba397376 100644 --- a/servatrice/src/playerzone.cpp +++ b/servatrice/src/playerzone.cpp @@ -21,8 +21,8 @@ #include "abstractrng.h" #include "card.h" -PlayerZone::PlayerZone(const QString &_name, bool _has_coords, ZoneType _type) - : name(_name), has_coords(_has_coords), type(_type), cardsBeingLookedAt(0) +PlayerZone::PlayerZone(ServerSocket *_player, const QString &_name, bool _has_coords, ZoneType _type) + : player(_player), name(_name), has_coords(_has_coords), type(_type), cardsBeingLookedAt(0) { } @@ -48,8 +48,10 @@ Card *PlayerZone::getCard(int id, bool remove, int *position) while (CardIterator.hasNext()) { Card *tmp = CardIterator.next(); if (tmp->getId() == id) { - if (remove) + if (remove) { cards.removeAt(i); + tmp->setZone(0); + } if (position) *position = i; return tmp; @@ -61,8 +63,10 @@ Card *PlayerZone::getCard(int id, bool remove, int *position) if ((id >= cards.size()) || (id < 0)) return NULL; Card *tmp = cards[id]; - if (remove) + if (remove) { cards.removeAt(id); + tmp->setZone(0); + } if (position) *position = id; return tmp; @@ -78,6 +82,7 @@ void PlayerZone::insertCard(Card *card, int x, int y) card->setCoords(0, 0); cards.insert(x, card); } + card->setZone(this); } void PlayerZone::clear() diff --git a/servatrice/src/playerzone.h b/servatrice/src/playerzone.h index 6f8b6a67..2c418420 100644 --- a/servatrice/src/playerzone.h +++ b/servatrice/src/playerzone.h @@ -24,6 +24,7 @@ #include class Card; +class ServerSocket; class AbstractRNG; class PlayerZone { @@ -38,12 +39,13 @@ public: // list index, whereas cards in any other zone are referenced by their ids. enum ZoneType { PrivateZone, PublicZone, HiddenZone }; private: + ServerSocket *player; QString name; bool has_coords; ZoneType type; int cardsBeingLookedAt; public: - PlayerZone(const QString &_name, bool _has_coords, ZoneType _type); + PlayerZone(ServerSocket *_player, const QString &_name, bool _has_coords, ZoneType _type); ~PlayerZone(); Card *getCard(int id, bool remove, int *position = NULL); @@ -53,6 +55,7 @@ public: bool hasCoords() const { return has_coords; } ZoneType getType() const { return type; } QString getName() const { return name; } + ServerSocket *getPlayer() const { return player; } QList cards; void insertCard(Card *card, int x, int y); diff --git a/servatrice/src/serversocket.cpp b/servatrice/src/serversocket.cpp index 4b877cd4..d6fcf33f 100644 --- a/servatrice/src/serversocket.cpp +++ b/servatrice/src/serversocket.cpp @@ -27,6 +27,7 @@ #include "playerzone.h" #include "counter.h" #include "card.h" +#include "arrow.h" #include "abstractrng.h" #include "chatchannel.h" @@ -89,7 +90,15 @@ ServerSocket::ServerSocket(Server *_server, QObject *parent) << QVariant::Int << QVariant::Int << QVariant::String + << QVariant::Int << QVariant::Int, &ServerSocket::cmdCreateArrow)); + commandHash.insert("delete_arrow", CommandProperties(true, true, true, false, QList() + << QVariant::Int + << QVariant::String + << QVariant::Int + << QVariant::Int + << QVariant::String + << QVariant::Int, &ServerSocket::cmdDeleteArrow)); commandHash.insert("set_card_attr", CommandProperties(true, true, true, false, QList() << QVariant::String << QVariant::Int @@ -137,6 +146,7 @@ ServerSocket::ServerSocket(Server *_server, QObject *parent) ServerSocket::~ServerSocket() { qDebug("ServerSocket destructor"); + clearZones(); // The socket has to be removed from the server's list before it is removed from the game's list // so it will not receive the game update event. server->removePlayer(this); @@ -183,14 +193,14 @@ void ServerSocket::setupZones() // ------------------------------------------------------------------ // Create zones - PlayerZone *deck = new PlayerZone("deck", false, PlayerZone::HiddenZone); + PlayerZone *deck = new PlayerZone(this, "deck", false, PlayerZone::HiddenZone); zones << deck; - PlayerZone *sb = new PlayerZone("sb", false, PlayerZone::HiddenZone); + PlayerZone *sb = new PlayerZone(this, "sb", false, PlayerZone::HiddenZone); zones << sb; - zones << new PlayerZone("table", true, PlayerZone::PublicZone); - zones << new PlayerZone("hand", false, PlayerZone::PrivateZone); - zones << new PlayerZone("grave", false, PlayerZone::PublicZone); - zones << new PlayerZone("rfg", false, PlayerZone::PublicZone); + zones << new PlayerZone(this, "table", true, PlayerZone::PublicZone); + zones << new PlayerZone(this, "hand", false, PlayerZone::PrivateZone); + zones << new PlayerZone(this, "grave", false, PlayerZone::PublicZone); + zones << new PlayerZone(this, "rfg", false, PlayerZone::PublicZone); // ------------------------------------------------------------------ @@ -222,6 +232,10 @@ void ServerSocket::clearZones() while (counterIterator.hasNext()) delete counterIterator.next().value(); counters.clear(); + + for (int i = 0; i < arrows.size(); i++) + delete arrows.at(i); + arrows.clear(); } void ServerSocket::leaveGame() @@ -583,8 +597,47 @@ ReturnMessage::ReturnCode ServerSocket::cmdCreateArrow(const QList &pa Card *targetCard = targetZone->getCard(params[5].toInt(), false); if (!startCard || !targetCard || (startCard == targetCard)) return ReturnMessage::ReturnContextError; + for (int i = 0; i < arrows.size(); ++i) + if ((arrows[i]->getStartCard() == startCard) && (arrows[i]->getTargetCard() == targetCard)) + return ReturnMessage::ReturnContextError; + int color = params[6].toInt(); - emit broadcastEvent(QString("create_arrow|%1|%2|%3|%4|%5|%6") + arrows.append(new Arrow(startCard, targetCard, color)); + emit broadcastEvent(QString("create_arrow|%1|%2|%3|%4|%5|%6|%7") + .arg(startPlayer->getPlayerId()) + .arg(startZone->getName()) + .arg(startCard->getId()) + .arg(targetPlayer->getPlayerId()) + .arg(targetZone->getName()) + .arg(targetCard->getId()) + .arg(color), this + ); + return ReturnMessage::ReturnOk; +} + +ReturnMessage::ReturnCode ServerSocket::cmdDeleteArrow(const QList ¶ms) +{ + ServerSocket *startPlayer = game->getPlayer(params[0].toInt()); + ServerSocket *targetPlayer = game->getPlayer(params[3].toInt()); + if (!startPlayer || !targetPlayer) + return ReturnMessage::ReturnContextError; + PlayerZone *startZone = startPlayer->getZone(params[1].toString()); + PlayerZone *targetZone = targetPlayer->getZone(params[4].toString()); + if (!startZone || !targetZone) + return ReturnMessage::ReturnContextError; + Card *startCard = startZone->getCard(params[2].toInt(), false); + Card *targetCard = targetZone->getCard(params[5].toInt(), false); + + Arrow *arrow = 0; + for (int i = 0; i < arrows.size(); ++i) + if ((arrows[i]->getStartCard() == startCard) && (arrows[i]->getTargetCard() == targetCard)) { + arrow = arrows.takeAt(i); + break; + } + if (!arrow) + return ReturnMessage::ReturnContextError; + + emit broadcastEvent(QString("delete_arrow|%1|%2|%3|%4|%5|%6") .arg(startPlayer->getPlayerId()) .arg(startZone->getName()) .arg(startCard->getId()) @@ -810,6 +863,22 @@ ReturnMessage::ReturnCode ServerSocket::cmdSetActivePhase(const QList return ReturnMessage::ReturnOk; } +QStringList ServerSocket::listArrowsHelper(ServerSocket *player) +{ + QStringList result; + const QList &arrowList = player->getArrows(); + for (int i = 0; i < arrowList.size(); ++i) { + Card *startCard = arrowList[i]->getStartCard(); + Card *targetCard = arrowList[i]->getTargetCard(); + PlayerZone *startZone = startCard->getZone(); + PlayerZone *targetZone = targetCard->getZone(); + ServerSocket *startPlayer = startZone->getPlayer(); + ServerSocket *targetPlayer = targetZone->getPlayer(); + result << QString("%1|%2|%3|%4|%5|%6|%7").arg(startPlayer->getPlayerName()).arg(startZone->getName()).arg(startCard->getId()).arg(targetPlayer->getPlayerName()).arg(targetZone->getName()).arg(targetCard->getId()).arg(arrowList[i]->getColor()); + } + return result; +} + ReturnMessage::ReturnCode ServerSocket::cmdDumpAll(const QList &/*params*/) { remsg->sendList(listPlayersHelper(), "list_players"); @@ -825,6 +894,7 @@ ReturnMessage::ReturnCode ServerSocket::cmdDumpAll(const QList &/*para remsg->sendList(dumpZoneHelper(players[i], zones[j], -1), "dump_zone"); remsg->sendList(listCountersHelper(players[i]), "list_counters"); + remsg->sendList(listArrowsHelper(players[i]), "list_arrows"); } } remsg->send(ReturnMessage::ReturnOk); diff --git a/servatrice/src/serversocket.h b/servatrice/src/serversocket.h index 36ef233e..d2fefed5 100644 --- a/servatrice/src/serversocket.h +++ b/servatrice/src/serversocket.h @@ -30,6 +30,7 @@ class Server; class ServerGame; class PlayerZone; class Counter; +class Arrow; enum PlayerStatusEnum { StatusNormal, StatusSubmitDeck, StatusReadyStart, StatusPlaying }; @@ -70,6 +71,7 @@ private: QStringList listZonesHelper(ServerSocket *player); QStringList dumpZoneHelper(ServerSocket *player, PlayerZone *zone, int numberCards); QStringList listCountersHelper(ServerSocket *player); + QStringList listArrowsHelper(ServerSocket *player); ReturnMessage::ReturnCode cmdPing(const QList ¶ms); ReturnMessage::ReturnCode cmdLogin(const QList ¶ms); @@ -91,6 +93,7 @@ private: ReturnMessage::ReturnCode cmdMoveCard(const QList ¶ms); ReturnMessage::ReturnCode cmdCreateToken(const QList ¶ms); ReturnMessage::ReturnCode cmdCreateArrow(const QList ¶ms); + ReturnMessage::ReturnCode cmdDeleteArrow(const QList ¶ms); ReturnMessage::ReturnCode cmdSetCardAttr(const QList ¶ms); ReturnMessage::ReturnCode cmdIncCounter(const QList ¶ms); ReturnMessage::ReturnCode cmdAddCounter(const QList ¶ms); @@ -112,6 +115,7 @@ private: QList SideboardList; QList zones; QMap counters; + QList arrows; int playerId; QString playerName; bool spectator; @@ -145,6 +149,7 @@ public: bool getAcceptsChatChannelListChanges() const { return acceptsChatChannelListChanges; } const QList &getZones() const { return zones; } const QMap &getCounters() const { return counters; } + const QList &getArrows() const { return arrows; } void setupZones(); };