Commit 58e803c3 authored by Max-Wilhelm Bruker's avatar Max-Wilhelm Bruker
Browse files

new files

parent 7921b5f8
#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));
}
#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
\ No newline at end of file
#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);
}
#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
\ No newline at end of file
#include "localserver.h"
#include "localserverinterface.h"
LocalServer::LocalServer(QObject *parent)
: Server(parent)
{
}
LocalServer::~LocalServer()
{
}
LocalServerInterface *LocalServer::newConnection()
{
LocalServerInterface *lsi = new LocalServerInterface(this);
return lsi;
}
#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
\ No newline at end of file
#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));
}
#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
\ No newline at end of file
#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);
}
#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
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment