Fixed elevation of spectator rights; added some spectator options; closes bug 0000005

This commit is contained in:
Max-Wilhelm Bruker 2010-05-26 21:36:54 +02:00
parent 604d1ffa94
commit befafa28ae
26 changed files with 430 additions and 220 deletions

View file

@ -14,11 +14,25 @@ DlgCreateGame::DlgCreateGame(Client *_client, QWidget *parent)
passwordLabel->setBuddy(passwordEdit); passwordLabel->setBuddy(passwordEdit);
maxPlayersLabel = new QLabel(tr("P&layers:")); 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); maxPlayersLabel->setBuddy(maxPlayersEdit);
spectatorsAllowedCheckBox = new QCheckBox(tr("&Spectators allowed")); spectatorsAllowedCheckBox = new QCheckBox(tr("&Spectators allowed"));
spectatorsAllowedCheckBox->setChecked(true); 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; QGridLayout *grid = new QGridLayout;
grid->addWidget(descriptionLabel, 0, 0); grid->addWidget(descriptionLabel, 0, 0);
@ -27,7 +41,7 @@ DlgCreateGame::DlgCreateGame(Client *_client, QWidget *parent)
grid->addWidget(passwordEdit, 1, 1); grid->addWidget(passwordEdit, 1, 1);
grid->addWidget(maxPlayersLabel, 2, 0); grid->addWidget(maxPlayersLabel, 2, 0);
grid->addWidget(maxPlayersEdit, 2, 1); 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 = new QPushButton(tr("&OK"));
okButton->setDefault(true); okButton->setDefault(true);
@ -53,13 +67,15 @@ DlgCreateGame::DlgCreateGame(Client *_client, QWidget *parent)
void DlgCreateGame::actOK() void DlgCreateGame::actOK()
{ {
bool ok; Command_CreateGame *createCommand = new Command_CreateGame(
int maxPlayers = maxPlayersEdit->text().toInt(&ok); descriptionEdit->text(),
if (!ok) { passwordEdit->text(),
QMessageBox::critical(this, tr("Error"), tr("Invalid number of players.")); maxPlayersEdit->value(),
return; spectatorsAllowedCheckBox->isChecked(),
} spectatorsNeedPasswordCheckBox->isChecked(),
Command_CreateGame *createCommand = new Command_CreateGame(descriptionEdit->text(), passwordEdit->text(), maxPlayers, spectatorsAllowedCheckBox->isChecked()); spectatorsCanTalkCheckBox->isChecked(),
spectatorsSeeEverythingCheckBox->isChecked()
);
connect(createCommand, SIGNAL(finished(ResponseCode)), this, SLOT(checkResponse(ResponseCode))); connect(createCommand, SIGNAL(finished(ResponseCode)), this, SLOT(checkResponse(ResponseCode)));
client->sendCommand(createCommand); client->sendCommand(createCommand);
@ -79,3 +95,10 @@ void DlgCreateGame::checkResponse(ResponseCode response)
return; return;
} }
} }
void DlgCreateGame::spectatorsAllowedChanged(int state)
{
spectatorsNeedPasswordCheckBox->setEnabled(state);
spectatorsCanTalkCheckBox->setEnabled(state);
spectatorsSeeEverythingCheckBox->setEnabled(state);
}

View file

@ -8,6 +8,8 @@ class QLabel;
class QLineEdit; class QLineEdit;
class QPushButton; class QPushButton;
class QCheckBox; class QCheckBox;
class QGroupBox;
class QSpinBox;
class DlgCreateGame : public QDialog { class DlgCreateGame : public QDialog {
Q_OBJECT Q_OBJECT
@ -16,12 +18,15 @@ public:
private slots: private slots:
void actOK(); void actOK();
void checkResponse(ResponseCode response); void checkResponse(ResponseCode response);
void spectatorsAllowedChanged(int state);
private: private:
Client *client; Client *client;
QGroupBox *spectatorsGroupBox;
QLabel *descriptionLabel, *passwordLabel, *maxPlayersLabel; QLabel *descriptionLabel, *passwordLabel, *maxPlayersLabel;
QLineEdit *descriptionEdit, *passwordEdit, *maxPlayersEdit; QLineEdit *descriptionEdit, *passwordEdit;
QCheckBox *spectatorsAllowedCheckBox; QSpinBox *maxPlayersEdit;
QCheckBox *spectatorsAllowedCheckBox, *spectatorsNeedPasswordCheckBox, *spectatorsCanTalkCheckBox, *spectatorsSeeEverythingCheckBox;
QPushButton *okButton, *cancelButton; QPushButton *okButton, *cancelButton;
}; };

View file

