From 4e8ba699d2a003db734b134a51049fce3baecd39 Mon Sep 17 00:00:00 2001 From: arxanas Date: Tue, 8 Jul 2014 22:53:02 -0400 Subject: [PATCH] Tabs to spaces. --- common/color.h | 22 +- common/decklist.cpp | 870 +++---- common/decklist.h | 196 +- common/get_pb_extension.cpp | 12 +- common/get_pb_extension.h | 6 +- common/rng_abstract.cpp | 38 +- common/rng_abstract.h | 10 +- common/rng_sfmt.cpp | 74 +- common/rng_sfmt.h | 14 +- common/server.cpp | 842 +++---- common/server.h | 152 +- common/server_abstractuserinterface.cpp | 116 +- common/server_abstractuserinterface.h | 46 +- common/server_arrow.cpp | 24 +- common/server_arrow.h | 22 +- common/server_arrowtarget.cpp | 2 +- common/server_arrowtarget.h | 2 +- common/server_card.cpp | 200 +- common/server_card.h | 118 +- common/server_cardzone.h | 80 +- common/server_counter.cpp | 10 +- common/server_counter.h | 30 +- common/server_database_interface.h | 46 +- common/server_game.cpp | 1124 ++++----- common/server_game.h | 150 +- common/server_player.cpp | 2782 +++++++++++------------ common/server_player.h | 188 +- common/server_player_reference.h | 16 +- common/server_protocolhandler.cpp | 900 ++++---- common/server_protocolhandler.h | 102 +- common/server_remoteuserinterface.cpp | 8 +- common/server_remoteuserinterface.h | 16 +- common/server_response_containers.cpp | 76 +- common/server_response_containers.h | 70 +- common/server_room.cpp | 500 ++-- common/server_room.h | 96 +- common/serverinfo_user_container.cpp | 42 +- common/serverinfo_user_container.h | 18 +- 38 files changed, 4510 insertions(+), 4510 deletions(-) diff --git a/common/color.h b/common/color.h index c96eda07..1ea3e33d 100644 --- a/common/color.h +++ b/common/color.h @@ -10,26 +10,26 @@ #ifdef QT_GUI_LIB inline QColor convertColorToQColor(const color &c) { - return QColor(c.r(), c.g(), c.b()); + return QColor(c.r(), c.g(), c.b()); } inline color convertQColorToColor(const QColor &c) { - color result; - result.set_r(c.red()); - result.set_g(c.green()); - result.set_b(c.blue()); - return result; + color result; + result.set_r(c.red()); + result.set_g(c.green()); + result.set_b(c.blue()); + return result; } #endif inline color makeColor(int r, int g, int b) { - color result; - result.set_r(r); - result.set_g(g); - result.set_b(b); - return result; + color result; + result.set_r(r); + result.set_g(g); + result.set_b(b); + return result; } #endif diff --git a/common/decklist.cpp b/common/decklist.cpp index 90b5cb7e..8e877ba9 100644 --- a/common/decklist.cpp +++ b/common/decklist.cpp @@ -6,155 +6,155 @@ #include "decklist.h" SideboardPlan::SideboardPlan(const QString &_name, const QList &_moveList) - : name(_name), moveList(_moveList) + : name(_name), moveList(_moveList) { } void SideboardPlan::setMoveList(const QList &_moveList) { - moveList = _moveList; + moveList = _moveList; } bool SideboardPlan::readElement(QXmlStreamReader *xml) { - while (!xml->atEnd()) { - xml->readNext(); - const QString childName = xml->name().toString(); - if (xml->isStartElement()) { - if (childName == "name") - name = xml->readElementText(); - else if (childName == "move_card_to_zone") { - MoveCard_ToZone m; - while (!xml->atEnd()) { - xml->readNext(); - const QString childName2 = xml->name().toString(); - if (xml->isStartElement()) { - if (childName2 == "card_name") - m.set_card_name(xml->readElementText().toStdString()); - else if (childName2 == "start_zone") - m.set_start_zone(xml->readElementText().toStdString()); - else if (childName2 == "target_zone") - m.set_target_zone(xml->readElementText().toStdString()); - } else if (xml->isEndElement() && (childName2 == "move_card_to_zone")) { - moveList.append(m); - break; - } - } - } - } else if (xml->isEndElement() && (childName == "sideboard_plan")) - return true; - } - return false; + while (!xml->atEnd()) { + xml->readNext(); + const QString childName = xml->name().toString(); + if (xml->isStartElement()) { + if (childName == "name") + name = xml->readElementText(); + else if (childName == "move_card_to_zone") { + MoveCard_ToZone m; + while (!xml->atEnd()) { + xml->readNext(); + const QString childName2 = xml->name().toString(); + if (xml->isStartElement()) { + if (childName2 == "card_name") + m.set_card_name(xml->readElementText().toStdString()); + else if (childName2 == "start_zone") + m.set_start_zone(xml->readElementText().toStdString()); + else if (childName2 == "target_zone") + m.set_target_zone(xml->readElementText().toStdString()); + } else if (xml->isEndElement() && (childName2 == "move_card_to_zone")) { + moveList.append(m); + break; + } + } + } + } else if (xml->isEndElement() && (childName == "sideboard_plan")) + return true; + } + return false; } void SideboardPlan::write(QXmlStreamWriter *xml) { - xml->writeStartElement("sideboard_plan"); - xml->writeTextElement("name", name); - for (int i = 0; i < moveList.size(); ++i) { - xml->writeStartElement("move_card_to_zone"); - xml->writeTextElement("card_name", QString::fromStdString(moveList[i].card_name())); - xml->writeTextElement("start_zone", QString::fromStdString(moveList[i].start_zone())); - xml->writeTextElement("target_zone", QString::fromStdString(moveList[i].target_zone())); - xml->writeEndElement(); - } - xml->writeEndElement(); + xml->writeStartElement("sideboard_plan"); + xml->writeTextElement("name", name); + for (int i = 0; i < moveList.size(); ++i) { + xml->writeStartElement("move_card_to_zone"); + xml->writeTextElement("card_name", QString::fromStdString(moveList[i].card_name())); + xml->writeTextElement("start_zone", QString::fromStdString(moveList[i].start_zone())); + xml->writeTextElement("target_zone", QString::fromStdString(moveList[i].target_zone())); + xml->writeEndElement(); + } + xml->writeEndElement(); } AbstractDecklistNode::AbstractDecklistNode(InnerDecklistNode *_parent) - : parent(_parent) + : parent(_parent) { - if (parent) - parent->append(this); + if (parent) + parent->append(this); } int AbstractDecklistNode::depth() const { - if (parent) - return parent->depth() + 1; - else - return 0; + if (parent) + return parent->depth() + 1; + else + return 0; } InnerDecklistNode::InnerDecklistNode(InnerDecklistNode *other, InnerDecklistNode *_parent) - : AbstractDecklistNode(_parent), name(other->getName()) + : AbstractDecklistNode(_parent), name(other->getName()) { - for (int i = 0; i < other->size(); ++i) { - InnerDecklistNode *inner = dynamic_cast(other->at(i)); - if (inner) - new InnerDecklistNode(inner, this); - else - new DecklistCardNode(dynamic_cast(other->at(i)), this); - } + for (int i = 0; i < other->size(); ++i) { + InnerDecklistNode *inner = dynamic_cast(other->at(i)); + if (inner) + new InnerDecklistNode(inner, this); + else + new DecklistCardNode(dynamic_cast(other->at(i)), this); + } } InnerDecklistNode::~InnerDecklistNode() { - clearTree(); + clearTree(); } QString InnerDecklistNode::visibleNameFromName(const QString &_name) { - if (_name == "main") - return QObject::tr("Maindeck"); - else if (_name == "side") - return QObject::tr("Sideboard"); - else if (_name == "tokens") - return QObject::tr("Tokens"); - else - return _name; + if (_name == "main") + return QObject::tr("Maindeck"); + else if (_name == "side") + return QObject::tr("Sideboard"); + else if (_name == "tokens") + return QObject::tr("Tokens"); + else + return _name; } void InnerDecklistNode::setSortMethod(DeckSortMethod method) { - sortMethod = method; - for (int i = 0; i < size(); i++) - at(i)->setSortMethod(method); + sortMethod = method; + for (int i = 0; i < size(); i++) + at(i)->setSortMethod(method); } QString InnerDecklistNode::getVisibleName() const { - return visibleNameFromName(name); + return visibleNameFromName(name); } void InnerDecklistNode::clearTree() { - for (int i = 0; i < size(); i++) - delete at(i); - clear(); + for (int i = 0; i < size(); i++) + delete at(i); + clear(); } DecklistCardNode::DecklistCardNode(DecklistCardNode *other, InnerDecklistNode *_parent) - : AbstractDecklistCardNode(_parent), name(other->getName()), number(other->getNumber()), price(other->getPrice()) + : AbstractDecklistCardNode(_parent), name(other->getName()), number(other->getNumber()), price(other->getPrice()) { } AbstractDecklistNode *InnerDecklistNode::findChild(const QString &name) { - for (int i = 0; i < size(); i++) - if (at(i)->getName() == name) - return at(i); - return 0; + for (int i = 0; i < size(); i++) + if (at(i)->getName() == name) + return at(i); + return 0; } int InnerDecklistNode::height() const { - return at(0)->height() + 1; + return at(0)->height() + 1; } int InnerDecklistNode::recursiveCount(bool countTotalCards) const { - int result = 0; - for (int i = 0; i < size(); i++) { - InnerDecklistNode *node = dynamic_cast(at(i)); - if (node) - result += node->recursiveCount(countTotalCards); - else if (countTotalCards) - result += dynamic_cast(at(i))->getNumber(); - else - result += 1; - } - return result; + int result = 0; + for (int i = 0; i < size(); i++) { + InnerDecklistNode *node = dynamic_cast(at(i)); + if (node) + result += node->recursiveCount(countTotalCards); + else if (countTotalCards) + result += dynamic_cast(at(i))->getNumber(); + else + result += 1; + } + return result; } float InnerDecklistNode::recursivePrice(bool countTotalCards) const @@ -172,275 +172,275 @@ float InnerDecklistNode::recursivePrice(bool countTotalCards) const bool InnerDecklistNode::compare(AbstractDecklistNode *other) const { - switch (sortMethod) { - case 0: - return compareNumber(other); - case 1: - return compareName(other); - case 2: - return comparePrice(other); - } + switch (sortMethod) { + case 0: + return compareNumber(other); + case 1: + return compareName(other); + case 2: + return comparePrice(other); + } return 0; } bool InnerDecklistNode::compareNumber(AbstractDecklistNode *other) const { - InnerDecklistNode *other2 = dynamic_cast(other); - if (other2) { - int n1 = recursiveCount(true); - int n2 = other2->recursiveCount(true); - return (n1 != n2) ? (n1 > n2) : compareName(other); - } else { - return false; - } + InnerDecklistNode *other2 = dynamic_cast(other); + if (other2) { + int n1 = recursiveCount(true); + int n2 = other2->recursiveCount(true); + return (n1 != n2) ? (n1 > n2) : compareName(other); + } else { + return false; + } } bool InnerDecklistNode::compareName(AbstractDecklistNode *other) const { - InnerDecklistNode *other2 = dynamic_cast(other); - if (other2) { - return (getName() > other2->getName()); - } else { - return false; - } + InnerDecklistNode *other2 = dynamic_cast(other); + if (other2) { + return (getName() > other2->getName()); + } else { + return false; + } } bool InnerDecklistNode::comparePrice(AbstractDecklistNode *other) const { - InnerDecklistNode *other2 = dynamic_cast(other); - if (other2) { - int p1 = 100*recursivePrice(true); - int p2 = 100*other2->recursivePrice(true); - return (p1 != p2) ? (p1 > p2) : compareName(other); - } else { - return false; - } + InnerDecklistNode *other2 = dynamic_cast(other); + if (other2) { + int p1 = 100*recursivePrice(true); + int p2 = 100*other2->recursivePrice(true); + return (p1 != p2) ? (p1 > p2) : compareName(other); + } else { + return false; + } } bool AbstractDecklistCardNode::compare(AbstractDecklistNode *other) const { - switch (sortMethod) { - case ByNumber: - return compareNumber(other); - case ByName: - return compareName(other); - case ByPrice: - return compareTotalPrice(other); - } + switch (sortMethod) { + case ByNumber: + return compareNumber(other); + case ByName: + return compareName(other); + case ByPrice: + return compareTotalPrice(other); + } return 0; } bool AbstractDecklistCardNode::compareNumber(AbstractDecklistNode *other) const { - AbstractDecklistCardNode *other2 = dynamic_cast(other); - if (other2) { - int n1 = getNumber(); - int n2 = other2->getNumber(); - return (n1 != n2) ? (n1 > n2) : compareName(other); - } else { - return true; - } + AbstractDecklistCardNode *other2 = dynamic_cast(other); + if (other2) { + int n1 = getNumber(); + int n2 = other2->getNumber(); + return (n1 != n2) ? (n1 > n2) : compareName(other); + } else { + return true; + } } bool AbstractDecklistCardNode::compareName(AbstractDecklistNode *other) const { - AbstractDecklistCardNode *other2 = dynamic_cast(other); - if (other2) { - return (getName() > other2->getName()); - } else { - return true; - } + AbstractDecklistCardNode *other2 = dynamic_cast(other); + if (other2) { + return (getName() > other2->getName()); + } else { + return true; + } } bool AbstractDecklistCardNode::compareTotalPrice(AbstractDecklistNode *other) const { - AbstractDecklistCardNode *other2 = dynamic_cast(other); - if (other2) { - int p1 = 100*getTotalPrice(); - int p2 = 100*other2->getTotalPrice(); - return (p1 != p2) ? (p1 > p2) : compareName(other); - } else { - return true; - } + AbstractDecklistCardNode *other2 = dynamic_cast(other); + if (other2) { + int p1 = 100*getTotalPrice(); + int p2 = 100*other2->getTotalPrice(); + return (p1 != p2) ? (p1 > p2) : compareName(other); + } else { + return true; + } } class InnerDecklistNode::compareFunctor { private: - Qt::SortOrder order; + Qt::SortOrder order; public: - compareFunctor(Qt::SortOrder _order) : order(_order) { } - inline bool operator()(QPair a, QPair b) const - { - return (order == Qt::AscendingOrder) ^ (a.second->compare(b.second)); - } + compareFunctor(Qt::SortOrder _order) : order(_order) { } + inline bool operator()(QPair a, QPair b) const + { + return (order == Qt::AscendingOrder) ^ (a.second->compare(b.second)); + } }; bool InnerDecklistNode::readElement(QXmlStreamReader *xml) { - while (!xml->atEnd()) { - xml->readNext(); - const QString childName = xml->name().toString(); - if (xml->isStartElement()) { - if (childName == "zone") { - InnerDecklistNode *newZone = new InnerDecklistNode(xml->attributes().value("name").toString(), this); - newZone->readElement(xml); - } else if (childName == "card") { - float price = (xml->attributes().value("price") != NULL) ? xml->attributes().value("price").toString().toFloat() : 0; - DecklistCardNode *newCard = new DecklistCardNode(xml->attributes().value("name").toString(), xml->attributes().value("number").toString().toInt(), price, this); - newCard->readElement(xml); - } - } else if (xml->isEndElement() && (childName == "zone")) - return false; - } - return true; + while (!xml->atEnd()) { + xml->readNext(); + const QString childName = xml->name().toString(); + if (xml->isStartElement()) { + if (childName == "zone") { + InnerDecklistNode *newZone = new InnerDecklistNode(xml->attributes().value("name").toString(), this); + newZone->readElement(xml); + } else if (childName == "card") { + float price = (xml->attributes().value("price") != NULL) ? xml->attributes().value("price").toString().toFloat() : 0; + DecklistCardNode *newCard = new DecklistCardNode(xml->attributes().value("name").toString(), xml->attributes().value("number").toString().toInt(), price, this); + newCard->readElement(xml); + } + } else if (xml->isEndElement() && (childName == "zone")) + return false; + } + return true; } void InnerDecklistNode::writeElement(QXmlStreamWriter *xml) { - xml->writeStartElement("zone"); - xml->writeAttribute("name", name); - for (int i = 0; i < size(); i++) - at(i)->writeElement(xml); - xml->writeEndElement(); // zone + xml->writeStartElement("zone"); + xml->writeAttribute("name", name); + for (int i = 0; i < size(); i++) + at(i)->writeElement(xml); + xml->writeEndElement(); // zone } bool AbstractDecklistCardNode::readElement(QXmlStreamReader *xml) { - while (!xml->atEnd()) { - xml->readNext(); - if (xml->isEndElement() && xml->name() == "card") - return false; - } - return true; + while (!xml->atEnd()) { + xml->readNext(); + if (xml->isEndElement() && xml->name() == "card") + return false; + } + return true; } void AbstractDecklistCardNode::writeElement(QXmlStreamWriter *xml) { - xml->writeEmptyElement("card"); - xml->writeAttribute("number", QString::number(getNumber())); + xml->writeEmptyElement("card"); + xml->writeAttribute("number", QString::number(getNumber())); xml->writeAttribute("price", QString::number(getPrice())); - xml->writeAttribute("name", getName()); + xml->writeAttribute("name", getName()); } QVector > InnerDecklistNode::sort(Qt::SortOrder order) { - QVector > result(size()); - - // Initialize temporary list with contents of current list - QVector > tempList(size()); - for (int i = size() - 1; i >= 0; --i) { - tempList[i].first = i; - tempList[i].second = at(i); - } - - // Sort temporary list - compareFunctor cmp(order); - qSort(tempList.begin(), tempList.end(), cmp); - - // Map old indexes to new indexes and - // copy temporary list to the current one - for (int i = size() - 1; i >= 0; --i) { - result[i].first = tempList[i].first; - result[i].second = i; - replace(i, tempList[i].second); - } + QVector > result(size()); + + // Initialize temporary list with contents of current list + QVector > tempList(size()); + for (int i = size() - 1; i >= 0; --i) { + tempList[i].first = i; + tempList[i].second = at(i); + } + + // Sort temporary list + compareFunctor cmp(order); + qSort(tempList.begin(), tempList.end(), cmp); + + // Map old indexes to new indexes and + // copy temporary list to the current one + for (int i = size() - 1; i >= 0; --i) { + result[i].first = tempList[i].first; + result[i].second = i; + replace(i, tempList[i].second); + } - return result; + return result; } DeckList::DeckList() { - root = new InnerDecklistNode; + root = new InnerDecklistNode; } // TODO: http://qt-project.org/doc/qt-4.8/qobject.html#no-copy-constructor-or-assignment-operator DeckList::DeckList(const DeckList &other) - : name(other.name), - comments(other.comments), - deckHash(other.deckHash) + : name(other.name), + comments(other.comments), + deckHash(other.deckHash) { - root = new InnerDecklistNode(other.getRoot()); - - QMapIterator spIterator(other.getSideboardPlans()); - while (spIterator.hasNext()) { - spIterator.next(); - sideboardPlans.insert(spIterator.key(), new SideboardPlan(spIterator.key(), spIterator.value()->getMoveList())); - } - updateDeckHash(); + root = new InnerDecklistNode(other.getRoot()); + + QMapIterator spIterator(other.getSideboardPlans()); + while (spIterator.hasNext()) { + spIterator.next(); + sideboardPlans.insert(spIterator.key(), new SideboardPlan(spIterator.key(), spIterator.value()->getMoveList())); + } + updateDeckHash(); } DeckList::DeckList(const QString &nativeString) { - root = new InnerDecklistNode; - loadFromString_Native(nativeString); + root = new InnerDecklistNode; + loadFromString_Native(nativeString); } DeckList::~DeckList() { - delete root; - - QMapIterator i(sideboardPlans); - while (i.hasNext()) - delete i.next().value(); + delete root; + + QMapIterator i(sideboardPlans); + while (i.hasNext()) + delete i.next().value(); } QList DeckList::getCurrentSideboardPlan() { - SideboardPlan *current = sideboardPlans.value(QString(), 0); - if (!current) - return QList(); - else - return current->getMoveList(); + SideboardPlan *current = sideboardPlans.value(QString(), 0); + if (!current) + return QList(); + else + return current->getMoveList(); } void DeckList::setCurrentSideboardPlan(const QList &plan) { - SideboardPlan *current = sideboardPlans.value(QString(), 0); - if (!current) { - current = new SideboardPlan; - sideboardPlans.insert(QString(), current); - } - - current->setMoveList(plan); + SideboardPlan *current = sideboardPlans.value(QString(), 0); + if (!current) { + current = new SideboardPlan; + sideboardPlans.insert(QString(), current); + } + + current->setMoveList(plan); } bool DeckList::readElement(QXmlStreamReader *xml) { - const QString childName = xml->name().toString(); - if (xml->isStartElement()) { - if (childName == "deckname") - name = xml->readElementText(); - else if (childName == "comments") - comments = xml->readElementText(); - else if (childName == "zone") { - InnerDecklistNode *newZone = new InnerDecklistNode(xml->attributes().value("name").toString(), root); - newZone->readElement(xml); - } else if (childName == "sideboard_plan") { - SideboardPlan *newSideboardPlan = new SideboardPlan; - if (newSideboardPlan->readElement(xml)) - sideboardPlans.insert(newSideboardPlan->getName(), newSideboardPlan); - else - delete newSideboardPlan; - } - } else if (xml->isEndElement() && (childName == "cockatrice_deck")) - return false; - return true; + const QString childName = xml->name().toString(); + if (xml->isStartElement()) { + if (childName == "deckname") + name = xml->readElementText(); + else if (childName == "comments") + comments = xml->readElementText(); + else if (childName == "zone") { + InnerDecklistNode *newZone = new InnerDecklistNode(xml->attributes().value("name").toString(), root); + newZone->readElement(xml); + } else if (childName == "sideboard_plan") { + SideboardPlan *newSideboardPlan = new SideboardPlan; + if (newSideboardPlan->readElement(xml)) + sideboardPlans.insert(newSideboardPlan->getName(), newSideboardPlan); + else + delete newSideboardPlan; + } + } else if (xml->isEndElement() && (childName == "cockatrice_deck")) + return false; + return true; } void DeckList::write(QXmlStreamWriter *xml) { - xml->writeStartElement("cockatrice_deck"); - xml->writeAttribute("version", "1"); - xml->writeTextElement("deckname", name); - xml->writeTextElement("comments", comments); + xml->writeStartElement("cockatrice_deck"); + xml->writeAttribute("version", "1"); + xml->writeTextElement("deckname", name); + xml->writeTextElement("comments", comments); - for (int i = 0; i < root->size(); i++) - root->at(i)->writeElement(xml); - - QMapIterator i(sideboardPlans); - while (i.hasNext()) - i.next().value()->write(xml); - xml->writeEndElement(); + for (int i = 0; i < root->size(); i++) + root->at(i)->writeElement(xml); + + QMapIterator i(sideboardPlans); + while (i.hasNext()) + i.next().value()->write(xml); + xml->writeEndElement(); } bool DeckList::loadFromXml(QXmlStreamReader *xml) @@ -450,187 +450,187 @@ bool DeckList::loadFromXml(QXmlStreamReader *xml) return false; } - cleanList(); - while (!xml->atEnd()) { - xml->readNext(); - if (xml->isStartElement()) { - if (xml->name() != "cockatrice_deck") - return false; - while (!xml->atEnd()) { - xml->readNext(); - if (!readElement(xml)) - break; - } - } - } - updateDeckHash(); + cleanList(); + while (!xml->atEnd()) { + xml->readNext(); + if (xml->isStartElement()) { + if (xml->name() != "cockatrice_deck") + return false; + while (!xml->atEnd()) { + xml->readNext(); + if (!readElement(xml)) + break; + } + } + } + updateDeckHash(); if (xml->error()) { qDebug() << "Error loading deck from xml: " << xml->errorString(); return false; } - return true; + return true; } bool DeckList::loadFromString_Native(const QString &nativeString) { - QXmlStreamReader xml(nativeString); - return loadFromXml(&xml); + QXmlStreamReader xml(nativeString); + return loadFromXml(&xml); } QString DeckList::writeToString_Native() { - QString result; - QXmlStreamWriter xml(&result); - xml.writeStartDocument(); - write(&xml); - xml.writeEndDocument(); - return result; + QString result; + QXmlStreamWriter xml(&result); + xml.writeStartDocument(); + write(&xml); + xml.writeEndDocument(); + return result; } bool DeckList::loadFromFile_Native(QIODevice *device) { - QXmlStreamReader xml(device); - return loadFromXml(&xml); + QXmlStreamReader xml(device); + return loadFromXml(&xml); } bool DeckList::saveToFile_Native(QIODevice *device) { - QXmlStreamWriter xml(device); - xml.setAutoFormatting(true); - xml.writeStartDocument(); + QXmlStreamWriter xml(device); + xml.setAutoFormatting(true); + xml.writeStartDocument(); - write(&xml); + write(&xml); - xml.writeEndDocument(); - return true; + xml.writeEndDocument(); + return true; } bool DeckList::loadFromStream_Plain(QTextStream &in) { - cleanList(); + cleanList(); - InnerDecklistNode *main = 0, *side = 0; - bool inSideboard = false; + InnerDecklistNode *main = 0, *side = 0; + bool inSideboard = false; - int okRows = 0; - while (!in.atEnd()) { - QString line = in.readLine().simplified(); - if (line.startsWith("//")) - continue; + int okRows = 0; + while (!in.atEnd()) { + QString line = in.readLine().simplified(); + if (line.startsWith("//")) + continue; - InnerDecklistNode *zone; - if (line.startsWith("Sideboard", Qt::CaseInsensitive)) { - inSideboard = true; - continue; - } else if (line.startsWith("SB:", Qt::CaseInsensitive)) { - line = line.mid(3).trimmed(); - if (!side) - side = new InnerDecklistNode("side", root); - zone = side; - } else if (inSideboard) { - if (!side) - side = new InnerDecklistNode("side", root); - zone = side; - } else { - if (!main) - main = new InnerDecklistNode("main", root); - zone = main; - } + InnerDecklistNode *zone; + if (line.startsWith("Sideboard", Qt::CaseInsensitive)) { + inSideboard = true; + continue; + } else if (line.startsWith("SB:", Qt::CaseInsensitive)) { + line = line.mid(3).trimmed(); + if (!side) + side = new InnerDecklistNode("side", root); + zone = side; + } else if (inSideboard) { + if (!side) + side = new InnerDecklistNode("side", root); + zone = side; + } else { + if (!main) + main = new InnerDecklistNode("main", root); + zone = main; + } - // Filter out MWS edition symbols and basic land extras - QRegExp rx("\\[.*\\]"); - line.remove(rx); - rx.setPattern("\\(.*\\)"); - line.remove(rx); - //Filter out post card name editions - rx.setPattern("\\|.*$"); - line.remove(rx); - line = line.simplified(); + // Filter out MWS edition symbols and basic land extras + QRegExp rx("\\[.*\\]"); + line.remove(rx); + rx.setPattern("\\(.*\\)"); + line.remove(rx); + //Filter out post card name editions + rx.setPattern("\\|.*$"); + line.remove(rx); + line = line.simplified(); - int i = line.indexOf(' '); - bool ok; - int number = line.left(i).toInt(&ok); - if (!ok) - continue; + int i = line.indexOf(' '); + bool ok; + int number = line.left(i).toInt(&ok); + if (!ok) + continue; - QString cardName = line.mid(i + 1); + QString cardName = line.mid(i + 1); // Common differences between cockatrice's card names // and what's commonly used in decklists - rx.setPattern("’"); + rx.setPattern("’"); cardName.replace(rx, "'"); - rx.setPattern("Æ"); - cardName.replace(rx, "AE"); - rx.setPattern("^Aether"); - cardName.replace(rx, "AEther"); - rx.setPattern("\\s*[&|/]{1,2}\\s*"); - cardName.replace(rx, " // "); + rx.setPattern("Æ"); + cardName.replace(rx, "AE"); + rx.setPattern("^Aether"); + cardName.replace(rx, "AEther"); + rx.setPattern("\\s*[&|/]{1,2}\\s*"); + cardName.replace(rx, " // "); - ++okRows; - new DecklistCardNode(cardName, number, zone); - } - updateDeckHash(); - return (okRows > 0); + ++okRows; + new DecklistCardNode(cardName, number, zone); + } + updateDeckHash(); + return (okRows > 0); } bool DeckList::loadFromFile_Plain(QIODevice *device) { - QTextStream in(device); - return loadFromStream_Plain(in); + QTextStream in(device); + return loadFromStream_Plain(in); } bool DeckList::saveToStream_Plain(QTextStream &out) { - // Support for this is only possible if the internal structure doesn't get more complicated. - for (int i = 0; i < root->size(); i++) { - InnerDecklistNode *node = dynamic_cast(root->at(i)); - for (int j = 0; j < node->size(); j++) { - DecklistCardNode *card = dynamic_cast(node->at(j)); - out << QString("%1%2 %3\n").arg(node->getName() == "side" ? "SB: " : "").arg(card->getNumber()).arg(card->getName()); - } - } - return true; + // Support for this is only possible if the internal structure doesn't get more complicated. + for (int i = 0; i < root->size(); i++) { + InnerDecklistNode *node = dynamic_cast(root->at(i)); + for (int j = 0; j < node->size(); j++) { + DecklistCardNode *card = dynamic_cast(node->at(j)); + out << QString("%1%2 %3\n").arg(node->getName() == "side" ? "SB: " : "").arg(card->getNumber()).arg(card->getName()); + } + } + return true; } bool DeckList::saveToFile_Plain(QIODevice *device) { - QTextStream out(device); - return saveToStream_Plain(out); + QTextStream out(device); + return saveToStream_Plain(out); } QString DeckList::writeToString_Plain() { - QString result; - QTextStream out(&result); - saveToStream_Plain(out); - return result; + QString result; + QTextStream out(&result); + saveToStream_Plain(out); + return result; } void DeckList::cleanList() { - root->clearTree(); - setName(); - setComments(); - deckHash = QString(); - emit deckHashChanged(); + root->clearTree(); + setName(); + setComments(); + deckHash = QString(); + emit deckHashChanged(); } void DeckList::getCardListHelper(InnerDecklistNode *item, QSet &result) const { - for (int i = 0; i < item->size(); ++i) { - DecklistCardNode *node = dynamic_cast(item->at(i)); - if (node) - result.insert(node->getName()); - else - getCardListHelper(dynamic_cast(item->at(i)), result); - } + for (int i = 0; i < item->size(); ++i) { + DecklistCardNode *node = dynamic_cast(item->at(i)); + if (node) + result.insert(node->getName()); + else + getCardListHelper(dynamic_cast(item->at(i)), result); + } } QStringList DeckList::getCardList() const { - QSet result; - getCardListHelper(root, result); - return result.toList(); + QSet result; + getCardListHelper(root, result); + return result.toList(); } int DeckList::getSideboardSize() const @@ -640,7 +640,7 @@ int DeckList::getSideboardSize() const InnerDecklistNode *node = dynamic_cast(root->at(i)); if (node->getName() != "side") continue; - for (int j = 0; j < node->size(); j++) { + for (int j = 0; j < node->size(); j++) { DecklistCardNode *card = dynamic_cast(node->at(j)); size += card->getNumber(); } @@ -650,65 +650,65 @@ int DeckList::getSideboardSize() const DecklistCardNode *DeckList::addCard(const QString &cardName, const QString &zoneName) { - InnerDecklistNode *zoneNode = dynamic_cast(root->findChild(zoneName)); - if (!zoneNode) - zoneNode = new InnerDecklistNode(zoneName, root); + InnerDecklistNode *zoneNode = dynamic_cast(root->findChild(zoneName)); + if (!zoneNode) + zoneNode = new InnerDecklistNode(zoneName, root); - DecklistCardNode *node = new DecklistCardNode(cardName, 1, zoneNode); - updateDeckHash(); - return node; + DecklistCardNode *node = new DecklistCardNode(cardName, 1, zoneNode); + updateDeckHash(); + return node; } bool DeckList::deleteNode(AbstractDecklistNode *node, InnerDecklistNode *rootNode) { - if (node == root) - return true; - bool updateHash = false; - if (!rootNode) { - rootNode = root; - updateHash = true; - } - - int index = rootNode->indexOf(node); - if (index != -1) { - delete rootNode->takeAt(index); - if (!rootNode->size()) - deleteNode(rootNode, rootNode->getParent()); - if (updateHash) - updateDeckHash(); - return true; - } - for (int i = 0; i < rootNode->size(); i++) { - InnerDecklistNode *inner = dynamic_cast(rootNode->at(i)); - if (inner) - if (deleteNode(node, inner)) { - if (updateHash) - updateDeckHash(); - return true; - } - } - return false; + if (node == root) + return true; + bool updateHash = false; + if (!rootNode) { + rootNode = root; + updateHash = true; + } + + int index = rootNode->indexOf(node); + if (index != -1) { + delete rootNode->takeAt(index); + if (!rootNode->size()) + deleteNode(rootNode, rootNode->getParent()); + if (updateHash) + updateDeckHash(); + return true; + } + for (int i = 0; i < rootNode->size(); i++) { + InnerDecklistNode *inner = dynamic_cast(rootNode->at(i)); + if (inner) + if (deleteNode(node, inner)) { + if (updateHash) + updateDeckHash(); + return true; + } + } + return false; } void DeckList::updateDeckHash() { - QStringList cardList; - for (int i = 0; i < root->size(); i++) { - InnerDecklistNode *node = dynamic_cast(root->at(i)); - for (int j = 0; j < node->size(); j++) { - DecklistCardNode *card = dynamic_cast(node->at(j)); - for (int k = 0; k < card->getNumber(); ++k) - cardList.append((node->getName() == "side" ? "SB:" : "") + card->getName().toLower()); - } - } - cardList.sort(); - QByteArray deckHashArray = QCryptographicHash::hash(cardList.join(";").toUtf8(), QCryptographicHash::Sha1); - quint64 number = (((quint64) (unsigned char) deckHashArray[0]) << 32) - + (((quint64) (unsigned char) deckHashArray[1]) << 24) - + (((quint64) (unsigned char) deckHashArray[2] << 16)) - + (((quint64) (unsigned char) deckHashArray[3]) << 8) - + (quint64) (unsigned char) deckHashArray[4]; - deckHash = QString::number(number, 32).rightJustified(8, '0'); - - emit deckHashChanged(); + QStringList cardList; + for (int i = 0; i < root->size(); i++) { + InnerDecklistNode *node = dynamic_cast(root->at(i)); + for (int j = 0; j < node->size(); j++) { + DecklistCardNode *card = dynamic_cast(node->at(j)); + for (int k = 0; k < card->getNumber(); ++k) + cardList.append((node->getName() == "side" ? "SB:" : "") + card->getName().toLower()); + } + } + cardList.sort(); + QByteArray deckHashArray = QCryptographicHash::hash(cardList.join(";").toUtf8(), QCryptographicHash::Sha1); + quint64 number = (((quint64) (unsigned char) deckHashArray[0]) << 32) + + (((quint64) (unsigned char) deckHashArray[1]) << 24) + + (((quint64) (unsigned char) deckHashArray[2] << 16)) + + (((quint64) (unsigned char) deckHashArray[3]) << 8) + + (quint64) (unsigned char) deckHashArray[4]; + deckHash = QString::number(number, 32).rightJustified(8, '0'); + + emit deckHashChanged(); } diff --git a/common/decklist.h b/common/decklist.h index 2eed52fc..8b71a4b7 100644 --- a/common/decklist.h +++ b/common/decklist.h @@ -23,152 +23,152 @@ class InnerDecklistNode; class SideboardPlan { private: - QString name; - QList moveList; + QString name; + QList moveList; public: - SideboardPlan(const QString &_name = QString(), const QList &_moveList = QList()); - bool readElement(QXmlStreamReader *xml); - void write(QXmlStreamWriter *xml); + SideboardPlan(const QString &_name = QString(), const QList &_moveList = QList()); + bool readElement(QXmlStreamReader *xml); + void write(QXmlStreamWriter *xml); - QString getName() const { return name; } - const QList &getMoveList() const { return moveList; } - void setMoveList(const QList &_moveList); + QString getName() const { return name; } + const QList &getMoveList() const { return moveList; } + void setMoveList(const QList &_moveList); }; enum DeckSortMethod { ByNumber, ByName, ByPrice }; class AbstractDecklistNode { protected: - InnerDecklistNode *parent; - DeckSortMethod sortMethod; + InnerDecklistNode *parent; + DeckSortMethod sortMethod; public: - AbstractDecklistNode(InnerDecklistNode *_parent = 0); - virtual ~AbstractDecklistNode() { } - virtual void setSortMethod(DeckSortMethod method) { sortMethod = method; } - virtual QString getName() const = 0; - InnerDecklistNode *getParent() const { return parent; } - int depth() const; - virtual int height() const = 0; - virtual bool compare(AbstractDecklistNode *other) const = 0; + AbstractDecklistNode(InnerDecklistNode *_parent = 0); + virtual ~AbstractDecklistNode() { } + virtual void setSortMethod(DeckSortMethod method) { sortMethod = method; } + virtual QString getName() const = 0; + InnerDecklistNode *getParent() const { return parent; } + int depth() const; + virtual int height() const = 0; + virtual bool compare(AbstractDecklistNode *other) const = 0; - virtual bool readElement(QXmlStreamReader *xml) = 0; - virtual void writeElement(QXmlStreamWriter *xml) = 0; + virtual bool readElement(QXmlStreamReader *xml) = 0; + virtual void writeElement(QXmlStreamWriter *xml) = 0; }; class InnerDecklistNode : public AbstractDecklistNode, public QList { private: - QString name; - class compareFunctor; + QString name; + class compareFunctor; public: - InnerDecklistNode(const QString &_name = QString(), InnerDecklistNode *_parent = 0) : AbstractDecklistNode(_parent), name(_name) { } - InnerDecklistNode(InnerDecklistNode *other, InnerDecklistNode *_parent = 0); - virtual ~InnerDecklistNode(); - void setSortMethod(DeckSortMethod method); - QString getName() const { return name; } - void setName(const QString &_name) { name = _name; } - static QString visibleNameFromName(const QString &_name); - virtual QString getVisibleName() const; - void clearTree(); - AbstractDecklistNode *findChild(const QString &name); - int height() const; - int recursiveCount(bool countTotalCards = false) const; + InnerDecklistNode(const QString &_name = QString(), InnerDecklistNode *_parent = 0) : AbstractDecklistNode(_parent), name(_name) { } + InnerDecklistNode(InnerDecklistNode *other, InnerDecklistNode *_parent = 0); + virtual ~InnerDecklistNode(); + void setSortMethod(DeckSortMethod method); + QString getName() const { return name; } + void setName(const QString &_name) { name = _name; } + static QString visibleNameFromName(const QString &_name); + virtual QString getVisibleName() const; + void clearTree(); + AbstractDecklistNode *findChild(const QString &name); + int height() const; + int recursiveCount(bool countTotalCards = false) const; float recursivePrice(bool countTotalCards = false) const; - bool compare(AbstractDecklistNode *other) const; - bool compareNumber(AbstractDecklistNode *other) const; - bool compareName(AbstractDecklistNode *other) const; - bool comparePrice(AbstractDecklistNode *other) const; - QVector > sort(Qt::SortOrder order = Qt::AscendingOrder); + bool compare(AbstractDecklistNode *other) const; + bool compareNumber(AbstractDecklistNode *other) const; + bool compareName(AbstractDecklistNode *other) const; + bool comparePrice(AbstractDecklistNode *other) const; + QVector > sort(Qt::SortOrder order = Qt::AscendingOrder); - bool readElement(QXmlStreamReader *xml); - void writeElement(QXmlStreamWriter *xml); + bool readElement(QXmlStreamReader *xml); + void writeElement(QXmlStreamWriter *xml); }; class AbstractDecklistCardNode : public AbstractDecklistNode { public: - AbstractDecklistCardNode(InnerDecklistNode *_parent = 0) : AbstractDecklistNode(_parent) { } - virtual int getNumber() const = 0; - virtual void setNumber(int _number) = 0; - virtual QString getName() const = 0; - virtual void setName(const QString &_name) = 0; + AbstractDecklistCardNode(InnerDecklistNode *_parent = 0) : AbstractDecklistNode(_parent) { } + virtual int getNumber() const = 0; + virtual void setNumber(int _number) = 0; + virtual QString getName() const = 0; + virtual void setName(const QString &_name) = 0; virtual float getPrice() const = 0; virtual void setPrice(const float _price) = 0; float getTotalPrice() const { return getNumber() * getPrice(); } - int height() const { return 0; } - bool compare(AbstractDecklistNode *other) const; - bool compareNumber(AbstractDecklistNode *other) const; - bool compareName(AbstractDecklistNode *other) const; - bool compareTotalPrice(AbstractDecklistNode *other) const; + int height() const { return 0; } + bool compare(AbstractDecklistNode *other) const; + bool compareNumber(AbstractDecklistNode *other) const; + bool compareName(AbstractDecklistNode *other) const; + bool compareTotalPrice(AbstractDecklistNode *other) const; - bool readElement(QXmlStreamReader *xml); - void writeElement(QXmlStreamWriter *xml); + bool readElement(QXmlStreamReader *xml); + void writeElement(QXmlStreamWriter *xml); }; class DecklistCardNode : public AbstractDecklistCardNode { private: - QString name; - int number; + QString name; + int number; float price; public: DecklistCardNode(const QString &_name = QString(), int _number = 1, float _price = 0, InnerDecklistNode *_parent = 0) : AbstractDecklistCardNode(_parent), name(_name), number(_number), price(_price) { } DecklistCardNode(const QString &_name = QString(), int _number = 1, InnerDecklistNode *_parent = 0) : AbstractDecklistCardNode(_parent), name(_name), number(_number), price(0) { } - DecklistCardNode(DecklistCardNode *other, InnerDecklistNode *_parent); - int getNumber() const { return number; } - void setNumber(int _number) { number = _number; } - QString getName() const { return name; } - void setName(const QString &_name) { name = _name; } + DecklistCardNode(DecklistCardNode *other, InnerDecklistNode *_parent); + int getNumber() const { return number; } + void setNumber(int _number) { number = _number; } + QString getName() const { return name; } + void setName(const QString &_name) { name = _name; } float getPrice() const { return price; } void setPrice(const float _price) { price = _price; } }; class DeckList : public QObject { - Q_OBJECT + Q_OBJECT private: - QString name, comments; - QString deckHash; - QMap sideboardPlans; - InnerDecklistNode *root; - void getCardListHelper(InnerDecklistNode *node, QSet &result) const; + QString name, comments; + QString deckHash; + QMap sideboardPlans; + InnerDecklistNode *root; + void getCardListHelper(InnerDecklistNode *node, QSet &result) const; signals: - void deckHashChanged(); + void deckHashChanged(); public slots: - void setName(const QString &_name = QString()) { name = _name; } - void setComments(const QString &_comments = QString()) { comments = _comments; } + void setName(const QString &_name = QString()) { name = _name; } + void setComments(const QString &_comments = QString()) { comments = _comments; } public: - DeckList(); - DeckList(const DeckList &other); - DeckList(const QString &nativeString); - ~DeckList(); - QString getName() const { return name; } - QString getComments() const { return comments; } - QList getCurrentSideboardPlan(); - void setCurrentSideboardPlan(const QList &plan); - const QMap &getSideboardPlans() const { return sideboardPlans; } + DeckList(); + DeckList(const DeckList &other); + DeckList(const QString &nativeString); + ~DeckList(); + QString getName() const { return name; } + QString getComments() const { return comments; } + QList getCurrentSideboardPlan(); + void setCurrentSideboardPlan(const QList &plan); + const QMap &getSideboardPlans() const { return sideboardPlans; } - bool readElement(QXmlStreamReader *xml); - void write(QXmlStreamWriter *xml); - bool loadFromXml(QXmlStreamReader *xml); - bool loadFromString_Native(const QString &nativeString); - QString writeToString_Native(); - bool loadFromFile_Native(QIODevice *device); - bool saveToFile_Native(QIODevice *device); - bool loadFromStream_Plain(QTextStream &stream); - bool loadFromFile_Plain(QIODevice *device); - bool saveToStream_Plain(QTextStream &stream); - bool saveToFile_Plain(QIODevice *device); - QString writeToString_Plain(); + bool readElement(QXmlStreamReader *xml); + void write(QXmlStreamWriter *xml); + bool loadFromXml(QXmlStreamReader *xml); + bool loadFromString_Native(const QString &nativeString); + QString writeToString_Native(); + bool loadFromFile_Native(QIODevice *device); + bool saveToFile_Native(QIODevice *device); + bool loadFromStream_Plain(QTextStream &stream); + bool loadFromFile_Plain(QIODevice *device); + bool saveToStream_Plain(QTextStream &stream); + bool saveToFile_Plain(QIODevice *device); + QString writeToString_Plain(); - void cleanList(); - bool isEmpty() const { return root->isEmpty() && name.isEmpty() && comments.isEmpty() && sideboardPlans.isEmpty(); } - QStringList getCardList() const; + void cleanList(); + bool isEmpty() const { return root->isEmpty() && name.isEmpty() && comments.isEmpty() && sideboardPlans.isEmpty(); } + QStringList getCardList() const; int getSideboardSize() const; - QString getDeckHash() const { return deckHash; } - void updateDeckHash(); + QString getDeckHash() const { return deckHash; } + void updateDeckHash(); - InnerDecklistNode *getRoot() const { return root; } - DecklistCardNode *addCard(const QString &cardName, const QString &zoneName); - bool deleteNode(AbstractDecklistNode *node, InnerDecklistNode *rootNode = 0); + InnerDecklistNode *getRoot() const { return root; } + DecklistCardNode *addCard(const QString &cardName, const QString &zoneName); + bool deleteNode(AbstractDecklistNode *node, InnerDecklistNode *rootNode = 0); }; #endif diff --git a/common/get_pb_extension.cpp b/common/get_pb_extension.cpp index d561f0c8..1e980f4b 100644 --- a/common/get_pb_extension.cpp +++ b/common/get_pb_extension.cpp @@ -4,10 +4,10 @@ int getPbExtension(const ::google::protobuf::Message &message) { - std::vector< const ::google::protobuf::FieldDescriptor * > fieldList; - message.GetReflection()->ListFields(message, &fieldList); - for (unsigned int j = 0; j < fieldList.size(); ++j) - if (fieldList[j]->is_extension()) - return fieldList[j]->number(); - return -1; + std::vector< const ::google::protobuf::FieldDescriptor * > fieldList; + message.GetReflection()->ListFields(message, &fieldList); + for (unsigned int j = 0; j < fieldList.size(); ++j) + if (fieldList[j]->is_extension()) + return fieldList[j]->number(); + return -1; } diff --git a/common/get_pb_extension.h b/common/get_pb_extension.h index c55aa937..bebef39e 100644 --- a/common/get_pb_extension.h +++ b/common/get_pb_extension.h @@ -2,9 +2,9 @@ #define GET_PB_EXTENSION_H namespace google { - namespace protobuf { - class Message; - } + namespace protobuf { + class Message; + } } int getPbExtension(const ::google::protobuf::Message &message); diff --git a/common/rng_abstract.cpp b/common/rng_abstract.cpp index 4c51143a..79054908 100644 --- a/common/rng_abstract.cpp +++ b/common/rng_abstract.cpp @@ -4,27 +4,27 @@ QVector RNG_Abstract::makeNumbersVector(int n, int min, int max) { - const int bins = max - min + 1; - QVector result(bins); - for (int i = 0; i < n; ++i) { - int number = rand(min, max); - if ((number < min) || (number > max)) - qDebug() << "rand(" << min << "," << max << ") returned " << number; - else - result[number - min]++; - } - return result; + const int bins = max - min + 1; + QVector result(bins); + for (int i = 0; i < n; ++i) { + int number = rand(min, max); + if ((number < min) || (number > max)) + qDebug() << "rand(" << min << "," << max << ") returned " << number; + else + result[number - min]++; + } + return result; } double RNG_Abstract::testRandom(const QVector &numbers) const { - int n = 0; - for (int i = 0; i < numbers.size(); ++i) - n += numbers[i]; - double expected = (double) n / (double) numbers.size(); - double chisq = 0; - for (int i = 0; i < numbers.size(); ++i) - chisq += ((double) numbers[i] - expected) * ((double) numbers[i] - expected) / expected; - - return chisq; + int n = 0; + for (int i = 0; i < numbers.size(); ++i) + n += numbers[i]; + double expected = (double) n / (double) numbers.size(); + double chisq = 0; + for (int i = 0; i < numbers.size(); ++i) + chisq += ((double) numbers[i] - expected) * ((double) numbers[i] - expected) / expected; + + return chisq; } diff --git a/common/rng_abstract.h b/common/rng_abstract.h index f2017819..0423930c 100644 --- a/common/rng_abstract.h +++ b/common/rng_abstract.h @@ -5,12 +5,12 @@ #include class RNG_Abstract : public QObject { - Q_OBJECT + Q_OBJECT public: - RNG_Abstract(QObject *parent = 0) : QObject(parent) { } - virtual unsigned int rand(int min, int max) = 0; - QVector makeNumbersVector(int n, int min, int max); - double testRandom(const QVector &numbers) const; + RNG_Abstract(QObject *parent = 0) : QObject(parent) { } + virtual unsigned int rand(int min, int max) = 0; + QVector makeNumbersVector(int n, int min, int max); + double testRandom(const QVector &numbers) const; }; extern RNG_Abstract *rng; diff --git a/common/rng_sfmt.cpp b/common/rng_sfmt.cpp index d3d55d1c..783594a0 100644 --- a/common/rng_sfmt.cpp +++ b/common/rng_sfmt.cpp @@ -11,10 +11,10 @@ #endif RNG_SFMT::RNG_SFMT(QObject *parent) - : RNG_Abstract(parent) + : RNG_Abstract(parent) { - // initialize the random number generator with a 32bit integer seed (timestamp) - sfmt_init_gen_rand(&sfmt, QDateTime::currentDateTime().toTime_t()); + // initialize the random number generator with a 32bit integer seed (timestamp) + sfmt_init_gen_rand(&sfmt, QDateTime::currentDateTime().toTime_t()); } /** @@ -32,11 +32,11 @@ unsigned int RNG_SFMT::rand(int min, int max) { * There has been no use for negative random numbers with rand() though, so it's treated as error. */ if(min < 0) { - throw std::invalid_argument( - QString("Invalid bounds for RNG: Got min " + - QString::number(min) + " < 0!\n").toStdString()); - // at this point, the method exits. No return value is needed, because - // basically the exception itself is returned. + throw std::invalid_argument( + QString("Invalid bounds for RNG: Got min " + + QString::number(min) + " < 0!\n").toStdString()); + // at this point, the method exits. No return value is needed, because + // basically the exception itself is returned. } // For complete fairness and equal timing, this should be a roll, but let's skip it anyway @@ -99,38 +99,38 @@ unsigned int RNG_SFMT::rand(int min, int max) { */ unsigned int RNG_SFMT::cdf(unsigned int min, unsigned int max) { - // This all makes no sense if min > max, which should never happen. - if(min > max) { - throw std::invalid_argument( - QString("Invalid bounds for RNG: min > max! Values were: min = " + - QString::number(min) + ", max = " + - QString::number(max)).toStdString()); - // at this point, the method exits. No return value is needed, because - // basically the exception itself is returned. - } + // This all makes no sense if min > max, which should never happen. + if(min > max) { + throw std::invalid_argument( + QString("Invalid bounds for RNG: min > max! Values were: min = " + + QString::number(min) + ", max = " + + QString::number(max)).toStdString()); + // at this point, the method exits. No return value is needed, because + // basically the exception itself is returned. + } - // First compute the diameter (aka size, length) of the [min, max] interval - const unsigned int diameter = max - min + 1; + // First compute the diameter (aka size, length) of the [min, max] interval + const unsigned int diameter = max - min + 1; - // Compute how many buckets (each in size of the diameter) will fit into the - // universe. - // If the division has a remainder, the result is floored automatically. - const uint64_t buckets = UINT64_MAX / diameter; + // Compute how many buckets (each in size of the diameter) will fit into the + // universe. + // If the division has a remainder, the result is floored automatically. + const uint64_t buckets = UINT64_MAX / diameter; - // Compute the last valid random number. All numbers beyond have to be ignored. - // If there was no remainder in the previous step, limit is equal to UINT64_MAX. - const uint64_t limit = diameter * buckets; + // Compute the last valid random number. All numbers beyond have to be ignored. + // If there was no remainder in the previous step, limit is equal to UINT64_MAX. + const uint64_t limit = diameter * buckets; - uint64_t rand; - // To make the random number generation thread-safe, a mutex is created around - // the generation. Outside of the loop of course, to avoid lock/unlock overhead. - mutex.lock(); - do { - rand = sfmt_genrand_uint64(&sfmt); - } while (rand >= limit); - mutex.unlock(); + uint64_t rand; + // To make the random number generation thread-safe, a mutex is created around + // the generation. Outside of the loop of course, to avoid lock/unlock overhead. + mutex.lock(); + do { + rand = sfmt_genrand_uint64(&sfmt); + } while (rand >= limit); + mutex.unlock(); - // Now determine the bucket containing the SFMT() random number and after adding - // the lower bound, a random number from [min, max] can be returned. - return (unsigned int) (rand / buckets + min); + // Now determine the bucket containing the SFMT() random number and after adding + // the lower bound, a random number from [min, max] can be returned. + return (unsigned int) (rand / buckets + min); } diff --git a/common/rng_sfmt.h b/common/rng_sfmt.h index d35ce97d..ec7a75c9 100644 --- a/common/rng_sfmt.h +++ b/common/rng_sfmt.h @@ -26,15 +26,15 @@ */ class RNG_SFMT : public RNG_Abstract { - Q_OBJECT + Q_OBJECT private: - QMutex mutex; - sfmt_t sfmt; - // The discrete cumulative distribution function for the RNG - unsigned int cdf(unsigned int min, unsigned int max); + QMutex mutex; + sfmt_t sfmt; + // The discrete cumulative distribution function for the RNG + unsigned int cdf(unsigned int min, unsigned int max); public: - RNG_SFMT(QObject *parent = 0); - unsigned int rand(int min, int max); + RNG_SFMT(QObject *parent = 0); + unsigned int rand(int min, int max); }; #endif diff --git a/common/server.cpp b/common/server.cpp index f0530497..132cba94 100644 --- a/common/server.cpp +++ b/common/server.cpp @@ -36,18 +36,18 @@ #include Server::Server(bool _threaded, QObject *parent) - : QObject(parent), threaded(_threaded), nextLocalGameId(0) + : QObject(parent), threaded(_threaded), nextLocalGameId(0) { - qRegisterMetaType("ServerInfo_Game"); - qRegisterMetaType("ServerInfo_Room"); - qRegisterMetaType("ServerInfo_User"); - qRegisterMetaType("CommandContainer"); - qRegisterMetaType("Response"); - qRegisterMetaType("GameEventContainer"); - qRegisterMetaType("IslMessage"); - qRegisterMetaType("Command_JoinGame"); - - connect(this, SIGNAL(sigSendIslMessage(IslMessage, int)), this, SLOT(doSendIslMessage(IslMessage, int)), Qt::QueuedConnection); + qRegisterMetaType("ServerInfo_Game"); + qRegisterMetaType("ServerInfo_Room"); + qRegisterMetaType("ServerInfo_User"); + qRegisterMetaType("CommandContainer"); + qRegisterMetaType("Response"); + qRegisterMetaType("GameEventContainer"); + qRegisterMetaType("IslMessage"); + qRegisterMetaType("Command_JoinGame"); + + connect(this, SIGNAL(sigSendIslMessage(IslMessage, int)), this, SLOT(doSendIslMessage(IslMessage, int)), Qt::QueuedConnection); } Server::~Server() @@ -56,532 +56,532 @@ Server::~Server() void Server::prepareDestroy() { - // dirty :( - if (threaded) { - clientsLock.lockForRead(); - for (int i = 0; i < clients.size(); ++i) - QMetaObject::invokeMethod(clients.at(i), "prepareDestroy", Qt::QueuedConnection); - clientsLock.unlock(); - - bool done = false; - - class SleeperThread : public QThread - { - public: - static void msleep(unsigned long msecs) { QThread::usleep(msecs); } - }; + // dirty :( + if (threaded) { + clientsLock.lockForRead(); + for (int i = 0; i < clients.size(); ++i) + QMetaObject::invokeMethod(clients.at(i), "prepareDestroy", Qt::QueuedConnection); + clientsLock.unlock(); + + bool done = false; + + class SleeperThread : public QThread + { + public: + static void msleep(unsigned long msecs) { QThread::usleep(msecs); } + }; - do { - SleeperThread::msleep(10); - clientsLock.lockForRead(); - if (clients.isEmpty()) - done = true; - clientsLock.unlock(); - } while (!done); - } else { - // no locking is needed in unthreaded mode - while (!clients.isEmpty()) - clients.first()->prepareDestroy(); - } - - roomsLock.lockForWrite(); - QMapIterator roomIterator(rooms); - while (roomIterator.hasNext()) - delete roomIterator.next().value(); - rooms.clear(); - roomsLock.unlock(); + do { + SleeperThread::msleep(10); + clientsLock.lockForRead(); + if (clients.isEmpty()) + done = true; + clientsLock.unlock(); + } while (!done); + } else { + // no locking is needed in unthreaded mode + while (!clients.isEmpty()) + clients.first()->prepareDestroy(); + } + + roomsLock.lockForWrite(); + QMapIterator roomIterator(rooms); + while (roomIterator.hasNext()) + delete roomIterator.next().value(); + rooms.clear(); + roomsLock.unlock(); } void Server::setDatabaseInterface(Server_DatabaseInterface *_databaseInterface) { - connect(this, SIGNAL(endSession(qint64)), _databaseInterface, SLOT(endSession(qint64))); - databaseInterfaces.insert(QThread::currentThread(), _databaseInterface); + connect(this, SIGNAL(endSession(qint64)), _databaseInterface, SLOT(endSession(qint64))); + databaseInterfaces.insert(QThread::currentThread(), _databaseInterface); } Server_DatabaseInterface *Server::getDatabaseInterface() const { - return databaseInterfaces.value(QThread::currentThread()); + return databaseInterfaces.value(QThread::currentThread()); } AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString &name, const QString &password, QString &reasonStr, int &secondsLeft) { - if (name.size() > 35) - name = name.left(35); - - Server_DatabaseInterface *databaseInterface = getDatabaseInterface(); - - QWriteLocker locker(&clientsLock); - - AuthenticationResult authState = databaseInterface->checkUserPassword(session, name, password, reasonStr, secondsLeft); - if ((authState == NotLoggedIn) || (authState == UserIsBanned || authState == UsernameInvalid)) - return authState; - - ServerInfo_User data = databaseInterface->getUserData(name, true); - data.set_address(session->getAddress().toStdString()); - name = QString::fromStdString(data.name()); // Compensate for case indifference - - databaseInterface->lockSessionTables(); - - if (authState == PasswordRight) { - if (users.contains(name) || databaseInterface->userSessionExists(name)) { - qDebug("Login denied: would overwrite old session"); - databaseInterface->unlockSessionTables(); - return WouldOverwriteOldSession; - } - } else if (authState == UnknownUser) { - // Change user name so that no two users have the same names, - // don't interfere with registered user names though. - QString tempName = name; - int i = 0; - while (users.contains(tempName) || databaseInterface->userExists(tempName) || databaseInterface->userSessionExists(tempName)) - tempName = name + "_" + QString::number(++i); - name = tempName; - data.set_name(name.toStdString()); - } - - users.insert(name, session); - qDebug() << "Server::loginUser:" << session << "name=" << name; - - data.set_session_id(databaseInterface->startSession(name, session->getAddress())); - databaseInterface->unlockSessionTables(); - - usersBySessionId.insert(data.session_id(), session); - - qDebug() << "session id:" << data.session_id(); - session->setUserInfo(data); - - Event_UserJoined event; - event.mutable_user_info()->CopyFrom(session->copyUserInfo(false)); - SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event); - for (int i = 0; i < clients.size(); ++i) - if (clients[i]->getAcceptsUserListChanges()) - clients[i]->sendProtocolItem(*se); - delete se; - - event.mutable_user_info()->CopyFrom(session->copyUserInfo(true, true, true)); - locker.unlock(); - - se = Server_ProtocolHandler::prepareSessionEvent(event); - sendIsl_SessionEvent(*se); - delete se; - - return authState; + if (name.size() > 35) + name = name.left(35); + + Server_DatabaseInterface *databaseInterface = getDatabaseInterface(); + + QWriteLocker locker(&clientsLock); + + AuthenticationResult authState = databaseInterface->checkUserPassword(session, name, password, reasonStr, secondsLeft); + if ((authState == NotLoggedIn) || (authState == UserIsBanned || authState == UsernameInvalid)) + return authState; + + ServerInfo_User data = databaseInterface->getUserData(name, true); + data.set_address(session->getAddress().toStdString()); + name = QString::fromStdString(data.name()); // Compensate for case indifference + + databaseInterface->lockSessionTables(); + + if (authState == PasswordRight) { + if (users.contains(name) || databaseInterface->userSessionExists(name)) { + qDebug("Login denied: would overwrite old session"); + databaseInterface->unlockSessionTables(); + return WouldOverwriteOldSession; + } + } else if (authState == UnknownUser) { + // Change user name so that no two users have the same names, + // don't interfere with registered user names though. + QString tempName = name; + int i = 0; + while (users.contains(tempName) || databaseInterface->userExists(tempName) || databaseInterface->userSessionExists(tempName)) + tempName = name + "_" + QString::number(++i); + name = tempName; + data.set_name(name.toStdString()); + } + + users.insert(name, session); + qDebug() << "Server::loginUser:" << session << "name=" << name; + + data.set_session_id(databaseInterface->startSession(name, session->getAddress())); + databaseInterface->unlockSessionTables(); + + usersBySessionId.insert(data.session_id(), session); + + qDebug() << "session id:" << data.session_id(); + session->setUserInfo(data); + + Event_UserJoined event; + event.mutable_user_info()->CopyFrom(session->copyUserInfo(false)); + SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event); + for (int i = 0; i < clients.size(); ++i) + if (clients[i]->getAcceptsUserListChanges()) + clients[i]->sendProtocolItem(*se); + delete se; + + event.mutable_user_info()->CopyFrom(session->copyUserInfo(true, true, true)); + locker.unlock(); + + se = Server_ProtocolHandler::prepareSessionEvent(event); + sendIsl_SessionEvent(*se); + delete se; + + return authState; } void Server::addPersistentPlayer(const QString &userName, int roomId, int gameId, int playerId) { - QWriteLocker locker(&persistentPlayersLock); - persistentPlayers.insert(userName, PlayerReference(roomId, gameId, playerId)); + QWriteLocker locker(&persistentPlayersLock); + persistentPlayers.insert(userName, PlayerReference(roomId, gameId, playerId)); } void Server::removePersistentPlayer(const QString &userName, int roomId, int gameId, int playerId) { - QWriteLocker locker(&persistentPlayersLock); - persistentPlayers.remove(userName, PlayerReference(roomId, gameId, playerId)); + QWriteLocker locker(&persistentPlayersLock); + persistentPlayers.remove(userName, PlayerReference(roomId, gameId, playerId)); } QList Server::getPersistentPlayerReferences(const QString &userName) const { - QReadLocker locker(&persistentPlayersLock); - return persistentPlayers.values(userName); + QReadLocker locker(&persistentPlayersLock); + return persistentPlayers.values(userName); } Server_AbstractUserInterface *Server::findUser(const QString &userName) const { - // Call this only with clientsLock set. - - Server_AbstractUserInterface *userHandler = users.value(userName); - if (userHandler) - return userHandler; - else - return externalUsers.value(userName); + // Call this only with clientsLock set. + + Server_AbstractUserInterface *userHandler = users.value(userName); + if (userHandler) + return userHandler; + else + return externalUsers.value(userName); } void Server::addClient(Server_ProtocolHandler *client) { - QWriteLocker locker(&clientsLock); - clients << client; + QWriteLocker locker(&clientsLock); + clients << client; } void Server::removeClient(Server_ProtocolHandler *client) { - QWriteLocker locker(&clientsLock); - clients.removeAt(clients.indexOf(client)); - ServerInfo_User *data = client->getUserInfo(); - if (data) { - Event_UserLeft event; - event.set_name(data->name()); - SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event); - for (int i = 0; i < clients.size(); ++i) - if (clients[i]->getAcceptsUserListChanges()) - clients[i]->sendProtocolItem(*se); - sendIsl_SessionEvent(*se); - delete se; - - users.remove(QString::fromStdString(data->name())); - qDebug() << "Server::removeClient: name=" << QString::fromStdString(data->name()); - - if (data->has_session_id()) { - const qint64 sessionId = data->session_id(); - usersBySessionId.remove(sessionId); - emit endSession(sessionId); - qDebug() << "closed session id:" << sessionId; - } - } - qDebug() << "Server::removeClient: removed" << (void *) client << ";" << clients.size() << "clients; " << users.size() << "users left"; + QWriteLocker locker(&clientsLock); + clients.removeAt(clients.indexOf(client)); + ServerInfo_User *data = client->getUserInfo(); + if (data) { + Event_UserLeft event; + event.set_name(data->name()); + SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event); + for (int i = 0; i < clients.size(); ++i) + if (clients[i]->getAcceptsUserListChanges()) + clients[i]->sendProtocolItem(*se); + sendIsl_SessionEvent(*se); + delete se; + + users.remove(QString::fromStdString(data->name())); + qDebug() << "Server::removeClient: name=" << QString::fromStdString(data->name()); + + if (data->has_session_id()) { + const qint64 sessionId = data->session_id(); + usersBySessionId.remove(sessionId); + emit endSession(sessionId); + qDebug() << "closed session id:" << sessionId; + } + } + qDebug() << "Server::removeClient: removed" << (void *) client << ";" << clients.size() << "clients; " << users.size() << "users left"; } void Server::externalUserJoined(const ServerInfo_User &userInfo) { - // This function is always called from the main thread via signal/slot. - clientsLock.lockForWrite(); - - Server_RemoteUserInterface *newUser = new Server_RemoteUserInterface(this, ServerInfo_User_Container(userInfo)); - externalUsers.insert(QString::fromStdString(userInfo.name()), newUser); - externalUsersBySessionId.insert(userInfo.session_id(), newUser); - - Event_UserJoined event; - event.mutable_user_info()->CopyFrom(userInfo); - - SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event); - for (int i = 0; i < clients.size(); ++i) - if (clients[i]->getAcceptsUserListChanges()) - clients[i]->sendProtocolItem(*se); - delete se; - clientsLock.unlock(); - - ResponseContainer rc(-1); - newUser->joinPersistentGames(rc); - newUser->sendResponseContainer(rc, Response::RespNothing); + // This function is always called from the main thread via signal/slot. + clientsLock.lockForWrite(); + + Server_RemoteUserInterface *newUser = new Server_RemoteUserInterface(this, ServerInfo_User_Container(userInfo)); + externalUsers.insert(QString::fromStdString(userInfo.name()), newUser); + externalUsersBySessionId.insert(userInfo.session_id(), newUser); + + Event_UserJoined event; + event.mutable_user_info()->CopyFrom(userInfo); + + SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event); + for (int i = 0; i < clients.size(); ++i) + if (clients[i]->getAcceptsUserListChanges()) + clients[i]->sendProtocolItem(*se); + delete se; + clientsLock.unlock(); + + ResponseContainer rc(-1); + newUser->joinPersistentGames(rc); + newUser->sendResponseContainer(rc, Response::RespNothing); } void Server::externalUserLeft(const QString &userName) { - // This function is always called from the main thread via signal/slot. - - clientsLock.lockForWrite(); - Server_AbstractUserInterface *user = externalUsers.take(userName); - externalUsersBySessionId.remove(user->getUserInfo()->session_id()); - clientsLock.unlock(); - - QMap > userGames(user->getGames()); - QMapIterator > userGamesIterator(userGames); - roomsLock.lockForRead(); - while (userGamesIterator.hasNext()) { - userGamesIterator.next(); - Server_Room *room = rooms.value(userGamesIterator.value().first); - if (!room) - continue; - - QReadLocker roomGamesLocker(&room->gamesLock); - Server_Game *game = room->getGames().value(userGamesIterator.key()); - if (!game) - continue; - - QMutexLocker gameLocker(&game->gameMutex); - Server_Player *player = game->getPlayers().value(userGamesIterator.value().second); - if (!player) - continue; - - player->disconnectClient(); - } - roomsLock.unlock(); - - delete user; - - Event_UserLeft event; - event.set_name(userName.toStdString()); - - SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event); - clientsLock.lockForRead(); - for (int i = 0; i < clients.size(); ++i) - if (clients[i]->getAcceptsUserListChanges()) - clients[i]->sendProtocolItem(*se); - clientsLock.unlock(); - delete se; + // This function is always called from the main thread via signal/slot. + + clientsLock.lockForWrite(); + Server_AbstractUserInterface *user = externalUsers.take(userName); + externalUsersBySessionId.remove(user->getUserInfo()->session_id()); + clientsLock.unlock(); + + QMap > userGames(user->getGames()); + QMapIterator > userGamesIterator(userGames); + roomsLock.lockForRead(); + while (userGamesIterator.hasNext()) { + userGamesIterator.next(); + Server_Room *room = rooms.value(userGamesIterator.value().first); + if (!room) + continue; + + QReadLocker roomGamesLocker(&room->gamesLock); + Server_Game *game = room->getGames().value(userGamesIterator.key()); + if (!game) + continue; + + QMutexLocker gameLocker(&game->gameMutex); + Server_Player *player = game->getPlayers().value(userGamesIterator.value().second); + if (!player) + continue; + + player->disconnectClient(); + } + roomsLock.unlock(); + + delete user; + + Event_UserLeft event; + event.set_name(userName.toStdString()); + + SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event); + clientsLock.lockForRead(); + for (int i = 0; i < clients.size(); ++i) + if (clients[i]->getAcceptsUserListChanges()) + clients[i]->sendProtocolItem(*se); + clientsLock.unlock(); + delete se; } void Server::externalRoomUserJoined(int roomId, const ServerInfo_User &userInfo) { - // This function is always called from the main thread via signal/slot. - QReadLocker locker(&roomsLock); - - Server_Room *room = rooms.value(roomId); - if (!room) { - qDebug() << "externalRoomUserJoined: room id=" << roomId << "not found"; - return; - } - room->addExternalUser(userInfo); + // This function is always called from the main thread via signal/slot. + QReadLocker locker(&roomsLock); + + Server_Room *room = rooms.value(roomId); + if (!room) { + qDebug() << "externalRoomUserJoined: room id=" << roomId << "not found"; + return; + } + room->addExternalUser(userInfo); } void Server::externalRoomUserLeft(int roomId, const QString &userName) { - // This function is always called from the main thread via signal/slot. - QReadLocker locker(&roomsLock); - - Server_Room *room = rooms.value(roomId); - if (!room) { - qDebug() << "externalRoomUserLeft: room id=" << roomId << "not found"; - return; - } - room->removeExternalUser(userName); + // This function is always called from the main thread via signal/slot. + QReadLocker locker(&roomsLock); + + Server_Room *room = rooms.value(roomId); + if (!room) { + qDebug() << "externalRoomUserLeft: room id=" << roomId << "not found"; + return; + } + room->removeExternalUser(userName); } void Server::externalRoomSay(int roomId, const QString &userName, const QString &message) { - // This function is always called from the main thread via signal/slot. - QReadLocker locker(&roomsLock); - - Server_Room *room = rooms.value(roomId); - if (!room) { - qDebug() << "externalRoomSay: room id=" << roomId << "not found"; - return; - } - room->say(userName, message, false); + // This function is always called from the main thread via signal/slot. + QReadLocker locker(&roomsLock); + + Server_Room *room = rooms.value(roomId); + if (!room) { + qDebug() << "externalRoomSay: room id=" << roomId << "not found"; + return; + } + room->say(userName, message, false); } void Server::externalRoomGameListChanged(int roomId, const ServerInfo_Game &gameInfo) { - // This function is always called from the main thread via signal/slot. - QReadLocker locker(&roomsLock); - - Server_Room *room = rooms.value(roomId); - if (!room) { - qDebug() << "externalRoomGameListChanged: room id=" << roomId << "not found"; - return; - } - room->updateExternalGameList(gameInfo); + // This function is always called from the main thread via signal/slot. + QReadLocker locker(&roomsLock); + + Server_Room *room = rooms.value(roomId); + if (!room) { + qDebug() << "externalRoomGameListChanged: room id=" << roomId << "not found"; + return; + } + room->updateExternalGameList(gameInfo); } void Server::externalJoinGameCommandReceived(const Command_JoinGame &cmd, int cmdId, int roomId, int serverId, qint64 sessionId) { - // This function is always called from the main thread via signal/slot. - - try { - QReadLocker roomsLocker(&roomsLock); - QReadLocker clientsLocker(&clientsLock); - - Server_Room *room = rooms.value(roomId); - if (!room) { - qDebug() << "externalJoinGameCommandReceived: room id=" << roomId << "not found"; - throw Response::RespNotInRoom; - } - Server_AbstractUserInterface *userInterface = externalUsersBySessionId.value(sessionId); - if (!userInterface) { - qDebug() << "externalJoinGameCommandReceived: session id=" << sessionId << "not found"; - throw Response::RespNotInRoom; - } - - ResponseContainer responseContainer(cmdId); - Response::ResponseCode responseCode = room->processJoinGameCommand(cmd, responseContainer, userInterface); - userInterface->sendResponseContainer(responseContainer, responseCode); - } catch (Response::ResponseCode code) { - Response response; - response.set_cmd_id(cmdId); - response.set_response_code(code); - - sendIsl_Response(response, serverId, sessionId); - } + // This function is always called from the main thread via signal/slot. + + try { + QReadLocker roomsLocker(&roomsLock); + QReadLocker clientsLocker(&clientsLock); + + Server_Room *room = rooms.value(roomId); + if (!room) { + qDebug() << "externalJoinGameCommandReceived: room id=" << roomId << "not found"; + throw Response::RespNotInRoom; + } + Server_AbstractUserInterface *userInterface = externalUsersBySessionId.value(sessionId); + if (!userInterface) { + qDebug() << "externalJoinGameCommandReceived: session id=" << sessionId << "not found"; + throw Response::RespNotInRoom; + } + + ResponseContainer responseContainer(cmdId); + Response::ResponseCode responseCode = room->processJoinGameCommand(cmd, responseContainer, userInterface); + userInterface->sendResponseContainer(responseContainer, responseCode); + } catch (Response::ResponseCode code) { + Response response; + response.set_cmd_id(cmdId); + response.set_response_code(code); + + sendIsl_Response(response, serverId, sessionId); + } } void Server::externalGameCommandContainerReceived(const CommandContainer &cont, int playerId, int serverId, qint64 sessionId) { - // This function is always called from the main thread via signal/slot. - - try { - ResponseContainer responseContainer(cont.cmd_id()); - Response::ResponseCode finalResponseCode = Response::RespOk; - - QReadLocker roomsLocker(&roomsLock); - Server_Room *room = rooms.value(cont.room_id()); - if (!room) { - qDebug() << "externalGameCommandContainerReceived: room id=" << cont.room_id() << "not found"; - throw Response::RespNotInRoom; - } - - QReadLocker roomGamesLocker(&room->gamesLock); - Server_Game *game = room->getGames().value(cont.game_id()); - if (!game) { - qDebug() << "externalGameCommandContainerReceived: game id=" << cont.game_id() << "not found"; - throw Response::RespNotInRoom; - } - - QMutexLocker gameLocker(&game->gameMutex); - Server_Player *player = game->getPlayers().value(playerId); - if (!player) { - qDebug() << "externalGameCommandContainerReceived: player id=" << playerId << "not found"; - throw Response::RespNotInRoom; - } - - GameEventStorage ges; - for (int i = cont.game_command_size() - 1; i >= 0; --i) { - const GameCommand &sc = cont.game_command(i); - qDebug() << "[ISL]" << QString::fromStdString(sc.ShortDebugString()); - - Response::ResponseCode resp = player->processGameCommand(sc, responseContainer, ges); - - if (resp != Response::RespOk) - finalResponseCode = resp; - } - ges.sendToGame(game); - - if (finalResponseCode != Response::RespNothing) { - player->playerMutex.lock(); - player->getUserInterface()->sendResponseContainer(responseContainer, finalResponseCode); - player->playerMutex.unlock(); - } - } catch (Response::ResponseCode code) { - Response response; - response.set_cmd_id(cont.cmd_id()); - response.set_response_code(code); - - sendIsl_Response(response, serverId, sessionId); - } + // This function is always called from the main thread via signal/slot. + + try { + ResponseContainer responseContainer(cont.cmd_id()); + Response::ResponseCode finalResponseCode = Response::RespOk; + + QReadLocker roomsLocker(&roomsLock); + Server_Room *room = rooms.value(cont.room_id()); + if (!room) { + qDebug() << "externalGameCommandContainerReceived: room id=" << cont.room_id() << "not found"; + throw Response::RespNotInRoom; + } + + QReadLocker roomGamesLocker(&room->gamesLock); + Server_Game *game = room->getGames().value(cont.game_id()); + if (!game) { + qDebug() << "externalGameCommandContainerReceived: game id=" << cont.game_id() << "not found"; + throw Response::RespNotInRoom; + } + + QMutexLocker gameLocker(&game->gameMutex); + Server_Player *player = game->getPlayers().value(playerId); + if (!player) { + qDebug() << "externalGameCommandContainerReceived: player id=" << playerId << "not found"; + throw Response::RespNotInRoom; + } + + GameEventStorage ges; + for (int i = cont.game_command_size() - 1; i >= 0; --i) { + const GameCommand &sc = cont.game_command(i); + qDebug() << "[ISL]" << QString::fromStdString(sc.ShortDebugString()); + + Response::ResponseCode resp = player->processGameCommand(sc, responseContainer, ges); + + if (resp != Response::RespOk) + finalResponseCode = resp; + } + ges.sendToGame(game); + + if (finalResponseCode != Response::RespNothing) { + player->playerMutex.lock(); + player->getUserInterface()->sendResponseContainer(responseContainer, finalResponseCode); + player->playerMutex.unlock(); + } + } catch (Response::ResponseCode code) { + Response response; + response.set_cmd_id(cont.cmd_id()); + response.set_response_code(code); + + sendIsl_Response(response, serverId, sessionId); + } } void Server::externalGameEventContainerReceived(const GameEventContainer &cont, qint64 sessionId) { - // This function is always called from the main thread via signal/slot. - - QReadLocker usersLocker(&clientsLock); - - Server_ProtocolHandler *client = usersBySessionId.value(sessionId); - if (!client) { - qDebug() << "externalGameEventContainerReceived: session" << sessionId << "not found"; - return; - } - client->sendProtocolItem(cont); + // This function is always called from the main thread via signal/slot. + + QReadLocker usersLocker(&clientsLock); + + Server_ProtocolHandler *client = usersBySessionId.value(sessionId); + if (!client) { + qDebug() << "externalGameEventContainerReceived: session" << sessionId << "not found"; + return; + } + client->sendProtocolItem(cont); } void Server::externalResponseReceived(const Response &resp, qint64 sessionId) { - // This function is always called from the main thread via signal/slot. - - QReadLocker usersLocker(&clientsLock); - - Server_ProtocolHandler *client = usersBySessionId.value(sessionId); - if (!client) { - qDebug() << "externalResponseReceived: session" << sessionId << "not found"; - return; - } - client->sendProtocolItem(resp); + // This function is always called from the main thread via signal/slot. + + QReadLocker usersLocker(&clientsLock); + + Server_ProtocolHandler *client = usersBySessionId.value(sessionId); + if (!client) { + qDebug() << "externalResponseReceived: session" << sessionId << "not found"; + return; + } + client->sendProtocolItem(resp); } void Server::broadcastRoomUpdate(const ServerInfo_Room &roomInfo, bool sendToIsl) { - // This function is always called from the main thread via signal/slot. - - Event_ListRooms event; - event.add_room_list()->CopyFrom(roomInfo); - - SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event); + // This function is always called from the main thread via signal/slot. + + Event_ListRooms event; + event.add_room_list()->CopyFrom(roomInfo); + + SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event); - clientsLock.lockForRead(); - for (int i = 0; i < clients.size(); ++i) - if (clients[i]->getAcceptsRoomListChanges()) - clients[i]->sendProtocolItem(*se); - clientsLock.unlock(); - - if (sendToIsl) - sendIsl_SessionEvent(*se); - - delete se; + clientsLock.lockForRead(); + for (int i = 0; i < clients.size(); ++i) + if (clients[i]->getAcceptsRoomListChanges()) + clients[i]->sendProtocolItem(*se); + clientsLock.unlock(); + + if (sendToIsl) + sendIsl_SessionEvent(*se); + + delete se; } void Server::addRoom(Server_Room *newRoom) { - QWriteLocker locker(&roomsLock); - qDebug() << "Adding room: ID=" << newRoom->getId() << "name=" << newRoom->getName(); - rooms.insert(newRoom->getId(), newRoom); - connect(newRoom, SIGNAL(roomInfoChanged(ServerInfo_Room)), this, SLOT(broadcastRoomUpdate(const ServerInfo_Room &)), Qt::QueuedConnection); + QWriteLocker locker(&roomsLock); + qDebug() << "Adding room: ID=" << newRoom->getId() << "name=" << newRoom->getName(); + rooms.insert(newRoom->getId(), newRoom); + connect(newRoom, SIGNAL(roomInfoChanged(ServerInfo_Room)), this, SLOT(broadcastRoomUpdate(const ServerInfo_Room &)), Qt::QueuedConnection); } int Server::getUsersCount() const { - QReadLocker locker(&clientsLock); - return users.size(); + QReadLocker locker(&clientsLock); + return users.size(); } int Server::getGamesCount() const { - int result = 0; - QReadLocker locker(&roomsLock); - QMapIterator roomIterator(rooms); - while (roomIterator.hasNext()) { - Server_Room *room = roomIterator.next().value(); - QReadLocker roomLocker(&room->gamesLock); - result += room->getGames().size(); - } - return result; + int result = 0; + QReadLocker locker(&roomsLock); + QMapIterator roomIterator(rooms); + while (roomIterator.hasNext()) { + Server_Room *room = roomIterator.next().value(); + QReadLocker roomLocker(&room->gamesLock); + result += room->getGames().size(); + } + return result; } void Server::sendIsl_Response(const Response &item, int serverId, qint64 sessionId) { - IslMessage msg; - msg.set_message_type(IslMessage::RESPONSE); - if (sessionId != -1) - msg.set_session_id(sessionId); - msg.mutable_response()->CopyFrom(item); - - emit sigSendIslMessage(msg, serverId); + IslMessage msg; + msg.set_message_type(IslMessage::RESPONSE); + if (sessionId != -1) + msg.set_session_id(sessionId); + msg.mutable_response()->CopyFrom(item); + + emit sigSendIslMessage(msg, serverId); } void Server::sendIsl_SessionEvent(const SessionEvent &item, int serverId, qint64 sessionId) { - IslMessage msg; - msg.set_message_type(IslMessage::SESSION_EVENT); - if (sessionId != -1) - msg.set_session_id(sessionId); - msg.mutable_session_event()->CopyFrom(item); - - emit sigSendIslMessage(msg, serverId); + IslMessage msg; + msg.set_message_type(IslMessage::SESSION_EVENT); + if (sessionId != -1) + msg.set_session_id(sessionId); + msg.mutable_session_event()->CopyFrom(item); + + emit sigSendIslMessage(msg, serverId); } void Server::sendIsl_GameEventContainer(const GameEventContainer &item, int serverId, qint64 sessionId) { - IslMessage msg; - msg.set_message_type(IslMessage::GAME_EVENT_CONTAINER); - if (sessionId != -1) - msg.set_session_id(sessionId); - msg.mutable_game_event_container()->CopyFrom(item); - - emit sigSendIslMessage(msg, serverId); + IslMessage msg; + msg.set_message_type(IslMessage::GAME_EVENT_CONTAINER); + if (sessionId != -1) + msg.set_session_id(sessionId); + msg.mutable_game_event_container()->CopyFrom(item); + + emit sigSendIslMessage(msg, serverId); } void Server::sendIsl_RoomEvent(const RoomEvent &item, int serverId, qint64 sessionId) { - IslMessage msg; - msg.set_message_type(IslMessage::ROOM_EVENT); - if (sessionId != -1) - msg.set_session_id(sessionId); - msg.mutable_room_event()->CopyFrom(item); - - emit sigSendIslMessage(msg, serverId); + IslMessage msg; + msg.set_message_type(IslMessage::ROOM_EVENT); + if (sessionId != -1) + msg.set_session_id(sessionId); + msg.mutable_room_event()->CopyFrom(item); + + emit sigSendIslMessage(msg, serverId); } void Server::sendIsl_GameCommand(const CommandContainer &item, int serverId, qint64 sessionId, int roomId, int playerId) { - IslMessage msg; - msg.set_message_type(IslMessage::GAME_COMMAND_CONTAINER); - msg.set_session_id(sessionId); - msg.set_player_id(playerId); - - CommandContainer *cont = msg.mutable_game_command(); - cont->CopyFrom(item); - cont->set_room_id(roomId); - - emit sigSendIslMessage(msg, serverId); + IslMessage msg; + msg.set_message_type(IslMessage::GAME_COMMAND_CONTAINER); + msg.set_session_id(sessionId); + msg.set_player_id(playerId); + + CommandContainer *cont = msg.mutable_game_command(); + cont->CopyFrom(item); + cont->set_room_id(roomId); + + emit sigSendIslMessage(msg, serverId); } void Server::sendIsl_RoomCommand(const CommandContainer &item, int serverId, qint64 sessionId, int roomId) { - IslMessage msg; - msg.set_message_type(IslMessage::ROOM_COMMAND_CONTAINER); - msg.set_session_id(sessionId); - - CommandContainer *cont = msg.mutable_room_command(); - cont->CopyFrom(item); - cont->set_room_id(roomId); - - emit sigSendIslMessage(msg, serverId); + IslMessage msg; + msg.set_message_type(IslMessage::ROOM_COMMAND_CONTAINER); + msg.set_session_id(sessionId); + + CommandContainer *cont = msg.mutable_room_command(); + cont->CopyFrom(item); + cont->set_room_id(roomId); + + emit sigSendIslMessage(msg, serverId); } diff --git a/common/server.h b/common/server.h index 631d2d2e..6742f6e2 100644 --- a/common/server.h +++ b/common/server.h @@ -31,87 +31,87 @@ enum AuthenticationResult { NotLoggedIn = 0, PasswordRight = 1, UnknownUser = 2, class Server : public QObject { - Q_OBJECT + Q_OBJECT signals: - void pingClockTimeout(); - void sigSendIslMessage(const IslMessage &message, int serverId); - void endSession(qint64 sessionId); + void pingClockTimeout(); + void sigSendIslMessage(const IslMessage &message, int serverId); + void endSession(qint64 sessionId); private slots: - void broadcastRoomUpdate(const ServerInfo_Room &roomInfo, bool sendToIsl = false); + void broadcastRoomUpdate(const ServerInfo_Room &roomInfo, bool sendToIsl = false); public: - mutable QReadWriteLock clientsLock, roomsLock; // locking order: roomsLock before clientsLock - Server(bool _threaded, QObject *parent = 0); - ~Server(); - void setThreaded(bool _threaded) { threaded = _threaded; } - AuthenticationResult loginUser(Server_ProtocolHandler *session, QString &name, const QString &password, QString &reason, int &secondsLeft); - const QMap &getRooms() { return rooms; } - - Server_AbstractUserInterface *findUser(const QString &userName) const; - const QMap &getUsers() const { return users; } - const QMap &getUsersBySessionId() const { return usersBySessionId; } - void addClient(Server_ProtocolHandler *player); - void removeClient(Server_ProtocolHandler *player); - virtual QString getLoginMessage() const { return QString(); } - - virtual bool getGameShouldPing() const { return false; } - virtual int getMaxGameInactivityTime() const { return 9999999; } - virtual int getMaxPlayerInactivityTime() const { return 9999999; } - virtual int getMessageCountingInterval() const { return 0; } - virtual int getMaxMessageCountPerInterval() const { return 0; } - virtual int getMaxMessageSizePerInterval() const { return 0; } - virtual int getMaxGamesPerUser() const { return 0; } - virtual bool getThreaded() const { return false; } - - Server_DatabaseInterface *getDatabaseInterface() const; - int getNextLocalGameId() { QMutexLocker locker(&nextLocalGameIdMutex); return ++nextLocalGameId; } - - void sendIsl_Response(const Response &item, int serverId = -1, qint64 sessionId = -1); - void sendIsl_SessionEvent(const SessionEvent &item, int serverId = -1, qint64 sessionId = -1); - void sendIsl_GameEventContainer(const GameEventContainer &item, int serverId = -1, qint64 sessionId = -1); - void sendIsl_RoomEvent(const RoomEvent &item, int serverId = -1, qint64 sessionId = -1); - void sendIsl_GameCommand(const CommandContainer &item, int serverId, qint64 sessionId, int roomId, int playerId); - void sendIsl_RoomCommand(const CommandContainer &item, int serverId, qint64 sessionId, int roomId); - - void addExternalUser(const ServerInfo_User &userInfo); - void removeExternalUser(const QString &userName); - const QMap &getExternalUsers() const { return externalUsers; } - - void addPersistentPlayer(const QString &userName, int roomId, int gameId, int playerId); - void removePersistentPlayer(const QString &userName, int roomId, int gameId, int playerId); - QList getPersistentPlayerReferences(const QString &userName) const; + mutable QReadWriteLock clientsLock, roomsLock; // locking order: roomsLock before clientsLock + Server(bool _threaded, QObject *parent = 0); + ~Server(); + void setThreaded(bool _threaded) { threaded = _threaded; } + AuthenticationResult loginUser(Server_ProtocolHandler *session, QString &name, const QString &password, QString &reason, int &secondsLeft); + const QMap &getRooms() { return rooms; } + + Server_AbstractUserInterface *findUser(const QString &userName) const; + const QMap &getUsers() const { return users; } + const QMap &getUsersBySessionId() const { return usersBySessionId; } + void addClient(Server_ProtocolHandler *player); + void removeClient(Server_ProtocolHandler *player); + virtual QString getLoginMessage() const { return QString(); } + + virtual bool getGameShouldPing() const { return false; } + virtual int getMaxGameInactivityTime() const { return 9999999; } + virtual int getMaxPlayerInactivityTime() const { return 9999999; } + virtual int getMessageCountingInterval() const { return 0; } + virtual int getMaxMessageCountPerInterval() const { return 0; } + virtual int getMaxMessageSizePerInterval() const { return 0; } + virtual int getMaxGamesPerUser() const { return 0; } + virtual bool getThreaded() const { return false; } + + Server_DatabaseInterface *getDatabaseInterface() const; + int getNextLocalGameId() { QMutexLocker locker(&nextLocalGameIdMutex); return ++nextLocalGameId; } + + void sendIsl_Response(const Response &item, int serverId = -1, qint64 sessionId = -1); + void sendIsl_SessionEvent(const SessionEvent &item, int serverId = -1, qint64 sessionId = -1); + void sendIsl_GameEventContainer(const GameEventContainer &item, int serverId = -1, qint64 sessionId = -1); + void sendIsl_RoomEvent(const RoomEvent &item, int serverId = -1, qint64 sessionId = -1); + void sendIsl_GameCommand(const CommandContainer &item, int serverId, qint64 sessionId, int roomId, int playerId); + void sendIsl_RoomCommand(const CommandContainer &item, int serverId, qint64 sessionId, int roomId); + + void addExternalUser(const ServerInfo_User &userInfo); + void removeExternalUser(const QString &userName); + const QMap &getExternalUsers() const { return externalUsers; } + + void addPersistentPlayer(const QString &userName, int roomId, int gameId, int playerId); + void removePersistentPlayer(const QString &userName, int roomId, int gameId, int playerId); + QList getPersistentPlayerReferences(const QString &userName) const; private: - bool threaded; - QMultiMap persistentPlayers; - mutable QReadWriteLock persistentPlayersLock; - int nextLocalGameId; - QMutex nextLocalGameIdMutex; -protected slots: - void externalUserJoined(const ServerInfo_User &userInfo); - void externalUserLeft(const QString &userName); - void externalRoomUserJoined(int roomId, const ServerInfo_User &userInfo); - void externalRoomUserLeft(int roomId, const QString &userName); - void externalRoomSay(int roomId, const QString &userName, const QString &message); - void externalRoomGameListChanged(int roomId, const ServerInfo_Game &gameInfo); - void externalJoinGameCommandReceived(const Command_JoinGame &cmd, int cmdId, int roomId, int serverId, qint64 sessionId); - void externalGameCommandContainerReceived(const CommandContainer &cont, int playerId, int serverId, qint64 sessionId); - void externalGameEventContainerReceived(const GameEventContainer &cont, qint64 sessionId); - void externalResponseReceived(const Response &resp, qint64 sessionId); - - virtual void doSendIslMessage(const IslMessage &msg, int serverId) { } + bool threaded; + QMultiMap persistentPlayers; + mutable QReadWriteLock persistentPlayersLock; + int nextLocalGameId; + QMutex nextLocalGameIdMutex; +protected slots: + void externalUserJoined(const ServerInfo_User &userInfo); + void externalUserLeft(const QString &userName); + void externalRoomUserJoined(int roomId, const ServerInfo_User &userInfo); + void externalRoomUserLeft(int roomId, const QString &userName); + void externalRoomSay(int roomId, const QString &userName, const QString &message); + void externalRoomGameListChanged(int roomId, const ServerInfo_Game &gameInfo); + void externalJoinGameCommandReceived(const Command_JoinGame &cmd, int cmdId, int roomId, int serverId, qint64 sessionId); + void externalGameCommandContainerReceived(const CommandContainer &cont, int playerId, int serverId, qint64 sessionId); + void externalGameEventContainerReceived(const GameEventContainer &cont, qint64 sessionId); + void externalResponseReceived(const Response &resp, qint64 sessionId); + + virtual void doSendIslMessage(const IslMessage &msg, int serverId) { } protected: - void prepareDestroy(); - void setDatabaseInterface(Server_DatabaseInterface *_databaseInterface); - QList clients; - QMap usersBySessionId; - QMap users; - QMap externalUsersBySessionId; - QMap externalUsers; - QMap rooms; - QMap databaseInterfaces; - - int getUsersCount() const; - int getGamesCount() const; - void addRoom(Server_Room *newRoom); + void prepareDestroy(); + void setDatabaseInterface(Server_DatabaseInterface *_databaseInterface); + QList clients; + QMap usersBySessionId; + QMap users; + QMap externalUsersBySessionId; + QMap externalUsers; + QMap rooms; + QMap databaseInterfaces; + + int getUsersCount() const; + int getGamesCount() const; + void addRoom(Server_Room *newRoom); }; #endif diff --git a/common/server_abstractuserinterface.cpp b/common/server_abstractuserinterface.cpp index ea4b0f6b..d00c5034 100644 --- a/common/server_abstractuserinterface.cpp +++ b/common/server_abstractuserinterface.cpp @@ -15,82 +15,82 @@ void Server_AbstractUserInterface::sendProtocolItemByType(ServerMessage::MessageType type, const ::google::protobuf::Message &item) { - switch (type) { - case ServerMessage::RESPONSE: sendProtocolItem(static_cast(item)); break; - case ServerMessage::SESSION_EVENT: sendProtocolItem(static_cast(item)); break; - case ServerMessage::GAME_EVENT_CONTAINER: sendProtocolItem(static_cast(item)); break; - case ServerMessage::ROOM_EVENT: sendProtocolItem(static_cast(item)); break; - } + switch (type) { + case ServerMessage::RESPONSE: sendProtocolItem(static_cast(item)); break; + case ServerMessage::SESSION_EVENT: sendProtocolItem(static_cast(item)); break; + case ServerMessage::GAME_EVENT_CONTAINER: sendProtocolItem(static_cast(item)); break; + case ServerMessage::ROOM_EVENT: sendProtocolItem(static_cast(item)); break; + } } SessionEvent *Server_AbstractUserInterface::prepareSessionEvent(const ::google::protobuf::Message &sessionEvent) { - SessionEvent *event = new SessionEvent; - event->GetReflection()->MutableMessage(event, sessionEvent.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(sessionEvent); - return event; + SessionEvent *event = new SessionEvent; + event->GetReflection()->MutableMessage(event, sessionEvent.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(sessionEvent); + return event; } void Server_AbstractUserInterface::sendResponseContainer(const ResponseContainer &responseContainer, Response::ResponseCode responseCode) { - const QList > &preResponseQueue = responseContainer.getPreResponseQueue(); - for (int i = 0; i < preResponseQueue.size(); ++i) - sendProtocolItemByType(preResponseQueue[i].first, *preResponseQueue[i].second); - - if (responseCode != Response::RespNothing) { - Response response; - response.set_cmd_id(responseContainer.getCmdId()); - response.set_response_code(responseCode); - ::google::protobuf::Message *responseExtension = responseContainer.getResponseExtension(); - if (responseExtension) - response.GetReflection()->MutableMessage(&response, responseExtension->GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(*responseExtension); - sendProtocolItem(response); - } - - const QList > &postResponseQueue = responseContainer.getPostResponseQueue(); - for (int i = 0; i < postResponseQueue.size(); ++i) - sendProtocolItemByType(postResponseQueue[i].first, *postResponseQueue[i].second); + const QList > &preResponseQueue = responseContainer.getPreResponseQueue(); + for (int i = 0; i < preResponseQueue.size(); ++i) + sendProtocolItemByType(preResponseQueue[i].first, *preResponseQueue[i].second); + + if (responseCode != Response::RespNothing) { + Response response; + response.set_cmd_id(responseContainer.getCmdId()); + response.set_response_code(responseCode); + ::google::protobuf::Message *responseExtension = responseContainer.getResponseExtension(); + if (responseExtension) + response.GetReflection()->MutableMessage(&response, responseExtension->GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(*responseExtension); + sendProtocolItem(response); + } + + const QList > &postResponseQueue = responseContainer.getPostResponseQueue(); + for (int i = 0; i < postResponseQueue.size(); ++i) + sendProtocolItemByType(postResponseQueue[i].first, *postResponseQueue[i].second); } void Server_AbstractUserInterface::playerRemovedFromGame(Server_Game *game) { - qDebug() << "Server_AbstractUserInterface::playerRemovedFromGame(): gameId =" << game->getGameId(); - - QMutexLocker locker(&gameListMutex); - games.remove(game->getGameId()); + qDebug() << "Server_AbstractUserInterface::playerRemovedFromGame(): gameId =" << game->getGameId(); + + QMutexLocker locker(&gameListMutex); + games.remove(game->getGameId()); } void Server_AbstractUserInterface::playerAddedToGame(int gameId, int roomId, int playerId) { - qDebug() << "Server_AbstractUserInterface::playerAddedToGame(): gameId =" << gameId; - - QMutexLocker locker(&gameListMutex); - games.insert(gameId, QPair(roomId, playerId)); + qDebug() << "Server_AbstractUserInterface::playerAddedToGame(): gameId =" << gameId; + + QMutexLocker locker(&gameListMutex); + games.insert(gameId, QPair(roomId, playerId)); } void Server_AbstractUserInterface::joinPersistentGames(ResponseContainer &rc) { - QList gamesToJoin = server->getPersistentPlayerReferences(QString::fromStdString(userInfo->name())); - - server->roomsLock.lockForRead(); - for (int i = 0; i < gamesToJoin.size(); ++i) { - const PlayerReference &pr = gamesToJoin.at(i); - - Server_Room *room = server->getRooms().value(pr.getRoomId()); - if (!room) - continue; - QReadLocker roomGamesLocker(&room->gamesLock); - - Server_Game *game = room->getGames().value(pr.getGameId()); - if (!game) - continue; - QMutexLocker gameLocker(&game->gameMutex); - - Server_Player *player = game->getPlayers().value(pr.getPlayerId()); - - player->setUserInterface(this); - playerAddedToGame(game->getGameId(), room->getId(), player->getPlayerId()); - - game->createGameJoinedEvent(player, rc, true); - } - server->roomsLock.unlock(); + QList gamesToJoin = server->getPersistentPlayerReferences(QString::fromStdString(userInfo->name())); + + server->roomsLock.lockForRead(); + for (int i = 0; i < gamesToJoin.size(); ++i) { + const PlayerReference &pr = gamesToJoin.at(i); + + Server_Room *room = server->getRooms().value(pr.getRoomId()); + if (!room) + continue; + QReadLocker roomGamesLocker(&room->gamesLock); + + Server_Game *game = room->getGames().value(pr.getGameId()); + if (!game) + continue; + QMutexLocker gameLocker(&game->gameMutex); + + Server_Player *player = game->getPlayers().value(pr.getPlayerId()); + + player->setUserInterface(this); + playerAddedToGame(game->getGameId(), room->getId(), player->getPlayerId()); + + game->createGameJoinedEvent(player, rc, true); + } + server->roomsLock.unlock(); } diff --git a/common/server_abstractuserinterface.h b/common/server_abstractuserinterface.h index 485162e0..1253c0f4 100644 --- a/common/server_abstractuserinterface.h +++ b/common/server_abstractuserinterface.h @@ -18,31 +18,31 @@ class Server_Game; class Server_AbstractUserInterface : public ServerInfo_User_Container { private: - mutable QMutex gameListMutex; - QMap > games; // gameId -> (roomId, playerId) + mutable QMutex gameListMutex; + QMap > games; // gameId -> (roomId, playerId) protected: - Server *server; + Server *server; public: - Server_AbstractUserInterface(Server *_server) : server(_server) { } - Server_AbstractUserInterface(Server *_server, const ServerInfo_User_Container &other) : ServerInfo_User_Container(other), server(_server) { } - virtual ~Server_AbstractUserInterface() { } - - virtual int getLastCommandTime() const = 0; - - void playerRemovedFromGame(Server_Game *game); - void playerAddedToGame(int gameId, int roomId, int playerId); - void joinPersistentGames(ResponseContainer &rc); - - QMap > getGames() const { QMutexLocker locker(&gameListMutex); return games; } - - virtual void sendProtocolItem(const Response &item) = 0; - virtual void sendProtocolItem(const SessionEvent &item) = 0; - virtual void sendProtocolItem(const GameEventContainer &item) = 0; - virtual void sendProtocolItem(const RoomEvent &item) = 0; - void sendProtocolItemByType(ServerMessage::MessageType type, const ::google::protobuf::Message &item); - - static SessionEvent *prepareSessionEvent(const ::google::protobuf::Message &sessionEvent); - void sendResponseContainer(const ResponseContainer &responseContainer, Response::ResponseCode responseCode); + Server_AbstractUserInterface(Server *_server) : server(_server) { } + Server_AbstractUserInterface(Server *_server, const ServerInfo_User_Container &other) : ServerInfo_User_Container(other), server(_server) { } + virtual ~Server_AbstractUserInterface() { } + + virtual int getLastCommandTime() const = 0; + + void playerRemovedFromGame(Server_Game *game); + void playerAddedToGame(int gameId, int roomId, int playerId); + void joinPersistentGames(ResponseContainer &rc); + + QMap > getGames() const { QMutexLocker locker(&gameListMutex); return games; } + + virtual void sendProtocolItem(const Response &item) = 0; + virtual void sendProtocolItem(const SessionEvent &item) = 0; + virtual void sendProtocolItem(const GameEventContainer &item) = 0; + virtual void sendProtocolItem(const RoomEvent &item) = 0; + void sendProtocolItemByType(ServerMessage::MessageType type, const ::google::protobuf::Message &item); + + static SessionEvent *prepareSessionEvent(const ::google::protobuf::Message &sessionEvent); + void sendResponseContainer(const ResponseContainer &responseContainer, Response::ResponseCode responseCode); }; #endif diff --git a/common/server_arrow.cpp b/common/server_arrow.cpp index 9cbb2c38..a668cc25 100644 --- a/common/server_arrow.cpp +++ b/common/server_arrow.cpp @@ -14,17 +14,17 @@ Server_Arrow::Server_Arrow(int _id, Server_Card *_startCard, Server_ArrowTarget void Server_Arrow::getInfo(ServerInfo_Arrow *info) { - info->set_id(id); - info->set_start_player_id(startCard->getZone()->getPlayer()->getPlayerId()); - info->set_start_zone(startCard->getZone()->getName().toStdString()); - info->set_start_card_id(startCard->getId()); - info->mutable_arrow_color()->CopyFrom(arrowColor); + info->set_id(id); + info->set_start_player_id(startCard->getZone()->getPlayer()->getPlayerId()); + info->set_start_zone(startCard->getZone()->getName().toStdString()); + info->set_start_card_id(startCard->getId()); + info->mutable_arrow_color()->CopyFrom(arrowColor); - Server_Card *targetCard = qobject_cast(targetItem); - if (targetCard) { - info->set_target_player_id(targetCard->getZone()->getPlayer()->getPlayerId()); - info->set_target_zone(targetCard->getZone()->getName().toStdString()); - info->set_target_card_id(targetCard->getId()); - } else - info->set_target_player_id(static_cast(targetItem)->getPlayerId()); + Server_Card *targetCard = qobject_cast(targetItem); + if (targetCard) { + info->set_target_player_id(targetCard->getZone()->getPlayer()->getPlayerId()); + info->set_target_zone(targetCard->getZone()->getName().toStdString()); + info->set_target_card_id(targetCard->getId()); + } else + info->set_target_player_id(static_cast(targetItem)->getPlayerId()); } diff --git a/common/server_arrow.h b/common/server_arrow.h index 1d171ef3..01c472ef 100644 --- a/common/server_arrow.h +++ b/common/server_arrow.h @@ -9,18 +9,18 @@ class ServerInfo_Arrow; class Server_Arrow { private: - int id; - Server_Card *startCard; - Server_ArrowTarget *targetItem; - color arrowColor; + int id; + Server_Card *startCard; + Server_ArrowTarget *targetItem; + color arrowColor; public: - Server_Arrow(int _id, Server_Card *_startCard, Server_ArrowTarget *_targetItem, const color &_arrowColor); - int getId() const { return id; } - Server_Card *getStartCard() const { return startCard; } - Server_ArrowTarget *getTargetItem() const { return targetItem; } - const color &getColor() const { return arrowColor; } - - void getInfo(ServerInfo_Arrow *info); + Server_Arrow(int _id, Server_Card *_startCard, Server_ArrowTarget *_targetItem, const color &_arrowColor); + int getId() const { return id; } + Server_Card *getStartCard() const { return startCard; } + Server_ArrowTarget *getTargetItem() const { return targetItem; } + const color &getColor() const { return arrowColor; } + + void getInfo(ServerInfo_Arrow *info); }; #endif diff --git a/common/server_arrowtarget.cpp b/common/server_arrowtarget.cpp index aa7789dd..1b3385d5 100644 --- a/common/server_arrowtarget.cpp +++ b/common/server_arrowtarget.cpp @@ -1,2 +1,2 @@ -#include "server_arrowtarget.h" \ No newline at end of file +#include "server_arrowtarget.h" diff --git a/common/server_arrowtarget.h b/common/server_arrowtarget.h index f5783d5b..d94fc4b7 100644 --- a/common/server_arrowtarget.h +++ b/common/server_arrowtarget.h @@ -4,7 +4,7 @@ #include class Server_ArrowTarget : public QObject { - Q_OBJECT + Q_OBJECT }; #endif diff --git a/common/server_card.cpp b/common/server_card.cpp index 10c465b8..39e4aadc 100644 --- a/common/server_card.cpp +++ b/common/server_card.cpp @@ -23,138 +23,138 @@ #include "pb/serverinfo_card.pb.h" Server_Card::Server_Card(QString _name, int _id, int _coord_x, int _coord_y, Server_CardZone *_zone) - : zone(_zone), id(_id), coord_x(_coord_x), coord_y(_coord_y), name(_name), tapped(false), attacking(false), facedown(false), color(QString()), power(-1), toughness(-1), annotation(QString()), destroyOnZoneChange(false), doesntUntap(false), parentCard(0) + : zone(_zone), id(_id), coord_x(_coord_x), coord_y(_coord_y), name(_name), tapped(false), attacking(false), facedown(false), color(QString()), power(-1), toughness(-1), annotation(QString()), destroyOnZoneChange(false), doesntUntap(false), parentCard(0) { } Server_Card::~Server_Card() { - // setParentCard(0) leads to the item being removed from our list, so we can't iterate properly - while (!attachedCards.isEmpty()) - attachedCards.first()->setParentCard(0); - - if (parentCard) - parentCard->removeAttachedCard(this); + // setParentCard(0) leads to the item being removed from our list, so we can't iterate properly + while (!attachedCards.isEmpty()) + attachedCards.first()->setParentCard(0); + + if (parentCard) + parentCard->removeAttachedCard(this); } void Server_Card::resetState() { - counters.clear(); - setTapped(false); - setAttacking(false); - power = -1; - toughness = -1; - setAnnotation(QString()); - setDoesntUntap(false); + counters.clear(); + setTapped(false); + setAttacking(false); + power = -1; + toughness = -1; + setAnnotation(QString()); + setDoesntUntap(false); } QString Server_Card::setAttribute(CardAttribute attribute, const QString &avalue, bool allCards) { - switch (attribute) { - case AttrTapped: { - bool value = avalue == "1"; - if (!(!value && allCards && doesntUntap)) - setTapped(value); - break; - } - case AttrAttacking: setAttacking(avalue == "1"); break; - case AttrFaceDown: setFaceDown(avalue == "1"); break; - case AttrColor: setColor(avalue); break; - case AttrPT: setPT(avalue); return getPT(); - case AttrAnnotation: setAnnotation(avalue); break; - case AttrDoesntUntap: setDoesntUntap(avalue == "1"); break; - } - return avalue; + switch (attribute) { + case AttrTapped: { + bool value = avalue == "1"; + if (!(!value && allCards && doesntUntap)) + setTapped(value); + break; + } + case AttrAttacking: setAttacking(avalue == "1"); break; + case AttrFaceDown: setFaceDown(avalue == "1"); break; + case AttrColor: setColor(avalue); break; + case AttrPT: setPT(avalue); return getPT(); + case AttrAnnotation: setAnnotation(avalue); break; + case AttrDoesntUntap: setDoesntUntap(avalue == "1"); break; + } + return avalue; } void Server_Card::setCounter(int id, int value) { - if (value) - counters.insert(id, value); - else - counters.remove(id); + if (value) + counters.insert(id, value); + else + counters.remove(id); } void Server_Card::setPT(const QString &_pt) { - if (_pt.isEmpty()) { - power = 0; - toughness = -1; - } else { - int sep = _pt.indexOf('/'); - QString p1 = _pt.left(sep); - QString p2 = _pt.mid(sep + 1); - if (p1.isEmpty() || p2.isEmpty()) - return; - if ((p1[0] == '+') || (p2[0] == '+')) { - if (power < 0) - power = 0; - if (toughness < 0) - toughness = 0; - } - if (p1[0] == '+') - power += p1.mid(1).toInt(); - else - power = p1.toInt(); - if (p2[0] == '+') - toughness += p2.mid(1).toInt(); - else - toughness = p2.toInt(); - } + if (_pt.isEmpty()) { + power = 0; + toughness = -1; + } else { + int sep = _pt.indexOf('/'); + QString p1 = _pt.left(sep); + QString p2 = _pt.mid(sep + 1); + if (p1.isEmpty() || p2.isEmpty()) + return; + if ((p1[0] == '+') || (p2[0] == '+')) { + if (power < 0) + power = 0; + if (toughness < 0) + toughness = 0; + } + if (p1[0] == '+') + power += p1.mid(1).toInt(); + else + power = p1.toInt(); + if (p2[0] == '+') + toughness += p2.mid(1).toInt(); + else + toughness = p2.toInt(); + } } QString Server_Card::getPT() const { - if (toughness < 0) - return QString(""); - return QString::number(power) + "/" + QString::number(toughness); + if (toughness < 0) + return QString(""); + return QString::number(power) + "/" + QString::number(toughness); } void Server_Card::setParentCard(Server_Card *_parentCard) { - if (parentCard) - parentCard->removeAttachedCard(this); - parentCard = _parentCard; - if (parentCard) - parentCard->addAttachedCard(this); + if (parentCard) + parentCard->removeAttachedCard(this); + parentCard = _parentCard; + if (parentCard) + parentCard->addAttachedCard(this); } void Server_Card::getInfo(ServerInfo_Card *info) { - QString displayedName = facedown ? QString() : name; - - info->set_id(id); - info->set_name(displayedName.toStdString()); - info->set_x(coord_x); - info->set_y(coord_y); - if (facedown) - info->set_face_down(true); - info->set_tapped(tapped); - if (attacking) - info->set_attacking(true); - if (!color.isEmpty()) - info->set_color(color.toStdString()); - const QString ptStr = getPT(); - if (!ptStr.isEmpty()) - info->set_pt(ptStr.toStdString()); - if (!annotation.isEmpty()) - info->set_annotation(annotation.toStdString()); - if (destroyOnZoneChange) - info->set_destroy_on_zone_change(true); - if (doesntUntap) - info->set_doesnt_untap(true); - - QMapIterator cardCounterIterator(counters); - while (cardCounterIterator.hasNext()) { - cardCounterIterator.next(); - ServerInfo_CardCounter *counterInfo = info->add_counter_list(); - counterInfo->set_id(cardCounterIterator.key()); - counterInfo->set_value(cardCounterIterator.value()); - } + QString displayedName = facedown ? QString() : name; + + info->set_id(id); + info->set_name(displayedName.toStdString()); + info->set_x(coord_x); + info->set_y(coord_y); + if (facedown) + info->set_face_down(true); + info->set_tapped(tapped); + if (attacking) + info->set_attacking(true); + if (!color.isEmpty()) + info->set_color(color.toStdString()); + const QString ptStr = getPT(); + if (!ptStr.isEmpty()) + info->set_pt(ptStr.toStdString()); + if (!annotation.isEmpty()) + info->set_annotation(annotation.toStdString()); + if (destroyOnZoneChange) + info->set_destroy_on_zone_change(true); + if (doesntUntap) + info->set_doesnt_untap(true); + + QMapIterator cardCounterIterator(counters); + while (cardCounterIterator.hasNext()) { + cardCounterIterator.next(); + ServerInfo_CardCounter *counterInfo = info->add_counter_list(); + counterInfo->set_id(cardCounterIterator.key()); + counterInfo->set_value(cardCounterIterator.value()); + } - if (parentCard) { - info->set_attach_player_id(parentCard->getZone()->getPlayer()->getPlayerId()); - info->set_attach_zone(parentCard->getZone()->getName().toStdString()); - info->set_attach_card_id(parentCard->getId()); - } + if (parentCard) { + info->set_attach_player_id(parentCard->getZone()->getPlayer()->getPlayerId()); + info->set_attach_zone(parentCard->getZone()->getName().toStdString()); + info->set_attach_card_id(parentCard->getId()); + } } diff --git a/common/server_card.h b/common/server_card.h index 2af8aa6d..e3c76f05 100644 --- a/common/server_card.h +++ b/common/server_card.h @@ -29,68 +29,68 @@ class Server_CardZone; class ServerInfo_Card; class Server_Card : public Server_ArrowTarget { - Q_OBJECT + Q_OBJECT private: - Server_CardZone *zone; - int id; - int coord_x, coord_y; - QString name; - QMap counters; - bool tapped; - bool attacking; - bool facedown; - QString color; - int power, toughness; - QString annotation; - bool destroyOnZoneChange; - bool doesntUntap; - - Server_Card *parentCard; - QList attachedCards; + Server_CardZone *zone; + int id; + int coord_x, coord_y; + QString name; + QMap counters; + bool tapped; + bool attacking; + bool facedown; + QString color; + int power, toughness; + QString annotation; + bool destroyOnZoneChange; + bool doesntUntap; + + Server_Card *parentCard; + QList attachedCards; public: - Server_Card(QString _name, int _id, int _coord_x, int _coord_y, Server_CardZone *_zone = 0); - ~Server_Card(); - - Server_CardZone *getZone() const { return zone; } - void setZone(Server_CardZone *_zone) { zone = _zone; } - - int getId() const { return id; } - int getX() const { return coord_x; } - int getY() const { return coord_y; } - QString getName() const { return name; } - const QMap &getCounters() const { return counters; } - int getCounter(int id) const { return counters.value(id, 0); } - bool getTapped() const { return tapped; } - bool getAttacking() const { return attacking; } - bool getFaceDown() const { return facedown; } - QString getColor() const { return color; } - QString getPT() const; - QString getAnnotation() const { return annotation; } - bool getDoesntUntap() const { return doesntUntap; } - bool getDestroyOnZoneChange() const { return destroyOnZoneChange; } - Server_Card *getParentCard() const { return parentCard; } - const QList &getAttachedCards() const { return attachedCards; } + Server_Card(QString _name, int _id, int _coord_x, int _coord_y, Server_CardZone *_zone = 0); + ~Server_Card(); + + Server_CardZone *getZone() const { return zone; } + void setZone(Server_CardZone *_zone) { zone = _zone; } + + int getId() const { return id; } + int getX() const { return coord_x; } + int getY() const { return coord_y; } + QString getName() const { return name; } + const QMap &getCounters() const { return counters; } + int getCounter(int id) const { return counters.value(id, 0); } + bool getTapped() const { return tapped; } + bool getAttacking() const { return attacking; } + bool getFaceDown() const { return facedown; } + QString getColor() const { return color; } + QString getPT() const; + QString getAnnotation() const { return annotation; } + bool getDoesntUntap() const { return doesntUntap; } + bool getDestroyOnZoneChange() const { return destroyOnZoneChange; } + Server_Card *getParentCard() const { return parentCard; } + const QList &getAttachedCards() const { return attachedCards; } - void setId(int _id) { id = _id; } - void setCoords(int x, int y) { coord_x = x; coord_y = y; } - void setName(const QString &_name) { name = _name; } - void setCounter(int id, int value); - void setTapped(bool _tapped) { tapped = _tapped; } - void setAttacking(bool _attacking) { attacking = _attacking; } - void setFaceDown(bool _facedown) { facedown = _facedown; } - void setColor(const QString &_color) { color = _color; } - void setPT(const QString &_pt); - void setAnnotation(const QString &_annotation) { annotation = _annotation; } - void setDestroyOnZoneChange(bool _destroy) { destroyOnZoneChange = _destroy; } - void setDoesntUntap(bool _doesntUntap) { doesntUntap = _doesntUntap; } - void setParentCard(Server_Card *_parentCard); - void addAttachedCard(Server_Card *card) { attachedCards.append(card); } - void removeAttachedCard(Server_Card *card) { attachedCards.removeAt(attachedCards.indexOf(card)); } - - void resetState(); - QString setAttribute(CardAttribute attribute, const QString &avalue, bool allCards); - - void getInfo(ServerInfo_Card *info); + void setId(int _id) { id = _id; } + void setCoords(int x, int y) { coord_x = x; coord_y = y; } + void setName(const QString &_name) { name = _name; } + void setCounter(int id, int value); + void setTapped(bool _tapped) { tapped = _tapped; } + void setAttacking(bool _attacking) { attacking = _attacking; } + void setFaceDown(bool _facedown) { facedown = _facedown; } + void setColor(const QString &_color) { color = _color; } + void setPT(const QString &_pt); + void setAnnotation(const QString &_annotation) { annotation = _annotation; } + void setDestroyOnZoneChange(bool _destroy) { destroyOnZoneChange = _destroy; } + void setDoesntUntap(bool _doesntUntap) { doesntUntap = _doesntUntap; } + void setParentCard(Server_Card *_parentCard); + void addAttachedCard(Server_Card *card) { attachedCards.append(card); } + void removeAttachedCard(Server_Card *card) { attachedCards.removeAt(attachedCards.indexOf(card)); } + + void resetState(); + QString setAttribute(CardAttribute attribute, const QString &avalue, bool allCards); + + void getInfo(ServerInfo_Card *info); }; #endif diff --git a/common/server_cardzone.h b/common/server_cardzone.h index 1eeb9008..a00b367a 100644 --- a/common/server_cardzone.h +++ b/common/server_cardzone.h @@ -33,48 +33,48 @@ class GameEventStorage; class Server_CardZone { private: - Server_Player *player; - QString name; - bool has_coords; - ServerInfo_Zone::ZoneType type; - int cardsBeingLookedAt; - QSet playersWithWritePermission; - bool alwaysRevealTopCard; - QList cards; - QMap > coordinateMap; // y -> (x -> card) - QMap > freePilesMap; // y -> (cardName -> x) - QMap freeSpaceMap; // y -> x - void removeCardFromCoordMap(Server_Card *card, int oldX, int oldY); - void insertCardIntoCoordMap(Server_Card *card, int x, int y); + Server_Player *player; + QString name; + bool has_coords; + ServerInfo_Zone::ZoneType type; + int cardsBeingLookedAt; + QSet playersWithWritePermission; + bool alwaysRevealTopCard; + QList cards; + QMap > coordinateMap; // y -> (x -> card) + QMap > freePilesMap; // y -> (cardName -> x) + QMap freeSpaceMap; // y -> x + void removeCardFromCoordMap(Server_Card *card, int oldX, int oldY); + void insertCardIntoCoordMap(Server_Card *card, int x, int y); public: - Server_CardZone(Server_Player *_player, const QString &_name, bool _has_coords, ServerInfo_Zone::ZoneType _type); - ~Server_CardZone(); - - const QList &getCards() const { return cards; } - int removeCard(Server_Card *card); - Server_Card *getCard(int id, int *position = NULL, bool remove = false); + Server_CardZone(Server_Player *_player, const QString &_name, bool _has_coords, ServerInfo_Zone::ZoneType _type); + ~Server_CardZone(); + + const QList &getCards() const { return cards; } + int removeCard(Server_Card *card); + Server_Card *getCard(int id, int *position = NULL, bool remove = false); - int getCardsBeingLookedAt() const { return cardsBeingLookedAt; } - void setCardsBeingLookedAt(int _cardsBeingLookedAt) { cardsBeingLookedAt = _cardsBeingLookedAt; } - bool hasCoords() const { return has_coords; } - ServerInfo_Zone::ZoneType getType() const { return type; } - QString getName() const { return name; } - Server_Player *getPlayer() const { return player; } - void getInfo(ServerInfo_Zone *info, Server_Player *playerWhosAsking, bool omniscient); - - int getFreeGridColumn(int x, int y, const QString &cardName) const; - bool isColumnEmpty(int x, int y) const; - bool isColumnStacked(int x, int y) const; - void fixFreeSpaces(GameEventStorage &ges); - void moveCardInRow(GameEventStorage &ges, Server_Card *card, int x, int y); - void insertCard(Server_Card *card, int x, int y); - void updateCardCoordinates(Server_Card *card, int oldX, int oldY); - void shuffle(); - void clear(); - void addWritePermission(int playerId); - const QSet &getPlayersWithWritePermission() const { return playersWithWritePermission; } - bool getAlwaysRevealTopCard() const { return alwaysRevealTopCard; } - void setAlwaysRevealTopCard(bool _alwaysRevealTopCard) { alwaysRevealTopCard = _alwaysRevealTopCard; } + int getCardsBeingLookedAt() const { return cardsBeingLookedAt; } + void setCardsBeingLookedAt(int _cardsBeingLookedAt) { cardsBeingLookedAt = _cardsBeingLookedAt; } + bool hasCoords() const { return has_coords; } + ServerInfo_Zone::ZoneType getType() const { return type; } + QString getName() const { return name; } + Server_Player *getPlayer() const { return player; } + void getInfo(ServerInfo_Zone *info, Server_Player *playerWhosAsking, bool omniscient); + + int getFreeGridColumn(int x, int y, const QString &cardName) const; + bool isColumnEmpty(int x, int y) const; + bool isColumnStacked(int x, int y) const; + void fixFreeSpaces(GameEventStorage &ges); + void moveCardInRow(GameEventStorage &ges, Server_Card *card, int x, int y); + void insertCard(Server_Card *card, int x, int y); + void updateCardCoordinates(Server_Card *card, int oldX, int oldY); + void shuffle(); + void clear(); + void addWritePermission(int playerId); + const QSet &getPlayersWithWritePermission() const { return playersWithWritePermission; } + bool getAlwaysRevealTopCard() const { return alwaysRevealTopCard; } + void setAlwaysRevealTopCard(bool _alwaysRevealTopCard) { alwaysRevealTopCard = _alwaysRevealTopCard; } }; #endif diff --git a/common/server_counter.cpp b/common/server_counter.cpp index 2e0ffde8..df8dcd03 100644 --- a/common/server_counter.cpp +++ b/common/server_counter.cpp @@ -12,9 +12,9 @@ Server_Counter::Server_Counter(int _id, const QString &_name, const color &_coun void Server_Counter::getInfo(ServerInfo_Counter *info) { - info->set_id(id); - info->set_name(name.toStdString()); - info->mutable_counter_color()->CopyFrom(counterColor); - info->set_radius(radius); - info->set_count(count); + info->set_id(id); + info->set_name(name.toStdString()); + info->mutable_counter_color()->CopyFrom(counterColor); + info->set_radius(radius); + info->set_count(count); } diff --git a/common/server_counter.h b/common/server_counter.h index 42483b9d..60b70e69 100644 --- a/common/server_counter.h +++ b/common/server_counter.h @@ -27,22 +27,22 @@ class ServerInfo_Counter; class Server_Counter { protected: - int id; - QString name; - color counterColor; - int radius; - int count; + int id; + QString name; + color counterColor; + int radius; + int count; public: - Server_Counter(int _id, const QString &_name, const color &_counterColor, int _radius, int _count = 0); - ~Server_Counter() { } - int getId() const { return id; } - QString getName() const { return name; } - const color &getColor() const { return counterColor; } - int getRadius() const { return radius; } - int getCount() const { return count; } - void setCount(int _count) { count = _count; } - - void getInfo(ServerInfo_Counter *info); + Server_Counter(int _id, const QString &_name, const color &_counterColor, int _radius, int _count = 0); + ~Server_Counter() { } + int getId() const { return id; } + QString getName() const { return name; } + const color &getColor() const { return counterColor; } + int getRadius() const { return radius; } + int getCount() const { return count; } + void setCount(int _count) { count = _count; } + + void getInfo(ServerInfo_Counter *info); }; #endif diff --git a/common/server_database_interface.h b/common/server_database_interface.h index 10ce082a..df75cd63 100644 --- a/common/server_database_interface.h +++ b/common/server_database_interface.h @@ -6,32 +6,32 @@ #include "server.h" class Server_DatabaseInterface : public QObject { - Q_OBJECT + Q_OBJECT public: - Server_DatabaseInterface(QObject *parent = 0) - : QObject(parent) { } - - virtual AuthenticationResult checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password, QString &reasonStr, int &secondsLeft) = 0; - virtual bool userExists(const QString &user) { return false; } - virtual QMap getBuddyList(const QString &name) { return QMap(); } - virtual QMap getIgnoreList(const QString &name) { return QMap(); } - virtual bool isInBuddyList(const QString &whoseList, const QString &who) { return false; } - virtual bool isInIgnoreList(const QString &whoseList, const QString &who) { return false; } - virtual ServerInfo_User getUserData(const QString &name, bool withId = false) = 0; - virtual void storeGameInformation(const QString &roomName, const QStringList &roomGameTypes, const ServerInfo_Game &gameInfo, const QSet &allPlayersEver, const QSet &allSpectatorsEver, const QList &replayList) { } - virtual DeckList *getDeckFromDatabase(int deckId, int userId) { return 0; } - - virtual qint64 startSession(const QString &userName, const QString &address) { return 0; } + Server_DatabaseInterface(QObject *parent = 0) + : QObject(parent) { } + + virtual AuthenticationResult checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password, QString &reasonStr, int &secondsLeft) = 0; + virtual bool userExists(const QString &user) { return false; } + virtual QMap getBuddyList(const QString &name) { return QMap(); } + virtual QMap getIgnoreList(const QString &name) { return QMap(); } + virtual bool isInBuddyList(const QString &whoseList, const QString &who) { return false; } + virtual bool isInIgnoreList(const QString &whoseList, const QString &who) { return false; } + virtual ServerInfo_User getUserData(const QString &name, bool withId = false) = 0; + virtual void storeGameInformation(const QString &roomName, const QStringList &roomGameTypes, const ServerInfo_Game &gameInfo, const QSet &allPlayersEver, const QSet &allSpectatorsEver, const QList &replayList) { } + virtual DeckList *getDeckFromDatabase(int deckId, int userId) { return 0; } + + virtual qint64 startSession(const QString &userName, const QString &address) { return 0; } public slots: - virtual void endSession(qint64 sessionId) { } + virtual void endSession(qint64 sessionId) { } public: - virtual int getNextGameId() = 0; - virtual int getNextReplayId() = 0; - - virtual void clearSessionTables() { } - virtual void lockSessionTables() { } - virtual void unlockSessionTables() { } - virtual bool userSessionExists(const QString &userName) { return false; } + virtual int getNextGameId() = 0; + virtual int getNextReplayId() = 0; + + virtual void clearSessionTables() { } + virtual void lockSessionTables() { } + virtual void unlockSessionTables() { } + virtual bool userSessionExists(const QString &userName) { return false; } }; #endif diff --git a/common/server_game.cpp b/common/server_game.cpp index 94eb03ae..647aa22e 100644 --- a/common/server_game.cpp +++ b/common/server_game.cpp @@ -48,7 +48,7 @@ #include Server_Game::Server_Game(const ServerInfo_User &_creatorInfo, int _gameId, const QString &_description, const QString &_password, int _maxPlayers, const QList &_gameTypes, bool _onlyBuddies, bool _onlyRegistered, bool _spectatorsAllowed, bool _spectatorsNeedPassword, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, Server_Room *_room) - : QObject(), + : QObject(), room(_room), nextPlayerId(0), hostId(0), @@ -75,667 +75,667 @@ Server_Game::Server_Game(const ServerInfo_User &_creatorInfo, int _gameId, const startTime(QDateTime::currentDateTime()), gameMutex(QMutex::Recursive) { - currentReplay = new GameReplay; - currentReplay->set_replay_id(room->getServer()->getDatabaseInterface()->getNextReplayId()); - - connect(this, SIGNAL(sigStartGameIfReady()), this, SLOT(doStartGameIfReady()), Qt::QueuedConnection); - - getInfo(*currentReplay->mutable_game_info()); + currentReplay = new GameReplay; + currentReplay->set_replay_id(room->getServer()->getDatabaseInterface()->getNextReplayId()); + + connect(this, SIGNAL(sigStartGameIfReady()), this, SLOT(doStartGameIfReady()), Qt::QueuedConnection); + + getInfo(*currentReplay->mutable_game_info()); - if (room->getServer()->getGameShouldPing()) { - pingClock = new QTimer(this); - connect(pingClock, SIGNAL(timeout()), this, SLOT(pingClockTimeout())); - pingClock->start(1000); - } + if (room->getServer()->getGameShouldPing()) { + pingClock = new QTimer(this); + connect(pingClock, SIGNAL(timeout()), this, SLOT(pingClockTimeout())); + pingClock->start(1000); + } } Server_Game::~Server_Game() { - room->gamesLock.lockForWrite(); - gameMutex.lock(); - - gameClosed = true; - sendGameEventContainer(prepareGameEvent(Event_GameClosed(), -1)); - - QMapIterator playerIterator(players); - while (playerIterator.hasNext()) - playerIterator.next().value()->prepareDestroy(); - players.clear(); - - room->removeGame(this); - delete creatorInfo; - creatorInfo = 0; - - gameMutex.unlock(); - room->gamesLock.unlock(); - - currentReplay->set_duration_seconds(secondsElapsed - startTimeOfThisGame); - replayList.append(currentReplay); - storeGameInformation(); - - for (int i = 0; i < replayList.size(); ++i) - delete replayList[i]; - - qDebug() << "Server_Game destructor: gameId=" << gameId; + room->gamesLock.lockForWrite(); + gameMutex.lock(); + + gameClosed = true; + sendGameEventContainer(prepareGameEvent(Event_GameClosed(), -1)); + + QMapIterator playerIterator(players); + while (playerIterator.hasNext()) + playerIterator.next().value()->prepareDestroy(); + players.clear(); + + room->removeGame(this); + delete creatorInfo; + creatorInfo = 0; + + gameMutex.unlock(); + room->gamesLock.unlock(); + + currentReplay->set_duration_seconds(secondsElapsed - startTimeOfThisGame); + replayList.append(currentReplay); + storeGameInformation(); + + for (int i = 0; i < replayList.size(); ++i) + delete replayList[i]; + + qDebug() << "Server_Game destructor: gameId=" << gameId; } void Server_Game::storeGameInformation() { - const ServerInfo_Game &gameInfo = replayList.first()->game_info(); - - Event_ReplayAdded replayEvent; - ServerInfo_ReplayMatch *replayMatchInfo = replayEvent.mutable_match_info(); - replayMatchInfo->set_game_id(gameInfo.game_id()); - replayMatchInfo->set_room_name(room->getName().toStdString()); - replayMatchInfo->set_time_started(QDateTime::currentDateTime().addSecs(-secondsElapsed).toTime_t()); - replayMatchInfo->set_length(secondsElapsed); - replayMatchInfo->set_game_name(gameInfo.description()); - - const QStringList &allGameTypes = room->getGameTypes(); - QStringList gameTypes; - for (int i = gameInfo.game_types_size() - 1; i >= 0; --i) - gameTypes.append(allGameTypes[gameInfo.game_types(i)]); - - QSetIterator playerIterator(allPlayersEver); - while (playerIterator.hasNext()) - replayMatchInfo->add_player_names(playerIterator.next().toStdString()); - - for (int i = 0; i < replayList.size(); ++i) { - ServerInfo_Replay *replayInfo = replayMatchInfo->add_replay_list(); - replayInfo->set_replay_id(replayList[i]->replay_id()); - replayInfo->set_replay_name(gameInfo.description()); - replayInfo->set_duration(replayList[i]->duration_seconds()); - } - - QSet allUsersInGame = allPlayersEver + allSpectatorsEver; - QSetIterator allUsersIterator(allUsersInGame); - - SessionEvent *sessionEvent = Server_ProtocolHandler::prepareSessionEvent(replayEvent); - Server *server = room->getServer(); - server->clientsLock.lockForRead(); - while (allUsersIterator.hasNext()) { - Server_AbstractUserInterface *userHandler = server->findUser(allUsersIterator.next()); - if (userHandler) - userHandler->sendProtocolItem(*sessionEvent); - } - server->clientsLock.unlock(); - delete sessionEvent; - - server->getDatabaseInterface()->storeGameInformation(room->getName(), gameTypes, gameInfo, allPlayersEver, allSpectatorsEver, replayList); + const ServerInfo_Game &gameInfo = replayList.first()->game_info(); + + Event_ReplayAdded replayEvent; + ServerInfo_ReplayMatch *replayMatchInfo = replayEvent.mutable_match_info(); + replayMatchInfo->set_game_id(gameInfo.game_id()); + replayMatchInfo->set_room_name(room->getName().toStdString()); + replayMatchInfo->set_time_started(QDateTime::currentDateTime().addSecs(-secondsElapsed).toTime_t()); + replayMatchInfo->set_length(secondsElapsed); + replayMatchInfo->set_game_name(gameInfo.description()); + + const QStringList &allGameTypes = room->getGameTypes(); + QStringList gameTypes; + for (int i = gameInfo.game_types_size() - 1; i >= 0; --i) + gameTypes.append(allGameTypes[gameInfo.game_types(i)]); + + QSetIterator playerIterator(allPlayersEver); + while (playerIterator.hasNext()) + replayMatchInfo->add_player_names(playerIterator.next().toStdString()); + + for (int i = 0; i < replayList.size(); ++i) { + ServerInfo_Replay *replayInfo = replayMatchInfo->add_replay_list(); + replayInfo->set_replay_id(replayList[i]->replay_id()); + replayInfo->set_replay_name(gameInfo.description()); + replayInfo->set_duration(replayList[i]->duration_seconds()); + } + + QSet allUsersInGame = allPlayersEver + allSpectatorsEver; + QSetIterator allUsersIterator(allUsersInGame); + + SessionEvent *sessionEvent = Server_ProtocolHandler::prepareSessionEvent(replayEvent); + Server *server = room->getServer(); + server->clientsLock.lockForRead(); + while (allUsersIterator.hasNext()) { + Server_AbstractUserInterface *userHandler = server->findUser(allUsersIterator.next()); + if (userHandler) + userHandler->sendProtocolItem(*sessionEvent); + } + server->clientsLock.unlock(); + delete sessionEvent; + + server->getDatabaseInterface()->storeGameInformation(room->getName(), gameTypes, gameInfo, allPlayersEver, allSpectatorsEver, replayList); } void Server_Game::pingClockTimeout() { - QMutexLocker locker(&gameMutex); - ++secondsElapsed; - - GameEventStorage ges; - ges.setGameEventContext(Context_PingChanged()); - - QList pingList; - QMapIterator playerIterator(players); - bool allPlayersInactive = true; - int playerCount = 0; - while (playerIterator.hasNext()) { - Server_Player *player = playerIterator.next().value(); - if (!player->getSpectator()) - ++playerCount; - - const int oldPingTime = player->getPingTime(); - player->playerMutex.lock(); - int newPingTime; - if (player->getUserInterface()) - newPingTime = player->getUserInterface()->getLastCommandTime(); - else - newPingTime = -1; - player->playerMutex.unlock(); - - if ((newPingTime != -1) && !player->getSpectator()) - allPlayersInactive = false; - - if ((abs(oldPingTime - newPingTime) > 1) || ((newPingTime == -1) && (oldPingTime != -1)) || ((newPingTime != -1) && (oldPingTime == -1))) { - player->setPingTime(newPingTime); - - Event_PlayerPropertiesChanged event; - event.mutable_player_properties()->set_ping_seconds(newPingTime); - ges.enqueueGameEvent(event, player->getPlayerId()); - } - } - ges.sendToGame(this); - - const int maxTime = room->getServer()->getMaxGameInactivityTime(); - if (allPlayersInactive) { - if (((++inactivityCounter >= maxTime) && (maxTime > 0)) || (playerCount < maxPlayers)) - deleteLater(); - } else - inactivityCounter = 0; + QMutexLocker locker(&gameMutex); + ++secondsElapsed; + + GameEventStorage ges; + ges.setGameEventContext(Context_PingChanged()); + + QList pingList; + QMapIterator playerIterator(players); + bool allPlayersInactive = true; + int playerCount = 0; + while (playerIterator.hasNext()) { + Server_Player *player = playerIterator.next().value(); + if (!player->getSpectator()) + ++playerCount; + + const int oldPingTime = player->getPingTime(); + player->playerMutex.lock(); + int newPingTime; + if (player->getUserInterface()) + newPingTime = player->getUserInterface()->getLastCommandTime(); + else + newPingTime = -1; + player->playerMutex.unlock(); + + if ((newPingTime != -1) && !player->getSpectator()) + allPlayersInactive = false; + + if ((abs(oldPingTime - newPingTime) > 1) || ((newPingTime == -1) && (oldPingTime != -1)) || ((newPingTime != -1) && (oldPingTime == -1))) { + player->setPingTime(newPingTime); + + Event_PlayerPropertiesChanged event; + event.mutable_player_properties()->set_ping_seconds(newPingTime); + ges.enqueueGameEvent(event, player->getPlayerId()); + } + } + ges.sendToGame(this); + + const int maxTime = room->getServer()->getMaxGameInactivityTime(); + if (allPlayersInactive) { + if (((++inactivityCounter >= maxTime) && (maxTime > 0)) || (playerCount < maxPlayers)) + deleteLater(); + } else + inactivityCounter = 0; } int Server_Game::getPlayerCount() const { - QMutexLocker locker(&gameMutex); - - QMapIterator playerIterator(players); - int result = 0; - while (playerIterator.hasNext()) - if (!playerIterator.next().value()->getSpectator()) - ++result; - return result; + QMutexLocker locker(&gameMutex); + + QMapIterator playerIterator(players); + int result = 0; + while (playerIterator.hasNext()) + if (!playerIterator.next().value()->getSpectator()) + ++result; + return result; } int Server_Game::getSpectatorCount() const { - QMutexLocker locker(&gameMutex); - - QMapIterator playerIterator(players); - int result = 0; - while (playerIterator.hasNext()) - if (playerIterator.next().value()->getSpectator()) - ++result; - return result; + QMutexLocker locker(&gameMutex); + + QMapIterator playerIterator(players); + int result = 0; + while (playerIterator.hasNext()) + if (playerIterator.next().value()->getSpectator()) + ++result; + return result; } void Server_Game::createGameStateChangedEvent(Event_GameStateChanged *event, Server_Player *playerWhosAsking, bool omniscient, bool withUserInfo) { - event->set_seconds_elapsed(secondsElapsed); - if (gameStarted) { - event->set_game_started(true); - event->set_active_player_id(0); - event->set_active_phase(0); - } else - event->set_game_started(false); - - QMapIterator playerIterator(players); - while (playerIterator.hasNext()) - playerIterator.next().value()->getInfo(event->add_player_list(), playerWhosAsking, omniscient, withUserInfo); + event->set_seconds_elapsed(secondsElapsed); + if (gameStarted) { + event->set_game_started(true); + event->set_active_player_id(0); + event->set_active_phase(0); + } else + event->set_game_started(false); + + QMapIterator playerIterator(players); + while (playerIterator.hasNext()) + playerIterator.next().value()->getInfo(event->add_player_list(), playerWhosAsking, omniscient, withUserInfo); } void Server_Game::sendGameStateToPlayers() { - // game state information for replay and omniscient spectators - Event_GameStateChanged omniscientEvent; - createGameStateChangedEvent(&omniscientEvent, 0, true, false); - - GameEventContainer *replayCont = prepareGameEvent(omniscientEvent, -1); - replayCont->set_seconds_elapsed(secondsElapsed - startTimeOfThisGame); - replayCont->clear_game_id(); - currentReplay->add_event_list()->CopyFrom(*replayCont); - delete replayCont; - - // If spectators are not omniscient, we need an additional createGameStateChangedEvent call, otherwise we can use the data we used for the replay. - // All spectators are equal, so we don't need to make a createGameStateChangedEvent call for each one. - Event_GameStateChanged spectatorEvent; - if (spectatorsSeeEverything) - spectatorEvent = omniscientEvent; - else - createGameStateChangedEvent(&spectatorEvent, 0, false, false); - - // send game state info to clients according to their role in the game - QMapIterator playerIterator(players); - while (playerIterator.hasNext()) { - Server_Player *player = playerIterator.next().value(); - GameEventContainer *gec; - if (player->getSpectator()) - gec = prepareGameEvent(spectatorEvent, -1); - else { - Event_GameStateChanged event; - createGameStateChangedEvent(&event, player, false, false); - - gec = prepareGameEvent(event, -1); - } - player->sendGameEvent(*gec); - delete gec; - } + // game state information for replay and omniscient spectators + Event_GameStateChanged omniscientEvent; + createGameStateChangedEvent(&omniscientEvent, 0, true, false); + + GameEventContainer *replayCont = prepareGameEvent(omniscientEvent, -1); + replayCont->set_seconds_elapsed(secondsElapsed - startTimeOfThisGame); + replayCont->clear_game_id(); + currentReplay->add_event_list()->CopyFrom(*replayCont); + delete replayCont; + + // If spectators are not omniscient, we need an additional createGameStateChangedEvent call, otherwise we can use the data we used for the replay. + // All spectators are equal, so we don't need to make a createGameStateChangedEvent call for each one. + Event_GameStateChanged spectatorEvent; + if (spectatorsSeeEverything) + spectatorEvent = omniscientEvent; + else + createGameStateChangedEvent(&spectatorEvent, 0, false, false); + + // send game state info to clients according to their role in the game + QMapIterator playerIterator(players); + while (playerIterator.hasNext()) { + Server_Player *player = playerIterator.next().value(); + GameEventContainer *gec; + if (player->getSpectator()) + gec = prepareGameEvent(spectatorEvent, -1); + else { + Event_GameStateChanged event; + createGameStateChangedEvent(&event, player, false, false); + + gec = prepareGameEvent(event, -1); + } + player->sendGameEvent(*gec); + delete gec; + } } void Server_Game::doStartGameIfReady() { - Server_DatabaseInterface *databaseInterface = room->getServer()->getDatabaseInterface(); - QMutexLocker locker(&gameMutex); - - if (getPlayerCount() < maxPlayers) - return; - QMapIterator playerIterator(players); - while (playerIterator.hasNext()) { - Server_Player *p = playerIterator.next().value(); - if (!p->getReadyStart() && !p->getSpectator()) - return; - } - playerIterator.toFront(); - while (playerIterator.hasNext()) { - Server_Player *p = playerIterator.next().value(); - if (!p->getSpectator()) - p->setupZones(); - } + Server_DatabaseInterface *databaseInterface = room->getServer()->getDatabaseInterface(); + QMutexLocker locker(&gameMutex); + + if (getPlayerCount() < maxPlayers) + return; + QMapIterator playerIterator(players); + while (playerIterator.hasNext()) { + Server_Player *p = playerIterator.next().value(); + if (!p->getReadyStart() && !p->getSpectator()) + return; + } + playerIterator.toFront(); + while (playerIterator.hasNext()) { + Server_Player *p = playerIterator.next().value(); + if (!p->getSpectator()) + p->setupZones(); + } - gameStarted = true; - playerIterator.toFront(); - while (playerIterator.hasNext()) { - Server_Player *player = playerIterator.next().value(); - player->setConceded(false); - player->setReadyStart(false); - } - - if (firstGameStarted) { - currentReplay->set_duration_seconds(secondsElapsed - startTimeOfThisGame); - replayList.append(currentReplay); - currentReplay = new GameReplay; - currentReplay->set_replay_id(databaseInterface->getNextReplayId()); - ServerInfo_Game *gameInfo = currentReplay->mutable_game_info(); - getInfo(*gameInfo); - gameInfo->set_started(false); - - Event_GameStateChanged omniscientEvent; - createGameStateChangedEvent(&omniscientEvent, 0, true, true); - - GameEventContainer *replayCont = prepareGameEvent(omniscientEvent, -1); - replayCont->set_seconds_elapsed(0); - replayCont->clear_game_id(); - currentReplay->add_event_list()->CopyFrom(*replayCont); - delete replayCont; - - startTimeOfThisGame = secondsElapsed; - } else - firstGameStarted = true; - - sendGameStateToPlayers(); - - activePlayer = -1; - nextTurn(); - - locker.unlock(); - - ServerInfo_Game gameInfo; - gameInfo.set_room_id(room->getId()); - gameInfo.set_game_id(gameId); - gameInfo.set_started(true); - emit gameInfoChanged(gameInfo); + gameStarted = true; + playerIterator.toFront(); + while (playerIterator.hasNext()) { + Server_Player *player = playerIterator.next().value(); + player->setConceded(false); + player->setReadyStart(false); + } + + if (firstGameStarted) { + currentReplay->set_duration_seconds(secondsElapsed - startTimeOfThisGame); + replayList.append(currentReplay); + currentReplay = new GameReplay; + currentReplay->set_replay_id(databaseInterface->getNextReplayId()); + ServerInfo_Game *gameInfo = currentReplay->mutable_game_info(); + getInfo(*gameInfo); + gameInfo->set_started(false); + + Event_GameStateChanged omniscientEvent; + createGameStateChangedEvent(&omniscientEvent, 0, true, true); + + GameEventContainer *replayCont = prepareGameEvent(omniscientEvent, -1); + replayCont->set_seconds_elapsed(0); + replayCont->clear_game_id(); + currentReplay->add_event_list()->CopyFrom(*replayCont); + delete replayCont; + + startTimeOfThisGame = secondsElapsed; + } else + firstGameStarted = true; + + sendGameStateToPlayers(); + + activePlayer = -1; + nextTurn(); + + locker.unlock(); + + ServerInfo_Game gameInfo; + gameInfo.set_room_id(room->getId()); + gameInfo.set_game_id(gameId); + gameInfo.set_started(true); + emit gameInfoChanged(gameInfo); } void Server_Game::startGameIfReady() { - emit sigStartGameIfReady(); + emit sigStartGameIfReady(); } void Server_Game::stopGameIfFinished() { - QMutexLocker locker(&gameMutex); - - QMapIterator playerIterator(players); - int playing = 0; - while (playerIterator.hasNext()) { - Server_Player *p = playerIterator.next().value(); - if (!p->getConceded() && !p->getSpectator()) - ++playing; - } - if (playing > 1) - return; + QMutexLocker locker(&gameMutex); + + QMapIterator playerIterator(players); + int playing = 0; + while (playerIterator.hasNext()) { + Server_Player *p = playerIterator.next().value(); + if (!p->getConceded() && !p->getSpectator()) + ++playing; + } + if (playing > 1) + return; - gameStarted = false; + gameStarted = false; - playerIterator.toFront(); - while (playerIterator.hasNext()) { - Server_Player *p = playerIterator.next().value(); - p->clearZones(); - p->setConceded(false); - } + playerIterator.toFront(); + while (playerIterator.hasNext()) { + Server_Player *p = playerIterator.next().value(); + p->clearZones(); + p->setConceded(false); + } - sendGameStateToPlayers(); - - locker.unlock(); - - ServerInfo_Game gameInfo; - gameInfo.set_room_id(room->getId()); - gameInfo.set_game_id(gameId); - gameInfo.set_started(false); - emit gameInfoChanged(gameInfo); + sendGameStateToPlayers(); + + locker.unlock(); + + ServerInfo_Game gameInfo; + gameInfo.set_room_id(room->getId()); + gameInfo.set_game_id(gameId); + gameInfo.set_started(false); + emit gameInfoChanged(gameInfo); } Response::ResponseCode Server_Game::checkJoin(ServerInfo_User *user, const QString &_password, bool spectator, bool overrideRestrictions) { - Server_DatabaseInterface *databaseInterface = room->getServer()->getDatabaseInterface(); - { - QMapIterator playerIterator(players); - while (playerIterator.hasNext()) - if (playerIterator.next().value()->getUserInfo()->name() == user->name()) - return Response::RespContextError; - } - if (!(overrideRestrictions && (user->user_level() & ServerInfo_User::IsModerator))) { - if ((_password != password) && !(spectator && !spectatorsNeedPassword)) - return Response::RespWrongPassword; - if (!(user->user_level() & ServerInfo_User::IsRegistered) && onlyRegistered) - return Response::RespUserLevelTooLow; - if (onlyBuddies && (user->name() != creatorInfo->name())) - if (!databaseInterface->isInBuddyList(QString::fromStdString(creatorInfo->name()), QString::fromStdString(user->name()))) - return Response::RespOnlyBuddies; - if (databaseInterface->isInIgnoreList(QString::fromStdString(creatorInfo->name()), QString::fromStdString(user->name()))) - return Response::RespInIgnoreList; - if (spectator) { - if (!spectatorsAllowed) - return Response::RespSpectatorsNotAllowed; - } - } - if (!spectator && (gameStarted || (getPlayerCount() >= getMaxPlayers()))) - return Response::RespGameFull; - - return Response::RespOk; + Server_DatabaseInterface *databaseInterface = room->getServer()->getDatabaseInterface(); + { + QMapIterator playerIterator(players); + while (playerIterator.hasNext()) + if (playerIterator.next().value()->getUserInfo()->name() == user->name()) + return Response::RespContextError; + } + if (!(overrideRestrictions && (user->user_level() & ServerInfo_User::IsModerator))) { + if ((_password != password) && !(spectator && !spectatorsNeedPassword)) + return Response::RespWrongPassword; + if (!(user->user_level() & ServerInfo_User::IsRegistered) && onlyRegistered) + return Response::RespUserLevelTooLow; + if (onlyBuddies && (user->name() != creatorInfo->name())) + if (!databaseInterface->isInBuddyList(QString::fromStdString(creatorInfo->name()), QString::fromStdString(user->name()))) + return Response::RespOnlyBuddies; + if (databaseInterface->isInIgnoreList(QString::fromStdString(creatorInfo->name()), QString::fromStdString(user->name()))) + return Response::RespInIgnoreList; + if (spectator) { + if (!spectatorsAllowed) + return Response::RespSpectatorsNotAllowed; + } + } + if (!spectator && (gameStarted || (getPlayerCount() >= getMaxPlayers()))) + return Response::RespGameFull; + + return Response::RespOk; } bool Server_Game::containsUser(const QString &userName) const { - QMutexLocker locker(&gameMutex); - - QMapIterator playerIterator(players); - while (playerIterator.hasNext()) - if (playerIterator.next().value()->getUserInfo()->name() == userName.toStdString()) - return true; - return false; + QMutexLocker locker(&gameMutex); + + QMapIterator playerIterator(players); + while (playerIterator.hasNext()) + if (playerIterator.next().value()->getUserInfo()->name() == userName.toStdString()) + return true; + return false; } void Server_Game::addPlayer(Server_AbstractUserInterface *userInterface, ResponseContainer &rc, bool spectator, bool broadcastUpdate) { - QMutexLocker locker(&gameMutex); - - Server_Player *newPlayer = new Server_Player(this, nextPlayerId++, userInterface->copyUserInfo(true, true), spectator, userInterface); - newPlayer->moveToThread(thread()); - - Event_Join joinEvent; - newPlayer->getProperties(*joinEvent.mutable_player_properties(), true); - sendGameEventContainer(prepareGameEvent(joinEvent, -1)); - - const QString playerName = QString::fromStdString(newPlayer->getUserInfo()->name()); - if (spectator) - allSpectatorsEver.insert(playerName); - else - allPlayersEver.insert(playerName); - players.insert(newPlayer->getPlayerId(), newPlayer); - if (newPlayer->getUserInfo()->name() == creatorInfo->name()) { - hostId = newPlayer->getPlayerId(); - sendGameEventContainer(prepareGameEvent(Event_GameHostChanged(), hostId)); - } - - if (broadcastUpdate) { - ServerInfo_Game gameInfo; - gameInfo.set_room_id(room->getId()); - gameInfo.set_game_id(gameId); - gameInfo.set_player_count(getPlayerCount()); - gameInfo.set_spectators_count(getSpectatorCount()); - emit gameInfoChanged(gameInfo); - } - - if ((newPlayer->getUserInfo()->user_level() & ServerInfo_User::IsRegistered) && !spectator) - room->getServer()->addPersistentPlayer(playerName, room->getId(), gameId, newPlayer->getPlayerId()); - - userInterface->playerAddedToGame(gameId, room->getId(), newPlayer->getPlayerId()); - - createGameJoinedEvent(newPlayer, rc, false); + QMutexLocker locker(&gameMutex); + + Server_Player *newPlayer = new Server_Player(this, nextPlayerId++, userInterface->copyUserInfo(true, true), spectator, userInterface); + newPlayer->moveToThread(thread()); + + Event_Join joinEvent; + newPlayer->getProperties(*joinEvent.mutable_player_properties(), true); + sendGameEventContainer(prepareGameEvent(joinEvent, -1)); + + const QString playerName = QString::fromStdString(newPlayer->getUserInfo()->name()); + if (spectator) + allSpectatorsEver.insert(playerName); + else + allPlayersEver.insert(playerName); + players.insert(newPlayer->getPlayerId(), newPlayer); + if (newPlayer->getUserInfo()->name() == creatorInfo->name()) { + hostId = newPlayer->getPlayerId(); + sendGameEventContainer(prepareGameEvent(Event_GameHostChanged(), hostId)); + } + + if (broadcastUpdate) { + ServerInfo_Game gameInfo; + gameInfo.set_room_id(room->getId()); + gameInfo.set_game_id(gameId); + gameInfo.set_player_count(getPlayerCount()); + gameInfo.set_spectators_count(getSpectatorCount()); + emit gameInfoChanged(gameInfo); + } + + if ((newPlayer->getUserInfo()->user_level() & ServerInfo_User::IsRegistered) && !spectator) + room->getServer()->addPersistentPlayer(playerName, room->getId(), gameId, newPlayer->getPlayerId()); + + userInterface->playerAddedToGame(gameId, room->getId(), newPlayer->getPlayerId()); + + createGameJoinedEvent(newPlayer, rc, false); } void Server_Game::removePlayer(Server_Player *player) { - room->getServer()->removePersistentPlayer(QString::fromStdString(player->getUserInfo()->name()), room->getId(), gameId, player->getPlayerId()); - players.remove(player->getPlayerId()); - - GameEventStorage ges; - removeArrowsRelatedToPlayer(ges, player); - unattachCards(ges, player); - ges.enqueueGameEvent(Event_Leave(), player->getPlayerId()); - ges.sendToGame(this); - - bool playerActive = activePlayer == player->getPlayerId(); - bool playerHost = hostId == player->getPlayerId(); - bool spectator = player->getSpectator(); - player->prepareDestroy(); - - if (!getPlayerCount()) { - gameClosed = true; - deleteLater(); - return; - } else if (!spectator) { - if (playerHost) { - int newHostId = -1; - QMapIterator playerIterator(players); - while (playerIterator.hasNext()) { - Server_Player *p = playerIterator.next().value(); - if (!p->getSpectator()) { - newHostId = p->getPlayerId(); - break; - } - } - if (newHostId != -1) { - hostId = newHostId; - sendGameEventContainer(prepareGameEvent(Event_GameHostChanged(), hostId)); - } - } - stopGameIfFinished(); - if (gameStarted && playerActive) - nextTurn(); - } - - ServerInfo_Game gameInfo; - gameInfo.set_room_id(room->getId()); - gameInfo.set_game_id(gameId); - gameInfo.set_player_count(getPlayerCount()); - gameInfo.set_spectators_count(getSpectatorCount()); - emit gameInfoChanged(gameInfo); + room->getServer()->removePersistentPlayer(QString::fromStdString(player->getUserInfo()->name()), room->getId(), gameId, player->getPlayerId()); + players.remove(player->getPlayerId()); + + GameEventStorage ges; + removeArrowsRelatedToPlayer(ges, player); + unattachCards(ges, player); + ges.enqueueGameEvent(Event_Leave(), player->getPlayerId()); + ges.sendToGame(this); + + bool playerActive = activePlayer == player->getPlayerId(); + bool playerHost = hostId == player->getPlayerId(); + bool spectator = player->getSpectator(); + player->prepareDestroy(); + + if (!getPlayerCount()) { + gameClosed = true; + deleteLater(); + return; + } else if (!spectator) { + if (playerHost) { + int newHostId = -1; + QMapIterator playerIterator(players); + while (playerIterator.hasNext()) { + Server_Player *p = playerIterator.next().value(); + if (!p->getSpectator()) { + newHostId = p->getPlayerId(); + break; + } + } + if (newHostId != -1) { + hostId = newHostId; + sendGameEventContainer(prepareGameEvent(Event_GameHostChanged(), hostId)); + } + } + stopGameIfFinished(); + if (gameStarted && playerActive) + nextTurn(); + } + + ServerInfo_Game gameInfo; + gameInfo.set_room_id(room->getId()); + gameInfo.set_game_id(gameId); + gameInfo.set_player_count(getPlayerCount()); + gameInfo.set_spectators_count(getSpectatorCount()); + emit gameInfoChanged(gameInfo); } void Server_Game::removeArrowsRelatedToPlayer(GameEventStorage &ges, Server_Player *player) { - QMutexLocker locker(&gameMutex); - - // Remove all arrows of other players pointing to the player being removed or to one of his cards. - // Also remove all arrows starting at one of his cards. This is necessary since players can create - // arrows that start at another person's cards. - QMapIterator playerIterator(players); - while (playerIterator.hasNext()) { - Server_Player *p = playerIterator.next().value(); - QList arrows = p->getArrows().values(); - QList toDelete; - for (int i = 0; i < arrows.size(); ++i) { - Server_Arrow *a = arrows[i]; - Server_Card *targetCard = qobject_cast(a->getTargetItem()); - if (targetCard) { - if (targetCard->getZone()->getPlayer() == player) - toDelete.append(a); - } else if (static_cast(a->getTargetItem()) == player) - toDelete.append(a); - - // Don't use else here! It has to happen regardless of whether targetCard == 0. - if (a->getStartCard()->getZone()->getPlayer() == player) - toDelete.append(a); - } - for (int i = 0; i < toDelete.size(); ++i) { - Event_DeleteArrow event; - event.set_arrow_id(toDelete[i]->getId()); - ges.enqueueGameEvent(event, p->getPlayerId()); - - p->deleteArrow(toDelete[i]->getId()); - } - } + QMutexLocker locker(&gameMutex); + + // Remove all arrows of other players pointing to the player being removed or to one of his cards. + // Also remove all arrows starting at one of his cards. This is necessary since players can create + // arrows that start at another person's cards. + QMapIterator playerIterator(players); + while (playerIterator.hasNext()) { + Server_Player *p = playerIterator.next().value(); + QList arrows = p->getArrows().values(); + QList toDelete; + for (int i = 0; i < arrows.size(); ++i) { + Server_Arrow *a = arrows[i]; + Server_Card *targetCard = qobject_cast(a->getTargetItem()); + if (targetCard) { + if (targetCard->getZone()->getPlayer() == player) + toDelete.append(a); + } else if (static_cast(a->getTargetItem()) == player) + toDelete.append(a); + + // Don't use else here! It has to happen regardless of whether targetCard == 0. + if (a->getStartCard()->getZone()->getPlayer() == player) + toDelete.append(a); + } + for (int i = 0; i < toDelete.size(); ++i) { + Event_DeleteArrow event; + event.set_arrow_id(toDelete[i]->getId()); + ges.enqueueGameEvent(event, p->getPlayerId()); + + p->deleteArrow(toDelete[i]->getId()); + } + } } void Server_Game::unattachCards(GameEventStorage &ges, Server_Player *player) { - QMutexLocker locker(&gameMutex); - - QMapIterator zoneIterator(player->getZones()); - while (zoneIterator.hasNext()) { - Server_CardZone *zone = zoneIterator.next().value(); - for (int i = 0; i < zone->getCards().size(); ++i) { - Server_Card *card = zone->getCards().at(i); - - // Make a copy of the list because the original one gets modified during the loop - QList attachedCards = card->getAttachedCards(); - for (int i = 0; i < attachedCards.size(); ++i) - attachedCards[i]->getZone()->getPlayer()->unattachCard(ges, attachedCards[i]); - } - } + QMutexLocker locker(&gameMutex); + + QMapIterator zoneIterator(player->getZones()); + while (zoneIterator.hasNext()) { + Server_CardZone *zone = zoneIterator.next().value(); + for (int i = 0; i < zone->getCards().size(); ++i) { + Server_Card *card = zone->getCards().at(i); + + // Make a copy of the list because the original one gets modified during the loop + QList attachedCards = card->getAttachedCards(); + for (int i = 0; i < attachedCards.size(); ++i) + attachedCards[i]->getZone()->getPlayer()->unattachCard(ges, attachedCards[i]); + } + } } bool Server_Game::kickPlayer(int playerId) { - QMutexLocker locker(&gameMutex); - - Server_Player *playerToKick = players.value(playerId); - if (!playerToKick) - return false; - - GameEventContainer *gec = prepareGameEvent(Event_Kicked(), -1); - playerToKick->sendGameEvent(*gec); - delete gec; - - removePlayer(playerToKick); - - return true; + QMutexLocker locker(&gameMutex); + + Server_Player *playerToKick = players.value(playerId); + if (!playerToKick) + return false; + + GameEventContainer *gec = prepareGameEvent(Event_Kicked(), -1); + playerToKick->sendGameEvent(*gec); + delete gec; + + removePlayer(playerToKick); + + return true; } void Server_Game::setActivePlayer(int _activePlayer) { - QMutexLocker locker(&gameMutex); - - activePlayer = _activePlayer; - - Event_SetActivePlayer event; - event.set_active_player_id(activePlayer); - sendGameEventContainer(prepareGameEvent(event, -1)); - - setActivePhase(0); + QMutexLocker locker(&gameMutex); + + activePlayer = _activePlayer; + + Event_SetActivePlayer event; + event.set_active_player_id(activePlayer); + sendGameEventContainer(prepareGameEvent(event, -1)); + + setActivePhase(0); } void Server_Game::setActivePhase(int _activePhase) { - QMutexLocker locker(&gameMutex); - - QMapIterator playerIterator(players); - while (playerIterator.hasNext()) { - Server_Player *player = playerIterator.next().value(); - QList toDelete = player->getArrows().values(); - for (int i = 0; i < toDelete.size(); ++i) { - Server_Arrow *a = toDelete[i]; - - Event_DeleteArrow event; - event.set_arrow_id(a->getId()); - sendGameEventContainer(prepareGameEvent(event, player->getPlayerId())); - - player->deleteArrow(a->getId()); - } - } - - activePhase = _activePhase; - - Event_SetActivePhase event; - event.set_phase(activePhase); - sendGameEventContainer(prepareGameEvent(event, -1)); + QMutexLocker locker(&gameMutex); + + QMapIterator playerIterator(players); + while (playerIterator.hasNext()) { + Server_Player *player = playerIterator.next().value(); + QList toDelete = player->getArrows().values(); + for (int i = 0; i < toDelete.size(); ++i) { + Server_Arrow *a = toDelete[i]; + + Event_DeleteArrow event; + event.set_arrow_id(a->getId()); + sendGameEventContainer(prepareGameEvent(event, player->getPlayerId())); + + player->deleteArrow(a->getId()); + } + } + + activePhase = _activePhase; + + Event_SetActivePhase event; + event.set_phase(activePhase); + sendGameEventContainer(prepareGameEvent(event, -1)); } void Server_Game::nextTurn() { - QMutexLocker locker(&gameMutex); - - const QList keys = players.keys(); - int listPos = -1; - if (activePlayer != -1) - listPos = keys.indexOf(activePlayer); - do { - ++listPos; - if (listPos == keys.size()) - listPos = 0; - } while (players.value(keys[listPos])->getSpectator() || players.value(keys[listPos])->getConceded()); - - setActivePlayer(keys[listPos]); + QMutexLocker locker(&gameMutex); + + const QList keys = players.keys(); + int listPos = -1; + if (activePlayer != -1) + listPos = keys.indexOf(activePlayer); + do { + ++listPos; + if (listPos == keys.size()) + listPos = 0; + } while (players.value(keys[listPos])->getSpectator() || players.value(keys[listPos])->getConceded()); + + setActivePlayer(keys[listPos]); } void Server_Game::createGameJoinedEvent(Server_Player *player, ResponseContainer &rc, bool resuming) { - Event_GameJoined event1; - getInfo(*event1.mutable_game_info()); - event1.set_host_id(hostId); - event1.set_player_id(player->getPlayerId()); - event1.set_spectator(player->getSpectator()); - event1.set_resuming(resuming); - if (resuming) { - const QStringList &allGameTypes = room->getGameTypes(); - for (int i = 0; i < allGameTypes.size(); ++i) { - ServerInfo_GameType *newGameType = event1.add_game_types(); - newGameType->set_game_type_id(i); - newGameType->set_description(allGameTypes[i].toStdString()); - } - } - rc.enqueuePostResponseItem(ServerMessage::SESSION_EVENT, Server_AbstractUserInterface::prepareSessionEvent(event1)); - - Event_GameStateChanged event2; - event2.set_seconds_elapsed(secondsElapsed); - event2.set_game_started(gameStarted); - event2.set_active_player_id(activePlayer); - event2.set_active_phase(activePhase); - - QMapIterator playerIterator(players); - while (playerIterator.hasNext()) - playerIterator.next().value()->getInfo(event2.add_player_list(), player, player->getSpectator() && spectatorsSeeEverything, true); + Event_GameJoined event1; + getInfo(*event1.mutable_game_info()); + event1.set_host_id(hostId); + event1.set_player_id(player->getPlayerId()); + event1.set_spectator(player->getSpectator()); + event1.set_resuming(resuming); + if (resuming) { + const QStringList &allGameTypes = room->getGameTypes(); + for (int i = 0; i < allGameTypes.size(); ++i) { + ServerInfo_GameType *newGameType = event1.add_game_types(); + newGameType->set_game_type_id(i); + newGameType->set_description(allGameTypes[i].toStdString()); + } + } + rc.enqueuePostResponseItem(ServerMessage::SESSION_EVENT, Server_AbstractUserInterface::prepareSessionEvent(event1)); + + Event_GameStateChanged event2; + event2.set_seconds_elapsed(secondsElapsed); + event2.set_game_started(gameStarted); + event2.set_active_player_id(activePlayer); + event2.set_active_phase(activePhase); + + QMapIterator playerIterator(players); + while (playerIterator.hasNext()) + playerIterator.next().value()->getInfo(event2.add_player_list(), player, player->getSpectator() && spectatorsSeeEverything, true); - rc.enqueuePostResponseItem(ServerMessage::GAME_EVENT_CONTAINER, prepareGameEvent(event2, -1)); + rc.enqueuePostResponseItem(ServerMessage::GAME_EVENT_CONTAINER, prepareGameEvent(event2, -1)); } void Server_Game::sendGameEventContainer(GameEventContainer *cont, GameEventStorageItem::EventRecipients recipients, int privatePlayerId) { - QMutexLocker locker(&gameMutex); - - cont->set_game_id(gameId); - QMapIterator playerIterator(players); - while (playerIterator.hasNext()) { - Server_Player *p = playerIterator.next().value(); - const bool playerPrivate = (p->getPlayerId() == privatePlayerId) || (p->getSpectator() && spectatorsSeeEverything); - if ((recipients.testFlag(GameEventStorageItem::SendToPrivate) && playerPrivate) || (recipients.testFlag(GameEventStorageItem::SendToOthers) && !playerPrivate)) - p->sendGameEvent(*cont); - } - if (recipients.testFlag(GameEventStorageItem::SendToPrivate)) { - cont->set_seconds_elapsed(secondsElapsed - startTimeOfThisGame); - cont->clear_game_id(); - currentReplay->add_event_list()->CopyFrom(*cont); - } - - delete cont; + QMutexLocker locker(&gameMutex); + + cont->set_game_id(gameId); + QMapIterator playerIterator(players); + while (playerIterator.hasNext()) { + Server_Player *p = playerIterator.next().value(); + const bool playerPrivate = (p->getPlayerId() == privatePlayerId) || (p->getSpectator() && spectatorsSeeEverything); + if ((recipients.testFlag(GameEventStorageItem::SendToPrivate) && playerPrivate) || (recipients.testFlag(GameEventStorageItem::SendToOthers) && !playerPrivate)) + p->sendGameEvent(*cont); + } + if (recipients.testFlag(GameEventStorageItem::SendToPrivate)) { + cont->set_seconds_elapsed(secondsElapsed - startTimeOfThisGame); + cont->clear_game_id(); + currentReplay->add_event_list()->CopyFrom(*cont); + } + + delete cont; } GameEventContainer *Server_Game::prepareGameEvent(const ::google::protobuf::Message &gameEvent, int playerId, GameEventContext *context) { - GameEventContainer *cont = new GameEventContainer; - cont->set_game_id(gameId); - if (context) - cont->mutable_context()->CopyFrom(*context); - GameEvent *event = cont->add_event_list(); - if (playerId != -1) - event->set_player_id(playerId); - event->GetReflection()->MutableMessage(event, gameEvent.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(gameEvent); - return cont; + GameEventContainer *cont = new GameEventContainer; + cont->set_game_id(gameId); + if (context) + cont->mutable_context()->CopyFrom(*context); + GameEvent *event = cont->add_event_list(); + if (playerId != -1) + event->set_player_id(playerId); + event->GetReflection()->MutableMessage(event, gameEvent.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(gameEvent); + return cont; } void Server_Game::getInfo(ServerInfo_Game &result) const { - QMutexLocker locker(&gameMutex); - - result.set_room_id(room->getId()); - result.set_game_id(gameId); - if (gameClosed) - result.set_closed(true); - else { - for (int i = 0; i < gameTypes.size(); ++i) - result.add_game_types(gameTypes[i]); - - result.set_max_players(getMaxPlayers()); - result.set_description(getDescription().toStdString()); - result.set_with_password(!getPassword().isEmpty()); - result.set_player_count(getPlayerCount()); - result.set_started(gameStarted); - result.mutable_creator_info()->CopyFrom(*getCreatorInfo()); - result.set_only_buddies(onlyBuddies); - result.set_only_registered(onlyRegistered); - result.set_spectators_allowed(getSpectatorsAllowed()); - result.set_spectators_need_password(getSpectatorsNeedPassword()); - result.set_spectators_can_chat(spectatorsCanTalk); - result.set_spectators_omniscient(spectatorsSeeEverything); - result.set_spectators_count(getSpectatorCount()); - result.set_start_time(startTime.toTime_t()); - } + QMutexLocker locker(&gameMutex); + + result.set_room_id(room->getId()); + result.set_game_id(gameId); + if (gameClosed) + result.set_closed(true); + else { + for (int i = 0; i < gameTypes.size(); ++i) + result.add_game_types(gameTypes[i]); + + result.set_max_players(getMaxPlayers()); + result.set_description(getDescription().toStdString()); + result.set_with_password(!getPassword().isEmpty()); + result.set_player_count(getPlayerCount()); + result.set_started(gameStarted); + result.mutable_creator_info()->CopyFrom(*getCreatorInfo()); + result.set_only_buddies(onlyBuddies); + result.set_only_registered(onlyRegistered); + result.set_spectators_allowed(getSpectatorsAllowed()); + result.set_spectators_need_password(getSpectatorsNeedPassword()); + result.set_spectators_can_chat(spectatorsCanTalk); + result.set_spectators_omniscient(spectatorsSeeEverything); + result.set_spectators_count(getSpectatorCount()); + result.set_start_time(startTime.toTime_t()); + } } diff --git a/common/server_game.h b/common/server_game.h index f6ddbf92..cf7eb086 100644 --- a/common/server_game.h +++ b/common/server_game.h @@ -42,86 +42,86 @@ class Server_AbstractUserInterface; class Event_GameStateChanged; class Server_Game : public QObject { - Q_OBJECT + Q_OBJECT private: - Server_Room *room; - int nextPlayerId; - int hostId; - ServerInfo_User *creatorInfo; - QMap players; - QSet allPlayersEver, allSpectatorsEver; - bool gameStarted; - bool gameClosed; - int gameId; - QString description; - QString password; - int maxPlayers; - QList gameTypes; - int activePlayer, activePhase; - bool onlyBuddies, onlyRegistered; - bool spectatorsAllowed; - bool spectatorsNeedPassword; - bool spectatorsCanTalk; - bool spectatorsSeeEverything; - int inactivityCounter; - int startTimeOfThisGame, secondsElapsed; - bool firstGameStarted; - QDateTime startTime; - QTimer *pingClock; - QList replayList; - GameReplay *currentReplay; - - void createGameStateChangedEvent(Event_GameStateChanged *event, Server_Player *playerWhosAsking, bool omniscient, bool withUserInfo); - void sendGameStateToPlayers(); - void storeGameInformation(); + Server_Room *room; + int nextPlayerId; + int hostId; + ServerInfo_User *creatorInfo; + QMap players; + QSet allPlayersEver, allSpectatorsEver; + bool gameStarted; + bool gameClosed; + int gameId; + QString description; + QString password; + int maxPlayers; + QList gameTypes; + int activePlayer, activePhase; + bool onlyBuddies, onlyRegistered; + bool spectatorsAllowed; + bool spectatorsNeedPassword; + bool spectatorsCanTalk; + bool spectatorsSeeEverything; + int inactivityCounter; + int startTimeOfThisGame, secondsElapsed; + bool firstGameStarted; + QDateTime startTime; + QTimer *pingClock; + QList replayList; + GameReplay *currentReplay; + + void createGameStateChangedEvent(Event_GameStateChanged *event, Server_Player *playerWhosAsking, bool omniscient, bool withUserInfo); + void sendGameStateToPlayers(); + void storeGameInformation(); signals: - void sigStartGameIfReady(); - void gameInfoChanged(ServerInfo_Game gameInfo); + void sigStartGameIfReady(); + void gameInfoChanged(ServerInfo_Game gameInfo); private slots: - void pingClockTimeout(); - void doStartGameIfReady(); + void pingClockTimeout(); + void doStartGameIfReady(); public: - mutable QMutex gameMutex; - Server_Game(const ServerInfo_User &_creatorInfo, int _gameId, const QString &_description, const QString &_password, int _maxPlayers, const QList &_gameTypes, bool _onlyBuddies, bool _onlyRegistered, bool _spectatorsAllowed, bool _spectatorsNeedPassword, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, Server_Room *parent); - ~Server_Game(); - Server_Room *getRoom() const { return room; } - void getInfo(ServerInfo_Game &result) const; - int getHostId() const { return hostId; } - ServerInfo_User *getCreatorInfo() const { return creatorInfo; } - bool getGameStarted() const { return gameStarted; } - int getPlayerCount() const; - int getSpectatorCount() const; - const QMap &getPlayers() const { return players; } - int getGameId() const { return gameId; } - QString getDescription() const { return description; } - QString getPassword() const { return password; } - int getMaxPlayers() const { return maxPlayers; } - bool getSpectatorsAllowed() const { return spectatorsAllowed; } - bool getSpectatorsNeedPassword() const { return spectatorsNeedPassword; } - bool getSpectatorsCanTalk() const { return spectatorsCanTalk; } - bool getSpectatorsSeeEverything() const { return spectatorsSeeEverything; } - Response::ResponseCode checkJoin(ServerInfo_User *user, const QString &_password, bool spectator, bool overrideRestrictions); - bool containsUser(const QString &userName) const; - void addPlayer(Server_AbstractUserInterface *userInterface, ResponseContainer &rc, bool spectator, bool broadcastUpdate = true); - void removePlayer(Server_Player *player); - void removeArrowsRelatedToPlayer(GameEventStorage &ges, Server_Player *player); - void unattachCards(GameEventStorage &ges, Server_Player *player); - bool kickPlayer(int playerId); - void startGameIfReady(); - void stopGameIfFinished(); - int getActivePlayer() const { return activePlayer; } - int getActivePhase() const { return activePhase; } - void setActivePlayer(int _activePlayer); - void setActivePhase(int _activePhase); - void nextTurn(); - int getSecondsElapsed() const { return secondsElapsed; } + mutable QMutex gameMutex; + Server_Game(const ServerInfo_User &_creatorInfo, int _gameId, const QString &_description, const QString &_password, int _maxPlayers, const QList &_gameTypes, bool _onlyBuddies, bool _onlyRegistered, bool _spectatorsAllowed, bool _spectatorsNeedPassword, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, Server_Room *parent); + ~Server_Game(); + Server_Room *getRoom() const { return room; } + void getInfo(ServerInfo_Game &result) const; + int getHostId() const { return hostId; } + ServerInfo_User *getCreatorInfo() const { return creatorInfo; } + bool getGameStarted() const { return gameStarted; } + int getPlayerCount() const; + int getSpectatorCount() const; + const QMap &getPlayers() const { return players; } + int getGameId() const { return gameId; } + QString getDescription() const { return description; } + QString getPassword() const { return password; } + int getMaxPlayers() const { return maxPlayers; } + bool getSpectatorsAllowed() const { return spectatorsAllowed; } + bool getSpectatorsNeedPassword() const { return spectatorsNeedPassword; } + bool getSpectatorsCanTalk() const { return spectatorsCanTalk; } + bool getSpectatorsSeeEverything() const { return spectatorsSeeEverything; } + Response::ResponseCode checkJoin(ServerInfo_User *user, const QString &_password, bool spectator, bool overrideRestrictions); + bool containsUser(const QString &userName) const; + void addPlayer(Server_AbstractUserInterface *userInterface, ResponseContainer &rc, bool spectator, bool broadcastUpdate = true); + void removePlayer(Server_Player *player); + void removeArrowsRelatedToPlayer(GameEventStorage &ges, Server_Player *player); + void unattachCards(GameEventStorage &ges, Server_Player *player); + bool kickPlayer(int playerId); + void startGameIfReady(); + void stopGameIfFinished(); + int getActivePlayer() const { return activePlayer; } + int getActivePhase() const { return activePhase; } + void setActivePlayer(int _activePlayer); + void setActivePhase(int _activePhase); + void nextTurn(); + int getSecondsElapsed() const { return secondsElapsed; } - void createGameJoinedEvent(Server_Player *player, ResponseContainer &rc, bool resuming); - - GameEventContainer *prepareGameEvent(const ::google::protobuf::Message &gameEvent, int playerId, GameEventContext *context = 0); - GameEventContext prepareGameEventContext(const ::google::protobuf::Message &gameEventContext); - - void sendGameEventContainer(GameEventContainer *cont, GameEventStorageItem::EventRecipients recipients = GameEventStorageItem::SendToPrivate | GameEventStorageItem::SendToOthers, int privatePlayerId = -1); + void createGameJoinedEvent(Server_Player *player, ResponseContainer &rc, bool resuming); + + GameEventContainer *prepareGameEvent(const ::google::protobuf::Message &gameEvent, int playerId, GameEventContext *context = 0); + GameEventContext prepareGameEventContext(const ::google::protobuf::Message &gameEventContext); + + void sendGameEventContainer(GameEventContainer *cont, GameEventStorageItem::EventRecipients recipients = GameEventStorageItem::SendToPrivate | GameEventStorageItem::SendToOthers, int privatePlayerId = -1); }; #endif diff --git a/common/server_player.cpp b/common/server_player.cpp index 76cd260d..c25151e8 100644 --- a/common/server_player.cpp +++ b/common/server_player.cpp @@ -84,7 +84,7 @@ #include Server_Player::Server_Player(Server_Game *_game, int _playerId, const ServerInfo_User &_userInfo, bool _spectator, Server_AbstractUserInterface *_userInterface) - : ServerInfo_User_Container(_userInfo), game(_game), userInterface(_userInterface), deck(0), pingTime(0), playerId(_playerId), spectator(_spectator), nextCardId(0), readyStart(false), conceded(false), sideboardLocked(true) + : ServerInfo_User_Container(_userInfo), game(_game), userInterface(_userInterface), deck(0), pingTime(0), playerId(_playerId), spectator(_spectator), nextCardId(0), readyStart(false), conceded(false), sideboardLocked(true) { } @@ -94,1624 +94,1624 @@ Server_Player::~Server_Player() void Server_Player::prepareDestroy() { - delete deck; - - playerMutex.lock(); - if (userInterface) - userInterface->playerRemovedFromGame(game); - playerMutex.unlock(); - - clearZones(); - - deleteLater(); + delete deck; + + playerMutex.lock(); + if (userInterface) + userInterface->playerRemovedFromGame(game); + playerMutex.unlock(); + + clearZones(); + + deleteLater(); } int Server_Player::newCardId() { - return nextCardId++; + return nextCardId++; } int Server_Player::newCounterId() const { - int id = 0; - QMapIterator i(counters); - while (i.hasNext()) { - Server_Counter *c = i.next().value(); - if (c->getId() > id) - id = c->getId(); - } - return id + 1; + int id = 0; + QMapIterator i(counters); + while (i.hasNext()) { + Server_Counter *c = i.next().value(); + if (c->getId() > id) + id = c->getId(); + } + return id + 1; } int Server_Player::newArrowId() const { - int id = 0; - QMapIterator i(arrows); - while (i.hasNext()) { - Server_Arrow *a = i.next().value(); - if (a->getId() > id) - id = a->getId(); - } - return id + 1; + int id = 0; + QMapIterator i(arrows); + while (i.hasNext()) { + Server_Arrow *a = i.next().value(); + if (a->getId() > id) + id = a->getId(); + } + return id + 1; } void Server_Player::setupZones() { - // This may need to be customized according to the game rules. - // ------------------------------------------------------------------ + // This may need to be customized according to the game rules. + // ------------------------------------------------------------------ - // Create zones - Server_CardZone *deckZone = new Server_CardZone(this, "deck", false, ServerInfo_Zone::HiddenZone); - addZone(deckZone); - Server_CardZone *sbZone = new Server_CardZone(this, "sb", false, ServerInfo_Zone::HiddenZone); - addZone(sbZone); - addZone(new Server_CardZone(this, "table", true, ServerInfo_Zone::PublicZone)); - addZone(new Server_CardZone(this, "hand", false, ServerInfo_Zone::PrivateZone)); - addZone(new Server_CardZone(this, "stack", false, ServerInfo_Zone::PublicZone)); - addZone(new Server_CardZone(this, "grave", false, ServerInfo_Zone::PublicZone)); - addZone(new Server_CardZone(this, "rfg", false, ServerInfo_Zone::PublicZone)); + // Create zones + Server_CardZone *deckZone = new Server_CardZone(this, "deck", false, ServerInfo_Zone::HiddenZone); + addZone(deckZone); + Server_CardZone *sbZone = new Server_CardZone(this, "sb", false, ServerInfo_Zone::HiddenZone); + addZone(sbZone); + addZone(new Server_CardZone(this, "table", true, ServerInfo_Zone::PublicZone)); + addZone(new Server_CardZone(this, "hand", false, ServerInfo_Zone::PrivateZone)); + addZone(new Server_CardZone(this, "stack", false, ServerInfo_Zone::PublicZone)); + addZone(new Server_CardZone(this, "grave", false, ServerInfo_Zone::PublicZone)); + addZone(new Server_CardZone(this, "rfg", false, ServerInfo_Zone::PublicZone)); - addCounter(new Server_Counter(0, "life", makeColor(255, 255, 255), 25, 20)); - addCounter(new Server_Counter(1, "w", makeColor(255, 255, 150), 20, 0)); - addCounter(new Server_Counter(2, "u", makeColor(150, 150, 255), 20, 0)); - addCounter(new Server_Counter(3, "b", makeColor(150, 150, 150), 20, 0)); - addCounter(new Server_Counter(4, "r", makeColor(250, 150, 150), 20, 0)); - addCounter(new Server_Counter(5, "g", makeColor(150, 255, 150), 20, 0)); - addCounter(new Server_Counter(6, "x", makeColor(255, 255, 255), 20, 0)); - addCounter(new Server_Counter(7, "storm", makeColor(255, 255, 255), 20, 0)); + addCounter(new Server_Counter(0, "life", makeColor(255, 255, 255), 25, 20)); + addCounter(new Server_Counter(1, "w", makeColor(255, 255, 150), 20, 0)); + addCounter(new Server_Counter(2, "u", makeColor(150, 150, 255), 20, 0)); + addCounter(new Server_Counter(3, "b", makeColor(150, 150, 150), 20, 0)); + addCounter(new Server_Counter(4, "r", makeColor(250, 150, 150), 20, 0)); + addCounter(new Server_Counter(5, "g", makeColor(150, 255, 150), 20, 0)); + addCounter(new Server_Counter(6, "x", makeColor(255, 255, 255), 20, 0)); + addCounter(new Server_Counter(7, "storm", makeColor(255, 255, 255), 20, 0)); - initialCards = 7; + initialCards = 7; - // ------------------------------------------------------------------ + // ------------------------------------------------------------------ - // Assign card ids and create deck from decklist - InnerDecklistNode *listRoot = deck->getRoot(); - nextCardId = 0; - for (int i = 0; i < listRoot->size(); ++i) { - InnerDecklistNode *currentZone = dynamic_cast(listRoot->at(i)); - Server_CardZone *z; - if (currentZone->getName() == "main") - z = deckZone; - else if (currentZone->getName() == "side") - z = sbZone; - else - continue; - - for (int j = 0; j < currentZone->size(); ++j) { - DecklistCardNode *currentCard = dynamic_cast(currentZone->at(j)); - if (!currentCard) - continue; - for (int k = 0; k < currentCard->getNumber(); ++k) - z->insertCard(new Server_Card(currentCard->getName(), nextCardId++, 0, 0, z), -1, 0); - } - } - - const QList &sideboardPlan = deck->getCurrentSideboardPlan(); - for (int i = 0; i < sideboardPlan.size(); ++i) { - const MoveCard_ToZone &m = sideboardPlan[i]; - const QString startZone = QString::fromStdString(m.start_zone()); - const QString targetZone = QString::fromStdString(m.target_zone()); - - Server_CardZone *start, *target; - if (startZone == "main") - start = deckZone; - else if (startZone == "side") - start = sbZone; - else - continue; - if (targetZone == "main") - target = deckZone; - else if (targetZone == "side") - target = sbZone; - else - continue; - - for (int j = 0; j < start->getCards().size(); ++j) - if (start->getCards()[j]->getName() == QString::fromStdString(m.card_name())) { - Server_Card *card = start->getCard(j, NULL, true); - target->insertCard(card, -1, 0); - break; - } - } - - deckZone->shuffle(); + // Assign card ids and create deck from decklist + InnerDecklistNode *listRoot = deck->getRoot(); + nextCardId = 0; + for (int i = 0; i < listRoot->size(); ++i) { + InnerDecklistNode *currentZone = dynamic_cast(listRoot->at(i)); + Server_CardZone *z; + if (currentZone->getName() == "main") + z = deckZone; + else if (currentZone->getName() == "side") + z = sbZone; + else + continue; + + for (int j = 0; j < currentZone->size(); ++j) { + DecklistCardNode *currentCard = dynamic_cast(currentZone->at(j)); + if (!currentCard) + continue; + for (int k = 0; k < currentCard->getNumber(); ++k) + z->insertCard(new Server_Card(currentCard->getName(), nextCardId++, 0, 0, z), -1, 0); + } + } + + const QList &sideboardPlan = deck->getCurrentSideboardPlan(); + for (int i = 0; i < sideboardPlan.size(); ++i) { + const MoveCard_ToZone &m = sideboardPlan[i]; + const QString startZone = QString::fromStdString(m.start_zone()); + const QString targetZone = QString::fromStdString(m.target_zone()); + + Server_CardZone *start, *target; + if (startZone == "main") + start = deckZone; + else if (startZone == "side") + start = sbZone; + else + continue; + if (targetZone == "main") + target = deckZone; + else if (targetZone == "side") + target = sbZone; + else + continue; + + for (int j = 0; j < start->getCards().size(); ++j) + if (start->getCards()[j]->getName() == QString::fromStdString(m.card_name())) { + Server_Card *card = start->getCard(j, NULL, true); + target->insertCard(card, -1, 0); + break; + } + } + + deckZone->shuffle(); } void Server_Player::clearZones() { - QMapIterator zoneIterator(zones); - while (zoneIterator.hasNext()) - delete zoneIterator.next().value(); - zones.clear(); + QMapIterator zoneIterator(zones); + while (zoneIterator.hasNext()) + delete zoneIterator.next().value(); + zones.clear(); - QMapIterator counterIterator(counters); - while (counterIterator.hasNext()) - delete counterIterator.next().value(); - counters.clear(); - - QMapIterator arrowIterator(arrows); - while (arrowIterator.hasNext()) - delete arrowIterator.next().value(); - arrows.clear(); + QMapIterator counterIterator(counters); + while (counterIterator.hasNext()) + delete counterIterator.next().value(); + counters.clear(); + + QMapIterator arrowIterator(arrows); + while (arrowIterator.hasNext()) + delete arrowIterator.next().value(); + arrows.clear(); - lastDrawList.clear(); + lastDrawList.clear(); } void Server_Player::getProperties(ServerInfo_PlayerProperties &result, bool withUserInfo) { - result.set_player_id(playerId); - if (withUserInfo) - copyUserInfo(*(result.mutable_user_info()), true); - result.set_spectator(spectator); - if (!spectator) { - result.set_conceded(conceded); - result.set_sideboard_locked(sideboardLocked); - result.set_ready_start(readyStart); - } - if (deck) - result.set_deck_hash(deck->getDeckHash().toStdString()); - result.set_ping_seconds(pingTime); + result.set_player_id(playerId); + if (withUserInfo) + copyUserInfo(*(result.mutable_user_info()), true); + result.set_spectator(spectator); + if (!spectator) { + result.set_conceded(conceded); + result.set_sideboard_locked(sideboardLocked); + result.set_ready_start(readyStart); + } + if (deck) + result.set_deck_hash(deck->getDeckHash().toStdString()); + result.set_ping_seconds(pingTime); } void Server_Player::addZone(Server_CardZone *zone) { - zones.insert(zone->getName(), zone); + zones.insert(zone->getName(), zone); } void Server_Player::addArrow(Server_Arrow *arrow) { - arrows.insert(arrow->getId(), arrow); + arrows.insert(arrow->getId(), arrow); } bool Server_Player::deleteArrow(int arrowId) { - Server_Arrow *arrow = arrows.value(arrowId, 0); - if (!arrow) - return false; - arrows.remove(arrowId); - delete arrow; - return true; + Server_Arrow *arrow = arrows.value(arrowId, 0); + if (!arrow) + return false; + arrows.remove(arrowId); + delete arrow; + return true; } void Server_Player::addCounter(Server_Counter *counter) { - counters.insert(counter->getId(), counter); + counters.insert(counter->getId(), counter); } Response::ResponseCode Server_Player::drawCards(GameEventStorage &ges, int number) { - Server_CardZone *deckZone = zones.value("deck"); - Server_CardZone *handZone = zones.value("hand"); - if (deckZone->getCards().size() < number) - number = deckZone->getCards().size(); - - Event_DrawCards eventOthers; - eventOthers.set_number(number); - Event_DrawCards eventPrivate(eventOthers); - - for (int i = 0; i < number; ++i) { - Server_Card *card = deckZone->getCard(0, NULL, true); - handZone->insertCard(card, -1, 0); - lastDrawList.append(card->getId()); - - ServerInfo_Card *cardInfo = eventPrivate.add_cards(); - cardInfo->set_id(card->getId()); - cardInfo->set_name(card->getName().toStdString()); - } - - ges.enqueueGameEvent(eventPrivate, playerId, GameEventStorageItem::SendToPrivate, playerId); - ges.enqueueGameEvent(eventOthers, playerId, GameEventStorageItem::SendToOthers); - - if (deckZone->getAlwaysRevealTopCard() && !deckZone->getCards().isEmpty()) { - Event_RevealCards revealEvent; - revealEvent.set_zone_name(deckZone->getName().toStdString()); - revealEvent.set_card_id(0); - deckZone->getCards().first()->getInfo(revealEvent.add_cards()); - - ges.enqueueGameEvent(revealEvent, playerId); - } - - return Response::RespOk; + Server_CardZone *deckZone = zones.value("deck"); + Server_CardZone *handZone = zones.value("hand"); + if (deckZone->getCards().size() < number) + number = deckZone->getCards().size(); + + Event_DrawCards eventOthers; + eventOthers.set_number(number); + Event_DrawCards eventPrivate(eventOthers); + + for (int i = 0; i < number; ++i) { + Server_Card *card = deckZone->getCard(0, NULL, true); + handZone->insertCard(card, -1, 0); + lastDrawList.append(card->getId()); + + ServerInfo_Card *cardInfo = eventPrivate.add_cards(); + cardInfo->set_id(card->getId()); + cardInfo->set_name(card->getName().toStdString()); + } + + ges.enqueueGameEvent(eventPrivate, playerId, GameEventStorageItem::SendToPrivate, playerId); + ges.enqueueGameEvent(eventOthers, playerId, GameEventStorageItem::SendToOthers); + + if (deckZone->getAlwaysRevealTopCard() && !deckZone->getCards().isEmpty()) { + Event_RevealCards revealEvent; + revealEvent.set_zone_name(deckZone->getName().toStdString()); + revealEvent.set_card_id(0); + deckZone->getCards().first()->getInfo(revealEvent.add_cards()); + + ges.enqueueGameEvent(revealEvent, playerId); + } + + return Response::RespOk; } class Server_Player::MoveCardCompareFunctor { private: - int x; + int x; public: - MoveCardCompareFunctor(int _x) : x(_x) { } - inline bool operator()(QPair a, QPair b) - { - if (a.second < x) { - if (b.second >= x) - return false; - else - return (a.second > b.second); - } else { - if (b.second < x) - return true; - else - return (a.second < b.second); - } - } + MoveCardCompareFunctor(int _x) : x(_x) { } + inline bool operator()(QPair a, QPair b) + { + if (a.second < x) { + if (b.second >= x) + return false; + else + return (a.second > b.second); + } else { + if (b.second < x) + return true; + else + return (a.second < b.second); + } + } }; Response::ResponseCode Server_Player::moveCard(GameEventStorage &ges, Server_CardZone *startzone, const QList &_cards, Server_CardZone *targetzone, int x, int y, bool fixFreeSpaces, bool undoingDraw) { - // Disallow controller change to other zones than the table. - if (((targetzone->getType() != ServerInfo_Zone::PublicZone) || !targetzone->hasCoords()) && (startzone->getPlayer() != targetzone->getPlayer())) - return Response::RespContextError; - - if (!targetzone->hasCoords() && (x == -1)) - x = targetzone->getCards().size(); - - QList > cardsToMove; - QMap cardProperties; - QSet cardIdsToMove; - for (int i = 0; i < _cards.size(); ++i) { - // The same card being moved twice would lead to undefined behaviour. - if (cardIdsToMove.contains(_cards[i]->card_id())) - continue; - cardIdsToMove.insert(_cards[i]->card_id()); - - // Consistency checks. In case the command contains illegal moves, try to resolve the legal ones still. - int position; - Server_Card *card = startzone->getCard(_cards[i]->card_id(), &position); - if (!card) - return Response::RespNameNotFound; - if (card->getParentCard()) - continue; - if (!card->getAttachedCards().isEmpty() && !targetzone->isColumnEmpty(x, y)) - continue; - cardsToMove.append(QPair(card, position)); - cardProperties.insert(card, _cards[i]); - } - // In case all moves were filtered out, abort. - if (cardsToMove.isEmpty()) - return Response::RespContextError; - - MoveCardCompareFunctor cmp(startzone == targetzone ? -1 : x); - qSort(cardsToMove.begin(), cardsToMove.end(), cmp); - - bool secondHalf = false; - int xIndex = -1; - for (int cardIndex = 0; cardIndex < cardsToMove.size(); ++cardIndex) { - Server_Card *card = cardsToMove[cardIndex].first; - const CardToMove *thisCardProperties = cardProperties.value(card); - bool faceDown = thisCardProperties->has_face_down() ? thisCardProperties->face_down() : card->getFaceDown(); - if (!targetzone->hasCoords()) - faceDown = false; - - int originalPosition = cardsToMove[cardIndex].second; - int position = startzone->removeCard(card); - if (startzone->getName() == "hand") { - if (undoingDraw) - lastDrawList.removeAt(lastDrawList.indexOf(card->getId())); - else if (lastDrawList.contains(card->getId())) - lastDrawList.clear(); - } - - if ((startzone == targetzone) && !startzone->hasCoords()) { - if (!secondHalf && (originalPosition < x)) { - xIndex = -1; - secondHalf = true; - } else if (secondHalf) - --xIndex; - else - ++xIndex; - } else - ++xIndex; - int newX = x + xIndex; - - // Attachment relationships can be retained when moving a card onto the opponent's table - if (startzone->getName() != targetzone->getName()) { - // Delete all attachment relationships - if (card->getParentCard()) - card->setParentCard(0); - - // Make a copy of the list because the original one gets modified during the loop - QList attachedCards = card->getAttachedCards(); - for (int i = 0; i < attachedCards.size(); ++i) - attachedCards[i]->getZone()->getPlayer()->unattachCard(ges, attachedCards[i]); - } - - if (startzone != targetzone) { - // Delete all arrows from and to the card - const QList &players = game->getPlayers().values(); - for (int i = 0; i < players.size(); ++i) { - QList arrowsToDelete; - QMapIterator arrowIterator(players[i]->getArrows()); - while (arrowIterator.hasNext()) { - Server_Arrow *arrow = arrowIterator.next().value(); - if ((arrow->getStartCard() == card) || (arrow->getTargetItem() == card)) - arrowsToDelete.append(arrow->getId()); - } - for (int j = 0; j < arrowsToDelete.size(); ++j) - players[i]->deleteArrow(arrowsToDelete[j]); - } - } - - int publicNewX; - if (card->getDestroyOnZoneChange() && (startzone->getName() != targetzone->getName())) { - Event_DestroyCard event; - event.set_zone_name(startzone->getName().toStdString()); - event.set_card_id(card->getId()); - ges.enqueueGameEvent(event, playerId); - - card->deleteLater(); - } else { - if (!targetzone->hasCoords()) { - y = 0; - card->resetState(); - } else - newX = targetzone->getFreeGridColumn(newX, y, card->getName()); - - targetzone->insertCard(card, newX, y); - - bool targetBeingLookedAt = (targetzone->getType() != ServerInfo_Zone::HiddenZone) || (targetzone->getCardsBeingLookedAt() > newX) || (targetzone->getCardsBeingLookedAt() == -1); - bool sourceBeingLookedAt = (startzone->getType() != ServerInfo_Zone::HiddenZone) || (startzone->getCardsBeingLookedAt() > position) || (startzone->getCardsBeingLookedAt() == -1); - - bool targetHiddenToPlayer = faceDown || !targetBeingLookedAt; - bool targetHiddenToOthers = faceDown || (targetzone->getType() != ServerInfo_Zone::PublicZone); - bool sourceHiddenToPlayer = card->getFaceDown() || !sourceBeingLookedAt; - bool sourceHiddenToOthers = card->getFaceDown() || (startzone->getType() != ServerInfo_Zone::PublicZone); - - QString privateCardName, publicCardName; - if (!(sourceHiddenToPlayer && targetHiddenToPlayer)) - privateCardName = card->getName(); - if (!(sourceHiddenToOthers && targetHiddenToOthers)) - publicCardName = card->getName(); - - int oldCardId = card->getId(); - if ((faceDown && (startzone != targetzone)) || (targetzone->getPlayer() != startzone->getPlayer())) - card->setId(targetzone->getPlayer()->newCardId()); - card->setFaceDown(faceDown); - - // The player does not get to see which card he moved if it moves between two parts of hidden zones which - // are not being looked at. - int privateNewCardId = card->getId(); - int privateOldCardId = oldCardId; - if (!targetBeingLookedAt && !sourceBeingLookedAt) { - privateOldCardId = -1; - privateNewCardId = -1; - privateCardName = QString(); - } - int privatePosition = -1; - if (startzone->getType() == ServerInfo_Zone::HiddenZone) - privatePosition = position; - - publicNewX = newX; - - Event_MoveCard eventOthers; - eventOthers.set_start_player_id(startzone->getPlayer()->getPlayerId()); - eventOthers.set_start_zone(startzone->getName().toStdString()); - eventOthers.set_target_player_id(targetzone->getPlayer()->getPlayerId()); - if (startzone != targetzone) - eventOthers.set_target_zone(targetzone->getName().toStdString()); - eventOthers.set_y(y); - eventOthers.set_face_down(faceDown); - - Event_MoveCard eventPrivate(eventOthers); - eventPrivate.set_card_id(privateOldCardId); - if (!privateCardName.isEmpty()) - eventPrivate.set_card_name(privateCardName.toStdString()); - eventPrivate.set_position(privatePosition); - eventPrivate.set_new_card_id(privateNewCardId); - eventPrivate.set_x(newX); - - // Other players do not get to see the start and/or target position of the card if the respective - // part of the zone is being looked at. The information is not needed anyway because in hidden zones, - // all cards are equal. - if ( - ((startzone->getType() == ServerInfo_Zone::HiddenZone) && ((startzone->getCardsBeingLookedAt() > position) || (startzone->getCardsBeingLookedAt() == -1))) - || (startzone->getType() == ServerInfo_Zone::PublicZone) - ) - position = -1; - if ((targetzone->getType() == ServerInfo_Zone::HiddenZone) && ((targetzone->getCardsBeingLookedAt() > newX) || (targetzone->getCardsBeingLookedAt() == -1))) - publicNewX = -1; - - eventOthers.set_x(publicNewX); - eventOthers.set_position(position); - if ((startzone->getType() == ServerInfo_Zone::PublicZone) || (targetzone->getType() == ServerInfo_Zone::PublicZone)) { - eventOthers.set_card_id(oldCardId); - if (!publicCardName.isEmpty()) - eventOthers.set_card_name(publicCardName.toStdString()); - eventOthers.set_new_card_id(card->getId()); - } - - ges.enqueueGameEvent(eventPrivate, playerId, GameEventStorageItem::SendToPrivate, playerId); - ges.enqueueGameEvent(eventOthers, playerId, GameEventStorageItem::SendToOthers); - - if (thisCardProperties->tapped()) - setCardAttrHelper(ges, targetzone->getName(), card->getId(), AttrTapped, "1"); - QString ptString = QString::fromStdString(thisCardProperties->pt()); - if (!ptString.isEmpty() && !faceDown) - setCardAttrHelper(ges, targetzone->getName(), card->getId(), AttrPT, ptString); - } - if (startzone->getAlwaysRevealTopCard() && !startzone->getCards().isEmpty() && (originalPosition == 0)) { - Event_RevealCards revealEvent; - revealEvent.set_zone_name(startzone->getName().toStdString()); - revealEvent.set_card_id(0); - startzone->getCards().first()->getInfo(revealEvent.add_cards()); - - ges.enqueueGameEvent(revealEvent, playerId); - } - if (targetzone->getAlwaysRevealTopCard() && !targetzone->getCards().isEmpty() && (newX == 0)) { - Event_RevealCards revealEvent; - revealEvent.set_zone_name(targetzone->getName().toStdString()); - revealEvent.set_card_id(0); - targetzone->getCards().first()->getInfo(revealEvent.add_cards()); - - ges.enqueueGameEvent(revealEvent, playerId); - } - } - if (undoingDraw) - ges.setGameEventContext(Context_UndoDraw()); - else - ges.setGameEventContext(Context_MoveCard()); - - if (startzone->hasCoords() && fixFreeSpaces) - startzone->fixFreeSpaces(ges); - - return Response::RespOk; + // Disallow controller change to other zones than the table. + if (((targetzone->getType() != ServerInfo_Zone::PublicZone) || !targetzone->hasCoords()) && (startzone->getPlayer() != targetzone->getPlayer())) + return Response::RespContextError; + + if (!targetzone->hasCoords() && (x == -1)) + x = targetzone->getCards().size(); + + QList > cardsToMove; + QMap cardProperties; + QSet cardIdsToMove; + for (int i = 0; i < _cards.size(); ++i) { + // The same card being moved twice would lead to undefined behaviour. + if (cardIdsToMove.contains(_cards[i]->card_id())) + continue; + cardIdsToMove.insert(_cards[i]->card_id()); + + // Consistency checks. In case the command contains illegal moves, try to resolve the legal ones still. + int position; + Server_Card *card = startzone->getCard(_cards[i]->card_id(), &position); + if (!card) + return Response::RespNameNotFound; + if (card->getParentCard()) + continue; + if (!card->getAttachedCards().isEmpty() && !targetzone->isColumnEmpty(x, y)) + continue; + cardsToMove.append(QPair(card, position)); + cardProperties.insert(card, _cards[i]); + } + // In case all moves were filtered out, abort. + if (cardsToMove.isEmpty()) + return Response::RespContextError; + + MoveCardCompareFunctor cmp(startzone == targetzone ? -1 : x); + qSort(cardsToMove.begin(), cardsToMove.end(), cmp); + + bool secondHalf = false; + int xIndex = -1; + for (int cardIndex = 0; cardIndex < cardsToMove.size(); ++cardIndex) { + Server_Card *card = cardsToMove[cardIndex].first; + const CardToMove *thisCardProperties = cardProperties.value(card); + bool faceDown = thisCardProperties->has_face_down() ? thisCardProperties->face_down() : card->getFaceDown(); + if (!targetzone->hasCoords()) + faceDown = false; + + int originalPosition = cardsToMove[cardIndex].second; + int position = startzone->removeCard(card); + if (startzone->getName() == "hand") { + if (undoingDraw) + lastDrawList.removeAt(lastDrawList.indexOf(card->getId())); + else if (lastDrawList.contains(card->getId())) + lastDrawList.clear(); + } + + if ((startzone == targetzone) && !startzone->hasCoords()) { + if (!secondHalf && (originalPosition < x)) { + xIndex = -1; + secondHalf = true; + } else if (secondHalf) + --xIndex; + else + ++xIndex; + } else + ++xIndex; + int newX = x + xIndex; + + // Attachment relationships can be retained when moving a card onto the opponent's table + if (startzone->getName() != targetzone->getName()) { + // Delete all attachment relationships + if (card->getParentCard()) + card->setParentCard(0); + + // Make a copy of the list because the original one gets modified during the loop + QList attachedCards = card->getAttachedCards(); + for (int i = 0; i < attachedCards.size(); ++i) + attachedCards[i]->getZone()->getPlayer()->unattachCard(ges, attachedCards[i]); + } + + if (startzone != targetzone) { + // Delete all arrows from and to the card + const QList &players = game->getPlayers().values(); + for (int i = 0; i < players.size(); ++i) { + QList arrowsToDelete; + QMapIterator arrowIterator(players[i]->getArrows()); + while (arrowIterator.hasNext()) { + Server_Arrow *arrow = arrowIterator.next().value(); + if ((arrow->getStartCard() == card) || (arrow->getTargetItem() == card)) + arrowsToDelete.append(arrow->getId()); + } + for (int j = 0; j < arrowsToDelete.size(); ++j) + players[i]->deleteArrow(arrowsToDelete[j]); + } + } + + int publicNewX; + if (card->getDestroyOnZoneChange() && (startzone->getName() != targetzone->getName())) { + Event_DestroyCard event; + event.set_zone_name(startzone->getName().toStdString()); + event.set_card_id(card->getId()); + ges.enqueueGameEvent(event, playerId); + + card->deleteLater(); + } else { + if (!targetzone->hasCoords()) { + y = 0; + card->resetState(); + } else + newX = targetzone->getFreeGridColumn(newX, y, card->getName()); + + targetzone->insertCard(card, newX, y); + + bool targetBeingLookedAt = (targetzone->getType() != ServerInfo_Zone::HiddenZone) || (targetzone->getCardsBeingLookedAt() > newX) || (targetzone->getCardsBeingLookedAt() == -1); + bool sourceBeingLookedAt = (startzone->getType() != ServerInfo_Zone::HiddenZone) || (startzone->getCardsBeingLookedAt() > position) || (startzone->getCardsBeingLookedAt() == -1); + + bool targetHiddenToPlayer = faceDown || !targetBeingLookedAt; + bool targetHiddenToOthers = faceDown || (targetzone->getType() != ServerInfo_Zone::PublicZone); + bool sourceHiddenToPlayer = card->getFaceDown() || !sourceBeingLookedAt; + bool sourceHiddenToOthers = card->getFaceDown() || (startzone->getType() != ServerInfo_Zone::PublicZone); + + QString privateCardName, publicCardName; + if (!(sourceHiddenToPlayer && targetHiddenToPlayer)) + privateCardName = card->getName(); + if (!(sourceHiddenToOthers && targetHiddenToOthers)) + publicCardName = card->getName(); + + int oldCardId = card->getId(); + if ((faceDown && (startzone != targetzone)) || (targetzone->getPlayer() != startzone->getPlayer())) + card->setId(targetzone->getPlayer()->newCardId()); + card->setFaceDown(faceDown); + + // The player does not get to see which card he moved if it moves between two parts of hidden zones which + // are not being looked at. + int privateNewCardId = card->getId(); + int privateOldCardId = oldCardId; + if (!targetBeingLookedAt && !sourceBeingLookedAt) { + privateOldCardId = -1; + privateNewCardId = -1; + privateCardName = QString(); + } + int privatePosition = -1; + if (startzone->getType() == ServerInfo_Zone::HiddenZone) + privatePosition = position; + + publicNewX = newX; + + Event_MoveCard eventOthers; + eventOthers.set_start_player_id(startzone->getPlayer()->getPlayerId()); + eventOthers.set_start_zone(startzone->getName().toStdString()); + eventOthers.set_target_player_id(targetzone->getPlayer()->getPlayerId()); + if (startzone != targetzone) + eventOthers.set_target_zone(targetzone->getName().toStdString()); + eventOthers.set_y(y); + eventOthers.set_face_down(faceDown); + + Event_MoveCard eventPrivate(eventOthers); + eventPrivate.set_card_id(privateOldCardId); + if (!privateCardName.isEmpty()) + eventPrivate.set_card_name(privateCardName.toStdString()); + eventPrivate.set_position(privatePosition); + eventPrivate.set_new_card_id(privateNewCardId); + eventPrivate.set_x(newX); + + // Other players do not get to see the start and/or target position of the card if the respective + // part of the zone is being looked at. The information is not needed anyway because in hidden zones, + // all cards are equal. + if ( + ((startzone->getType() == ServerInfo_Zone::HiddenZone) && ((startzone->getCardsBeingLookedAt() > position) || (startzone->getCardsBeingLookedAt() == -1))) + || (startzone->getType() == ServerInfo_Zone::PublicZone) + ) + position = -1; + if ((targetzone->getType() == ServerInfo_Zone::HiddenZone) && ((targetzone->getCardsBeingLookedAt() > newX) || (targetzone->getCardsBeingLookedAt() == -1))) + publicNewX = -1; + + eventOthers.set_x(publicNewX); + eventOthers.set_position(position); + if ((startzone->getType() == ServerInfo_Zone::PublicZone) || (targetzone->getType() == ServerInfo_Zone::PublicZone)) { + eventOthers.set_card_id(oldCardId); + if (!publicCardName.isEmpty()) + eventOthers.set_card_name(publicCardName.toStdString()); + eventOthers.set_new_card_id(card->getId()); + } + + ges.enqueueGameEvent(eventPrivate, playerId, GameEventStorageItem::SendToPrivate, playerId); + ges.enqueueGameEvent(eventOthers, playerId, GameEventStorageItem::SendToOthers); + + if (thisCardProperties->tapped()) + setCardAttrHelper(ges, targetzone->getName(), card->getId(), AttrTapped, "1"); + QString ptString = QString::fromStdString(thisCardProperties->pt()); + if (!ptString.isEmpty() && !faceDown) + setCardAttrHelper(ges, targetzone->getName(), card->getId(), AttrPT, ptString); + } + if (startzone->getAlwaysRevealTopCard() && !startzone->getCards().isEmpty() && (originalPosition == 0)) { + Event_RevealCards revealEvent; + revealEvent.set_zone_name(startzone->getName().toStdString()); + revealEvent.set_card_id(0); + startzone->getCards().first()->getInfo(revealEvent.add_cards()); + + ges.enqueueGameEvent(revealEvent, playerId); + } + if (targetzone->getAlwaysRevealTopCard() && !targetzone->getCards().isEmpty() && (newX == 0)) { + Event_RevealCards revealEvent; + revealEvent.set_zone_name(targetzone->getName().toStdString()); + revealEvent.set_card_id(0); + targetzone->getCards().first()->getInfo(revealEvent.add_cards()); + + ges.enqueueGameEvent(revealEvent, playerId); + } + } + if (undoingDraw) + ges.setGameEventContext(Context_UndoDraw()); + else + ges.setGameEventContext(Context_MoveCard()); + + if (startzone->hasCoords() && fixFreeSpaces) + startzone->fixFreeSpaces(ges); + + return Response::RespOk; } void Server_Player::unattachCard(GameEventStorage &ges, Server_Card *card) { - Server_CardZone *zone = card->getZone(); - Server_Card *parentCard = card->getParentCard(); - card->setParentCard(0); - - Event_AttachCard event; - event.set_start_zone(zone->getName().toStdString()); - event.set_card_id(card->getId()); - ges.enqueueGameEvent(event, playerId); - - CardToMove *cardToMove = new CardToMove; - cardToMove->set_card_id(card->getId()); - moveCard(ges, zone, QList() << cardToMove, zone, -1, card->getY(), card->getFaceDown()); - delete cardToMove; - - if (parentCard->getZone()) - parentCard->getZone()->updateCardCoordinates(parentCard, parentCard->getX(), parentCard->getY()); + Server_CardZone *zone = card->getZone(); + Server_Card *parentCard = card->getParentCard(); + card->setParentCard(0); + + Event_AttachCard event; + event.set_start_zone(zone->getName().toStdString()); + event.set_card_id(card->getId()); + ges.enqueueGameEvent(event, playerId); + + CardToMove *cardToMove = new CardToMove; + cardToMove->set_card_id(card->getId()); + moveCard(ges, zone, QList() << cardToMove, zone, -1, card->getY(), card->getFaceDown()); + delete cardToMove; + + if (parentCard->getZone()) + parentCard->getZone()->updateCardCoordinates(parentCard, parentCard->getX(), parentCard->getY()); } Response::ResponseCode Server_Player::setCardAttrHelper(GameEventStorage &ges, const QString &zoneName, int cardId, CardAttribute attribute, const QString &attrValue) { - Server_CardZone *zone = getZones().value(zoneName); - if (!zone) - return Response::RespNameNotFound; - if (!zone->hasCoords()) - return Response::RespContextError; + Server_CardZone *zone = getZones().value(zoneName); + if (!zone) + return Response::RespNameNotFound; + if (!zone->hasCoords()) + return Response::RespContextError; - QString result; - if (cardId == -1) { - QListIterator CardIterator(zone->getCards()); - while (CardIterator.hasNext()) { - result = CardIterator.next()->setAttribute(attribute, attrValue, true); - if (result.isNull()) - return Response::RespInvalidCommand; - } - } else { - Server_Card *card = zone->getCard(cardId); - if (!card) - return Response::RespNameNotFound; - result = card->setAttribute(attribute, attrValue, false); - if (result.isNull()) - return Response::RespInvalidCommand; - } - - Event_SetCardAttr event; - event.set_zone_name(zone->getName().toStdString()); - if (cardId != -1) - event.set_card_id(cardId); - event.set_attribute(attribute); - event.set_attr_value(result.toStdString()); - ges.enqueueGameEvent(event, playerId); - - return Response::RespOk; + QString result; + if (cardId == -1) { + QListIterator CardIterator(zone->getCards()); + while (CardIterator.hasNext()) { + result = CardIterator.next()->setAttribute(attribute, attrValue, true); + if (result.isNull()) + return Response::RespInvalidCommand; + } + } else { + Server_Card *card = zone->getCard(cardId); + if (!card) + return Response::RespNameNotFound; + result = card->setAttribute(attribute, attrValue, false); + if (result.isNull()) + return Response::RespInvalidCommand; + } + + Event_SetCardAttr event; + event.set_zone_name(zone->getName().toStdString()); + if (cardId != -1) + event.set_card_id(cardId); + event.set_attribute(attribute); + event.set_attr_value(result.toStdString()); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdLeaveGame(const Command_LeaveGame & /*cmd*/, ResponseContainer & /*rc*/, GameEventStorage & /*ges*/) { - game->removePlayer(this); - return Response::RespOk; + game->removePlayer(this); + return Response::RespOk; } Response::ResponseCode Server_Player::cmdKickFromGame(const Command_KickFromGame &cmd, ResponseContainer & /*rc*/, GameEventStorage & /*ges*/) { - if ((game->getHostId() != playerId) && !(userInfo->user_level() & ServerInfo_User::IsModerator)) - return Response::RespFunctionNotAllowed; - - if (!game->kickPlayer(cmd.player_id())) - return Response::RespNameNotFound; - - return Response::RespOk; + if ((game->getHostId() != playerId) && !(userInfo->user_level() & ServerInfo_User::IsModerator)) + return Response::RespFunctionNotAllowed; + + if (!game->kickPlayer(cmd.player_id())) + return Response::RespNameNotFound; + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdDeckSelect(const Command_DeckSelect &cmd, ResponseContainer &rc, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - DeckList *newDeck; - if (cmd.has_deck_id()) { - try { - newDeck = game->getRoom()->getServer()->getDatabaseInterface()->getDeckFromDatabase(cmd.deck_id(), userInfo->id()); - } catch(Response::ResponseCode r) { - return r; - } - } else - newDeck = new DeckList(QString::fromStdString(cmd.deck())); - - if (!newDeck) - return Response::RespInternalError; - - delete deck; - deck = newDeck; - sideboardLocked = true; - - Event_PlayerPropertiesChanged event; - event.mutable_player_properties()->set_sideboard_locked(true); - event.mutable_player_properties()->set_deck_hash(deck->getDeckHash().toStdString()); - ges.enqueueGameEvent(event, playerId); - - Context_DeckSelect context; - context.set_deck_hash(deck->getDeckHash().toStdString()); + if (spectator) + return Response::RespFunctionNotAllowed; + + DeckList *newDeck; + if (cmd.has_deck_id()) { + try { + newDeck = game->getRoom()->getServer()->getDatabaseInterface()->getDeckFromDatabase(cmd.deck_id(), userInfo->id()); + } catch(Response::ResponseCode r) { + return r; + } + } else + newDeck = new DeckList(QString::fromStdString(cmd.deck())); + + if (!newDeck) + return Response::RespInternalError; + + delete deck; + deck = newDeck; + sideboardLocked = true; + + Event_PlayerPropertiesChanged event; + event.mutable_player_properties()->set_sideboard_locked(true); + event.mutable_player_properties()->set_deck_hash(deck->getDeckHash().toStdString()); + ges.enqueueGameEvent(event, playerId); + + Context_DeckSelect context; + context.set_deck_hash(deck->getDeckHash().toStdString()); context.set_sideboard_size(deck->getSideboardSize()); - ges.setGameEventContext(context); - - Response_DeckDownload *re = new Response_DeckDownload; - re->set_deck(deck->writeToString_Native().toStdString()); - - rc.setResponseExtension(re); - return Response::RespOk; + ges.setGameEventContext(context); + + Response_DeckDownload *re = new Response_DeckDownload; + re->set_deck(deck->writeToString_Native().toStdString()); + + rc.setResponseExtension(re); + return Response::RespOk; } Response::ResponseCode Server_Player::cmdSetSideboardPlan(const Command_SetSideboardPlan &cmd, ResponseContainer & /*rc*/, GameEventStorage & /*ges*/) { - if (spectator) - return Response::RespFunctionNotAllowed; - if (readyStart) - return Response::RespContextError; - if (!deck) - return Response::RespContextError; - if (sideboardLocked) - return Response::RespContextError; - - QList sideboardPlan; - for (int i = 0; i < cmd.move_list_size(); ++i) - sideboardPlan.append(cmd.move_list(i)); - deck->setCurrentSideboardPlan(sideboardPlan); - - return Response::RespOk; + if (spectator) + return Response::RespFunctionNotAllowed; + if (readyStart) + return Response::RespContextError; + if (!deck) + return Response::RespContextError; + if (sideboardLocked) + return Response::RespContextError; + + QList sideboardPlan; + for (int i = 0; i < cmd.move_list_size(); ++i) + sideboardPlan.append(cmd.move_list(i)); + deck->setCurrentSideboardPlan(sideboardPlan); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdSetSideboardLock(const Command_SetSideboardLock &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - if (readyStart) - return Response::RespContextError; - if (!deck) - return Response::RespContextError; - if (sideboardLocked == cmd.locked()) - return Response::RespContextError; - - sideboardLocked = cmd.locked(); - if (sideboardLocked) - deck->setCurrentSideboardPlan(QList()); - - Event_PlayerPropertiesChanged event; - event.mutable_player_properties()->set_sideboard_locked(sideboardLocked); - ges.enqueueGameEvent(event, playerId); - ges.setGameEventContext(Context_SetSideboardLock()); - - return Response::RespOk; + if (spectator) + return Response::RespFunctionNotAllowed; + if (readyStart) + return Response::RespContextError; + if (!deck) + return Response::RespContextError; + if (sideboardLocked == cmd.locked()) + return Response::RespContextError; + + sideboardLocked = cmd.locked(); + if (sideboardLocked) + deck->setCurrentSideboardPlan(QList()); + + Event_PlayerPropertiesChanged event; + event.mutable_player_properties()->set_sideboard_locked(sideboardLocked); + ges.enqueueGameEvent(event, playerId); + ges.setGameEventContext(Context_SetSideboardLock()); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdConcede(const Command_Concede & /*cmd*/, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - setConceded(true); - game->removeArrowsRelatedToPlayer(ges, this); - game->unattachCards(ges, this); - clearZones(); - - Event_PlayerPropertiesChanged event; - event.mutable_player_properties()->set_conceded(true); - ges.enqueueGameEvent(event, playerId); - ges.setGameEventContext(Context_Concede()); - - game->stopGameIfFinished(); - if (game->getGameStarted() && (game->getActivePlayer() == playerId)) - game->nextTurn(); - - return Response::RespOk; + if (spectator) + return Response::RespFunctionNotAllowed; + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + setConceded(true); + game->removeArrowsRelatedToPlayer(ges, this); + game->unattachCards(ges, this); + clearZones(); + + Event_PlayerPropertiesChanged event; + event.mutable_player_properties()->set_conceded(true); + ges.enqueueGameEvent(event, playerId); + ges.setGameEventContext(Context_Concede()); + + game->stopGameIfFinished(); + if (game->getGameStarted() && (game->getActivePlayer() == playerId)) + game->nextTurn(); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdReadyStart(const Command_ReadyStart &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!deck || game->getGameStarted()) - return Response::RespContextError; + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!deck || game->getGameStarted()) + return Response::RespContextError; - if (readyStart == cmd.ready()) - return Response::RespContextError; - - setReadyStart(cmd.ready()); - - Event_PlayerPropertiesChanged event; - event.mutable_player_properties()->set_ready_start(cmd.ready()); - ges.enqueueGameEvent(event, playerId); - ges.setGameEventContext(Context_ReadyStart()); - - if (cmd.ready()) - game->startGameIfReady(); - - return Response::RespOk; + if (readyStart == cmd.ready()) + return Response::RespContextError; + + setReadyStart(cmd.ready()); + + Event_PlayerPropertiesChanged event; + event.mutable_player_properties()->set_ready_start(cmd.ready()); + ges.enqueueGameEvent(event, playerId); + ges.setGameEventContext(Context_ReadyStart()); + + if (cmd.ready()) + game->startGameIfReady(); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdGameSay(const Command_GameSay &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator && !game->getSpectatorsCanTalk() && !(userInfo->user_level() & ServerInfo_User::IsModerator)) - return Response::RespFunctionNotAllowed; - - Event_GameSay event; - event.set_message(cmd.message()); - ges.enqueueGameEvent(event, playerId); - - return Response::RespOk; + if (spectator && !game->getSpectatorsCanTalk() && !(userInfo->user_level() & ServerInfo_User::IsModerator)) + return Response::RespFunctionNotAllowed; + + Event_GameSay event; + event.set_message(cmd.message()); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdShuffle(const Command_Shuffle & /*cmd*/, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - Server_CardZone *deckZone = zones.value("deck"); - deckZone->shuffle(); - - Event_Shuffle event; - event.set_zone_name("deck"); - ges.enqueueGameEvent(event, playerId); - - if (deckZone->getAlwaysRevealTopCard() && !deckZone->getCards().isEmpty()) { - Event_RevealCards revealEvent; - revealEvent.set_zone_name(deckZone->getName().toStdString()); - revealEvent.set_card_id(0); - deckZone->getCards().first()->getInfo(revealEvent.add_cards()); - - ges.enqueueGameEvent(revealEvent, playerId); - } - - return Response::RespOk; + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_CardZone *deckZone = zones.value("deck"); + deckZone->shuffle(); + + Event_Shuffle event; + event.set_zone_name("deck"); + ges.enqueueGameEvent(event, playerId); + + if (deckZone->getAlwaysRevealTopCard() && !deckZone->getCards().isEmpty()) { + Event_RevealCards revealEvent; + revealEvent.set_zone_name(deckZone->getName().toStdString()); + revealEvent.set_card_id(0); + deckZone->getCards().first()->getInfo(revealEvent.add_cards()); + + ges.enqueueGameEvent(revealEvent, playerId); + } + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdMulligan(const Command_Mulligan & /*cmd*/, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - Server_CardZone *hand = zones.value("hand"); - int number = (hand->getCards().size() <= 1) ? initialCards : hand->getCards().size() - 1; - - Server_CardZone *deck = zones.value("deck"); - while (!hand->getCards().isEmpty()) { - CardToMove *cardToMove = new CardToMove; - cardToMove->set_card_id(hand->getCards().first()->getId()); - moveCard(ges, hand, QList() << cardToMove, deck, 0, 0, false); - delete cardToMove; - } - - deck->shuffle(); - ges.enqueueGameEvent(Event_Shuffle(), playerId); + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_CardZone *hand = zones.value("hand"); + int number = (hand->getCards().size() <= 1) ? initialCards : hand->getCards().size() - 1; + + Server_CardZone *deck = zones.value("deck"); + while (!hand->getCards().isEmpty()) { + CardToMove *cardToMove = new CardToMove; + cardToMove->set_card_id(hand->getCards().first()->getId()); + moveCard(ges, hand, QList() << cardToMove, deck, 0, 0, false); + delete cardToMove; + } + + deck->shuffle(); + ges.enqueueGameEvent(Event_Shuffle(), playerId); - drawCards(ges, number); - - if (number == initialCards) - number = -1; - - Context_Mulligan context; - context.set_number(number); - ges.setGameEventContext(context); + drawCards(ges, number); + + if (number == initialCards) + number = -1; + + Context_Mulligan context; + context.set_number(number); + ges.setGameEventContext(context); - return Response::RespOk; + return Response::RespOk; } Response::ResponseCode Server_Player::cmdRollDie(const Command_RollDie &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - if (conceded) - return Response::RespContextError; - - Event_RollDie event; - event.set_sides(cmd.sides()); - event.set_value(rng->rand(1, cmd.sides())); - ges.enqueueGameEvent(event, playerId); - - return Response::RespOk; + if (spectator) + return Response::RespFunctionNotAllowed; + if (conceded) + return Response::RespContextError; + + Event_RollDie event; + event.set_sides(cmd.sides()); + event.set_value(rng->rand(1, cmd.sides())); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdDrawCards(const Command_DrawCards &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - return drawCards(ges, cmd.number()); + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + return drawCards(ges, cmd.number()); } Response::ResponseCode Server_Player::cmdUndoDraw(const Command_UndoDraw & /*cmd*/, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - if (lastDrawList.isEmpty()) - return Response::RespContextError; - - Response::ResponseCode retVal; - CardToMove *cardToMove = new CardToMove; - cardToMove->set_card_id(lastDrawList.takeLast()); - retVal = moveCard(ges, zones.value("hand"), QList() << cardToMove, zones.value("deck"), 0, 0, false, true); - delete cardToMove; - - return retVal; + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + if (lastDrawList.isEmpty()) + return Response::RespContextError; + + Response::ResponseCode retVal; + CardToMove *cardToMove = new CardToMove; + cardToMove->set_card_id(lastDrawList.takeLast()); + retVal = moveCard(ges, zones.value("hand"), QList() << cardToMove, zones.value("deck"), 0, 0, false, true); + delete cardToMove; + + return retVal; } Response::ResponseCode Server_Player::cmdMoveCard(const Command_MoveCard &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - Server_Player *startPlayer = game->getPlayers().value(cmd.has_start_player_id() ? cmd.start_player_id() : playerId); - if (!startPlayer) - return Response::RespNameNotFound; - Server_CardZone *startZone = startPlayer->getZones().value(QString::fromStdString(cmd.start_zone())); - if (!startZone) - return Response::RespNameNotFound; - - if ((startPlayer != this) && (!startZone->getPlayersWithWritePermission().contains(playerId))) - return Response::RespContextError; - - Server_Player *targetPlayer = game->getPlayers().value(cmd.target_player_id()); - if (!targetPlayer) - return Response::RespNameNotFound; - Server_CardZone *targetZone = targetPlayer->getZones().value(QString::fromStdString(cmd.target_zone())); - if (!targetZone) - return Response::RespNameNotFound; - - if ((startPlayer != this) && (targetPlayer != this)) - return Response::RespContextError; - - QList cardsToMove; - for (int i = 0; i < cmd.cards_to_move().card_size(); ++i) - cardsToMove.append(&cmd.cards_to_move().card(i)); - - return moveCard(ges, startZone, cardsToMove, targetZone, cmd.x(), cmd.y()); + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_Player *startPlayer = game->getPlayers().value(cmd.has_start_player_id() ? cmd.start_player_id() : playerId); + if (!startPlayer) + return Response::RespNameNotFound; + Server_CardZone *startZone = startPlayer->getZones().value(QString::fromStdString(cmd.start_zone())); + if (!startZone) + return Response::RespNameNotFound; + + if ((startPlayer != this) && (!startZone->getPlayersWithWritePermission().contains(playerId))) + return Response::RespContextError; + + Server_Player *targetPlayer = game->getPlayers().value(cmd.target_player_id()); + if (!targetPlayer) + return Response::RespNameNotFound; + Server_CardZone *targetZone = targetPlayer->getZones().value(QString::fromStdString(cmd.target_zone())); + if (!targetZone) + return Response::RespNameNotFound; + + if ((startPlayer != this) && (targetPlayer != this)) + return Response::RespContextError; + + QList cardsToMove; + for (int i = 0; i < cmd.cards_to_move().card_size(); ++i) + cardsToMove.append(&cmd.cards_to_move().card(i)); + + return moveCard(ges, startZone, cardsToMove, targetZone, cmd.x(), cmd.y()); } Response::ResponseCode Server_Player::cmdFlipCard(const Command_FlipCard &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - Server_CardZone *zone = zones.value(QString::fromStdString(cmd.zone())); - if (!zone) - return Response::RespNameNotFound; - if (!zone->hasCoords()) - return Response::RespContextError; - - Server_Card *card = zone->getCard(cmd.card_id()); - if (!card) - return Response::RespNameNotFound; - - const bool faceDown = cmd.face_down(); - if (faceDown == card->getFaceDown()) - return Response::RespContextError; - - card->setFaceDown(faceDown); - - Event_FlipCard event; - event.set_zone_name(zone->getName().toStdString()); - event.set_card_id(card->getId()); - if (!faceDown) - event.set_card_name(card->getName().toStdString()); - event.set_face_down(faceDown); - ges.enqueueGameEvent(event, playerId); - - return Response::RespOk; + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_CardZone *zone = zones.value(QString::fromStdString(cmd.zone())); + if (!zone) + return Response::RespNameNotFound; + if (!zone->hasCoords()) + return Response::RespContextError; + + Server_Card *card = zone->getCard(cmd.card_id()); + if (!card) + return Response::RespNameNotFound; + + const bool faceDown = cmd.face_down(); + if (faceDown == card->getFaceDown()) + return Response::RespContextError; + + card->setFaceDown(faceDown); + + Event_FlipCard event; + event.set_zone_name(zone->getName().toStdString()); + event.set_card_id(card->getId()); + if (!faceDown) + event.set_card_name(card->getName().toStdString()); + event.set_face_down(faceDown); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdAttachCard(const Command_AttachCard &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - Server_CardZone *startzone = zones.value(QString::fromStdString(cmd.start_zone())); - if (!startzone) - return Response::RespNameNotFound; - - Server_Card *card = startzone->getCard(cmd.card_id()); - if (!card) - return Response::RespNameNotFound; + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_CardZone *startzone = zones.value(QString::fromStdString(cmd.start_zone())); + if (!startzone) + return Response::RespNameNotFound; + + Server_Card *card = startzone->getCard(cmd.card_id()); + if (!card) + return Response::RespNameNotFound; - Server_Player *targetPlayer = 0; - Server_CardZone *targetzone = 0; - Server_Card *targetCard = 0; - - if (cmd.has_target_player_id()) { - targetPlayer = game->getPlayers().value(cmd.target_player_id()); - if (!targetPlayer) - return Response::RespNameNotFound; - } else if (!card->getParentCard()) - return Response::RespContextError; - if (targetPlayer) - targetzone = targetPlayer->getZones().value(QString::fromStdString(cmd.target_zone())); - if (targetzone) { - // This is currently enough to make sure cards don't get attached to a card that is not on the table. - // Possibly a flag will have to be introduced for this sometime. - if (!targetzone->hasCoords()) - return Response::RespContextError; - if (cmd.has_target_card_id()) - targetCard = targetzone->getCard(cmd.target_card_id()); - if (targetCard) { - if (targetCard->getParentCard()) - return Response::RespContextError; - } else - return Response::RespNameNotFound; - } - if (!startzone->hasCoords()) - return Response::RespContextError; - - // Get all arrows pointing to or originating from the card being attached and delete them. - QMapIterator playerIterator(game->getPlayers()); - while (playerIterator.hasNext()) { - Server_Player *p = playerIterator.next().value(); - QList arrows = p->getArrows().values(); - QList toDelete; - for (int i = 0; i < arrows.size(); ++i) { - Server_Arrow *a = arrows[i]; - Server_Card *tCard = qobject_cast(a->getTargetItem()); - if ((tCard == card) || (a->getStartCard() == card)) - toDelete.append(a); - } - for (int i = 0; i < toDelete.size(); ++i) { - Event_DeleteArrow event; - event.set_arrow_id(toDelete[i]->getId()); - ges.enqueueGameEvent(event, p->getPlayerId()); - p->deleteArrow(toDelete[i]->getId()); - } - } + Server_Player *targetPlayer = 0; + Server_CardZone *targetzone = 0; + Server_Card *targetCard = 0; + + if (cmd.has_target_player_id()) { + targetPlayer = game->getPlayers().value(cmd.target_player_id()); + if (!targetPlayer) + return Response::RespNameNotFound; + } else if (!card->getParentCard()) + return Response::RespContextError; + if (targetPlayer) + targetzone = targetPlayer->getZones().value(QString::fromStdString(cmd.target_zone())); + if (targetzone) { + // This is currently enough to make sure cards don't get attached to a card that is not on the table. + // Possibly a flag will have to be introduced for this sometime. + if (!targetzone->hasCoords()) + return Response::RespContextError; + if (cmd.has_target_card_id()) + targetCard = targetzone->getCard(cmd.target_card_id()); + if (targetCard) { + if (targetCard->getParentCard()) + return Response::RespContextError; + } else + return Response::RespNameNotFound; + } + if (!startzone->hasCoords()) + return Response::RespContextError; + + // Get all arrows pointing to or originating from the card being attached and delete them. + QMapIterator playerIterator(game->getPlayers()); + while (playerIterator.hasNext()) { + Server_Player *p = playerIterator.next().value(); + QList arrows = p->getArrows().values(); + QList toDelete; + for (int i = 0; i < arrows.size(); ++i) { + Server_Arrow *a = arrows[i]; + Server_Card *tCard = qobject_cast(a->getTargetItem()); + if ((tCard == card) || (a->getStartCard() == card)) + toDelete.append(a); + } + for (int i = 0; i < toDelete.size(); ++i) { + Event_DeleteArrow event; + event.set_arrow_id(toDelete[i]->getId()); + ges.enqueueGameEvent(event, p->getPlayerId()); + p->deleteArrow(toDelete[i]->getId()); + } + } - if (targetCard) { - // Unattach all cards attached to the card being attached. - // Make a copy of the list because its contents change during the loop otherwise. - QList attachedList = card->getAttachedCards(); - for (int i = 0; i < attachedList.size(); ++i) - attachedList[i]->getZone()->getPlayer()->unattachCard(ges, attachedList[i]); - - card->setParentCard(targetCard); - const int oldX = card->getX(); - card->setCoords(-1, card->getY()); - startzone->updateCardCoordinates(card, oldX, card->getY()); - - if (targetzone->isColumnStacked(targetCard->getX(), targetCard->getY())) { - CardToMove *cardToMove = new CardToMove; - cardToMove->set_card_id(targetCard->getId()); - targetPlayer->moveCard(ges, targetzone, QList() << cardToMove, targetzone, targetzone->getFreeGridColumn(-2, targetCard->getY(), targetCard->getName()), targetCard->getY(), targetCard->getFaceDown()); - delete cardToMove; - } - - Event_AttachCard event; - event.set_start_zone(startzone->getName().toStdString()); - event.set_card_id(card->getId()); - event.set_target_player_id(targetPlayer->getPlayerId()); - event.set_target_zone(targetzone->getName().toStdString()); - event.set_target_card_id(targetCard->getId()); - ges.enqueueGameEvent(event, playerId); - - startzone->fixFreeSpaces(ges); - } else - unattachCard(ges, card); - - return Response::RespOk; + if (targetCard) { + // Unattach all cards attached to the card being attached. + // Make a copy of the list because its contents change during the loop otherwise. + QList attachedList = card->getAttachedCards(); + for (int i = 0; i < attachedList.size(); ++i) + attachedList[i]->getZone()->getPlayer()->unattachCard(ges, attachedList[i]); + + card->setParentCard(targetCard); + const int oldX = card->getX(); + card->setCoords(-1, card->getY()); + startzone->updateCardCoordinates(card, oldX, card->getY()); + + if (targetzone->isColumnStacked(targetCard->getX(), targetCard->getY())) { + CardToMove *cardToMove = new CardToMove; + cardToMove->set_card_id(targetCard->getId()); + targetPlayer->moveCard(ges, targetzone, QList() << cardToMove, targetzone, targetzone->getFreeGridColumn(-2, targetCard->getY(), targetCard->getName()), targetCard->getY(), targetCard->getFaceDown()); + delete cardToMove; + } + + Event_AttachCard event; + event.set_start_zone(startzone->getName().toStdString()); + event.set_card_id(card->getId()); + event.set_target_player_id(targetPlayer->getPlayerId()); + event.set_target_zone(targetzone->getName().toStdString()); + event.set_target_card_id(targetCard->getId()); + ges.enqueueGameEvent(event, playerId); + + startzone->fixFreeSpaces(ges); + } else + unattachCard(ges, card); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdCreateToken(const Command_CreateToken &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - Server_CardZone *zone = zones.value(QString::fromStdString(cmd.zone())); - if (!zone) - return Response::RespNameNotFound; + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_CardZone *zone = zones.value(QString::fromStdString(cmd.zone())); + if (!zone) + return Response::RespNameNotFound; - QString cardName = QString::fromStdString(cmd.card_name()); - int x = cmd.x(); - int y = cmd.y(); - if (zone->hasCoords()) - x = zone->getFreeGridColumn(x, y, cardName); - if (x < 0) - x = 0; - if (y < 0) - y = 0; + QString cardName = QString::fromStdString(cmd.card_name()); + int x = cmd.x(); + int y = cmd.y(); + if (zone->hasCoords()) + x = zone->getFreeGridColumn(x, y, cardName); + if (x < 0) + x = 0; + if (y < 0) + y = 0; - Server_Card *card = new Server_Card(cardName, newCardId(), x, y); - card->moveToThread(thread()); - card->setPT(QString::fromStdString(cmd.pt())); - card->setColor(QString::fromStdString(cmd.color())); - card->setAnnotation(QString::fromStdString(cmd.annotation())); - card->setDestroyOnZoneChange(cmd.destroy_on_zone_change()); - - zone->insertCard(card, x, y); - - Event_CreateToken event; - event.set_zone_name(zone->getName().toStdString()); - event.set_card_id(card->getId()); - event.set_card_name(card->getName().toStdString()); - event.set_color(card->getColor().toStdString()); - event.set_pt(card->getPT().toStdString()); - event.set_annotation(card->getAnnotation().toStdString()); - event.set_destroy_on_zone_change(card->getDestroyOnZoneChange()); - event.set_x(x); - event.set_y(y); - ges.enqueueGameEvent(event, playerId); - - return Response::RespOk; + Server_Card *card = new Server_Card(cardName, newCardId(), x, y); + card->moveToThread(thread()); + card->setPT(QString::fromStdString(cmd.pt())); + card->setColor(QString::fromStdString(cmd.color())); + card->setAnnotation(QString::fromStdString(cmd.annotation())); + card->setDestroyOnZoneChange(cmd.destroy_on_zone_change()); + + zone->insertCard(card, x, y); + + Event_CreateToken event; + event.set_zone_name(zone->getName().toStdString()); + event.set_card_id(card->getId()); + event.set_card_name(card->getName().toStdString()); + event.set_color(card->getColor().toStdString()); + event.set_pt(card->getPT().toStdString()); + event.set_annotation(card->getAnnotation().toStdString()); + event.set_destroy_on_zone_change(card->getDestroyOnZoneChange()); + event.set_x(x); + event.set_y(y); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdCreateArrow(const Command_CreateArrow &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - Server_Player *startPlayer = game->getPlayers().value(cmd.start_player_id()); - Server_Player *targetPlayer = game->getPlayers().value(cmd.target_player_id()); - if (!startPlayer || !targetPlayer) - return Response::RespNameNotFound; - QString startZoneName = QString::fromStdString(cmd.start_zone()); - Server_CardZone *startZone = startPlayer->getZones().value(startZoneName); - bool playerTarget = !cmd.has_target_zone(); - Server_CardZone *targetZone = 0; - if (!playerTarget) - targetZone = targetPlayer->getZones().value(QString::fromStdString(cmd.target_zone())); - if (!startZone || (!targetZone && !playerTarget)) - return Response::RespNameNotFound; - if (startZone->getType() != ServerInfo_Zone::PublicZone) - return Response::RespContextError; - Server_Card *startCard = startZone->getCard(cmd.start_card_id()); - if (!startCard) - return Response::RespNameNotFound; - Server_Card *targetCard = 0; - if (!playerTarget) { - if (targetZone->getType() != ServerInfo_Zone::PublicZone) - return Response::RespContextError; - targetCard = targetZone->getCard(cmd.target_card_id()); - } - - Server_ArrowTarget *targetItem; - if (playerTarget) - targetItem = targetPlayer; - else - targetItem = targetCard; - if (!targetItem) - return Response::RespNameNotFound; + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_Player *startPlayer = game->getPlayers().value(cmd.start_player_id()); + Server_Player *targetPlayer = game->getPlayers().value(cmd.target_player_id()); + if (!startPlayer || !targetPlayer) + return Response::RespNameNotFound; + QString startZoneName = QString::fromStdString(cmd.start_zone()); + Server_CardZone *startZone = startPlayer->getZones().value(startZoneName); + bool playerTarget = !cmd.has_target_zone(); + Server_CardZone *targetZone = 0; + if (!playerTarget) + targetZone = targetPlayer->getZones().value(QString::fromStdString(cmd.target_zone())); + if (!startZone || (!targetZone && !playerTarget)) + return Response::RespNameNotFound; + if (startZone->getType() != ServerInfo_Zone::PublicZone) + return Response::RespContextError; + Server_Card *startCard = startZone->getCard(cmd.start_card_id()); + if (!startCard) + return Response::RespNameNotFound; + Server_Card *targetCard = 0; + if (!playerTarget) { + if (targetZone->getType() != ServerInfo_Zone::PublicZone) + return Response::RespContextError; + targetCard = targetZone->getCard(cmd.target_card_id()); + } + + Server_ArrowTarget *targetItem; + if (playerTarget) + targetItem = targetPlayer; + else + targetItem = targetCard; + if (!targetItem) + return Response::RespNameNotFound; - QMapIterator arrowIterator(arrows); - while (arrowIterator.hasNext()) { - Server_Arrow *temp = arrowIterator.next().value(); - if ((temp->getStartCard() == startCard) && (temp->getTargetItem() == targetItem)) - return Response::RespContextError; - } - - Server_Arrow *arrow = new Server_Arrow(newArrowId(), startCard, targetItem, cmd.arrow_color()); - addArrow(arrow); - - Event_CreateArrow event; - ServerInfo_Arrow *arrowInfo = event.mutable_arrow_info(); - arrowInfo->set_id(arrow->getId()); - arrowInfo->set_start_player_id(startPlayer->getPlayerId()); - arrowInfo->set_start_zone(startZoneName.toStdString()); - arrowInfo->set_start_card_id(startCard->getId()); - arrowInfo->set_target_player_id(targetPlayer->getPlayerId()); - if (!playerTarget) { - arrowInfo->set_target_zone(cmd.target_zone()); - arrowInfo->set_target_card_id(cmd.target_card_id()); - } - arrowInfo->mutable_arrow_color()->CopyFrom(cmd.arrow_color()); - ges.enqueueGameEvent(event, playerId); - - return Response::RespOk; + QMapIterator arrowIterator(arrows); + while (arrowIterator.hasNext()) { + Server_Arrow *temp = arrowIterator.next().value(); + if ((temp->getStartCard() == startCard) && (temp->getTargetItem() == targetItem)) + return Response::RespContextError; + } + + Server_Arrow *arrow = new Server_Arrow(newArrowId(), startCard, targetItem, cmd.arrow_color()); + addArrow(arrow); + + Event_CreateArrow event; + ServerInfo_Arrow *arrowInfo = event.mutable_arrow_info(); + arrowInfo->set_id(arrow->getId()); + arrowInfo->set_start_player_id(startPlayer->getPlayerId()); + arrowInfo->set_start_zone(startZoneName.toStdString()); + arrowInfo->set_start_card_id(startCard->getId()); + arrowInfo->set_target_player_id(targetPlayer->getPlayerId()); + if (!playerTarget) { + arrowInfo->set_target_zone(cmd.target_zone()); + arrowInfo->set_target_card_id(cmd.target_card_id()); + } + arrowInfo->mutable_arrow_color()->CopyFrom(cmd.arrow_color()); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdDeleteArrow(const Command_DeleteArrow &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - if (!deleteArrow(cmd.arrow_id())) - return Response::RespNameNotFound; - - Event_DeleteArrow event; - event.set_arrow_id(cmd.arrow_id()); - ges.enqueueGameEvent(event, playerId); - - return Response::RespOk; + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + if (!deleteArrow(cmd.arrow_id())) + return Response::RespNameNotFound; + + Event_DeleteArrow event; + event.set_arrow_id(cmd.arrow_id()); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdSetCardAttr(const Command_SetCardAttr &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - return setCardAttrHelper(ges, QString::fromStdString(cmd.zone()), cmd.card_id(), cmd.attribute(), QString::fromStdString(cmd.attr_value())); + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + return setCardAttrHelper(ges, QString::fromStdString(cmd.zone()), cmd.card_id(), cmd.attribute(), QString::fromStdString(cmd.attr_value())); } Response::ResponseCode Server_Player::cmdSetCardCounter(const Command_SetCardCounter &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - Server_CardZone *zone = zones.value(QString::fromStdString(cmd.zone())); - if (!zone) - return Response::RespNameNotFound; - if (!zone->hasCoords()) - return Response::RespContextError; + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_CardZone *zone = zones.value(QString::fromStdString(cmd.zone())); + if (!zone) + return Response::RespNameNotFound; + if (!zone->hasCoords()) + return Response::RespContextError; - Server_Card *card = zone->getCard(cmd.card_id()); - if (!card) - return Response::RespNameNotFound; - - card->setCounter(cmd.counter_id(), cmd.counter_value()); - - Event_SetCardCounter event; - event.set_zone_name(zone->getName().toStdString()); - event.set_card_id(card->getId()); - event.set_counter_id(cmd.counter_id()); - event.set_counter_value(cmd.counter_value()); - ges.enqueueGameEvent(event, playerId); - - return Response::RespOk; + Server_Card *card = zone->getCard(cmd.card_id()); + if (!card) + return Response::RespNameNotFound; + + card->setCounter(cmd.counter_id(), cmd.counter_value()); + + Event_SetCardCounter event; + event.set_zone_name(zone->getName().toStdString()); + event.set_card_id(card->getId()); + event.set_counter_id(cmd.counter_id()); + event.set_counter_value(cmd.counter_value()); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdIncCardCounter(const Command_IncCardCounter &cmd, ResponseContainer &/*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - Server_CardZone *zone = zones.value(QString::fromStdString(cmd.zone())); - if (!zone) - return Response::RespNameNotFound; - if (!zone->hasCoords()) - return Response::RespContextError; + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_CardZone *zone = zones.value(QString::fromStdString(cmd.zone())); + if (!zone) + return Response::RespNameNotFound; + if (!zone->hasCoords()) + return Response::RespContextError; - Server_Card *card = zone->getCard(cmd.card_id()); - if (!card) - return Response::RespNameNotFound; - - int newValue = card->getCounter(cmd.counter_id()) + cmd.counter_delta(); - card->setCounter(cmd.counter_id(), newValue); - - Event_SetCardCounter event; - event.set_zone_name(zone->getName().toStdString()); - event.set_card_id(card->getId()); - event.set_counter_id(cmd.counter_id()); - event.set_counter_value(newValue); - ges.enqueueGameEvent(event, playerId); - - return Response::RespOk; + Server_Card *card = zone->getCard(cmd.card_id()); + if (!card) + return Response::RespNameNotFound; + + int newValue = card->getCounter(cmd.counter_id()) + cmd.counter_delta(); + card->setCounter(cmd.counter_id(), newValue); + + Event_SetCardCounter event; + event.set_zone_name(zone->getName().toStdString()); + event.set_card_id(card->getId()); + event.set_counter_id(cmd.counter_id()); + event.set_counter_value(newValue); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdIncCounter(const Command_IncCounter &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - Server_Counter *c = counters.value(cmd.counter_id(), 0); - if (!c) - return Response::RespNameNotFound; - - c->setCount(c->getCount() + cmd.delta()); - - Event_SetCounter event; - event.set_counter_id(c->getId()); - event.set_value(c->getCount()); - ges.enqueueGameEvent(event, playerId); - - return Response::RespOk; + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_Counter *c = counters.value(cmd.counter_id(), 0); + if (!c) + return Response::RespNameNotFound; + + c->setCount(c->getCount() + cmd.delta()); + + Event_SetCounter event; + event.set_counter_id(c->getId()); + event.set_value(c->getCount()); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdCreateCounter(const Command_CreateCounter &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - Server_Counter *c = new Server_Counter(newCounterId(), QString::fromStdString(cmd.counter_name()), cmd.counter_color(), cmd.radius(), cmd.value()); - addCounter(c); - - Event_CreateCounter event; - ServerInfo_Counter *counterInfo = event.mutable_counter_info(); - counterInfo->set_id(c->getId()); - counterInfo->set_name(c->getName().toStdString()); - counterInfo->mutable_counter_color()->CopyFrom(cmd.counter_color()); - counterInfo->set_radius(c->getRadius()); - counterInfo->set_count(c->getCount()); - ges.enqueueGameEvent(event, playerId); - - return Response::RespOk; + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_Counter *c = new Server_Counter(newCounterId(), QString::fromStdString(cmd.counter_name()), cmd.counter_color(), cmd.radius(), cmd.value()); + addCounter(c); + + Event_CreateCounter event; + ServerInfo_Counter *counterInfo = event.mutable_counter_info(); + counterInfo->set_id(c->getId()); + counterInfo->set_name(c->getName().toStdString()); + counterInfo->mutable_counter_color()->CopyFrom(cmd.counter_color()); + counterInfo->set_radius(c->getRadius()); + counterInfo->set_count(c->getCount()); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdSetCounter(const Command_SetCounter &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - Server_Counter *c = counters.value(cmd.counter_id(), 0);; - if (!c) - return Response::RespNameNotFound; - - c->setCount(cmd.value()); - - Event_SetCounter event; - event.set_counter_id(c->getId()); - event.set_value(c->getCount()); - ges.enqueueGameEvent(event, playerId); - - return Response::RespOk; + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_Counter *c = counters.value(cmd.counter_id(), 0);; + if (!c) + return Response::RespNameNotFound; + + c->setCount(cmd.value()); + + Event_SetCounter event; + event.set_counter_id(c->getId()); + event.set_value(c->getCount()); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdDelCounter(const Command_DelCounter &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - Server_Counter *counter = counters.value(cmd.counter_id(), 0); - if (!counter) - return Response::RespNameNotFound; - counters.remove(cmd.counter_id()); - delete counter; - - Event_DelCounter event; - event.set_counter_id(cmd.counter_id()); - ges.enqueueGameEvent(event, playerId); - - return Response::RespOk; + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_Counter *counter = counters.value(cmd.counter_id(), 0); + if (!counter) + return Response::RespNameNotFound; + counters.remove(cmd.counter_id()); + delete counter; + + Event_DelCounter event; + event.set_counter_id(cmd.counter_id()); + ges.enqueueGameEvent(event, playerId); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdNextTurn(const Command_NextTurn & /*cmd*/, ResponseContainer & /*rc*/, GameEventStorage & /*ges*/) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - game->nextTurn(); - return Response::RespOk; + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + game->nextTurn(); + return Response::RespOk; } Response::ResponseCode Server_Player::cmdSetActivePhase(const Command_SetActivePhase &cmd, ResponseContainer & /*rc*/, GameEventStorage & /*ges*/) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - if (game->getActivePlayer() != playerId) - return Response::RespContextError; - game->setActivePhase(cmd.phase()); - - return Response::RespOk; + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + if (game->getActivePlayer() != playerId) + return Response::RespContextError; + game->setActivePhase(cmd.phase()); + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdDumpZone(const Command_DumpZone &cmd, ResponseContainer &rc, GameEventStorage &ges) { - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - - Server_Player *otherPlayer = game->getPlayers().value(cmd.player_id()); - if (!otherPlayer) - return Response::RespNameNotFound; - Server_CardZone *zone = otherPlayer->getZones().value(QString::fromStdString(cmd.zone_name())); - if (!zone) - return Response::RespNameNotFound; - if (!((zone->getType() == ServerInfo_Zone::PublicZone) || (this == otherPlayer))) - return Response::RespContextError; - - int numberCards = cmd.number_cards(); - const QList &cards = zone->getCards(); - - Response_DumpZone *re = new Response_DumpZone; - ServerInfo_Zone *zoneInfo = re->mutable_zone_info(); - zoneInfo->set_name(zone->getName().toStdString()); - zoneInfo->set_type(zone->getType()); - zoneInfo->set_with_coords(zone->hasCoords()); - zoneInfo->set_card_count(numberCards < cards.size() ? cards.size() : numberCards); - - for (int i = 0; (i < cards.size()) && (i < numberCards || numberCards == -1); ++i) { - Server_Card *card = cards[i]; - QString displayedName = card->getFaceDown() ? QString() : card->getName(); - ServerInfo_Card *cardInfo = zoneInfo->add_card_list(); - cardInfo->set_name(displayedName.toStdString()); - if (zone->getType() == ServerInfo_Zone::HiddenZone) - cardInfo->set_id(i); - else { - cardInfo->set_id(card->getId()); - cardInfo->set_x(card->getX()); - cardInfo->set_y(card->getY()); - cardInfo->set_face_down(card->getFaceDown()); - cardInfo->set_tapped(card->getTapped()); - cardInfo->set_attacking(card->getAttacking()); - cardInfo->set_color(card->getColor().toStdString()); - cardInfo->set_pt(card->getPT().toStdString()); - cardInfo->set_annotation(card->getAnnotation().toStdString()); - cardInfo->set_destroy_on_zone_change(card->getDestroyOnZoneChange()); - cardInfo->set_doesnt_untap(card->getDoesntUntap()); - - QMapIterator cardCounterIterator(card->getCounters()); - while (cardCounterIterator.hasNext()) { - cardCounterIterator.next(); - ServerInfo_CardCounter *counterInfo = cardInfo->add_counter_list(); - counterInfo->set_id(cardCounterIterator.key()); - counterInfo->set_value(cardCounterIterator.value()); - } + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + + Server_Player *otherPlayer = game->getPlayers().value(cmd.player_id()); + if (!otherPlayer) + return Response::RespNameNotFound; + Server_CardZone *zone = otherPlayer->getZones().value(QString::fromStdString(cmd.zone_name())); + if (!zone) + return Response::RespNameNotFound; + if (!((zone->getType() == ServerInfo_Zone::PublicZone) || (this == otherPlayer))) + return Response::RespContextError; + + int numberCards = cmd.number_cards(); + const QList &cards = zone->getCards(); + + Response_DumpZone *re = new Response_DumpZone; + ServerInfo_Zone *zoneInfo = re->mutable_zone_info(); + zoneInfo->set_name(zone->getName().toStdString()); + zoneInfo->set_type(zone->getType()); + zoneInfo->set_with_coords(zone->hasCoords()); + zoneInfo->set_card_count(numberCards < cards.size() ? cards.size() : numberCards); + + for (int i = 0; (i < cards.size()) && (i < numberCards || numberCards == -1); ++i) { + Server_Card *card = cards[i]; + QString displayedName = card->getFaceDown() ? QString() : card->getName(); + ServerInfo_Card *cardInfo = zoneInfo->add_card_list(); + cardInfo->set_name(displayedName.toStdString()); + if (zone->getType() == ServerInfo_Zone::HiddenZone) + cardInfo->set_id(i); + else { + cardInfo->set_id(card->getId()); + cardInfo->set_x(card->getX()); + cardInfo->set_y(card->getY()); + cardInfo->set_face_down(card->getFaceDown()); + cardInfo->set_tapped(card->getTapped()); + cardInfo->set_attacking(card->getAttacking()); + cardInfo->set_color(card->getColor().toStdString()); + cardInfo->set_pt(card->getPT().toStdString()); + cardInfo->set_annotation(card->getAnnotation().toStdString()); + cardInfo->set_destroy_on_zone_change(card->getDestroyOnZoneChange()); + cardInfo->set_doesnt_untap(card->getDoesntUntap()); + + QMapIterator cardCounterIterator(card->getCounters()); + while (cardCounterIterator.hasNext()) { + cardCounterIterator.next(); + ServerInfo_CardCounter *counterInfo = cardInfo->add_counter_list(); + counterInfo->set_id(cardCounterIterator.key()); + counterInfo->set_value(cardCounterIterator.value()); + } - if (card->getParentCard()) { - cardInfo->set_attach_player_id(card->getParentCard()->getZone()->getPlayer()->getPlayerId()); - cardInfo->set_attach_zone(card->getParentCard()->getZone()->getName().toStdString()); - cardInfo->set_attach_card_id(card->getParentCard()->getId()); - } - } - } - if (zone->getType() == ServerInfo_Zone::HiddenZone) { - zone->setCardsBeingLookedAt(numberCards); - - Event_DumpZone event; - event.set_zone_owner_id(otherPlayer->getPlayerId()); - event.set_zone_name(zone->getName().toStdString()); - event.set_number_cards(numberCards); - ges.enqueueGameEvent(event, playerId); - } - rc.setResponseExtension(re); - return Response::RespOk; + if (card->getParentCard()) { + cardInfo->set_attach_player_id(card->getParentCard()->getZone()->getPlayer()->getPlayerId()); + cardInfo->set_attach_zone(card->getParentCard()->getZone()->getName().toStdString()); + cardInfo->set_attach_card_id(card->getParentCard()->getId()); + } + } + } + if (zone->getType() == ServerInfo_Zone::HiddenZone) { + zone->setCardsBeingLookedAt(numberCards); + + Event_DumpZone event; + event.set_zone_owner_id(otherPlayer->getPlayerId()); + event.set_zone_name(zone->getName().toStdString()); + event.set_number_cards(numberCards); + ges.enqueueGameEvent(event, playerId); + } + rc.setResponseExtension(re); + return Response::RespOk; } Response::ResponseCode Server_Player::cmdStopDumpZone(const Command_StopDumpZone &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - Server_Player *otherPlayer = game->getPlayers().value(cmd.player_id()); - if (!otherPlayer) - return Response::RespNameNotFound; - Server_CardZone *zone = otherPlayer->getZones().value(QString::fromStdString(cmd.zone_name())); - if (!zone) - return Response::RespNameNotFound; - - if (zone->getType() == ServerInfo_Zone::HiddenZone) { - zone->setCardsBeingLookedAt(0); - - Event_StopDumpZone event; - event.set_zone_owner_id(cmd.player_id()); - event.set_zone_name(zone->getName().toStdString()); - ges.enqueueGameEvent(event, playerId); - } - return Response::RespOk; + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_Player *otherPlayer = game->getPlayers().value(cmd.player_id()); + if (!otherPlayer) + return Response::RespNameNotFound; + Server_CardZone *zone = otherPlayer->getZones().value(QString::fromStdString(cmd.zone_name())); + if (!zone) + return Response::RespNameNotFound; + + if (zone->getType() == ServerInfo_Zone::HiddenZone) { + zone->setCardsBeingLookedAt(0); + + Event_StopDumpZone event; + event.set_zone_owner_id(cmd.player_id()); + event.set_zone_name(zone->getName().toStdString()); + ges.enqueueGameEvent(event, playerId); + } + return Response::RespOk; } Response::ResponseCode Server_Player::cmdRevealCards(const Command_RevealCards &cmd, ResponseContainer & /*rc*/, GameEventStorage &ges) { - if (spectator) - return Response::RespFunctionNotAllowed; - - if (!game->getGameStarted()) - return Response::RespGameNotStarted; - if (conceded) - return Response::RespContextError; - - Server_Player *otherPlayer = 0; - if (cmd.has_player_id()) { - otherPlayer = game->getPlayers().value(cmd.player_id()); - if (!otherPlayer) - return Response::RespNameNotFound; - } - Server_CardZone *zone = zones.value(QString::fromStdString(cmd.zone_name())); - if (!zone) - return Response::RespNameNotFound; - - QList cardsToReveal; - if (!cmd.has_card_id()) - cardsToReveal = zone->getCards(); - else if (cmd.card_id() == -2) { - if (zone->getCards().isEmpty()) - return Response::RespContextError; - cardsToReveal.append(zone->getCards().at(rng->rand(0, zone->getCards().size() - 1))); - } else { - Server_Card *card = zone->getCard(cmd.card_id()); - if (!card) - return Response::RespNameNotFound; - cardsToReveal.append(card); - } - - Event_RevealCards eventOthers; - eventOthers.set_grant_write_access(cmd.grant_write_access()); - eventOthers.set_zone_name(zone->getName().toStdString()); - if (cmd.has_card_id()) - eventOthers.set_card_id(cmd.card_id()); - if (cmd.has_player_id()) - eventOthers.set_other_player_id(cmd.player_id()); - - Event_RevealCards eventPrivate(eventOthers); - - for (int i = 0; i < cardsToReveal.size(); ++i) { - Server_Card *card = cardsToReveal[i]; - ServerInfo_Card *cardInfo = eventPrivate.add_cards(); + if (spectator) + return Response::RespFunctionNotAllowed; + + if (!game->getGameStarted()) + return Response::RespGameNotStarted; + if (conceded) + return Response::RespContextError; + + Server_Player *otherPlayer = 0; + if (cmd.has_player_id()) { + otherPlayer = game->getPlayers().value(cmd.player_id()); + if (!otherPlayer) + return Response::RespNameNotFound; + } + Server_CardZone *zone = zones.value(QString::fromStdString(cmd.zone_name())); + if (!zone) + return Response::RespNameNotFound; + + QList cardsToReveal; + if (!cmd.has_card_id()) + cardsToReveal = zone->getCards(); + else if (cmd.card_id() == -2) { + if (zone->getCards().isEmpty()) + return Response::RespContextError; + cardsToReveal.append(zone->getCards().at(rng->rand(0, zone->getCards().size() - 1))); + } else { + Server_Card *card = zone->getCard(cmd.card_id()); + if (!card) + return Response::RespNameNotFound; + cardsToReveal.append(card); + } + + Event_RevealCards eventOthers; + eventOthers.set_grant_write_access(cmd.grant_write_access()); + eventOthers.set_zone_name(zone->getName().toStdString()); + if (cmd.has_card_id()) + eventOthers.set_card_id(cmd.card_id()); + if (cmd.has_player_id()) + eventOthers.set_other_player_id(cmd.player_id()); + + Event_RevealCards eventPrivate(eventOthers); + + for (int i = 0; i < cardsToReveal.size(); ++i) { + Server_Card *card = cardsToReveal[i]; + ServerInfo_Card *cardInfo = eventPrivate.add_cards(); - cardInfo->set_id(card->getId()); - cardInfo->set_name(card->getName().toStdString()); - cardInfo->set_x(card->getX()); - cardInfo->set_y(card->getY()); - cardInfo->set_face_down(card->getFaceDown()); - cardInfo->set_tapped(card->getTapped()); - cardInfo->set_attacking(card->getAttacking()); - cardInfo->set_color(card->getColor().toStdString()); - cardInfo->set_pt(card->getPT().toStdString()); - cardInfo->set_annotation(card->getAnnotation().toStdString()); - cardInfo->set_destroy_on_zone_change(card->getDestroyOnZoneChange()); - cardInfo->set_doesnt_untap(card->getDoesntUntap()); - - QMapIterator cardCounterIterator(card->getCounters()); - while (cardCounterIterator.hasNext()) { - cardCounterIterator.next(); - ServerInfo_CardCounter *counterInfo = cardInfo->add_counter_list(); - counterInfo->set_id(cardCounterIterator.key()); - counterInfo->set_value(cardCounterIterator.value()); - } - - if (card->getParentCard()) { - cardInfo->set_attach_player_id(card->getParentCard()->getZone()->getPlayer()->getPlayerId()); - cardInfo->set_attach_zone(card->getParentCard()->getZone()->getName().toStdString()); - cardInfo->set_attach_card_id(card->getParentCard()->getId()); - } - } - - if (cmd.has_player_id()) { - if (cmd.grant_write_access()) - zone->addWritePermission(cmd.player_id()); - - ges.enqueueGameEvent(eventPrivate, playerId, GameEventStorageItem::SendToPrivate, cmd.player_id()); - ges.enqueueGameEvent(eventOthers, playerId, GameEventStorageItem::SendToOthers); - } else { - if (cmd.grant_write_access()) { - const QList &playerIds = game->getPlayers().keys(); - for (int i = 0; i < playerIds.size(); ++i) - zone->addWritePermission(playerIds[i]); - } - - ges.enqueueGameEvent(eventPrivate, playerId); - } - - return Response::RespOk; + cardInfo->set_id(card->getId()); + cardInfo->set_name(card->getName().toStdString()); + cardInfo->set_x(card->getX()); + cardInfo->set_y(card->getY()); + cardInfo->set_face_down(card->getFaceDown()); + cardInfo->set_tapped(card->getTapped()); + cardInfo->set_attacking(card->getAttacking()); + cardInfo->set_color(card->getColor().toStdString()); + cardInfo->set_pt(card->getPT().toStdString()); + cardInfo->set_annotation(card->getAnnotation().toStdString()); + cardInfo->set_destroy_on_zone_change(card->getDestroyOnZoneChange()); + cardInfo->set_doesnt_untap(card->getDoesntUntap()); + + QMapIterator cardCounterIterator(card->getCounters()); + while (cardCounterIterator.hasNext()) { + cardCounterIterator.next(); + ServerInfo_CardCounter *counterInfo = cardInfo->add_counter_list(); + counterInfo->set_id(cardCounterIterator.key()); + counterInfo->set_value(cardCounterIterator.value()); + } + + if (card->getParentCard()) { + cardInfo->set_attach_player_id(card->getParentCard()->getZone()->getPlayer()->getPlayerId()); + cardInfo->set_attach_zone(card->getParentCard()->getZone()->getName().toStdString()); + cardInfo->set_attach_card_id(card->getParentCard()->getId()); + } + } + + if (cmd.has_player_id()) { + if (cmd.grant_write_access()) + zone->addWritePermission(cmd.player_id()); + + ges.enqueueGameEvent(eventPrivate, playerId, GameEventStorageItem::SendToPrivate, cmd.player_id()); + ges.enqueueGameEvent(eventOthers, playerId, GameEventStorageItem::SendToOthers); + } else { + if (cmd.grant_write_access()) { + const QList &playerIds = game->getPlayers().keys(); + for (int i = 0; i < playerIds.size(); ++i) + zone->addWritePermission(playerIds[i]); + } + + ges.enqueueGameEvent(eventPrivate, playerId); + } + + return Response::RespOk; } Response::ResponseCode Server_Player::cmdChangeZoneProperties(const Command_ChangeZoneProperties &cmd, ResponseContainer &rc, GameEventStorage &ges) { - Server_CardZone *zone = zones.value(QString::fromStdString(cmd.zone_name())); - if (!zone) - return Response::RespNameNotFound; - - Event_ChangeZoneProperties event; - event.set_zone_name(cmd.zone_name()); - - if (cmd.has_always_reveal_top_card()) { - if (zone->getAlwaysRevealTopCard() == cmd.always_reveal_top_card()) - return Response::RespContextError; - zone->setAlwaysRevealTopCard(cmd.always_reveal_top_card()); - event.set_always_reveal_top_card(cmd.always_reveal_top_card()); - - ges.enqueueGameEvent(event, playerId); - - if (!zone->getCards().isEmpty() && cmd.always_reveal_top_card()) { - Event_RevealCards revealEvent; - revealEvent.set_zone_name(zone->getName().toStdString()); - revealEvent.set_card_id(0); - zone->getCards().first()->getInfo(revealEvent.add_cards()); - - ges.enqueueGameEvent(revealEvent, playerId); - } - return Response::RespOk; - } else - return Response::RespContextError; + Server_CardZone *zone = zones.value(QString::fromStdString(cmd.zone_name())); + if (!zone) + return Response::RespNameNotFound; + + Event_ChangeZoneProperties event; + event.set_zone_name(cmd.zone_name()); + + if (cmd.has_always_reveal_top_card()) { + if (zone->getAlwaysRevealTopCard() == cmd.always_reveal_top_card()) + return Response::RespContextError; + zone->setAlwaysRevealTopCard(cmd.always_reveal_top_card()); + event.set_always_reveal_top_card(cmd.always_reveal_top_card()); + + ges.enqueueGameEvent(event, playerId); + + if (!zone->getCards().isEmpty() && cmd.always_reveal_top_card()) { + Event_RevealCards revealEvent; + revealEvent.set_zone_name(zone->getName().toStdString()); + revealEvent.set_card_id(0); + zone->getCards().first()->getInfo(revealEvent.add_cards()); + + ges.enqueueGameEvent(revealEvent, playerId); + } + return Response::RespOk; + } else + return Response::RespContextError; } Response::ResponseCode Server_Player::processGameCommand(const GameCommand &command, ResponseContainer &rc, GameEventStorage &ges) { - switch ((GameCommand::GameCommandType) getPbExtension(command)) { - case GameCommand::KICK_FROM_GAME: return cmdKickFromGame(command.GetExtension(Command_KickFromGame::ext), rc, ges); break; - case GameCommand::LEAVE_GAME: return cmdLeaveGame(command.GetExtension(Command_LeaveGame::ext), rc, ges); break; - case GameCommand::GAME_SAY: return cmdGameSay(command.GetExtension(Command_GameSay::ext), rc, ges); break; - case GameCommand::SHUFFLE: return cmdShuffle(command.GetExtension(Command_Shuffle::ext), rc, ges); break; - case GameCommand::MULLIGAN: return cmdMulligan(command.GetExtension(Command_Mulligan::ext), rc, ges); break; - case GameCommand::ROLL_DIE: return cmdRollDie(command.GetExtension(Command_RollDie::ext), rc, ges); break; - case GameCommand::DRAW_CARDS: return cmdDrawCards(command.GetExtension(Command_DrawCards::ext), rc, ges); break; - case GameCommand::UNDO_DRAW: return cmdUndoDraw(command.GetExtension(Command_UndoDraw::ext), rc, ges); break; - case GameCommand::FLIP_CARD: return cmdFlipCard(command.GetExtension(Command_FlipCard::ext), rc, ges); break; - case GameCommand::ATTACH_CARD: return cmdAttachCard(command.GetExtension(Command_AttachCard::ext), rc, ges); break; - case GameCommand::CREATE_TOKEN: return cmdCreateToken(command.GetExtension(Command_CreateToken::ext), rc, ges); break; - case GameCommand::CREATE_ARROW: return cmdCreateArrow(command.GetExtension(Command_CreateArrow::ext), rc, ges); break; - case GameCommand::DELETE_ARROW: return cmdDeleteArrow(command.GetExtension(Command_DeleteArrow::ext), rc, ges); break; - case GameCommand::SET_CARD_ATTR: return cmdSetCardAttr(command.GetExtension(Command_SetCardAttr::ext), rc, ges); break; - case GameCommand::SET_CARD_COUNTER: return cmdSetCardCounter(command.GetExtension(Command_SetCardCounter::ext), rc, ges); break; - case GameCommand::INC_CARD_COUNTER: return cmdIncCardCounter(command.GetExtension(Command_IncCardCounter::ext), rc, ges); break; - case GameCommand::READY_START: return cmdReadyStart(command.GetExtension(Command_ReadyStart::ext), rc, ges); break; - case GameCommand::CONCEDE: return cmdConcede(command.GetExtension(Command_Concede::ext), rc, ges); break; - case GameCommand::INC_COUNTER: return cmdIncCounter(command.GetExtension(Command_IncCounter::ext), rc, ges); break; - case GameCommand::CREATE_COUNTER: return cmdCreateCounter(command.GetExtension(Command_CreateCounter::ext), rc, ges); break; - case GameCommand::SET_COUNTER: return cmdSetCounter(command.GetExtension(Command_SetCounter::ext), rc, ges); break; - case GameCommand::DEL_COUNTER: return cmdDelCounter(command.GetExtension(Command_DelCounter::ext), rc, ges); break; - case GameCommand::NEXT_TURN: return cmdNextTurn(command.GetExtension(Command_NextTurn::ext), rc, ges); break; - case GameCommand::SET_ACTIVE_PHASE: return cmdSetActivePhase(command.GetExtension(Command_SetActivePhase::ext), rc, ges); break; - case GameCommand::DUMP_ZONE: return cmdDumpZone(command.GetExtension(Command_DumpZone::ext), rc, ges); break; - case GameCommand::STOP_DUMP_ZONE: return cmdStopDumpZone(command.GetExtension(Command_StopDumpZone::ext), rc, ges); break; - case GameCommand::REVEAL_CARDS: return cmdRevealCards(command.GetExtension(Command_RevealCards::ext), rc, ges); break; - case GameCommand::MOVE_CARD: return cmdMoveCard(command.GetExtension(Command_MoveCard::ext), rc, ges); break; - case GameCommand::SET_SIDEBOARD_PLAN: return cmdSetSideboardPlan(command.GetExtension(Command_SetSideboardPlan::ext), rc, ges); break; - case GameCommand::DECK_SELECT: return cmdDeckSelect(command.GetExtension(Command_DeckSelect::ext), rc, ges); break; - case GameCommand::SET_SIDEBOARD_LOCK: return cmdSetSideboardLock(command.GetExtension(Command_SetSideboardLock::ext), rc, ges); break; - case GameCommand::CHANGE_ZONE_PROPERTIES: return cmdChangeZoneProperties(command.GetExtension(Command_ChangeZoneProperties::ext), rc, ges); break; - default: return Response::RespInvalidCommand; - } + switch ((GameCommand::GameCommandType) getPbExtension(command)) { + case GameCommand::KICK_FROM_GAME: return cmdKickFromGame(command.GetExtension(Command_KickFromGame::ext), rc, ges); break; + case GameCommand::LEAVE_GAME: return cmdLeaveGame(command.GetExtension(Command_LeaveGame::ext), rc, ges); break; + case GameCommand::GAME_SAY: return cmdGameSay(command.GetExtension(Command_GameSay::ext), rc, ges); break; + case GameCommand::SHUFFLE: return cmdShuffle(command.GetExtension(Command_Shuffle::ext), rc, ges); break; + case GameCommand::MULLIGAN: return cmdMulligan(command.GetExtension(Command_Mulligan::ext), rc, ges); break; + case GameCommand::ROLL_DIE: return cmdRollDie(command.GetExtension(Command_RollDie::ext), rc, ges); break; + case GameCommand::DRAW_CARDS: return cmdDrawCards(command.GetExtension(Command_DrawCards::ext), rc, ges); break; + case GameCommand::UNDO_DRAW: return cmdUndoDraw(command.GetExtension(Command_UndoDraw::ext), rc, ges); break; + case GameCommand::FLIP_CARD: return cmdFlipCard(command.GetExtension(Command_FlipCard::ext), rc, ges); break; + case GameCommand::ATTACH_CARD: return cmdAttachCard(command.GetExtension(Command_AttachCard::ext), rc, ges); break; + case GameCommand::CREATE_TOKEN: return cmdCreateToken(command.GetExtension(Command_CreateToken::ext), rc, ges); break; + case GameCommand::CREATE_ARROW: return cmdCreateArrow(command.GetExtension(Command_CreateArrow::ext), rc, ges); break; + case GameCommand::DELETE_ARROW: return cmdDeleteArrow(command.GetExtension(Command_DeleteArrow::ext), rc, ges); break; + case GameCommand::SET_CARD_ATTR: return cmdSetCardAttr(command.GetExtension(Command_SetCardAttr::ext), rc, ges); break; + case GameCommand::SET_CARD_COUNTER: return cmdSetCardCounter(command.GetExtension(Command_SetCardCounter::ext), rc, ges); break; + case GameCommand::INC_CARD_COUNTER: return cmdIncCardCounter(command.GetExtension(Command_IncCardCounter::ext), rc, ges); break; + case GameCommand::READY_START: return cmdReadyStart(command.GetExtension(Command_ReadyStart::ext), rc, ges); break; + case GameCommand::CONCEDE: return cmdConcede(command.GetExtension(Command_Concede::ext), rc, ges); break; + case GameCommand::INC_COUNTER: return cmdIncCounter(command.GetExtension(Command_IncCounter::ext), rc, ges); break; + case GameCommand::CREATE_COUNTER: return cmdCreateCounter(command.GetExtension(Command_CreateCounter::ext), rc, ges); break; + case GameCommand::SET_COUNTER: return cmdSetCounter(command.GetExtension(Command_SetCounter::ext), rc, ges); break; + case GameCommand::DEL_COUNTER: return cmdDelCounter(command.GetExtension(Command_DelCounter::ext), rc, ges); break; + case GameCommand::NEXT_TURN: return cmdNextTurn(command.GetExtension(Command_NextTurn::ext), rc, ges); break; + case GameCommand::SET_ACTIVE_PHASE: return cmdSetActivePhase(command.GetExtension(Command_SetActivePhase::ext), rc, ges); break; + case GameCommand::DUMP_ZONE: return cmdDumpZone(command.GetExtension(Command_DumpZone::ext), rc, ges); break; + case GameCommand::STOP_DUMP_ZONE: return cmdStopDumpZone(command.GetExtension(Command_StopDumpZone::ext), rc, ges); break; + case GameCommand::REVEAL_CARDS: return cmdRevealCards(command.GetExtension(Command_RevealCards::ext), rc, ges); break; + case GameCommand::MOVE_CARD: return cmdMoveCard(command.GetExtension(Command_MoveCard::ext), rc, ges); break; + case GameCommand::SET_SIDEBOARD_PLAN: return cmdSetSideboardPlan(command.GetExtension(Command_SetSideboardPlan::ext), rc, ges); break; + case GameCommand::DECK_SELECT: return cmdDeckSelect(command.GetExtension(Command_DeckSelect::ext), rc, ges); break; + case GameCommand::SET_SIDEBOARD_LOCK: return cmdSetSideboardLock(command.GetExtension(Command_SetSideboardLock::ext), rc, ges); break; + case GameCommand::CHANGE_ZONE_PROPERTIES: return cmdChangeZoneProperties(command.GetExtension(Command_ChangeZoneProperties::ext), rc, ges); break; + default: return Response::RespInvalidCommand; + } } void Server_Player::sendGameEvent(const GameEventContainer &cont) { - QMutexLocker locker(&playerMutex); - - if (userInterface) - userInterface->sendProtocolItem(cont); + QMutexLocker locker(&playerMutex); + + if (userInterface) + userInterface->sendProtocolItem(cont); } void Server_Player::setUserInterface(Server_AbstractUserInterface *_userInterface) { - playerMutex.lock(); - userInterface = _userInterface; - playerMutex.unlock(); - - pingTime = _userInterface ? 0 : -1; - - Event_PlayerPropertiesChanged event; - event.mutable_player_properties()->set_ping_seconds(pingTime); - - GameEventStorage ges; - ges.setGameEventContext(Context_ConnectionStateChanged()); - ges.enqueueGameEvent(event, playerId); - ges.sendToGame(game); + playerMutex.lock(); + userInterface = _userInterface; + playerMutex.unlock(); + + pingTime = _userInterface ? 0 : -1; + + Event_PlayerPropertiesChanged event; + event.mutable_player_properties()->set_ping_seconds(pingTime); + + GameEventStorage ges; + ges.setGameEventContext(Context_ConnectionStateChanged()); + ges.enqueueGameEvent(event, playerId); + ges.sendToGame(game); } void Server_Player::disconnectClient() { - if (!(userInfo->user_level() & ServerInfo_User::IsRegistered) || spectator) - game->removePlayer(this); - else - setUserInterface(0); + if (!(userInfo->user_level() & ServerInfo_User::IsRegistered) || spectator) + game->removePlayer(this); + else + setUserInterface(0); } void Server_Player::getInfo(ServerInfo_Player *info, Server_Player *playerWhosAsking, bool omniscient, bool withUserInfo) { - getProperties(*info->mutable_properties(), withUserInfo); - if (playerWhosAsking == this) - if (deck) - info->set_deck_list(deck->writeToString_Native().toStdString()); - - QMapIterator arrowIterator(arrows); - while (arrowIterator.hasNext()) - arrowIterator.next().value()->getInfo(info->add_arrow_list()); - - QMapIterator counterIterator(counters); - while (counterIterator.hasNext()) - counterIterator.next().value()->getInfo(info->add_counter_list()); - - QMapIterator zoneIterator(zones); - while (zoneIterator.hasNext()) - zoneIterator.next().value()->getInfo(info->add_zone_list(), playerWhosAsking, omniscient); + getProperties(*info->mutable_properties(), withUserInfo); + if (playerWhosAsking == this) + if (deck) + info->set_deck_list(deck->writeToString_Native().toStdString()); + + QMapIterator arrowIterator(arrows); + while (arrowIterator.hasNext()) + arrowIterator.next().value()->getInfo(info->add_arrow_list()); + + QMapIterator counterIterator(counters); + while (counterIterator.hasNext()) + counterIterator.next().value()->getInfo(info->add_counter_list()); + + QMapIterator zoneIterator(zones); + while (zoneIterator.hasNext()) + zoneIterator.next().value()->getInfo(info->add_zone_list(), playerWhosAsking, omniscient); } diff --git a/common/server_player.h b/common/server_player.h index 61e29bab..873a4a76 100644 --- a/common/server_player.h +++ b/common/server_player.h @@ -62,104 +62,104 @@ class Command_SetSideboardLock; class Command_ChangeZoneProperties; class Server_Player : public Server_ArrowTarget, public ServerInfo_User_Container { - Q_OBJECT + Q_OBJECT private: - class MoveCardCompareFunctor; - Server_Game *game; - Server_AbstractUserInterface *userInterface; - DeckList *deck; - QMap zones; - QMap counters; - QMap arrows; - QList lastDrawList; - int pingTime; - int playerId; - bool spectator; - int initialCards; - int nextCardId; - bool readyStart; - bool conceded; - bool sideboardLocked; + class MoveCardCompareFunctor; + Server_Game *game; + Server_AbstractUserInterface *userInterface; + DeckList *deck; + QMap zones; + QMap counters; + QMap arrows; + QList lastDrawList; + int pingTime; + int playerId; + bool spectator; + int initialCards; + int nextCardId; + bool readyStart; + bool conceded; + bool sideboardLocked; public: - mutable QMutex playerMutex; - Server_Player(Server_Game *_game, int _playerId, const ServerInfo_User &_userInfo, bool _spectator, Server_AbstractUserInterface *_handler); - ~Server_Player(); - void prepareDestroy(); - Server_AbstractUserInterface *getUserInterface() const { return userInterface; } - void setUserInterface(Server_AbstractUserInterface *_userInterface); - void disconnectClient(); - - void setPlayerId(int _id) { playerId = _id; } - bool getReadyStart() const { return readyStart; } - void setReadyStart(bool _readyStart) { readyStart = _readyStart; } - int getPlayerId() const { return playerId; } - bool getSpectator() const { return spectator; } - bool getConceded() const { return conceded; } - void setConceded(bool _conceded) { conceded = _conceded; } - DeckList *getDeck() const { return deck; } - Server_Game *getGame() const { return game; } - const QMap &getZones() const { return zones; } - const QMap &getCounters() const { return counters; } - const QMap &getArrows() const { return arrows; } - - int getPingTime() const { return pingTime; } - void setPingTime(int _pingTime) { pingTime = _pingTime; } - void getProperties(ServerInfo_PlayerProperties &result, bool withUserInfo); - - int newCardId(); - int newCounterId() const; - int newArrowId() const; - - void addZone(Server_CardZone *zone); - void addArrow(Server_Arrow *arrow); - bool deleteArrow(int arrowId); - void addCounter(Server_Counter *counter); - - void clearZones(); - void setupZones(); + mutable QMutex playerMutex; + Server_Player(Server_Game *_game, int _playerId, const ServerInfo_User &_userInfo, bool _spectator, Server_AbstractUserInterface *_handler); + ~Server_Player(); + void prepareDestroy(); + Server_AbstractUserInterface *getUserInterface() const { return userInterface; } + void setUserInterface(Server_AbstractUserInterface *_userInterface); + void disconnectClient(); + + void setPlayerId(int _id) { playerId = _id; } + bool getReadyStart() const { return readyStart; } + void setReadyStart(bool _readyStart) { readyStart = _readyStart; } + int getPlayerId() const { return playerId; } + bool getSpectator() const { return spectator; } + bool getConceded() const { return conceded; } + void setConceded(bool _conceded) { conceded = _conceded; } + DeckList *getDeck() const { return deck; } + Server_Game *getGame() const { return game; } + const QMap &getZones() const { return zones; } + const QMap &getCounters() const { return counters; } + const QMap &getArrows() const { return arrows; } + + int getPingTime() const { return pingTime; } + void setPingTime(int _pingTime) { pingTime = _pingTime; } + void getProperties(ServerInfo_PlayerProperties &result, bool withUserInfo); + + int newCardId(); + int newCounterId() const; + int newArrowId() const; + + void addZone(Server_CardZone *zone); + void addArrow(Server_Arrow *arrow); + bool deleteArrow(int arrowId); + void addCounter(Server_Counter *counter); + + void clearZones(); + void setupZones(); - Response::ResponseCode drawCards(GameEventStorage &ges, int number); - Response::ResponseCode moveCard(GameEventStorage &ges, Server_CardZone *startzone, const QList &_cards, Server_CardZone *targetzone, int x, int y, bool fixFreeSpaces = true, bool undoingDraw = false); - void unattachCard(GameEventStorage &ges, Server_Card *card); - Response::ResponseCode setCardAttrHelper(GameEventStorage &ges, const QString &zone, int cardId, CardAttribute attribute, const QString &attrValue); + Response::ResponseCode drawCards(GameEventStorage &ges, int number); + Response::ResponseCode moveCard(GameEventStorage &ges, Server_CardZone *startzone, const QList &_cards, Server_CardZone *targetzone, int x, int y, bool fixFreeSpaces = true, bool undoingDraw = false); + void unattachCard(GameEventStorage &ges, Server_Card *card); + Response::ResponseCode setCardAttrHelper(GameEventStorage &ges, const QString &zone, int cardId, CardAttribute attribute, const QString &attrValue); - Response::ResponseCode cmdLeaveGame(const Command_LeaveGame &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdKickFromGame(const Command_KickFromGame &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdConcede(const Command_Concede &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdReadyStart(const Command_ReadyStart &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdDeckSelect(const Command_DeckSelect &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdSetSideboardPlan(const Command_SetSideboardPlan &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdSetSideboardLock(const Command_SetSideboardLock &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdGameSay(const Command_GameSay &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdShuffle(const Command_Shuffle &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdMulligan(const Command_Mulligan &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdRollDie(const Command_RollDie &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdDrawCards(const Command_DrawCards &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdUndoDraw(const Command_UndoDraw &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdMoveCard(const Command_MoveCard &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdFlipCard(const Command_FlipCard &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdAttachCard(const Command_AttachCard &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdCreateToken(const Command_CreateToken &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdCreateArrow(const Command_CreateArrow &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdDeleteArrow(const Command_DeleteArrow &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdSetCardAttr(const Command_SetCardAttr &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdSetCardCounter(const Command_SetCardCounter &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdIncCardCounter(const Command_IncCardCounter &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdIncCounter(const Command_IncCounter &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdCreateCounter(const Command_CreateCounter &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdSetCounter(const Command_SetCounter &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdDelCounter(const Command_DelCounter &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdNextTurn(const Command_NextTurn &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdSetActivePhase(const Command_SetActivePhase &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdDumpZone(const Command_DumpZone &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdStopDumpZone(const Command_StopDumpZone &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdRevealCards(const Command_RevealCards &cmd, ResponseContainer &rc, GameEventStorage &ges); - Response::ResponseCode cmdChangeZoneProperties(const Command_ChangeZoneProperties &cmd, ResponseContainer &rc, GameEventStorage &ges); - - Response::ResponseCode processGameCommand(const GameCommand &command, ResponseContainer &rc, GameEventStorage &ges); - void sendGameEvent(const GameEventContainer &event); - - void getInfo(ServerInfo_Player *info, Server_Player *playerWhosAsking, bool omniscient, bool withUserInfo); + Response::ResponseCode cmdLeaveGame(const Command_LeaveGame &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdKickFromGame(const Command_KickFromGame &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdConcede(const Command_Concede &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdReadyStart(const Command_ReadyStart &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdDeckSelect(const Command_DeckSelect &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdSetSideboardPlan(const Command_SetSideboardPlan &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdSetSideboardLock(const Command_SetSideboardLock &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdGameSay(const Command_GameSay &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdShuffle(const Command_Shuffle &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdMulligan(const Command_Mulligan &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdRollDie(const Command_RollDie &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdDrawCards(const Command_DrawCards &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdUndoDraw(const Command_UndoDraw &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdMoveCard(const Command_MoveCard &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdFlipCard(const Command_FlipCard &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdAttachCard(const Command_AttachCard &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdCreateToken(const Command_CreateToken &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdCreateArrow(const Command_CreateArrow &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdDeleteArrow(const Command_DeleteArrow &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdSetCardAttr(const Command_SetCardAttr &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdSetCardCounter(const Command_SetCardCounter &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdIncCardCounter(const Command_IncCardCounter &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdIncCounter(const Command_IncCounter &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdCreateCounter(const Command_CreateCounter &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdSetCounter(const Command_SetCounter &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdDelCounter(const Command_DelCounter &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdNextTurn(const Command_NextTurn &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdSetActivePhase(const Command_SetActivePhase &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdDumpZone(const Command_DumpZone &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdStopDumpZone(const Command_StopDumpZone &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdRevealCards(const Command_RevealCards &cmd, ResponseContainer &rc, GameEventStorage &ges); + Response::ResponseCode cmdChangeZoneProperties(const Command_ChangeZoneProperties &cmd, ResponseContainer &rc, GameEventStorage &ges); + + Response::ResponseCode processGameCommand(const GameCommand &command, ResponseContainer &rc, GameEventStorage &ges); + void sendGameEvent(const GameEventContainer &event); + + void getInfo(ServerInfo_Player *info, Server_Player *playerWhosAsking, bool omniscient, bool withUserInfo); }; #endif diff --git a/common/server_player_reference.h b/common/server_player_reference.h index fc784a1a..868b40b6 100644 --- a/common/server_player_reference.h +++ b/common/server_player_reference.h @@ -3,15 +3,15 @@ class PlayerReference { private: - int roomId; - int gameId; - int playerId; + int roomId; + int gameId; + int playerId; public: - PlayerReference(int _roomId, int _gameId, int _playerId) : roomId(_roomId), gameId(_gameId), playerId(_playerId) { } - int getRoomId() const { return roomId; } - int getGameId() const { return gameId; } - int getPlayerId() const { return playerId; } - bool operator==(const PlayerReference &other) { return ((roomId == other.roomId) && (gameId == other.gameId) && (playerId == other.playerId)); } + PlayerReference(int _roomId, int _gameId, int _playerId) : roomId(_roomId), gameId(_gameId), playerId(_playerId) { } + int getRoomId() const { return roomId; } + int getGameId() const { return gameId; } + int getPlayerId() const { return playerId; } + bool operator==(const PlayerReference &other) { return ((roomId == other.roomId) && (gameId == other.gameId) && (playerId == other.playerId)); } }; #endif diff --git a/common/server_protocolhandler.cpp b/common/server_protocolhandler.cpp index eb8322d0..f7561b2a 100644 --- a/common/server_protocolhandler.cpp +++ b/common/server_protocolhandler.cpp @@ -21,17 +21,17 @@ #include Server_ProtocolHandler::Server_ProtocolHandler(Server *_server, Server_DatabaseInterface *_databaseInterface, QObject *parent) - : QObject(parent), - Server_AbstractUserInterface(_server), - deleted(false), - databaseInterface(_databaseInterface), - authState(NotLoggedIn), - acceptsUserListChanges(false), - acceptsRoomListChanges(false), - timeRunning(0), - lastDataReceived(0) + : QObject(parent), + Server_AbstractUserInterface(_server), + deleted(false), + databaseInterface(_databaseInterface), + authState(NotLoggedIn), + acceptsUserListChanges(false), + acceptsRoomListChanges(false), + timeRunning(0), + lastDataReceived(0) { - connect(server, SIGNAL(pingClockTimeout()), this, SLOT(pingClockTimeout())); + connect(server, SIGNAL(pingClockTimeout()), this, SLOT(pingClockTimeout())); } Server_ProtocolHandler::~Server_ProtocolHandler() @@ -42,540 +42,540 @@ Server_ProtocolHandler::~Server_ProtocolHandler() // The thread must not hold any server locks when calling this (e.g. clientsLock, roomsLock). void Server_ProtocolHandler::prepareDestroy() { - if (deleted) - return; - deleted = true; - - QMapIterator roomIterator(rooms); - while (roomIterator.hasNext()) - roomIterator.next().value()->removeClient(this); - - QMap > tempGames(getGames()); - - server->roomsLock.lockForRead(); - QMapIterator > gameIterator(tempGames); - while (gameIterator.hasNext()) { - gameIterator.next(); - - Server_Room *r = server->getRooms().value(gameIterator.value().first); - if (!r) - continue; - r->gamesLock.lockForRead(); - Server_Game *g = r->getGames().value(gameIterator.key()); - if (!g) { - r->gamesLock.unlock(); - continue; - } - g->gameMutex.lock(); - Server_Player *p = g->getPlayers().value(gameIterator.value().second); - if (!p) { - g->gameMutex.unlock(); - r->gamesLock.unlock(); - continue; - } - - p->disconnectClient(); - - g->gameMutex.unlock(); - r->gamesLock.unlock(); - } - server->roomsLock.unlock(); - - server->removeClient(this); - - deleteLater(); + if (deleted) + return; + deleted = true; + + QMapIterator roomIterator(rooms); + while (roomIterator.hasNext()) + roomIterator.next().value()->removeClient(this); + + QMap > tempGames(getGames()); + + server->roomsLock.lockForRead(); + QMapIterator > gameIterator(tempGames); + while (gameIterator.hasNext()) { + gameIterator.next(); + + Server_Room *r = server->getRooms().value(gameIterator.value().first); + if (!r) + continue; + r->gamesLock.lockForRead(); + Server_Game *g = r->getGames().value(gameIterator.key()); + if (!g) { + r->gamesLock.unlock(); + continue; + } + g->gameMutex.lock(); + Server_Player *p = g->getPlayers().value(gameIterator.value().second); + if (!p) { + g->gameMutex.unlock(); + r->gamesLock.unlock(); + continue; + } + + p->disconnectClient(); + + g->gameMutex.unlock(); + r->gamesLock.unlock(); + } + server->roomsLock.unlock(); + + server->removeClient(this); + + deleteLater(); } void Server_ProtocolHandler::sendProtocolItem(const Response &item) { - ServerMessage msg; - msg.mutable_response()->CopyFrom(item); - msg.set_message_type(ServerMessage::RESPONSE); - - transmitProtocolItem(msg); + ServerMessage msg; + msg.mutable_response()->CopyFrom(item); + msg.set_message_type(ServerMessage::RESPONSE); + + transmitProtocolItem(msg); } void Server_ProtocolHandler::sendProtocolItem(const SessionEvent &item) { - ServerMessage msg; - msg.mutable_session_event()->CopyFrom(item); - msg.set_message_type(ServerMessage::SESSION_EVENT); - - transmitProtocolItem(msg); + ServerMessage msg; + msg.mutable_session_event()->CopyFrom(item); + msg.set_message_type(ServerMessage::SESSION_EVENT); + + transmitProtocolItem(msg); } void Server_ProtocolHandler::sendProtocolItem(const GameEventContainer &item) { - ServerMessage msg; - msg.mutable_game_event_container()->CopyFrom(item); - msg.set_message_type(ServerMessage::GAME_EVENT_CONTAINER); - - transmitProtocolItem(msg); + ServerMessage msg; + msg.mutable_game_event_container()->CopyFrom(item); + msg.set_message_type(ServerMessage::GAME_EVENT_CONTAINER); + + transmitProtocolItem(msg); } void Server_ProtocolHandler::sendProtocolItem(const RoomEvent &item) { - ServerMessage msg; - msg.mutable_room_event()->CopyFrom(item); - msg.set_message_type(ServerMessage::ROOM_EVENT); - - transmitProtocolItem(msg); + ServerMessage msg; + msg.mutable_room_event()->CopyFrom(item); + msg.set_message_type(ServerMessage::ROOM_EVENT); + + transmitProtocolItem(msg); } Response::ResponseCode Server_ProtocolHandler::processSessionCommandContainer(const CommandContainer &cont, ResponseContainer &rc) { - Response::ResponseCode finalResponseCode = Response::RespOk; - for (int i = cont.session_command_size() - 1; i >= 0; --i) { - Response::ResponseCode resp = Response::RespInvalidCommand; - const SessionCommand &sc = cont.session_command(i); - const int num = getPbExtension(sc); - if (num != SessionCommand::PING) { // don't log ping commands - if (num == SessionCommand::LOGIN) { // log login commands, but hide passwords - SessionCommand debugSc(sc); - debugSc.MutableExtension(Command_Login::ext)->clear_password(); - logDebugMessage(QString::fromStdString(debugSc.ShortDebugString())); - } else - logDebugMessage(QString::fromStdString(sc.ShortDebugString())); - } - switch ((SessionCommand::SessionCommandType) num) { - case SessionCommand::PING: resp = cmdPing(sc.GetExtension(Command_Ping::ext), rc); break; - case SessionCommand::LOGIN: resp = cmdLogin(sc.GetExtension(Command_Login::ext), rc); break; - case SessionCommand::MESSAGE: resp = cmdMessage(sc.GetExtension(Command_Message::ext), rc); break; - case SessionCommand::GET_GAMES_OF_USER: resp = cmdGetGamesOfUser(sc.GetExtension(Command_GetGamesOfUser::ext), rc); break; - case SessionCommand::GET_USER_INFO: resp = cmdGetUserInfo(sc.GetExtension(Command_GetUserInfo::ext), rc); break; - case SessionCommand::LIST_ROOMS: resp = cmdListRooms(sc.GetExtension(Command_ListRooms::ext), rc); break; - case SessionCommand::JOIN_ROOM: resp = cmdJoinRoom(sc.GetExtension(Command_JoinRoom::ext), rc); break; - case SessionCommand::LIST_USERS: resp = cmdListUsers(sc.GetExtension(Command_ListUsers::ext), rc); break; - default: resp = processExtendedSessionCommand(num, sc, rc); - } - if (resp != Response::RespOk) - finalResponseCode = resp; - } - return finalResponseCode; + Response::ResponseCode finalResponseCode = Response::RespOk; + for (int i = cont.session_command_size() - 1; i >= 0; --i) { + Response::ResponseCode resp = Response::RespInvalidCommand; + const SessionCommand &sc = cont.session_command(i); + const int num = getPbExtension(sc); + if (num != SessionCommand::PING) { // don't log ping commands + if (num == SessionCommand::LOGIN) { // log login commands, but hide passwords + SessionCommand debugSc(sc); + debugSc.MutableExtension(Command_Login::ext)->clear_password(); + logDebugMessage(QString::fromStdString(debugSc.ShortDebugString())); + } else + logDebugMessage(QString::fromStdString(sc.ShortDebugString())); + } + switch ((SessionCommand::SessionCommandType) num) { + case SessionCommand::PING: resp = cmdPing(sc.GetExtension(Command_Ping::ext), rc); break; + case SessionCommand::LOGIN: resp = cmdLogin(sc.GetExtension(Command_Login::ext), rc); break; + case SessionCommand::MESSAGE: resp = cmdMessage(sc.GetExtension(Command_Message::ext), rc); break; + case SessionCommand::GET_GAMES_OF_USER: resp = cmdGetGamesOfUser(sc.GetExtension(Command_GetGamesOfUser::ext), rc); break; + case SessionCommand::GET_USER_INFO: resp = cmdGetUserInfo(sc.GetExtension(Command_GetUserInfo::ext), rc); break; + case SessionCommand::LIST_ROOMS: resp = cmdListRooms(sc.GetExtension(Command_ListRooms::ext), rc); break; + case SessionCommand::JOIN_ROOM: resp = cmdJoinRoom(sc.GetExtension(Command_JoinRoom::ext), rc); break; + case SessionCommand::LIST_USERS: resp = cmdListUsers(sc.GetExtension(Command_ListUsers::ext), rc); break; + default: resp = processExtendedSessionCommand(num, sc, rc); + } + if (resp != Response::RespOk) + finalResponseCode = resp; + } + return finalResponseCode; } Response::ResponseCode Server_ProtocolHandler::processRoomCommandContainer(const CommandContainer &cont, ResponseContainer &rc) { - if (authState == NotLoggedIn) - return Response::RespLoginNeeded; + if (authState == NotLoggedIn) + return Response::RespLoginNeeded; - QReadLocker locker(&server->roomsLock); - Server_Room *room = rooms.value(cont.room_id(), 0); - if (!room) - return Response::RespNotInRoom; - - Response::ResponseCode finalResponseCode = Response::RespOk; - for (int i = cont.room_command_size() - 1; i >= 0; --i) { - Response::ResponseCode resp = Response::RespInvalidCommand; - const RoomCommand &sc = cont.room_command(i); - const int num = getPbExtension(sc); - logDebugMessage(QString::fromStdString(sc.ShortDebugString())); - switch ((RoomCommand::RoomCommandType) num) { - case RoomCommand::LEAVE_ROOM: resp = cmdLeaveRoom(sc.GetExtension(Command_LeaveRoom::ext), room, rc); break; - case RoomCommand::ROOM_SAY: resp = cmdRoomSay(sc.GetExtension(Command_RoomSay::ext), room, rc); break; - case RoomCommand::CREATE_GAME: resp = cmdCreateGame(sc.GetExtension(Command_CreateGame::ext), room, rc); break; - case RoomCommand::JOIN_GAME: resp = cmdJoinGame(sc.GetExtension(Command_JoinGame::ext), room, rc); break; - } - if (resp != Response::RespOk) - finalResponseCode = resp; - } - return finalResponseCode; + QReadLocker locker(&server->roomsLock); + Server_Room *room = rooms.value(cont.room_id(), 0); + if (!room) + return Response::RespNotInRoom; + + Response::ResponseCode finalResponseCode = Response::RespOk; + for (int i = cont.room_command_size() - 1; i >= 0; --i) { + Response::ResponseCode resp = Response::RespInvalidCommand; + const RoomCommand &sc = cont.room_command(i); + const int num = getPbExtension(sc); + logDebugMessage(QString::fromStdString(sc.ShortDebugString())); + switch ((RoomCommand::RoomCommandType) num) { + case RoomCommand::LEAVE_ROOM: resp = cmdLeaveRoom(sc.GetExtension(Command_LeaveRoom::ext), room, rc); break; + case RoomCommand::ROOM_SAY: resp = cmdRoomSay(sc.GetExtension(Command_RoomSay::ext), room, rc); break; + case RoomCommand::CREATE_GAME: resp = cmdCreateGame(sc.GetExtension(Command_CreateGame::ext), room, rc); break; + case RoomCommand::JOIN_GAME: resp = cmdJoinGame(sc.GetExtension(Command_JoinGame::ext), room, rc); break; + } + if (resp != Response::RespOk) + finalResponseCode = resp; + } + return finalResponseCode; } Response::ResponseCode Server_ProtocolHandler::processGameCommandContainer(const CommandContainer &cont, ResponseContainer &rc) { - if (authState == NotLoggedIn) - return Response::RespLoginNeeded; - - QMap > gameMap = getGames(); - if (!gameMap.contains(cont.game_id())) - return Response::RespNotInRoom; - const QPair roomIdAndPlayerId = gameMap.value(cont.game_id()); - - QReadLocker roomsLocker(&server->roomsLock); - Server_Room *room = server->getRooms().value(roomIdAndPlayerId.first); - if (!room) - return Response::RespNotInRoom; - - QReadLocker roomGamesLocker(&room->gamesLock); - Server_Game *game = room->getGames().value(cont.game_id()); - if (!game) { - if (room->getExternalGames().contains(cont.game_id())) { - server->sendIsl_GameCommand(cont, - room->getExternalGames().value(cont.game_id()).server_id(), - userInfo->session_id(), - roomIdAndPlayerId.first, - roomIdAndPlayerId.second - ); - return Response::RespNothing; - } - return Response::RespNotInRoom; - } - - QMutexLocker gameLocker(&game->gameMutex); - Server_Player *player = game->getPlayers().value(roomIdAndPlayerId.second); - if (!player) - return Response::RespNotInRoom; - - GameEventStorage ges; - Response::ResponseCode finalResponseCode = Response::RespOk; - for (int i = cont.game_command_size() - 1; i >= 0; --i) { - const GameCommand &sc = cont.game_command(i); - logDebugMessage(QString("game %1 player %2: ").arg(cont.game_id()).arg(roomIdAndPlayerId.second) + QString::fromStdString(sc.ShortDebugString())); - - Response::ResponseCode resp = player->processGameCommand(sc, rc, ges); + if (authState == NotLoggedIn) + return Response::RespLoginNeeded; + + QMap > gameMap = getGames(); + if (!gameMap.contains(cont.game_id())) + return Response::RespNotInRoom; + const QPair roomIdAndPlayerId = gameMap.value(cont.game_id()); + + QReadLocker roomsLocker(&server->roomsLock); + Server_Room *room = server->getRooms().value(roomIdAndPlayerId.first); + if (!room) + return Response::RespNotInRoom; + + QReadLocker roomGamesLocker(&room->gamesLock); + Server_Game *game = room->getGames().value(cont.game_id()); + if (!game) { + if (room->getExternalGames().contains(cont.game_id())) { + server->sendIsl_GameCommand(cont, + room->getExternalGames().value(cont.game_id()).server_id(), + userInfo->session_id(), + roomIdAndPlayerId.first, + roomIdAndPlayerId.second + ); + return Response::RespNothing; + } + return Response::RespNotInRoom; + } + + QMutexLocker gameLocker(&game->gameMutex); + Server_Player *player = game->getPlayers().value(roomIdAndPlayerId.second); + if (!player) + return Response::RespNotInRoom; + + GameEventStorage ges; + Response::ResponseCode finalResponseCode = Response::RespOk; + for (int i = cont.game_command_size() - 1; i >= 0; --i) { + const GameCommand &sc = cont.game_command(i); + logDebugMessage(QString("game %1 player %2: ").arg(cont.game_id()).arg(roomIdAndPlayerId.second) + QString::fromStdString(sc.ShortDebugString())); + + Response::ResponseCode resp = player->processGameCommand(sc, rc, ges); - if (resp != Response::RespOk) - finalResponseCode = resp; - } - ges.sendToGame(game); - - return finalResponseCode; + if (resp != Response::RespOk) + finalResponseCode = resp; + } + ges.sendToGame(game); + + return finalResponseCode; } Response::ResponseCode Server_ProtocolHandler::processModeratorCommandContainer(const CommandContainer &cont, ResponseContainer &rc) { - if (!userInfo) - return Response::RespLoginNeeded; - if (!(userInfo->user_level() & ServerInfo_User::IsModerator)) - return Response::RespLoginNeeded; + if (!userInfo) + return Response::RespLoginNeeded; + if (!(userInfo->user_level() & ServerInfo_User::IsModerator)) + return Response::RespLoginNeeded; - Response::ResponseCode finalResponseCode = Response::RespOk; - for (int i = cont.moderator_command_size() - 1; i >= 0; --i) { - Response::ResponseCode resp = Response::RespInvalidCommand; - const ModeratorCommand &sc = cont.moderator_command(i); - const int num = getPbExtension(sc); - logDebugMessage(QString::fromStdString(sc.ShortDebugString())); - - resp = processExtendedModeratorCommand(num, sc, rc); - if (resp != Response::RespOk) - finalResponseCode = resp; - } - return finalResponseCode; + Response::ResponseCode finalResponseCode = Response::RespOk; + for (int i = cont.moderator_command_size() - 1; i >= 0; --i) { + Response::ResponseCode resp = Response::RespInvalidCommand; + const ModeratorCommand &sc = cont.moderator_command(i); + const int num = getPbExtension(sc); + logDebugMessage(QString::fromStdString(sc.ShortDebugString())); + + resp = processExtendedModeratorCommand(num, sc, rc); + if (resp != Response::RespOk) + finalResponseCode = resp; + } + return finalResponseCode; } Response::ResponseCode Server_ProtocolHandler::processAdminCommandContainer(const CommandContainer &cont, ResponseContainer &rc) { - if (!userInfo) - return Response::RespLoginNeeded; - if (!(userInfo->user_level() & ServerInfo_User::IsAdmin)) - return Response::RespLoginNeeded; + if (!userInfo) + return Response::RespLoginNeeded; + if (!(userInfo->user_level() & ServerInfo_User::IsAdmin)) + return Response::RespLoginNeeded; - Response::ResponseCode finalResponseCode = Response::RespOk; - for (int i = cont.admin_command_size() - 1; i >= 0; --i) { - Response::ResponseCode resp = Response::RespInvalidCommand; - const AdminCommand &sc = cont.admin_command(i); - const int num = getPbExtension(sc); - logDebugMessage(QString::fromStdString(sc.ShortDebugString())); - - resp = processExtendedAdminCommand(num, sc, rc); - if (resp != Response::RespOk) - finalResponseCode = resp; - } - return finalResponseCode; + Response::ResponseCode finalResponseCode = Response::RespOk; + for (int i = cont.admin_command_size() - 1; i >= 0; --i) { + Response::ResponseCode resp = Response::RespInvalidCommand; + const AdminCommand &sc = cont.admin_command(i); + const int num = getPbExtension(sc); + logDebugMessage(QString::fromStdString(sc.ShortDebugString())); + + resp = processExtendedAdminCommand(num, sc, rc); + if (resp != Response::RespOk) + finalResponseCode = resp; + } + return finalResponseCode; } void Server_ProtocolHandler::processCommandContainer(const CommandContainer &cont) { - // Command processing must be disabled after prepareDestroy() has been called. - if (deleted) - return; - - lastDataReceived = timeRunning; - - ResponseContainer responseContainer(cont.has_cmd_id() ? cont.cmd_id() : -1); - Response::ResponseCode finalResponseCode; - - if (cont.game_command_size()) - finalResponseCode = processGameCommandContainer(cont, responseContainer); - else if (cont.room_command_size()) - finalResponseCode = processRoomCommandContainer(cont, responseContainer); - else if (cont.session_command_size()) - finalResponseCode = processSessionCommandContainer(cont, responseContainer); - else if (cont.moderator_command_size()) - finalResponseCode = processModeratorCommandContainer(cont, responseContainer); - else if (cont.admin_command_size()) - finalResponseCode = processAdminCommandContainer(cont, responseContainer); - else - finalResponseCode = Response::RespInvalidCommand; - - if ((finalResponseCode != Response::RespNothing)) - sendResponseContainer(responseContainer, finalResponseCode); + // Command processing must be disabled after prepareDestroy() has been called. + if (deleted) + return; + + lastDataReceived = timeRunning; + + ResponseContainer responseContainer(cont.has_cmd_id() ? cont.cmd_id() : -1); + Response::ResponseCode finalResponseCode; + + if (cont.game_command_size()) + finalResponseCode = processGameCommandContainer(cont, responseContainer); + else if (cont.room_command_size()) + finalResponseCode = processRoomCommandContainer(cont, responseContainer); + else if (cont.session_command_size()) + finalResponseCode = processSessionCommandContainer(cont, responseContainer); + else if (cont.moderator_command_size()) + finalResponseCode = processModeratorCommandContainer(cont, responseContainer); + else if (cont.admin_command_size()) + finalResponseCode = processAdminCommandContainer(cont, responseContainer); + else + finalResponseCode = Response::RespInvalidCommand; + + if ((finalResponseCode != Response::RespNothing)) + sendResponseContainer(responseContainer, finalResponseCode); } void Server_ProtocolHandler::pingClockTimeout() { - int interval = server->getMessageCountingInterval(); - if (interval > 0) { - messageSizeOverTime.prepend(0); - if (messageSizeOverTime.size() > server->getMessageCountingInterval()) - messageSizeOverTime.removeLast(); - messageCountOverTime.prepend(0); - if (messageCountOverTime.size() > server->getMessageCountingInterval()) - messageCountOverTime.removeLast(); - } - - if (timeRunning - lastDataReceived > server->getMaxPlayerInactivityTime()) - prepareDestroy(); - ++timeRunning; + int interval = server->getMessageCountingInterval(); + if (interval > 0) { + messageSizeOverTime.prepend(0); + if (messageSizeOverTime.size() > server->getMessageCountingInterval()) + messageSizeOverTime.removeLast(); + messageCountOverTime.prepend(0); + if (messageCountOverTime.size() > server->getMessageCountingInterval()) + messageCountOverTime.removeLast(); + } + + if (timeRunning - lastDataReceived > server->getMaxPlayerInactivityTime()) + prepareDestroy(); + ++timeRunning; } Response::ResponseCode Server_ProtocolHandler::cmdPing(const Command_Ping & /*cmd*/, ResponseContainer & /*rc*/) { - return Response::RespOk; + return Response::RespOk; } Response::ResponseCode Server_ProtocolHandler::cmdLogin(const Command_Login &cmd, ResponseContainer &rc) { - QString userName = QString::fromStdString(cmd.user_name()).simplified(); - if (userName.isEmpty() || (userInfo != 0)) - return Response::RespContextError; - QString reasonStr; - int banSecondsLeft = 0; - AuthenticationResult res = server->loginUser(this, userName, QString::fromStdString(cmd.password()), reasonStr, banSecondsLeft); - switch (res) { - case UserIsBanned: { - Response_Login *re = new Response_Login; - re->set_denied_reason_str(reasonStr.toStdString()); - if (banSecondsLeft != 0) - re->set_denied_end_time(QDateTime::currentDateTime().addSecs(banSecondsLeft).toTime_t()); - rc.setResponseExtension(re); - return Response::RespUserIsBanned; - } - case NotLoggedIn: return Response::RespWrongPassword; - case WouldOverwriteOldSession: return Response::RespWouldOverwriteOldSession; - case UsernameInvalid: return Response::RespUsernameInvalid; - default: authState = res; - } - - userName = QString::fromStdString(userInfo->name()); - Event_ServerMessage event; - event.set_message(server->getLoginMessage().toStdString()); - rc.enqueuePostResponseItem(ServerMessage::SESSION_EVENT, prepareSessionEvent(event)); - - Response_Login *re = new Response_Login; - re->mutable_user_info()->CopyFrom(copyUserInfo(true)); - - if (authState == PasswordRight) { - QMapIterator buddyIterator(databaseInterface->getBuddyList(userName)); - while (buddyIterator.hasNext()) - re->add_buddy_list()->CopyFrom(buddyIterator.next().value()); - - QMapIterator ignoreIterator(databaseInterface->getIgnoreList(userName)); - while (ignoreIterator.hasNext()) - re->add_ignore_list()->CopyFrom(ignoreIterator.next().value()); - } - - joinPersistentGames(rc); - - rc.setResponseExtension(re); - return Response::RespOk; + QString userName = QString::fromStdString(cmd.user_name()).simplified(); + if (userName.isEmpty() || (userInfo != 0)) + return Response::RespContextError; + QString reasonStr; + int banSecondsLeft = 0; + AuthenticationResult res = server->loginUser(this, userName, QString::fromStdString(cmd.password()), reasonStr, banSecondsLeft); + switch (res) { + case UserIsBanned: { + Response_Login *re = new Response_Login; + re->set_denied_reason_str(reasonStr.toStdString()); + if (banSecondsLeft != 0) + re->set_denied_end_time(QDateTime::currentDateTime().addSecs(banSecondsLeft).toTime_t()); + rc.setResponseExtension(re); + return Response::RespUserIsBanned; + } + case NotLoggedIn: return Response::RespWrongPassword; + case WouldOverwriteOldSession: return Response::RespWouldOverwriteOldSession; + case UsernameInvalid: return Response::RespUsernameInvalid; + default: authState = res; + } + + userName = QString::fromStdString(userInfo->name()); + Event_ServerMessage event; + event.set_message(server->getLoginMessage().toStdString()); + rc.enqueuePostResponseItem(ServerMessage::SESSION_EVENT, prepareSessionEvent(event)); + + Response_Login *re = new Response_Login; + re->mutable_user_info()->CopyFrom(copyUserInfo(true)); + + if (authState == PasswordRight) { + QMapIterator buddyIterator(databaseInterface->getBuddyList(userName)); + while (buddyIterator.hasNext()) + re->add_buddy_list()->CopyFrom(buddyIterator.next().value()); + + QMapIterator ignoreIterator(databaseInterface->getIgnoreList(userName)); + while (ignoreIterator.hasNext()) + re->add_ignore_list()->CopyFrom(ignoreIterator.next().value()); + } + + joinPersistentGames(rc); + + rc.setResponseExtension(re); + return Response::RespOk; } Response::ResponseCode Server_ProtocolHandler::cmdMessage(const Command_Message &cmd, ResponseContainer &rc) { - if (authState == NotLoggedIn) - return Response::RespLoginNeeded; - - QReadLocker locker(&server->clientsLock); - - QString receiver = QString::fromStdString(cmd.user_name()); - Server_AbstractUserInterface *userInterface = server->findUser(receiver); - if (!userInterface) - return Response::RespNameNotFound; - if (databaseInterface->isInIgnoreList(receiver, QString::fromStdString(userInfo->name()))) - return Response::RespInIgnoreList; - - Event_UserMessage event; - event.set_sender_name(userInfo->name()); - event.set_receiver_name(cmd.user_name()); - event.set_message(cmd.message()); - - SessionEvent *se = prepareSessionEvent(event); - userInterface->sendProtocolItem(*se); - rc.enqueuePreResponseItem(ServerMessage::SESSION_EVENT, se); - - return Response::RespOk; + if (authState == NotLoggedIn) + return Response::RespLoginNeeded; + + QReadLocker locker(&server->clientsLock); + + QString receiver = QString::fromStdString(cmd.user_name()); + Server_AbstractUserInterface *userInterface = server->findUser(receiver); + if (!userInterface) + return Response::RespNameNotFound; + if (databaseInterface->isInIgnoreList(receiver, QString::fromStdString(userInfo->name()))) + return Response::RespInIgnoreList; + + Event_UserMessage event; + event.set_sender_name(userInfo->name()); + event.set_receiver_name(cmd.user_name()); + event.set_message(cmd.message()); + + SessionEvent *se = prepareSessionEvent(event); + userInterface->sendProtocolItem(*se); + rc.enqueuePreResponseItem(ServerMessage::SESSION_EVENT, se); + + return Response::RespOk; } Response::ResponseCode Server_ProtocolHandler::cmdGetGamesOfUser(const Command_GetGamesOfUser &cmd, ResponseContainer &rc) { - if (authState == NotLoggedIn) - return Response::RespLoginNeeded; - - // We don't need to check whether the user is logged in; persistent games should also work. - // The client needs to deal with an empty result list. - - Response_GetGamesOfUser *re = new Response_GetGamesOfUser; - server->roomsLock.lockForRead(); - QMapIterator roomIterator(server->getRooms()); - while (roomIterator.hasNext()) { - Server_Room *room = roomIterator.next().value(); - room->gamesLock.lockForRead(); - room->getInfo(*re->add_room_list(), false, true); - QListIterator gameIterator(room->getGamesOfUser(QString::fromStdString(cmd.user_name()))); - while (gameIterator.hasNext()) - re->add_game_list()->CopyFrom(gameIterator.next()); - room->gamesLock.unlock(); - } - server->roomsLock.unlock(); - - rc.setResponseExtension(re); - return Response::RespOk; + if (authState == NotLoggedIn) + return Response::RespLoginNeeded; + + // We don't need to check whether the user is logged in; persistent games should also work. + // The client needs to deal with an empty result list. + + Response_GetGamesOfUser *re = new Response_GetGamesOfUser; + server->roomsLock.lockForRead(); + QMapIterator roomIterator(server->getRooms()); + while (roomIterator.hasNext()) { + Server_Room *room = roomIterator.next().value(); + room->gamesLock.lockForRead(); + room->getInfo(*re->add_room_list(), false, true); + QListIterator gameIterator(room->getGamesOfUser(QString::fromStdString(cmd.user_name()))); + while (gameIterator.hasNext()) + re->add_game_list()->CopyFrom(gameIterator.next()); + room->gamesLock.unlock(); + } + server->roomsLock.unlock(); + + rc.setResponseExtension(re); + return Response::RespOk; } Response::ResponseCode Server_ProtocolHandler::cmdGetUserInfo(const Command_GetUserInfo &cmd, ResponseContainer &rc) { - if (authState == NotLoggedIn) - return Response::RespLoginNeeded; - - QString userName = QString::fromStdString(cmd.user_name()); - Response_GetUserInfo *re = new Response_GetUserInfo; - if (userName.isEmpty()) - re->mutable_user_info()->CopyFrom(*userInfo); - else { - - QReadLocker locker(&server->clientsLock); - - ServerInfo_User_Container *infoSource = server->findUser(userName); - if (!infoSource) - return Response::RespNameNotFound; - - re->mutable_user_info()->CopyFrom(infoSource->copyUserInfo(true, false, userInfo->user_level() & ServerInfo_User::IsModerator)); - } - - rc.setResponseExtension(re); - return Response::RespOk; + if (authState == NotLoggedIn) + return Response::RespLoginNeeded; + + QString userName = QString::fromStdString(cmd.user_name()); + Response_GetUserInfo *re = new Response_GetUserInfo; + if (userName.isEmpty()) + re->mutable_user_info()->CopyFrom(*userInfo); + else { + + QReadLocker locker(&server->clientsLock); + + ServerInfo_User_Container *infoSource = server->findUser(userName); + if (!infoSource) + return Response::RespNameNotFound; + + re->mutable_user_info()->CopyFrom(infoSource->copyUserInfo(true, false, userInfo->user_level() & ServerInfo_User::IsModerator)); + } + + rc.setResponseExtension(re); + return Response::RespOk; } Response::ResponseCode Server_ProtocolHandler::cmdListRooms(const Command_ListRooms & /*cmd*/, ResponseContainer &rc) { - if (authState == NotLoggedIn) - return Response::RespLoginNeeded; - - Event_ListRooms event; - QMapIterator roomIterator(server->getRooms()); - while (roomIterator.hasNext()) - roomIterator.next().value()->getInfo(*event.add_room_list(), false); - rc.enqueuePreResponseItem(ServerMessage::SESSION_EVENT, prepareSessionEvent(event)); - - acceptsRoomListChanges = true; - return Response::RespOk; + if (authState == NotLoggedIn) + return Response::RespLoginNeeded; + + Event_ListRooms event; + QMapIterator roomIterator(server->getRooms()); + while (roomIterator.hasNext()) + roomIterator.next().value()->getInfo(*event.add_room_list(), false); + rc.enqueuePreResponseItem(ServerMessage::SESSION_EVENT, prepareSessionEvent(event)); + + acceptsRoomListChanges = true; + return Response::RespOk; } Response::ResponseCode Server_ProtocolHandler::cmdJoinRoom(const Command_JoinRoom &cmd, ResponseContainer &rc) { - if (authState == NotLoggedIn) - return Response::RespLoginNeeded; - - if (rooms.contains(cmd.room_id())) - return Response::RespContextError; - - QReadLocker serverLocker(&server->roomsLock); - Server_Room *r = server->getRooms().value(cmd.room_id(), 0); - if (!r) - return Response::RespNameNotFound; - - r->addClient(this); - rooms.insert(r->getId(), r); - - Event_RoomSay joinMessageEvent; - joinMessageEvent.set_message(r->getJoinMessage().toStdString()); - rc.enqueuePostResponseItem(ServerMessage::ROOM_EVENT, r->prepareRoomEvent(joinMessageEvent)); - - Response_JoinRoom *re = new Response_JoinRoom; - r->getInfo(*re->mutable_room_info(), true); - - rc.setResponseExtension(re); - return Response::RespOk; + if (authState == NotLoggedIn) + return Response::RespLoginNeeded; + + if (rooms.contains(cmd.room_id())) + return Response::RespContextError; + + QReadLocker serverLocker(&server->roomsLock); + Server_Room *r = server->getRooms().value(cmd.room_id(), 0); + if (!r) + return Response::RespNameNotFound; + + r->addClient(this); + rooms.insert(r->getId(), r); + + Event_RoomSay joinMessageEvent; + joinMessageEvent.set_message(r->getJoinMessage().toStdString()); + rc.enqueuePostResponseItem(ServerMessage::ROOM_EVENT, r->prepareRoomEvent(joinMessageEvent)); + + Response_JoinRoom *re = new Response_JoinRoom; + r->getInfo(*re->mutable_room_info(), true); + + rc.setResponseExtension(re); + return Response::RespOk; } Response::ResponseCode Server_ProtocolHandler::cmdListUsers(const Command_ListUsers & /*cmd*/, ResponseContainer &rc) { - if (authState == NotLoggedIn) - return Response::RespLoginNeeded; - - Response_ListUsers *re = new Response_ListUsers; - server->clientsLock.lockForRead(); - QMapIterator userIterator = server->getUsers(); - while (userIterator.hasNext()) - re->add_user_list()->CopyFrom(userIterator.next().value()->copyUserInfo(false)); - QMapIterator extIterator = server->getExternalUsers(); - while (extIterator.hasNext()) - re->add_user_list()->CopyFrom(extIterator.next().value()->copyUserInfo(false)); - - acceptsUserListChanges = true; - server->clientsLock.unlock(); - - rc.setResponseExtension(re); - return Response::RespOk; + if (authState == NotLoggedIn) + return Response::RespLoginNeeded; + + Response_ListUsers *re = new Response_ListUsers; + server->clientsLock.lockForRead(); + QMapIterator userIterator = server->getUsers(); + while (userIterator.hasNext()) + re->add_user_list()->CopyFrom(userIterator.next().value()->copyUserInfo(false)); + QMapIterator extIterator = server->getExternalUsers(); + while (extIterator.hasNext()) + re->add_user_list()->CopyFrom(extIterator.next().value()->copyUserInfo(false)); + + acceptsUserListChanges = true; + server->clientsLock.unlock(); + + rc.setResponseExtension(re); + return Response::RespOk; } Response::ResponseCode Server_ProtocolHandler::cmdLeaveRoom(const Command_LeaveRoom & /*cmd*/, Server_Room *room, ResponseContainer & /*rc*/) { - rooms.remove(room->getId()); - room->removeClient(this); - return Response::RespOk; + rooms.remove(room->getId()); + room->removeClient(this); + return Response::RespOk; } Response::ResponseCode Server_ProtocolHandler::cmdRoomSay(const Command_RoomSay &cmd, Server_Room *room, ResponseContainer & /*rc*/) { - QString msg = QString::fromStdString(cmd.message()); - - if (server->getMessageCountingInterval() > 0) { - int totalSize = 0, totalCount = 0; - if (messageSizeOverTime.isEmpty()) - messageSizeOverTime.prepend(0); - messageSizeOverTime[0] += msg.size(); - for (int i = 0; i < messageSizeOverTime.size(); ++i) - totalSize += messageSizeOverTime[i]; - - if (messageCountOverTime.isEmpty()) - messageCountOverTime.prepend(0); - ++messageCountOverTime[0]; - for (int i = 0; i < messageCountOverTime.size(); ++i) - totalCount += messageCountOverTime[i]; - - if ((totalSize > server->getMaxMessageSizePerInterval()) || (totalCount > server->getMaxMessageCountPerInterval())) - return Response::RespChatFlood; - } - msg.replace(QChar('\n'), QChar(' ')); - - room->say(QString::fromStdString(userInfo->name()), msg); - return Response::RespOk; + QString msg = QString::fromStdString(cmd.message()); + + if (server->getMessageCountingInterval() > 0) { + int totalSize = 0, totalCount = 0; + if (messageSizeOverTime.isEmpty()) + messageSizeOverTime.prepend(0); + messageSizeOverTime[0] += msg.size(); + for (int i = 0; i < messageSizeOverTime.size(); ++i) + totalSize += messageSizeOverTime[i]; + + if (messageCountOverTime.isEmpty()) + messageCountOverTime.prepend(0); + ++messageCountOverTime[0]; + for (int i = 0; i < messageCountOverTime.size(); ++i) + totalCount += messageCountOverTime[i]; + + if ((totalSize > server->getMaxMessageSizePerInterval()) || (totalCount > server->getMaxMessageCountPerInterval())) + return Response::RespChatFlood; + } + msg.replace(QChar('\n'), QChar(' ')); + + room->say(QString::fromStdString(userInfo->name()), msg); + return Response::RespOk; } Response::ResponseCode Server_ProtocolHandler::cmdCreateGame(const Command_CreateGame &cmd, Server_Room *room, ResponseContainer &rc) { - if (authState == NotLoggedIn) - return Response::RespLoginNeeded; - const int gameId = databaseInterface->getNextGameId(); - if (gameId == -1) - return Response::RespInternalError; - - if (server->getMaxGamesPerUser() > 0) - if (room->getGamesCreatedByUser(QString::fromStdString(userInfo->name())) >= server->getMaxGamesPerUser()) - return Response::RespContextError; - - QList gameTypes; - for (int i = cmd.game_type_ids_size() - 1; i >= 0; --i) - gameTypes.append(cmd.game_type_ids(i)); - - QString description = QString::fromStdString(cmd.description()); - if (description.size() > 60) - description = description.left(60); - - Server_Game *game = new Server_Game(copyUserInfo(false), gameId, description, QString::fromStdString(cmd.password()), cmd.max_players(), gameTypes, cmd.only_buddies(), cmd.only_registered(), cmd.spectators_allowed(), cmd.spectators_need_password(), cmd.spectators_can_talk(), cmd.spectators_see_everything(), room); - game->addPlayer(this, rc, false, false); - room->addGame(game); - - return Response::RespOk; + if (authState == NotLoggedIn) + return Response::RespLoginNeeded; + const int gameId = databaseInterface->getNextGameId(); + if (gameId == -1) + return Response::RespInternalError; + + if (server->getMaxGamesPerUser() > 0) + if (room->getGamesCreatedByUser(QString::fromStdString(userInfo->name())) >= server->getMaxGamesPerUser()) + return Response::RespContextError; + + QList gameTypes; + for (int i = cmd.game_type_ids_size() - 1; i >= 0; --i) + gameTypes.append(cmd.game_type_ids(i)); + + QString description = QString::fromStdString(cmd.description()); + if (description.size() > 60) + description = description.left(60); + + Server_Game *game = new Server_Game(copyUserInfo(false), gameId, description, QString::fromStdString(cmd.password()), cmd.max_players(), gameTypes, cmd.only_buddies(), cmd.only_registered(), cmd.spectators_allowed(), cmd.spectators_need_password(), cmd.spectators_can_talk(), cmd.spectators_see_everything(), room); + game->addPlayer(this, rc, false, false); + room->addGame(game); + + return Response::RespOk; } Response::ResponseCode Server_ProtocolHandler::cmdJoinGame(const Command_JoinGame &cmd, Server_Room *room, ResponseContainer &rc) { - if (authState == NotLoggedIn) - return Response::RespLoginNeeded; - - return room->processJoinGameCommand(cmd, rc, this); + if (authState == NotLoggedIn) + return Response::RespLoginNeeded; + + return room->processJoinGameCommand(cmd, rc, this); } diff --git a/common/server_protocolhandler.h b/common/server_protocolhandler.h index 56165c80..0cea37ae 100644 --- a/common/server_protocolhandler.h +++ b/common/server_protocolhandler.h @@ -40,64 +40,64 @@ class Command_CreateGame; class Command_JoinGame; class Server_ProtocolHandler : public QObject, public Server_AbstractUserInterface { - Q_OBJECT + Q_OBJECT protected: - QMap rooms; - - bool deleted; - Server_DatabaseInterface *databaseInterface; - AuthenticationResult authState; - bool acceptsUserListChanges; - bool acceptsRoomListChanges; - virtual void logDebugMessage(const QString &message) { } + QMap rooms; + + bool deleted; + Server_DatabaseInterface *databaseInterface; + AuthenticationResult authState; + bool acceptsUserListChanges; + bool acceptsRoomListChanges; + virtual void logDebugMessage(const QString &message) { } private: - QList messageSizeOverTime, messageCountOverTime; - int timeRunning, lastDataReceived; - QTimer *pingClock; + QList messageSizeOverTime, messageCountOverTime; + int timeRunning, lastDataReceived; + QTimer *pingClock; - virtual void transmitProtocolItem(const ServerMessage &item) = 0; - - Response::ResponseCode cmdPing(const Command_Ping &cmd, ResponseContainer &rc); - Response::ResponseCode cmdLogin(const Command_Login &cmd, ResponseContainer &rc); - Response::ResponseCode cmdMessage(const Command_Message &cmd, ResponseContainer &rc); - Response::ResponseCode cmdGetGamesOfUser(const Command_GetGamesOfUser &cmd, ResponseContainer &rc); - Response::ResponseCode cmdGetUserInfo(const Command_GetUserInfo &cmd, ResponseContainer &rc); - Response::ResponseCode cmdListRooms(const Command_ListRooms &cmd, ResponseContainer &rc); - Response::ResponseCode cmdJoinRoom(const Command_JoinRoom &cmd, ResponseContainer &rc); - Response::ResponseCode cmdListUsers(const Command_ListUsers &cmd, ResponseContainer &rc); - Response::ResponseCode cmdLeaveRoom(const Command_LeaveRoom &cmd, Server_Room *room, ResponseContainer &rc); - Response::ResponseCode cmdRoomSay(const Command_RoomSay &cmd, Server_Room *room, ResponseContainer &rc); - Response::ResponseCode cmdCreateGame(const Command_CreateGame &cmd, Server_Room *room, ResponseContainer &rc); - Response::ResponseCode cmdJoinGame(const Command_JoinGame &cmd, Server_Room *room, ResponseContainer &rc); - - Response::ResponseCode processSessionCommandContainer(const CommandContainer &cont, ResponseContainer &rc); - virtual Response::ResponseCode processExtendedSessionCommand(int cmdType, const SessionCommand &cmd, ResponseContainer &rc) { return Response::RespFunctionNotAllowed; } - Response::ResponseCode processRoomCommandContainer(const CommandContainer &cont, ResponseContainer &rc); - Response::ResponseCode processGameCommandContainer(const CommandContainer &cont, ResponseContainer &rc); - Response::ResponseCode processModeratorCommandContainer(const CommandContainer &cont, ResponseContainer &rc); - virtual Response::ResponseCode processExtendedModeratorCommand(int cmdType, const ModeratorCommand &cmd, ResponseContainer &rc) { return Response::RespFunctionNotAllowed; } - Response::ResponseCode processAdminCommandContainer(const CommandContainer &cont, ResponseContainer &rc); - virtual Response::ResponseCode processExtendedAdminCommand(int cmdType, const AdminCommand &cmd, ResponseContainer &rc) { return Response::RespFunctionNotAllowed; } + virtual void transmitProtocolItem(const ServerMessage &item) = 0; + + Response::ResponseCode cmdPing(const Command_Ping &cmd, ResponseContainer &rc); + Response::ResponseCode cmdLogin(const Command_Login &cmd, ResponseContainer &rc); + Response::ResponseCode cmdMessage(const Command_Message &cmd, ResponseContainer &rc); + Response::ResponseCode cmdGetGamesOfUser(const Command_GetGamesOfUser &cmd, ResponseContainer &rc); + Response::ResponseCode cmdGetUserInfo(const Command_GetUserInfo &cmd, ResponseContainer &rc); + Response::ResponseCode cmdListRooms(const Command_ListRooms &cmd, ResponseContainer &rc); + Response::ResponseCode cmdJoinRoom(const Command_JoinRoom &cmd, ResponseContainer &rc); + Response::ResponseCode cmdListUsers(const Command_ListUsers &cmd, ResponseContainer &rc); + Response::ResponseCode cmdLeaveRoom(const Command_LeaveRoom &cmd, Server_Room *room, ResponseContainer &rc); + Response::ResponseCode cmdRoomSay(const Command_RoomSay &cmd, Server_Room *room, ResponseContainer &rc); + Response::ResponseCode cmdCreateGame(const Command_CreateGame &cmd, Server_Room *room, ResponseContainer &rc); + Response::ResponseCode cmdJoinGame(const Command_JoinGame &cmd, Server_Room *room, ResponseContainer &rc); + + Response::ResponseCode processSessionCommandContainer(const CommandContainer &cont, ResponseContainer &rc); + virtual Response::ResponseCode processExtendedSessionCommand(int cmdType, const SessionCommand &cmd, ResponseContainer &rc) { return Response::RespFunctionNotAllowed; } + Response::ResponseCode processRoomCommandContainer(const CommandContainer &cont, ResponseContainer &rc); + Response::ResponseCode processGameCommandContainer(const CommandContainer &cont, ResponseContainer &rc); + Response::ResponseCode processModeratorCommandContainer(const CommandContainer &cont, ResponseContainer &rc); + virtual Response::ResponseCode processExtendedModeratorCommand(int cmdType, const ModeratorCommand &cmd, ResponseContainer &rc) { return Response::RespFunctionNotAllowed; } + Response::ResponseCode processAdminCommandContainer(const CommandContainer &cont, ResponseContainer &rc); + virtual Response::ResponseCode processExtendedAdminCommand(int cmdType, const AdminCommand &cmd, ResponseContainer &rc) { return Response::RespFunctionNotAllowed; } private slots: - void pingClockTimeout(); + void pingClockTimeout(); public slots: - void prepareDestroy(); + void prepareDestroy(); public: - Server_ProtocolHandler(Server *_server, Server_DatabaseInterface *_databaseInterface, QObject *parent = 0); - ~Server_ProtocolHandler(); - - bool getAcceptsUserListChanges() const { return acceptsUserListChanges; } - bool getAcceptsRoomListChanges() const { return acceptsRoomListChanges; } - virtual QString getAddress() const = 0; - Server_DatabaseInterface *getDatabaseInterface() const { return databaseInterface; } + Server_ProtocolHandler(Server *_server, Server_DatabaseInterface *_databaseInterface, QObject *parent = 0); + ~Server_ProtocolHandler(); + + bool getAcceptsUserListChanges() const { return acceptsUserListChanges; } + bool getAcceptsRoomListChanges() const { return acceptsRoomListChanges; } + virtual QString getAddress() const = 0; + Server_DatabaseInterface *getDatabaseInterface() const { return databaseInterface; } - int getLastCommandTime() const { return timeRunning - lastDataReceived; } - void processCommandContainer(const CommandContainer &cont); - - void sendProtocolItem(const Response &item); - void sendProtocolItem(const SessionEvent &item); - void sendProtocolItem(const GameEventContainer &item); - void sendProtocolItem(const RoomEvent &item); + int getLastCommandTime() const { return timeRunning - lastDataReceived; } + void processCommandContainer(const CommandContainer &cont); + + void sendProtocolItem(const Response &item); + void sendProtocolItem(const SessionEvent &item); + void sendProtocolItem(const GameEventContainer &item); + void sendProtocolItem(const RoomEvent &item); }; #endif diff --git a/common/server_remoteuserinterface.cpp b/common/server_remoteuserinterface.cpp index cd0e3031..7bbcf963 100644 --- a/common/server_remoteuserinterface.cpp +++ b/common/server_remoteuserinterface.cpp @@ -4,20 +4,20 @@ void Server_RemoteUserInterface::sendProtocolItem(const Response &item) { - server->sendIsl_Response(item, userInfo->server_id(), userInfo->session_id()); + server->sendIsl_Response(item, userInfo->server_id(), userInfo->session_id()); } void Server_RemoteUserInterface::sendProtocolItem(const SessionEvent &item) { - server->sendIsl_SessionEvent(item, userInfo->server_id(), userInfo->session_id()); + server->sendIsl_SessionEvent(item, userInfo->server_id(), userInfo->session_id()); } void Server_RemoteUserInterface::sendProtocolItem(const GameEventContainer &item) { - server->sendIsl_GameEventContainer(item, userInfo->server_id(), userInfo->session_id()); + server->sendIsl_GameEventContainer(item, userInfo->server_id(), userInfo->session_id()); } void Server_RemoteUserInterface::sendProtocolItem(const RoomEvent &item) { - server->sendIsl_RoomEvent(item, userInfo->server_id(), userInfo->session_id()); + server->sendIsl_RoomEvent(item, userInfo->server_id(), userInfo->session_id()); } diff --git a/common/server_remoteuserinterface.h b/common/server_remoteuserinterface.h index d85b54a3..311f0516 100644 --- a/common/server_remoteuserinterface.h +++ b/common/server_remoteuserinterface.h @@ -5,14 +5,14 @@ class Server_RemoteUserInterface : public Server_AbstractUserInterface { public: - Server_RemoteUserInterface(Server *_server, const ServerInfo_User_Container &_userInfoContainer) : Server_AbstractUserInterface(_server, _userInfoContainer) { } - - int getLastCommandTime() const { return 0; } - - void sendProtocolItem(const Response &item); - void sendProtocolItem(const SessionEvent &item); - void sendProtocolItem(const GameEventContainer &item); - void sendProtocolItem(const RoomEvent &item); + Server_RemoteUserInterface(Server *_server, const ServerInfo_User_Container &_userInfoContainer) : Server_AbstractUserInterface(_server, _userInfoContainer) { } + + int getLastCommandTime() const { return 0; } + + void sendProtocolItem(const Response &item); + void sendProtocolItem(const SessionEvent &item); + void sendProtocolItem(const GameEventContainer &item); + void sendProtocolItem(const RoomEvent &item); }; #endif diff --git a/common/server_response_containers.cpp b/common/server_response_containers.cpp index bc36222e..0c95e537 100644 --- a/common/server_response_containers.cpp +++ b/common/server_response_containers.cpp @@ -3,64 +3,64 @@ #include "server_game.h" GameEventStorageItem::GameEventStorageItem(const ::google::protobuf::Message &_event, int _playerId, EventRecipients _recipients) - : event(new GameEvent), recipients(_recipients) + : event(new GameEvent), recipients(_recipients) { - event->GetReflection()->MutableMessage(event, _event.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(_event); - event->set_player_id(_playerId); + event->GetReflection()->MutableMessage(event, _event.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(_event); + event->set_player_id(_playerId); } GameEventStorageItem::~GameEventStorageItem() { - delete event; + delete event; } GameEventStorage::GameEventStorage() - : gameEventContext(0) + : gameEventContext(0) { } GameEventStorage::~GameEventStorage() { - delete gameEventContext; - for (int i = 0; i < gameEventList.size(); ++i) - delete gameEventList[i]; + delete gameEventContext; + for (int i = 0; i < gameEventList.size(); ++i) + delete gameEventList[i]; } void GameEventStorage::setGameEventContext(const ::google::protobuf::Message &_gameEventContext) { - delete gameEventContext; - gameEventContext = new GameEventContext; - gameEventContext->GetReflection()->MutableMessage(gameEventContext, _gameEventContext.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(_gameEventContext); + delete gameEventContext; + gameEventContext = new GameEventContext; + gameEventContext->GetReflection()->MutableMessage(gameEventContext, _gameEventContext.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(_gameEventContext); } void GameEventStorage::enqueueGameEvent(const ::google::protobuf::Message &event, int playerId, GameEventStorageItem::EventRecipients recipients, int _privatePlayerId) { - gameEventList.append(new GameEventStorageItem(event, playerId, recipients)); - if (_privatePlayerId != -1) - privatePlayerId = _privatePlayerId; + gameEventList.append(new GameEventStorageItem(event, playerId, recipients)); + if (_privatePlayerId != -1) + privatePlayerId = _privatePlayerId; } void GameEventStorage::sendToGame(Server_Game *game) { - if (gameEventList.isEmpty()) - return; - - GameEventContainer *contPrivate = new GameEventContainer; - GameEventContainer *contOthers = new GameEventContainer; - for (int i = 0; i < gameEventList.size(); ++i) { - const GameEvent &event = gameEventList[i]->getGameEvent(); - const GameEventStorageItem::EventRecipients recipients = gameEventList[i]->getRecipients(); - if (recipients.testFlag(GameEventStorageItem::SendToPrivate)) - contPrivate->add_event_list()->CopyFrom(event); - if (recipients.testFlag(GameEventStorageItem::SendToOthers)) - contOthers->add_event_list()->CopyFrom(event); - } - if (gameEventContext) { - contPrivate->mutable_context()->CopyFrom(*gameEventContext); - contOthers->mutable_context()->CopyFrom(*gameEventContext); - } - game->sendGameEventContainer(contPrivate, GameEventStorageItem::SendToPrivate, privatePlayerId); - game->sendGameEventContainer(contOthers, GameEventStorageItem::SendToOthers, privatePlayerId); + if (gameEventList.isEmpty()) + return; + + GameEventContainer *contPrivate = new GameEventContainer; + GameEventContainer *contOthers = new GameEventContainer; + for (int i = 0; i < gameEventList.size(); ++i) { + const GameEvent &event = gameEventList[i]->getGameEvent(); + const GameEventStorageItem::EventRecipients recipients = gameEventList[i]->getRecipients(); + if (recipients.testFlag(GameEventStorageItem::SendToPrivate)) + contPrivate->add_event_list()->CopyFrom(event); + if (recipients.testFlag(GameEventStorageItem::SendToOthers)) + contOthers->add_event_list()->CopyFrom(event); + } + if (gameEventContext) { + contPrivate->mutable_context()->CopyFrom(*gameEventContext); + contOthers->mutable_context()->CopyFrom(*gameEventContext); + } + game->sendGameEventContainer(contPrivate, GameEventStorageItem::SendToPrivate, privatePlayerId); + game->sendGameEventContainer(contOthers, GameEventStorageItem::SendToOthers, privatePlayerId); } ResponseContainer::ResponseContainer(int _cmdId) @@ -70,9 +70,9 @@ ResponseContainer::ResponseContainer(int _cmdId) ResponseContainer::~ResponseContainer() { - delete responseExtension; - for (int i = 0; i < preResponseQueue.size(); ++i) - delete preResponseQueue[i].second; - for (int i = 0; i < postResponseQueue.size(); ++i) - delete postResponseQueue[i].second; + delete responseExtension; + for (int i = 0; i < preResponseQueue.size(); ++i) + delete preResponseQueue[i].second; + for (int i = 0; i < postResponseQueue.size(); ++i) + delete postResponseQueue[i].second; } diff --git a/common/server_response_containers.h b/common/server_response_containers.h index 9220cdac..c6c9da74 100644 --- a/common/server_response_containers.h +++ b/common/server_response_containers.h @@ -9,54 +9,54 @@ class Server_Game; class GameEventStorageItem { public: - enum EventRecipient { SendToPrivate = 0x01, SendToOthers = 0x02}; - Q_DECLARE_FLAGS(EventRecipients, EventRecipient) + enum EventRecipient { SendToPrivate = 0x01, SendToOthers = 0x02}; + Q_DECLARE_FLAGS(EventRecipients, EventRecipient) private: - GameEvent *event; - EventRecipients recipients; + GameEvent *event; + EventRecipients recipients; public: - GameEventStorageItem(const ::google::protobuf::Message &_event, int _playerId, EventRecipients _recipients); - ~GameEventStorageItem(); - - const GameEvent &getGameEvent() const { return *event; } - EventRecipients getRecipients() const { return recipients; } + GameEventStorageItem(const ::google::protobuf::Message &_event, int _playerId, EventRecipients _recipients); + ~GameEventStorageItem(); + + const GameEvent &getGameEvent() const { return *event; } + EventRecipients getRecipients() const { return recipients; } }; Q_DECLARE_OPERATORS_FOR_FLAGS(GameEventStorageItem::EventRecipients) class GameEventStorage { private: - ::google::protobuf::Message *gameEventContext; - QList gameEventList; - int privatePlayerId; + ::google::protobuf::Message *gameEventContext; + QList gameEventList; + int privatePlayerId; public: - GameEventStorage(); - ~GameEventStorage(); - - void setGameEventContext(const ::google::protobuf::Message &_gameEventContext); - ::google::protobuf::Message *getGameEventContext() const { return gameEventContext; } - const QList &getGameEventList() const { return gameEventList; } - int getPrivatePlayerId() const { return privatePlayerId; } - - void enqueueGameEvent(const ::google::protobuf::Message &event, int playerId, GameEventStorageItem::EventRecipients recipients = GameEventStorageItem::SendToPrivate | GameEventStorageItem::SendToOthers, int _privatePlayerId = -1); - void sendToGame(Server_Game *game); + GameEventStorage(); + ~GameEventStorage(); + + void setGameEventContext(const ::google::protobuf::Message &_gameEventContext); + ::google::protobuf::Message *getGameEventContext() const { return gameEventContext; } + const QList &getGameEventList() const { return gameEventList; } + int getPrivatePlayerId() const { return privatePlayerId; } + + void enqueueGameEvent(const ::google::protobuf::Message &event, int playerId, GameEventStorageItem::EventRecipients recipients = GameEventStorageItem::SendToPrivate | GameEventStorageItem::SendToOthers, int _privatePlayerId = -1); + void sendToGame(Server_Game *game); }; class ResponseContainer { private: - int cmdId; - ::google::protobuf::Message *responseExtension; - QList > preResponseQueue, postResponseQueue; + int cmdId; + ::google::protobuf::Message *responseExtension; + QList > preResponseQueue, postResponseQueue; public: - ResponseContainer(int _cmdId); - ~ResponseContainer(); - - int getCmdId() const { return cmdId; } - void setResponseExtension(::google::protobuf::Message *_responseExtension) { responseExtension = _responseExtension; } - ::google::protobuf::Message *getResponseExtension() const { return responseExtension; } - void enqueuePreResponseItem(ServerMessage::MessageType type, ::google::protobuf::Message *item) { preResponseQueue.append(qMakePair(type, item)); } - void enqueuePostResponseItem(ServerMessage::MessageType type, ::google::protobuf::Message *item) { postResponseQueue.append(qMakePair(type, item)); } - const QList > &getPreResponseQueue() const { return preResponseQueue; } - const QList > &getPostResponseQueue() const { return postResponseQueue; } + ResponseContainer(int _cmdId); + ~ResponseContainer(); + + int getCmdId() const { return cmdId; } + void setResponseExtension(::google::protobuf::Message *_responseExtension) { responseExtension = _responseExtension; } + ::google::protobuf::Message *getResponseExtension() const { return responseExtension; } + void enqueuePreResponseItem(ServerMessage::MessageType type, ::google::protobuf::Message *item) { preResponseQueue.append(qMakePair(type, item)); } + void enqueuePostResponseItem(ServerMessage::MessageType type, ::google::protobuf::Message *item) { postResponseQueue.append(qMakePair(type, item)); } + const QList > &getPreResponseQueue() const { return preResponseQueue; } + const QList > &getPostResponseQueue() const { return postResponseQueue; } }; #endif diff --git a/common/server_room.cpp b/common/server_room.cpp index 4369e129..985fb543 100644 --- a/common/server_room.cpp +++ b/common/server_room.cpp @@ -13,326 +13,326 @@ #include Server_Room::Server_Room(int _id, const QString &_name, const QString &_description, bool _autoJoin, const QString &_joinMessage, const QStringList &_gameTypes, Server *parent) - : QObject(parent), id(_id), name(_name), description(_description), autoJoin(_autoJoin), joinMessage(_joinMessage), gameTypes(_gameTypes), gamesLock(QReadWriteLock::Recursive) + : QObject(parent), id(_id), name(_name), description(_description), autoJoin(_autoJoin), joinMessage(_joinMessage), gameTypes(_gameTypes), gamesLock(QReadWriteLock::Recursive) { - connect(this, SIGNAL(gameListChanged(ServerInfo_Game)), this, SLOT(broadcastGameListUpdate(ServerInfo_Game)), Qt::QueuedConnection); + connect(this, SIGNAL(gameListChanged(ServerInfo_Game)), this, SLOT(broadcastGameListUpdate(ServerInfo_Game)), Qt::QueuedConnection); } Server_Room::~Server_Room() { - qDebug("Server_Room destructor"); - - gamesLock.lockForWrite(); - const QList gameList = games.values(); - for (int i = 0; i < gameList.size(); ++i) - delete gameList[i]; - games.clear(); - gamesLock.unlock(); - - usersLock.lockForWrite(); - users.clear(); - usersLock.unlock(); + qDebug("Server_Room destructor"); + + gamesLock.lockForWrite(); + const QList gameList = games.values(); + for (int i = 0; i < gameList.size(); ++i) + delete gameList[i]; + games.clear(); + gamesLock.unlock(); + + usersLock.lockForWrite(); + users.clear(); + usersLock.unlock(); } Server *Server_Room::getServer() const { - return static_cast(parent()); + return static_cast(parent()); } const ServerInfo_Room &Server_Room::getInfo(ServerInfo_Room &result, bool complete, bool showGameTypes, bool includeExternalData) const { - result.set_room_id(id); - - result.set_name(name.toStdString()); - result.set_description(description.toStdString()); - result.set_auto_join(autoJoin); - - gamesLock.lockForRead(); - result.set_game_count(games.size() + externalGames.size()); - if (complete) { - QMapIterator gameIterator(games); - while (gameIterator.hasNext()) - gameIterator.next().value()->getInfo(*result.add_game_list()); - if (includeExternalData) { - QMapIterator externalGameIterator(externalGames); - while (externalGameIterator.hasNext()) - result.add_game_list()->CopyFrom(externalGameIterator.next().value()); - } - } - gamesLock.unlock(); - - usersLock.lockForRead(); - result.set_player_count(users.size() + externalUsers.size()); - if (complete) { - QMapIterator userIterator(users); - while (userIterator.hasNext()) - result.add_user_list()->CopyFrom(userIterator.next().value()->copyUserInfo(false)); - if (includeExternalData) { - QMapIterator externalUserIterator(externalUsers); - while (externalUserIterator.hasNext()) - result.add_user_list()->CopyFrom(externalUserIterator.next().value().copyUserInfo(false)); - } - } - usersLock.unlock(); - - if (complete || showGameTypes) - for (int i = 0; i < gameTypes.size(); ++i) { - ServerInfo_GameType *gameTypeInfo = result.add_gametype_list(); - gameTypeInfo->set_game_type_id(i); - gameTypeInfo->set_description(gameTypes[i].toStdString()); - } - - return result; + result.set_room_id(id); + + result.set_name(name.toStdString()); + result.set_description(description.toStdString()); + result.set_auto_join(autoJoin); + + gamesLock.lockForRead(); + result.set_game_count(games.size() + externalGames.size()); + if (complete) { + QMapIterator gameIterator(games); + while (gameIterator.hasNext()) + gameIterator.next().value()->getInfo(*result.add_game_list()); + if (includeExternalData) { + QMapIterator externalGameIterator(externalGames); + while (externalGameIterator.hasNext()) + result.add_game_list()->CopyFrom(externalGameIterator.next().value()); + } + } + gamesLock.unlock(); + + usersLock.lockForRead(); + result.set_player_count(users.size() + externalUsers.size()); + if (complete) { + QMapIterator userIterator(users); + while (userIterator.hasNext()) + result.add_user_list()->CopyFrom(userIterator.next().value()->copyUserInfo(false)); + if (includeExternalData) { + QMapIterator externalUserIterator(externalUsers); + while (externalUserIterator.hasNext()) + result.add_user_list()->CopyFrom(externalUserIterator.next().value().copyUserInfo(false)); + } + } + usersLock.unlock(); + + if (complete || showGameTypes) + for (int i = 0; i < gameTypes.size(); ++i) { + ServerInfo_GameType *gameTypeInfo = result.add_gametype_list(); + gameTypeInfo->set_game_type_id(i); + gameTypeInfo->set_description(gameTypes[i].toStdString()); + } + + return result; } RoomEvent *Server_Room::prepareRoomEvent(const ::google::protobuf::Message &roomEvent) { - RoomEvent *event = new RoomEvent; - event->set_room_id(id); - event->GetReflection()->MutableMessage(event, roomEvent.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(roomEvent); - return event; + RoomEvent *event = new RoomEvent; + event->set_room_id(id); + event->GetReflection()->MutableMessage(event, roomEvent.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(roomEvent); + return event; } void Server_Room::addClient(Server_ProtocolHandler *client) { - Event_JoinRoom event; - event.mutable_user_info()->CopyFrom(client->copyUserInfo(false)); - sendRoomEvent(prepareRoomEvent(event)); - - ServerInfo_Room roomInfo; - roomInfo.set_room_id(id); - - usersLock.lockForWrite(); - users.insert(QString::fromStdString(client->getUserInfo()->name()), client); - roomInfo.set_player_count(users.size() + externalUsers.size()); - usersLock.unlock(); - - // XXX This can be removed during the next client update. - gamesLock.lockForRead(); - roomInfo.set_game_count(games.size() + externalGames.size()); - gamesLock.unlock(); - // ----------- - - emit roomInfoChanged(roomInfo); + Event_JoinRoom event; + event.mutable_user_info()->CopyFrom(client->copyUserInfo(false)); + sendRoomEvent(prepareRoomEvent(event)); + + ServerInfo_Room roomInfo; + roomInfo.set_room_id(id); + + usersLock.lockForWrite(); + users.insert(QString::fromStdString(client->getUserInfo()->name()), client); + roomInfo.set_player_count(users.size() + externalUsers.size()); + usersLock.unlock(); + + // XXX This can be removed during the next client update. + gamesLock.lockForRead(); + roomInfo.set_game_count(games.size() + externalGames.size()); + gamesLock.unlock(); + // ----------- + + emit roomInfoChanged(roomInfo); } void Server_Room::removeClient(Server_ProtocolHandler *client) { - usersLock.lockForWrite(); - users.remove(QString::fromStdString(client->getUserInfo()->name())); - - ServerInfo_Room roomInfo; - roomInfo.set_room_id(id); - roomInfo.set_player_count(users.size() + externalUsers.size()); - usersLock.unlock(); - - Event_LeaveRoom event; - event.set_name(client->getUserInfo()->name()); - sendRoomEvent(prepareRoomEvent(event)); - - // XXX This can be removed during the next client update. - gamesLock.lockForRead(); - roomInfo.set_game_count(games.size() + externalGames.size()); - gamesLock.unlock(); - // ----------- - - emit roomInfoChanged(roomInfo); + usersLock.lockForWrite(); + users.remove(QString::fromStdString(client->getUserInfo()->name())); + + ServerInfo_Room roomInfo; + roomInfo.set_room_id(id); + roomInfo.set_player_count(users.size() + externalUsers.size()); + usersLock.unlock(); + + Event_LeaveRoom event; + event.set_name(client->getUserInfo()->name()); + sendRoomEvent(prepareRoomEvent(event)); + + // XXX This can be removed during the next client update. + gamesLock.lockForRead(); + roomInfo.set_game_count(games.size() + externalGames.size()); + gamesLock.unlock(); + // ----------- + + emit roomInfoChanged(roomInfo); } void Server_Room::addExternalUser(const ServerInfo_User &userInfo) { - // This function is always called from the Server thread with server->roomsMutex locked. - ServerInfo_User_Container userInfoContainer(userInfo); - Event_JoinRoom event; - event.mutable_user_info()->CopyFrom(userInfoContainer.copyUserInfo(false)); - sendRoomEvent(prepareRoomEvent(event), false); - - ServerInfo_Room roomInfo; - roomInfo.set_room_id(id); + // This function is always called from the Server thread with server->roomsMutex locked. + ServerInfo_User_Container userInfoContainer(userInfo); + Event_JoinRoom event; + event.mutable_user_info()->CopyFrom(userInfoContainer.copyUserInfo(false)); + sendRoomEvent(prepareRoomEvent(event), false); + + ServerInfo_Room roomInfo; + roomInfo.set_room_id(id); - usersLock.lockForWrite(); - externalUsers.insert(QString::fromStdString(userInfo.name()), userInfoContainer); - roomInfo.set_player_count(users.size() + externalUsers.size()); - usersLock.unlock(); - - emit roomInfoChanged(roomInfo); + usersLock.lockForWrite(); + externalUsers.insert(QString::fromStdString(userInfo.name()), userInfoContainer); + roomInfo.set_player_count(users.size() + externalUsers.size()); + usersLock.unlock(); + + emit roomInfoChanged(roomInfo); } void Server_Room::removeExternalUser(const QString &name) { - // This function is always called from the Server thread with server->roomsMutex locked. - ServerInfo_Room roomInfo; - roomInfo.set_room_id(id); - - usersLock.lockForWrite(); - if (externalUsers.contains(name)) - externalUsers.remove(name); - roomInfo.set_player_count(users.size() + externalUsers.size()); - usersLock.unlock(); - - Event_LeaveRoom event; - event.set_name(name.toStdString()); - sendRoomEvent(prepareRoomEvent(event), false); - - emit roomInfoChanged(roomInfo); + // This function is always called from the Server thread with server->roomsMutex locked. + ServerInfo_Room roomInfo; + roomInfo.set_room_id(id); + + usersLock.lockForWrite(); + if (externalUsers.contains(name)) + externalUsers.remove(name); + roomInfo.set_player_count(users.size() + externalUsers.size()); + usersLock.unlock(); + + Event_LeaveRoom event; + event.set_name(name.toStdString()); + sendRoomEvent(prepareRoomEvent(event), false); + + emit roomInfoChanged(roomInfo); } void Server_Room::updateExternalGameList(const ServerInfo_Game &gameInfo) { - // This function is always called from the Server thread with server->roomsMutex locked. - ServerInfo_Room roomInfo; - roomInfo.set_room_id(id); - - gamesLock.lockForWrite(); - if (!gameInfo.has_player_count() && externalGames.contains(gameInfo.game_id())) - externalGames.remove(gameInfo.game_id()); - else - externalGames.insert(gameInfo.game_id(), gameInfo); - roomInfo.set_game_count(games.size() + externalGames.size()); - gamesLock.unlock(); - - broadcastGameListUpdate(gameInfo, false); - emit roomInfoChanged(roomInfo); + // This function is always called from the Server thread with server->roomsMutex locked. + ServerInfo_Room roomInfo; + roomInfo.set_room_id(id); + + gamesLock.lockForWrite(); + if (!gameInfo.has_player_count() && externalGames.contains(gameInfo.game_id())) + externalGames.remove(gameInfo.game_id()); + else + externalGames.insert(gameInfo.game_id(), gameInfo); + roomInfo.set_game_count(games.size() + externalGames.size()); + gamesLock.unlock(); + + broadcastGameListUpdate(gameInfo, false); + emit roomInfoChanged(roomInfo); } Response::ResponseCode Server_Room::processJoinGameCommand(const Command_JoinGame &cmd, ResponseContainer &rc, Server_AbstractUserInterface *userInterface) { - // This function is called from the Server thread and from the S_PH thread. - // server->roomsMutex is always locked. - - QReadLocker roomGamesLocker(&gamesLock); - Server_Game *g = games.value(cmd.game_id()); - if (!g) { - if (externalGames.contains(cmd.game_id())) { - CommandContainer cont; - cont.set_cmd_id(rc.getCmdId()); - RoomCommand *roomCommand = cont.add_room_command(); - roomCommand->GetReflection()->MutableMessage(roomCommand, cmd.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(cmd); - getServer()->sendIsl_RoomCommand(cont, externalGames.value(cmd.game_id()).server_id(), userInterface->getUserInfo()->session_id(), id); - - return Response::RespNothing; - } else - return Response::RespNameNotFound; - } - - QMutexLocker gameLocker(&g->gameMutex); - - Response::ResponseCode result = g->checkJoin(userInterface->getUserInfo(), QString::fromStdString(cmd.password()), cmd.spectator(), cmd.override_restrictions()); - if (result == Response::RespOk) - g->addPlayer(userInterface, rc, cmd.spectator()); - - return result; + // This function is called from the Server thread and from the S_PH thread. + // server->roomsMutex is always locked. + + QReadLocker roomGamesLocker(&gamesLock); + Server_Game *g = games.value(cmd.game_id()); + if (!g) { + if (externalGames.contains(cmd.game_id())) { + CommandContainer cont; + cont.set_cmd_id(rc.getCmdId()); + RoomCommand *roomCommand = cont.add_room_command(); + roomCommand->GetReflection()->MutableMessage(roomCommand, cmd.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(cmd); + getServer()->sendIsl_RoomCommand(cont, externalGames.value(cmd.game_id()).server_id(), userInterface->getUserInfo()->session_id(), id); + + return Response::RespNothing; + } else + return Response::RespNameNotFound; + } + + QMutexLocker gameLocker(&g->gameMutex); + + Response::ResponseCode result = g->checkJoin(userInterface->getUserInfo(), QString::fromStdString(cmd.password()), cmd.spectator(), cmd.override_restrictions()); + if (result == Response::RespOk) + g->addPlayer(userInterface, rc, cmd.spectator()); + + return result; } void Server_Room::say(const QString &userName, const QString &s, bool sendToIsl) { - Event_RoomSay event; - event.set_name(userName.toStdString()); - event.set_message(s.toStdString()); - sendRoomEvent(prepareRoomEvent(event), sendToIsl); + Event_RoomSay event; + event.set_name(userName.toStdString()); + event.set_message(s.toStdString()); + sendRoomEvent(prepareRoomEvent(event), sendToIsl); } void Server_Room::sendRoomEvent(RoomEvent *event, bool sendToIsl) { - usersLock.lockForRead(); - { - QMapIterator userIterator(users); - while (userIterator.hasNext()) - userIterator.next().value()->sendProtocolItem(*event); - } - usersLock.unlock(); - - if (sendToIsl) - static_cast(parent())->sendIsl_RoomEvent(*event); - - delete event; + usersLock.lockForRead(); + { + QMapIterator userIterator(users); + while (userIterator.hasNext()) + userIterator.next().value()->sendProtocolItem(*event); + } + usersLock.unlock(); + + if (sendToIsl) + static_cast(parent())->sendIsl_RoomEvent(*event); + + delete event; } void Server_Room::broadcastGameListUpdate(const ServerInfo_Game &gameInfo, bool sendToIsl) { - Event_ListGames event; - event.add_game_list()->CopyFrom(gameInfo); - sendRoomEvent(prepareRoomEvent(event), sendToIsl); + Event_ListGames event; + event.add_game_list()->CopyFrom(gameInfo); + sendRoomEvent(prepareRoomEvent(event), sendToIsl); } void Server_Room::addGame(Server_Game *game) { - ServerInfo_Room roomInfo; - roomInfo.set_room_id(id); - - gamesLock.lockForWrite(); - connect(game, SIGNAL(gameInfoChanged(ServerInfo_Game)), this, SLOT(broadcastGameListUpdate(ServerInfo_Game))); - - game->gameMutex.lock(); - games.insert(game->getGameId(), game); - ServerInfo_Game gameInfo; - game->getInfo(gameInfo); - roomInfo.set_game_count(games.size() + externalGames.size()); - game->gameMutex.unlock(); - gamesLock.unlock(); - - // XXX This can be removed during the next client update. - usersLock.lockForRead(); - roomInfo.set_player_count(users.size() + externalUsers.size()); - usersLock.unlock(); - // ----------- + ServerInfo_Room roomInfo; + roomInfo.set_room_id(id); + + gamesLock.lockForWrite(); + connect(game, SIGNAL(gameInfoChanged(ServerInfo_Game)), this, SLOT(broadcastGameListUpdate(ServerInfo_Game))); + + game->gameMutex.lock(); + games.insert(game->getGameId(), game); + ServerInfo_Game gameInfo; + game->getInfo(gameInfo); + roomInfo.set_game_count(games.size() + externalGames.size()); + game->gameMutex.unlock(); + gamesLock.unlock(); + + // XXX This can be removed during the next client update. + usersLock.lockForRead(); + roomInfo.set_player_count(users.size() + externalUsers.size()); + usersLock.unlock(); + // ----------- - emit gameListChanged(gameInfo); - emit roomInfoChanged(roomInfo); + emit gameListChanged(gameInfo); + emit roomInfoChanged(roomInfo); } void Server_Room::removeGame(Server_Game *game) { - // No need to lock gamesLock or gameMutex. This method is only - // called from ~Server_Game, which locks both mutexes anyway beforehand. - - disconnect(game, 0, this, 0); - - ServerInfo_Game gameInfo; - game->getInfo(gameInfo); - emit gameListChanged(gameInfo); - - games.remove(game->getGameId()); - - ServerInfo_Room roomInfo; - roomInfo.set_room_id(id); - roomInfo.set_game_count(games.size() + externalGames.size()); - - // XXX This can be removed during the next client update. - usersLock.lockForRead(); - roomInfo.set_player_count(users.size() + externalUsers.size()); - usersLock.unlock(); - // ----------- - - emit roomInfoChanged(roomInfo); + // No need to lock gamesLock or gameMutex. This method is only + // called from ~Server_Game, which locks both mutexes anyway beforehand. + + disconnect(game, 0, this, 0); + + ServerInfo_Game gameInfo; + game->getInfo(gameInfo); + emit gameListChanged(gameInfo); + + games.remove(game->getGameId()); + + ServerInfo_Room roomInfo; + roomInfo.set_room_id(id); + roomInfo.set_game_count(games.size() + externalGames.size()); + + // XXX This can be removed during the next client update. + usersLock.lockForRead(); + roomInfo.set_player_count(users.size() + externalUsers.size()); + usersLock.unlock(); + // ----------- + + emit roomInfoChanged(roomInfo); } int Server_Room::getGamesCreatedByUser(const QString &userName) const { - QReadLocker locker(&gamesLock); - - QMapIterator gamesIterator(games); - int result = 0; - while (gamesIterator.hasNext()) - if (gamesIterator.next().value()->getCreatorInfo()->name() == userName.toStdString()) - ++result; - return result; + QReadLocker locker(&gamesLock); + + QMapIterator gamesIterator(games); + int result = 0; + while (gamesIterator.hasNext()) + if (gamesIterator.next().value()->getCreatorInfo()->name() == userName.toStdString()) + ++result; + return result; } QList Server_Room::getGamesOfUser(const QString &userName) const { - QReadLocker locker(&gamesLock); - - QList result; - QMapIterator gamesIterator(games); - while (gamesIterator.hasNext()) { - Server_Game *game = gamesIterator.next().value(); - if (game->containsUser(userName)) { - ServerInfo_Game gameInfo; - game->getInfo(gameInfo); - result.append(gameInfo); - } - } - return result; + QReadLocker locker(&gamesLock); + + QList result; + QMapIterator gamesIterator(games); + while (gamesIterator.hasNext()) { + Server_Game *game = gamesIterator.next().value(); + if (game->containsUser(userName)) { + ServerInfo_Game gameInfo; + game->getInfo(gameInfo); + result.append(gameInfo); + } + } + return result; } diff --git a/common/server_room.h b/common/server_room.h index 355d89d2..bf91510c 100644 --- a/common/server_room.h +++ b/common/server_room.h @@ -24,58 +24,58 @@ class ResponseContainer; class Server_AbstractUserInterface; class Server_Room : public QObject { - Q_OBJECT + Q_OBJECT signals: - void roomInfoChanged(const ServerInfo_Room &roomInfo); - void gameListChanged(const ServerInfo_Game &gameInfo); + void roomInfoChanged(const ServerInfo_Room &roomInfo); + void gameListChanged(const ServerInfo_Game &gameInfo); private: - int id; - QString name; - QString description; - bool autoJoin; - QString joinMessage; - QStringList gameTypes; - QMap games; - QMap externalGames; - QMap users; - QMap externalUsers; + int id; + QString name; + QString description; + bool autoJoin; + QString joinMessage; + QStringList gameTypes; + QMap games; + QMap externalGames; + QMap users; + QMap externalUsers; private slots: - void broadcastGameListUpdate(const ServerInfo_Game &gameInfo, bool sendToIsl = true); + void broadcastGameListUpdate(const ServerInfo_Game &gameInfo, bool sendToIsl = true); public: - mutable QReadWriteLock usersLock; - mutable QReadWriteLock gamesLock; - Server_Room(int _id, const QString &_name, const QString &_description, bool _autoJoin, const QString &_joinMessage, const QStringList &_gameTypes, Server *parent); - ~Server_Room(); - int getId() const { return id; } - QString getName() const { return name; } - QString getDescription() const { return description; } - bool getAutoJoin() const { return autoJoin; } - QString getJoinMessage() const { return joinMessage; } - const QStringList &getGameTypes() const { return gameTypes; } - const QMap &getGames() const { return games; } - const QMap &getExternalGames() const { return externalGames; } - Server *getServer() const; - const ServerInfo_Room &getInfo(ServerInfo_Room &result, bool complete, bool showGameTypes = false, bool includeExternalData = true) const; - int getGamesCreatedByUser(const QString &name) const; - QList getGamesOfUser(const QString &name) const; - - void addClient(Server_ProtocolHandler *client); - void removeClient(Server_ProtocolHandler *client); - - void addExternalUser(const ServerInfo_User &userInfo); - void removeExternalUser(const QString &name); - const QMap &getExternalUsers() const { return externalUsers; } - void updateExternalGameList(const ServerInfo_Game &gameInfo); - - Response::ResponseCode processJoinGameCommand(const Command_JoinGame &cmd, ResponseContainer &rc, Server_AbstractUserInterface *userInterface); - - void say(const QString &userName, const QString &s, bool sendToIsl = true); - - void addGame(Server_Game *game); - void removeGame(Server_Game *game); - - void sendRoomEvent(RoomEvent *event, bool sendToIsl = true); - RoomEvent *prepareRoomEvent(const ::google::protobuf::Message &roomEvent); + mutable QReadWriteLock usersLock; + mutable QReadWriteLock gamesLock; + Server_Room(int _id, const QString &_name, const QString &_description, bool _autoJoin, const QString &_joinMessage, const QStringList &_gameTypes, Server *parent); + ~Server_Room(); + int getId() const { return id; } + QString getName() const { return name; } + QString getDescription() const { return description; } + bool getAutoJoin() const { return autoJoin; } + QString getJoinMessage() const { return joinMessage; } + const QStringList &getGameTypes() const { return gameTypes; } + const QMap &getGames() const { return games; } + const QMap &getExternalGames() const { return externalGames; } + Server *getServer() const; + const ServerInfo_Room &getInfo(ServerInfo_Room &result, bool complete, bool showGameTypes = false, bool includeExternalData = true) const; + int getGamesCreatedByUser(const QString &name) const; + QList getGamesOfUser(const QString &name) const; + + void addClient(Server_ProtocolHandler *client); + void removeClient(Server_ProtocolHandler *client); + + void addExternalUser(const ServerInfo_User &userInfo); + void removeExternalUser(const QString &name); + const QMap &getExternalUsers() const { return externalUsers; } + void updateExternalGameList(const ServerInfo_Game &gameInfo); + + Response::ResponseCode processJoinGameCommand(const Command_JoinGame &cmd, ResponseContainer &rc, Server_AbstractUserInterface *userInterface); + + void say(const QString &userName, const QString &s, bool sendToIsl = true); + + void addGame(Server_Game *game); + void removeGame(Server_Game *game); + + void sendRoomEvent(RoomEvent *event, bool sendToIsl = true); + RoomEvent *prepareRoomEvent(const ::google::protobuf::Message &roomEvent); }; #endif diff --git a/common/serverinfo_user_container.cpp b/common/serverinfo_user_container.cpp index deead4e0..14435f75 100644 --- a/common/serverinfo_user_container.cpp +++ b/common/serverinfo_user_container.cpp @@ -7,46 +7,46 @@ ServerInfo_User_Container::ServerInfo_User_Container(ServerInfo_User *_userInfo) } ServerInfo_User_Container::ServerInfo_User_Container(const ServerInfo_User &_userInfo) - : userInfo(new ServerInfo_User(_userInfo)) + : userInfo(new ServerInfo_User(_userInfo)) { } ServerInfo_User_Container::ServerInfo_User_Container(const ServerInfo_User_Container &other) { - if (other.userInfo) - userInfo = new ServerInfo_User(*other.userInfo); - else - userInfo = 0; + if (other.userInfo) + userInfo = new ServerInfo_User(*other.userInfo); + else + userInfo = 0; } ServerInfo_User_Container::~ServerInfo_User_Container() { - delete userInfo; + delete userInfo; } void ServerInfo_User_Container::setUserInfo(const ServerInfo_User &_userInfo) { - userInfo = new ServerInfo_User(_userInfo); + userInfo = new ServerInfo_User(_userInfo); } ServerInfo_User &ServerInfo_User_Container::copyUserInfo(ServerInfo_User &result, bool complete, bool internalInfo, bool sessionInfo) const { - if (userInfo) { - result.CopyFrom(*userInfo); - if (!sessionInfo) { - result.clear_session_id(); - result.clear_address(); - } - if (!internalInfo) - result.clear_id(); - if (!complete) - result.clear_avatar_bmp(); - } - return result; + if (userInfo) { + result.CopyFrom(*userInfo); + if (!sessionInfo) { + result.clear_session_id(); + result.clear_address(); + } + if (!internalInfo) + result.clear_id(); + if (!complete) + result.clear_avatar_bmp(); + } + return result; } ServerInfo_User ServerInfo_User_Container::copyUserInfo(bool complete, bool internalInfo, bool sessionInfo) const { - ServerInfo_User result; - return copyUserInfo(result, complete, internalInfo, sessionInfo); + ServerInfo_User result; + return copyUserInfo(result, complete, internalInfo, sessionInfo); } diff --git a/common/serverinfo_user_container.h b/common/serverinfo_user_container.h index 6cf87ab1..d7fb76f8 100644 --- a/common/serverinfo_user_container.h +++ b/common/serverinfo_user_container.h @@ -5,16 +5,16 @@ class ServerInfo_User; class ServerInfo_User_Container { protected: - ServerInfo_User *userInfo; + ServerInfo_User *userInfo; public: - ServerInfo_User_Container(ServerInfo_User *_userInfo = 0); - ServerInfo_User_Container(const ServerInfo_User &_userInfo); - ServerInfo_User_Container(const ServerInfo_User_Container &other); - virtual ~ServerInfo_User_Container(); - ServerInfo_User *getUserInfo() const { return userInfo; } - void setUserInfo(const ServerInfo_User &_userInfo); - ServerInfo_User ©UserInfo(ServerInfo_User &result, bool complete, bool internalInfo = false, bool sessionInfo = false) const; - ServerInfo_User copyUserInfo(bool complete, bool internalInfo = false, bool sessionInfo = false) const; + ServerInfo_User_Container(ServerInfo_User *_userInfo = 0); + ServerInfo_User_Container(const ServerInfo_User &_userInfo); + ServerInfo_User_Container(const ServerInfo_User_Container &other); + virtual ~ServerInfo_User_Container(); + ServerInfo_User *getUserInfo() const { return userInfo; } + void setUserInfo(const ServerInfo_User &_userInfo); + ServerInfo_User ©UserInfo(ServerInfo_User &result, bool complete, bool internalInfo = false, bool sessionInfo = false) const; + ServerInfo_User copyUserInfo(bool complete, bool internalInfo = false, bool sessionInfo = false) const; }; #endif