final (?) spectator code, small bugfix

This commit is contained in:
Max-Wilhelm Bruker 2009-09-24 20:12:44 +02:00
parent fa16d86283
commit a543c9b90c
22 changed files with 453 additions and 190 deletions

View file

@ -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;

View file

@ -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

View file

@ -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)

View file

@ -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;

View file

@ -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)

View file

@ -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);

View file

@ -116,6 +116,7 @@ ServerSocket::ServerSocket(Server *_server, QObject *parent)
commandHash.insert("next_turn", CommandProperties(true, true, true, false, QList<QVariant::Type>(), &ServerSocket::cmdNextTurn));
commandHash.insert("set_active_phase", CommandProperties(true, true, true, false, QList<QVariant::Type>()
<< QVariant::Int, &ServerSocket::cmdSetActivePhase));
commandHash.insert("dump_all", CommandProperties(true, true, false, true, QList<QVariant::Type>(), &ServerSocket::cmdDumpAll));
}
remsg = new ReturnMessage(this);
@ -323,10 +324,9 @@ ReturnMessage::ReturnCode ServerSocket::cmdChatSay(const QList<QVariant> &params
ReturnMessage::ReturnCode ServerSocket::cmdListGames(const QList<QVariant> &/*params*/)
{
QList<ServerGame *> gameList = server->listOpenGames();
QListIterator<ServerGame *> gameListIterator(gameList);
while (gameListIterator.hasNext())
msg(gameListIterator.next()->getGameListLine());
const QList<ServerGame *> &gameList = server->getGames();
for (int i = 0; i < gameList.size(); ++i)
msg(gameList[i]->getGameListLine());
acceptsGameListChanges = true;
return ReturnMessage::ReturnOk;
@ -375,14 +375,18 @@ ReturnMessage::ReturnCode ServerSocket::cmdLeaveGame(const QList<QVariant> &/*pa
return ReturnMessage::ReturnOk;
}
ReturnMessage::ReturnCode ServerSocket::cmdListPlayers(const QList<QVariant> &/*params*/)
QStringList ServerSocket::listPlayersHelper()
{
QStringList result;
const QList<ServerSocket *> &players = game->getPlayers();
for (int i = 0; i < players.size(); ++i)
result << QString("%1|%2|%3").arg(players[i]->getPlayerId()).arg(players[i]->getPlayerName()).arg(players[i] == this ? 1 : 0);
remsg->sendList(result);
return result;
}
ReturnMessage::ReturnCode ServerSocket::cmdListPlayers(const QList<QVariant> &/*params*/)
{
remsg->sendList(listPlayersHelper());
return ReturnMessage::ReturnOk;
}
@ -632,6 +636,15 @@ ReturnMessage::ReturnCode ServerSocket::cmdDelCounter(const QList<QVariant> &par
return ReturnMessage::ReturnOk;
}
QStringList ServerSocket::listCountersHelper(ServerSocket *player)
{
QStringList result;
const QList<Counter *> &counterList = player->getCounters();
for (int i = 0; i < counterList.size(); ++i)
result << QString("%1|%2|%3|%4").arg(player->getPlayerId()).arg(counterList[i]->getName()).arg(counterList[i]->getColor()).arg(counterList[i]->getCount());
return result;
}
ReturnMessage::ReturnCode ServerSocket::cmdListCounters(const QList<QVariant> &params)
{
int player_id = params[0].toInt();
@ -639,15 +652,27 @@ ReturnMessage::ReturnCode ServerSocket::cmdListCounters(const QList<QVariant> &p
if (!player)
return ReturnMessage::ReturnContextError;
QStringList result;
const QList<Counter *> &counterList = player->getCounters();
for (int i = 0; i < counterList.size(); ++i)
result << QString("%1|%2|%3").arg(counterList[i]->getName()).arg(counterList[i]->getColor()).arg(counterList[i]->getCount());
remsg->sendList(result);
remsg->sendList(listCountersHelper(player));
return ReturnMessage::ReturnOk;
}
QStringList ServerSocket::listZonesHelper(ServerSocket *player)
{
QStringList result;
const QList<PlayerZone *> &zoneList = player->getZones();
for (int i = 0; i < zoneList.size(); ++i) {
QString typeStr;
switch (zoneList[i]->getType()) {
case PlayerZone::PublicZone: typeStr = "public"; break;
case PlayerZone::PrivateZone: typeStr = "private"; break;
case PlayerZone::HiddenZone: typeStr = "hidden"; break;
default: ;
}
result << QString("%1|%2|%3|%4|%5").arg(player->getPlayerId()).arg(zoneList[i]->getName()).arg(typeStr).arg(zoneList[i]->hasCoords()).arg(zoneList[i]->cards.size());
}
return result;
}
ReturnMessage::ReturnCode ServerSocket::cmdListZones(const QList<QVariant> &params)
{
int player_id = params[0].toInt();
@ -655,14 +680,36 @@ ReturnMessage::ReturnCode ServerSocket::cmdListZones(const QList<QVariant> &para
if (!player)
return ReturnMessage::ReturnContextError;
QStringList result;
const QList<PlayerZone *> &zoneList = player->getZones();
for (int i = 0; i < zoneList.size(); ++i)
result << QString("%1|%2|%3|%4").arg(zoneList[i]->getName()).arg(zoneList[i]->getType() == PlayerZone::PublicZone ? 1 : 0).arg(zoneList[i]->hasCoords()).arg(zoneList[i]->cards.size());
remsg->sendList(result);
remsg->sendList(listZonesHelper(player));
return ReturnMessage::ReturnOk;
}
QStringList ServerSocket::dumpZoneHelper(ServerSocket *player, PlayerZone *zone, int number_cards)
{
QListIterator<Card *> card_iterator(zone->cards);
QStringList result;
for (int i = 0; card_iterator.hasNext() && (i < number_cards || number_cards == -1); i++) {
Card *tmp = card_iterator.next();
// XXX Face down cards
if (zone->getType() != PlayerZone::HiddenZone)
result << QString("%1|%2|%3|%4|%5|%6|%7|%8|%9|%10").arg(player->getPlayerId())
.arg(zone->getName())
.arg(tmp->getId())
.arg(tmp->getName())
.arg(tmp->getX())
.arg(tmp->getY())
.arg(tmp->getCounters())
.arg(tmp->getTapped())
.arg(tmp->getAttacking())
.arg(tmp->getAnnotation());
else {
zone->setCardsBeingLookedAt(number_cards);
result << QString("%1|%2|%3|%4||||||").arg(player->getPlayerId()).arg(zone->getName()).arg(i).arg(tmp->getName());
}
}
return result;
}
ReturnMessage::ReturnCode ServerSocket::cmdDumpZone(const QList<QVariant> &params)
{
int player_id = params[0].toInt();
@ -675,28 +722,11 @@ ReturnMessage::ReturnCode ServerSocket::cmdDumpZone(const QList<QVariant> &param
return ReturnMessage::ReturnContextError;
if (!((zone->getType() == PlayerZone::PublicZone) || (player_id == playerId)))
return ReturnMessage::ReturnContextError;
QListIterator<Card *> card_iterator(zone->cards);
QStringList result;
for (int i = 0; card_iterator.hasNext() && (i < number_cards || number_cards == -1); i++) {
Card *tmp = card_iterator.next();
// XXX Face down cards
if (zone->getType() != PlayerZone::HiddenZone)
result << QString("%1|%2|%3|%4|%5|%6|%7|%8").arg(tmp->getId())
.arg(tmp->getName())
.arg(tmp->getX())
.arg(tmp->getY())
.arg(tmp->getCounters())
.arg(tmp->getTapped())
.arg(tmp->getAttacking())
.arg(tmp->getAnnotation());
else {
zone->setCardsBeingLookedAt(number_cards);
result << QString("%1|%2||||||").arg(i).arg(tmp->getName());
}
}
emit broadcastEvent(QString("dump_zone|%1|%2|%3").arg(player_id).arg(zone->getName()).arg(number_cards), this);
remsg->sendList(result);
if (zone->getType() == PlayerZone::HiddenZone)
emit broadcastEvent(QString("dump_zone|%1|%2|%3").arg(player_id).arg(zone->getName()).arg(number_cards), this);
remsg->sendList(dumpZoneHelper(player, zone, number_cards));
return ReturnMessage::ReturnOk;
}
@ -742,6 +772,32 @@ ReturnMessage::ReturnCode ServerSocket::cmdSetActivePhase(const QList<QVariant>
return ReturnMessage::ReturnOk;
}
ReturnMessage::ReturnCode ServerSocket::cmdDumpAll(const QList<QVariant> &/*params*/)
{
remsg->sendList(listPlayersHelper(), "list_players");
if (game->getGameStarted()) {
const QList<ServerSocket *> &players = game->getPlayers();
for (int i = 0; i < players.size(); ++i) {
remsg->sendList(listZonesHelper(players[i]), "list_zones");
const QList<PlayerZone *> &zones = players[i]->getZones();
for (int j = 0; j < zones.size(); ++j)
if ((zones[j]->getType() == PlayerZone::PublicZone) || ((zones[j]->getType() == PlayerZone::PrivateZone) && (playerId == players[i]->getPlayerId())))
remsg->sendList(dumpZoneHelper(players[i], zones[j], -1), "dump_zone");
remsg->sendList(listCountersHelper(players[i]), "list_counters");
}
}
remsg->send(ReturnMessage::ReturnOk);
if (game->getGameStarted()) {
publicEvent(QString("set_active_player|%1").arg(game->getActivePlayer()));
publicEvent(QString("set_active_phase|%1").arg(game->getActivePhase()));
}
return ReturnMessage::ReturnNothing;
}
bool ServerSocket::parseCommand(QString line)
{
QStringList params = line.split("|");
@ -817,9 +873,12 @@ void ServerSocket::privateEvent(const QString &line)
msg(QString("private|%1|%2|%3").arg(playerId).arg(playerName).arg(line));
}
void ServerSocket::setGame(ServerGame *g)
void ServerSocket::publicEvent(const QString &line, ServerSocket *player)
{
game = g;
if (player)
msg(QString("public|%1|%2|%3").arg(player->getPlayerId()).arg(player->getPlayerName()).arg(line));
else
msg(QString("public|||%1").arg(line));
}
void ServerSocket::msg(const QString &s)

View file

@ -66,6 +66,11 @@ private:
};
static QHash<QString, CommandProperties> commandHash;
QStringList listPlayersHelper();
QStringList listZonesHelper(ServerSocket *player);
QStringList dumpZoneHelper(ServerSocket *player, PlayerZone *zone, int numberCards);
QStringList listCountersHelper(ServerSocket *player);
ReturnMessage::ReturnCode cmdPing(const QList<QVariant> &params);
ReturnMessage::ReturnCode cmdLogin(const QList<QVariant> &params);
ReturnMessage::ReturnCode cmdChatListChannels(const QList<QVariant> &params);
@ -97,6 +102,7 @@ private:
ReturnMessage::ReturnCode cmdRollDie(const QList<QVariant> &params);
ReturnMessage::ReturnCode cmdNextTurn(const QList<QVariant> &params);
ReturnMessage::ReturnCode cmdSetActivePhase(const QList<QVariant> &params);
ReturnMessage::ReturnCode cmdDumpAll(const QList<QVariant> &params);
Server *server;
ServerGame *game;
@ -113,9 +119,7 @@ private:
PlayerZone *getZone(const QString &name) const;
Counter *getCounter(const QString &name) const;
void clearZones();
void leaveGame();
bool parseCommand(QString line);
void privateEvent(const QString &line);
PlayerStatusEnum PlayerStatus;
ReturnMessage *remsg;
AuthenticationResult authState;
@ -125,7 +129,10 @@ public:
ServerSocket(Server *_server, QObject *parent = 0);
~ServerSocket();
void msg(const QString &s);
void setGame(ServerGame *g);
void privateEvent(const QString &line);
void publicEvent(const QString &line, ServerSocket *player = 0);
void setGame(ServerGame *g) { game = g; }
void leaveGame();
PlayerStatusEnum getStatus() { return PlayerStatus; }
void setStatus(PlayerStatusEnum _status) { PlayerStatus = _status; }
void initConnection();