From c46ef255a16eb50f7de4e9098685c82cd6dd5be6 Mon Sep 17 00:00:00 2001 From: Max-Wilhelm Bruker Date: Thu, 12 Nov 2009 17:04:06 +0100 Subject: [PATCH] some client code --- cockatrice/src/client.cpp | 124 +++++++++++++++++----------- cockatrice/src/client.h | 24 +++--- cockatrice/src/messagelogwidget.cpp | 8 +- cockatrice/src/messagelogwidget.h | 4 +- cockatrice/src/window_main.cpp | 7 +- cockatrice/src/window_main.h | 1 + common/protocol.cpp | 5 ++ common/protocol.h | 11 ++- 8 files changed, 115 insertions(+), 69 deletions(-) diff --git a/cockatrice/src/client.cpp b/cockatrice/src/client.cpp index 9b392249..42a3c83d 100644 --- a/cockatrice/src/client.cpp +++ b/cockatrice/src/client.cpp @@ -8,6 +8,8 @@ Client::Client(QObject *parent) : QObject(parent), currentItem(0), status(StatusDisconnected) { + ProtocolItem::initializeHash(); + timer = new QTimer(this); timer->setInterval(1000); connect(timer, SIGNAL(timeout()), this, SLOT(ping())); @@ -40,36 +42,21 @@ void Client::slotConnected() setStatus(StatusAwaitingWelcome); } -void Client::removePendingCommand() -{ - pendingCommands.remove(static_cast(sender())->getCmdId()); -} -/* -void Client::loginResponse(ServerResponse response) +void Client::loginResponse(ResponseCode response) { if (response == RespOk) - setStatus(StatusIdle); + setStatus(StatusLoggedIn); else { emit serverError(response); disconnectFromServer(); } } -void Client::enterGameResponse(ServerResponse response) -{ - if (response == RespOk) - setStatus(StatusPlaying); -} - -void Client::leaveGameResponse(ServerResponse response) -{ - if (response == RespOk) - setStatus(StatusIdle); -} -*/ void Client::readData() { - xmlReader->addData(socket->readAll()); + QByteArray data = socket->readAll(); + qDebug() << data; + xmlReader->addData(data); if (currentItem) { if (!currentItem->read(xmlReader)) @@ -80,8 +67,25 @@ void Client::readData() xmlReader->readNext(); if (xmlReader->isStartElement()) { QString itemType = xmlReader->name().toString(); - if (itemType == "cockatrice_server_stream") - continue; + if (itemType == "cockatrice_server_stream") { + int serverVersion = xmlReader->attributes().value("version").toString().toInt(); + if (serverVersion != ProtocolItem::protocolVersion) { + emit protocolVersionMismatch(ProtocolItem::protocolVersion, serverVersion); + disconnectFromServer(); + return; + } else { + xmlWriter->writeStartDocument(); + xmlWriter->writeStartElement("cockatrice_client_stream"); + xmlWriter->writeAttribute("version", QString::number(ProtocolItem::protocolVersion)); + + setStatus(StatusLoggingIn); + Command_Login *cmdLogin = new Command_Login(userName, password); + connect(cmdLogin, SIGNAL(finished(ResponseCode)), this, SLOT(loginResponse(ResponseCode))); + sendCommand(cmdLogin); + + continue; + } + } QString itemName = xmlReader->attributes().value("name").toString(); qDebug() << "parseXml: startElement: " << "type =" << itemType << ", name =" << itemName; currentItem = ProtocolItem::getNewItem(itemType + itemName); @@ -90,13 +94,9 @@ void Client::readData() if (!currentItem->read(xmlReader)) return; else { -/* Command *command = qobject_cast(currentItem); - if (qobject_cast(command)) - sendProtocolItem(new ProtocolResponse(command->getCmdId(), ProtocolResponse::RespInvalidCommand)); - else - processCommand(command); + processProtocolItem(currentItem); currentItem = 0; -*/ } + } } } /* @@ -265,6 +265,46 @@ void Client::readData() */ } +void Client::processProtocolItem(ProtocolItem *item) +{ + ProtocolResponse *response = qobject_cast(item); + if (response) { + Command *cmd = pendingCommands.value(response->getCmdId(), 0); + if (!cmd) + return; + + cmd->processResponse(response); + delete response; + + pendingCommands.remove(cmd->getCmdId()); + delete cmd; + + return; + } + + GenericEvent *genericEvent = qobject_cast(item); + if (genericEvent) { + switch (genericEvent->getItemId()) { + } + delete genericEvent; + return; + } + +/* GameEvent *gameEvent = qobject_cast(item); + if (gameEvent) { + emit gameEventReceived(gameEvent); + delete gameEvent; + return; + } +*/ + ChatEvent *chatEvent = qobject_cast(item); + if (chatEvent) { + qDebug() << "chatEventReceived()"; + emit chatEventReceived(chatEvent); + delete chatEvent; + } +} + void Client::setStatus(const ClientStatus _status) { if (_status != status) { @@ -272,26 +312,18 @@ void Client::setStatus(const ClientStatus _status) emit statusChanged(_status); } } -/* -PendingCommand *Client::cmd(const QString &s, PendingCommand *_pc) + +void Client::sendCommand(Command *cmd) { - msg(QString("%1|%2").arg(++MsgId).arg(s)); - 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())); - return pc; + cmd->write(xmlWriter); + pendingCommands.insert(cmd->getCmdId(), cmd); } -*/ -void Client::connectToServer(const QString &hostname, unsigned int port, const QString &_playerName, const QString &_password) + +void Client::connectToServer(const QString &hostname, unsigned int port, const QString &_userName, const QString &_password) { disconnectFromServer(); - playerName = _playerName; + userName = _userName; password = _password; socket->connectToHost(hostname, port); setStatus(StatusConnecting); @@ -326,10 +358,8 @@ void Client::ping() if (maxTime >= maxTimeout) { emit serverTimeout(); disconnectFromServer(); - } -/* else - cmd("ping"); -*/ + } else + sendCommand(new Command_Ping); } /* PendingCommand *Client::chatListChannels() diff --git a/cockatrice/src/client.h b/cockatrice/src/client.h index bd080a35..81497665 100644 --- a/cockatrice/src/client.h +++ b/cockatrice/src/client.h @@ -5,12 +5,15 @@ #include #include #include +#include "protocol_datastructures.h" class QTimer; class Command; class QXmlStreamReader; class QXmlStreamWriter; + class ProtocolItem; +class ChatEvent; enum ClientStatus { StatusDisconnected, @@ -24,26 +27,23 @@ class Client : public QObject { Q_OBJECT signals: void statusChanged(ClientStatus _status); - void welcomeMsgReceived(QString welcomeMsg); // void gameListEvent(const ServerGame &game); - void playerIdReceived(int id, QString name); +// void playerIdReceived(int id, QString name); // void gameEvent(const ServerEventData &msg); -// void chatEvent(const ChatEventData &msg); void maxPingTime(int seconds, int maxSeconds); void serverTimeout(); void logSocketError(const QString &errorString); -// void serverError(ServerResponse resp); - void protocolVersionMismatch(); + void serverError(ResponseCode resp); + void protocolVersionMismatch(int clientVersion, int serverVersion); void protocolError(); + + void chatEventReceived(ChatEvent *event); private slots: void slotConnected(); void readData(); void slotSocketError(QAbstractSocket::SocketError error); void ping(); - void removePendingCommand(); -// void loginResponse(ServerResponse response); -// void enterGameResponse(ServerResponse response); -// void leaveGameResponse(ServerResponse response); + void loginResponse(ResponseCode response); private: static const int maxTimeout = 10; @@ -54,16 +54,18 @@ private: QXmlStreamWriter *xmlWriter; ProtocolItem *currentItem; ClientStatus status; - QString playerName, password; + QString userName, password; void setStatus(ClientStatus _status); + void processProtocolItem(ProtocolItem *item); public: Client(QObject *parent = 0); ~Client(); ClientStatus getStatus() const { return status; } QString peerName() const { return socket->peerName(); } - void connectToServer(const QString &hostname, unsigned int port, const QString &_playerName, const QString &_password); + void connectToServer(const QString &hostname, unsigned int port, const QString &_userName, const QString &_password); void disconnectFromServer(); + void sendCommand(Command *cmd); public slots: void chatListChannels() { } diff --git a/cockatrice/src/messagelogwidget.cpp b/cockatrice/src/messagelogwidget.cpp index 2f065dde..aa255d3e 100644 --- a/cockatrice/src/messagelogwidget.cpp +++ b/cockatrice/src/messagelogwidget.cpp @@ -17,9 +17,9 @@ void MessageLogWidget::logConnecting(QString hostname) append(tr("Connecting to %1...").arg(sanitizeHtml(hostname))); } -void MessageLogWidget::logConnected(QString welcomeMsg) +void MessageLogWidget::logConnected() { - append(tr("Connected: %1").arg(welcomeMsg)); + append(tr("Connected.")); } void MessageLogWidget::logDisconnected() @@ -40,9 +40,9 @@ void MessageLogWidget::logServerError(ResponseCode response) } } -void MessageLogWidget::logProtocolVersionMismatch() +void MessageLogWidget::logProtocolVersionMismatch(int clientVersion, int serverVersion) { - append(tr("Protocol version mismatch.")); + append(tr("Protocol version mismatch. Client: %1, Server: %2").arg(clientVersion).arg(serverVersion)); } void MessageLogWidget::logProtocolError() diff --git a/cockatrice/src/messagelogwidget.h b/cockatrice/src/messagelogwidget.h index d8e2e03d..1175186f 100644 --- a/cockatrice/src/messagelogwidget.h +++ b/cockatrice/src/messagelogwidget.h @@ -17,11 +17,11 @@ private: QString trZoneName(CardZone *zone, Player *player, bool hisOwn, GrammaticalCase gc) const; public slots: void logConnecting(QString hostname); - void logConnected(QString welcomeMsg); + void logConnected(); void logDisconnected(); void logSocketError(const QString &errorString); void logServerError(ResponseCode response); - void logProtocolVersionMismatch(); + void logProtocolVersionMismatch(int clientVersion, int serverVersion); void logProtocolError(); private slots: void logPlayerListReceived(QStringList players); diff --git a/cockatrice/src/window_main.cpp b/cockatrice/src/window_main.cpp index 1e9b1699..4238540b 100644 --- a/cockatrice/src/window_main.cpp +++ b/cockatrice/src/window_main.cpp @@ -98,6 +98,7 @@ void MainWindow::statusChanged(ClientStatus _status) emit logDisconnected(); break; case StatusLoggingIn: + emit logConnected(); aConnect->setEnabled(false); aDisconnect->setEnabled(true); break; @@ -341,11 +342,11 @@ MainWindow::MainWindow(QTranslator *_translator, QWidget *parent) connect(client, SIGNAL(statusChanged(ClientStatus)), this, SLOT(statusChanged(ClientStatus))); connect(this, SIGNAL(logConnecting(QString)), messageLog, SLOT(logConnecting(QString))); - connect(client, SIGNAL(welcomeMsgReceived(QString)), messageLog, SLOT(logConnected(QString))); + connect(this, SIGNAL(logConnected()), messageLog, SLOT(logConnected())); connect(this, SIGNAL(logDisconnected()), messageLog, SLOT(logDisconnected())); 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(serverError(ResponseCode)), messageLog, SLOT(logServerError(ResponseCode))); + connect(client, SIGNAL(protocolVersionMismatch(int, int)), messageLog, SLOT(logProtocolVersionMismatch(int, int))); connect(client, SIGNAL(protocolError()), messageLog, SLOT(logProtocolError())); connect(phasesToolbar, SIGNAL(signalSetPhase(int)), client, SLOT(setActivePhase(int))); connect(phasesToolbar, SIGNAL(signalNextTurn()), client, SLOT(nextTurn())); diff --git a/cockatrice/src/window_main.h b/cockatrice/src/window_main.h index 7b4c74fa..3f3fdaae 100644 --- a/cockatrice/src/window_main.h +++ b/cockatrice/src/window_main.h @@ -75,6 +75,7 @@ private slots: void actExit(); signals: void logConnecting(QString hostname); + void logConnected(); void logDisconnected(); private: void retranslateUi(); diff --git a/common/protocol.cpp b/common/protocol.cpp index 8634a028..8697e812 100644 --- a/common/protocol.cpp +++ b/common/protocol.cpp @@ -84,6 +84,11 @@ void Command::extractParameters() cmdId = -1; } +void Command::processResponse(ProtocolResponse *response) +{ + emit finished(response->getResponseCode()); +} + QHash ProtocolResponse::responseHash; ProtocolResponse::ProtocolResponse(int _cmdId, ResponseCode _responseCode) diff --git a/common/protocol.h b/common/protocol.h index c989d631..1a8a6f17 100644 --- a/common/protocol.h +++ b/common/protocol.h @@ -13,6 +13,8 @@ class QXmlStreamReader; class QXmlStreamWriter; class QXmlStreamAttributes; +class ProtocolResponse; + enum ItemId { ItemId_Event_ChatListChannels = ItemId_Other + 1, ItemId_Event_ChatListPlayers = ItemId_Other + 2, @@ -51,6 +53,8 @@ public: class Command : public ProtocolItem { Q_OBJECT +signals: + void finished(ResponseCode response); private: int cmdId; int ticks; @@ -62,6 +66,7 @@ public: Command(const QString &_itemName = QString(), int _cmdId = -1); int getCmdId() const { return cmdId; } int tick() { return ++ticks; } + void processResponse(ProtocolResponse *response); }; class InvalidCommand : public Command { @@ -121,6 +126,8 @@ public: int getItemId() const { return ItemId_Other; } static void initializeHash(); static ProtocolItem *newItem() { return new ProtocolResponse; } + int getCmdId() const { return cmdId; } + ResponseCode getResponseCode() const { return responseCode; } }; class GenericEvent : public ProtocolItem { @@ -157,12 +164,12 @@ public: ChatEvent(const QString &_eventName, const QString &_channel); }; -class Event_ChatListChannels : public GenericEvent { +class Event_ChatListChannels : public ChatEvent { Q_OBJECT private: QList channelList; public: - Event_ChatListChannels() : GenericEvent("chat_list_channels") { } + Event_ChatListChannels() : ChatEvent("chat_list_channels", QString()) { } int getItemId() const { return ItemId_Event_ChatListChannels; } void addChannel(const QString &_name, const QString &_description, int _playerCount, bool _autoJoin) {