diff --git a/cockatrice/cockatrice.pro b/cockatrice/cockatrice.pro index e3fe6d46..22a16227 100644 --- a/cockatrice/cockatrice.pro +++ b/cockatrice/cockatrice.pro @@ -13,8 +13,6 @@ HEADERS += src/counter.h \ src/gamesmodel.h \ src/client.h \ src/window_main.h \ - src/servergame.h \ - src/servereventdata.h \ src/zonelist.h \ src/cardzone.h \ src/player.h \ @@ -30,7 +28,6 @@ HEADERS += src/counter.h \ src/dlg_startgame.h \ src/cardinfowidget.h \ src/messagelogwidget.h \ - src/serverzonecard.h \ src/zoneviewzone.h \ src/zoneviewwidget.h \ src/pilezone.h \ @@ -53,7 +50,6 @@ SOURCES += src/counter.cpp \ src/client.cpp \ src/main.cpp \ src/window_main.cpp \ - src/servereventdata.cpp \ src/gamesmodel.cpp \ src/player.cpp \ src/cardzone.cpp \ diff --git a/cockatrice/src/chatwidget.cpp b/cockatrice/src/chatwidget.cpp index 75d6bd74..ed952d93 100644 --- a/cockatrice/src/chatwidget.cpp +++ b/cockatrice/src/chatwidget.cpp @@ -212,8 +212,7 @@ void ChatWidget::chatEvent(const ChatEventData &data) void ChatWidget::joinChannel(const QString &channelName) { - PendingCommand *pc = client->chatJoinChannel(channelName); - pc->setExtraData(channelName); + PendingCommand_ChatJoinChannel *pc = client->chatJoinChannel(channelName); connect(pc, SIGNAL(finished(ServerResponse)), this, SLOT(joinFinished(ServerResponse))); } @@ -234,8 +233,8 @@ void ChatWidget::joinFinished(ServerResponse resp) if (resp != RespOk) return; - PendingCommand *pc = qobject_cast(sender()); - QString channelName = pc->getExtraData(); + PendingCommand_ChatJoinChannel *pc = qobject_cast(sender()); + QString channelName = pc->getChannelName(); ChannelWidget *cw = new ChannelWidget(client, channelName); tab->addTab(cw, channelName); } diff --git a/cockatrice/src/chatwidget.h b/cockatrice/src/chatwidget.h index c4075f6f..3d959636 100644 --- a/cockatrice/src/chatwidget.h +++ b/cockatrice/src/chatwidget.h @@ -2,7 +2,6 @@ #define CHATWIDGET_H #include -#include "servereventdata.h" #include "client.h" class QListWidget; diff --git a/cockatrice/src/client.cpp b/cockatrice/src/client.cpp index c16b68e3..08a5247a 100644 --- a/cockatrice/src/client.cpp +++ b/cockatrice/src/client.cpp @@ -1,17 +1,74 @@ #include #include "client.h" -PendingCommand::PendingCommand(const QString &_cmd, int _msgid, QObject *parent) - : QObject(parent), cmd(_cmd), msgid(_msgid), time(0) +// Message structure for server events: +// {"private","public"}|PlayerId|PlayerName|EventType|EventData + +QHash ServerEventData::eventHash; + +ServerEventData::ServerEventData(const QString &line) +{ + if (eventHash.isEmpty()) { + eventHash.insert("player_id", eventPlayerId); + eventHash.insert("say", eventSay); + eventHash.insert("name", eventName); + eventHash.insert("join", eventJoin); + eventHash.insert("leave", eventLeave); + eventHash.insert("ready_start", eventReadyStart); + eventHash.insert("setup_zones", eventSetupZones); + eventHash.insert("game_start", eventGameStart); + eventHash.insert("shuffle", eventShuffle); + eventHash.insert("roll_die", eventRollDie); + eventHash.insert("draw", eventDraw); + eventHash.insert("move_card", eventMoveCard); + eventHash.insert("create_token", eventCreateToken); + eventHash.insert("set_card_attr", eventSetCardAttr); + eventHash.insert("add_counter", eventAddCounter); + eventHash.insert("set_counter", eventSetCounter); + eventHash.insert("del_counter", eventDelCounter); + eventHash.insert("set_active_player", eventSetActivePlayer); + eventHash.insert("set_active_phase", eventSetActivePhase); + eventHash.insert("dump_zone", eventDumpZone); + eventHash.insert("stop_dump_zone", eventStopDumpZone); + } + + QStringList values = line.split('|'); + + IsPublic = !values.takeFirst().compare("public"); + PlayerId = values.takeFirst().toInt(); + PlayerName = values.takeFirst(); + EventType = eventHash.value(values.takeFirst(), eventInvalid); + EventData = values; +} + +QHash ChatEventData::eventHash; + +ChatEventData::ChatEventData(const QString &line) +{ + if (eventHash.isEmpty()) { + eventHash.insert("list_channels", eventChatListChannels); + eventHash.insert("join_channel", eventChatJoinChannel); + eventHash.insert("list_players", eventChatListPlayers); + eventHash.insert("leave_channel", eventChatLeaveChannel); + eventHash.insert("say", eventChatSay); + eventHash.insert("server_message", eventChatServerMessage); + } + + QStringList values = line.split('|'); + values.removeFirst(); + eventType = eventHash.value(values.takeFirst(), eventChatInvalid); + eventData = values; +} + +PendingCommand::PendingCommand(int _msgid) + : QObject(), msgid(_msgid), time(0) { } -void PendingCommand::responseReceived(int _msgid, ServerResponse _resp) +void PendingCommand::responseReceived(ServerResponse resp) { - if (_msgid == msgid) { - emit finished(_resp); - deleteLater(); - } + emit finished(resp); + deleteLater(); } void PendingCommand::checkTimeout() @@ -20,6 +77,54 @@ void PendingCommand::checkTimeout() emit timeout(); } +void PendingCommand_ListPlayers::responseReceived(ServerResponse resp) +{ + if (resp == RespOk) + emit playerListReceived(playerList); + PendingCommand::responseReceived(resp); +} + +void PendingCommand_ListPlayers::addPlayer(const ServerPlayer &player) +{ + playerList.append(player); +} + +void PendingCommand_ListZones::responseReceived(ServerResponse resp) +{ + if (resp == RespOk) + emit zoneListReceived(zoneList); + PendingCommand::responseReceived(resp); +} + +void PendingCommand_ListZones::addZone(const ServerZone &zone) +{ + zoneList.append(zone); +} + +void PendingCommand_DumpZone::responseReceived(ServerResponse resp) +{ + if (resp == RespOk) + emit cardListReceived(cardList); + PendingCommand::responseReceived(resp); +} + +void PendingCommand_DumpZone::addCard(const ServerZoneCard &card) +{ + cardList.append(card); +} + +void PendingCommand_ListCounters::responseReceived(ServerResponse resp) +{ + if (resp == RespOk) + emit counterListReceived(counterList); + PendingCommand::responseReceived(resp); +} + +void PendingCommand_ListCounters::addCounter(const ServerCounter &counter) +{ + counterList.append(counter); +} + Client::Client(QObject *parent) : QObject(parent), status(StatusDisconnected), MsgId(0) { @@ -59,7 +164,7 @@ void Client::slotConnected() void Client::removePendingCommand() { - PendingCommands.removeAt(PendingCommands.indexOf(static_cast(sender()))); + pendingCommands.remove(static_cast(sender())->getMsgId()); } void Client::loginResponse(ServerResponse response) @@ -114,14 +219,16 @@ void Client::readLine() emit chatEvent(ChatEventData(line)); } else if (prefix == "resp") { if (values.size() != 2) { - // XXX + qDebug("Client::parseCommand: Invalid response"); + continue; } bool ok; int msgid = values.takeFirst().toInt(&ok); - if (!ok) { - // XXX + PendingCommand *pc = pendingCommands.value(msgid, 0); + if (!ok || !pc) { + qDebug("Client::parseCommand: Invalid msgid"); + continue; } - ServerResponse resp; if (values[0] == "ok") resp = RespOk; @@ -129,14 +236,14 @@ void Client::readLine() resp = RespPassword; else resp = RespErr; - emit responseReceived(msgid, resp); + pc->responseReceived(resp); } else if (prefix == "list_games") { if (values.size() != 8) - return; + continue; emit gameListEvent(new ServerGame(values[0].toInt(), values[5], values[1], values[2].toInt(), values[3].toInt(), values[4].toInt(), values[6].toInt(), values[7].toInt())); } else if (prefix == "welcome") { if (values.size() != 2) { - emit protocolVersionMismatch(); + emit protocolError(); disconnectFromServer(); } else if (values[0].toInt() != protocolVersion) { emit protocolVersionMismatch(); @@ -146,40 +253,45 @@ void Client::readLine() setStatus(StatusLoggingIn); login(playerName, password); } - } else if ((prefix == "list_players") || (prefix == "list_counters") || (prefix == "list_zones") || (prefix == "dump_zone")) { + } else if (prefix == "list_players") { + if (values.size() != 4) { + emit protocolError(); + continue; + } int cmdid = values.takeFirst().toInt(); - if (values[0] == ".") { - QListIterator i(msgbuf); - QList playerlist; - QList zonelist; - QList zonedump; - while (i.hasNext()) { - QStringList val = i.next(); - - // XXX Parametergültigkeit überprüfen - if (prefix == "list_players") - playerlist << new ServerPlayer(val[0].toInt(), val[1], val[2].toInt()); - else if (prefix == "list_counters") - { } - else if (prefix == "list_zones") - zonelist << new ServerZone(val[0], val[1] == "1", val[2] == "1", val[3].toInt()); - else if (prefix == "dump_zone") - zonedump << new ServerZoneCard(val[0].toInt(), val[1], val[2].toInt(), val[3].toInt(), val[4].toInt(), val[5] == "1", val[6]); - } - if (prefix == "list_players") - emit playerListReceived(playerlist); - else if (prefix == "list_counters") - { } - else if (prefix == "list_zones") - emit zoneListReceived(cmdid, zonelist); - else if (prefix == "dump_zone") - emit zoneDumpReceived(cmdid, zonedump); - msgbuf.clear(); - } else - msgbuf << values; - } else { - // XXX - } + PendingCommand_ListPlayers *pc = qobject_cast(pendingCommands.value(cmdid, 0)); + if (!pc) { + emit protocolError(); + continue; + } + pc->addPlayer(ServerPlayer(values[0].toInt(), values[1], values[2].toInt())); + } else if (prefix == "dump_zone") { + if (values.size() != 9) { + emit protocolError(); + continue; + } + int cmdid = values.takeFirst().toInt(); + PendingCommand_DumpZone *pc = qobject_cast(pendingCommands.value(cmdid, 0)); + if (!pc) { + emit protocolError(); + continue; + } + pc->addCard(ServerZoneCard(values[0].toInt(), values[1], values[2].toInt(), values[3].toInt(), values[4].toInt(), values[5] == "1", values[6] == "1", values[7])); + } else if (prefix == "list_zones") { + if (values.size() != 5) { + emit protocolError(); + continue; + } + int cmdid = values.takeFirst().toInt(); + PendingCommand_ListZones *pc = qobject_cast(pendingCommands.value(cmdid, 0)); + if (!pc) { + emit protocolError(); + continue; + } + pc->addZone(ServerZone(values[0], values[1] == "1", values[2] == "1", values[3].toInt())); + } else if (prefix == "list_counters") { + } else + emit protocolError(); } } @@ -200,12 +312,16 @@ void Client::msg(const QString &s) stream.flush(); } -PendingCommand *Client::cmd(const QString &s) +PendingCommand *Client::cmd(const QString &s, PendingCommand *_pc) { msg(QString("%1|%2").arg(++MsgId).arg(s)); - PendingCommand *pc = new PendingCommand(s, MsgId, this); - PendingCommands << pc; - connect(this, SIGNAL(responseReceived(int, ServerResponse)), pc, SLOT(responseReceived(int, ServerResponse))); + PendingCommand *pc; + if (_pc) { + pc = _pc; + pc->setMsgId(MsgId); + } else + pc = new PendingCommand(MsgId); + pendingCommands.insert(MsgId, pc); connect(pc, SIGNAL(finished(ServerResponse)), this, SLOT(removePendingCommand())); connect(pc, SIGNAL(timeout()), this, SLOT(timeout())); connect(timer, SIGNAL(timeout()), pc, SLOT(checkTimeout())); @@ -226,9 +342,10 @@ void Client::disconnectFromServer() { timer->stop(); - for (int i = 0; i < PendingCommands.size(); i++) - delete PendingCommands[i]; - PendingCommands.clear(); + QList pc = pendingCommands.values(); + for (int i = 0; i < pc.size(); i++) + delete pc[i]; + pendingCommands.clear(); setStatus(StatusDisconnected); socket->close(); @@ -244,9 +361,9 @@ PendingCommand *Client::chatListChannels() return cmd("chat_list_channels"); } -PendingCommand *Client::chatJoinChannel(const QString &name) +PendingCommand_ChatJoinChannel *Client::chatJoinChannel(const QString &name) { - return cmd(QString("chat_join_channel|%1").arg(name)); + return static_cast(cmd(QString("chat_join_channel|%1").arg(name), new PendingCommand_ChatJoinChannel(name))); } PendingCommand *Client::chatLeaveChannel(const QString &name) @@ -264,9 +381,9 @@ PendingCommand *Client::listGames() return cmd("list_games"); } -PendingCommand *Client::listPlayers() +PendingCommand_ListPlayers *Client::listPlayers() { - return cmd("list_players"); + return static_cast(cmd("list_players", new PendingCommand_ListPlayers)); } PendingCommand *Client::createGame(const QString &description, const QString &password, unsigned int maxPlayers, bool spectatorsAllowed) @@ -368,6 +485,13 @@ PendingCommand *Client::delCounter(const QString &counter) return cmd(QString("del_counter|%1").arg(counter)); } +PendingCommand_ListCounters *Client::listCounters(int playerId) +{ + PendingCommand_ListCounters *pc = new PendingCommand_ListCounters(playerId); + cmd(QString("list_counters|%1").arg(playerId), pc); + return pc; +} + PendingCommand *Client::nextTurn() { return cmd(QString("next_turn")); @@ -378,9 +502,18 @@ PendingCommand *Client::setActivePhase(int phase) return cmd(QString("set_active_phase|%1").arg(phase)); } -PendingCommand *Client::dumpZone(int player, const QString &zone, int numberCards) +PendingCommand_ListZones *Client::listZones(int playerId) { - return cmd(QString("dump_zone|%1|%2|%3").arg(player).arg(zone).arg(numberCards)); + PendingCommand_ListZones *pc = new PendingCommand_ListZones(playerId); + cmd(QString("list_zones|%1").arg(playerId), pc); + return pc; +} + +PendingCommand_DumpZone *Client::dumpZone(int player, const QString &zone, int numberCards) +{ + PendingCommand_DumpZone *pc = new PendingCommand_DumpZone(player, zone, numberCards); + cmd(QString("dump_zone|%1|%2|%3").arg(player).arg(zone).arg(numberCards), pc); + return pc; } PendingCommand *Client::stopDumpZone(int player, const QString &zone) diff --git a/cockatrice/src/client.h b/cockatrice/src/client.h index 876669f8..869e294c 100644 --- a/cockatrice/src/client.h +++ b/cockatrice/src/client.h @@ -1,13 +1,10 @@ #ifndef CLIENT_H #define CLIENT_H -#include "servereventdata.h" -#include "servergame.h" -#include "serverplayer.h" -#include "serverzone.h" -#include "serverzonecard.h" #include #include +#include +#include class QTimer; @@ -27,25 +24,242 @@ enum ServerResponse { RespErr }; +enum ServerEventType { + eventInvalid, + eventPlayerId, + eventSay, + eventName, + eventJoin, + eventLeave, + eventReadyStart, + eventSetupZones, + eventGameStart, + eventShuffle, + eventRollDie, + eventDraw, + eventMoveCard, + eventCreateToken, + eventSetCardAttr, + eventAddCounter, + eventSetCounter, + eventDelCounter, + eventSetActivePlayer, + eventSetActivePhase, + eventDumpZone, + eventStopDumpZone +}; + +class ServerEventData { +private: + static QHash eventHash; + + bool IsPublic; + int PlayerId; + QString PlayerName; + ServerEventType EventType; + QStringList EventData; +public: + ServerEventData(const QString &line); + bool getPublic() const { return IsPublic; } + int getPlayerId() const { return PlayerId; } + const QString &getPlayerName() const { return PlayerName; } + ServerEventType getEventType() const { return EventType; } + const QStringList &getEventData() const { return EventData; } +}; + +enum ChatEventType { + eventChatInvalid, + eventChatListChannels, + eventChatJoinChannel, + eventChatListPlayers, + eventChatLeaveChannel, + eventChatSay, + eventChatServerMessage +}; + +class ChatEventData { +private: + static QHash eventHash; + + ChatEventType eventType; + QStringList eventData; +public: + ChatEventData(const QString &line); + ChatEventType getEventType() const { return eventType; } + const QStringList &getEventData() const { return eventData; } +}; + +class ServerGame { +private: + int gameId; + QString creator; + QString description; + bool hasPassword; + unsigned char playerCount; + unsigned char maxPlayers; + bool spectatorsAllowed; + unsigned int spectatorsCount; +public: + ServerGame(int _gameId, const QString &_creator, const QString &_description, bool _hasPassword, unsigned char _playerCount, unsigned char _maxPlayers, bool _spectatorsAllowed, unsigned int _spectatorsCount) + : gameId(_gameId), creator(_creator), description(_description), hasPassword(_hasPassword), playerCount(_playerCount), maxPlayers(_maxPlayers), spectatorsAllowed(_spectatorsAllowed), spectatorsCount(_spectatorsCount) { } + int getGameId() const { return gameId; } + QString getCreator() const { return creator; } + QString getDescription() const { return description; } + bool getHasPassword() const { return hasPassword; } + unsigned char getPlayerCount() const { return playerCount; } + unsigned char getMaxPlayers() const { return maxPlayers; } + bool getSpectatorsAllowed() const { return spectatorsAllowed; } + unsigned int getSpectatorsCount() const { return spectatorsCount; } +}; + +class ServerPlayer { +private: + int PlayerId; + QString name; + bool local; +public: + ServerPlayer(int _PlayerId, const QString &_name, bool _local) + : PlayerId(_PlayerId), name(_name), local(_local) { } + int getPlayerId() const { return PlayerId; } + QString getName() const { return name; } + bool getLocal() const { return local; } +}; + +class ServerZoneCard { +private: + int id; + QString name; + int x, y; + int counters; + bool tapped; + bool attacking; + QString annotation; +public: + ServerZoneCard(int _id, const QString &_name, int _x, int _y, int _counters, bool _tapped, bool _attacking, const QString &_annotation) + : id(_id), name(_name), x(_x), y(_y), counters(_counters), tapped(_tapped), attacking(_attacking), annotation(_annotation) { } + int getId() const { return id; } + QString getName() const { return name; } + int getX() const { return x; } + int getY() const { return y; } + int getCounters() const { return counters; } + bool getTapped() const { return tapped; } + bool getAttacking() const { return attacking; } + QString getAnnotation() const { return annotation; } +}; + +class ServerZone { +private: + QString name; + bool isPublic; + bool hasCoords; + int cardCount; +public: + ServerZone(const QString &_name, bool _isPublic, bool _hasCoords, int _cardCount) + : name(_name), isPublic(_isPublic), hasCoords(_hasCoords), cardCount(_cardCount) { } + QString getName() const { return name; } + bool getPublic() const { return isPublic; } + bool getHasCoords() const { return hasCoords; } + int getCardCount() const { return cardCount; } +}; + +class ServerCounter { +private: + QString name; + int color; + int count; +public: + ServerCounter(const QString &_name, int _color, int _count) + : name(_name), color(_color), count(_count) { } + QString getName() const { return name; } + int getColor() const { return color; } + int getCount() const { return count; } +}; + class PendingCommand : public QObject { Q_OBJECT private: - QString cmd; int msgid; int time; - QString extraData; signals: void finished(ServerResponse resp); void timeout(); public slots: - void responseReceived(int _msgid, ServerResponse _resp); + virtual void responseReceived(ServerResponse resp); void checkTimeout(); public: + PendingCommand(int _msgid = -1); int getMsgId() const { return msgid; } - QString getCmd() const { return cmd; } - const QString &getExtraData() const { return extraData; } - void setExtraData(const QString &_extraData) { extraData = _extraData; } - PendingCommand(const QString &_cmd, int _msgid, QObject *parent = 0); + void setMsgId(int _msgId) { msgid = _msgId; } +}; + +class PendingCommand_ChatJoinChannel : public PendingCommand { + Q_OBJECT +private: + QString channelName; +public: + PendingCommand_ChatJoinChannel(const QString &_channelName) + : channelName(_channelName) { } + const QString &getChannelName() const { return channelName; } +}; + +class PendingCommand_ListPlayers : public PendingCommand { + Q_OBJECT +private: + QList playerList; +signals: + void playerListReceived(QList _playerList); +public: + void responseReceived(ServerResponse resp); + void addPlayer(const ServerPlayer &player); +}; + +class PendingCommand_ListZones : public PendingCommand { + Q_OBJECT +private: + QList zoneList; + int playerId; +signals: + void zoneListReceived(QList _zoneList); +public: + PendingCommand_ListZones(int _playerId) + : playerId(_playerId) { } + void responseReceived(ServerResponse resp); + void addZone(const ServerZone &zone); + int getPlayerId() const { return playerId; } +}; + +class PendingCommand_DumpZone : public PendingCommand { + Q_OBJECT +private: + QList cardList; + int playerId; + QString zoneName; + int numberCards; +signals: + void cardListReceived(QList _cardList); +public: + PendingCommand_DumpZone(int _playerId, const QString &_zoneName, int _numberCards) + : playerId(_playerId), zoneName(_zoneName), numberCards(_numberCards) { } + void responseReceived(ServerResponse resp); + void addCard(const ServerZoneCard &card); + int getPlayerId() const { return playerId; } + QString getZoneName() const { return zoneName; } + int getNumberCards() const { return numberCards; } +}; + +class PendingCommand_ListCounters : public PendingCommand { + Q_OBJECT +private: + QList counterList; + int playerId; +signals: + void counterListReceived(QList _counterList); +public: + PendingCommand_ListCounters(int _playerId) + : playerId(_playerId) { } + void responseReceived(ServerResponse resp); + void addCounter(const ServerCounter &counter); + int getPlayerId() const { return playerId; } }; class Client : public QObject { @@ -54,10 +268,6 @@ signals: void statusChanged(ProtocolStatus _status); void welcomeMsgReceived(QString welcomeMsg); void gameListEvent(ServerGame *game); - void playerListReceived(QList players); - void zoneListReceived(int commandId, QList zones); - void zoneDumpReceived(int commandId, QList cards); - void responseReceived(int msgid, ServerResponse resp); void playerIdReceived(int id, QString name); void gameEvent(const ServerEventData &msg); void chatEvent(const ChatEventData &msg); @@ -65,6 +275,7 @@ signals: void logSocketError(const QString &errorString); void serverError(ServerResponse resp); void protocolVersionMismatch(); + void protocolError(); private slots: void slotConnected(); void readLine(); @@ -78,14 +289,13 @@ private slots: private: static const int protocolVersion = 1; QTimer *timer; - QList PendingCommands; + QMap pendingCommands; QTcpSocket *socket; ProtocolStatus status; - QList msgbuf; QString playerName, password; unsigned int MsgId; void msg(const QString &s); - PendingCommand *cmd(const QString &s); + PendingCommand *cmd(const QString &s, PendingCommand *_pc = 0); void setStatus(const ProtocolStatus _status); public: Client(QObject *parent = 0); @@ -97,11 +307,11 @@ public: void disconnectFromServer(); public slots: PendingCommand *chatListChannels(); - PendingCommand *chatJoinChannel(const QString &name); + PendingCommand_ChatJoinChannel *chatJoinChannel(const QString &name); PendingCommand *chatLeaveChannel(const QString &name); PendingCommand *chatSay(const QString &name, const QString &s); PendingCommand *listGames(); - PendingCommand *listPlayers(); + PendingCommand_ListPlayers *listPlayers(); PendingCommand *createGame(const QString &description, const QString &password, unsigned int maxPlayers, bool spectatorsAllowed); PendingCommand *joinGame(int gameId, const QString &password, bool spectator); PendingCommand *leaveGame(); @@ -119,9 +329,11 @@ public slots: PendingCommand *addCounter(const QString &counter, QColor color, int value); PendingCommand *setCounter(const QString &counter, int value); PendingCommand *delCounter(const QString &counter); + PendingCommand_ListCounters *listCounters(int playerId); PendingCommand *nextTurn(); PendingCommand *setActivePhase(int phase); - PendingCommand *dumpZone(int player, const QString &zone, int numberCards); + PendingCommand_ListZones *listZones(int playerId); + PendingCommand_DumpZone *dumpZone(int player, const QString &zone, int numberCards); PendingCommand *stopDumpZone(int player, const QString &zone); void submitDeck(const QStringList &deck); }; diff --git a/cockatrice/src/game.cpp b/cockatrice/src/game.cpp index 0461a8ab..a1260ed8 100644 --- a/cockatrice/src/game.cpp +++ b/cockatrice/src/game.cpp @@ -3,9 +3,7 @@ #include #include #include -#include "serverplayer.h" #include "game.h" -#include "servereventdata.h" #include "client.h" #include "tablezone.h" #include "handzone.h" @@ -18,7 +16,6 @@ Game::Game(CardDatabase *_db, Client *_client, GameScene *_scene, QMenuBar *menu : QObject(parent), db(_db), client(_client), scene(_scene), started(false), currentPhase(-1) { connect(client, SIGNAL(gameEvent(const ServerEventData &)), this, SLOT(gameEvent(const ServerEventData &))); - connect(client, SIGNAL(playerListReceived(QList)), this, SLOT(playerListReceived(QList))); aNextPhase = new QAction(this); connect(aNextPhase, SIGNAL(triggered()), this, SLOT(actNextPhase())); @@ -82,7 +79,8 @@ Game::Game(CardDatabase *_db, Client *_client, GameScene *_scene, QMenuBar *menu retranslateUi(); - client->listPlayers(); + PendingCommand_ListPlayers *pc = client->listPlayers(); + connect(pc, SIGNAL(playerListReceived(QList)), this, SLOT(playerListReceived(QList))); } Game::~Game() @@ -143,18 +141,12 @@ Player *Game::addPlayer(int playerId, const QString &playerName, bool local) return newPlayer; } -void Game::playerListReceived(QList playerList) +void Game::playerListReceived(QList playerList) { - QListIterator i(playerList); QStringList nameList; - while (i.hasNext()) { - ServerPlayer *temp = i.next(); - nameList << temp->getName(); - int id = temp->getPlayerId(); - - addPlayer(id, temp->getName(), temp->getLocal()); - - delete temp; + for (int i = 0; i < playerList.size(); ++i) { + nameList << playerList[i].getName(); + addPlayer(playerList[i].getPlayerId(), playerList[i].getName(), playerList[i].getLocal()); } emit logPlayerListReceived(nameList); restartGameDialog(); diff --git a/cockatrice/src/game.h b/cockatrice/src/game.h index 2e02c149..ee53d047 100644 --- a/cockatrice/src/game.h +++ b/cockatrice/src/game.h @@ -4,11 +4,10 @@ #include #include #include "playerlist.h" +#include "client.h" -class ServerPlayer; class GameScene; class Player; -class Client; class ServerEventData; class CardDatabase; class DlgStartGame; @@ -56,7 +55,7 @@ private slots: void actMoveToExile(CardItem *card); void gameEvent(const ServerEventData &msg); - void playerListReceived(QList playerList); + void playerListReceived(QList playerList); void readyStart(); signals: void submitDecklist(); diff --git a/cockatrice/src/gameselector.h b/cockatrice/src/gameselector.h index 6f5d1cb8..ccca733d 100644 --- a/cockatrice/src/gameselector.h +++ b/cockatrice/src/gameselector.h @@ -3,7 +3,6 @@ #include #include "gamesmodel.h" -#include "servergame.h" #include "client.h" class QPushButton; diff --git a/cockatrice/src/gamesmodel.cpp b/cockatrice/src/gamesmodel.cpp index a9cc6ff0..534c026f 100644 --- a/cockatrice/src/gamesmodel.cpp +++ b/cockatrice/src/gamesmodel.cpp @@ -1,5 +1,5 @@ #include "gamesmodel.h" -#include "servergame.h" +#include "client.h" GamesModel::~GamesModel() { diff --git a/cockatrice/src/gamesmodel.h b/cockatrice/src/gamesmodel.h index ef352fb9..57c603db 100644 --- a/cockatrice/src/gamesmodel.h +++ b/cockatrice/src/gamesmodel.h @@ -3,7 +3,8 @@ #include #include -#include "servergame.h" + +class ServerGame; class GamesModel : public QAbstractTableModel { Q_OBJECT diff --git a/cockatrice/src/messagelogwidget.cpp b/cockatrice/src/messagelogwidget.cpp index 95a75963..29bd5daa 100644 --- a/cockatrice/src/messagelogwidget.cpp +++ b/cockatrice/src/messagelogwidget.cpp @@ -45,6 +45,11 @@ void MessageLogWidget::logProtocolVersionMismatch() append(tr("Protocol version mismatch.")); } +void MessageLogWidget::logProtocolError() +{ + append(tr("Protocol error.")); +} + void MessageLogWidget::logPlayerListReceived(QStringList players) { append("---"); diff --git a/cockatrice/src/messagelogwidget.h b/cockatrice/src/messagelogwidget.h index 9f9e9b15..d3c17b63 100644 --- a/cockatrice/src/messagelogwidget.h +++ b/cockatrice/src/messagelogwidget.h @@ -22,6 +22,7 @@ public slots: void logSocketError(const QString &errorString); void logServerError(ServerResponse response); void logProtocolVersionMismatch(); + void logProtocolError(); private slots: void logPlayerListReceived(QStringList players); void logJoin(Player *player); diff --git a/cockatrice/src/player.h b/cockatrice/src/player.h index e41f30a0..622d718d 100644 --- a/cockatrice/src/player.h +++ b/cockatrice/src/player.h @@ -4,7 +4,6 @@ #include #include #include "zonelist.h" -#include "servereventdata.h" class Client; class CardDatabase; @@ -15,6 +14,7 @@ class Game; class Counter; class TableZone; class HandZone; +class ServerEventData; class Player : public QObject, public QGraphicsItem { Q_OBJECT diff --git a/cockatrice/src/servereventdata.cpp b/cockatrice/src/servereventdata.cpp deleted file mode 100644 index dbdb32a3..00000000 --- a/cockatrice/src/servereventdata.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "servereventdata.h" - -// Message structure for server events: -// {"private","public"}|PlayerId|PlayerName|EventType|EventData - -QHash ServerEventData::eventHash; - -ServerEventData::ServerEventData(const QString &line) -{ - if (eventHash.isEmpty()) { - eventHash.insert("player_id", eventPlayerId); - eventHash.insert("say", eventSay); - eventHash.insert("name", eventName); - eventHash.insert("join", eventJoin); - eventHash.insert("leave", eventLeave); - eventHash.insert("ready_start", eventReadyStart); - eventHash.insert("setup_zones", eventSetupZones); - eventHash.insert("game_start", eventGameStart); - eventHash.insert("shuffle", eventShuffle); - eventHash.insert("roll_die", eventRollDie); - eventHash.insert("draw", eventDraw); - eventHash.insert("move_card", eventMoveCard); - eventHash.insert("create_token", eventCreateToken); - eventHash.insert("set_card_attr", eventSetCardAttr); - eventHash.insert("add_counter", eventAddCounter); - eventHash.insert("set_counter", eventSetCounter); - eventHash.insert("del_counter", eventDelCounter); - eventHash.insert("set_active_player", eventSetActivePlayer); - eventHash.insert("set_active_phase", eventSetActivePhase); - eventHash.insert("dump_zone", eventDumpZone); - eventHash.insert("stop_dump_zone", eventStopDumpZone); - } - - QStringList values = line.split('|'); - - IsPublic = !values.takeFirst().compare("public"); - PlayerId = values.takeFirst().toInt(); - PlayerName = values.takeFirst(); - EventType = eventHash.value(values.takeFirst(), eventInvalid); - EventData = values; -} - -QHash ChatEventData::eventHash; - -ChatEventData::ChatEventData(const QString &line) -{ - if (eventHash.isEmpty()) { - eventHash.insert("list_channels", eventChatListChannels); - eventHash.insert("join_channel", eventChatJoinChannel); - eventHash.insert("list_players", eventChatListPlayers); - eventHash.insert("leave_channel", eventChatLeaveChannel); - eventHash.insert("say", eventChatSay); - eventHash.insert("server_message", eventChatServerMessage); - } - - QStringList values = line.split('|'); - values.removeFirst(); - eventType = eventHash.value(values.takeFirst(), eventChatInvalid); - eventData = values; -} diff --git a/cockatrice/src/servereventdata.h b/cockatrice/src/servereventdata.h deleted file mode 100644 index f9fdbe7a..00000000 --- a/cockatrice/src/servereventdata.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef SERVEREVENTDATA_H -#define SERVEREVENTDATA_H - -#include -#include - -enum ServerEventType { - eventInvalid, - eventPlayerId, - eventSay, - eventName, - eventJoin, - eventLeave, - eventReadyStart, - eventSetupZones, - eventGameStart, - eventShuffle, - eventRollDie, - eventDraw, - eventMoveCard, - eventCreateToken, - eventSetCardAttr, - eventAddCounter, - eventSetCounter, - eventDelCounter, - eventSetActivePlayer, - eventSetActivePhase, - eventDumpZone, - eventStopDumpZone -}; - -class ServerEventData { -private: - static QHash eventHash; - - bool IsPublic; - int PlayerId; - QString PlayerName; - ServerEventType EventType; - QStringList EventData; -public: - ServerEventData(const QString &line); - bool getPublic() const { return IsPublic; } - int getPlayerId() const { return PlayerId; } - const QString &getPlayerName() const { return PlayerName; } - ServerEventType getEventType() const { return EventType; } - const QStringList &getEventData() const { return EventData; } -}; - -enum ChatEventType { - eventChatInvalid, - eventChatListChannels, - eventChatJoinChannel, - eventChatListPlayers, - eventChatLeaveChannel, - eventChatSay, - eventChatServerMessage -}; - -class ChatEventData { -private: - static QHash eventHash; - - ChatEventType eventType; - QStringList eventData; -public: - ChatEventData(const QString &line); - ChatEventType getEventType() const { return eventType; } - const QStringList &getEventData() const { return eventData; } -}; - -#endif diff --git a/cockatrice/src/servergame.h b/cockatrice/src/servergame.h deleted file mode 100644 index a5295266..00000000 --- a/cockatrice/src/servergame.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef SERVERGAME_H -#define SERVERGAME_H - -class ServerGame { -private: - int gameId; - QString creator; - QString description; - bool hasPassword; - unsigned char playerCount; - unsigned char maxPlayers; - bool spectatorsAllowed; - unsigned int spectatorsCount; -public: - ServerGame(int _gameId, const QString &_creator, const QString &_description, bool _hasPassword, unsigned char _playerCount, unsigned char _maxPlayers, bool _spectatorsAllowed, unsigned int _spectatorsCount) - : gameId(_gameId), creator(_creator), description(_description), hasPassword(_hasPassword), playerCount(_playerCount), maxPlayers(_maxPlayers), spectatorsAllowed(_spectatorsAllowed), spectatorsCount(_spectatorsCount) { } - int getGameId() const { return gameId; } - QString getCreator() const { return creator; } - QString getDescription() const { return description; } - bool getHasPassword() const { return hasPassword; } - unsigned char getPlayerCount() const { return playerCount; } - unsigned char getMaxPlayers() const { return maxPlayers; } - bool getSpectatorsAllowed() const { return spectatorsAllowed; } - unsigned int getSpectatorsCount() const { return spectatorsCount; } -}; - -#endif diff --git a/cockatrice/src/serverplayer.h b/cockatrice/src/serverplayer.h deleted file mode 100644 index 820f9bda..00000000 --- a/cockatrice/src/serverplayer.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef SERVERPLAYER_H -#define SERVERPLAYER_H - -#include - -class ServerPlayer { -private: - int PlayerId; - QString name; - bool local; -public: - ServerPlayer(int _PlayerId, const QString &_name, bool _local) - : PlayerId(_PlayerId), name(_name), local(_local) { } - int getPlayerId() const { return PlayerId; } - QString getName() const { return name; } - bool getLocal() const { return local; } -}; - -#endif diff --git a/cockatrice/src/serverzone.h b/cockatrice/src/serverzone.h deleted file mode 100644 index 6884d372..00000000 --- a/cockatrice/src/serverzone.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef SERVERZONE_H -#define SERVERZONE_H - -#include - -class ServerZone { -private: - QString name; - bool isPublic; - bool hasCoords; - int cardCount; -public: - ServerZone(const QString &_name, bool _isPublic, bool _hasCoords, int _cardCount) - : name(_name), isPublic(_isPublic), hasCoords(_hasCoords), cardCount(_cardCount) { } - QString getName() const { return name; } - bool getPublic() const { return isPublic; } - bool getHasCoords() const { return hasCoords; } - int getCardCount() const { return cardCount; } -}; - -#endif diff --git a/cockatrice/src/serverzonecard.h b/cockatrice/src/serverzonecard.h deleted file mode 100644 index acd1cf56..00000000 --- a/cockatrice/src/serverzonecard.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef SERVERZONECARD_H -#define SERVERZONECARD_H - -#include - -class ServerZoneCard { -private: - int id; - QString name; - int x, y; - int counters; - bool tapped; - bool attacking; - QString annotation; -public: - ServerZoneCard(int _id, const QString &_name, int _x, int _y, int _counters, bool _attacking, const QString &_annotation) - : id(_id), name(_name), x(_x), y(_y), counters(_counters), attacking(_attacking), annotation(_annotation) { } - int getId() const { return id; } - QString getName() const { return name; } - int getX() const { return x; } - int getY() const { return y; } - int getCounters() const { return counters; } - bool getTapped() const { return tapped; } - bool getAttacking() const { return attacking; } - QString getAnnotation() const { return annotation; } -}; - -#endif diff --git a/cockatrice/src/window_main.cpp b/cockatrice/src/window_main.cpp index 62cb19dd..fc37292d 100644 --- a/cockatrice/src/window_main.cpp +++ b/cockatrice/src/window_main.cpp @@ -307,6 +307,7 @@ MainWindow::MainWindow(QTranslator *_translator, QWidget *parent) connect(client, SIGNAL(logSocketError(const QString &)), messageLog, SLOT(logSocketError(const QString &))); connect(client, SIGNAL(serverError(ServerResponse)), messageLog, SLOT(logServerError(ServerResponse))); connect(client, SIGNAL(protocolVersionMismatch()), messageLog, SLOT(logProtocolVersionMismatch())); + connect(client, SIGNAL(protocolError()), messageLog, SLOT(logProtocolError())); connect(phasesToolbar, SIGNAL(signalSetPhase(int)), client, SLOT(setActivePhase(int))); connect(phasesToolbar, SIGNAL(signalNextTurn()), client, SLOT(nextTurn())); connect(phasesToolbar, SIGNAL(signalDrawCard()), client, SLOT(drawCard())); diff --git a/cockatrice/src/zoneviewwidget.h b/cockatrice/src/zoneviewwidget.h index 1e817aa4..0ac74e4c 100644 --- a/cockatrice/src/zoneviewwidget.h +++ b/cockatrice/src/zoneviewwidget.h @@ -4,7 +4,6 @@ #include #include #include -#include "serverzonecard.h" class CardZone; class ZoneViewZone; diff --git a/cockatrice/src/zoneviewzone.cpp b/cockatrice/src/zoneviewzone.cpp index f1aeb14c..334e2413 100644 --- a/cockatrice/src/zoneviewzone.cpp +++ b/cockatrice/src/zoneviewzone.cpp @@ -27,9 +27,8 @@ void ZoneViewZone::paint(QPainter */*painter*/, const QStyleOptionGraphicsItem * void ZoneViewZone::initializeCards() { if (!origZone->contentsKnown()) { - connect(player->client, SIGNAL(zoneDumpReceived(int, QList)), this, SLOT(zoneDumpReceived(int, QList))); - PendingCommand *dumpZoneCommand = player->client->dumpZone(player->getId(), name, numberCards); - cmdId = dumpZoneCommand->getMsgId(); + PendingCommand_DumpZone *dumpZoneCommand = player->client->dumpZone(player->getId(), name, numberCards); + connect(dumpZoneCommand, SIGNAL(cardListReceived(QList)), this, SLOT(zoneDumpReceived(QList))); } else { const CardList &c = origZone->getCards(); int number = numberCards == -1 ? c.size() : (numberCards < c.size() ? numberCards : c.size()); @@ -42,18 +41,11 @@ void ZoneViewZone::initializeCards() } } -void ZoneViewZone::zoneDumpReceived(int commandId, QList cards) +void ZoneViewZone::zoneDumpReceived(QList cards) { - if (commandId != cmdId) - return; - for (int i = 0; i < cards.size(); i++) { - ServerZoneCard *temp = cards[i]; - - CardItem *card = new CardItem(player->getDb(), temp->getName(), i, this); + CardItem *card = new CardItem(player->getDb(), cards[i].getName(), i, this); addCard(card, false, i); - - delete temp; } emit contentsChanged(); diff --git a/cockatrice/src/zoneviewzone.h b/cockatrice/src/zoneviewzone.h index d7e43856..c385db54 100644 --- a/cockatrice/src/zoneviewzone.h +++ b/cockatrice/src/zoneviewzone.h @@ -2,7 +2,7 @@ #define ZONEVIEWERZONE_H #include "cardzone.h" -#include "serverzonecard.h" +#include "client.h" #include #include @@ -16,7 +16,6 @@ private: void handleDropEvent(int cardId, CardZone *startZone, const QPoint &dropPoint, bool faceDown); CardZone *origZone; bool sortingEnabled; - int cmdId; public: ZoneViewZone(Player *_p, CardZone *_origZone, int _numberCards = -1, QGraphicsItem *parent = 0); ~ZoneViewZone(); @@ -30,7 +29,7 @@ public: public slots: void setSortingEnabled(int _sortingEnabled); private slots: - void zoneDumpReceived(int commandId, QList cards); + void zoneDumpReceived(QList cards); protected: void addCardImpl(CardItem *card, int x, int y); QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; diff --git a/servatrice/src/counter.h b/servatrice/src/counter.h index f7a27701..8eeed18f 100644 --- a/servatrice/src/counter.h +++ b/servatrice/src/counter.h @@ -30,9 +30,10 @@ protected: public: Counter(QString _name, int _color, int _count = 0) : name(_name), color(_color), count(_count) { } ~Counter() { } + QString getName() const { return name; } + int getColor() const { return color; } int getCount() const { return count; } void setCount(int _count) { count = _count; } - QString getName() const { return name; } }; #endif diff --git a/servatrice/src/returnmessage.cpp b/servatrice/src/returnmessage.cpp index d8825ac9..b16a21ca 100644 --- a/servatrice/src/returnmessage.cpp +++ b/servatrice/src/returnmessage.cpp @@ -32,7 +32,5 @@ bool ReturnMessage::sendList(const QStringList &args) s->msg(QString("%1|%2|%3").arg(cmd) .arg(msg_id) .arg(args[i])); - s->msg(QString("%1|%2|.").arg(cmd).arg(msg_id)); - return true; } diff --git a/servatrice/src/serversocket.cpp b/servatrice/src/serversocket.cpp index d9928628..ff75842b 100644 --- a/servatrice/src/serversocket.cpp +++ b/servatrice/src/serversocket.cpp @@ -30,9 +30,94 @@ #include "abstractrng.h" #include "chatchannel.h" +QHash ServerSocket::commandHash; + ServerSocket::ServerSocket(Server *_server, QObject *parent) : QTcpSocket(parent), server(_server), game(0), spectator(false), PlayerStatus(StatusNormal), authState(PasswordWrong), acceptsGameListChanges(false) { + if (commandHash.isEmpty()) { + commandHash.insert("ping", CommandProperties(false, false, false, true, QList(), &ServerSocket::cmdPing)); + commandHash.insert("login", CommandProperties(false, false, false, true, QList() + << QVariant::String + << QVariant::String, &ServerSocket::cmdLogin)); + commandHash.insert("chat_list_channels", CommandProperties(true, false, false, true, QList(), &ServerSocket::cmdChatListChannels)); + commandHash.insert("chat_join_channel", CommandProperties(true, false, false, true, QList() + << QVariant::String, &ServerSocket::cmdChatJoinChannel)); + commandHash.insert("chat_leave_channel", CommandProperties(true, false, false, true, QList() + << QVariant::String, &ServerSocket::cmdChatLeaveChannel)); + commandHash.insert("chat_say", CommandProperties(true, false, false, true, QList() + << QVariant::String + << QVariant::String, &ServerSocket::cmdChatSay)); + commandHash.insert("list_games", CommandProperties(true, false, false, true, QList(), &ServerSocket::cmdListGames)); + commandHash.insert("create_game", CommandProperties(true, false, false, true, QList() + << QVariant::String + << QVariant::String + << QVariant::Int + << QVariant::Bool, &ServerSocket::cmdCreateGame)); + commandHash.insert("join_game", CommandProperties(true, false, false, true, QList() + << QVariant::Int + << QVariant::String + << QVariant::Bool, &ServerSocket::cmdJoinGame)); + commandHash.insert("leave_game", CommandProperties(true, true, false, true, QList(), &ServerSocket::cmdLeaveGame)); + commandHash.insert("list_players", CommandProperties(true, true, false, true, QList(), &ServerSocket::cmdListPlayers)); + commandHash.insert("say", CommandProperties(true, true, false, false, QList() + << QVariant::String, &ServerSocket::cmdSay)); + commandHash.insert("submit_deck", CommandProperties(true, true, false, false, QList(), &ServerSocket::cmdSubmitDeck)); + commandHash.insert("ready_start", CommandProperties(true, true, false, false, QList(), &ServerSocket::cmdReadyStart)); + commandHash.insert("shuffle", CommandProperties(true, true, true, false, QList(), &ServerSocket::cmdShuffle)); + commandHash.insert("draw_cards", CommandProperties(true, true, true, false, QList() + << QVariant::Int, &ServerSocket::cmdDrawCards)); + commandHash.insert("reveal_card", CommandProperties(true, true, true, false, QList() + << QVariant::Int + << QVariant::String, &ServerSocket::cmdRevealCard)); + commandHash.insert("move_card", CommandProperties(true, true, true, false, QList() + << QVariant::Int + << QVariant::String + << QVariant::String + << QVariant::Int + << QVariant::Int + << QVariant::Bool, &ServerSocket::cmdMoveCard)); + commandHash.insert("create_token", CommandProperties(true, true, true, false, QList() + << QVariant::String + << QVariant::String + << QVariant::String + << QVariant::Int + << QVariant::Int, &ServerSocket::cmdCreateToken)); + commandHash.insert("set_card_attr", CommandProperties(true, true, true, false, QList() + << QVariant::String + << QVariant::Int + << QVariant::String + << QVariant::String, &ServerSocket::cmdSetCardAttr)); + commandHash.insert("inc_counter", CommandProperties(true, true, true, false, QList() + << QVariant::String + << QVariant::Int, &ServerSocket::cmdIncCounter)); + commandHash.insert("add_counter", CommandProperties(true, true, true, false, QList() + << QVariant::String + << QVariant::Int + << QVariant::Int, &ServerSocket::cmdAddCounter)); + commandHash.insert("set_counter", CommandProperties(true, true, true, false, QList() + << QVariant::String + << QVariant::Int, &ServerSocket::cmdSetCounter)); + commandHash.insert("del_counter", CommandProperties(true, true, true, false, QList() + << QVariant::String, &ServerSocket::cmdDelCounter)); + commandHash.insert("list_counters", CommandProperties(true, true, true, true, QList() + << QVariant::Int, &ServerSocket::cmdListCounters)); + commandHash.insert("list_zones", CommandProperties(true, true, true, true, QList() + << QVariant::Int, &ServerSocket::cmdListZones)); + commandHash.insert("dump_zone", CommandProperties(true, true, true, true, QList() + << QVariant::Int + << QVariant::String + << QVariant::Int, &ServerSocket::cmdDumpZone)); + commandHash.insert("stop_dump_zone", CommandProperties(true, true, true, true, QList() + << QVariant::Int + << QVariant::String, &ServerSocket::cmdStopDumpZone)); + commandHash.insert("roll_die", CommandProperties(true, true, true, false, QList() + << QVariant::Int, &ServerSocket::cmdRollDie)); + commandHash.insert("next_turn", CommandProperties(true, true, true, false, QList(), &ServerSocket::cmdNextTurn)); + commandHash.insert("set_active_phase", CommandProperties(true, true, true, false, QList() + << QVariant::Int, &ServerSocket::cmdSetActivePhase)); + } + remsg = new ReturnMessage(this); connect(this, SIGNAL(readyRead()), this, SLOT(readClient())); connect(this, SIGNAL(disconnected()), this, SLOT(deleteLater())); @@ -165,67 +250,6 @@ void ServerSocket::readClient() } } -const ServerSocket::CommandProperties ServerSocket::commandList[ServerSocket::numberCommands] = { - {"ping", false, false, false, true, QList(), &ServerSocket::cmdPing}, - {"login", false, false, false, true, QList() << QVariant::String - << QVariant::String, &ServerSocket::cmdLogin}, - {"chat_list_channels", true, false, false, true, QList(), &ServerSocket::cmdChatListChannels}, - {"chat_join_channel", true, false, false, true, QList() << QVariant::String, &ServerSocket::cmdChatJoinChannel}, - {"chat_leave_channel", true, false, false, true, QList() << QVariant::String, &ServerSocket::cmdChatLeaveChannel}, - {"chat_say", true, false, false, true, QList() << QVariant::String - << QVariant::String, &ServerSocket::cmdChatSay}, - {"list_games", true, false, false, true, QList(), &ServerSocket::cmdListGames}, - {"create_game", true, false, false, true, QList() << QVariant::String - << QVariant::String - << QVariant::Int - << QVariant::Bool, &ServerSocket::cmdCreateGame}, - {"join_game", true, false, false, true, QList() << QVariant::Int - << QVariant::String - << QVariant::Bool, &ServerSocket::cmdJoinGame}, - {"leave_game", true, true, false, true, QList(), &ServerSocket::cmdLeaveGame}, - {"list_players", true, true, false, true, QList(), &ServerSocket::cmdListPlayers}, - {"say", true, true, false, false, QList() << QVariant::String, &ServerSocket::cmdSay}, - {"submit_deck", true, true, false, false, QList(), &ServerSocket::cmdSubmitDeck}, - {"ready_start", true, true, false, false, QList(), &ServerSocket::cmdReadyStart}, - {"shuffle", true, true, true, false, QList(), &ServerSocket::cmdShuffle}, - {"draw_cards", true, true, true, false, QList() << QVariant::Int, &ServerSocket::cmdDrawCards}, - {"reveal_card", true, true, true, false, QList() << QVariant::Int - << QVariant::String, &ServerSocket::cmdRevealCard}, - {"move_card", true, true, true, false, QList() << QVariant::Int - << QVariant::String - << QVariant::String - << QVariant::Int - << QVariant::Int - << QVariant::Bool, &ServerSocket::cmdMoveCard}, - {"create_token", true, true, true, false, QList() << QVariant::String - << QVariant::String - << QVariant::String - << QVariant::Int - << QVariant::Int, &ServerSocket::cmdCreateToken}, - {"set_card_attr", true, true, true, false, QList() << QVariant::String - << QVariant::Int - << QVariant::String - << QVariant::String, &ServerSocket::cmdSetCardAttr}, - {"inc_counter", true, true, true, false, QList() << QVariant::String - << QVariant::Int, &ServerSocket::cmdIncCounter}, - {"add_counter", true, true, true, false, QList() << QVariant::String - << QVariant::Int - << QVariant::Int, &ServerSocket::cmdAddCounter}, - {"set_counter", true, true, true, false, QList() << QVariant::String - << QVariant::Int, &ServerSocket::cmdSetCounter}, - {"del_counter", true, true, true, false, QList() << QVariant::String, &ServerSocket::cmdDelCounter}, - {"list_counters", true, true, true, true, QList() << QVariant::Int, &ServerSocket::cmdListCounters}, - {"list_zones", true, true, true, true, QList() << QVariant::Int, &ServerSocket::cmdListZones}, - {"dump_zone", true, true, true, true, QList() << QVariant::Int - << QVariant::String - << QVariant::Int, &ServerSocket::cmdDumpZone}, - {"stop_dump_zone", true, true, true, true, QList() << QVariant::Int - << QVariant::String, &ServerSocket::cmdStopDumpZone}, - {"roll_die", true, true, true, false, QList() << QVariant::Int, &ServerSocket::cmdRollDie}, - {"next_turn", true, true, true, false, QList(), &ServerSocket::cmdNextTurn}, - {"set_active_phase", true, true, true, false, QList() << QVariant::Int, &ServerSocket::cmdSetActivePhase} -}; - ReturnMessage::ReturnCode ServerSocket::cmdPing(const QList &/*params*/) { return ReturnMessage::ReturnOk; @@ -614,7 +638,13 @@ ReturnMessage::ReturnCode ServerSocket::cmdListCounters(const QList &p ServerSocket *player = game->getPlayer(player_id); if (!player) return ReturnMessage::ReturnContextError; - remsg->sendList(player->listCounters()); + + QStringList result; + const QList &counterList = player->getCounters(); + for (int i = 0; i < counterList.size(); ++i) + result << QString("%1|%2|%3").arg(counterList[i]->getName()).arg(counterList[i]->getColor()).arg(counterList[i]->getCount()); + + remsg->sendList(result); return ReturnMessage::ReturnOk; } @@ -624,7 +654,12 @@ ReturnMessage::ReturnCode ServerSocket::cmdListZones(const QList ¶ ServerSocket *player = game->getPlayer(player_id); if (!player) return ReturnMessage::ReturnContextError; - remsg->sendList(player->listZones()); + + QStringList result; + const QList &zoneList = player->getZones(); + for (int i = 0; i < zoneList.size(); ++i) + result << QString("%1|%2|%3|%4").arg(zoneList[i]->getName()).arg(zoneList[i]->getType() == PlayerZone::PublicZone ? 1 : 0).arg(zoneList[i]->hasCoords()).arg(zoneList[i]->cards.size()); + remsg->sendList(result); return ReturnMessage::ReturnOk; } @@ -660,8 +695,8 @@ ReturnMessage::ReturnCode ServerSocket::cmdDumpZone(const QList ¶m result << QString("%1|%2||||||").arg(i).arg(tmp->getName()); } } - remsg->sendList(result); emit broadcastEvent(QString("dump_zone|%1|%2|%3").arg(player_id).arg(zone->getName()).arg(number_cards), this); + remsg->sendList(result); return ReturnMessage::ReturnOk; } @@ -727,55 +762,54 @@ bool ServerSocket::parseCommand(QString line) // Extract command QString cmd = params.takeFirst(); + if (!commandHash.contains(cmd)) + return remsg->send(ReturnMessage::ReturnSyntaxError); remsg->setCmd(cmd); - for (int i = 0; i < numberCommands; i++) - if (commandList[i].name == cmd) { - // Check login - if (commandList[i].needsLogin && (authState == PasswordWrong)) - return remsg->send(ReturnMessage::ReturnLoginNeeded); - // Check context - if (!commandList[i].allowedToSpectator && spectator) - return remsg->send(ReturnMessage::ReturnContextError); - if (commandList[i].needsGame && !game) - return remsg->send(ReturnMessage::ReturnContextError); - if (commandList[i].needsStartedGame && !game->getGameStarted()) - return remsg->send(ReturnMessage::ReturnContextError); - // Validate parameters - if (commandList[i].paramTypes.size() != params.size()) - return remsg->send(ReturnMessage::ReturnSyntaxError); - QList paramList; - for (int j = 0; j < commandList[i].paramTypes.size(); j++) - switch (commandList[i].paramTypes[j]) { - case QVariant::String: { - paramList << QVariant(params[j]); - break; - } - case QVariant::Int: { - bool ok; - int temp = params[j].toInt(&ok); - if (!ok) - return remsg->send(ReturnMessage::ReturnSyntaxError); - paramList << QVariant(temp); - break; - } - case QVariant::Bool: { - if (params[j] == "1") - paramList << QVariant(true); - else if (params[j] == "0") - paramList << QVariant(false); - else - return remsg->send(ReturnMessage::ReturnSyntaxError); - break; - } - default: - paramList << QVariant(params[j]); - } - // Call handler function - CommandHandler handler = commandList[i].handler; - return remsg->send((this->*handler)(paramList)); + const CommandProperties &cp = commandHash[cmd]; + + // Check login + if (cp.getNeedsLogin() && (authState == PasswordWrong)) + return remsg->send(ReturnMessage::ReturnLoginNeeded); + // Check context + if (!cp.getAllowedToSpectator() && spectator) + return remsg->send(ReturnMessage::ReturnContextError); + if (cp.getNeedsGame() && !game) + return remsg->send(ReturnMessage::ReturnContextError); + if (cp.getNeedsStartedGame() && !game->getGameStarted()) + return remsg->send(ReturnMessage::ReturnContextError); + // Validate parameters + if (cp.getParamTypes().size() != params.size()) + return remsg->send(ReturnMessage::ReturnSyntaxError); + QList paramList; + for (int j = 0; j < cp.getParamTypes().size(); j++) + switch (cp.getParamTypes()[j]) { + case QVariant::String: { + paramList << QVariant(params[j]); + break; + } + case QVariant::Int: { + bool ok; + int temp = params[j].toInt(&ok); + if (!ok) + return remsg->send(ReturnMessage::ReturnSyntaxError); + paramList << QVariant(temp); + break; + } + case QVariant::Bool: { + if (params[j] == "1") + paramList << QVariant(true); + else if (params[j] == "0") + paramList << QVariant(false); + else + return remsg->send(ReturnMessage::ReturnSyntaxError); + break; + } + default: + paramList << QVariant(params[j]); } - return remsg->send(ReturnMessage::ReturnSyntaxError); + // Call handler function + return remsg->send((this->*(cp.getHandler()))(paramList)); } void ServerSocket::privateEvent(const QString &line) @@ -788,28 +822,6 @@ void ServerSocket::setGame(ServerGame *g) game = g; } -QStringList ServerSocket::listCounters() const -{ - QStringList counter_list; - QListIterator i(counters); - while (i.hasNext()) { - Counter *tmp = i.next(); - counter_list << QString("%1|%2").arg(tmp->getName()).arg(tmp->getCount()); - } - return counter_list; -} - -QStringList ServerSocket::listZones() const -{ - QStringList zone_list; - QListIterator i(zones); - while (i.hasNext()) { - PlayerZone *tmp = i.next(); - zone_list << QString("%1|%2|%3|%4").arg(tmp->getName()).arg(tmp->getType() == PlayerZone::PublicZone ? 1 : 0).arg(tmp->hasCoords()).arg(tmp->cards.size()); - } - return zone_list; -} - void ServerSocket::msg(const QString &s) { qDebug(QString("OUT id=%1 name=%2 >>> %3").arg(playerId).arg(playerName).arg(s).toLatin1()); diff --git a/servatrice/src/serversocket.h b/servatrice/src/serversocket.h index f1e504a3..5cf73339 100644 --- a/servatrice/src/serversocket.h +++ b/servatrice/src/serversocket.h @@ -46,17 +46,25 @@ signals: void startGameIfReady(); private: typedef ReturnMessage::ReturnCode (ServerSocket::*CommandHandler)(const QList &); - struct CommandProperties { - QString name; + class CommandProperties { + private: bool needsLogin; bool needsGame; bool needsStartedGame; bool allowedToSpectator; QList paramTypes; CommandHandler handler; + public: + CommandProperties(bool _needsLogin = false, bool _needsGame = false, bool _needsStartedGame = false, bool _allowedToSpectator = false, const QList &_paramTypes = QList(), CommandHandler _handler = 0) + : needsLogin(_needsLogin), needsGame(_needsGame), needsStartedGame(_needsStartedGame), allowedToSpectator(_allowedToSpectator), paramTypes(_paramTypes), handler(_handler) { } + bool getNeedsLogin() const { return needsLogin; } + bool getNeedsGame() const { return needsGame; } + bool getNeedsStartedGame() const { return needsStartedGame; } + bool getAllowedToSpectator() const { return allowedToSpectator; } + const QList &getParamTypes() const { return paramTypes; } + CommandHandler getHandler() const { return handler; } }; - static const int numberCommands = 31; - static const CommandProperties commandList[numberCommands]; + static QHash commandHash; ReturnMessage::ReturnCode cmdPing(const QList ¶ms); ReturnMessage::ReturnCode cmdLogin(const QList ¶ms); @@ -127,8 +135,8 @@ public: QString getPlayerName() const { return playerName; } bool getAcceptsGameListChanges() const { return acceptsGameListChanges; } bool getAcceptsChatChannelListChanges() const { return acceptsChatChannelListChanges; } - QStringList listCounters() const; - QStringList listZones() const; + const QList &getZones() const { return zones; } + const QList &getCounters() const { return counters; } void setupZones(); };