mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-06-15 11:38:49 -07:00
new files
This commit is contained in:
parent
7921b5f82d
commit
58e803c3e7
10 changed files with 452 additions and 0 deletions
70
cockatrice/src/abstractclient.cpp
Normal file
70
cockatrice/src/abstractclient.cpp
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
#include "abstractclient.h"
|
||||||
|
#include "protocol.h"
|
||||||
|
#include "protocol_items.h"
|
||||||
|
|
||||||
|
AbstractClient::AbstractClient(QObject *parent)
|
||||||
|
: QObject(parent), status(StatusDisconnected)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractClient::~AbstractClient()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractClient::processProtocolItem(ProtocolItem *item)
|
||||||
|
{
|
||||||
|
ProtocolResponse *response = qobject_cast<ProtocolResponse *>(item);
|
||||||
|
if (response) {
|
||||||
|
CommandContainer *cmdCont = pendingCommands.value(response->getCmdId(), 0);
|
||||||
|
if (!cmdCont)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pendingCommands.remove(cmdCont->getCmdId());
|
||||||
|
cmdCont->processResponse(response);
|
||||||
|
delete response;
|
||||||
|
delete cmdCont;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GenericEvent *genericEvent = qobject_cast<GenericEvent *>(item);
|
||||||
|
if (genericEvent) {
|
||||||
|
switch (genericEvent->getItemId()) {
|
||||||
|
case ItemId_Event_ListGames: emit listGamesEventReceived(qobject_cast<Event_ListGames *>(item)); break;
|
||||||
|
case ItemId_Event_ServerMessage: emit serverMessageEventReceived(qobject_cast<Event_ServerMessage *>(item)); break;
|
||||||
|
case ItemId_Event_ListChatChannels: emit listChatChannelsEventReceived(qobject_cast<Event_ListChatChannels *>(item)); break;
|
||||||
|
case ItemId_Event_GameJoined: emit gameJoinedEventReceived(qobject_cast<Event_GameJoined *>(item)); break;
|
||||||
|
}
|
||||||
|
delete genericEvent;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GameEventContainer *gameEventContainer = qobject_cast<GameEventContainer *>(item);
|
||||||
|
if (gameEventContainer) {
|
||||||
|
emit gameEventContainerReceived(gameEventContainer);
|
||||||
|
delete gameEventContainer;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChatEvent *chatEvent = qobject_cast<ChatEvent *>(item);
|
||||||
|
if (chatEvent) {
|
||||||
|
emit chatEventReceived(chatEvent);
|
||||||
|
delete chatEvent;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void AbstractClient::setStatus(const ClientStatus _status)
|
||||||
|
{
|
||||||
|
if (_status != status) {
|
||||||
|
status = _status;
|
||||||
|
emit statusChanged(_status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractClient::sendCommand(Command *cmd)
|
||||||
|
{
|
||||||
|
sendCommandContainer(new CommandContainer(QList<Command *>() << cmd));
|
||||||
|
}
|
||||||
|
|
||||||
60
cockatrice/src/abstractclient.h
Normal file
60
cockatrice/src/abstractclient.h
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
#ifndef ABSTRACTCLIENT_H
|
||||||
|
#define ABSTRACTCLIENT_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include "protocol_datastructures.h"
|
||||||
|
|
||||||
|
class Command;
|
||||||
|
class CommandContainer;
|
||||||
|
class ProtocolItem;
|
||||||
|
class ProtocolResponse;
|
||||||
|
class TopLevelProtocolItem;
|
||||||
|
class CommandContainer;
|
||||||
|
class ChatEvent;
|
||||||
|
class GameEventContainer;
|
||||||
|
class Event_ListGames;
|
||||||
|
class Event_ServerMessage;
|
||||||
|
class Event_ListChatChannels;
|
||||||
|
class Event_GameJoined;
|
||||||
|
|
||||||
|
enum ClientStatus {
|
||||||
|
StatusDisconnected,
|
||||||
|
StatusDisconnecting,
|
||||||
|
StatusConnecting,
|
||||||
|
StatusAwaitingWelcome,
|
||||||
|
StatusLoggingIn,
|
||||||
|
StatusLoggedIn,
|
||||||
|
};
|
||||||
|
|
||||||
|
class AbstractClient : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
signals:
|
||||||
|
void statusChanged(ClientStatus _status);
|
||||||
|
void serverError(ResponseCode resp);
|
||||||
|
|
||||||
|
// Chat events
|
||||||
|
void chatEventReceived(ChatEvent *event);
|
||||||
|
// Game events
|
||||||
|
void gameEventContainerReceived(GameEventContainer *event);
|
||||||
|
// Generic events
|
||||||
|
void listGamesEventReceived(Event_ListGames *event);
|
||||||
|
void serverMessageEventReceived(Event_ServerMessage *event);
|
||||||
|
void listChatChannelsEventReceived(Event_ListChatChannels *event);
|
||||||
|
void gameJoinedEventReceived(Event_GameJoined *event);
|
||||||
|
protected slots:
|
||||||
|
void processProtocolItem(ProtocolItem *item);
|
||||||
|
protected:
|
||||||
|
QMap<int, CommandContainer *> pendingCommands;
|
||||||
|
ClientStatus status;
|
||||||
|
QString userName, password;
|
||||||
|
void setStatus(ClientStatus _status);
|
||||||
|
public:
|
||||||
|
AbstractClient(QObject *parent = 0);
|
||||||
|
~AbstractClient();
|
||||||
|
|
||||||
|
ClientStatus getStatus() const { return status; }
|
||||||
|
virtual void sendCommand(Command *cmd);
|
||||||
|
virtual void sendCommandContainer(CommandContainer *cont) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
23
cockatrice/src/localclient.cpp
Normal file
23
cockatrice/src/localclient.cpp
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
#include "localclient.h"
|
||||||
|
#include "localserverinterface.h"
|
||||||
|
#include "protocol.h"
|
||||||
|
|
||||||
|
LocalClient::LocalClient(LocalServerInterface *_lsi, QObject *parent)
|
||||||
|
: AbstractClient(parent), lsi(_lsi)
|
||||||
|
{
|
||||||
|
connect(lsi, SIGNAL(itemToClient(ProtocolItem *)), this, SLOT(itemFromServer(ProtocolItem *)));
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalClient::~LocalClient()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocalClient::sendCommandContainer(CommandContainer *cont)
|
||||||
|
{
|
||||||
|
lsi->itemFromClient(cont);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocalClient::itemFromServer(ProtocolItem *item)
|
||||||
|
{
|
||||||
|
processProtocolItem(item);
|
||||||
|
}
|
||||||
24
cockatrice/src/localclient.h
Normal file
24
cockatrice/src/localclient.h
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
#ifndef LOCALCLIENT_H
|
||||||
|
#define LOCALCLIENT_H
|
||||||
|
|
||||||
|
#include "abstractclient.h"
|
||||||
|
|
||||||
|
class LocalServerInterface;
|
||||||
|
|
||||||
|
class LocalClient : public AbstractClient {
|
||||||
|
Q_OBJECT
|
||||||
|
private:
|
||||||
|
LocalServerInterface *lsi;
|
||||||
|
public:
|
||||||
|
LocalClient(LocalServerInterface *_lsi, QObject *parent = 0);
|
||||||
|
~LocalClient();
|
||||||
|
|
||||||
|
void sendCommandContainer(CommandContainer *cont);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void itemFromServer(ProtocolItem *item);
|
||||||
|
signals:
|
||||||
|
void itemToServer(ProtocolItem *item);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
17
cockatrice/src/localserver.cpp
Normal file
17
cockatrice/src/localserver.cpp
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
#include "localserver.h"
|
||||||
|
#include "localserverinterface.h"
|
||||||
|
|
||||||
|
LocalServer::LocalServer(QObject *parent)
|
||||||
|
: Server(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalServer::~LocalServer()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalServerInterface *LocalServer::newConnection()
|
||||||
|
{
|
||||||
|
LocalServerInterface *lsi = new LocalServerInterface(this);
|
||||||
|
return lsi;
|
||||||
|
}
|
||||||
22
cockatrice/src/localserver.h
Normal file
22
cockatrice/src/localserver.h
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
#ifndef LOCALSERVER_H
|
||||||
|
#define LOCALSERVER_H
|
||||||
|
|
||||||
|
#include "server.h"
|
||||||
|
|
||||||
|
class LocalServerInterface;
|
||||||
|
|
||||||
|
class LocalServer : public Server
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
LocalServer(QObject *parent = 0);
|
||||||
|
~LocalServer();
|
||||||
|
AuthenticationResult checkUserPassword(const QString & /*user*/, const QString & /*password*/) { return UnknownUser; }
|
||||||
|
QString getLoginMessage() const { return QString(); }
|
||||||
|
int getMaxGameInactivityTime() const { return 9999999; }
|
||||||
|
int getMaxPlayerInactivityTime() const { return 9999999; }
|
||||||
|
|
||||||
|
LocalServerInterface *newConnection();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
22
cockatrice/src/localserverinterface.cpp
Normal file
22
cockatrice/src/localserverinterface.cpp
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
#include "localserverinterface.h"
|
||||||
|
#include "localserver.h"
|
||||||
|
|
||||||
|
LocalServerInterface::LocalServerInterface(LocalServer *_server)
|
||||||
|
: Server_ProtocolHandler(_server, _server)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalServerInterface::~LocalServerInterface()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LocalServerInterface::sendProtocolItem(ProtocolItem *item, bool deleteItem)
|
||||||
|
{
|
||||||
|
emit itemToClient(item);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocalServerInterface::itemFromClient(ProtocolItem *item)
|
||||||
|
{
|
||||||
|
processCommandContainer(static_cast<CommandContainer *>(item));
|
||||||
|
}
|
||||||
31
cockatrice/src/localserverinterface.h
Normal file
31
cockatrice/src/localserverinterface.h
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
#ifndef LOCALSERVERINTERFACE_H
|
||||||
|
#define LOCALSERVERINTERFACE_H
|
||||||
|
|
||||||
|
#include "server_protocolhandler.h"
|
||||||
|
|
||||||
|
class LocalServer;
|
||||||
|
|
||||||
|
class LocalServerInterface : public Server_ProtocolHandler
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
private:
|
||||||
|
DeckList *getDeckFromDatabase(int /*deckId*/) { return 0; }
|
||||||
|
ResponseCode cmdDeckList(Command_DeckList * /*cmd*/, CommandContainer * /*cont*/) { return RespFunctionNotAllowed; }
|
||||||
|
ResponseCode cmdDeckNewDir(Command_DeckNewDir * /*cmd*/, CommandContainer * /*cont*/) { return RespFunctionNotAllowed; }
|
||||||
|
ResponseCode cmdDeckDelDir(Command_DeckDelDir * /*cmd*/, CommandContainer * /*cont*/) { return RespFunctionNotAllowed; }
|
||||||
|
ResponseCode cmdDeckDel(Command_DeckDel * /*cmd*/, CommandContainer * /*cont*/) { return RespFunctionNotAllowed; }
|
||||||
|
ResponseCode cmdDeckUpload(Command_DeckUpload * /*cmd*/, CommandContainer * /*cont*/) { return RespFunctionNotAllowed; }
|
||||||
|
ResponseCode cmdDeckDownload(Command_DeckDownload * /*cmd*/, CommandContainer * /*cont*/) { return RespFunctionNotAllowed; }
|
||||||
|
public:
|
||||||
|
LocalServerInterface(LocalServer *_server);
|
||||||
|
~LocalServerInterface();
|
||||||
|
|
||||||
|
bool sendProtocolItem(ProtocolItem *item, bool deleteItem = true);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void itemToClient(ProtocolItem *item);
|
||||||
|
public slots:
|
||||||
|
void itemFromClient(ProtocolItem *item);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
138
cockatrice/src/remoteclient.cpp
Normal file
138
cockatrice/src/remoteclient.cpp
Normal file
|
|
@ -0,0 +1,138 @@
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QXmlStreamReader>
|
||||||
|
#include <QXmlStreamWriter>
|
||||||
|
#include "remoteclient.h"
|
||||||
|
#include "protocol.h"
|
||||||
|
#include "protocol_items.h"
|
||||||
|
|
||||||
|
RemoteClient::RemoteClient(QObject *parent)
|
||||||
|
: AbstractClient(parent), topLevelItem(0)
|
||||||
|
{
|
||||||
|
ProtocolItem::initializeHash();
|
||||||
|
|
||||||
|
timer = new QTimer(this);
|
||||||
|
timer->setInterval(1000);
|
||||||
|
connect(timer, SIGNAL(timeout()), this, SLOT(ping()));
|
||||||
|
|
||||||
|
socket = new QTcpSocket(this);
|
||||||
|
connect(socket, SIGNAL(connected()), this, SLOT(slotConnected()));
|
||||||
|
connect(socket, SIGNAL(readyRead()), this, SLOT(readData()));
|
||||||
|
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(slotSocketError(QAbstractSocket::SocketError)));
|
||||||
|
|
||||||
|
xmlReader = new QXmlStreamReader;
|
||||||
|
xmlWriter = new QXmlStreamWriter;
|
||||||
|
xmlWriter->setAutoFormatting(true);
|
||||||
|
xmlWriter->setDevice(socket);
|
||||||
|
}
|
||||||
|
|
||||||
|
RemoteClient::~RemoteClient()
|
||||||
|
{
|
||||||
|
disconnectFromServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoteClient::slotSocketError(QAbstractSocket::SocketError /*error*/)
|
||||||
|
{
|
||||||
|
emit socketError(socket->errorString());
|
||||||
|
disconnectFromServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoteClient::slotConnected()
|
||||||
|
{
|
||||||
|
timer->start();
|
||||||
|
setStatus(StatusAwaitingWelcome);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoteClient::loginResponse(ResponseCode response)
|
||||||
|
{
|
||||||
|
if (response == RespOk)
|
||||||
|
setStatus(StatusLoggedIn);
|
||||||
|
else {
|
||||||
|
emit serverError(response);
|
||||||
|
setStatus(StatusDisconnecting);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoteClient::readData()
|
||||||
|
{
|
||||||
|
QByteArray data = socket->readAll();
|
||||||
|
qDebug() << data;
|
||||||
|
xmlReader->addData(data);
|
||||||
|
|
||||||
|
while (!xmlReader->atEnd()) {
|
||||||
|
xmlReader->readNext();
|
||||||
|
if (topLevelItem)
|
||||||
|
topLevelItem->readElement(xmlReader);
|
||||||
|
else if (xmlReader->isStartElement() && (xmlReader->name().toString() == "cockatrice_server_stream")) {
|
||||||
|
int serverVersion = xmlReader->attributes().value("version").toString().toInt();
|
||||||
|
if (serverVersion != ProtocolItem::protocolVersion) {
|
||||||
|
emit protocolVersionMismatch(ProtocolItem::protocolVersion, serverVersion);
|
||||||
|
disconnectFromServer();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
xmlWriter->writeStartDocument();
|
||||||
|
xmlWriter->writeStartElement("cockatrice_client_stream");
|
||||||
|
xmlWriter->writeAttribute("version", QString::number(ProtocolItem::protocolVersion));
|
||||||
|
|
||||||
|
topLevelItem = new TopLevelProtocolItem;
|
||||||
|
connect(topLevelItem, SIGNAL(protocolItemReceived(ProtocolItem *)), this, SLOT(processProtocolItem(ProtocolItem *)));
|
||||||
|
|
||||||
|
setStatus(StatusLoggingIn);
|
||||||
|
Command_Login *cmdLogin = new Command_Login(userName, password);
|
||||||
|
connect(cmdLogin, SIGNAL(finished(ResponseCode)), this, SLOT(loginResponse(ResponseCode)));
|
||||||
|
sendCommand(cmdLogin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (status == StatusDisconnecting)
|
||||||
|
disconnectFromServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoteClient::sendCommandContainer(CommandContainer *cont)
|
||||||
|
{
|
||||||
|
cont->write(xmlWriter);
|
||||||
|
pendingCommands.insert(cont->getCmdId(), cont);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoteClient::connectToServer(const QString &hostname, unsigned int port, const QString &_userName, const QString &_password)
|
||||||
|
{
|
||||||
|
disconnectFromServer();
|
||||||
|
|
||||||
|
userName = _userName;
|
||||||
|
password = _password;
|
||||||
|
socket->connectToHost(hostname, port);
|
||||||
|
setStatus(StatusConnecting);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoteClient::disconnectFromServer()
|
||||||
|
{
|
||||||
|
delete topLevelItem;
|
||||||
|
topLevelItem = 0;
|
||||||
|
|
||||||
|
xmlReader->clear();
|
||||||
|
|
||||||
|
timer->stop();
|
||||||
|
|
||||||
|
QList<CommandContainer *> pc = pendingCommands.values();
|
||||||
|
for (int i = 0; i < pc.size(); i++)
|
||||||
|
delete pc[i];
|
||||||
|
pendingCommands.clear();
|
||||||
|
|
||||||
|
setStatus(StatusDisconnected);
|
||||||
|
socket->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoteClient::ping()
|
||||||
|
{
|
||||||
|
int maxTime = 0;
|
||||||
|
QMapIterator<int, CommandContainer *> i(pendingCommands);
|
||||||
|
while (i.hasNext()) {
|
||||||
|
int time = i.next().value()->tick();
|
||||||
|
if (time > maxTime)
|
||||||
|
maxTime = time;
|
||||||
|
}
|
||||||
|
emit maxPingTime(maxTime, maxTimeout);
|
||||||
|
if (maxTime >= maxTimeout) {
|
||||||
|
emit serverTimeout();
|
||||||
|
disconnectFromServer();
|
||||||
|
} else
|
||||||
|
sendCommand(new Command_Ping);
|
||||||
|
}
|
||||||
45
cockatrice/src/remoteclient.h
Normal file
45
cockatrice/src/remoteclient.h
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
#ifndef REMOTECLIENT_H
|
||||||
|
#define REMOTECLIENT_H
|
||||||
|
|
||||||
|
#include <QTcpSocket>
|
||||||
|
#include "protocol_datastructures.h"
|
||||||
|
#include "abstractclient.h"
|
||||||
|
|
||||||
|
class QTimer;
|
||||||
|
class QXmlStreamReader;
|
||||||
|
class QXmlStreamWriter;
|
||||||
|
|
||||||
|
class RemoteClient : public AbstractClient {
|
||||||
|
Q_OBJECT
|
||||||
|
signals:
|
||||||
|
void maxPingTime(int seconds, int maxSeconds);
|
||||||
|
void serverTimeout();
|
||||||
|
void socketError(const QString &errorString);
|
||||||
|
void protocolVersionMismatch(int clientVersion, int serverVersion);
|
||||||
|
void protocolError();
|
||||||
|
private slots:
|
||||||
|
void slotConnected();
|
||||||
|
void readData();
|
||||||
|
void slotSocketError(QAbstractSocket::SocketError error);
|
||||||
|
void ping();
|
||||||
|
void loginResponse(ResponseCode response);
|
||||||
|
private:
|
||||||
|
static const int maxTimeout = 10;
|
||||||
|
|
||||||
|
QTimer *timer;
|
||||||
|
QTcpSocket *socket;
|
||||||
|
QXmlStreamReader *xmlReader;
|
||||||
|
QXmlStreamWriter *xmlWriter;
|
||||||
|
TopLevelProtocolItem *topLevelItem;
|
||||||
|
public:
|
||||||
|
RemoteClient(QObject *parent = 0);
|
||||||
|
~RemoteClient();
|
||||||
|
QString peerName() const { return socket->peerName(); }
|
||||||
|
|
||||||
|
void connectToServer(const QString &hostname, unsigned int port, const QString &_userName, const QString &_password);
|
||||||
|
void disconnectFromServer();
|
||||||
|
|
||||||
|
void sendCommandContainer(CommandContainer *cont);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
Loading…
Add table
Add a link
Reference in a new issue