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

restructured protocol code

parent 122f8ea9
......@@ -4,9 +4,7 @@
#include <QString>
#include <QColor>
#include <QDateTime>
class QXmlStreamReader;
class QXmlStreamWriter;
#include "serializable_item.h"
enum ResponseCode { RespNothing, RespOk, RespInvalidCommand, RespInvalidData, RespNameNotFound, RespLoginNeeded, RespContextError, RespWrongPassword, RespSpectatorsNotAllowed };
......@@ -20,210 +18,124 @@ enum ResponseCode { RespNothing, RespOk, RespInvalidCommand, RespInvalidData, Re
// list index, whereas cards in any other zone are referenced by their ids.
enum ZoneType { PrivateZone, PublicZone, HiddenZone };
class ColorConverter {
class ServerInfo_ChatChannel : public SerializableItem_Map {
public:
static int colorToInt(const QColor &color)
{
return color.red() * 65536 + color.green() * 256 + color.blue();
}
static QColor colorFromInt(int colorValue)
{
return QColor(colorValue / 65536, (colorValue % 65536) / 256, colorValue % 256);
}
ServerInfo_ChatChannel(const QString &_name = QString(), const QString &_description = QString(), int _playerCount = -1, bool _autoJoin = false);
static SerializableItem *newItem() { return new ServerInfo_ChatChannel; }
QString getName() const { return static_cast<SerializableItem_String *>(itemMap.value("name"))->getData(); }
QString getDescription() const { return static_cast<SerializableItem_String *>(itemMap.value("description"))->getData(); }
int getPlayerCount() const { return static_cast<SerializableItem_Int *>(itemMap.value("player_count"))->getData(); }
bool getAutoJoin() const { return static_cast<SerializableItem_Bool *>(itemMap.value("auto_join"))->getData(); }
};
class SerializableItem {
protected:
SerializableItem *currentItem;
class ServerInfo_ChatUser : public SerializableItem_Map {
public:
SerializableItem() : currentItem(0) { }
virtual bool readElement(QXmlStreamReader *xml) = 0;
virtual void writeElement(QXmlStreamWriter *xml) = 0;
ServerInfo_ChatUser(const QString &_name = QString());
static SerializableItem *newItem() { return new ServerInfo_ChatUser; }
QString getName() const { return static_cast<SerializableItem_String *>(itemMap.value("name"))->getData(); }
};
class ServerChatChannelInfo {
private:
QString name;
QString description;
int playerCount;
bool autoJoin;
class ServerInfo_Game : public SerializableItem_Map {
public:
ServerChatChannelInfo(const QString &_name, const QString &_description, int _playerCount, bool _autoJoin)
: name(_name), description(_description), playerCount(_playerCount), autoJoin(_autoJoin) { }
QString getName() const { return name; }
QString getDescription() const { return description; }
int getPlayerCount() const { return playerCount; }
bool getAutoJoin() const { return autoJoin; }
ServerInfo_Game(int _gameId = -1, const QString &_description = QString(), bool _hasPassword = false, int _playerCount = -1, int _maxPlayers = -1, const QString &_creatorName = QString(), bool _spectatorsAllowed = false, int _spectatorCount = -1);
static SerializableItem *newItem() { return new ServerInfo_Game; }
int getGameId() const { return static_cast<SerializableItem_Int *>(itemMap.value("game_id"))->getData(); }
QString getDescription() const { return static_cast<SerializableItem_String *>(itemMap.value("description"))->getData(); }
bool getHasPassword() const { return static_cast<SerializableItem_Bool *>(itemMap.value("has_password"))->getData(); }
int getPlayerCount() const { return static_cast<SerializableItem_Int *>(itemMap.value("player_count"))->getData(); }
int getMaxPlayers() const { return static_cast<SerializableItem_Int *>(itemMap.value("max_players"))->getData(); }
QString getCreatorName() const { return static_cast<SerializableItem_String *>(itemMap.value("creator_name"))->getData(); }
bool getSpectatorsAllowed() const { return static_cast<SerializableItem_Bool *>(itemMap.value("spectators_allowed"))->getData(); }
int getSpectatorCount() const { return static_cast<SerializableItem_Int *>(itemMap.value("spectator_count"))->getData(); }
};
class ServerChatUserInfo {
private:
QString name;
class ServerInfo_Card : public SerializableItem_Map {
public:
ServerChatUserInfo(const QString &_name)
: name(_name) { }
QString getName() const { return name; }
ServerInfo_Card(int _id = -1, const QString &_name = QString(), int _x = -1, int _y = -1, int _counters = -1, bool _tapped = false, bool _attacking = false, const QString &_annotation = QString());
static SerializableItem *newItem() { return new ServerInfo_Card; }
int getId() const { return static_cast<SerializableItem_Int *>(itemMap.value("id"))->getData(); }
QString getName() const { return static_cast<SerializableItem_String *>(itemMap.value("name"))->getData(); }
int getX() const { return static_cast<SerializableItem_Int *>(itemMap.value("x"))->getData(); }
int getY() const { return static_cast<SerializableItem_Int *>(itemMap.value("y"))->getData(); }
int getCounters() const { return static_cast<SerializableItem_Int *>(itemMap.value("counters"))->getData(); }
bool getTapped() const { return static_cast<SerializableItem_Bool *>(itemMap.value("tapped"))->getData(); }
bool getAttacking() const { return static_cast<SerializableItem_Bool *>(itemMap.value("attacking"))->getData(); }
QString getAnnotation() const { return static_cast<SerializableItem_String *>(itemMap.value("annotation"))->getData(); }
};
class ServerGameInfo {
class ServerInfo_Zone : public SerializableItem_Map {
private:
int gameId;
QString description;
bool hasPassword;
int playerCount;
int maxPlayers;
QString creatorName;
bool spectatorsAllowed;
int spectatorCount;
ZoneType typeFromString(const QString &type) const;
QString typeToString(ZoneType type) const;
public:
ServerGameInfo(int _gameId, const QString &_description, bool _hasPassword, int _playerCount, int _maxPlayers, const QString &_creatorName, bool _spectatorsAllowed, int _spectatorCount)
: gameId(_gameId), description(_description), hasPassword(_hasPassword), playerCount(_playerCount), maxPlayers(_maxPlayers), creatorName(_creatorName), spectatorsAllowed(_spectatorsAllowed), spectatorCount(_spectatorCount) { }
int getGameId() const { return gameId; }
QString getDescription() const { return description; }
bool getHasPassword() const { return hasPassword; }
int getPlayerCount() const { return playerCount; }
int getMaxPlayers() const { return maxPlayers; }
QString getCreatorName() const { return creatorName; }
bool getSpectatorsAllowed() const { return spectatorsAllowed; }
int getSpectatorCount() const { return spectatorCount; }
ServerInfo_Zone(const QString &_name = QString(), ZoneType _type = PrivateZone, bool _hasCoords = false, int _cardCount = -1, const QList<ServerInfo_Card *> &_cardList = QList<ServerInfo_Card *>());
static SerializableItem *newItem() { return new ServerInfo_Zone; }
QString getName() const { return static_cast<SerializableItem_String *>(itemMap.value("name"))->getData(); }
ZoneType getType() const { return typeFromString(static_cast<SerializableItem_String *>(itemMap.value("type"))->getData()); }
bool getHasCoords() const { return static_cast<SerializableItem_Bool *>(itemMap.value("has_coords"))->getData(); }
int getCardCount() const { return static_cast<SerializableItem_Int *>(itemMap.value("card_count"))->getData(); }
QList<ServerInfo_Card *> getCardList() const;
};
class ServerInfo_Card : public SerializableItem {
private:
int id;
QString name;
int x, y;
int counters;
bool tapped;
bool attacking;
QString annotation;
class ServerInfo_Counter : public SerializableItem_Map {
public:
ServerInfo_Card(int _id = -1, const QString &_name = QString(), int _x = -1, int _y = -1, int _counters = -1, bool _tapped = false, bool _attacking = false, const QString &_annotation = QString())
: id(_id), name(_name), x(_x), y(_y), counters(_counters), tapped(_tapped), attacking(_attacking), annotation(_annotation) { }
int getId() const { return id; }
QString getName() const { return name; }
int getX() const { return x; }
int getY() const { return y; }
int getCounters() const { return counters; }
bool getTapped() const { return tapped; }
bool getAttacking() const { return attacking; }
QString getAnnotation() const { return annotation; }
bool readElement(QXmlStreamReader *xml);
void writeElement(QXmlStreamWriter *xml);
ServerInfo_Counter(int _id = -1, const QString &_name = QString(), const QColor &_color = QColor(), int _radius = -1, int _count = -1);
static SerializableItem *newItem() { return new ServerInfo_Counter; }
int getId() const { return static_cast<SerializableItem_Int *>(itemMap.value("id"))->getData(); }
QString getName() const { return static_cast<SerializableItem_String *>(itemMap.value("name"))->getData(); }
QColor getColor() const { return static_cast<SerializableItem_Color *>(itemMap.value("color"))->getData(); }
int getRadius() const { return static_cast<SerializableItem_Int *>(itemMap.value("radius"))->getData(); }
int getCount() const { return static_cast<SerializableItem_Int *>(itemMap.value("count"))->getData(); }
};
class ServerInfo_Zone : public SerializableItem {
private:
QString name;
ZoneType type;
bool hasCoords;
int cardCount;
QList<ServerInfo_Card *> cardList;
class ServerInfo_Arrow : public SerializableItem_Map {
public:
ServerInfo_Zone(const QString &_name = QString(), ZoneType _type = PrivateZone, bool _hasCoords = false, int _cardCount = -1, const QList<ServerInfo_Card *> &_cardList = QList<ServerInfo_Card *>())
: name(_name), type(_type), hasCoords(_hasCoords), cardCount(_cardCount), cardList(_cardList) { }
~ServerInfo_Zone();
QString getName() const { return name; }
ZoneType getType() const { return type; }
bool getHasCoords() const { return hasCoords; }
int getCardCount() const { return cardCount; }
const QList<ServerInfo_Card *> &getCardList() const { return cardList; }
void addCard(ServerInfo_Card *card) { cardList.append(card); ++cardCount; }
bool readElement(QXmlStreamReader *xml);
void writeElement(QXmlStreamWriter *xml);
ServerInfo_Arrow(int _id = -1, int _startPlayerId = -1, const QString &_startZone = QString(), int _startCardId = -1, int _targetPlayerId = -1, const QString &_targetZone = QString(), int _targetCardId = -1, const QColor &_color = QColor());
static SerializableItem *newItem() { return new ServerInfo_Arrow; }
int getId() const { return static_cast<SerializableItem_Int *>(itemMap.value("id"))->getData(); }
int getStartPlayerId() const { return static_cast<SerializableItem_Int *>(itemMap.value("start_player_id"))->getData(); }
QString getStartZone() const { return static_cast<SerializableItem_String *>(itemMap.value("start_zone"))->getData(); }
int getStartCardId() const { return static_cast<SerializableItem_Int *>(itemMap.value("start_card_id"))->getData(); }
int getTargetPlayerId() const { return static_cast<SerializableItem_Int *>(itemMap.value("target_player_id"))->getData(); }
QString getTargetZone() const { return static_cast<SerializableItem_String *>(itemMap.value("target_zone"))->getData(); }
int getTargetCardId() const { return static_cast<SerializableItem_Int *>(itemMap.value("target_card_id"))->getData(); }
QColor getColor() const { return static_cast<SerializableItem_Color *>(itemMap.value("color"))->getData(); }
};
class ServerInfo_Counter : public SerializableItem {
class ServerInfo_Player : public SerializableItem_Map {
private:
int id;
QString name;
QColor color;
int radius;
int count;
public:
ServerInfo_Counter(int _id = -1, const QString &_name = QString(), const QColor &_color = QColor(), int _radius = -1, int _count = -1)
: id(_id), name(_name), color(_color), radius(_radius), count(_count) { }
int getId() const { return id; }
QString getName() const { return name; }
QColor getColor() const { return color; }
int getRadius() const { return radius; }
int getCount() const { return count; }
bool readElement(QXmlStreamReader *xml);
void writeElement(QXmlStreamWriter *xml);
};
class ServerInfo_Arrow : public SerializableItem {
private:
int id;
int startPlayerId;
QString startZone;
int startCardId;
int targetPlayerId;
QString targetZone;
int targetCardId;
QColor color;
public:
ServerInfo_Arrow(int _id = -1, int _startPlayerId = -1, const QString &_startZone = QString(), int _startCardId = -1, int _targetPlayerId = -1, const QString &_targetZone = QString(), int _targetCardId = -1, const QColor &_color = QColor())
: id(_id), startPlayerId(_startPlayerId), startZone(_startZone), startCardId(_startCardId), targetPlayerId(_targetPlayerId), targetZone(_targetZone), targetCardId(_targetCardId), color(_color) { }
int getId() const { return id; }
int getStartPlayerId() const { return startPlayerId; }
QString getStartZone() const { return startZone; }
int getStartCardId() const { return startCardId; }
int getTargetPlayerId() const { return targetPlayerId; }
QString getTargetZone() const { return targetZone; }
int getTargetCardId() const { return targetCardId; }
QColor getColor() const { return color; }
bool readElement(QXmlStreamReader *xml);
void writeElement(QXmlStreamWriter *xml);
};
class ServerInfo_Player : public SerializableItem {
private:
int playerId;
QString name;
QList<ServerInfo_Zone *> zoneList;
QList<ServerInfo_Counter *> counterList;
QList<ServerInfo_Arrow *> arrowList;
protected:
void extractData();
public:
ServerInfo_Player(int _playerId = -1, const QString &_name = QString(), const QList<ServerInfo_Zone *> &_zoneList = QList<ServerInfo_Zone *>(), const QList<ServerInfo_Counter *> &_counterList = QList<ServerInfo_Counter *>(), const QList<ServerInfo_Arrow *> &_arrowList = QList<ServerInfo_Arrow *>())
: playerId(_playerId), name(_name), zoneList(_zoneList), counterList(_counterList), arrowList(_arrowList) { }
~ServerInfo_Player();
int getPlayerId() const { return playerId; }
QString getName() const { return name; }
ServerInfo_Player(int _playerId = -1, const QString &_name = QString(), const QList<ServerInfo_Zone *> &_zoneList = QList<ServerInfo_Zone *>(), const QList<ServerInfo_Counter *> &_counterList = QList<ServerInfo_Counter *>(), const QList<ServerInfo_Arrow *> &_arrowList = QList<ServerInfo_Arrow *>());
static SerializableItem *newItem() { return new ServerInfo_Player; }
int getPlayerId() const { return static_cast<SerializableItem_Int *>(itemMap.value("player_id"))->getData(); }
QString getName() const { return static_cast<SerializableItem_String *>(itemMap.value("name"))->getData(); }
const QList<ServerInfo_Zone *> &getZoneList() const { return zoneList; }
const QList<ServerInfo_Counter *> &getCounterList() const { return counterList; }
const QList<ServerInfo_Arrow *> &getArrowList() const { return arrowList; }
void addZone(ServerInfo_Zone *zone) { zoneList.append(zone); }
void addCounter(ServerInfo_Counter *counter) { counterList.append(counter); }
void addArrow(ServerInfo_Arrow *arrow) { arrowList.append(arrow); }
bool readElement(QXmlStreamReader *xml);
void writeElement(QXmlStreamWriter *xml);
};
class DeckList_TreeItem : public SerializableItem {
protected:
QString name;
int id;
class DeckList_TreeItem : public SerializableItem_Map {
public:
DeckList_TreeItem(const QString &_name, int _id) : name(_name), id(_id) { }
QString getName() const { return name; }
int getId() const { return id; }
DeckList_TreeItem(const QString &_itemType, const QString &_name, int _id);
QString getName() const { return static_cast<SerializableItem_String *>(itemMap.value("name"))->getData(); }
int getId() const { return static_cast<SerializableItem_Int *>(itemMap.value("id"))->getData(); }
};
class DeckList_File : public DeckList_TreeItem {
private:
QDateTime uploadTime;
public:
DeckList_File(const QString &_name, int _id, QDateTime _uploadTime) : DeckList_TreeItem(_name, _id), uploadTime(_uploadTime) { }
bool readElement(QXmlStreamReader *xml);
void writeElement(QXmlStreamWriter *xml);
QDateTime getUploadTime() const { return uploadTime; }
DeckList_File(const QString &_name = QString(), int _id = -1, QDateTime _uploadTime = QDateTime());
static SerializableItem *newItem() { return new DeckList_File; }
QDateTime getUploadTime() const { return static_cast<SerializableItem_DateTime *>(itemMap.value("upload_time"))->getData(); }
};
class DeckList_Directory : public DeckList_TreeItem, public QList<DeckList_TreeItem *> {
class DeckList_Directory : public DeckList_TreeItem {
public:
DeckList_Directory(const QString &_name = QString(), int _id = 0) : DeckList_TreeItem(_name, _id) { }
~DeckList_Directory();
bool readElement(QXmlStreamReader *xml);
void writeElement(QXmlStreamWriter *xml);
DeckList_Directory(const QString &_name = QString(), int _id = 0);
static SerializableItem *newItem() { return new DeckList_Directory; }
QList<DeckList_TreeItem *> getTreeItems() const { return typecastItemList<DeckList_TreeItem *>(); }
};
#endif
This diff is collapsed.
This diff is collapsed.
......@@ -70,12 +70,9 @@ while (<file>) {
$className = $namePrefix . '_' . $name2;
$itemEnum .= "ItemId_$className = " . ++$itemId . ",\n";
$headerfileBuffer .= "class $className : public $baseClass {\n"
. "\tQ_OBJECT\n"
. "private:\n";
$paramStr2 = '';
$paramStr3 = '';
$paramStr4 = '';
$paramStr5 = '';
. "\tQ_OBJECT\n";
$constructorCode = '';
$getFunctionCode = '';
while ($param = shift(@line)) {
($key, $value) = split(/,/, $param);
($prettyVarName = $value) =~ s/_(.)/\U$1\E/g;
......@@ -85,52 +82,44 @@ while (<file>) {
if (!($constructorParamsCpp eq '')) {
$constructorParamsCpp .= ', ';
}
$paramStr2 .= ", $prettyVarName(_$prettyVarName)";
$paramStr3 .= "\tsetParameter(\"$value\", $prettyVarName);\n";
($prettyVarName2 = $prettyVarName) =~ s/^(.)/\U$1\E/;
if ($key eq 'b') {
$dataType = 'bool';
$constructorParamsH .= "bool _$prettyVarName = false";
$constructorParamsCpp .= "bool _$prettyVarName";
$paramStr5 .= "\t$prettyVarName = (parameters[\"$value\"] == \"1\");\n";
$constructorCode .= "\tinsertItem(new SerializableItem_Bool(\"$value\", _$prettyVarName));\n";
$getFunctionCode .= "\t$dataType get$prettyVarName2() const { return static_cast<SerializableItem_Bool *>(itemMap.value(\"$value\"))->getData(); };\n";
} elsif ($key eq 's') {
$dataType = 'QString';
$constructorParamsH .= "const QString &_$prettyVarName = QString()";
$constructorParamsCpp .= "const QString &_$prettyVarName";
$paramStr5 .= "\t$prettyVarName = parameters[\"$value\"];\n";
$constructorCode .= "\tinsertItem(new SerializableItem_String(\"$value\", _$prettyVarName));\n";
$getFunctionCode .= "\t$dataType get$prettyVarName2() const { return static_cast<SerializableItem_String *>(itemMap.value(\"$value\"))->getData(); };\n";
} elsif ($key eq 'i') {
$dataType = 'int';
$constructorParamsH .= "int _$prettyVarName = -1";
$constructorParamsCpp .= "int _$prettyVarName";
$paramStr5 .= "\t$prettyVarName = parameters[\"$value\"].toInt();\n";
$constructorCode .= "\tinsertItem(new SerializableItem_Int(\"$value\", _$prettyVarName));\n";
$getFunctionCode .= "\t$dataType get$prettyVarName2() const { return static_cast<SerializableItem_Int *>(itemMap.value(\"$value\"))->getData(); };\n";
} elsif ($key eq 'c') {
$dataType = 'QColor';
$constructorParamsH .= "const QColor &_$prettyVarName = QColor()";
$constructorParamsCpp .= "const QColor &_$prettyVarName";
$paramStr5 .= "\t$prettyVarName = ColorConverter::colorFromInt(parameters[\"$value\"].toInt());\n";
$constructorCode .= "\tinsertItem(new SerializableItem_Color(\"$value\", _$prettyVarName));\n";
$getFunctionCode .= "\t$dataType get$prettyVarName2() const { return static_cast<SerializableItem_Color *>(itemMap.value(\"$value\"))->getData(); };\n";
}
($prettyVarName2 = $prettyVarName) =~ s/^(.)/\U$1\E/;
$paramStr4 .= "\t$dataType get$prettyVarName2() const { return $prettyVarName; }\n";
$headerfileBuffer .= "\t$dataType $prettyVarName;\n";
}
$headerfileBuffer .= "public:\n"
. "\t$className($constructorParamsH);\n"
. $paramStr4
. "\tstatic ProtocolItem *newItem() { return new $className; }\n"
. $getFunctionCode
. "\tstatic SerializableItem *newItem() { return new $className; }\n"
. "\tint getItemId() const { return ItemId_$className; }\n"
. ($paramStr5 eq '' ? '' : "protected:\n\tvoid extractParameters();\n")
. "};\n";
print cppfile $className . "::$className($constructorParamsCpp)\n"
. "\t: $parentConstructorCall$paramStr2\n"
. "\t: $parentConstructorCall\n"
. "{\n"
. $paramStr3
. $constructorCode
. "}\n";
if (!($paramStr5 eq '')) {
print cppfile "void $className" . "::extractParameters()\n"
. "{\n"
. "\t$baseClass" . "::extractParameters();\n"
. $paramStr5
. "}\n";
}
$initializeHash .= "\titemNameHash.insert(\"$type$name1\", $className" . "::newItem);\n";
}
close(file);
......
#include "serializable_item.h"
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
#include <QDebug>
QHash<QString, SerializableItem::NewItemFunction> SerializableItem::itemNameHash;
SerializableItem *SerializableItem::getNewItem(const QString &name)
{
if (!itemNameHash.contains(name))
return 0;
return itemNameHash.value(name)();
}
void SerializableItem::registerSerializableItem(const QString &name, NewItemFunction func)
{
itemNameHash.insert(name, func);
}
bool SerializableItem::read(QXmlStreamReader *xml)
{
while (!xml->atEnd()) {
xml->readNext();
readElement(xml);
if (xml->isEndElement() && (xml->name() == itemType))
return true;
}
return false;
}
void SerializableItem::write(QXmlStreamWriter *xml)
{
xml->writeStartElement(itemType);
if (!itemSubType.isEmpty())
xml->writeAttribute("type", itemSubType);
writeElement(xml);
xml->writeEndElement();
}
SerializableItem_Map::~SerializableItem_Map()
{
QMapIterator<QString, SerializableItem *> mapIterator(itemMap);
while (mapIterator.hasNext())
delete mapIterator.next().value();
for (int i = 0; i < itemList.size(); ++i)
delete itemList[i];
}
void SerializableItem_Map::readElement(QXmlStreamReader *xml)
{
if (currentItem) {
if (currentItem->read(xml))
currentItem = 0;
} else if (xml->isEndElement() && (xml->name() == itemType))
extractData();
else if (xml->isStartElement()) {
QString childName = xml->name().toString();
QString childSubType = xml->attributes().value("type").toString();
qDebug() << "Map: started new item, name=" << childName << "subtype=" << childSubType;
currentItem = itemMap.value(childName);
if (!currentItem) {
qDebug() << "Item not found in map";
currentItem = getNewItem(childName + childSubType);
itemList.append(currentItem);
if (!currentItem) {
qDebug() << "Item still not found";
currentItem = new SerializableItem_Invalid(childName);
}
}
if (currentItem->read(xml))
currentItem = 0;
}
}
void SerializableItem_Map::writeElement(QXmlStreamWriter *xml)
{
QMapIterator<QString, SerializableItem *> mapIterator(itemMap);
while (mapIterator.hasNext())
mapIterator.next().value()->write(xml);
for (int i = 0; i < itemList.size(); ++i)
itemList[i]->write(xml);
}
void SerializableItem_String::readElement(QXmlStreamReader *xml)
{
if (xml->isCharacters() && !xml->isWhitespace())
data = xml->text().toString();
}
void SerializableItem_String::writeElement(QXmlStreamWriter *xml)
{
xml->writeCharacters(data);
}
void SerializableItem_Int::readElement(QXmlStreamReader *xml)
{
if (xml->isCharacters() && !xml->isWhitespace()) {
bool ok;
data = xml->text().toString().toInt(&ok);
if (!ok)
data = -1;
}
}
void SerializableItem_Int::writeElement(QXmlStreamWriter *xml)
{
xml->writeCharacters(QString::number(data));
}
void SerializableItem_Bool::readElement(QXmlStreamReader *xml)
{
if (xml->isCharacters() && !xml->isWhitespace())
data = xml->text().toString() == "1";
}
void SerializableItem_Bool::writeElement(QXmlStreamWriter *xml)
{
xml->writeCharacters(data ? "1" : "0");
}
int SerializableItem_Color::colorToInt(const QColor &color) const
{
return color.red() * 65536 + color.green() * 256 + color.blue();
}
QColor SerializableItem_Color::colorFromInt(int colorValue) const
{
return QColor(colorValue / 65536, (colorValue % 65536) / 256, colorValue % 256);
}
void SerializableItem_Color::readElement(QXmlStreamReader *xml)
{
if (xml->isCharacters() && !xml->isWhitespace()) {
bool ok;
int colorValue = xml->text().toString().toInt(&ok);
data = ok ? colorFromInt(colorValue) : Qt::black;
}
}
void SerializableItem_Color::writeElement(QXmlStreamWriter *xml)
{
xml->writeCharacters(QString::number(colorToInt(data)));
}
void SerializableItem_DateTime::readElement(QXmlStreamReader *xml)
{
if (xml->isCharacters() && !xml->isWhitespace()) {
bool ok;
unsigned int dateTimeValue = xml->text().toString().toUInt(&ok);
data = ok ? QDateTime::fromTime_t(dateTimeValue) : QDateTime();
}
}
void SerializableItem_DateTime::writeElement(QXmlStreamWriter *xml)
{
xml->writeCharacters(QString::number(data.toTime_t()));
}
#ifndef SERIALIZABLE_ITEM_H
#define SERIALIZABLE_ITEM_H
#include <QObject>
#include <QMap>
#include <QList>
#include <QHash>
#include <QColor>
#include <QDateTime>
class QXmlStreamReader;
class QXmlStreamWriter;
class SerializableItem : public QObject {
Q_OBJECT
protected:
typedef SerializableItem *(*NewItemFunction)();
static QHash<QString, NewItemFunction> itemNameHash;
QString itemType, itemSubType;
public:
SerializableItem(const QString &_itemType, const QString &_itemSubType = QString())
: QObject(), itemType(_itemType), itemSubType(_itemSubType) { }
static void registerSerializableItem(const QString &name, NewItemFunction func);
static SerializableItem *getNewItem(const QString &name);
const QString &getItemType() const { return itemType; }
const QString &getItemSubType() const { return itemSubType; }
virtual void readElement(QXmlStreamReader *xml) = 0;
virtual void writeElement(QXmlStreamWriter *xml) = 0;
bool read(QXmlStreamReader *xml);
void write(QXmlStreamWriter *xml);
};
class SerializableItem_Invalid : public SerializableItem {
public:
SerializableItem_Invalid(const QString &_itemType) : SerializableItem(_itemType) { }
void readElement(QXmlStreamReader * /*xml*/) { }
void writeElement(QXmlStreamWriter * /*xml*/) { }
};
class SerializableItem_Map : public SerializableItem {
private:
SerializableItem *currentItem;
protected:
QMap<QString, SerializableItem *> itemMap;
QList<SerializableItem *> itemList;
virtual void extractData() { }
void insertItem(SerializableItem *item)
{
itemMap.insert(item->getItemType(), item);
}
template<class T> QList<T> typecastItemList() const
{
QList<T> result;
for (int i = 0; i < itemList.size(); ++i) {
T item = dynamic_cast<T>(itemList[i]);
if (item)
result.append(item);
}
return result;
}
public:
SerializableItem_Map(const QString &_itemType, const QString &_itemSubType = QString())
: SerializableItem(_itemType, _itemSubType), currentItem(0)
{
}
~SerializableItem_Map();
void readElement(QXmlStreamReader *xml);
void writeElement(QXmlStreamWriter *xml);
void appendItem(SerializableItem *item) { itemList.append(item); }
};
class SerializableItem_String : public SerializableItem {
private:
QString data;
protected:
void readElement(QXmlStreamReader *xml);
void writeElement(QXmlStreamWriter *xml);
public:
SerializableItem_String(const QString &_itemType, const QString &_data)
: SerializableItem(_itemType), data(_data) { }
const QString &getData() { return data; }
void setData(const QString &_data) { data = _data; }
};
class SerializableItem_Int : public SerializableItem {
private:
int data;
protected:
void readElement(QXmlStreamReader *xml);
void writeElement(QXmlStreamWriter *xml);
public:
SerializableItem_Int(const QString &_itemType, int _data)
: SerializableItem(_itemType), data(_data) { }
int getData() { return data; }
void setData(int _data) { data = _data; }
};
class SerializableItem_Bool : public SerializableItem {
private:
bool data;
protected:
void readElement(QXmlStreamReader *xml);
void writeElement(QXmlStreamWriter *xml);
public:
SerializableItem_Bool(const QString &_itemType, bool _data)
: SerializableItem(_itemType), data(_data) { }
bool getData() { return data; }
void setData(bool _data) { data = _data; }
};
class SerializableItem_Color : public SerializableItem {
private:
QColor data;
int colorToInt(const QColor &color) const;
QColor colorFromInt(int colorValue) const;
protected:
void readElement(QXmlStreamReader *xml);
void writeElement(QXmlStreamWriter *xml);
public:
SerializableItem_Color(const QString &_itemType, const QColor &_data)
: SerializableItem(_itemType), data(_data) { }
const QColor &getData() { return data; }
void setData(const QColor &_data) { data = _data; }
};
class SerializableItem_DateTime : public SerializableItem {
private:
QDateTime data;
protected:
void readElement(QXmlStreamReader *xml);
void writeElement(QXmlStreamWriter *xml);
public:
SerializableItem_DateTime(const QString &_itemType, const QDateTime &_data)
: SerializableItem(_itemType), data(_data) { }
const QDateTime &getData() { return data; }
void setData(const QDateTime &_data) { data = _data; }
};
#endif
......@@ -61,10 +61,10 @@ Server_Game *Server::getGame(int gameId) const
void Server::broadcastGameListUpdate(Server_Game *game)
{
Event_ListGames *event = new Event_ListGames;
QList<ServerInfo_Game *> eventGameList;
if (game->getPlayerCount())
// Game is open
event->addGame(
eventGameList.append(new ServerInfo_Game(
game->getGameId(),
game->getDescription(),
!game->getPassword().isEmpty(),
......@@ -73,10 +73,11 @@ void Server::broadcastGameListUpdate(Server_Game *game)
game->getCreatorName(),
game->getSpectatorsAllowed(),
game->getSpectatorCount()
);
));
else
// Game is closing
event->addGame(game->getGameId(), QString(), false, 0, game->getMaxPlayers(), QString(), false, 0);
eventGameList.append(new ServerInfo_Game(game->getGameId(), QString(), false, 0, game->getMaxPlayers(), QString(), false, 0));
Event_ListGames *event = new Event_ListGames(eventGameList);
for (int i = 0; i < clients.size(); i++)
if (clients[i]->getAcceptsGameListChanges())
......@@ -87,8 +88,9 @@ void Server::broadcastGameListUpdate(Server_Game *game)
void Server::broadcastChannelUpdate()
{
Server_ChatChannel *channel = static_cast<Server_ChatChannel *>(sender());
Event_ListChatChannels *event = new Event_ListChatChannels;
event->addChannel(channel->getName(), channel->getDescription(), channel->size(), channel->getAutoJoin());
QList<ServerInfo_ChatChannel *> eventChannelList;
eventChannelList.append(new ServerInfo_ChatChannel(channel->getName(), channel->getDescription(), channel->size(), channel->getAutoJoin()));
Event_ListChatChannels *event = new Event_ListChatChannels(eventChannelList);
for (int i = 0; i < clients.size(); ++i)
if (clients[i]->getAcceptsChatChannelListChanges())
......
......@@ -11,9 +11,10 @@ void Server_ChatChannel::addClient(Server_ProtocolHandler *client)
sendChatEvent(new Event_ChatJoinChannel(name, client->getPlayerName()));
append(client);
Event_ChatListPlayers *eventCLP = new Event_ChatListPlayers(name);
QList<ServerInfo_ChatUser *> eventUserList;
for (int i = 0; i < size(); ++i)
eventCLP->addPlayer(at(i)->getPlayerName());
eventUserList.append(new ServerInfo_ChatUser(at(i)->getPlayerName()));
Event_ChatListPlayers *eventCLP = new Event_ChatListPlayers(name, eventUserList);
client->enqueueProtocolItem(eventCLP);
client->enqueueProtocolItem(new Event_ChatSay(name, QString(), joinMessage));
......
......@@ -10,6 +10,7 @@
#include "server_counter.h"
#include "server_game.h"
#include "server_player.h"
#include "decklist.h"
Server_ProtocolHandler::Server_ProtocolHandler(Server *_server, QObject *parent)
: QObject(parent), server(_server), authState(PasswordWrong), acceptsGameListChanges(false)
......@@ -148,13 +149,13 @@ ResponseCode Server_ProtocolHandler::cmdListChatChannels(Command_ListChatChannel
if (authState == PasswordWrong)
return RespLoginNeeded;
Event_ListChatChannels *event = new Event_ListChatChannels;
QList<ServerInfo_ChatChannel *> eventChannelList;
QMapIterator<QString, Server_ChatChannel *> channelIterator(server->getChatChannels());
while (channelIterator.hasNext()) {
Server_ChatChannel *c = channelIterator.next().value();
event->addChannel(c->getName(), c->getDescription(), c->size(), c->getAutoJoin());
eventChannelList.append(new ServerInfo_ChatChannel(c->getName(), c->getDescription(), c->size(), c->getAutoJoin()));
}
sendProtocolItem(event);
sendProtocolItem(new Event_ListChatChannels(eventChannelList));
acceptsChatChannelListChanges = true;
return RespOk;
......@@ -193,11 +194,11 @@ ResponseCode Server_ProtocolHandler::cmdChatSay(Command_ChatSay *cmd, Server_Cha
ResponseCode Server_ProtocolHandler::cmdListGames(Command_ListGames * /*cmd*/)
{
Event_ListGames *event = new Event_ListGames;
const QList<Server_Game *> &gameList = server->getGames();
QList<ServerInfo_Game *> eventGameList;
for (int i = 0; i < gameList.size(); ++i) {
Server_Game *g = gameList[i];
event->addGame(
eventGameList.append(new ServerInfo_Game(
g->getGameId(),
g->getDescription(),
!g->getPassword().isEmpty(),
......@@ -206,9 +207,9 @@ ResponseCode Server_ProtocolHandler::cmdListGames(Command_ListGames * /*cmd*/)
g->getCreatorName(),
g->getSpectatorsAllowed(),
g->getSpectatorCount()
);
));
}
sendProtocolItem(event);
sendProtocolItem(new Event_ListGames(eventGameList));
acceptsGameListChanges = true;
return RespOk;
......@@ -253,7 +254,7 @@ ResponseCode Server_ProtocolHandler::cmdDeckSelect(Command_DeckSelect *cmd, Serv
if (cmd->getDeckId() == -1) {
if (!cmd->getDeck())
return RespInvalidData;
deck = cmd->getDeck();
deck = new DeckList(cmd->getDeck());
} else {
try {
deck = getDeckFromDatabase(cmd->getDeckId());
......@@ -265,7 +266,7 @@ ResponseCode Server_ProtocolHandler::cmdDeckSelect(Command_DeckSelect *cmd, Serv
game->sendGameEvent(new Event_DeckSelect(-1, player->getPlayerId(), cmd->getDeckId()));
sendProtocolItem(new Response_DeckDownload(cmd->getCmdId(), RespOk, deck));
sendProtocolItem(new Response_DeckDownload(cmd->getCmdId(), RespOk, new DeckList(deck)));
return RespNothing;
}
......@@ -427,7 +428,7 @@ ResponseCode Server_ProtocolHandler::cmdCreateArrow(Command_CreateArrow *cmd, Se
Server_Arrow *arrow = new Server_Arrow(player->newArrowId(), startCard, targetCard, cmd->getColor());
player->addArrow(arrow);
game->sendGameEvent(new Event_CreateArrow(-1, player->getPlayerId(), new ServerInfo_Arrow(
game->sendGameEvent(new Event_CreateArrows(-1, player->getPlayerId(), QList<ServerInfo_Arrow *>() << new ServerInfo_Arrow(
arrow->getId(),
startPlayer->getPlayerId(),
startZone->getName(),
......@@ -500,7 +501,7 @@ ResponseCode Server_ProtocolHandler::cmdCreateCounter(Command_CreateCounter *cmd
{
Server_Counter *c = new Server_Counter(player->newCounterId(), cmd->getCounterName(), cmd->getColor(), cmd->getRadius(), cmd->getValue());
player->addCounter(c);
game->sendGameEvent(new Event_CreateCounter(-1, player->getPlayerId(), new ServerInfo_Counter(c->getId(), c->getName(), c->getColor(), c->getRadius(), c->getCount())));
game->sendGameEvent(new Event_CreateCounters(-1, player->getPlayerId(), QList<ServerInfo_Counter *>() << new ServerInfo_Counter(c->getId(), c->getName(), c->getColor(), c->getRadius(), c->getCount())));
return RespOk;
}
......
......@@ -14,6 +14,7 @@ QT += network sql
HEADERS += src/servatrice.h \
src/serversocketinterface.h \
../common/serializable_item.h \
../common/decklist.h \
../common/protocol.h \
../common/protocol_items.h \
......@@ -33,6 +34,7 @@ HEADERS += src/servatrice.h \
SOURCES += src/main.cpp \
src/servatrice.cpp \
src/serversocketinterface.cpp \
../common/serializable_item.cpp \
../common/decklist.cpp \
../common/protocol.cpp \
../common/protocol_items.cpp \
......
......@@ -29,7 +29,7 @@
#include "server_player.h"
ServerSocketInterface::ServerSocketInterface(Servatrice *_server, QTcpSocket *_socket, QObject *parent)
: Server_ProtocolHandler(_server, parent), servatrice(_server), socket(_socket), currentItem(0)
: Server_ProtocolHandler(_server, parent), servatrice(_server), socket(_socket), topLevelItem(0)
{
xmlWriter = new QXmlStreamWriter;
xmlWriter->setDevice(socket);
......@@ -57,41 +57,31 @@ ServerSocketInterface::~ServerSocketInterface()
delete socket;
}
void ServerSocketInterface::itemFinishedReading()
void ServerSocketInterface::processProtocolItem(ProtocolItem *item)
{
Command *command = qobject_cast<Command *>(currentItem);
if (qobject_cast<InvalidCommand *>(command))
Command *command = qobject_cast<Command *>(item);
if (!command)
sendProtocolItem(new ProtocolResponse(command->getCmdId(), RespInvalidCommand));
else
processCommand(command);
currentItem = 0;
}
void ServerSocketInterface::readClient()
{
xmlReader->addData(socket->readAll());
if (currentItem) {
if (!currentItem->read(xmlReader))
return;
itemFinishedReading();
}
while (!xmlReader->atEnd()) {
xmlReader->readNext();
if (xmlReader->isStartElement()) {
QString itemType = xmlReader->name().toString();
if (itemType == "cockatrice_client_stream")
continue;
QString itemName = xmlReader->attributes().value("name").toString();
qDebug() << "parseXml: startElement: " << "type =" << itemType << ", name =" << itemName;
currentItem = ProtocolItem::getNewItem(itemType + itemName);
if (!currentItem)
currentItem = new InvalidCommand;
if (!currentItem->read(xmlReader))
return;
itemFinishedReading();
if (topLevelItem)
topLevelItem->read(xmlReader);
else
while (!xmlReader->atEnd()) {
xmlReader->readNext();
if (xmlReader->isStartElement() && (xmlReader->name().toString() == "cockatrice_client_stream")) {
topLevelItem = new TopLevelProtocolItem;
connect(topLevelItem, SIGNAL(protocolItemReceived(ProtocolItem *)), this, SLOT(processProtocolItem(ProtocolItem *)));
topLevelItem->read(xmlReader);
}
}
}
}
void ServerSocketInterface::catchSocketError(QAbstractSocket::SocketError socketError)
......@@ -147,7 +137,7 @@ bool ServerSocketInterface::deckListHelper(DeckList_Directory *folder)
while (query.next()) {
DeckList_Directory *newFolder = new DeckList_Directory(query.value(1).toString(), query.value(0).toInt());
folder->append(newFolder);
folder->appendItem(newFolder);
if (!deckListHelper(newFolder))
return false;
}
......@@ -160,7 +150,7 @@ bool ServerSocketInterface::deckListHelper(DeckList_Directory *folder)
while (query.next()) {
DeckList_File *newFile = new DeckList_File(query.value(1).toString(), query.value(0).toInt(), query.value(2).toDateTime());
folder->append(newFile);
folder->appendItem(newFile);
}
return true;
......@@ -266,7 +256,7 @@ ResponseCode ServerSocketInterface::cmdDeckUpload(Command_DeckUpload *cmd)
QString deckContents;
QXmlStreamWriter deckWriter(&deckContents);
deckWriter.writeStartDocument();
cmd->getDeck()->writeElement(&deckWriter);
cmd->getDeck()->write(&deckWriter);
deckWriter.writeEndDocument();
QString deckName = cmd->getDeck()->getName();
......@@ -281,8 +271,6 @@ ResponseCode ServerSocketInterface::cmdDeckUpload(Command_DeckUpload *cmd)
query.bindValue(":content", deckContents);
servatrice->execSqlQuery(query);
delete cmd->getDeck();
sendProtocolItem(new Response_DeckUpload(cmd->getCmdId(), RespOk, new DeckList_File(deckName, query.lastInsertId().toInt(), QDateTime::currentDateTime())));
return RespNothing;
}
......@@ -302,8 +290,7 @@ DeckList *ServerSocketInterface::getDeckFromDatabase(int deckId)
QXmlStreamReader deckReader(query.value(0).toString());
DeckList *deck = new DeckList;
if (!deck->loadFromXml(&deckReader))
throw RespInvalidData;
deck->loadFromXml(&deckReader);
return deck;
}
......@@ -317,6 +304,5 @@ ResponseCode ServerSocketInterface::cmdDeckDownload(Command_DeckDownload *cmd)
return r;
}
sendProtocolItem(new Response_DeckDownload(cmd->getCmdId(), RespOk, deck));
delete deck;
return RespNothing;
}
......@@ -28,6 +28,7 @@ class Servatrice;
class QXmlStreamReader;
class QXmlStreamWriter;
class DeckList;
class TopLevelProtocolItem;
class ServerSocketInterface : public Server_ProtocolHandler
{
......@@ -35,12 +36,13 @@ class ServerSocketInterface : public Server_ProtocolHandler
private slots:
void readClient();
void catchSocketError(QAbstractSocket::SocketError socketError);
void processProtocolItem(ProtocolItem *item);
private:
Servatrice *servatrice;
QTcpSocket *socket;
QXmlStreamWriter *xmlWriter;
QXmlStreamReader *xmlReader;
ProtocolItem *currentItem;
TopLevelProtocolItem *topLevelItem;
int getDeckPathId(int basePathId, QStringList path);
int getDeckPathId(const QString &path);
......@@ -53,8 +55,6 @@ private:
ResponseCode cmdDeckUpload(Command_DeckUpload *cmd);
DeckList *getDeckFromDatabase(int deckId);
ResponseCode cmdDeckDownload(Command_DeckDownload *cmd);
void itemFinishedReading();
public:
ServerSocketInterface(Servatrice *_server, QTcpSocket *_socket, QObject *parent = 0);
~ServerSocketInterface();
......
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