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;