@ -27,7 +27,7 @@ QVariant GamesModel::data(const QModelIndex &index, int role) const
switch (index.column()) { switch (index.column()) {
case 0: return g->getDescription(); case 0: return g->getDescription();
case 1: return g->getCreatorName(); 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 3: return QString("%1/%2").arg(g->getPlayerCount()).arg(g->getMaxPlayers());
case 4: return g->getSpectatorsAllowed() ? QVariant(g->getSpectatorCount()) : QVariant(tr("not allowed")); case 4: return g->getSpectatorsAllowed() ? QVariant(g->getSpectatorCount()) : QVariant(tr("not allowed"));
default: return QVariant(); default: return QVariant();
@ -56,7 +56,7 @@ ServerInfo_Game *GamesModel::getGame(int row)
void GamesModel::updateGameList(ServerInfo_Game *_game) 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++) for (int i = 0; i < gameList.size(); i++)
if (gameList[i]->getGameId() == game->getGameId()) { if (gameList[i]->getGameId() == game->getGameId()) {
if (game->getPlayerCount() == 0) { if (game->getPlayerCount() == 0) {

View file

@ -5,8 +5,8 @@
#include "protocol_items.h" #include "protocol_items.h"
#include "settingscache.h" #include "settingscache.h"
HandZone::HandZone(Player *_p, int _zoneHeight, QGraphicsItem *parent) HandZone::HandZone(Player *_p, bool _contentsKnown, int _zoneHeight, QGraphicsItem *parent)
: CardZone(_p, "hand", false, false, _p->getLocal(), parent), zoneHeight(_zoneHeight) : CardZone(_p, "hand", false, false, _contentsKnown, parent), zoneHeight(_zoneHeight)
{ {
connect(settingsCache, SIGNAL(handBgPathChanged()), this, SLOT(updateBgPixmap())); connect(settingsCache, SIGNAL(handBgPathChanged()), this, SLOT(updateBgPixmap()));
updateBgPixmap(); updateBgPixmap();

View file

@ -11,7 +11,7 @@ private:
private slots: private slots:
void updateBgPixmap(); void updateBgPixmap();
public: public:
HandZone(Player *_p, int _zoneHeight, QGraphicsItem *parent = 0); HandZone(Player *_p, bool _contentsKnown, int _zoneHeight, QGraphicsItem *parent = 0);
QRectF boundingRect() const; QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
void reorganizeCards(); void reorganizeCards();

View file

@ -104,7 +104,12 @@ void MessageLogWidget::logGameStart()
void MessageLogWidget::logSay(Player *player, QString message) void MessageLogWidget::logSay(Player *player, QString message)
{ {
append(QString("<font color=\"red\">%1:</font> %2").arg(sanitizeHtml(player->getName())).arg(sanitizeHtml(message))); append(QString("<b><font color=\"red\">%1:</font></b> %2").arg(sanitizeHtml(player->getName())).arg(sanitizeHtml(message)));
}
void MessageLogWidget::logSpectatorSay(QString spectatorName, QString message)
{
append(QString("<font color=\"red\">%1:</font> %2").arg(sanitizeHtml(spectatorName)).arg(sanitizeHtml(message)));
} }
void MessageLogWidget::logShuffle(Player *player) void MessageLogWidget::logShuffle(Player *player)

View file

@ -33,6 +33,7 @@ public slots:
void logConcede(Player *player); void logConcede(Player *player);
void logGameStart(); void logGameStart();
void logSay(Player *player, QString message); void logSay(Player *player, QString message);
void logSpectatorSay(QString spectatorName, QString message);
void logShuffle(Player *player); void logShuffle(Player *player);
void logRollDie(Player *player, int sides, int roll); void logRollDie(Player *player, int sides, int roll);
void logDrawCards(Player *player, int number); void logDrawCards(Player *player, int number);

View file

@ -43,7 +43,7 @@ Player::Player(const QString &_name, int _id, bool _local, Client *_client, TabG
table = new TableZone(this, this); table = new TableZone(this, this);
connect(table, SIGNAL(sizeChanged()), this, SLOT(updateBoundingRect())); 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); base = QPointF(deck->boundingRect().width() + counterAreaWidth + 5, 0);
hand->setPos(base); hand->setPos(base);

View file

@ -19,8 +19,8 @@
#include "arrowitem.h" #include "arrowitem.h"
#include "main.h" #include "main.h"
TabGame::TabGame(Client *_client, int _gameId, const QString &_gameDescription, int _localPlayerId, bool _spectator, bool _resuming) 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), started(false), resuming(_resuming), currentPhase(-1) : 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); scene = new GameScene(this);
gameView = new GameView(scene); gameView = new GameView(scene);
@ -74,8 +74,10 @@ TabGame::TabGame(Client *_client, int _gameId, const QString &_gameDescription,
mainLayout->addLayout(verticalLayout); mainLayout->addLayout(verticalLayout);
if (spectator) { if (spectator) {
sayLabel->hide(); if (!spectatorsCanTalk) {
sayEdit->hide(); sayLabel->hide();
sayEdit->hide();
}
loadLocalButton->hide(); loadLocalButton->hide();
loadRemoteButton->hide(); loadRemoteButton->hide();
readyStartButton->hide(); readyStartButton->hide();
@ -226,7 +228,15 @@ void TabGame::processGameEventContainer(GameEventContainer *cont)
for (int i = 0; i < eventList.size(); ++i) { for (int i = 0; i < eventList.size(); ++i) {
GameEvent *event = eventList[i]; GameEvent *event = eventList[i];
switch (event->getItemId()) { if (spectators.contains(event->getPlayerId())) {
switch (event->getItemId()) {
case ItemId_Event_Say: eventSpectatorSay(qobject_cast<Event_Say *>(event), context); break;
default: {
qDebug() << "unhandled spectator game event";
break;
}
}
} else switch (event->getItemId()) {
case ItemId_Event_GameStateChanged: eventGameStateChanged(qobject_cast<Event_GameStateChanged *>(event), context); break; case ItemId_Event_GameStateChanged: eventGameStateChanged(qobject_cast<Event_GameStateChanged *>(event), context); break;
case ItemId_Event_PlayerPropertiesChanged: eventPlayerPropertiesChanged(qobject_cast<Event_PlayerPropertiesChanged *>(event), context); break; case ItemId_Event_PlayerPropertiesChanged: eventPlayerPropertiesChanged(qobject_cast<Event_PlayerPropertiesChanged *>(event), context); break;
case ItemId_Event_Join: eventJoin(qobject_cast<Event_Join *>(event), context); break; case ItemId_Event_Join: eventJoin(qobject_cast<Event_Join *>(event), context); break;
@ -289,6 +299,11 @@ void TabGame::stopGame()
deckViewContainer->show(); 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*/) void TabGame::eventGameStateChanged(Event_GameStateChanged *event, GameEventContext * /*context*/)
{ {
const QList<ServerInfo_Player *> &plList = event->getPlayerList(); const QList<ServerInfo_Player *> &plList = event->getPlayerList();

View file

@ -33,6 +33,7 @@ class Event_GameStart;
class Event_SetActivePlayer; class Event_SetActivePlayer;
class Event_SetActivePhase; class Event_SetActivePhase;
class Event_Ping; class Event_Ping;
class Event_Say;
class Player; class Player;
class CardZone; class CardZone;
class AbstractCardItem; class AbstractCardItem;
@ -46,6 +47,7 @@ private:
QString gameDescription; QString gameDescription;
int localPlayerId; int localPlayerId;
bool spectator; bool spectator;
bool spectatorsCanTalk, spectatorsSeeEverything;
QMap<int, Player *> players; QMap<int, Player *> players;
QMap<int, QString> spectators; QMap<int, QString> spectators;
bool started; bool started;
@ -73,6 +75,7 @@ private:
void startGame(); void startGame();
void stopGame(); void stopGame();
void eventSpectatorSay(Event_Say *event, GameEventContext *context);
void eventGameStateChanged(Event_GameStateChanged *event, GameEventContext *context); void eventGameStateChanged(Event_GameStateChanged *event, GameEventContext *context);
void eventPlayerPropertiesChanged(Event_PlayerPropertiesChanged *event, GameEventContext *context); void eventPlayerPropertiesChanged(Event_PlayerPropertiesChanged *event, GameEventContext *context);
void eventJoin(Event_Join *event, GameEventContext *context); void eventJoin(Event_Join *event, GameEventContext *context);
@ -100,12 +103,15 @@ private slots:
void actNextPhase(); void actNextPhase();
void actNextTurn(); void actNextTurn();
public: 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(); ~TabGame();
void retranslateUi(); void retranslateUi();
const QMap<int, Player *> &getPlayers() const { return players; } const QMap<int, Player *> &getPlayers() const { return players; }
int getGameId() const { return gameId; } int getGameId() const { return gameId; }
QString getTabText() const { return tr("Game %1: %2").arg(gameId).arg(gameDescription); } 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); void processGameEventContainer(GameEventContainer *cont);
public slots: public slots:

View file

@ -81,7 +81,7 @@ void GameSelector::actJoin()
return; return;
ServerInfo_Game *game = gameListModel->getGame(ind.data(Qt::UserRole).toInt()); ServerInfo_Game *game = gameListModel->getGame(ind.data(Qt::UserRole).toInt());
QString password; QString password;
if (game->getHasPassword()) { if (game->getHasPassword() && !(spectator && !game->getSpectatorsNeedPassword())) {
bool ok; bool ok;
password = QInputDialog::getText(this, tr("Join game"), tr("Password:"), QLineEdit::Password, QString(), &ok); password = QInputDialog::getText(this, tr("Join game"), tr("Password:"), QLineEdit::Password, QString(), &ok);
if (!ok) if (!ok)

View file

@ -103,7 +103,7 @@ void TabSupervisor::updatePingTime(int value, int max)
void TabSupervisor::gameJoined(Event_GameJoined *event) 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 *))); connect(tab, SIGNAL(gameClosing(TabGame *)), this, SLOT(gameLeft(TabGame *)));
myAddTab(tab); myAddTab(tab);
gameTabs.insert(event->getGameId(), tab); gameTabs.insert(event->getGameId(), tab);

View file

@ -476,38 +476,56 @@
<translation>&amp;Spieler:</translation> <translation>&amp;Spieler:</translation>
</message> </message>
<message> <message>
<location filename="../src/dlg_creategame.cpp" line="20"/> <location filename="../src/dlg_creategame.cpp" line="23"/>
<source>&amp;Spectators allowed</source> <source>&amp;Spectators allowed</source>
<translation>&amp;Zuschauer zugelassen</translation> <translation>&amp;Zuschauer zugelassen</translation>
</message> </message>
<message> <message>
<location filename="../src/dlg_creategame.cpp" line="32"/> <location filename="../src/dlg_creategame.cpp" line="26"/>
<source>Spectators &amp;need a password to join</source>
<translation>Zuschauer brauchen &amp;auch ein Passwort</translation>
</message>
<message>
<location filename="../src/dlg_creategame.cpp" line="27"/>
<source>Spectators can &amp;talk</source>
<translation>Zuschauer können sp&amp;rechen</translation>
</message>
<message>
<location filename="../src/dlg_creategame.cpp" line="28"/>
<source>Spectators see &amp;everything</source>
<translation>Zuschauer sehen &amp;alles</translation>
</message>
<message>
<location filename="../src/dlg_creategame.cpp" line="34"/>
<source>Spectators</source>
<translation>Zuschauer</translation>
</message>
<message>
<location filename="../src/dlg_creategame.cpp" line="46"/>
<source>&amp;OK</source> <source>&amp;OK</source>
<translation>&amp;OK</translation> <translation>&amp;OK</translation>
</message> </message>
<message> <message>
<location filename="../src/dlg_creategame.cpp" line="34"/> <location filename="../src/dlg_creategame.cpp" line="48"/>
<source>&amp;Cancel</source> <source>&amp;Cancel</source>
<translation>&amp;Abbruch</translation> <translation>&amp;Abbruch</translation>
</message> </message>
<message> <message>
<location filename="../src/dlg_creategame.cpp" line="47"/> <location filename="../src/dlg_creategame.cpp" line="61"/>
<source>Create game</source> <source>Create game</source>
<translation>Spiel erstellen</translation> <translation>Spiel erstellen</translation>
</message> </message>
<message> <message>
<location filename="../src/dlg_creategame.cpp" line="59"/> <location filename="../src/dlg_creategame.cpp" line="94"/>
<location filename="../src/dlg_creategame.cpp" line="78"/>
<source>Error</source> <source>Error</source>
<translation>Fehler</translation> <translation>Fehler</translation>
</message> </message>
<message> <message>
<location filename="../src/dlg_creategame.cpp" line="59"/>
<source>Invalid number of players.</source> <source>Invalid number of players.</source>
<translation>Ungültige Anzahl an Spielern.</translation> <translation type="obsolete">Ungültige Anzahl an Spielern.</translation>
</message> </message>
<message> <message>
<location filename="../src/dlg_creategame.cpp" line="78"/> <location filename="../src/dlg_creategame.cpp" line="94"/>
<source>Server error.</source> <source>Server error.</source>
<translation>Serverfehler.</translation> <translation>Serverfehler.</translation>
</message> </message>
@ -978,6 +996,11 @@
<source>Description</source> <source>Description</source>
<translation>Beschreibung</translation> <translation>Beschreibung</translation>
</message> </message>
<message>
<location filename="../src/gamesmodel.cpp" line="30"/>
<source>yes, free for spectators</source>
<translation>ja, außer für Zuschauer</translation>
</message>
<message> <message>
<location filename="../src/gamesmodel.cpp" line="32"/> <location filename="../src/gamesmodel.cpp" line="32"/>
<source>not allowed</source> <source>not allowed</source>
@ -1246,7 +1269,7 @@
<translation type="obsolete">%1 zieht %2 Karten</translation> <translation type="obsolete">%1 zieht %2 Karten</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="188"/> <location filename="../src/messagelogwidget.cpp" line="193"/>
<source>a card</source> <source>a card</source>
<translation>eine Karte</translation> <translation>eine Karte</translation>
</message> </message>
@ -1308,7 +1331,7 @@
<translation>Das Spiel hat begonnen.</translation> <translation>Das Spiel hat begonnen.</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="112"/> <location filename="../src/messagelogwidget.cpp" line="117"/>
<source>%1 shuffles his library.</source> <source>%1 shuffles his library.</source>
<translation>%1 mischt seine Bibliothek.</translation> <translation>%1 mischt seine Bibliothek.</translation>
</message> </message>
@ -1385,122 +1408,122 @@
<translation>%1 hat das Spiel aufgegeben.</translation> <translation>%1 hat das Spiel aufgegeben.</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="117"/> <location filename="../src/messagelogwidget.cpp" line="122"/>
<source>%1 rolls a %2 with a %3-sided die.</source> <source>%1 rolls a %2 with a %3-sided die.</source>
<translation>%1 würfelt eine %2 mit einem %3-seitigen Würfel.</translation> <translation>%1 würfelt eine %2 mit einem %3-seitigen Würfel.</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="123"/> <location filename="../src/messagelogwidget.cpp" line="128"/>
<source>%1 draws a card.</source> <source>%1 draws a card.</source>
<translation>%1 zieht eine Karte.</translation> <translation>%1 zieht eine Karte.</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="125"/> <location filename="../src/messagelogwidget.cpp" line="130"/>
<source>%1 draws %2 cards.</source> <source>%1 draws %2 cards.</source>
<translation>%1 zieht %2 Karten.</translation> <translation>%1 zieht %2 Karten.</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="138"/> <location filename="../src/messagelogwidget.cpp" line="143"/>
<source> from table</source> <source> from table</source>
<translation> vom Spielfeld</translation> <translation> vom Spielfeld</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="140"/> <location filename="../src/messagelogwidget.cpp" line="145"/>
<source> from graveyard</source> <source> from graveyard</source>
<translation> aus dem Friedhof</translation> <translation> aus dem Friedhof</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="142"/> <location filename="../src/messagelogwidget.cpp" line="147"/>
<source> from exile</source> <source> from exile</source>
<translation> aus dem Exil</translation> <translation> aus dem Exil</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="144"/> <location filename="../src/messagelogwidget.cpp" line="149"/>
<source> from hand</source> <source> from hand</source>
<translation> von der Hand</translation> <translation> von der Hand</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="148"/> <location filename="../src/messagelogwidget.cpp" line="153"/>
<source>the bottom card of his library</source> <source>the bottom card of his library</source>
<translation>die unterste Karte seiner Bibliothek</translation> <translation>die unterste Karte seiner Bibliothek</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="151"/> <location filename="../src/messagelogwidget.cpp" line="156"/>
<source> from the bottom of his library</source> <source> from the bottom of his library</source>
<translation>, die unterste Karte seiner Bibliothek,</translation> <translation>, die unterste Karte seiner Bibliothek,</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="154"/> <location filename="../src/messagelogwidget.cpp" line="159"/>
<source>the top card of his library</source> <source>the top card of his library</source>
<translation>die oberste Karte seiner Bibliothek</translation> <translation>die oberste Karte seiner Bibliothek</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="157"/> <location filename="../src/messagelogwidget.cpp" line="162"/>
<source> from the top of his library</source> <source> from the top of his library</source>
<translation>, die oberste Karte seiner Bibliothek,</translation> <translation>, die oberste Karte seiner Bibliothek,</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="159"/> <location filename="../src/messagelogwidget.cpp" line="164"/>
<source> from library</source> <source> from library</source>
<translation> aus der Bibliothek</translation> <translation> aus der Bibliothek</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="161"/> <location filename="../src/messagelogwidget.cpp" line="166"/>
<source> from sideboard</source> <source> from sideboard</source>
<translation> aus dem Sideboard</translation> <translation> aus dem Sideboard</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="165"/> <location filename="../src/messagelogwidget.cpp" line="170"/>
<source>%1 puts %2 into play%3.</source> <source>%1 puts %2 into play%3.</source>
<translation>%1 bringt %2%3 ins Spiel.</translation> <translation>%1 bringt %2%3 ins Spiel.</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="167"/> <location filename="../src/messagelogwidget.cpp" line="172"/>
<source>%1 puts %2%3 into graveyard.</source> <source>%1 puts %2%3 into graveyard.</source>
<translation>%1 legt %2%3 auf den Friedhof.</translation> <translation>%1 legt %2%3 auf den Friedhof.</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="169"/> <location filename="../src/messagelogwidget.cpp" line="174"/>
<source>%1 exiles %2%3.</source> <source>%1 exiles %2%3.</source>
<translation>%1 schickt %2%3 ins Exil.</translation> <translation>%1 schickt %2%3 ins Exil.</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="171"/> <location filename="../src/messagelogwidget.cpp" line="176"/>
<source>%1 moves %2%3 to hand.</source> <source>%1 moves %2%3 to hand.</source>
<translation>%1 nimmt %2%3 auf die Hand.</translation> <translation>%1 nimmt %2%3 auf die Hand.</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="174"/> <location filename="../src/messagelogwidget.cpp" line="179"/>
<source>%1 puts %2%3 into his library.</source> <source>%1 puts %2%3 into his library.</source>
<translation>%1 legt %2%3 in seine Bibliothek.</translation> <translation>%1 legt %2%3 in seine Bibliothek.</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="176"/> <location filename="../src/messagelogwidget.cpp" line="181"/>
<source>%1 puts %2%3 on bottom of his library.</source> <source>%1 puts %2%3 on bottom of his library.</source>
<translation>%1 legt %2%3 unter seine Bibliothek.</translation> <translation>%1 legt %2%3 unter seine Bibliothek.</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="178"/> <location filename="../src/messagelogwidget.cpp" line="183"/>
<source>%1 puts %2%3 on top of his library.</source> <source>%1 puts %2%3 on top of his library.</source>
<translation>%1 legt %2%3 auf die Bibliothek.</translation> <translation>%1 legt %2%3 auf die Bibliothek.</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="180"/> <location filename="../src/messagelogwidget.cpp" line="185"/>
<source>%1 puts %2%3 into his library at position %4.</source> <source>%1 puts %2%3 into his library at position %4.</source>
<translation>%1 legt %2%3 in seine Bibliothek an %4. Stelle.</translation> <translation>%1 legt %2%3 in seine Bibliothek an %4. Stelle.</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="182"/> <location filename="../src/messagelogwidget.cpp" line="187"/>
<source>%1 moves %2%3 to sideboard.</source> <source>%1 moves %2%3 to sideboard.</source>
<translation>%1 legt %2%3 in sein Sideboard.</translation> <translation>%1 legt %2%3 in sein Sideboard.</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="202"/> <location filename="../src/messagelogwidget.cpp" line="207"/>
<source>%1 points from %2&apos;s %3 to %4&apos;s %5.</source> <source>%1 points from %2&apos;s %3 to %4&apos;s %5.</source>
<translation>%1 zeigt von %2s %3 auf %4s %5.</translation> <translation>%1 zeigt von %2s %3 auf %4s %5.</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="249"/> <location filename="../src/messagelogwidget.cpp" line="254"/>
<source>%1 is looking at the top %2 cards %3.</source> <source>%1 is looking at the top %2 cards %3.</source>
<translation>%1 sieht sich die obersten %2 Karten %3 an.</translation> <translation>%1 sieht sich die obersten %2 Karten %3 an.</translation>
</message> </message>
@ -1585,27 +1608,27 @@
<translation type="obsolete">%1 legt %2%3in sein Sideboard.</translation> <translation type="obsolete">%1 legt %2%3in sein Sideboard.</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="197"/> <location filename="../src/messagelogwidget.cpp" line="202"/>
<source>%1 creates token: %2.</source> <source>%1 creates token: %2.</source>
<translation>%1 erstellt Token: %2.</translation> <translation>%1 erstellt Token: %2.</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="215"/> <location filename="../src/messagelogwidget.cpp" line="220"/>
<source>%1 places %2 counters on %3 (now %4).</source> <source>%1 places %2 counters on %3 (now %4).</source>
<translation>%1 legt %2 Zählmarken auf %3 (jetzt %4).</translation> <translation>%1 legt %2 Zählmarken auf %3 (jetzt %4).</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="217"/> <location filename="../src/messagelogwidget.cpp" line="222"/>
<source>%1 removes %2 counters from %3 (now %4).</source> <source>%1 removes %2 counters from %3 (now %4).</source>
<translation>%1 entfernt %2 Zählmarken von %3 (jetzt %4).</translation> <translation>%1 entfernt %2 Zählmarken von %3 (jetzt %4).</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="228"/> <location filename="../src/messagelogwidget.cpp" line="233"/>
<source>%1 %2 %3.</source> <source>%1 %2 %3.</source>
<translation>%1 %2 %3.</translation> <translation>%1 %2 %3.</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="233"/> <location filename="../src/messagelogwidget.cpp" line="238"/>
<source>%1 sets counter &quot;%2&quot; to %3 (%4%5).</source> <source>%1 sets counter &quot;%2&quot; to %3 (%4%5).</source>
<translation>%1 setzt Zählmarke &quot;%2&quot; auf %3 (%4%5).</translation> <translation>%1 setzt Zählmarke &quot;%2&quot; auf %3 (%4%5).</translation>
</message> </message>
@ -1614,17 +1637,17 @@
<translation type="obsolete">%1 sieht sich die obersten %2 Karten %3 an.</translation> <translation type="obsolete">%1 sieht sich die obersten %2 Karten %3 an.</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="251"/> <location filename="../src/messagelogwidget.cpp" line="256"/>
<source>%1 is looking at %2.</source> <source>%1 is looking at %2.</source>
<translation>%1 sieht sich %2 an.</translation> <translation>%1 sieht sich %2 an.</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="257"/> <location filename="../src/messagelogwidget.cpp" line="262"/>
<source>%1 stops looking at %2.</source> <source>%1 stops looking at %2.</source>
<translation>%1 sieht sich %2 nicht mehr an.</translation> <translation>%1 sieht sich %2 nicht mehr an.</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="281"/> <location filename="../src/messagelogwidget.cpp" line="286"/>
<source>ending phase</source> <source>ending phase</source>
<translation>die Zugendphase</translation> <translation>die Zugendphase</translation>
</message> </message>
@ -1653,57 +1676,57 @@
<translation type="obsolete">%1 sieht sich %2s %3 nicht mehr an</translation> <translation type="obsolete">%1 sieht sich %2s %3 nicht mehr an</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="263"/> <location filename="../src/messagelogwidget.cpp" line="268"/>
<source>It is now %1&apos;s turn.</source> <source>It is now %1&apos;s turn.</source>
<translation>%1 ist am Zug.</translation> <translation>%1 ist am Zug.</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="271"/> <location filename="../src/messagelogwidget.cpp" line="276"/>
<source>untap step</source> <source>untap step</source>
<translation>das Enttappsegment</translation> <translation>das Enttappsegment</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="272"/> <location filename="../src/messagelogwidget.cpp" line="277"/>
<source>upkeep step</source> <source>upkeep step</source>
<translation>das Versorgungssegment</translation> <translation>das Versorgungssegment</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="273"/> <location filename="../src/messagelogwidget.cpp" line="278"/>
<source>draw step</source> <source>draw step</source>
<translation>das Ziehsegment</translation> <translation>das Ziehsegment</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="274"/> <location filename="../src/messagelogwidget.cpp" line="279"/>
<source>first main phase</source> <source>first main phase</source>
<translation>die erste Hauptphase</translation> <translation>die erste Hauptphase</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="275"/> <location filename="../src/messagelogwidget.cpp" line="280"/>
<source>beginning of combat step</source> <source>beginning of combat step</source>
<translation>das Anfangssegment der Kampfphase</translation> <translation>das Anfangssegment der Kampfphase</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="276"/> <location filename="../src/messagelogwidget.cpp" line="281"/>
<source>declare attackers step</source> <source>declare attackers step</source>
<translation>das Angreifer-Deklarieren-Segment</translation> <translation>das Angreifer-Deklarieren-Segment</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="277"/> <location filename="../src/messagelogwidget.cpp" line="282"/>
<source>declare blockers step</source> <source>declare blockers step</source>
<translation>das Blocker-Deklarieren-Segment</translation> <translation>das Blocker-Deklarieren-Segment</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="278"/> <location filename="../src/messagelogwidget.cpp" line="283"/>
<source>combat damage step</source> <source>combat damage step</source>
<translation>das Kampfschadenssegment</translation> <translation>das Kampfschadenssegment</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="279"/> <location filename="../src/messagelogwidget.cpp" line="284"/>
<source>end of combat step</source> <source>end of combat step</source>
<translation>das Endsegment der Kampfphase</translation> <translation>das Endsegment der Kampfphase</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="280"/> <location filename="../src/messagelogwidget.cpp" line="285"/>
<source>second main phase</source> <source>second main phase</source>
<translation>die zweite Hauptphase</translation> <translation>die zweite Hauptphase</translation>
</message> </message>
@ -1712,7 +1735,7 @@
<translation type="obsolete">das Ende-des-Zuges-Segment</translation> <translation type="obsolete">das Ende-des-Zuges-Segment</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="283"/> <location filename="../src/messagelogwidget.cpp" line="288"/>
<source>It is now the %1.</source> <source>It is now the %1.</source>
<translation>Es ist nun %1.</translation> <translation>Es ist nun %1.</translation>
</message> </message>
@ -1721,12 +1744,12 @@
<translation type="obsolete">%1 bewegt %2 %3 nach %4</translation> <translation type="obsolete">%1 bewegt %2 %3 nach %4</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="228"/> <location filename="../src/messagelogwidget.cpp" line="233"/>
<source>taps</source> <source>taps</source>
<translation>tappt</translation> <translation>tappt</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="228"/> <location filename="../src/messagelogwidget.cpp" line="233"/>
<source>untaps</source> <source>untaps</source>
<translation>enttappt</translation> <translation>enttappt</translation>
</message> </message>
@ -1751,7 +1774,7 @@
<translation type="obsolete">%1 entfernt %2 Zählmarken von %3 (jetzt %4)</translation> <translation type="obsolete">%1 entfernt %2 Zählmarken von %3 (jetzt %4)</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="225"/> <location filename="../src/messagelogwidget.cpp" line="230"/>
<source>his permanents</source> <source>his permanents</source>
<translation>seine bleibenden Karten</translation> <translation>seine bleibenden Karten</translation>
</message> </message>
@ -1764,12 +1787,12 @@
<translation type="obsolete">%1 setzt Zähler &quot;%2&quot; auf %3 (%4%5)</translation> <translation type="obsolete">%1 setzt Zähler &quot;%2&quot; auf %3 (%4%5)</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="240"/> <location filename="../src/messagelogwidget.cpp" line="245"/>
<source>%1 sets %2 to not untap normally.</source> <source>%1 sets %2 to not untap normally.</source>
<translation>%1 setzt %2 auf explizites Enttappen.</translation> <translation>%1 setzt %2 auf explizites Enttappen.</translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="242"/> <location filename="../src/messagelogwidget.cpp" line="247"/>
<source>%1 sets %2 to untap normally.</source> <source>%1 sets %2 to untap normally.</source>
<translation>%1 setzt %2 auf normales Enttappen.</translation> <translation>%1 setzt %2 auf normales Enttappen.</translation>
</message> </message>
@ -2447,77 +2470,77 @@ Bitte geben Sie einen Namen ein:</translation>
<context> <context>
<name>TabGame</name> <name>TabGame</name>
<message> <message>
<location filename="../src/tab_game.cpp" line="130"/> <location filename="../src/tab_game.cpp" line="132"/>
<source>&amp;Game</source> <source>&amp;Game</source>
<translation>Spi&amp;el</translation> <translation>Spi&amp;el</translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="131"/> <location filename="../src/tab_game.cpp" line="133"/>
<source>Next &amp;phase</source> <source>Next &amp;phase</source>
<translation>Nächste &amp;Phase</translation> <translation>Nächste &amp;Phase</translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="132"/> <location filename="../src/tab_game.cpp" line="134"/>
<source>Ctrl+Space</source> <source>Ctrl+Space</source>
<translation>Ctrl+Space</translation> <translation>Ctrl+Space</translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="133"/> <location filename="../src/tab_game.cpp" line="135"/>
<source>Next &amp;turn</source> <source>Next &amp;turn</source>
<translation>Nächster &amp;Zug</translation> <translation>Nächster &amp;Zug</translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="134"/> <location filename="../src/tab_game.cpp" line="136"/>
<source>Ctrl+Return</source> <source>Ctrl+Return</source>
<translation>Ctrl+Return</translation> <translation>Ctrl+Return</translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="134"/> <location filename="../src/tab_game.cpp" line="136"/>
<source>Ctrl+Enter</source> <source>Ctrl+Enter</source>
<translation>Ctrl+Enter</translation> <translation>Ctrl+Enter</translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="135"/> <location filename="../src/tab_game.cpp" line="137"/>
<source>&amp;Remove all local arrows</source> <source>&amp;Remove all local arrows</source>
<translation>&amp;Lokale Pfeile entfernen</translation> <translation>&amp;Lokale Pfeile entfernen</translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="136"/> <location filename="../src/tab_game.cpp" line="138"/>
<source>Ctrl+R</source> <source>Ctrl+R</source>
<translation>Ctrl+R</translation> <translation>Ctrl+R</translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="137"/> <location filename="../src/tab_game.cpp" line="139"/>
<source>&amp;Concede</source> <source>&amp;Concede</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="138"/> <location filename="../src/tab_game.cpp" line="140"/>
<source>F2</source> <source>F2</source>
<translation>F2</translation> <translation>F2</translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="139"/> <location filename="../src/tab_game.cpp" line="141"/>
<source>&amp;Leave game</source> <source>&amp;Leave game</source>
<translation>Spiel ver&amp;lassen</translation> <translation>Spiel ver&amp;lassen</translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="141"/> <location filename="../src/tab_game.cpp" line="143"/>
<source>Load &amp;local deck</source> <source>Load &amp;local deck</source>
<translation>&amp;Lokales Deck laden</translation> <translation>&amp;Lokales Deck laden</translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="142"/> <location filename="../src/tab_game.cpp" line="144"/>
<source>Load d&amp;eck from server</source> <source>Load d&amp;eck from server</source>
<translation>Deck vom Server l&amp;aden</translation> <translation>Deck vom Server l&amp;aden</translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="143"/> <location filename="../src/tab_game.cpp" line="145"/>
<source>S&amp;tart game</source> <source>S&amp;tart game</source>
<translation>Spiel s&amp;tarten</translation> <translation>Spiel s&amp;tarten</translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="144"/> <location filename="../src/tab_game.cpp" line="146"/>
<source>&amp;Say:</source> <source>&amp;Say:</source>
<translation>&amp;Sagen:</translation> <translation>&amp;Sagen:</translation>
</message> </message>
@ -2530,32 +2553,32 @@ Bitte geben Sie einen Namen ein:</translation>
<translation type="obsolete">Esc</translation> <translation type="obsolete">Esc</translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="156"/> <location filename="../src/tab_game.cpp" line="158"/>
<source>Concede</source> <source>Concede</source>
<translation>Aufgeben</translation> <translation>Aufgeben</translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="156"/> <location filename="../src/tab_game.cpp" line="158"/>
<source>Are you sure you want to concede this game?</source> <source>Are you sure you want to concede this game?</source>
<translation>Sind Sie sicher, dass Sie das Spiel aufgeben möchten?</translation> <translation>Sind Sie sicher, dass Sie das Spiel aufgeben möchten?</translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="164"/> <location filename="../src/tab_game.cpp" line="166"/>
<source>Leave game</source> <source>Leave game</source>
<translation>Spiel verlassen</translation> <translation>Spiel verlassen</translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="164"/> <location filename="../src/tab_game.cpp" line="166"/>
<source>Are you sure you want to leave this game?</source> <source>Are you sure you want to leave this game?</source>
<translation>Sind Sie sicher, dass Sie das Spiel verlassen möchten?</translation> <translation>Sind Sie sicher, dass Sie das Spiel verlassen möchten?</translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="435"/> <location filename="../src/tab_game.cpp" line="450"/>
<source>Load deck</source> <source>Load deck</source>
<translation>Deck laden</translation> <translation>Deck laden</translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.h" line="108"/> <location filename="../src/tab_game.h" line="111"/>
<source>Game %1: %2</source> <source>Game %1: %2</source>
<translation>Spiel %1: %2</translation> <translation>Spiel %1: %2</translation>
</message> </message>

View file

@ -396,38 +396,52 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/dlg_creategame.cpp" line="20"/> <location filename="../src/dlg_creategame.cpp" line="23"/>
<source>&amp;Spectators allowed</source> <source>&amp;Spectators allowed</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/dlg_creategame.cpp" line="32"/> <location filename="../src/dlg_creategame.cpp" line="26"/>
<source>&amp;OK</source> <source>Spectators &amp;need a password to join</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/dlg_creategame.cpp" line="27"/>
<source>Spectators can &amp;talk</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/dlg_creategame.cpp" line="28"/>
<source>Spectators see &amp;everything</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/dlg_creategame.cpp" line="34"/> <location filename="../src/dlg_creategame.cpp" line="34"/>
<source>Spectators</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/dlg_creategame.cpp" line="46"/>
<source>&amp;OK</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/dlg_creategame.cpp" line="48"/>
<source>&amp;Cancel</source> <source>&amp;Cancel</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/dlg_creategame.cpp" line="47"/> <location filename="../src/dlg_creategame.cpp" line="61"/>
<source>Create game</source> <source>Create game</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/dlg_creategame.cpp" line="59"/> <location filename="../src/dlg_creategame.cpp" line="94"/>
<location filename="../src/dlg_creategame.cpp" line="78"/>
<source>Error</source> <source>Error</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/dlg_creategame.cpp" line="59"/> <location filename="../src/dlg_creategame.cpp" line="94"/>
<source>Invalid number of players.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../src/dlg_creategame.cpp" line="78"/>
<source>Server error.</source> <source>Server error.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -601,6 +615,11 @@
<source>Description</source> <source>Description</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<location filename="../src/gamesmodel.cpp" line="30"/>
<source>yes, free for spectators</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<location filename="../src/gamesmodel.cpp" line="32"/> <location filename="../src/gamesmodel.cpp" line="32"/>
<source>not allowed</source> <source>not allowed</source>
@ -808,117 +827,117 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="117"/> <location filename="../src/messagelogwidget.cpp" line="122"/>
<source>%1 rolls a %2 with a %3-sided die.</source> <source>%1 rolls a %2 with a %3-sided die.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="138"/> <location filename="../src/messagelogwidget.cpp" line="143"/>
<source> from table</source> <source> from table</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="140"/> <location filename="../src/messagelogwidget.cpp" line="145"/>
<source> from graveyard</source> <source> from graveyard</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="142"/> <location filename="../src/messagelogwidget.cpp" line="147"/>
<source> from exile</source> <source> from exile</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="144"/> <location filename="../src/messagelogwidget.cpp" line="149"/>
<source> from hand</source> <source> from hand</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="148"/> <location filename="../src/messagelogwidget.cpp" line="153"/>
<source>the bottom card of his library</source> <source>the bottom card of his library</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="151"/> <location filename="../src/messagelogwidget.cpp" line="156"/>
<source> from the bottom of his library</source> <source> from the bottom of his library</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="154"/> <location filename="../src/messagelogwidget.cpp" line="159"/>
<source>the top card of his library</source> <source>the top card of his library</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="157"/> <location filename="../src/messagelogwidget.cpp" line="162"/>
<source> from the top of his library</source> <source> from the top of his library</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="159"/> <location filename="../src/messagelogwidget.cpp" line="164"/>
<source> from library</source> <source> from library</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="161"/> <location filename="../src/messagelogwidget.cpp" line="166"/>
<source> from sideboard</source> <source> from sideboard</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="165"/> <location filename="../src/messagelogwidget.cpp" line="170"/>
<source>%1 puts %2 into play%3.</source> <source>%1 puts %2 into play%3.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="167"/> <location filename="../src/messagelogwidget.cpp" line="172"/>
<source>%1 puts %2%3 into graveyard.</source> <source>%1 puts %2%3 into graveyard.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="169"/> <location filename="../src/messagelogwidget.cpp" line="174"/>
<source>%1 exiles %2%3.</source> <source>%1 exiles %2%3.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="171"/> <location filename="../src/messagelogwidget.cpp" line="176"/>
<source>%1 moves %2%3 to hand.</source> <source>%1 moves %2%3 to hand.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="174"/> <location filename="../src/messagelogwidget.cpp" line="179"/>
<source>%1 puts %2%3 into his library.</source> <source>%1 puts %2%3 into his library.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="176"/> <location filename="../src/messagelogwidget.cpp" line="181"/>
<source>%1 puts %2%3 on bottom of his library.</source> <source>%1 puts %2%3 on bottom of his library.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="178"/> <location filename="../src/messagelogwidget.cpp" line="183"/>
<source>%1 puts %2%3 on top of his library.</source> <source>%1 puts %2%3 on top of his library.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="180"/> <location filename="../src/messagelogwidget.cpp" line="185"/>
<source>%1 puts %2%3 into his library at position %4.</source> <source>%1 puts %2%3 into his library at position %4.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="182"/> <location filename="../src/messagelogwidget.cpp" line="187"/>
<source>%1 moves %2%3 to sideboard.</source> <source>%1 moves %2%3 to sideboard.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="188"/> <location filename="../src/messagelogwidget.cpp" line="193"/>
<source>a card</source> <source>a card</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="202"/> <location filename="../src/messagelogwidget.cpp" line="207"/>
<source>%1 points from %2&apos;s %3 to %4&apos;s %5.</source> <source>%1 points from %2&apos;s %3 to %4&apos;s %5.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="249"/> <location filename="../src/messagelogwidget.cpp" line="254"/>
<source>%1 is looking at the top %2 cards %3.</source> <source>%1 is looking at the top %2 cards %3.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -973,142 +992,142 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="123"/> <location filename="../src/messagelogwidget.cpp" line="128"/>
<source>%1 draws a card.</source> <source>%1 draws a card.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="125"/> <location filename="../src/messagelogwidget.cpp" line="130"/>
<source>%1 draws %2 cards.</source> <source>%1 draws %2 cards.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="197"/> <location filename="../src/messagelogwidget.cpp" line="202"/>
<source>%1 creates token: %2.</source> <source>%1 creates token: %2.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="215"/> <location filename="../src/messagelogwidget.cpp" line="220"/>
<source>%1 places %2 counters on %3 (now %4).</source> <source>%1 places %2 counters on %3 (now %4).</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="217"/> <location filename="../src/messagelogwidget.cpp" line="222"/>
<source>%1 removes %2 counters from %3 (now %4).</source> <source>%1 removes %2 counters from %3 (now %4).</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="228"/> <location filename="../src/messagelogwidget.cpp" line="233"/>
<source>%1 %2 %3.</source> <source>%1 %2 %3.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="233"/> <location filename="../src/messagelogwidget.cpp" line="238"/>
<source>%1 sets counter &quot;%2&quot; to %3 (%4%5).</source> <source>%1 sets counter &quot;%2&quot; to %3 (%4%5).</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="251"/> <location filename="../src/messagelogwidget.cpp" line="256"/>
<source>%1 is looking at %2.</source> <source>%1 is looking at %2.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="257"/> <location filename="../src/messagelogwidget.cpp" line="262"/>
<source>%1 stops looking at %2.</source> <source>%1 stops looking at %2.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="281"/> <location filename="../src/messagelogwidget.cpp" line="286"/>
<source>ending phase</source> <source>ending phase</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="263"/> <location filename="../src/messagelogwidget.cpp" line="268"/>
<source>It is now %1&apos;s turn.</source> <source>It is now %1&apos;s turn.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="112"/> <location filename="../src/messagelogwidget.cpp" line="117"/>
<source>%1 shuffles his library.</source> <source>%1 shuffles his library.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="271"/> <location filename="../src/messagelogwidget.cpp" line="276"/>
<source>untap step</source> <source>untap step</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="272"/> <location filename="../src/messagelogwidget.cpp" line="277"/>
<source>upkeep step</source> <source>upkeep step</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="273"/> <location filename="../src/messagelogwidget.cpp" line="278"/>
<source>draw step</source> <source>draw step</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="274"/> <location filename="../src/messagelogwidget.cpp" line="279"/>
<source>first main phase</source> <source>first main phase</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="275"/> <location filename="../src/messagelogwidget.cpp" line="280"/>
<source>beginning of combat step</source> <source>beginning of combat step</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="276"/> <location filename="../src/messagelogwidget.cpp" line="281"/>
<source>declare attackers step</source> <source>declare attackers step</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="277"/> <location filename="../src/messagelogwidget.cpp" line="282"/>
<source>declare blockers step</source> <source>declare blockers step</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="278"/> <location filename="../src/messagelogwidget.cpp" line="283"/>
<source>combat damage step</source> <source>combat damage step</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="279"/> <location filename="../src/messagelogwidget.cpp" line="284"/>
<source>end of combat step</source> <source>end of combat step</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="280"/> <location filename="../src/messagelogwidget.cpp" line="285"/>
<source>second main phase</source> <source>second main phase</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="283"/> <location filename="../src/messagelogwidget.cpp" line="288"/>
<source>It is now the %1.</source> <source>It is now the %1.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="228"/> <location filename="../src/messagelogwidget.cpp" line="233"/>
<source>taps</source> <source>taps</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="228"/> <location filename="../src/messagelogwidget.cpp" line="233"/>
<source>untaps</source> <source>untaps</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="240"/> <location filename="../src/messagelogwidget.cpp" line="245"/>
<source>%1 sets %2 to not untap normally.</source> <source>%1 sets %2 to not untap normally.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="242"/> <location filename="../src/messagelogwidget.cpp" line="247"/>
<source>%1 sets %2 to untap normally.</source> <source>%1 sets %2 to untap normally.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/messagelogwidget.cpp" line="225"/> <location filename="../src/messagelogwidget.cpp" line="230"/>
<source>his permanents</source> <source>his permanents</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -1713,107 +1732,107 @@ Please enter a name:</source>
<context> <context>
<name>TabGame</name> <name>TabGame</name>
<message> <message>
<location filename="../src/tab_game.cpp" line="130"/> <location filename="../src/tab_game.cpp" line="132"/>
<source>&amp;Game</source> <source>&amp;Game</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="131"/> <location filename="../src/tab_game.cpp" line="133"/>
<source>Next &amp;phase</source> <source>Next &amp;phase</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="132"/> <location filename="../src/tab_game.cpp" line="134"/>
<source>Ctrl+Space</source> <source>Ctrl+Space</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="133"/> <location filename="../src/tab_game.cpp" line="135"/>
<source>Next &amp;turn</source> <source>Next &amp;turn</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="134"/> <location filename="../src/tab_game.cpp" line="136"/>
<source>Ctrl+Return</source> <source>Ctrl+Return</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="134"/> <location filename="../src/tab_game.cpp" line="136"/>
<source>Ctrl+Enter</source> <source>Ctrl+Enter</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="135"/> <location filename="../src/tab_game.cpp" line="137"/>
<source>&amp;Remove all local arrows</source> <source>&amp;Remove all local arrows</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="136"/> <location filename="../src/tab_game.cpp" line="138"/>
<source>Ctrl+R</source> <source>Ctrl+R</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="137"/> <location filename="../src/tab_game.cpp" line="139"/>
<source>&amp;Concede</source> <source>&amp;Concede</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="138"/> <location filename="../src/tab_game.cpp" line="140"/>
<source>F2</source> <source>F2</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="139"/> <location filename="../src/tab_game.cpp" line="141"/>
<source>&amp;Leave game</source> <source>&amp;Leave game</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="141"/> <location filename="../src/tab_game.cpp" line="143"/>
<source>Load &amp;local deck</source> <source>Load &amp;local deck</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="142"/> <location filename="../src/tab_game.cpp" line="144"/>
<source>Load d&amp;eck from server</source> <source>Load d&amp;eck from server</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="143"/> <location filename="../src/tab_game.cpp" line="145"/>
<source>S&amp;tart game</source> <source>S&amp;tart game</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="144"/> <location filename="../src/tab_game.cpp" line="146"/>
<source>&amp;Say:</source> <source>&amp;Say:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="156"/> <location filename="../src/tab_game.cpp" line="158"/>
<source>Concede</source> <source>Concede</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="156"/> <location filename="../src/tab_game.cpp" line="158"/>
<source>Are you sure you want to concede this game?</source> <source>Are you sure you want to concede this game?</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="164"/> <location filename="../src/tab_game.cpp" line="166"/>
<source>Leave game</source> <source>Leave game</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="164"/> <location filename="../src/tab_game.cpp" line="166"/>
<source>Are you sure you want to leave this game?</source> <source>Are you sure you want to leave this game?</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.cpp" line="435"/> <location filename="../src/tab_game.cpp" line="450"/>
<source>Load deck</source> <source>Load deck</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../src/tab_game.h" line="108"/> <location filename="../src/tab_game.h" line="111"/>
<source>Game %1: %2</source> <source>Game %1: %2</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>

View file

@ -104,7 +104,7 @@ void Command::processResponse(ProtocolResponse *response)
} }
CommandContainer::CommandContainer(const QList<Command *> &_commandList, int _cmdId) CommandContainer::CommandContainer(const QList<Command *> &_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) if (_cmdId == -1)
_cmdId = lastCmdId++; _cmdId = lastCmdId++;
@ -137,6 +137,13 @@ void CommandContainer::enqueueGameEventPublic(GameEvent *event, int gameId)
gameEventQueuePublic->appendItem(event); gameEventQueuePublic->appendItem(event);
} }
void CommandContainer::enqueueGameEventOmniscient(GameEvent *event, int gameId)
{
if (!gameEventQueueOmniscient)
gameEventQueueOmniscient = new GameEventContainer(QList<GameEvent *>(), gameId);
gameEventQueueOmniscient->appendItem(event);
}
void CommandContainer::enqueueGameEventPrivate(GameEvent *event, int gameId) void CommandContainer::enqueueGameEventPrivate(GameEvent *event, int gameId)
{ {
if (!gameEventQueuePrivate) if (!gameEventQueuePrivate)

View file

@ -103,6 +103,7 @@ private:
ProtocolResponse *resp; ProtocolResponse *resp;
QList<ProtocolItem *> itemQueue; QList<ProtocolItem *> itemQueue;
GameEventContainer *gameEventQueuePublic; GameEventContainer *gameEventQueuePublic;
GameEventContainer *gameEventQueueOmniscient;
GameEventContainer *gameEventQueuePrivate; GameEventContainer *gameEventQueuePrivate;
public: public:
CommandContainer(const QList<Command *> &_commandList = QList<Command *>(), int _cmdId = -1); CommandContainer(const QList<Command *> &_commandList = QList<Command *>(), int _cmdId = -1);
@ -119,6 +120,8 @@ public:
void enqueueItem(ProtocolItem *item) { itemQueue.append(item); } void enqueueItem(ProtocolItem *item) { itemQueue.append(item); }
GameEventContainer *getGameEventQueuePublic() const { return gameEventQueuePublic; } GameEventContainer *getGameEventQueuePublic() const { return gameEventQueuePublic; }
void enqueueGameEventPublic(GameEvent *event, int gameId); void enqueueGameEventPublic(GameEvent *event, int gameId);
GameEventContainer *getGameEventQueueOmniscient() const { return gameEventQueueOmniscient; }
void enqueueGameEventOmniscient(GameEvent *event, int gameId);
GameEventContainer *getGameEventQueuePrivate() const { return gameEventQueuePrivate; } GameEventContainer *getGameEventQueuePrivate() const { return gameEventQueuePrivate; }
void enqueueGameEventPrivate(GameEvent *event, int gameId); void enqueueGameEventPrivate(GameEvent *event, int gameId);
}; };

View file

@ -18,7 +18,7 @@ ServerInfo_ChatUser::ServerInfo_ChatUser(const QString &_name)
insertItem(new SerializableItem_String("name", _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") : SerializableItem_Map("game")
{ {
insertItem(new SerializableItem_Int("game_id", _gameId)); 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_Int("max_players", _maxPlayers));
insertItem(new SerializableItem_String("creator_name", _creatorName)); insertItem(new SerializableItem_String("creator_name", _creatorName));
insertItem(new SerializableItem_Bool("spectators_allowed", _spectatorsAllowed)); insertItem(new SerializableItem_Bool("spectators_allowed", _spectatorsAllowed));
insertItem(new SerializableItem_Bool("spectators_need_password", _spectatorsNeedPassword));
insertItem(new SerializableItem_Int("spectator_count", _spectatorCount)); insertItem(new SerializableItem_Int("spectator_count", _spectatorCount));
} }

View file

@ -39,7 +39,7 @@ public:
class ServerInfo_Game : public SerializableItem_Map { class ServerInfo_Game : public SerializableItem_Map {
public: 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; } static SerializableItem *newItem() { return new ServerInfo_Game; }
int getGameId() const { return static_cast<SerializableItem_Int *>(itemMap.value("game_id"))->getData(); } int getGameId() const { return static_cast<SerializableItem_Int *>(itemMap.value("game_id"))->getData(); }
QString getDescription() const { return static_cast<SerializableItem_String *>(itemMap.value("description"))->getData(); } QString getDescription() const { return static_cast<SerializableItem_String *>(itemMap.value("description"))->getData(); }
@ -48,6 +48,7 @@ public:
int getMaxPlayers() const { return static_cast<SerializableItem_Int *>(itemMap.value("max_players"))->getData(); } int getMaxPlayers() const { return static_cast<SerializableItem_Int *>(itemMap.value("max_players"))->getData(); }
QString getCreatorName() const { return static_cast<SerializableItem_String *>(itemMap.value("creator_name"))->getData(); } QString getCreatorName() const { return static_cast<SerializableItem_String *>(itemMap.value("creator_name"))->getData(); }
bool getSpectatorsAllowed() const { return static_cast<SerializableItem_Bool *>(itemMap.value("spectators_allowed"))->getData(); } bool getSpectatorsAllowed() const { return static_cast<SerializableItem_Bool *>(itemMap.value("spectators_allowed"))->getData(); }
bool getSpectatorsNeedPassword() const { return static_cast<SerializableItem_Bool *>(itemMap.value("spectators_need_password"))->getData(); }
int getSpectatorCount() const { return static_cast<SerializableItem_Int *>(itemMap.value("spectator_count"))->getData(); } int getSpectatorCount() const { return static_cast<SerializableItem_Int *>(itemMap.value("spectator_count"))->getData(); }
}; };

View file

@ -58,13 +58,16 @@ Command_ListGames::Command_ListGames()
: Command("list_games") : 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") : Command("create_game")
{ {
insertItem(new SerializableItem_String("description", _description)); insertItem(new SerializableItem_String("description", _description));
insertItem(new SerializableItem_String("password", _password)); insertItem(new SerializableItem_String("password", _password));
insertItem(new SerializableItem_Int("max_players", _maxPlayers)); insertItem(new SerializableItem_Int("max_players", _maxPlayers));
insertItem(new SerializableItem_Bool("spectators_allowed", _spectatorsAllowed)); 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_JoinGame::Command_JoinGame(int _gameId, const QString &_password, bool _spectator)
: Command("join_game") : Command("join_game")
@ -297,13 +300,15 @@ Event_ServerMessage::Event_ServerMessage(const QString &_message)
{ {
insertItem(new SerializableItem_String("message", _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") : GenericEvent("game_joined")
{ {
insertItem(new SerializableItem_Int("game_id", _gameId)); insertItem(new SerializableItem_Int("game_id", _gameId));
insertItem(new SerializableItem_String("game_description", _gameDescription)); insertItem(new SerializableItem_String("game_description", _gameDescription));
insertItem(new SerializableItem_Int("player_id", _playerId)); insertItem(new SerializableItem_Int("player_id", _playerId));
insertItem(new SerializableItem_Bool("spectator", _spectator)); 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)); insertItem(new SerializableItem_Bool("resuming", _resuming));
} }
Event_ChatJoinChannel::Event_ChatJoinChannel(const QString &_channel, const QString &_playerName) Event_ChatJoinChannel::Event_ChatJoinChannel(const QString &_channel, const QString &_playerName)

View file

@ -10,7 +10,7 @@
1:chat_leave_channel 1:chat_leave_channel
1:chat_say:s,message 1:chat_say:s,message
0:list_games 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 0:join_game:i,game_id:s,password:b,spectator
2:leave_game 2:leave_game
2:say:s,message 2:say:s,message
@ -49,7 +49,7 @@
3:dump_zone:i,zone_owner_id:s,zone:i,number_cards 3:dump_zone:i,zone_owner_id:s,zone:i,number_cards
3:stop_dump_zone:i,zone_owner_id:s,zone 3:stop_dump_zone:i,zone_owner_id:s,zone
4:server_message:s,message 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_join_channel:s,player_name
5:chat_leave_channel:s,player_name 5:chat_leave_channel:s,player_name
5:chat_say:s,player_name:s,message 5:chat_say:s,player_name:s,message

View file

@ -99,11 +99,14 @@ public:
class Command_CreateGame : public Command { class Command_CreateGame : public Command {
Q_OBJECT Q_OBJECT
public: 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<SerializableItem_String *>(itemMap.value("description"))->getData(); }; QString getDescription() const { return static_cast<SerializableItem_String *>(itemMap.value("description"))->getData(); };
QString getPassword() const { return static_cast<SerializableItem_String *>(itemMap.value("password"))->getData(); }; QString getPassword() const { return static_cast<SerializableItem_String *>(itemMap.value("password"))->getData(); };
int getMaxPlayers() const { return static_cast<SerializableItem_Int *>(itemMap.value("max_players"))->getData(); }; int getMaxPlayers() const { return static_cast<SerializableItem_Int *>(itemMap.value("max_players"))->getData(); };
bool getSpectatorsAllowed() const { return static_cast<SerializableItem_Bool *>(itemMap.value("spectators_allowed"))->getData(); }; bool getSpectatorsAllowed() const { return static_cast<SerializableItem_Bool *>(itemMap.value("spectators_allowed"))->getData(); };
bool getSpectatorsNeedPassword() const { return static_cast<SerializableItem_Bool *>(itemMap.value("spectators_need_password"))->getData(); };
bool getSpectatorsCanTalk() const { return static_cast<SerializableItem_Bool *>(itemMap.value("spectators_can_talk"))->getData(); };
bool getSpectatorsSeeEverything() const { return static_cast<SerializableItem_Bool *>(itemMap.value("spectators_see_everything"))->getData(); };
static SerializableItem *newItem() { return new Command_CreateGame; } static SerializableItem *newItem() { return new Command_CreateGame; }
int getItemId() const { return ItemId_Command_CreateGame; } int getItemId() const { return ItemId_Command_CreateGame; }
}; };
@ -455,11 +458,13 @@ public:
class Event_GameJoined : public GenericEvent { class Event_GameJoined : public GenericEvent {
Q_OBJECT Q_OBJECT
public: 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<SerializableItem_Int *>(itemMap.value("game_id"))->getData(); }; int getGameId() const { return static_cast<SerializableItem_Int *>(itemMap.value("game_id"))->getData(); };
QString getGameDescription() const { return static_cast<SerializableItem_String *>(itemMap.value("game_description"))->getData(); }; QString getGameDescription() const { return static_cast<SerializableItem_String *>(itemMap.value("game_description"))->getData(); };
int getPlayerId() const { return static_cast<SerializableItem_Int *>(itemMap.value("player_id"))->getData(); }; int getPlayerId() const { return static_cast<SerializableItem_Int *>(itemMap.value("player_id"))->getData(); };
bool getSpectator() const { return static_cast<SerializableItem_Bool *>(itemMap.value("spectator"))->getData(); }; bool getSpectator() const { return static_cast<SerializableItem_Bool *>(itemMap.value("spectator"))->getData(); };
bool getSpectatorsCanTalk() const { return static_cast<SerializableItem_Bool *>(itemMap.value("spectators_can_talk"))->getData(); };
bool getSpectatorsSeeEverything() const { return static_cast<SerializableItem_Bool *>(itemMap.value("spectators_see_everything"))->getData(); };
bool getResuming() const { return static_cast<SerializableItem_Bool *>(itemMap.value("resuming"))->getData(); }; bool getResuming() const { return static_cast<SerializableItem_Bool *>(itemMap.value("resuming"))->getData(); };
static SerializableItem *newItem() { return new Event_GameJoined; } static SerializableItem *newItem() { return new Event_GameJoined; }
int getItemId() const { return ItemId_Event_GameJoined; } int getItemId() const { return ItemId_Event_GameJoined; }

View file

@ -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); games.insert(newGame->getGameId(), newGame);
connect(newGame, SIGNAL(gameClosing()), this, SLOT(gameClosing())); connect(newGame, SIGNAL(gameClosing()), this, SLOT(gameClosing()));
@ -84,6 +84,7 @@ void Server::broadcastGameListUpdate(Server_Game *game)
game->getMaxPlayers(), game->getMaxPlayers(),
game->getCreatorName(), game->getCreatorName(),
game->getSpectatorsAllowed(), game->getSpectatorsAllowed(),
game->getSpectatorsNeedPassword(),
game->getSpectatorCount() game->getSpectatorCount()
)); ));
else else

View file

@ -30,7 +30,7 @@ public:
void removeClient(Server_ProtocolHandler *player); void removeClient(Server_ProtocolHandler *player);
void closeOldSession(const QString &playerName); void closeOldSession(const QString &playerName);
virtual QString getLoginMessage() const = 0; 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 getMaxGameInactivityTime() const = 0;
virtual int getMaxPlayerInactivityTime() const = 0; virtual int getMaxPlayerInactivityTime() const = 0;

View file

@ -27,8 +27,8 @@
#include <QSqlQuery> #include <QSqlQuery>
#include <QTimer> #include <QTimer>
Server_Game::Server_Game(Server_ProtocolHandler *_creator, int _gameId, const QString &_description, const QString &_password, int _maxPlayers, bool _spectatorsAllowed, QObject *parent) 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), inactivityCounter(0) : 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); creator = addPlayer(_creator, false, false);
@ -168,7 +168,7 @@ void Server_Game::stopGameIfFinished()
ResponseCode Server_Game::checkJoin(const QString &_password, bool spectator) ResponseCode Server_Game::checkJoin(const QString &_password, bool spectator)
{ {
if (_password != password) if ((_password != password) && !(spectator && !spectatorsNeedPassword))
return RespWrongPassword; return RespWrongPassword;
if (spectator) { if (spectator) {
if (!spectatorsAllowed) if (!spectatorsAllowed)
@ -292,13 +292,26 @@ void Server_Game::sendGameEvent(GameEvent *event, GameEventContext *context, Ser
sendGameEventContainer(new GameEventContainer(QList<GameEvent *>() << event, -1, context), exclude); sendGameEventContainer(new GameEventContainer(QList<GameEvent *>() << 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); cont->setGameId(gameId);
QMapIterator<int, Server_Player *> playerIterator(players); QMapIterator<int, Server_Player *> playerIterator(players);
while (playerIterator.hasNext()) { while (playerIterator.hasNext()) {
Server_Player *p = playerIterator.next().value(); 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<int, Server_Player *> playerIterator(players);
while (playerIterator.hasNext()) {
Server_Player *p = playerIterator.next().value();
if ((p != exclude) && (p->getSpectator() && spectatorsSeeEverything))
p->sendProtocolItem(cont, false); p->sendProtocolItem(cont, false);
} }

View file

@ -40,6 +40,9 @@ private:
int maxPlayers; int maxPlayers;
int activePlayer, activePhase; int activePlayer, activePhase;
bool spectatorsAllowed; bool spectatorsAllowed;
bool spectatorsNeedPassword;
bool spectatorsCanTalk;
bool spectatorsSeeEverything;
int inactivityCounter; int inactivityCounter;
QTimer *pingClock; QTimer *pingClock;
signals: signals:
@ -47,7 +50,7 @@ signals:
private slots: private slots:
void pingClockTimeout(); void pingClockTimeout();
public: 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_Game();
Server_Player *getCreator() const { return creator; } Server_Player *getCreator() const { return creator; }
QString getCreatorName() const { return creator ? creator->getPlayerName() : QString(); } QString getCreatorName() const { return creator ? creator->getPlayerName() : QString(); }
@ -61,6 +64,9 @@ public:
QString getPassword() const { return password; } QString getPassword() const { return password; }
int getMaxPlayers() const { return maxPlayers; } int getMaxPlayers() const { return maxPlayers; }
bool getSpectatorsAllowed() const { return spectatorsAllowed; } 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); ResponseCode checkJoin(const QString &_password, bool spectator);
Server_Player *addPlayer(Server_ProtocolHandler *handler, bool spectator, bool broadcastUpdate = true); Server_Player *addPlayer(Server_ProtocolHandler *handler, bool spectator, bool broadcastUpdate = true);
void removePlayer(Server_Player *player); void removePlayer(Server_Player *player);
@ -73,7 +79,8 @@ public:
QList<ServerInfo_Player *> getGameState(Server_Player *playerWhosAsking) const; QList<ServerInfo_Player *> getGameState(Server_Player *playerWhosAsking) const;
void sendGameEvent(GameEvent *event, GameEventContext *context = 0, Server_Player *exclude = 0); 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); void sendGameEventToPlayer(Server_Player *player, GameEvent *event);
}; };

View file

@ -148,8 +148,13 @@ void Server_ProtocolHandler::processCommandContainer(CommandContainer *cont)
Server_Game *game = games.value(gQPublic->getGameId()).first; Server_Game *game = games.value(gQPublic->getGameId()).first;
Server_Player *player = games.value(gQPublic->getGameId()).second; Server_Player *player = games.value(gQPublic->getGameId()).second;
GameEventContainer *gQPrivate = cont->getGameEventQueuePrivate(); GameEventContainer *gQPrivate = cont->getGameEventQueuePrivate();
GameEventContainer *gQOmniscient = cont->getGameEventQueueOmniscient();
if (gQPrivate) { 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); player->sendProtocolItem(gQPrivate);
} else } else
game->sendGameEventContainer(gQPublic); game->sendGameEventContainer(gQPublic);
@ -214,7 +219,7 @@ ResponseCode Server_ProtocolHandler::cmdLogin(Command_Login *cmd, CommandContain
gamePlayers[j]->setProtocolHandler(this); gamePlayers[j]->setProtocolHandler(this);
games.insert(serverGames[i]->getGameId(), QPair<Server_Game *, Server_Player *>(serverGames[i], gamePlayers[j])); games.insert(serverGames[i]->getGameId(), QPair<Server_Game *, Server_Player *>(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())); 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->getMaxPlayers(),
g->getCreatorName(), g->getCreatorName(),
g->getSpectatorsAllowed(), g->getSpectatorsAllowed(),
g->getSpectatorsNeedPassword(),
g->getSpectatorCount() g->getSpectatorCount()
)); ));
} }
@ -296,11 +302,11 @@ ResponseCode Server_ProtocolHandler::cmdListGames(Command_ListGames * /*cmd*/, C
ResponseCode Server_ProtocolHandler::cmdCreateGame(Command_CreateGame *cmd, CommandContainer *cont) 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(); Server_Player *creator = game->getCreator();
games.insert(game->getGameId(), QPair<Server_Game *, Server_Player *>(game, creator)); games.insert(game->getGameId(), QPair<Server_Game *, Server_Player *>(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())); enqueueProtocolItem(GameEventContainer::makeNew(new Event_GameStateChanged(game->getGameStarted(), game->getActivePlayer(), game->getActivePhase(), game->getGameState(creator)), game->getGameId()));
return RespOk; return RespOk;
} }
@ -318,7 +324,7 @@ ResponseCode Server_ProtocolHandler::cmdJoinGame(Command_JoinGame *cmd, CommandC
if (result == RespOk) { if (result == RespOk) {
Server_Player *player = g->addPlayer(this, cmd->getSpectator()); Server_Player *player = g->addPlayer(this, cmd->getSpectator());
games.insert(cmd->getGameId(), QPair<Server_Game *, Server_Player *>(g, player)); games.insert(cmd->getGameId(), QPair<Server_Game *, Server_Player *>(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())); enqueueProtocolItem(GameEventContainer::makeNew(new Event_GameStateChanged(g->getGameStarted(), g->getActivePlayer(), g->getActivePhase(), g->getGameState(player)), cmd->getGameId()));
} }
return result; 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) ResponseCode Server_ProtocolHandler::cmdDeckSelect(Command_DeckSelect *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player)
{ {
if (player->getSpectator())
return RespFunctionNotAllowed;
DeckList *deck; DeckList *deck;
if (cmd->getDeckId() == -1) { if (cmd->getDeckId() == -1) {
if (!cmd->getDeck()) 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) ResponseCode Server_ProtocolHandler::cmdSetSideboardPlan(Command_SetSideboardPlan *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player)
{ {
if (player->getSpectator())
return RespFunctionNotAllowed;
DeckList *deck = player->getDeck(); DeckList *deck = player->getDeck();
if (!deck) if (!deck)
return RespContextError; 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) ResponseCode Server_ProtocolHandler::cmdConcede(Command_Concede * /*cmd*/, CommandContainer *cont, Server_Game *game, Server_Player *player)
{ {
if (player->getSpectator())
return RespFunctionNotAllowed;
player->setConceded(true); player->setConceded(true);
game->sendGameEvent(new Event_PlayerPropertiesChanged(player->getProperties()), new Context_Concede); game->sendGameEvent(new Event_PlayerPropertiesChanged(player->getProperties()), new Context_Concede);
game->stopGameIfFinished(); 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) ResponseCode Server_ProtocolHandler::cmdReadyStart(Command_ReadyStart * /*cmd*/, CommandContainer *cont, Server_Game *game, Server_Player *player)
{ {
if (player->getSpectator())
return RespFunctionNotAllowed;
if (!player->getDeck()) if (!player->getDeck())
return RespContextError; 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) 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())); game->sendGameEvent(new Event_Say(player->getPlayerId(), cmd->getMessage()));
return RespOk; return RespOk;
} }
ResponseCode Server_ProtocolHandler::cmdShuffle(Command_Shuffle * /*cmd*/, CommandContainer *cont, Server_Game *game, Server_Player *player) ResponseCode Server_ProtocolHandler::cmdShuffle(Command_Shuffle * /*cmd*/, CommandContainer *cont, Server_Game *game, Server_Player *player)
{ {
if (player->getSpectator())
return RespFunctionNotAllowed;
if (!game->getGameStarted()) if (!game->getGameStarted())
return RespGameNotStarted; 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) ResponseCode Server_ProtocolHandler::cmdMulligan(Command_Mulligan * /*cmd*/, CommandContainer *cont, Server_Game *game, Server_Player *player)
{ {
if (player->getSpectator())
return RespFunctionNotAllowed;
if (!game->getGameStarted()) if (!game->getGameStarted())
return RespGameNotStarted; 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) 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()))); game->sendGameEvent(new Event_RollDie(player->getPlayerId(), cmd->getSides(), rng->getNumber(1, cmd->getSides())));
return RespOk; return RespOk;
} }
ResponseCode Server_ProtocolHandler::drawCards(Server_Game *game, Server_Player *player, CommandContainer *cont, int number) ResponseCode Server_ProtocolHandler::drawCards(Server_Game *game, Server_Player *player, CommandContainer *cont, int number)
{ {
if (player->getSpectator())
return RespFunctionNotAllowed;
if (!game->getGameStarted()) if (!game->getGameStarted())
return RespGameNotStarted; return RespGameNotStarted;
@ -436,15 +469,18 @@ ResponseCode Server_ProtocolHandler::drawCards(Server_Game *game, Server_Player
if (deck->cards.size() < number) if (deck->cards.size() < number)
number = deck->cards.size(); number = deck->cards.size();
QList<ServerInfo_Card *> cardList; QList<ServerInfo_Card *> cardListPrivate;
QList<ServerInfo_Card *> cardListOmniscient;
for (int i = 0; i < number; ++i) { for (int i = 0; i < number; ++i) {
Server_Card *card = deck->cards.takeFirst(); Server_Card *card = deck->cards.takeFirst();
hand->cards.append(card); 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->enqueueGameEventPrivate(new Event_DrawCards(player->getPlayerId(), cardListPrivate.size(), cardListPrivate), game->getGameId());
cont->enqueueGameEventPublic(new Event_DrawCards(player->getPlayerId(), cardList.size()), 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; 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) 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()) if (!game->getGameStarted())
return RespGameNotStarted; return RespGameNotStarted;
@ -508,6 +547,7 @@ ResponseCode Server_ProtocolHandler::moveCard(Server_Game *game, Server_Player *
if (startzone->getType() == HiddenZone) if (startzone->getType() == HiddenZone)
privatePosition = position; privatePosition = position;
cont->enqueueGameEventPrivate(new Event_MoveCard(player->getPlayerId(), privateOldCardId, privateCardName, startzone->getName(), privatePosition, targetzone->getName(), x, y, privateNewCardId, faceDown), game->getGameId()); 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 // 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, // 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) ResponseCode Server_ProtocolHandler::cmdCreateToken(Command_CreateToken *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player)
{ {
if (player->getSpectator())
return RespFunctionNotAllowed;
if (!game->getGameStarted()) if (!game->getGameStarted())
return RespGameNotStarted; 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) ResponseCode Server_ProtocolHandler::cmdCreateArrow(Command_CreateArrow *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player)
{ {
if (player->getSpectator())
return RespFunctionNotAllowed;
if (!game->getGameStarted()) if (!game->getGameStarted())
return RespGameNotStarted; 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) ResponseCode Server_ProtocolHandler::cmdDeleteArrow(Command_DeleteArrow *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player)
{ {
if (player->getSpectator())
return RespFunctionNotAllowed;
if (!game->getGameStarted()) if (!game->getGameStarted())
return RespGameNotStarted; 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) 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()) if (!game->getGameStarted())
return RespGameNotStarted; 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) ResponseCode Server_ProtocolHandler::cmdIncCounter(Command_IncCounter *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player)
{ {
if (player->getSpectator())
return RespFunctionNotAllowed;
if (!game->getGameStarted()) if (!game->getGameStarted())
return RespGameNotStarted; 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) ResponseCode Server_ProtocolHandler::cmdCreateCounter(Command_CreateCounter *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player)
{ {
if (player->getSpectator())
return RespFunctionNotAllowed;
if (!game->getGameStarted()) if (!game->getGameStarted())
return RespGameNotStarted; 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) ResponseCode Server_ProtocolHandler::cmdSetCounter(Command_SetCounter *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player)
{ {
if (player->getSpectator())
return RespFunctionNotAllowed;
if (!game->getGameStarted()) if (!game->getGameStarted())
return RespGameNotStarted; 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) ResponseCode Server_ProtocolHandler::cmdDelCounter(Command_DelCounter *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player)
{ {
if (player->getSpectator())
return RespFunctionNotAllowed;
if (!game->getGameStarted()) if (!game->getGameStarted())
return RespGameNotStarted; return RespGameNotStarted;
@ -705,8 +769,11 @@ ResponseCode Server_ProtocolHandler::cmdDelCounter(Command_DelCounter *cmd, Comm
return RespOk; 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()) if (!game->getGameStarted())
return RespGameNotStarted; 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) ResponseCode Server_ProtocolHandler::cmdSetActivePhase(Command_SetActivePhase *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player)
{ {
if (player->getSpectator())
return RespFunctionNotAllowed;
if (!game->getGameStarted()) if (!game->getGameStarted())
return RespGameNotStarted; return RespGameNotStarted;