some client code

This commit is contained in:
Max-Wilhelm Bruker 2009-11-12 17:04:06 +01:00
parent 240ff06032
commit c46ef255a1
8 changed files with 115 additions and 69 deletions

View file

@ -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<Command *>(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<Command *>(currentItem);
if (qobject_cast<InvalidCommand *>(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<ProtocolResponse *>(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<GenericEvent *>(item);
if (genericEvent) {
switch (genericEvent->getItemId()) {
}
delete genericEvent;
return;
}
/* GameEvent *gameEvent = qobject_cast<GameEvent *>(item);
if (gameEvent) {
emit gameEventReceived(gameEvent);
delete gameEvent;
return;
}
*/
ChatEvent *chatEvent = qobject_cast<ChatEvent *>(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()

View file

@ -5,12 +5,15 @@
#include <QColor>
#include <QStringList>
#include <QHash>
#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() { }

View file

@ -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()

View file

@ -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);

View file

@ -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()));

View file

@ -75,6 +75,7 @@ private slots:
void actExit();
signals:
void logConnecting(QString hostname);
void logConnected();
void logDisconnected();
private:
void retranslateUi();

View file

@ -84,6 +84,11 @@ void Command::extractParameters()
cmdId = -1;
}
void Command::processResponse(ProtocolResponse *response)
{
emit finished(response->getResponseCode());
}
QHash<QString, ResponseCode> ProtocolResponse::responseHash;
ProtocolResponse::ProtocolResponse(int _cmdId, ResponseCode _responseCode)

View file

@ -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<ServerChatChannelInfo> 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)
{