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

final (?) spectator code, small bugfix

parent fa16d862
......@@ -248,7 +248,7 @@ void CardItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
if (zone->getName() == "table")
((TableZone *) zone)->toggleTapped();
else {
TableZone *table = (TableZone *) zone->getPlayer()->getZones()->findZone("table");
TableZone *table = (TableZone *) zone->getPlayer()->getZones().findZone("table");
QPoint gridPoint = table->getFreeGridPoint(info->getTableRow());
table->handleDropEventByGrid(id, zone, gridPoint, false);
}
......
......@@ -11,9 +11,9 @@ ServerEventData::ServerEventData(const QString &line)
if (eventHash.isEmpty()) {
eventHash.insert("player_id", eventPlayerId);
eventHash.insert("say", eventSay);
eventHash.insert("name", eventName);
eventHash.insert("join", eventJoin);
eventHash.insert("leave", eventLeave);
eventHash.insert("game_closed", eventGameClosed);
eventHash.insert("ready_start", eventReadyStart);
eventHash.insert("setup_zones", eventSetupZones);
eventHash.insert("game_start", eventGameStart);
......@@ -35,7 +35,10 @@ ServerEventData::ServerEventData(const QString &line)
QStringList values = line.split('|');
IsPublic = !values.takeFirst().compare("public");
PlayerId = values.takeFirst().toInt();
bool ok = false;
PlayerId = values.takeFirst().toInt(&ok);
if (!ok)
PlayerId = -1;
PlayerName = values.takeFirst();
EventType = eventHash.value(values.takeFirst(), eventInvalid);
EventData = values;
......@@ -84,11 +87,6 @@ void PendingCommand_ListPlayers::responseReceived(ServerResponse resp)
PendingCommand::responseReceived(resp);
}
void PendingCommand_ListPlayers::addPlayer(const ServerPlayer &player)
{
playerList.append(player);
}
void PendingCommand_ListZones::responseReceived(ServerResponse resp)
{
if (resp == RespOk)
......@@ -96,11 +94,6 @@ void PendingCommand_ListZones::responseReceived(ServerResponse resp)
PendingCommand::responseReceived(resp);
}
void PendingCommand_ListZones::addZone(const ServerZone &zone)
{
zoneList.append(zone);
}
void PendingCommand_DumpZone::responseReceived(ServerResponse resp)
{
if (resp == RespOk)
......@@ -108,11 +101,6 @@ void PendingCommand_DumpZone::responseReceived(ServerResponse resp)
PendingCommand::responseReceived(resp);
}
void PendingCommand_DumpZone::addCard(const ServerZoneCard &card)
{
cardList.append(card);
}
void PendingCommand_ListCounters::responseReceived(ServerResponse resp)
{
if (resp == RespOk)
......@@ -120,9 +108,15 @@ void PendingCommand_ListCounters::responseReceived(ServerResponse resp)
PendingCommand::responseReceived(resp);
}
void PendingCommand_ListCounters::addCounter(const ServerCounter &counter)
void PendingCommand_DumpAll::responseReceived(ServerResponse resp)
{
counterList.append(counter);
if (resp == RespOk) {
emit playerListReceived(playerList);
emit zoneListReceived(zoneList);
emit cardListReceived(cardList);
emit counterListReceived(counterList);
}
PendingCommand::responseReceived(resp);
}
Client::Client(QObject *parent)
......@@ -238,9 +232,11 @@ void Client::readLine()
resp = RespErr;
pc->responseReceived(resp);
} else if (prefix == "list_games") {
if (values.size() != 8)
if (values.size() != 8) {
emit protocolError();
continue;
emit gameListEvent(new ServerGame(values[0].toInt(), values[5], values[1], values[2].toInt(), values[3].toInt(), values[4].toInt(), values[6].toInt(), values[7].toInt()));
}
emit gameListEvent(ServerGame(values[0].toInt(), values[5], values[1], values[2].toInt(), values[3].toInt(), values[4].toInt(), values[6].toInt(), values[7].toInt()));
} else if (prefix == "welcome") {
if (values.size() != 2) {
emit protocolError();
......@@ -259,37 +255,84 @@ void Client::readLine()
continue;
}
int cmdid = values.takeFirst().toInt();
PendingCommand_ListPlayers *pc = qobject_cast<PendingCommand_ListPlayers *>(pendingCommands.value(cmdid, 0));
if (!pc) {
emit protocolError();
continue;
PendingCommand *pc = pendingCommands.value(cmdid, 0);
ServerPlayer sp(values[0].toInt(), values[1], values[2].toInt());
PendingCommand_ListPlayers *pcLP = qobject_cast<PendingCommand_ListPlayers *>(pc);
if (pcLP)
pcLP->addPlayer(sp);
else {
PendingCommand_DumpAll *pcDA = qobject_cast<PendingCommand_DumpAll *>(pc);
if (pcDA)
pcDA->addPlayer(sp);
else
emit protocolError();
}
pc->addPlayer(ServerPlayer(values[0].toInt(), values[1], values[2].toInt()));
} else if (prefix == "dump_zone") {
if (values.size() != 9) {
if (values.size() != 11) {
emit protocolError();
continue;
}
int cmdid = values.takeFirst().toInt();
PendingCommand_DumpZone *pc = qobject_cast<PendingCommand_DumpZone *>(pendingCommands.value(cmdid, 0));
if (!pc) {
emit protocolError();
continue;
PendingCommand *pc = pendingCommands.value(cmdid, 0);
ServerZoneCard szc(values[0].toInt(), values[1], values[2].toInt(), values[3], values[4].toInt(), values[5].toInt(), values[6].toInt(), values[7] == "1", values[8] == "1", values[9]);
PendingCommand_DumpZone *pcDZ = qobject_cast<PendingCommand_DumpZone *>(pc);
if (pcDZ)
pcDZ->addCard(szc);
else {
PendingCommand_DumpAll *pcDA = qobject_cast<PendingCommand_DumpAll *>(pc);
if (pcDA)
pcDA->addCard(szc);
else
emit protocolError();
}
pc->addCard(ServerZoneCard(values[0].toInt(), values[1], values[2].toInt(), values[3].toInt(), values[4].toInt(), values[5] == "1", values[6] == "1", values[7]));
} else if (prefix == "list_zones") {
if (values.size() != 5) {
if (values.size() != 6) {
emit protocolError();
continue;
}
int cmdid = values.takeFirst().toInt();
PendingCommand_ListZones *pc = qobject_cast<PendingCommand_ListZones *>(pendingCommands.value(cmdid, 0));
if (!pc) {
PendingCommand *pc = pendingCommands.value(cmdid, 0);
ServerZone::ZoneType type;
if (values[2] == "private")
type = ServerZone::PrivateZone;
else if (values[2] == "hidden")
type = ServerZone::HiddenZone;
else
type = ServerZone::PublicZone;
ServerZone sz(values[0].toInt(), values[1], type, values[3] == "1", values[4].toInt());
PendingCommand_ListZones *pcLZ = qobject_cast<PendingCommand_ListZones *>(pc);
if (pcLZ)
pcLZ->addZone(sz);
else {
PendingCommand_DumpAll *pcDA = qobject_cast<PendingCommand_DumpAll *>(pc);
if (pcDA)
pcDA->addZone(sz);
else
emit protocolError();
}
} else if (prefix == "list_counters") {
if (values.size() != 5) {
emit protocolError();
continue;
}
pc->addZone(ServerZone(values[0], values[1] == "1", values[2] == "1", values[3].toInt()));
} else if (prefix == "list_counters") {
int cmdid = values.takeFirst().toInt();
PendingCommand *pc = pendingCommands.value(cmdid, 0);
int colorValue = values[2].toInt();
ServerCounter sc(values[0].toInt(), values[1], QColor(colorValue / 65536, (colorValue % 65536) / 256, colorValue % 256), values[3].toInt());
PendingCommand_ListCounters *pcLC = qobject_cast<PendingCommand_ListCounters *>(pc);
if (pcLC)
pcLC->addCounter(sc);
else {
PendingCommand_DumpAll *pcDA = qobject_cast<PendingCommand_DumpAll *>(pc);
if (pcDA)
pcDA->addCounter(sc);
else
emit protocolError();
}
} else
emit protocolError();
}
......@@ -520,3 +563,10 @@ PendingCommand *Client::stopDumpZone(int player, const QString &zone)
{
return cmd(QString("stop_dump_zone|%1|%2").arg(player).arg(zone));
}
PendingCommand_DumpAll *Client::dumpAll()
{
PendingCommand_DumpAll *pc = new PendingCommand_DumpAll;
cmd("dump_all", pc);
return pc;
}
......@@ -28,9 +28,9 @@ enum ServerEventType {
eventInvalid,
eventPlayerId,
eventSay,
eventName,
eventJoin,
eventLeave,
eventGameClosed,
eventReadyStart,
eventSetupZones,
eventGameStart,
......@@ -100,7 +100,7 @@ private:
bool spectatorsAllowed;
unsigned int spectatorsCount;
public:
ServerGame(int _gameId, const QString &_creator, const QString &_description, bool _hasPassword, unsigned char _playerCount, unsigned char _maxPlayers, bool _spectatorsAllowed, unsigned int _spectatorsCount)
ServerGame(int _gameId = -1, const QString &_creator = QString(), const QString &_description = QString(), bool _hasPassword = false, unsigned char _playerCount = 0, unsigned char _maxPlayers = 0, bool _spectatorsAllowed = false, unsigned int _spectatorsCount = 0)
: gameId(_gameId), creator(_creator), description(_description), hasPassword(_hasPassword), playerCount(_playerCount), maxPlayers(_maxPlayers), spectatorsAllowed(_spectatorsAllowed), spectatorsCount(_spectatorsCount) { }
int getGameId() const { return gameId; }
QString getCreator() const { return creator; }
......@@ -127,6 +127,8 @@ public:
class ServerZoneCard {
private:
int playerId;
QString zoneName;
int id;
QString name;
int x, y;
......@@ -135,8 +137,10 @@ private:
bool attacking;
QString annotation;
public:
ServerZoneCard(int _id, const QString &_name, int _x, int _y, int _counters, bool _tapped, bool _attacking, const QString &_annotation)
: id(_id), name(_name), x(_x), y(_y), counters(_counters), tapped(_tapped), attacking(_attacking), annotation(_annotation) { }
ServerZoneCard(int _playerId, const QString &_zoneName, int _id, const QString &_name, int _x, int _y, int _counters, bool _tapped, bool _attacking, const QString &_annotation)
: playerId(_playerId), zoneName(_zoneName), id(_id), name(_name), x(_x), y(_y), counters(_counters), tapped(_tapped), attacking(_attacking), annotation(_annotation) { }
int getPlayerId() const { return playerId; }
QString getZoneName() const { return zoneName; }
int getId() const { return id; }
QString getName() const { return name; }
int getX() const { return x; }
......@@ -148,30 +152,36 @@ public:
};
class ServerZone {
public:
enum ZoneType { PrivateZone, PublicZone, HiddenZone };
private:
int playerId;
QString name;
bool isPublic;
ZoneType type;
bool hasCoords;
int cardCount;
public:
ServerZone(const QString &_name, bool _isPublic, bool _hasCoords, int _cardCount)
: name(_name), isPublic(_isPublic), hasCoords(_hasCoords), cardCount(_cardCount) { }
ServerZone(int _playerId, const QString &_name, ZoneType _type, bool _hasCoords, int _cardCount)
: playerId(_playerId), name(_name), type(_type), hasCoords(_hasCoords), cardCount(_cardCount) { }
int getPlayerId() const { return playerId; }
QString getName() const { return name; }
bool getPublic() const { return isPublic; }
ZoneType getType() const { return type; }
bool getHasCoords() const { return hasCoords; }
int getCardCount() const { return cardCount; }
};
class ServerCounter {
private:
int playerId;
QString name;
int color;
QColor color;
int count;
public:
ServerCounter(const QString &_name, int _color, int _count)
: name(_name), color(_color), count(_count) { }
ServerCounter(int _playerId, const QString &_name, QColor _color, int _count)
: playerId(_playerId), name(_name), color(_color), count(_count) { }
int getPlayerId() const { return playerId; }
QString getName() const { return name; }
int getColor() const { return color; }
QColor getColor() const { return color; }
int getCount() const { return count; }
};
......@@ -210,7 +220,7 @@ signals:
void playerListReceived(QList<ServerPlayer> _playerList);
public:
void responseReceived(ServerResponse resp);
void addPlayer(const ServerPlayer &player);
void addPlayer(const ServerPlayer &player) { playerList.append(player); }
};
class PendingCommand_ListZones : public PendingCommand {
......@@ -224,7 +234,7 @@ public:
PendingCommand_ListZones(int _playerId)
: playerId(_playerId) { }
void responseReceived(ServerResponse resp);
void addZone(const ServerZone &zone);
void addZone(const ServerZone &zone) { zoneList.append(zone); }
int getPlayerId() const { return playerId; }
};
......@@ -241,7 +251,7 @@ public:
PendingCommand_DumpZone(int _playerId, const QString &_zoneName, int _numberCards)
: playerId(_playerId), zoneName(_zoneName), numberCards(_numberCards) { }
void responseReceived(ServerResponse resp);
void addCard(const ServerZoneCard &card);
void addCard(const ServerZoneCard &card) { cardList.append(card); }
int getPlayerId() const { return playerId; }
QString getZoneName() const { return zoneName; }
int getNumberCards() const { return numberCards; }
......@@ -258,16 +268,36 @@ public:
PendingCommand_ListCounters(int _playerId)
: playerId(_playerId) { }
void responseReceived(ServerResponse resp);
void addCounter(const ServerCounter &counter);
void addCounter(const ServerCounter &counter) { counterList.append(counter); }
int getPlayerId() const { return playerId; }
};
class PendingCommand_DumpAll : public PendingCommand {
Q_OBJECT
private:
QList<ServerPlayer> playerList;
QList<ServerZone> zoneList;
QList<ServerZoneCard> cardList;
QList<ServerCounter> counterList;
signals:
void playerListReceived(QList<ServerPlayer> _playerList);
void zoneListReceived(QList<ServerZone> _zoneList);
void cardListReceived(QList<ServerZoneCard> _cardList);
void counterListReceived(QList<ServerCounter> _counterList);
public:
void responseReceived(ServerResponse resp);
void addPlayer(const ServerPlayer &player) { playerList.append(player); }
void addZone(const ServerZone &zone) { zoneList.append(zone); }
void addCard(const ServerZoneCard &card) { cardList.append(card); }
void addCounter(const ServerCounter &counter) { counterList.append(counter); }
};
class Client : public QObject {
Q_OBJECT
signals:
void statusChanged(ProtocolStatus _status);
void welcomeMsgReceived(QString welcomeMsg);
void gameListEvent(ServerGame *game);
void gameListEvent(const ServerGame &game);
void playerIdReceived(int id, QString name);
void gameEvent(const ServerEventData &msg);
void chatEvent(const ChatEventData &msg);
......@@ -335,6 +365,7 @@ public slots:
PendingCommand_ListZones *listZones(int playerId);
PendingCommand_DumpZone *dumpZone(int player, const QString &zone, int numberCards);
PendingCommand *stopDumpZone(int player, const QString &zone);
PendingCommand_DumpAll *dumpAll();
void submitDeck(const QStringList &deck);
};
......
......@@ -78,9 +78,6 @@ Game::Game(CardDatabase *_db, Client *_client, GameScene *_scene, QMenuBar *menu
connect(dlgStartGame, SIGNAL(finished(int)), this, SLOT(readyStart()));
retranslateUi();
PendingCommand_ListPlayers *pc = client->listPlayers();
connect(pc, SIGNAL(playerListReceived(QList<ServerPlayer>)), this, SLOT(playerListReceived(QList<ServerPlayer>)));
}
Game::~Game()
......@@ -141,6 +138,59 @@ Player *Game::addPlayer(int playerId, const QString &playerName, bool local)
return newPlayer;
}
void Game::cardListReceived(QList<ServerZoneCard> list)
{
for (int i = 0; i < list.size(); ++i) {
Player *p = players.findPlayer(list[i].getPlayerId());
if (!p)
continue;
CardZone *zone = p->getZones().findZone(list[i].getZoneName());
if (!zone)
continue;
CardItem *card = new CardItem(db, list[i].getName(), list[i].getId());
zone->addCard(card, false, list[i].getX(), list[i].getY());
card->setCounters(list[i].getCounters());
card->setTapped(list[i].getTapped());
card->setAttacking(list[i].getAttacking());
card->setAnnotation(list[i].getAnnotation());
}
}
void Game::zoneListReceived(QList<ServerZone> list)
{
for (int i = 0; i < list.size(); ++i) {
Player *p = players.findPlayer(list[i].getPlayerId());
if (!p)
continue;
CardZone *zone = p->getZones().findZone(list[i].getName());
if (!zone)
continue;
zone->clearContents();
if (
(list[i].getType() != ServerZone::PublicZone)
&& !((list[i].getType() == ServerZone::PrivateZone) && p->getLocal())
) {
for (int j = 0; j < list[i].getCardCount(); ++j)
zone->addCard(new CardItem(db), false, -1);
zone->reorganizeCards();
}
}
}
void Game::counterListReceived(QList<ServerCounter> list)
{
for (int i = 0; i < players.size(); ++i)
players[i]->clearCounters();
for (int i = 0; i < list.size(); ++i) {
Player *p = players.findPlayer(list[i].getPlayerId());
if (p)
p->addCounter(list[i].getName(), list[i].getColor(), list[i].getCount());
}
}
void Game::playerListReceived(QList<ServerPlayer> playerList)
{
QStringList nameList;
......@@ -171,8 +221,9 @@ void Game::gameEvent(const ServerEventData &msg)
return;
p->gameEvent(msg);
} else {
if ((!p) && (msg.getEventType() != eventJoin)) {
// XXX
if ((msg.getPlayerId() != -1) && (!p) && (msg.getEventType() != eventJoin) && (msg.getEventType() != eventLeave)) {
qDebug("Game::gameEvent: invalid player");
return;
}
switch(msg.getEventType()) {
......@@ -206,6 +257,11 @@ void Game::gameEvent(const ServerEventData &msg)
}
break;
}
case eventGameClosed: {
started = false;
emit logGameClosed();
break;
}
case eventReadyStart:
if (started) {
started = false;
......@@ -251,7 +307,6 @@ void Game::gameEvent(const ServerEventData &msg)
break;
}
case eventName:
case eventCreateToken:
case eventSetupZones:
case eventSetCardAttr:
......@@ -267,7 +322,7 @@ void Game::gameEvent(const ServerEventData &msg)
Player *zoneOwner = players.findPlayer(data[0].toInt());
if (!zoneOwner)
break;
CardZone *zone = zoneOwner->getZones()->findZone(data[1]);
CardZone *zone = zoneOwner->getZones().findZone(data[1]);
if (!zone)
break;
emit logDumpZone(p, zone, data[2].toInt());
......@@ -278,7 +333,7 @@ void Game::gameEvent(const ServerEventData &msg)
Player *zoneOwner = players.findPlayer(data[0].toInt());
if (!zoneOwner)
break;
CardZone *zone = zoneOwner->getZones()->findZone(data[1]);
CardZone *zone = zoneOwner->getZones().findZone(data[1]);
if (!zone)
break;
emit logStopDumpZone(p, zone);
......@@ -415,3 +470,12 @@ void Game::hoverCardEvent(CardItem *card)
{
emit hoverCard(card->getName());
}
void Game::queryGameState()
{
PendingCommand_DumpAll *pc = client->dumpAll();
connect(pc, SIGNAL(playerListReceived(QList<ServerPlayer>)), this, SLOT(playerListReceived(QList<ServerPlayer>)));
connect(pc, SIGNAL(zoneListReceived(QList<ServerZone>)), this, SLOT(zoneListReceived(QList<ServerZone>)));
connect(pc, SIGNAL(cardListReceived(QList<ServerZoneCard>)), this, SLOT(cardListReceived(QList<ServerZoneCard>)));
connect(pc, SIGNAL(counterListReceived(QList<ServerCounter>)), this, SLOT(counterListReceived(QList<ServerCounter>)));
}
......@@ -55,7 +55,12 @@ private slots:
void actMoveToExile(CardItem *card);
void gameEvent(const ServerEventData &msg);
void playerListReceived(QList<ServerPlayer> playerList);
void cardListReceived(QList<ServerZoneCard> list);
void zoneListReceived(QList<ServerZone> list);
void counterListReceived(QList<ServerCounter> list);
void readyStart();
signals:
void submitDecklist();
......@@ -67,6 +72,7 @@ signals:
void logPlayerListReceived(QStringList players);
void logJoin(Player *player);
void logLeave(Player *player);
void logGameClosed();
void logJoinSpectator(QString playerName);
void logLeaveSpectator(QString playerName);
void logReadyStart(Player *player);
......@@ -92,6 +98,7 @@ public:
void restartGameDialog();
void hoverCardEvent(CardItem *card);
Player *addPlayer(int playerId, const QString &playerName, bool local);
void queryGameState();
};
#endif
#include <QtGui>
#include "gameselector.h"
#include "dlg_creategame.h"
#include "gamesmodel.h"
GameSelector::GameSelector(Client *_client, QWidget *parent)
: QWidget(parent), client(_client)
{
gameListView = new QTreeView;
gameListModel = new GamesModel(this);
gameListView->setModel(gameListModel);
gameListProxyModel = new GamesProxyModel(this);
gameListProxyModel->setSourceModel(gameListModel);
gameListView->setModel(gameListProxyModel);
showFullGamesCheckBox = new QCheckBox;
createButton = new QPushButton;
joinButton = new QPushButton;
spectateButton = new QPushButton;
QHBoxLayout *buttonLayout = new QHBoxLayout;
buttonLayout->addWidget(showFullGamesCheckBox);
buttonLayout->addStretch();
buttonLayout->addWidget(createButton);
buttonLayout->addWidget(joinButton);
......@@ -28,11 +33,17 @@ GameSelector::GameSelector(Client *_client, QWidget *parent)
setMinimumWidth(gameListView->columnWidth(0) * gameListModel->columnCount());
setMinimumHeight(400);
connect(showFullGamesCheckBox, SIGNAL(stateChanged(int)), this, SLOT(showFullGamesChanged(int)));
connect(createButton, SIGNAL(clicked()), this, SLOT(actCreate()));
connect(joinButton, SIGNAL(clicked()), this, SLOT(actJoin()));
connect(spectateButton, SIGNAL(clicked()), this, SLOT(actJoin()));
}
void GameSelector::showFullGamesChanged(int state)
{
gameListProxyModel->setFullGamesVisible(state);
}
void GameSelector::actCreate()
{
DlgCreateGame dlg(client, this);
......@@ -66,16 +77,16 @@ void GameSelector::actJoin()
QModelIndex ind = gameListView->currentIndex();
if (!ind.isValid())
return;
ServerGame *game = gameListModel->getGame(ind.row());
const ServerGame &game = gameListModel->getGame(ind.row());
QString password;
if (game->getHasPassword()) {
if (game.getHasPassword()) {
bool ok;
password = QInputDialog::getText(this, tr("Join game"), tr("Password:"), QLineEdit::Password, QString(), &ok);
if (!ok)
return;
}
PendingCommand *joinCommand = client->joinGame(game->getGameId(), password, spectator);
PendingCommand *joinCommand = client->joinGame(game.getGameId(), password, spectator);
connect(joinCommand, SIGNAL(finished(ServerResponse)), this, SLOT(checkResponse(ServerResponse)));
createButton->setEnabled(false);
joinButton->setEnabled(false);
......@@ -87,7 +98,7 @@ void GameSelector::enableGameList()
if (isVisible())
return;
connect(client, SIGNAL(gameListEvent(ServerGame *)), gameListModel, SLOT(updateGameList(ServerGame *)));
connect(client, SIGNAL(gameListEvent(const ServerGame &)), gameListModel, SLOT(updateGameList(const ServerGame &)));
client->listGames();
show();
}
......@@ -104,6 +115,7 @@ void GameSelector::disableGameList()
void GameSelector::retranslateUi()
{
showFullGamesCheckBox->setText(tr("&Show full games"));
createButton->setText(tr("C&reate"));
joinButton->setText(tr("&Join"));
spectateButton->setText(tr("J&oin as spectator"));
......
......@@ -2,11 +2,13 @@
#define GAMESELECTOR_H
#include <QWidget>
#include "gamesmodel.h"
#include "client.h"
class QPushButton;
class QCheckBox;
class QTreeView;
class GamesModel;
class GamesProxyModel;
class GameSelector : public QWidget {
Q_OBJECT
......@@ -16,6 +18,7 @@ public:
void disableGameList();
void retranslateUi();
private slots:
void showFullGamesChanged(int state);
void actCreate();
void actRefresh();
void actJoin();
......@@ -25,7 +28,9 @@ private:
QTreeView *gameListView;
GamesModel *gameListModel;
GamesProxyModel *gameListProxyModel;
QPushButton *createButton, *joinButton, *spectateButton;
QCheckBox *showFullGamesCheckBox;
};
#endif
......
......@@ -13,13 +13,13 @@ QVariant GamesModel::data(const QModelIndex &index, int role) const
if ((index.row() >= gameList.size()) || (index.column() >= columnCount()))
return QVariant();
ServerGame *g = gameList.at(index.row());
const ServerGame &g = gameList[index.row()];
switch (index.column()) {
case 0: return g->getDescription();
case 1: return g->getCreator();
case 2: return g->getHasPassword() ? tr("yes") : tr("no");
case 3: return QString("%1/%2").arg(g->getPlayerCount()).arg(g->getMaxPlayers());
case 4: return g->getSpectatorsAllowed() ? QVariant(g->getSpectatorsCount()) : QVariant(tr("not allowed"));
case 0: return g.getDescription();
case 1: return g.getCreator();
case 2: return g.getHasPassword() ? tr("yes") : tr("no");
case 3: return QString("%1/%2").arg(g.getPlayerCount()).arg(g.getMaxPlayers());
case 4: return g.getSpectatorsAllowed() ? QVariant(g.getSpectatorsCount()) : QVariant(tr("not allowed"));
default: return QVariant();
}
}
......@@ -38,29 +38,27 @@ QVariant GamesModel::headerData(int section, Qt::Orientation orientation, int ro
}
}
ServerGame *GamesModel::getGame(int row)
const ServerGame &GamesModel::getGame(int row)
{
if (row >= gameList.size())
return 0;
Q_ASSERT(row < gameList.size());
return gameList[row];
}
void GamesModel::updateGameList(ServerGame *game)
void GamesModel::updateGameList(const ServerGame &game)
{
for (int i = 0; i < gameList.size(); i++)
if (gameList[i]->getGameId() == game->getGameId()) {
if ((game->getPlayerCount() == 0) || (game->getPlayerCount() == game->getMaxPlayers())) {
if (gameList[i].getGameId() == game.getGameId()) {
if (game.getPlayerCount() == 0) {
beginRemoveRows(QModelIndex(), i, i);
delete gameList.takeAt(i);
gameList.removeAt(i);
endRemoveRows();
} else {
delete gameList[i];
gameList[i] = game;
emit dataChanged(index(i, 0), index(i, 4));
}
return;
}
if ((game->getPlayerCount() == 0) || (game->getPlayerCount() == game->getMaxPlayers()))
if (game.getPlayerCount() == 0)
return;
beginInsertRows(QModelIndex(), gameList.size(), gameList.size());
gameList << game;
......@@ -73,9 +71,34 @@ void GamesModel::cleanList()
return;
beginRemoveRows(QModelIndex(), 0, gameList.size() - 1);
QListIterator<ServerGame *> i(gameList);
while (i.hasNext())
delete i.next();
gameList.clear();
endRemoveRows();
}
GamesProxyModel::GamesProxyModel(QObject *parent)
: QSortFilterProxyModel(parent), fullGamesVisible(false)
{
setDynamicSortFilter(true);
}
void GamesProxyModel::setFullGamesVisible(bool _fullGamesVisible)
{
fullGamesVisible = _fullGamesVisible;
invalidateFilter();
}
bool GamesProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &/*sourceParent*/) const
{
if (fullGamesVisible)
return true;
GamesModel *model = qobject_cast<GamesModel *>(sourceModel());
if (!model)
return false;
const ServerGame &game = model->getGame(sourceRow);
if (game.getPlayerCount() == game.getMaxPlayers())
return false;
return true;
}
#ifndef GAMESMODEL_H
#define GAMESMODEL_H
#include <QAbstractListModel>
#include <QAbstractTableModel>
#include <QSortFilterProxyModel>
#include <QList>
class ServerGame;
#include "client.h"
class GamesModel : public QAbstractTableModel {
Q_OBJECT
......@@ -16,12 +16,23 @@ public:
QVariant data(const QModelIndex &index, int role) const;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
ServerGame *getGame(int row);
const ServerGame &getGame(int row);
void cleanList();
public slots:
void updateGameList(ServerGame *game);
void updateGameList(const ServerGame &game);
private:
QList<ServerGame> gameList;
};
class GamesProxyModel : public QSortFilterProxyModel {
Q_OBJECT
private:
QList<ServerGame *> gameList;
bool fullGamesVisible;
public:
GamesProxyModel(QObject *parent = 0);
void setFullGamesVisible(bool _fullGamesVisible);
protected:
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
};
#endif
......@@ -69,6 +69,11 @@ void MessageLogWidget::logLeave(Player *player)
append(tr("%1 has left the game").arg(sanitizeHtml(player->getName())));
}
void MessageLogWidget::logGameClosed()
{
append(tr("The game has been closed."));
}
void MessageLogWidget::logJoinSpectator(QString name)
{
append(tr("%1 is now watching the game.").arg(sanitizeHtml(name)));
......@@ -264,6 +269,7 @@ void MessageLogWidget::connectToGame(Game *game)
connect(game, SIGNAL(logPlayerListReceived(QStringList)), this, SLOT(logPlayerListReceived(QStringList)));
connect(game, SIGNAL(logJoin(Player *)), this, SLOT(logJoin(Player *)));
connect(game, SIGNAL(logLeave(Player *)), this, SLOT(logLeave(Player *)));
connect(game, SIGNAL(logGameClosed()), this, SLOT(logGameClosed()));
connect(game, SIGNAL(logJoinSpectator(QString)), this, SLOT(logJoinSpectator(QString)));
connect(game, SIGNAL(logLeaveSpectator(QString)), this, SLOT(logLeaveSpectator(QString)));
connect(game, SIGNAL(logReadyStart(Player *)), this, SLOT(logReadyStart(Player *)));
......
......@@ -27,6 +27,7 @@ private slots:
void logPlayerListReceived(QStringList players);
void logJoin(Player *player);
void logLeave(Player *player);
void logGameClosed();
void logJoinSpectator(QString name);
void logLeaveSpectator(QString name);
void logReadyStart(Player *player);
......
......@@ -4,6 +4,7 @@
#include <QInputDialog>
#include <QPoint>
#include "zonelist.h"
#include "client.h"
class Client;
class CardDatabase;
......@@ -14,7 +15,6 @@ class Game;
class Counter;
class TableZone;
class HandZone;
class ServerEventData;
class Player : public QObject, public QGraphicsItem {
Q_OBJECT
......@@ -103,7 +103,7 @@ public:
int getId() const { return id; }
QString getName() const { return name; }
bool getLocal() const { return local; }
const ZoneList *getZones() const { return &zones; }
const ZoneList &getZones() const { return zones; }
void gameEvent(const ServerEventData &event);
CardDatabase *getDb() const { return db; }
void showCardMenu(const QPoint &p);
......
......@@ -97,6 +97,8 @@ void MainWindow::statusChanged(ProtocolStatus _status)
aRestartGame->setEnabled(true);
aLeaveGame->setEnabled(true);
game->queryGameState();
phasesToolbar->show();
view->show();
break;
......
......@@ -45,7 +45,7 @@ void ZoneViewLayout::toggleZoneView(Player *player, const QString &zoneName, int
}
}
ZoneViewWidget *item = new ZoneViewWidget(db, player, player->getZones()->findZone(zoneName), numberCards, this);
ZoneViewWidget *item = new ZoneViewWidget(db, player, player->getZones().findZone(zoneName), numberCards, this);
views.append(item);
connect(item, SIGNAL(closePressed(ZoneViewWidget *)), this, SLOT(removeItem(ZoneViewWidget *)));
connect(item, SIGNAL(sizeChanged()), this, SLOT(reorganize()));
......
......@@ -22,14 +22,15 @@ bool ReturnMessage::send(ReturnCode code)
return (code == ReturnOk);
}
bool ReturnMessage::sendList(const QStringList &args)
bool ReturnMessage::sendList(const QStringList &args, const QString &prefix)
{
ServerSocket *s = qobject_cast<ServerSocket *>(parent());
if (!s)
return false;
QString arg1 = prefix.isEmpty() ? cmd : prefix;
for (int i = 0; i < args.size(); i++)
s->msg(QString("%1|%2|%3").arg(cmd)
s->msg(QString("%1|%2|%3").arg(arg1)
.arg(msg_id)
.arg(args[i]));
return true;
......
......@@ -15,7 +15,7 @@ public:
void setMsgId(unsigned int _msg_id) { msg_id = _msg_id; }
void setCmd(const QString &_cmd) { cmd = _cmd; }
bool send(ReturnCode code);
bool sendList(const QStringList &args);
bool sendList(const QStringList &args, const QString &prefix = QString());
};
#endif
......@@ -88,7 +88,7 @@ bool Server::openDatabase()
void Server::addGame(const QString description, const QString password, int maxPlayers, bool spectatorsAllowed, ServerSocket *creator)
{
ServerGame *newGame = new ServerGame(creator, nextGameId++, description, password, maxPlayers, spectatorsAllowed, this);
games << newGame;
games.insert(newGame->getGameId(), newGame);
connect(newGame, SIGNAL(gameClosing()), this, SLOT(gameClosing()));
newGame->addPlayer(creator, false);
......@@ -131,28 +131,9 @@ AuthenticationResult Server::checkUserPassword(const QString &user, const QStrin
return UnknownUser;
}
ServerGame *Server::getGame(int gameId)
ServerGame *Server::getGame(int gameId) const
{
QListIterator<ServerGame *> i(games);
while (i.hasNext()) {
ServerGame *tmp = i.next();
if ((tmp->getGameId() == gameId) && !tmp->getGameStarted())
return tmp;
}
return NULL;
}
QList<ServerGame *> Server::listOpenGames()
{
QList<ServerGame *> result;
QListIterator<ServerGame *> i(games);
while (i.hasNext()) {
ServerGame *tmp = i.next();
if ((!tmp->getGameStarted())
&& (tmp->getPlayerCount() < tmp->getMaxPlayers()))
result.append(tmp);
}
return result;
return games.value(gameId);
}
void Server::broadcastGameListUpdate(ServerGame *game)
......@@ -175,7 +156,7 @@ void Server::broadcastChannelUpdate()
void Server::gameClosing()
{
qDebug("Server::gameClosing");
games.removeAt(games.indexOf(static_cast<ServerGame *>(sender())));
games.remove(games.key(static_cast<ServerGame *>(sender())));
}
void Server::removePlayer(ServerSocket *player)
......
......@@ -45,16 +45,16 @@ public:
QSettings *settings;
bool openDatabase();
AuthenticationResult checkUserPassword(const QString &user, const QString &password);
QList<ServerGame *> listOpenGames();
QList<ServerGame *> getGames() const { return games.values(); }
ServerGame *getGame(int gameId) const;
QList<ChatChannel *> getChatChannelList() { return chatChannelList; }
ServerGame *getGame(int gameId);
AbstractRNG *getRNG() const { return rng; }
void broadcastGameListUpdate(ServerGame *game);
void removePlayer(ServerSocket *player);
const QStringList &getLoginMessage() const { return loginMessage; }
private:
void incomingConnection(int SocketId);
QList<ServerGame *> games;
QMap<int, ServerGame *> games;
QList<ServerSocket *> players;
QList<ChatChannel *> chatChannelList;
int nextGameId;
......
......@@ -29,6 +29,15 @@ ServerGame::ServerGame(ServerSocket *_creator, int _gameId, const QString &_desc
ServerGame::~ServerGame()
{
broadcastEvent("game_closed", 0);
for (int i = 0; i < players.size(); ++i)
players[i]->leaveGame();
players.clear();
for (int i = 0; i < spectators.size(); ++i)
spectators[i]->leaveGame();
spectators.clear();
emit gameClosing();
qDebug("ServerGame destructor");
}
......@@ -37,15 +46,17 @@ QString ServerGame::getGameListLine() const
{
if (players.isEmpty())
return QString("list_games|%1|||0|%2||0").arg(gameId).arg(maxPlayers);
else
else {
QString creatorName = creator ? creator->getPlayerName() : QString();
return QString("list_games|%1|%2|%3|%4|%5|%6|%7|%8").arg(gameId)
.arg(description)
.arg(password.isEmpty() ? 0 : 1)
.arg(players.size())
.arg(maxPlayers)
.arg(creator->getPlayerName())
.arg(creatorName)
.arg(spectatorsAllowed ? 1 : 0)
.arg(spectators.size());
}
}
ServerSocket *ServerGame::getPlayer(int playerId)
......@@ -59,20 +70,11 @@ ServerSocket *ServerGame::getPlayer(int playerId)
return NULL;
}
void ServerGame::msg(const QString &s)
void ServerGame::broadcastEvent(const QString &eventStr, ServerSocket *player)
{
for (int i = 0; i < players.size(); ++i)
players[i]->msg(s);
for (int i = 0; i < spectators.size(); ++i)
spectators[i]->msg(s);
}
void ServerGame::broadcastEvent(const QString &cmd, ServerSocket *player)
{
if (player)
msg(QString("public|%1|%2|%3").arg(player->getPlayerId()).arg(player->getPlayerName()).arg(cmd));
else
msg(QString("public|||%1").arg(cmd));
QList<ServerSocket *> allClients = QList<ServerSocket *>() << players << spectators;
for (int i = 0; i < allClients.size(); ++i)
allClients[i]->publicEvent(eventStr, player);
}
void ServerGame::startGameIfReady()
......@@ -152,6 +154,8 @@ void ServerGame::removePlayer(ServerSocket *player)
else
players.removeAt(players.indexOf(player));
broadcastEvent("leave", player);
disconnect(player, 0, this, 0);
if (!players.size())
deleteLater();
if (!gameStarted)
......
......@@ -21,14 +21,14 @@
#define SERVERGAME_H
#include <QStringList>
#include <QPointer>
#include "returnmessage.h"
class ServerSocket;
#include "serversocket.h"
class ServerGame : public QObject {
Q_OBJECT
private:
ServerSocket *creator;
QPointer<ServerSocket> creator;
QList<ServerSocket *> players;
QList<ServerSocket *> spectators;
bool gameStarted;
......@@ -41,7 +41,7 @@ private:
signals:
void gameClosing();
public slots:
void broadcastEvent(const QString &event, ServerSocket *player);
void broadcastEvent(const QString &eventStr, ServerSocket *player);
public:
ServerGame(ServerSocket *_creator, int _gameId, const QString &_description, const QString &_password, int _maxPlayers, bool _spectatorsAllowed, QObject *parent = 0);
~ServerGame();
......@@ -60,7 +60,6 @@ public:
void addPlayer(ServerSocket *player, bool spectator);
void removePlayer(ServerSocket *player);
void startGameIfReady();
void msg(const QString &s);
int getActivePlayer() const { return activePlayer; }
int getActivePhase() const { return activePhase; }
void setActivePlayer(int _activePlayer);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment