Commit 7921b5f8 authored by Max-Wilhelm Bruker's avatar Max-Wilhelm Bruker
Browse files

initial commit of local server code

parent cbfbc542
......@@ -6,13 +6,15 @@ MOC_DIR = build
OBJECTS_DIR = build
RESOURCES = cockatrice.qrc
QT += network svg
CONFIG += debug
HEADERS += src/counter.h \
src/dlg_creategame.h \
src/dlg_connect.h \
src/dlg_create_token.h \
src/gamesmodel.h \
src/client.h \
src/abstractclient.h \
src/remoteclient.h \
src/window_main.h \
src/cardzone.h \
src/player.h \
......@@ -58,17 +60,33 @@ HEADERS += src/counter.h \
src/playerlistwidget.h \
src/pingpixmapgenerator.h \
src/settingscache.h \
src/localserver.h \
src/localserverinterface.h \
src/localclient.h \
../common/serializable_item.h \
../common/decklist.h \
../common/protocol.h \
../common/protocol_items.h \
../common/protocol_datastructures.h
../common/protocol_datastructures.h \
../common/rng_abstract.h \
../common/rng_qt.h \
../common/server.h \
../common/server_arrow.h \
../common/server_card.h \
../common/server_cardzone.h \
../common/server_chatchannel.h \
../common/server_counter.h \
../common/server_game.h \
../common/server_player.h \
../common/server_protocolhandler.h \
../common/server_arrowtarget.h
SOURCES += src/counter.cpp \
src/dlg_creategame.cpp \
src/dlg_connect.cpp \
src/dlg_create_token.cpp \
src/client.cpp \
src/abstractclient.cpp \
src/remoteclient.cpp \
src/main.cpp \
src/window_main.cpp \
src/gamesmodel.cpp \
......@@ -115,12 +133,24 @@ SOURCES += src/counter.cpp \
src/playerlistwidget.cpp \
src/pingpixmapgenerator.cpp \
src/settingscache.cpp \
src/localserver.cpp \
src/localserverinterface.cpp \
src/localclient.cpp \
../common/serializable_item.cpp \
../common/decklist.cpp \
../common/protocol.cpp \
../common/protocol_items.cpp \
../common/protocol_datastructures.cpp
../common/protocol_datastructures.cpp \
../common/rng_abstract.cpp \
../common/rng_qt.cpp \
../common/server.cpp \
../common/server_card.cpp \
../common/server_cardzone.cpp \
../common/server_chatchannel.cpp \
../common/server_game.cpp \
../common/server_player.cpp \
../common/server_protocolhandler.cpp
TRANSLATIONS += translations/cockatrice_de.ts translations/cockatrice_en.ts
win32 {
RC_FILE = cockatrice.rc
......
#include <QTimer>
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
#include "client.h"
#include "protocol.h"
#include "protocol_items.h"
Client::Client(QObject *parent)
: QObject(parent), topLevelItem(0), status(StatusDisconnected)
{
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);
}
Client::~Client()
{
disconnectFromServer();
}
void Client::slotSocketError(QAbstractSocket::SocketError /*error*/)
{
emit socketError(socket->errorString());
disconnectFromServer();
}
void Client::slotConnected()
{
timer->start();
setStatus(StatusAwaitingWelcome);
}
void Client::loginResponse(ResponseCode response)
{
if (response == RespOk)
setStatus(StatusLoggedIn);
else {
emit serverError(response);
setStatus(StatusDisconnecting);
}
}
void Client::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 Client::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 Client::setStatus(const ClientStatus _status)
{
if (_status != status) {
status = _status;
emit statusChanged(_status);
}
}
void Client::sendCommand(Command *cmd)
{
sendCommandContainer(new CommandContainer(QList<Command *>() << cmd));
}
void Client::sendCommandContainer(CommandContainer *cont)
{
cont->write(xmlWriter);
pendingCommands.insert(cont->getCmdId(), cont);
}
void Client::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 Client::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 Client::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 CLIENT_H
#define CLIENT_H
#include <QTcpSocket>
#include <QColor>
#include <QStringList>
#include <QHash>
#include "protocol_datastructures.h"
class QTimer;
class Command;
class CommandContainer;
class QXmlStreamReader;
class QXmlStreamWriter;
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 Client : public QObject {
Q_OBJECT
signals:
void statusChanged(ClientStatus _status);
void maxPingTime(int seconds, int maxSeconds);
void serverTimeout();
void socketError(const QString &errorString);
void serverError(ResponseCode resp);
void protocolVersionMismatch(int clientVersion, int serverVersion);
void protocolError();
// 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);
private slots:
void slotConnected();
void readData();
void slotSocketError(QAbstractSocket::SocketError error);
void ping();
void loginResponse(ResponseCode response);
void processProtocolItem(ProtocolItem *item);
private:
static const int maxTimeout = 10;
QTimer *timer;
QMap<int, CommandContainer *> pendingCommands;
QTcpSocket *socket;
QXmlStreamReader *xmlReader;
QXmlStreamWriter *xmlWriter;
TopLevelProtocolItem *topLevelItem;
ClientStatus status;
QString userName, password;
void setStatus(ClientStatus _status);
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 &_userName, const QString &_password);
void disconnectFromServer();
void sendCommand(Command *cmd);
void sendCommandContainer(CommandContainer *cont);
};
#endif
#include "counter.h"
#include "player.h"
#include "client.h"
#include "protocol_items.h"
#include <QtGui>
......
......@@ -2,7 +2,7 @@
#include "dlg_creategame.h"
#include "protocol_items.h"
DlgCreateGame::DlgCreateGame(Client *_client, QWidget *parent)
DlgCreateGame::DlgCreateGame(AbstractClient *_client, QWidget *parent)
: QDialog(parent), client(_client)
{
descriptionLabel = new QLabel(tr("&Description:"));
......
......@@ -2,7 +2,7 @@
#define DLG_CREATEGAME_H
#include <QDialog>
#include "client.h"
#include "abstractclient.h"
class QLabel;
class QLineEdit;
......@@ -14,13 +14,13 @@ class QSpinBox;
class DlgCreateGame : public QDialog {
Q_OBJECT
public:
DlgCreateGame(Client *_client, QWidget *parent = 0);
DlgCreateGame(AbstractClient *_client, QWidget *parent = 0);
private slots:
void actOK();
void checkResponse(ResponseCode response);
void spectatorsAllowedChanged(int state);
private:
Client *client;
AbstractClient *client;
QGroupBox *spectatorsGroupBox;
QLabel *descriptionLabel, *passwordLabel, *maxPlayersLabel;
......
......@@ -5,7 +5,7 @@
#include "dlg_load_remote_deck.h"
#include "main.h"
DlgLoadRemoteDeck::DlgLoadRemoteDeck(Client *_client, QWidget *parent)
DlgLoadRemoteDeck::DlgLoadRemoteDeck(AbstractClient *_client, QWidget *parent)
: QDialog(parent), client(_client)
{
dirView = new RemoteDeckList_TreeWidget(client);
......
......@@ -5,19 +5,19 @@
class RemoteDeckList_TreeWidget;
class QModelIndex;
class Client;
class AbstractClient;
class QPushButton;
class DlgLoadRemoteDeck: public QDialog {
Q_OBJECT
private:
Client *client;
AbstractClient *client;
RemoteDeckList_TreeWidget *dirView;
QPushButton *okButton, *cancelButton;
private slots:
void currentItemChanged(const QModelIndex &current, const QModelIndex &previous);
public:
DlgLoadRemoteDeck(Client *_client, QWidget *parent = 0);
DlgLoadRemoteDeck(AbstractClient *_client, QWidget *parent = 0);
int getDeckId() const;
};
......
#include <QtGui>
#include "pilezone.h"
#include "player.h"
#include "client.h"
#include "carddragitem.h"
#include "zoneviewzone.h"
#include "protocol_items.h"
......
#include "player.h"
#include "client.h"
#include "abstractclient.h"
#include "cardzone.h"
#include "playertarget.h"
#include "counter.h"
......@@ -19,8 +19,9 @@
#include <QSettings>
#include <QPainter>
#include <QMenu>
#include <QDebug>
Player::Player(const QString &_name, int _id, bool _local, Client *_client, TabGame *_parent)
Player::Player(const QString &_name, int _id, bool _local, AbstractClient *_client, TabGame *_parent)
: QObject(_parent), defaultNumberTopCards(3), lastTokenDestroy(true), name(_name), id(_id), active(false), local(_local), mirrored(false), client(_client)
{
setCacheMode(DeviceCoordinateCache);
......
......@@ -6,7 +6,7 @@
#include <QMap>
#include "carditem.h"
class Client;
class AbstractClient;
class CardDatabase;
class QMenu;
class QAction;
......@@ -171,8 +171,8 @@ public:
void clearArrows();
PlayerTarget *getPlayerTarget() const { return playerTarget; }
Client *client;
Player(const QString &_name, int _id, bool _local, Client *_client, TabGame *_parent);
AbstractClient *client;
Player(const QString &_name, int _id, bool _local, AbstractClient *_client, TabGame *_parent);
~Player();
void retranslateUi();
QMenu *getPlayerMenu() const { return playerMenu; }
......
......@@ -3,7 +3,7 @@
#include <QSortFilterProxyModel>
#include "remotedecklist_treewidget.h"
#include "protocol_items.h"
#include "client.h"
#include "abstractclient.h"
RemoteDeckList_TreeModel::DirectoryNode::DirectoryNode(const QString &_name, RemoteDeckList_TreeModel::DirectoryNode *_parent)
: RemoteDeckList_TreeModel::Node(_name, _parent)
......@@ -72,7 +72,7 @@ RemoteDeckList_TreeModel::FileNode *RemoteDeckList_TreeModel::DirectoryNode::get
return 0;
}
RemoteDeckList_TreeModel::RemoteDeckList_TreeModel(Client *_client, QObject *parent)
RemoteDeckList_TreeModel::RemoteDeckList_TreeModel(AbstractClient *_client, QObject *parent)
: QAbstractItemModel(parent), client(_client)
{
QFileIconProvider fip;
......@@ -256,7 +256,7 @@ void RemoteDeckList_TreeModel::deckListFinished(ProtocolResponse *r)
emit treeRefreshed();
}
RemoteDeckList_TreeWidget::RemoteDeckList_TreeWidget(Client *_client, QWidget *parent)
RemoteDeckList_TreeWidget::RemoteDeckList_TreeWidget(AbstractClient *_client, QWidget *parent)
: QTreeView(parent)
{
treeModel = new RemoteDeckList_TreeModel(_client, this);
......
......@@ -6,7 +6,7 @@
#include <QTreeView>
class ProtocolResponse;
class Client;
class AbstractClient;
class QSortFilterProxyModel;
class DeckList_File;
class DeckList_Directory;
......@@ -55,7 +55,7 @@ public:
return dynamic_cast<T>(static_cast<Node *>(index.internalPointer()));
}
private:
Client *client;
AbstractClient *client;
DirectoryNode *root;
QIcon fileIcon, dirIcon;
......@@ -66,7 +66,7 @@ signals:
private slots:
void deckListFinished(ProtocolResponse *r);
public:
RemoteDeckList_TreeModel(Client *_client, QObject *parent = 0);
RemoteDeckList_TreeModel(AbstractClient *_client, QObject *parent = 0);
~RemoteDeckList_TreeModel();
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &/*parent*/ = QModelIndex()) const;
......@@ -89,7 +89,7 @@ private:
RemoteDeckList_TreeModel *treeModel;
QSortFilterProxyModel *proxyModel;
public:
RemoteDeckList_TreeWidget(Client *_client, QWidget *parent = 0);
RemoteDeckList_TreeWidget(AbstractClient *_client, QWidget *parent = 0);
RemoteDeckList_TreeModel::Node *getNode(const QModelIndex &ind) const;
RemoteDeckList_TreeModel::Node *getCurrentItem() const;
RemoteDeckList_TreeModel::DirectoryNode *getNodeByPath(const QString &path) const;
......
#include <QtGui>
#include "tab_chatchannel.h"
#include "client.h"
#include "abstractclient.h"
#include "protocol_items.h"
TabChatChannel::TabChatChannel(Client *_client, const QString &_channelName)
TabChatChannel::TabChatChannel(AbstractClient *_client, const QString &_channelName)
: Tab(), client(_client), channelName(_channelName)
{
playerList = new QListWidget;
......
......@@ -3,7 +3,7 @@
#include "tab.h"
class Client;
class AbstractClient;
class QListWidget;
class QTextEdit;
class QLineEdit;
......@@ -16,7 +16,7 @@ class Event_ChatSay;
class TabChatChannel : public Tab {
Q_OBJECT
private:
Client *client;
AbstractClient *client;
QString channelName;
QListWidget *playerList;
......@@ -35,7 +35,7 @@ private slots:
void processLeaveChannelEvent(Event_ChatLeaveChannel *event);
void processSayEvent(Event_ChatSay *event);
public:
TabChatChannel(Client *_client, const QString &_channelName);
TabChatChannel(AbstractClient *_client, const QString &_channelName);
~TabChatChannel();
void retranslateUi();
void processChatEvent(ChatEvent *event);
......
#include <QtGui>
#include "tab_deck_storage.h"
#include "remotedecklist_treewidget.h"
#include "client.h"
#include "abstractclient.h"
#include "decklist.h"
#include "protocol_items.h"
#include "window_deckeditor.h"
TabDeckStorage::TabDeckStorage(Client *_client)
TabDeckStorage::TabDeckStorage(AbstractClient *_client)
: Tab(), client(_client)
{
localDirModel = new QFileSystemModel(this);
......
......@@ -4,7 +4,7 @@
#include "tab.h"
#include "protocol.h"
class Client;
class AbstractClient;
class QTreeView;
class QFileSystemModel;
class QSortFilterProxyModel;
......@@ -18,7 +18,7 @@ class RemoteDeckList_TreeWidget;
class TabDeckStorage : public Tab {
Q_OBJECT
private:
Client *client;
AbstractClient *client;
QTreeView *localDirView;
QFileSystemModel *localDirModel;
QSortFilterProxyModel *sortFilter;
......@@ -45,7 +45,7 @@ private slots:
void actDelete();
void deleteFinished(ResponseCode resp);
public:
TabDeckStorage(Client *_client);
TabDeckStorage(AbstractClient *_client);
void retranslateUi();
QString getTabText() const { return tr("Deck storage"); }
};
......
......@@ -14,7 +14,7 @@
#include "deck_picturecacher.h"
#include "protocol_items.h"
#include "dlg_load_remote_deck.h"
#include "client.h"
#include "abstractclient.h"
#include "carditem.h"
#include "arrowitem.h"
#include "main.h"
......@@ -42,7 +42,7 @@ void ReadyStartButton::setReadyStart(bool _readyStart)
update();
}
TabGame::TabGame(Client *_client, int _gameId, const QString &_gameDescription, int _localPlayerId, bool _spectator, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, bool _resuming)
TabGame::TabGame(AbstractClient *_client, int _gameId, const QString &_gameDescription, int _localPlayerId, bool _spectator, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, bool _resuming)
: Tab(), client(_client), gameId(_gameId), gameDescription(_gameDescription), localPlayerId(_localPlayerId), spectator(_spectator), spectatorsCanTalk(_spectatorsCanTalk), spectatorsSeeEverything(_spectatorsSeeEverything), started(false), resuming(_resuming), currentPhase(-1)
{
scene = new GameScene(this);
......
......@@ -5,7 +5,7 @@
#include <QPushButton>
#include "tab.h"
class Client;
class AbstractClient;
class CardDatabase;
class GameView;
class DeckView;
......@@ -55,7 +55,7 @@ protected:
class TabGame : public Tab {
Q_OBJECT
private:
Client *client;
AbstractClient *client;
int gameId;
QString gameDescription;
int localPlayerId;
......@@ -120,7 +120,7 @@ private slots:
void actNextPhase();
void actNextTurn();
public:
TabGame(Client *_client, int _gameId, const QString &_gameDescription, int _localPlayerId, bool _spectator, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, bool _resuming);
TabGame(AbstractClient *_client, int _gameId, const QString &_gameDescription, int _localPlayerId, bool _spectator, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, bool _resuming);
~TabGame();
void retranslateUi();
const QMap<int, Player *> &getPlayers() const { return players; }
......
......@@ -2,11 +2,11 @@
#include "tab_server.h"
#include "gamesmodel.h"
#include "dlg_creategame.h"
#include "client.h"
#include "abstractclient.h"
#include "protocol.h"
#include "protocol_items.h"
GameSelector::GameSelector(Client *_client, QWidget *parent)
GameSelector::GameSelector(AbstractClient *_client, QWidget *parent)
: QGroupBox(parent), client(_client)
{
gameListView = new QTreeView;
......@@ -113,7 +113,7 @@ void GameSelector::processListGamesEvent(Event_ListGames *event)
gameListModel->updateGameList(gamesToUpdate[i]);
}
ChatChannelSelector::ChatChannelSelector(Client *_client, QWidget *parent)
ChatChannelSelector::ChatChannelSelector(AbstractClient *_client, QWidget *parent)
: QGroupBox(parent), client(_client)
{
channelList = new QTreeWidget;
......@@ -200,7 +200,7 @@ void ChatChannelSelector::joinFinished(ResponseCode resp)
emit channelJoined(channelName);
}
ServerMessageLog::ServerMessageLog(Client *_client, QWidget *parent)
ServerMessageLog::ServerMessageLog(AbstractClient *_client, QWidget *parent)
: QGroupBox(parent)
{
textEdit = new QTextEdit;
......@@ -225,7 +225,7 @@ void ServerMessageLog::processServerMessageEvent(Event_ServerMessage *event)
textEdit->append(event->getMessage());
}
TabServer::TabServer(Client *_client, QWidget *parent)
TabServer::TabServer(AbstractClient *_client, QWidget *parent)
: Tab(parent), client(_client)
{
gameSelector = new GameSelector(client);
......
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