From befafa28ae6519e95b8225757bbcf9b460d24db8 Mon Sep 17 00:00:00 2001 From: Max-Wilhelm Bruker Date: Wed, 26 May 2010 21:36:54 +0200 Subject: [PATCH] Fixed elevation of spectator rights; added some spectator options; closes bug 0000005 --- cockatrice/src/dlg_creategame.cpp | 41 +++-- cockatrice/src/dlg_creategame.h | 9 +- cockatrice/src/gamesmodel.cpp | 4 +- cockatrice/src/handzone.cpp | 4 +- cockatrice/src/handzone.h | 2 +- cockatrice/src/messagelogwidget.cpp | 7 +- cockatrice/src/messagelogwidget.h | 1 + cockatrice/src/player.cpp | 2 +- cockatrice/src/tab_game.cpp | 25 ++- cockatrice/src/tab_game.h | 8 +- cockatrice/src/tab_server.cpp | 2 +- cockatrice/src/tab_supervisor.cpp | 2 +- cockatrice/translations/cockatrice_de.ts | 185 ++++++++++++---------- cockatrice/translations/cockatrice_en.ts | 187 +++++++++++++---------- common/protocol.cpp | 9 +- common/protocol.h | 3 + common/protocol_datastructures.cpp | 3 +- common/protocol_datastructures.h | 3 +- common/protocol_items.cpp | 9 +- common/protocol_items.dat | 4 +- common/protocol_items.h | 9 +- common/server.cpp | 5 +- common/server.h | 2 +- common/server_game.cpp | 23 ++- common/server_game.h | 11 +- common/server_protocolhandler.cpp | 90 +++++++++-- 26 files changed, 430 insertions(+), 220 deletions(-) diff --git a/cockatrice/src/dlg_creategame.cpp b/cockatrice/src/dlg_creategame.cpp index 76a1ce2e..fe59fefa 100644 --- a/cockatrice/src/dlg_creategame.cpp +++ b/cockatrice/src/dlg_creategame.cpp @@ -14,11 +14,25 @@ DlgCreateGame::DlgCreateGame(Client *_client, QWidget *parent) passwordLabel->setBuddy(passwordEdit); maxPlayersLabel = new QLabel(tr("P&layers:")); - maxPlayersEdit = new QLineEdit("2"); + maxPlayersEdit = new QSpinBox(); + maxPlayersEdit->setMinimum(1); + maxPlayersEdit->setMaximum(100); + maxPlayersEdit->setValue(2); maxPlayersLabel->setBuddy(maxPlayersEdit); spectatorsAllowedCheckBox = new QCheckBox(tr("&Spectators allowed")); spectatorsAllowedCheckBox->setChecked(true); + connect(spectatorsAllowedCheckBox, SIGNAL(stateChanged(int)), this, SLOT(spectatorsAllowedChanged(int))); + spectatorsNeedPasswordCheckBox = new QCheckBox(tr("Spectators &need a password to join")); + spectatorsCanTalkCheckBox = new QCheckBox(tr("Spectators can &talk")); + spectatorsSeeEverythingCheckBox = new QCheckBox(tr("Spectators see &everything")); + QVBoxLayout *spectatorsLayout = new QVBoxLayout; + spectatorsLayout->addWidget(spectatorsAllowedCheckBox); + spectatorsLayout->addWidget(spectatorsNeedPasswordCheckBox); + spectatorsLayout->addWidget(spectatorsCanTalkCheckBox); + spectatorsLayout->addWidget(spectatorsSeeEverythingCheckBox); + spectatorsGroupBox = new QGroupBox(tr("Spectators")); + spectatorsGroupBox->setLayout(spectatorsLayout); QGridLayout *grid = new QGridLayout; grid->addWidget(descriptionLabel, 0, 0); @@ -27,7 +41,7 @@ DlgCreateGame::DlgCreateGame(Client *_client, QWidget *parent) grid->addWidget(passwordEdit, 1, 1); grid->addWidget(maxPlayersLabel, 2, 0); grid->addWidget(maxPlayersEdit, 2, 1); - grid->addWidget(spectatorsAllowedCheckBox, 3, 0, 1, 2); + grid->addWidget(spectatorsGroupBox, 3, 0, 1, 2); okButton = new QPushButton(tr("&OK")); okButton->setDefault(true); @@ -53,13 +67,15 @@ DlgCreateGame::DlgCreateGame(Client *_client, QWidget *parent) void DlgCreateGame::actOK() { - bool ok; - int maxPlayers = maxPlayersEdit->text().toInt(&ok); - if (!ok) { - QMessageBox::critical(this, tr("Error"), tr("Invalid number of players.")); - return; - } - Command_CreateGame *createCommand = new Command_CreateGame(descriptionEdit->text(), passwordEdit->text(), maxPlayers, spectatorsAllowedCheckBox->isChecked()); + Command_CreateGame *createCommand = new Command_CreateGame( + descriptionEdit->text(), + passwordEdit->text(), + maxPlayersEdit->value(), + spectatorsAllowedCheckBox->isChecked(), + spectatorsNeedPasswordCheckBox->isChecked(), + spectatorsCanTalkCheckBox->isChecked(), + spectatorsSeeEverythingCheckBox->isChecked() + ); connect(createCommand, SIGNAL(finished(ResponseCode)), this, SLOT(checkResponse(ResponseCode))); client->sendCommand(createCommand); @@ -79,3 +95,10 @@ void DlgCreateGame::checkResponse(ResponseCode response) return; } } + +void DlgCreateGame::spectatorsAllowedChanged(int state) +{ + spectatorsNeedPasswordCheckBox->setEnabled(state); + spectatorsCanTalkCheckBox->setEnabled(state); + spectatorsSeeEverythingCheckBox->setEnabled(state); +} diff --git a/cockatrice/src/dlg_creategame.h b/cockatrice/src/dlg_creategame.h index 8ca34b77..529e4b22 100644 --- a/cockatrice/src/dlg_creategame.h +++ b/cockatrice/src/dlg_creategame.h @@ -8,6 +8,8 @@ class QLabel; class QLineEdit; class QPushButton; class QCheckBox; +class QGroupBox; +class QSpinBox; class DlgCreateGame : public QDialog { Q_OBJECT @@ -16,12 +18,15 @@ public: private slots: void actOK(); void checkResponse(ResponseCode response); + void spectatorsAllowedChanged(int state); private: Client *client; + QGroupBox *spectatorsGroupBox; QLabel *descriptionLabel, *passwordLabel, *maxPlayersLabel; - QLineEdit *descriptionEdit, *passwordEdit, *maxPlayersEdit; - QCheckBox *spectatorsAllowedCheckBox; + QLineEdit *descriptionEdit, *passwordEdit; + QSpinBox *maxPlayersEdit; + QCheckBox *spectatorsAllowedCheckBox, *spectatorsNeedPasswordCheckBox, *spectatorsCanTalkCheckBox, *spectatorsSeeEverythingCheckBox; QPushButton *okButton, *cancelButton; }; diff --git a/cockatrice/src/gamesmodel.cpp b/cockatrice/src/gamesmodel.cpp index 365d461f..14c45ea5 100644 --- a/cockatrice/src/gamesmodel.cpp +++ b/cockatrice/src/gamesmodel.cpp @@ -27,7 +27,7 @@ QVariant GamesModel::data(const QModelIndex &index, int role) const switch (index.column()) { case 0: return g->getDescription(); case 1: return g->getCreatorName(); - case 2: return g->getHasPassword() ? tr("yes") : tr("no"); + case 2: return g->getHasPassword() ? (g->getSpectatorsNeedPassword() ? tr("yes") : tr("yes, free for spectators")) : tr("no"); case 3: return QString("%1/%2").arg(g->getPlayerCount()).arg(g->getMaxPlayers()); case 4: return g->getSpectatorsAllowed() ? QVariant(g->getSpectatorCount()) : QVariant(tr("not allowed")); default: return QVariant(); @@ -56,7 +56,7 @@ ServerInfo_Game *GamesModel::getGame(int row) void GamesModel::updateGameList(ServerInfo_Game *_game) { - ServerInfo_Game *game = new ServerInfo_Game(_game->getGameId(), _game->getDescription(), _game->getHasPassword(), _game->getPlayerCount(), _game->getMaxPlayers(), _game->getCreatorName(), _game->getSpectatorsAllowed(), _game->getSpectatorCount()); + ServerInfo_Game *game = new ServerInfo_Game(_game->getGameId(), _game->getDescription(), _game->getHasPassword(), _game->getPlayerCount(), _game->getMaxPlayers(), _game->getCreatorName(), _game->getSpectatorsAllowed(), _game->getSpectatorsNeedPassword(), _game->getSpectatorCount()); for (int i = 0; i < gameList.size(); i++) if (gameList[i]->getGameId() == game->getGameId()) { if (game->getPlayerCount() == 0) { diff --git a/cockatrice/src/handzone.cpp b/cockatrice/src/handzone.cpp index 648464a0..3e1f269d 100644 --- a/cockatrice/src/handzone.cpp +++ b/cockatrice/src/handzone.cpp @@ -5,8 +5,8 @@ #include "protocol_items.h" #include "settingscache.h" -HandZone::HandZone(Player *_p, int _zoneHeight, QGraphicsItem *parent) - : CardZone(_p, "hand", false, false, _p->getLocal(), parent), zoneHeight(_zoneHeight) +HandZone::HandZone(Player *_p, bool _contentsKnown, int _zoneHeight, QGraphicsItem *parent) + : CardZone(_p, "hand", false, false, _contentsKnown, parent), zoneHeight(_zoneHeight) { connect(settingsCache, SIGNAL(handBgPathChanged()), this, SLOT(updateBgPixmap())); updateBgPixmap(); diff --git a/cockatrice/src/handzone.h b/cockatrice/src/handzone.h index 65d920e9..f784da56 100644 --- a/cockatrice/src/handzone.h +++ b/cockatrice/src/handzone.h @@ -11,7 +11,7 @@ private: private slots: void updateBgPixmap(); public: - HandZone(Player *_p, int _zoneHeight, QGraphicsItem *parent = 0); + HandZone(Player *_p, bool _contentsKnown, int _zoneHeight, QGraphicsItem *parent = 0); QRectF boundingRect() const; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); void reorganizeCards(); diff --git a/cockatrice/src/messagelogwidget.cpp b/cockatrice/src/messagelogwidget.cpp index 9fec0356..443782c8 100644 --- a/cockatrice/src/messagelogwidget.cpp +++ b/cockatrice/src/messagelogwidget.cpp @@ -104,7 +104,12 @@ void MessageLogWidget::logGameStart() void MessageLogWidget::logSay(Player *player, QString message) { - append(QString("%1: %2").arg(sanitizeHtml(player->getName())).arg(sanitizeHtml(message))); + append(QString("%1: %2").arg(sanitizeHtml(player->getName())).arg(sanitizeHtml(message))); +} + +void MessageLogWidget::logSpectatorSay(QString spectatorName, QString message) +{ + append(QString("%1: %2").arg(sanitizeHtml(spectatorName)).arg(sanitizeHtml(message))); } void MessageLogWidget::logShuffle(Player *player) diff --git a/cockatrice/src/messagelogwidget.h b/cockatrice/src/messagelogwidget.h index 61af628b..f8ba59d2 100644 --- a/cockatrice/src/messagelogwidget.h +++ b/cockatrice/src/messagelogwidget.h @@ -33,6 +33,7 @@ public slots: void logConcede(Player *player); void logGameStart(); void logSay(Player *player, QString message); + void logSpectatorSay(QString spectatorName, QString message); void logShuffle(Player *player); void logRollDie(Player *player, int sides, int roll); void logDrawCards(Player *player, int number); diff --git a/cockatrice/src/player.cpp b/cockatrice/src/player.cpp index 311c9cf2..973872be 100644 --- a/cockatrice/src/player.cpp +++ b/cockatrice/src/player.cpp @@ -43,7 +43,7 @@ Player::Player(const QString &_name, int _id, bool _local, Client *_client, TabG table = new TableZone(this, this); connect(table, SIGNAL(sizeChanged()), this, SLOT(updateBoundingRect())); - hand = new HandZone(this, (int) table->boundingRect().height(), this); + hand = new HandZone(this, _local || (_parent->getSpectator() && _parent->getSpectatorsSeeEverything()), (int) table->boundingRect().height(), this); base = QPointF(deck->boundingRect().width() + counterAreaWidth + 5, 0); hand->setPos(base); diff --git a/cockatrice/src/tab_game.cpp b/cockatrice/src/tab_game.cpp index 9c15e915..9ebbe998 100644 --- a/cockatrice/src/tab_game.cpp +++ b/cockatrice/src/tab_game.cpp @@ -19,8 +19,8 @@ #include "arrowitem.h" #include "main.h" -TabGame::TabGame(Client *_client, int _gameId, const QString &_gameDescription, int _localPlayerId, bool _spectator, bool _resuming) - : Tab(), client(_client), gameId(_gameId), gameDescription(_gameDescription), localPlayerId(_localPlayerId), spectator(_spectator), started(false), resuming(_resuming), currentPhase(-1) +TabGame::TabGame(Client *_client, int _gameId, const QString &_gameDescription, int _localPlayerId, bool _spectator, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, bool _resuming) + : Tab(), client(_client), gameId(_gameId), gameDescription(_gameDescription), localPlayerId(_localPlayerId), spectator(_spectator), spectatorsCanTalk(_spectatorsCanTalk), spectatorsSeeEverything(_spectatorsSeeEverything), started(false), resuming(_resuming), currentPhase(-1) { scene = new GameScene(this); gameView = new GameView(scene); @@ -74,8 +74,10 @@ TabGame::TabGame(Client *_client, int _gameId, const QString &_gameDescription, mainLayout->addLayout(verticalLayout); if (spectator) { - sayLabel->hide(); - sayEdit->hide(); + if (!spectatorsCanTalk) { + sayLabel->hide(); + sayEdit->hide(); + } loadLocalButton->hide(); loadRemoteButton->hide(); readyStartButton->hide(); @@ -226,7 +228,15 @@ void TabGame::processGameEventContainer(GameEventContainer *cont) for (int i = 0; i < eventList.size(); ++i) { GameEvent *event = eventList[i]; - switch (event->getItemId()) { + if (spectators.contains(event->getPlayerId())) { + switch (event->getItemId()) { + case ItemId_Event_Say: eventSpectatorSay(qobject_cast(event), context); break; + default: { + qDebug() << "unhandled spectator game event"; + break; + } + } + } else switch (event->getItemId()) { case ItemId_Event_GameStateChanged: eventGameStateChanged(qobject_cast(event), context); break; case ItemId_Event_PlayerPropertiesChanged: eventPlayerPropertiesChanged(qobject_cast(event), context); break; case ItemId_Event_Join: eventJoin(qobject_cast(event), context); break; @@ -289,6 +299,11 @@ void TabGame::stopGame() deckViewContainer->show(); } +void TabGame::eventSpectatorSay(Event_Say *event, GameEventContext * /*context*/) +{ + messageLog->logSpectatorSay(spectators.value(event->getPlayerId()), event->getMessage()); +} + void TabGame::eventGameStateChanged(Event_GameStateChanged *event, GameEventContext * /*context*/) { const QList &plList = event->getPlayerList(); diff --git a/cockatrice/src/tab_game.h b/cockatrice/src/tab_game.h index be557905..3f93b8e9 100644 --- a/cockatrice/src/tab_game.h +++ b/cockatrice/src/tab_game.h @@ -33,6 +33,7 @@ class Event_GameStart; class Event_SetActivePlayer; class Event_SetActivePhase; class Event_Ping; +class Event_Say; class Player; class CardZone; class AbstractCardItem; @@ -46,6 +47,7 @@ private: QString gameDescription; int localPlayerId; bool spectator; + bool spectatorsCanTalk, spectatorsSeeEverything; QMap players; QMap spectators; bool started; @@ -73,6 +75,7 @@ private: void startGame(); void stopGame(); + void eventSpectatorSay(Event_Say *event, GameEventContext *context); void eventGameStateChanged(Event_GameStateChanged *event, GameEventContext *context); void eventPlayerPropertiesChanged(Event_PlayerPropertiesChanged *event, GameEventContext *context); void eventJoin(Event_Join *event, GameEventContext *context); @@ -100,12 +103,15 @@ private slots: void actNextPhase(); void actNextTurn(); public: - TabGame(Client *_client, int _gameId, const QString &_gameDescription, int _localPlayerId, bool _spectator, bool _resuming); + TabGame(Client *_client, int _gameId, const QString &_gameDescription, int _localPlayerId, bool _spectator, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, bool _resuming); ~TabGame(); void retranslateUi(); const QMap &getPlayers() const { return players; } int getGameId() const { return gameId; } QString getTabText() const { return tr("Game %1: %2").arg(gameId).arg(gameDescription); } + bool getSpectator() const { return spectator; } + bool getSpectatorsCanTalk() const { return spectatorsCanTalk; } + bool getSpectatorsSeeEverything() const { return spectatorsSeeEverything; } void processGameEventContainer(GameEventContainer *cont); public slots: diff --git a/cockatrice/src/tab_server.cpp b/cockatrice/src/tab_server.cpp index 76536028..6c626262 100644 --- a/cockatrice/src/tab_server.cpp +++ b/cockatrice/src/tab_server.cpp @@ -81,7 +81,7 @@ void GameSelector::actJoin() return; ServerInfo_Game *game = gameListModel->getGame(ind.data(Qt::UserRole).toInt()); QString password; - if (game->getHasPassword()) { + if (game->getHasPassword() && !(spectator && !game->getSpectatorsNeedPassword())) { bool ok; password = QInputDialog::getText(this, tr("Join game"), tr("Password:"), QLineEdit::Password, QString(), &ok); if (!ok) diff --git a/cockatrice/src/tab_supervisor.cpp b/cockatrice/src/tab_supervisor.cpp index 88d92224..5c45c301 100644 --- a/cockatrice/src/tab_supervisor.cpp +++ b/cockatrice/src/tab_supervisor.cpp @@ -103,7 +103,7 @@ void TabSupervisor::updatePingTime(int value, int max) void TabSupervisor::gameJoined(Event_GameJoined *event) { - TabGame *tab = new TabGame(client, event->getGameId(), event->getGameDescription(), event->getPlayerId(), event->getSpectator(), event->getResuming()); + TabGame *tab = new TabGame(client, event->getGameId(), event->getGameDescription(), event->getPlayerId(), event->getSpectator(), event->getSpectatorsCanTalk(), event->getSpectatorsSeeEverything(), event->getResuming()); connect(tab, SIGNAL(gameClosing(TabGame *)), this, SLOT(gameLeft(TabGame *))); myAddTab(tab); gameTabs.insert(event->getGameId(), tab); diff --git a/cockatrice/translations/cockatrice_de.ts b/cockatrice/translations/cockatrice_de.ts index 020549b4..328e0a44 100644 --- a/cockatrice/translations/cockatrice_de.ts +++ b/cockatrice/translations/cockatrice_de.ts @@ -476,38 +476,56 @@ &Spieler: - + &Spectators allowed &Zuschauer zugelassen - + + Spectators &need a password to join + Zuschauer brauchen &auch ein Passwort + + + + Spectators can &talk + Zuschauer können sp&rechen + + + + Spectators see &everything + Zuschauer sehen &alles + + + + Spectators + Zuschauer + + + &OK &OK - + &Cancel &Abbruch - + Create game Spiel erstellen - - + Error Fehler - Invalid number of players. - Ungültige Anzahl an Spielern. + Ungültige Anzahl an Spielern. - + Server error. Serverfehler. @@ -978,6 +996,11 @@ Description Beschreibung + + + yes, free for spectators + ja, außer für Zuschauer + not allowed @@ -1246,7 +1269,7 @@ %1 zieht %2 Karten - + a card eine Karte @@ -1308,7 +1331,7 @@ Das Spiel hat begonnen. - + %1 shuffles his library. %1 mischt seine Bibliothek. @@ -1385,122 +1408,122 @@ %1 hat das Spiel aufgegeben. - + %1 rolls a %2 with a %3-sided die. %1 würfelt eine %2 mit einem %3-seitigen Würfel. - + %1 draws a card. %1 zieht eine Karte. - + %1 draws %2 cards. %1 zieht %2 Karten. - + from table vom Spielfeld - + from graveyard aus dem Friedhof - + from exile aus dem Exil - + from hand von der Hand - + the bottom card of his library die unterste Karte seiner Bibliothek - + from the bottom of his library , die unterste Karte seiner Bibliothek, - + the top card of his library die oberste Karte seiner Bibliothek - + from the top of his library , die oberste Karte seiner Bibliothek, - + from library aus der Bibliothek - + from sideboard aus dem Sideboard - + %1 puts %2 into play%3. %1 bringt %2%3 ins Spiel. - + %1 puts %2%3 into graveyard. %1 legt %2%3 auf den Friedhof. - + %1 exiles %2%3. %1 schickt %2%3 ins Exil. - + %1 moves %2%3 to hand. %1 nimmt %2%3 auf die Hand. - + %1 puts %2%3 into his library. %1 legt %2%3 in seine Bibliothek. - + %1 puts %2%3 on bottom of his library. %1 legt %2%3 unter seine Bibliothek. - + %1 puts %2%3 on top of his library. %1 legt %2%3 auf die Bibliothek. - + %1 puts %2%3 into his library at position %4. %1 legt %2%3 in seine Bibliothek an %4. Stelle. - + %1 moves %2%3 to sideboard. %1 legt %2%3 in sein Sideboard. - + %1 points from %2's %3 to %4's %5. %1 zeigt von %2s %3 auf %4s %5. - + %1 is looking at the top %2 cards %3. %1 sieht sich die obersten %2 Karten %3 an. @@ -1585,27 +1608,27 @@ %1 legt %2%3in sein Sideboard. - + %1 creates token: %2. %1 erstellt Token: %2. - + %1 places %2 counters on %3 (now %4). %1 legt %2 Zählmarken auf %3 (jetzt %4). - + %1 removes %2 counters from %3 (now %4). %1 entfernt %2 Zählmarken von %3 (jetzt %4). - + %1 %2 %3. %1 %2 %3. - + %1 sets counter "%2" to %3 (%4%5). %1 setzt Zählmarke "%2" auf %3 (%4%5). @@ -1614,17 +1637,17 @@ %1 sieht sich die obersten %2 Karten %3 an. - + %1 is looking at %2. %1 sieht sich %2 an. - + %1 stops looking at %2. %1 sieht sich %2 nicht mehr an. - + ending phase die Zugendphase @@ -1653,57 +1676,57 @@ %1 sieht sich %2s %3 nicht mehr an - + It is now %1's turn. %1 ist am Zug. - + untap step das Enttappsegment - + upkeep step das Versorgungssegment - + draw step das Ziehsegment - + first main phase die erste Hauptphase - + beginning of combat step das Anfangssegment der Kampfphase - + declare attackers step das Angreifer-Deklarieren-Segment - + declare blockers step das Blocker-Deklarieren-Segment - + combat damage step das Kampfschadenssegment - + end of combat step das Endsegment der Kampfphase - + second main phase die zweite Hauptphase @@ -1712,7 +1735,7 @@ das Ende-des-Zuges-Segment - + It is now the %1. Es ist nun %1. @@ -1721,12 +1744,12 @@ %1 bewegt %2 %3 nach %4 - + taps tappt - + untaps enttappt @@ -1751,7 +1774,7 @@ %1 entfernt %2 Zählmarken von %3 (jetzt %4) - + his permanents seine bleibenden Karten @@ -1764,12 +1787,12 @@ %1 setzt Zähler "%2" auf %3 (%4%5) - + %1 sets %2 to not untap normally. %1 setzt %2 auf explizites Enttappen. - + %1 sets %2 to untap normally. %1 setzt %2 auf normales Enttappen. @@ -2447,77 +2470,77 @@ Bitte geben Sie einen Namen ein: TabGame - + &Game Spi&el - + Next &phase Nächste &Phase - + Ctrl+Space Ctrl+Space - + Next &turn Nächster &Zug - + Ctrl+Return Ctrl+Return - + Ctrl+Enter Ctrl+Enter - + &Remove all local arrows &Lokale Pfeile entfernen - + Ctrl+R Ctrl+R - + &Concede - + F2 F2 - + &Leave game Spiel ver&lassen - + Load &local deck &Lokales Deck laden - + Load d&eck from server Deck vom Server l&aden - + S&tart game Spiel s&tarten - + &Say: &Sagen: @@ -2530,32 +2553,32 @@ Bitte geben Sie einen Namen ein: Esc - + Concede Aufgeben - + Are you sure you want to concede this game? Sind Sie sicher, dass Sie das Spiel aufgeben möchten? - + Leave game Spiel verlassen - + Are you sure you want to leave this game? Sind Sie sicher, dass Sie das Spiel verlassen möchten? - + Load deck Deck laden - + Game %1: %2 Spiel %1: %2 diff --git a/cockatrice/translations/cockatrice_en.ts b/cockatrice/translations/cockatrice_en.ts index c0b2a4a3..2d9eba8b 100644 --- a/cockatrice/translations/cockatrice_en.ts +++ b/cockatrice/translations/cockatrice_en.ts @@ -396,38 +396,52 @@ - + &Spectators allowed - - &OK + + Spectators &need a password to join + + + + + Spectators can &talk + + + + + Spectators see &everything + Spectators + + + + + &OK + + + + &Cancel - + Create game - - + Error - - Invalid number of players. - - - - + Server error. @@ -601,6 +615,11 @@ Description + + + yes, free for spectators + + not allowed @@ -808,117 +827,117 @@ - + %1 rolls a %2 with a %3-sided die. - + from table - + from graveyard - + from exile - + from hand - + the bottom card of his library - + from the bottom of his library - + the top card of his library - + from the top of his library - + from library - + from sideboard - + %1 puts %2 into play%3. - + %1 puts %2%3 into graveyard. - + %1 exiles %2%3. - + %1 moves %2%3 to hand. - + %1 puts %2%3 into his library. - + %1 puts %2%3 on bottom of his library. - + %1 puts %2%3 on top of his library. - + %1 puts %2%3 into his library at position %4. - + %1 moves %2%3 to sideboard. - + a card - + %1 points from %2's %3 to %4's %5. - + %1 is looking at the top %2 cards %3. @@ -973,142 +992,142 @@ - + %1 draws a card. - + %1 draws %2 cards. - + %1 creates token: %2. - + %1 places %2 counters on %3 (now %4). - + %1 removes %2 counters from %3 (now %4). - + %1 %2 %3. - + %1 sets counter "%2" to %3 (%4%5). - + %1 is looking at %2. - + %1 stops looking at %2. - + ending phase - + It is now %1's turn. - + %1 shuffles his library. - + untap step - + upkeep step - + draw step - + first main phase - + beginning of combat step - + declare attackers step - + declare blockers step - + combat damage step - + end of combat step - + second main phase - + It is now the %1. - + taps - + untaps - + %1 sets %2 to not untap normally. - + %1 sets %2 to untap normally. - + his permanents @@ -1713,107 +1732,107 @@ Please enter a name: TabGame - + &Game - + Next &phase - + Ctrl+Space - + Next &turn - + Ctrl+Return - + Ctrl+Enter - + &Remove all local arrows - + Ctrl+R - + &Concede - + F2 - + &Leave game - + Load &local deck - + Load d&eck from server - + S&tart game - + &Say: - + Concede - + Are you sure you want to concede this game? - + Leave game - + Are you sure you want to leave this game? - + Load deck - + Game %1: %2 diff --git a/common/protocol.cpp b/common/protocol.cpp index 79be614a..ca8ab0ee 100644 --- a/common/protocol.cpp +++ b/common/protocol.cpp @@ -104,7 +104,7 @@ void Command::processResponse(ProtocolResponse *response) } CommandContainer::CommandContainer(const QList &_commandList, int _cmdId) - : ProtocolItem("container", "cmd"), ticks(0), resp(0), gameEventQueuePublic(0), gameEventQueuePrivate(0) + : ProtocolItem("container", "cmd"), ticks(0), resp(0), gameEventQueuePublic(0), gameEventQueueOmniscient(0), gameEventQueuePrivate(0) { if (_cmdId == -1) _cmdId = lastCmdId++; @@ -137,6 +137,13 @@ void CommandContainer::enqueueGameEventPublic(GameEvent *event, int gameId) gameEventQueuePublic->appendItem(event); } +void CommandContainer::enqueueGameEventOmniscient(GameEvent *event, int gameId) +{ + if (!gameEventQueueOmniscient) + gameEventQueueOmniscient = new GameEventContainer(QList(), gameId); + gameEventQueueOmniscient->appendItem(event); +} + void CommandContainer::enqueueGameEventPrivate(GameEvent *event, int gameId) { if (!gameEventQueuePrivate) diff --git a/common/protocol.h b/common/protocol.h index 337db848..5e1af53b 100644 --- a/common/protocol.h +++ b/common/protocol.h @@ -103,6 +103,7 @@ private: ProtocolResponse *resp; QList itemQueue; GameEventContainer *gameEventQueuePublic; + GameEventContainer *gameEventQueueOmniscient; GameEventContainer *gameEventQueuePrivate; public: CommandContainer(const QList &_commandList = QList(), int _cmdId = -1); @@ -119,6 +120,8 @@ public: void enqueueItem(ProtocolItem *item) { itemQueue.append(item); } GameEventContainer *getGameEventQueuePublic() const { return gameEventQueuePublic; } void enqueueGameEventPublic(GameEvent *event, int gameId); + GameEventContainer *getGameEventQueueOmniscient() const { return gameEventQueueOmniscient; } + void enqueueGameEventOmniscient(GameEvent *event, int gameId); GameEventContainer *getGameEventQueuePrivate() const { return gameEventQueuePrivate; } void enqueueGameEventPrivate(GameEvent *event, int gameId); }; diff --git a/common/protocol_datastructures.cpp b/common/protocol_datastructures.cpp index a3824b33..38971f78 100644 --- a/common/protocol_datastructures.cpp +++ b/common/protocol_datastructures.cpp @@ -18,7 +18,7 @@ ServerInfo_ChatUser::ServerInfo_ChatUser(const QString &_name) insertItem(new SerializableItem_String("name", _name)); } -ServerInfo_Game::ServerInfo_Game(int _gameId, const QString &_description, bool _hasPassword, int _playerCount, int _maxPlayers, const QString &_creatorName, bool _spectatorsAllowed, int _spectatorCount) +ServerInfo_Game::ServerInfo_Game(int _gameId, const QString &_description, bool _hasPassword, int _playerCount, int _maxPlayers, const QString &_creatorName, bool _spectatorsAllowed, bool _spectatorsNeedPassword, int _spectatorCount) : SerializableItem_Map("game") { insertItem(new SerializableItem_Int("game_id", _gameId)); @@ -28,6 +28,7 @@ ServerInfo_Game::ServerInfo_Game(int _gameId, const QString &_description, bool insertItem(new SerializableItem_Int("max_players", _maxPlayers)); insertItem(new SerializableItem_String("creator_name", _creatorName)); insertItem(new SerializableItem_Bool("spectators_allowed", _spectatorsAllowed)); + insertItem(new SerializableItem_Bool("spectators_need_password", _spectatorsNeedPassword)); insertItem(new SerializableItem_Int("spectator_count", _spectatorCount)); } diff --git a/common/protocol_datastructures.h b/common/protocol_datastructures.h index d9e589e3..7d331498 100644 --- a/common/protocol_datastructures.h +++ b/common/protocol_datastructures.h @@ -39,7 +39,7 @@ public: class ServerInfo_Game : public SerializableItem_Map { public: - ServerInfo_Game(int _gameId = -1, const QString &_description = QString(), bool _hasPassword = false, int _playerCount = -1, int _maxPlayers = -1, const QString &_creatorName = QString(), bool _spectatorsAllowed = false, int _spectatorCount = -1); + ServerInfo_Game(int _gameId = -1, const QString &_description = QString(), bool _hasPassword = false, int _playerCount = -1, int _maxPlayers = -1, const QString &_creatorName = QString(), bool _spectatorsAllowed = false, bool _spectatorsNeedPassword = false, int _spectatorCount = -1); static SerializableItem *newItem() { return new ServerInfo_Game; } int getGameId() const { return static_cast(itemMap.value("game_id"))->getData(); } QString getDescription() const { return static_cast(itemMap.value("description"))->getData(); } @@ -48,6 +48,7 @@ public: int getMaxPlayers() const { return static_cast(itemMap.value("max_players"))->getData(); } QString getCreatorName() const { return static_cast(itemMap.value("creator_name"))->getData(); } bool getSpectatorsAllowed() const { return static_cast(itemMap.value("spectators_allowed"))->getData(); } + bool getSpectatorsNeedPassword() const { return static_cast(itemMap.value("spectators_need_password"))->getData(); } int getSpectatorCount() const { return static_cast(itemMap.value("spectator_count"))->getData(); } }; diff --git a/common/protocol_items.cpp b/common/protocol_items.cpp index 6a9c6a4d..d0ed4cfa 100644 --- a/common/protocol_items.cpp +++ b/common/protocol_items.cpp @@ -58,13 +58,16 @@ Command_ListGames::Command_ListGames() : Command("list_games") { } -Command_CreateGame::Command_CreateGame(const QString &_description, const QString &_password, int _maxPlayers, bool _spectatorsAllowed) +Command_CreateGame::Command_CreateGame(const QString &_description, const QString &_password, int _maxPlayers, bool _spectatorsAllowed, bool _spectatorsNeedPassword, bool _spectatorsCanTalk, bool _spectatorsSeeEverything) : Command("create_game") { insertItem(new SerializableItem_String("description", _description)); insertItem(new SerializableItem_String("password", _password)); insertItem(new SerializableItem_Int("max_players", _maxPlayers)); insertItem(new SerializableItem_Bool("spectators_allowed", _spectatorsAllowed)); + insertItem(new SerializableItem_Bool("spectators_need_password", _spectatorsNeedPassword)); + insertItem(new SerializableItem_Bool("spectators_can_talk", _spectatorsCanTalk)); + insertItem(new SerializableItem_Bool("spectators_see_everything", _spectatorsSeeEverything)); } Command_JoinGame::Command_JoinGame(int _gameId, const QString &_password, bool _spectator) : Command("join_game") @@ -297,13 +300,15 @@ Event_ServerMessage::Event_ServerMessage(const QString &_message) { insertItem(new SerializableItem_String("message", _message)); } -Event_GameJoined::Event_GameJoined(int _gameId, const QString &_gameDescription, int _playerId, bool _spectator, bool _resuming) +Event_GameJoined::Event_GameJoined(int _gameId, const QString &_gameDescription, int _playerId, bool _spectator, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, bool _resuming) : GenericEvent("game_joined") { insertItem(new SerializableItem_Int("game_id", _gameId)); insertItem(new SerializableItem_String("game_description", _gameDescription)); insertItem(new SerializableItem_Int("player_id", _playerId)); insertItem(new SerializableItem_Bool("spectator", _spectator)); + insertItem(new SerializableItem_Bool("spectators_can_talk", _spectatorsCanTalk)); + insertItem(new SerializableItem_Bool("spectators_see_everything", _spectatorsSeeEverything)); insertItem(new SerializableItem_Bool("resuming", _resuming)); } Event_ChatJoinChannel::Event_ChatJoinChannel(const QString &_channel, const QString &_playerName) diff --git a/common/protocol_items.dat b/common/protocol_items.dat index d7581f4d..1ff77468 100644 --- a/common/protocol_items.dat +++ b/common/protocol_items.dat @@ -10,7 +10,7 @@ 1:chat_leave_channel 1:chat_say:s,message 0:list_games -0:create_game:s,description:s,password:i,max_players:b,spectators_allowed +0:create_game:s,description:s,password:i,max_players:b,spectators_allowed:b,spectators_need_password:b,spectators_can_talk:b,spectators_see_everything 0:join_game:i,game_id:s,password:b,spectator 2:leave_game 2:say:s,message @@ -49,7 +49,7 @@ 3:dump_zone:i,zone_owner_id:s,zone:i,number_cards 3:stop_dump_zone:i,zone_owner_id:s,zone 4:server_message:s,message -4:game_joined:i,game_id:s,game_description:i,player_id:b,spectator:b,resuming +4:game_joined:i,game_id:s,game_description:i,player_id:b,spectator:b,spectators_can_talk:b,spectators_see_everything:b,resuming 5:chat_join_channel:s,player_name 5:chat_leave_channel:s,player_name 5:chat_say:s,player_name:s,message diff --git a/common/protocol_items.h b/common/protocol_items.h index 667d8249..feb67947 100644 --- a/common/protocol_items.h +++ b/common/protocol_items.h @@ -99,11 +99,14 @@ public: class Command_CreateGame : public Command { Q_OBJECT public: - Command_CreateGame(const QString &_description = QString(), const QString &_password = QString(), int _maxPlayers = -1, bool _spectatorsAllowed = false); + Command_CreateGame(const QString &_description = QString(), const QString &_password = QString(), int _maxPlayers = -1, bool _spectatorsAllowed = false, bool _spectatorsNeedPassword = false, bool _spectatorsCanTalk = false, bool _spectatorsSeeEverything = false); QString getDescription() const { return static_cast(itemMap.value("description"))->getData(); }; QString getPassword() const { return static_cast(itemMap.value("password"))->getData(); }; int getMaxPlayers() const { return static_cast(itemMap.value("max_players"))->getData(); }; bool getSpectatorsAllowed() const { return static_cast(itemMap.value("spectators_allowed"))->getData(); }; + bool getSpectatorsNeedPassword() const { return static_cast(itemMap.value("spectators_need_password"))->getData(); }; + bool getSpectatorsCanTalk() const { return static_cast(itemMap.value("spectators_can_talk"))->getData(); }; + bool getSpectatorsSeeEverything() const { return static_cast(itemMap.value("spectators_see_everything"))->getData(); }; static SerializableItem *newItem() { return new Command_CreateGame; } int getItemId() const { return ItemId_Command_CreateGame; } }; @@ -455,11 +458,13 @@ public: class Event_GameJoined : public GenericEvent { Q_OBJECT public: - Event_GameJoined(int _gameId = -1, const QString &_gameDescription = QString(), int _playerId = -1, bool _spectator = false, bool _resuming = false); + Event_GameJoined(int _gameId = -1, const QString &_gameDescription = QString(), int _playerId = -1, bool _spectator = false, bool _spectatorsCanTalk = false, bool _spectatorsSeeEverything = false, bool _resuming = false); int getGameId() const { return static_cast(itemMap.value("game_id"))->getData(); }; QString getGameDescription() const { return static_cast(itemMap.value("game_description"))->getData(); }; int getPlayerId() const { return static_cast(itemMap.value("player_id"))->getData(); }; bool getSpectator() const { return static_cast(itemMap.value("spectator"))->getData(); }; + bool getSpectatorsCanTalk() const { return static_cast(itemMap.value("spectators_can_talk"))->getData(); }; + bool getSpectatorsSeeEverything() const { return static_cast(itemMap.value("spectators_see_everything"))->getData(); }; bool getResuming() const { return static_cast(itemMap.value("resuming"))->getData(); }; static SerializableItem *newItem() { return new Event_GameJoined; } int getItemId() const { return ItemId_Event_GameJoined; } diff --git a/common/server.cpp b/common/server.cpp index 5410b348..ef5370c0 100644 --- a/common/server.cpp +++ b/common/server.cpp @@ -32,9 +32,9 @@ Server::~Server() { } -Server_Game *Server::createGame(const QString &description, const QString &password, int maxPlayers, bool spectatorsAllowed, Server_ProtocolHandler *creator) +Server_Game *Server::createGame(const QString &description, const QString &password, int maxPlayers, bool spectatorsAllowed, bool spectatorsNeedPassword, bool spectatorsCanTalk, bool spectatorsSeeEverything, Server_ProtocolHandler *creator) { - Server_Game *newGame = new Server_Game(creator, nextGameId++, description, password, maxPlayers, spectatorsAllowed, this); + Server_Game *newGame = new Server_Game(creator, nextGameId++, description, password, maxPlayers, spectatorsAllowed, spectatorsNeedPassword, spectatorsCanTalk, spectatorsSeeEverything, this); games.insert(newGame->getGameId(), newGame); connect(newGame, SIGNAL(gameClosing()), this, SLOT(gameClosing())); @@ -84,6 +84,7 @@ void Server::broadcastGameListUpdate(Server_Game *game) game->getMaxPlayers(), game->getCreatorName(), game->getSpectatorsAllowed(), + game->getSpectatorsNeedPassword(), game->getSpectatorCount() )); else diff --git a/common/server.h b/common/server.h index ec01de6c..461e516b 100644 --- a/common/server.h +++ b/common/server.h @@ -30,7 +30,7 @@ public: void removeClient(Server_ProtocolHandler *player); void closeOldSession(const QString &playerName); virtual QString getLoginMessage() const = 0; - Server_Game *createGame(const QString &description, const QString &password, int maxPlayers, bool spectatorsAllowed, Server_ProtocolHandler *creator); + Server_Game *createGame(const QString &description, const QString &password, int maxPlayers, bool spectatorsAllowed, bool spectatorsNeedPassword, bool spectatorsCanTalk, bool spectatorsSeeEverything, Server_ProtocolHandler *creator); virtual int getMaxGameInactivityTime() const = 0; virtual int getMaxPlayerInactivityTime() const = 0; diff --git a/common/server_game.cpp b/common/server_game.cpp index dea8bbf7..44a57088 100644 --- a/common/server_game.cpp +++ b/common/server_game.cpp @@ -27,8 +27,8 @@ #include #include -Server_Game::Server_Game(Server_ProtocolHandler *_creator, int _gameId, const QString &_description, const QString &_password, int _maxPlayers, bool _spectatorsAllowed, QObject *parent) - : QObject(parent), gameStarted(false), gameId(_gameId), description(_description), password(_password), maxPlayers(_maxPlayers), activePlayer(-1), activePhase(-1), spectatorsAllowed(_spectatorsAllowed), inactivityCounter(0) +Server_Game::Server_Game(Server_ProtocolHandler *_creator, int _gameId, const QString &_description, const QString &_password, int _maxPlayers, bool _spectatorsAllowed, bool _spectatorsNeedPassword, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, QObject *parent) + : QObject(parent), gameStarted(false), gameId(_gameId), description(_description), password(_password), maxPlayers(_maxPlayers), activePlayer(-1), activePhase(-1), spectatorsAllowed(_spectatorsAllowed), spectatorsNeedPassword(_spectatorsNeedPassword), spectatorsCanTalk(_spectatorsCanTalk), spectatorsSeeEverything(_spectatorsSeeEverything), inactivityCounter(0) { creator = addPlayer(_creator, false, false); @@ -168,7 +168,7 @@ void Server_Game::stopGameIfFinished() ResponseCode Server_Game::checkJoin(const QString &_password, bool spectator) { - if (_password != password) + if ((_password != password) && !(spectator && !spectatorsNeedPassword)) return RespWrongPassword; if (spectator) { if (!spectatorsAllowed) @@ -292,13 +292,26 @@ void Server_Game::sendGameEvent(GameEvent *event, GameEventContext *context, Ser sendGameEventContainer(new GameEventContainer(QList() << event, -1, context), exclude); } -void Server_Game::sendGameEventContainer(GameEventContainer *cont, Server_Player *exclude) +void Server_Game::sendGameEventContainer(GameEventContainer *cont, Server_Player *exclude, bool excludeOmniscient) { cont->setGameId(gameId); QMapIterator playerIterator(players); while (playerIterator.hasNext()) { Server_Player *p = playerIterator.next().value(); - if (p != exclude) + if ((p != exclude) && !(excludeOmniscient && p->getSpectator() && spectatorsSeeEverything)) + p->sendProtocolItem(cont, false); + } + + delete cont; +} + +void Server_Game::sendGameEventContainerOmniscient(GameEventContainer *cont, Server_Player *exclude) +{ + cont->setGameId(gameId); + QMapIterator playerIterator(players); + while (playerIterator.hasNext()) { + Server_Player *p = playerIterator.next().value(); + if ((p != exclude) && (p->getSpectator() && spectatorsSeeEverything)) p->sendProtocolItem(cont, false); } diff --git a/common/server_game.h b/common/server_game.h index 50456cd0..c6df423f 100644 --- a/common/server_game.h +++ b/common/server_game.h @@ -40,6 +40,9 @@ private: int maxPlayers; int activePlayer, activePhase; bool spectatorsAllowed; + bool spectatorsNeedPassword; + bool spectatorsCanTalk; + bool spectatorsSeeEverything; int inactivityCounter; QTimer *pingClock; signals: @@ -47,7 +50,7 @@ signals: private slots: void pingClockTimeout(); public: - Server_Game(Server_ProtocolHandler *_creator, int _gameId, const QString &_description, const QString &_password, int _maxPlayers, bool _spectatorsAllowed, QObject *parent = 0); + Server_Game(Server_ProtocolHandler *_creator, int _gameId, const QString &_description, const QString &_password, int _maxPlayers, bool _spectatorsAllowed, bool _spectatorsNeedPassword, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, QObject *parent = 0); ~Server_Game(); Server_Player *getCreator() const { return creator; } QString getCreatorName() const { return creator ? creator->getPlayerName() : QString(); } @@ -61,6 +64,9 @@ public: 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; } ResponseCode checkJoin(const QString &_password, bool spectator); Server_Player *addPlayer(Server_ProtocolHandler *handler, bool spectator, bool broadcastUpdate = true); void removePlayer(Server_Player *player); @@ -73,7 +79,8 @@ public: QList getGameState(Server_Player *playerWhosAsking) const; void sendGameEvent(GameEvent *event, GameEventContext *context = 0, Server_Player *exclude = 0); - void sendGameEventContainer(GameEventContainer *cont, Server_Player *exclude = 0); + void sendGameEventContainer(GameEventContainer *cont, Server_Player *exclude = 0, bool excludeOmniscient = false); + void sendGameEventContainerOmniscient(GameEventContainer *cont, Server_Player *exclude = 0); void sendGameEventToPlayer(Server_Player *player, GameEvent *event); }; diff --git a/common/server_protocolhandler.cpp b/common/server_protocolhandler.cpp index b4e5dc02..5ae69afe 100644 --- a/common/server_protocolhandler.cpp +++ b/common/server_protocolhandler.cpp @@ -148,8 +148,13 @@ void Server_ProtocolHandler::processCommandContainer(CommandContainer *cont) Server_Game *game = games.value(gQPublic->getGameId()).first; Server_Player *player = games.value(gQPublic->getGameId()).second; GameEventContainer *gQPrivate = cont->getGameEventQueuePrivate(); + GameEventContainer *gQOmniscient = cont->getGameEventQueueOmniscient(); if (gQPrivate) { - game->sendGameEventContainer(gQPublic, player); + if (gQOmniscient) { + game->sendGameEventContainer(gQPublic, player, true); + game->sendGameEventContainerOmniscient(gQOmniscient, player); + } else + game->sendGameEventContainer(gQPublic, player); player->sendProtocolItem(gQPrivate); } else game->sendGameEventContainer(gQPublic); @@ -214,7 +219,7 @@ ResponseCode Server_ProtocolHandler::cmdLogin(Command_Login *cmd, CommandContain gamePlayers[j]->setProtocolHandler(this); games.insert(serverGames[i]->getGameId(), QPair(serverGames[i], gamePlayers[j])); - enqueueProtocolItem(new Event_GameJoined(serverGames[i]->getGameId(), serverGames[i]->getDescription(), gamePlayers[j]->getPlayerId(), gamePlayers[j]->getSpectator(), true)); + enqueueProtocolItem(new Event_GameJoined(serverGames[i]->getGameId(), serverGames[i]->getDescription(), gamePlayers[j]->getPlayerId(), gamePlayers[j]->getSpectator(), serverGames[i]->getSpectatorsCanTalk(), serverGames[i]->getSpectatorsSeeEverything(), true)); enqueueProtocolItem(GameEventContainer::makeNew(new Event_GameStateChanged(serverGames[i]->getGameStarted(), serverGames[i]->getActivePlayer(), serverGames[i]->getActivePhase(), serverGames[i]->getGameState(gamePlayers[j])), serverGames[i]->getGameId())); } } @@ -285,6 +290,7 @@ ResponseCode Server_ProtocolHandler::cmdListGames(Command_ListGames * /*cmd*/, C g->getMaxPlayers(), g->getCreatorName(), g->getSpectatorsAllowed(), + g->getSpectatorsNeedPassword(), g->getSpectatorCount() )); } @@ -296,11 +302,11 @@ ResponseCode Server_ProtocolHandler::cmdListGames(Command_ListGames * /*cmd*/, C ResponseCode Server_ProtocolHandler::cmdCreateGame(Command_CreateGame *cmd, CommandContainer *cont) { - Server_Game *game = server->createGame(cmd->getDescription(), cmd->getPassword(), cmd->getMaxPlayers(), cmd->getSpectatorsAllowed(), this); + Server_Game *game = server->createGame(cmd->getDescription(), cmd->getPassword(), cmd->getMaxPlayers(), cmd->getSpectatorsAllowed(), cmd->getSpectatorsNeedPassword(), cmd->getSpectatorsCanTalk(), cmd->getSpectatorsSeeEverything(), this); Server_Player *creator = game->getCreator(); games.insert(game->getGameId(), QPair(game, creator)); - enqueueProtocolItem(new Event_GameJoined(game->getGameId(), game->getDescription(), creator->getPlayerId(), false, false)); + enqueueProtocolItem(new Event_GameJoined(game->getGameId(), game->getDescription(), creator->getPlayerId(), false, game->getSpectatorsCanTalk(), game->getSpectatorsSeeEverything(), false)); enqueueProtocolItem(GameEventContainer::makeNew(new Event_GameStateChanged(game->getGameStarted(), game->getActivePlayer(), game->getActivePhase(), game->getGameState(creator)), game->getGameId())); return RespOk; } @@ -318,7 +324,7 @@ ResponseCode Server_ProtocolHandler::cmdJoinGame(Command_JoinGame *cmd, CommandC if (result == RespOk) { Server_Player *player = g->addPlayer(this, cmd->getSpectator()); games.insert(cmd->getGameId(), QPair(g, player)); - enqueueProtocolItem(new Event_GameJoined(cmd->getGameId(), g->getDescription(), player->getPlayerId(), cmd->getSpectator(), false)); + enqueueProtocolItem(new Event_GameJoined(cmd->getGameId(), g->getDescription(), player->getPlayerId(), cmd->getSpectator(), g->getSpectatorsCanTalk(), g->getSpectatorsSeeEverything(), false)); enqueueProtocolItem(GameEventContainer::makeNew(new Event_GameStateChanged(g->getGameStarted(), g->getActivePlayer(), g->getActivePhase(), g->getGameState(player)), cmd->getGameId())); } return result; @@ -332,6 +338,9 @@ ResponseCode Server_ProtocolHandler::cmdLeaveGame(Command_LeaveGame * /*cmd*/, C ResponseCode Server_ProtocolHandler::cmdDeckSelect(Command_DeckSelect *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player) { + if (player->getSpectator()) + return RespFunctionNotAllowed; + DeckList *deck; if (cmd->getDeckId() == -1) { if (!cmd->getDeck()) @@ -354,6 +363,9 @@ ResponseCode Server_ProtocolHandler::cmdDeckSelect(Command_DeckSelect *cmd, Comm ResponseCode Server_ProtocolHandler::cmdSetSideboardPlan(Command_SetSideboardPlan *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player) { + if (player->getSpectator()) + return RespFunctionNotAllowed; + DeckList *deck = player->getDeck(); if (!deck) return RespContextError; @@ -364,6 +376,9 @@ ResponseCode Server_ProtocolHandler::cmdSetSideboardPlan(Command_SetSideboardPla ResponseCode Server_ProtocolHandler::cmdConcede(Command_Concede * /*cmd*/, CommandContainer *cont, Server_Game *game, Server_Player *player) { + if (player->getSpectator()) + return RespFunctionNotAllowed; + player->setConceded(true); game->sendGameEvent(new Event_PlayerPropertiesChanged(player->getProperties()), new Context_Concede); game->stopGameIfFinished(); @@ -372,6 +387,9 @@ ResponseCode Server_ProtocolHandler::cmdConcede(Command_Concede * /*cmd*/, Comma ResponseCode Server_ProtocolHandler::cmdReadyStart(Command_ReadyStart * /*cmd*/, CommandContainer *cont, Server_Game *game, Server_Player *player) { + if (player->getSpectator()) + return RespFunctionNotAllowed; + if (!player->getDeck()) return RespContextError; @@ -383,12 +401,18 @@ ResponseCode Server_ProtocolHandler::cmdReadyStart(Command_ReadyStart * /*cmd*/, ResponseCode Server_ProtocolHandler::cmdSay(Command_Say *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player) { + if (player->getSpectator() && !game->getSpectatorsCanTalk()) + return RespFunctionNotAllowed; + game->sendGameEvent(new Event_Say(player->getPlayerId(), cmd->getMessage())); return RespOk; } ResponseCode Server_ProtocolHandler::cmdShuffle(Command_Shuffle * /*cmd*/, CommandContainer *cont, Server_Game *game, Server_Player *player) { + if (player->getSpectator()) + return RespFunctionNotAllowed; + if (!game->getGameStarted()) return RespGameNotStarted; @@ -399,6 +423,9 @@ ResponseCode Server_ProtocolHandler::cmdShuffle(Command_Shuffle * /*cmd*/, Comma ResponseCode Server_ProtocolHandler::cmdMulligan(Command_Mulligan * /*cmd*/, CommandContainer *cont, Server_Game *game, Server_Player *player) { + if (player->getSpectator()) + return RespFunctionNotAllowed; + if (!game->getGameStarted()) return RespGameNotStarted; @@ -422,12 +449,18 @@ ResponseCode Server_ProtocolHandler::cmdMulligan(Command_Mulligan * /*cmd*/, Com ResponseCode Server_ProtocolHandler::cmdRollDie(Command_RollDie *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player) { + if (player->getSpectator()) + return RespFunctionNotAllowed; + game->sendGameEvent(new Event_RollDie(player->getPlayerId(), cmd->getSides(), rng->getNumber(1, cmd->getSides()))); return RespOk; } ResponseCode Server_ProtocolHandler::drawCards(Server_Game *game, Server_Player *player, CommandContainer *cont, int number) { + if (player->getSpectator()) + return RespFunctionNotAllowed; + if (!game->getGameStarted()) return RespGameNotStarted; @@ -436,15 +469,18 @@ ResponseCode Server_ProtocolHandler::drawCards(Server_Game *game, Server_Player if (deck->cards.size() < number) number = deck->cards.size(); - QList cardList; + QList cardListPrivate; + QList cardListOmniscient; for (int i = 0; i < number; ++i) { Server_Card *card = deck->cards.takeFirst(); hand->cards.append(card); - cardList.append(new ServerInfo_Card(card->getId(), card->getName())); + cardListPrivate.append(new ServerInfo_Card(card->getId(), card->getName())); + cardListOmniscient.append(new ServerInfo_Card(card->getId(), card->getName())); } - cont->enqueueGameEventPrivate(new Event_DrawCards(player->getPlayerId(), cardList.size(), cardList), game->getGameId()); - cont->enqueueGameEventPublic(new Event_DrawCards(player->getPlayerId(), cardList.size()), game->getGameId()); + cont->enqueueGameEventPrivate(new Event_DrawCards(player->getPlayerId(), cardListPrivate.size(), cardListPrivate), game->getGameId()); + cont->enqueueGameEventOmniscient(new Event_DrawCards(player->getPlayerId(), cardListOmniscient.size(), cardListOmniscient), game->getGameId()); + cont->enqueueGameEventPublic(new Event_DrawCards(player->getPlayerId(), cardListPrivate.size()), game->getGameId()); return RespOk; } @@ -457,6 +493,9 @@ ResponseCode Server_ProtocolHandler::cmdDrawCards(Command_DrawCards *cmd, Comman ResponseCode Server_ProtocolHandler::moveCard(Server_Game *game, Server_Player *player, CommandContainer *cont, const QString &_startZone, int _cardId, const QString &_targetZone, int x, int y, bool faceDown, bool tapped) { + if (player->getSpectator()) + return RespFunctionNotAllowed; + if (!game->getGameStarted()) return RespGameNotStarted; @@ -508,6 +547,7 @@ ResponseCode Server_ProtocolHandler::moveCard(Server_Game *game, Server_Player * if (startzone->getType() == HiddenZone) privatePosition = position; cont->enqueueGameEventPrivate(new Event_MoveCard(player->getPlayerId(), privateOldCardId, privateCardName, startzone->getName(), privatePosition, targetzone->getName(), x, y, privateNewCardId, faceDown), game->getGameId()); + cont->enqueueGameEventOmniscient(new Event_MoveCard(player->getPlayerId(), privateOldCardId, privateCardName, startzone->getName(), privatePosition, targetzone->getName(), x, y, privateNewCardId, faceDown), game->getGameId()); // 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, @@ -554,6 +594,9 @@ ResponseCode Server_ProtocolHandler::cmdMoveCard(Command_MoveCard *cmd, CommandC ResponseCode Server_ProtocolHandler::cmdCreateToken(Command_CreateToken *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player) { + if (player->getSpectator()) + return RespFunctionNotAllowed; + if (!game->getGameStarted()) return RespGameNotStarted; @@ -571,6 +614,9 @@ ResponseCode Server_ProtocolHandler::cmdCreateToken(Command_CreateToken *cmd, Co ResponseCode Server_ProtocolHandler::cmdCreateArrow(Command_CreateArrow *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player) { + if (player->getSpectator()) + return RespFunctionNotAllowed; + if (!game->getGameStarted()) return RespGameNotStarted; @@ -610,6 +656,9 @@ ResponseCode Server_ProtocolHandler::cmdCreateArrow(Command_CreateArrow *cmd, Co ResponseCode Server_ProtocolHandler::cmdDeleteArrow(Command_DeleteArrow *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player) { + if (player->getSpectator()) + return RespFunctionNotAllowed; + if (!game->getGameStarted()) return RespGameNotStarted; @@ -622,6 +671,9 @@ ResponseCode Server_ProtocolHandler::cmdDeleteArrow(Command_DeleteArrow *cmd, Co ResponseCode Server_ProtocolHandler::setCardAttrHelper(CommandContainer *cont, Server_Game *game, Server_Player *player, const QString &zoneName, int cardId, const QString &attrName, const QString &attrValue) { + if (player->getSpectator()) + return RespFunctionNotAllowed; + if (!game->getGameStarted()) return RespGameNotStarted; @@ -655,6 +707,9 @@ ResponseCode Server_ProtocolHandler::cmdSetCardAttr(Command_SetCardAttr *cmd, Co ResponseCode Server_ProtocolHandler::cmdIncCounter(Command_IncCounter *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player) { + if (player->getSpectator()) + return RespFunctionNotAllowed; + if (!game->getGameStarted()) return RespGameNotStarted; @@ -670,6 +725,9 @@ ResponseCode Server_ProtocolHandler::cmdIncCounter(Command_IncCounter *cmd, Comm ResponseCode Server_ProtocolHandler::cmdCreateCounter(Command_CreateCounter *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player) { + if (player->getSpectator()) + return RespFunctionNotAllowed; + if (!game->getGameStarted()) return RespGameNotStarted; @@ -682,6 +740,9 @@ ResponseCode Server_ProtocolHandler::cmdCreateCounter(Command_CreateCounter *cmd ResponseCode Server_ProtocolHandler::cmdSetCounter(Command_SetCounter *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player) { + if (player->getSpectator()) + return RespFunctionNotAllowed; + if (!game->getGameStarted()) return RespGameNotStarted; @@ -696,6 +757,9 @@ ResponseCode Server_ProtocolHandler::cmdSetCounter(Command_SetCounter *cmd, Comm ResponseCode Server_ProtocolHandler::cmdDelCounter(Command_DelCounter *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player) { + if (player->getSpectator()) + return RespFunctionNotAllowed; + if (!game->getGameStarted()) return RespGameNotStarted; @@ -705,8 +769,11 @@ ResponseCode Server_ProtocolHandler::cmdDelCounter(Command_DelCounter *cmd, Comm return RespOk; } -ResponseCode Server_ProtocolHandler::cmdNextTurn(Command_NextTurn * /*cmd*/, CommandContainer *cont, Server_Game *game, Server_Player * /*player*/) +ResponseCode Server_ProtocolHandler::cmdNextTurn(Command_NextTurn * /*cmd*/, CommandContainer *cont, Server_Game *game, Server_Player *player) { + if (player->getSpectator()) + return RespFunctionNotAllowed; + if (!game->getGameStarted()) return RespGameNotStarted; @@ -727,6 +794,9 @@ ResponseCode Server_ProtocolHandler::cmdNextTurn(Command_NextTurn * /*cmd*/, Com ResponseCode Server_ProtocolHandler::cmdSetActivePhase(Command_SetActivePhase *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player) { + if (player->getSpectator()) + return RespFunctionNotAllowed; + if (!game->getGameStarted()) return RespGameNotStarted;