reworked protocol; only server code for now
This commit is contained in:
parent
da6a1a0dbd
commit
a8c45fda1a
13 changed files with 669 additions and 534 deletions
|
@ -23,7 +23,8 @@ HEADERS += src/server.h src/servergame.h src/serversocket.h \
|
|||
src/abstractrng.h \
|
||||
src/rng_qt.h \
|
||||
src/returnmessage.h \
|
||||
src/chatchannel.h
|
||||
src/chatchannel.h \
|
||||
src/player.h
|
||||
SOURCES += src/main.cpp \
|
||||
src/server.cpp \
|
||||
src/servergame.cpp \
|
||||
|
@ -33,4 +34,5 @@ SOURCES += src/main.cpp \
|
|||
src/counter.cpp \
|
||||
src/rng_qt.cpp \
|
||||
src/returnmessage.cpp \
|
||||
src/chatchannel.cpp
|
||||
src/chatchannel.cpp \
|
||||
src/player.cpp
|
||||
|
|
|
@ -10,4 +10,6 @@ public:
|
|||
virtual unsigned int getNumber(unsigned int min, unsigned int max) = 0;
|
||||
};
|
||||
|
||||
extern AbstractRNG *rng;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,10 +18,12 @@
|
|||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QTextCodec>
|
||||
#include "server.h"
|
||||
#include "rng_qt.h"
|
||||
|
||||
AbstractRNG *rng;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
@ -31,6 +33,8 @@ int main(int argc, char *argv[])
|
|||
|
||||
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
|
||||
|
||||
rng = new RNG_Qt;
|
||||
|
||||
Server server;
|
||||
server.listen(QHostAddress::Any, 4747);
|
||||
|
||||
|
|
149
servatrice/src/player.cpp
Normal file
149
servatrice/src/player.cpp
Normal file
|
@ -0,0 +1,149 @@
|
|||
#include "player.h"
|
||||
#include "card.h"
|
||||
#include "counter.h"
|
||||
#include "arrow.h"
|
||||
#include "playerzone.h"
|
||||
#include "serversocket.h"
|
||||
#include "servergame.h"
|
||||
|
||||
Player::Player(ServerGame *_game, int _playerId, const QString &_playerName, bool _spectator)
|
||||
: game(_game), socket(0), playerId(_playerId), playerName(_playerName), spectator(_spectator), nextCardId(0), PlayerStatus(StatusNormal)
|
||||
{
|
||||
}
|
||||
|
||||
int Player::newCardId()
|
||||
{
|
||||
return nextCardId++;
|
||||
}
|
||||
|
||||
int Player::newCounterId() const
|
||||
{
|
||||
int id = 0;
|
||||
QMapIterator<int, Counter *> i(counters);
|
||||
while (i.hasNext()) {
|
||||
Counter *c = i.next().value();
|
||||
if (c->getId() > id)
|
||||
id = c->getId();
|
||||
}
|
||||
return id + 1;
|
||||
}
|
||||
|
||||
int Player::newArrowId() const
|
||||
{
|
||||
int id = 0;
|
||||
QMapIterator<int, Arrow *> i(arrows);
|
||||
while (i.hasNext()) {
|
||||
Arrow *a = i.next().value();
|
||||
if (a->getId() > id)
|
||||
id = a->getId();
|
||||
}
|
||||
return id + 1;
|
||||
}
|
||||
|
||||
void Player::setupZones()
|
||||
{
|
||||
// Delete existing zones and counters
|
||||
clearZones();
|
||||
|
||||
// This may need to be customized according to the game rules.
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
// Create zones
|
||||
PlayerZone *deck = new PlayerZone(this, "deck", false, PlayerZone::HiddenZone);
|
||||
addZone(deck);
|
||||
PlayerZone *sb = new PlayerZone(this, "sb", false, PlayerZone::HiddenZone);
|
||||
addZone(sb);
|
||||
addZone(new PlayerZone(this, "table", true, PlayerZone::PublicZone));
|
||||
addZone(new PlayerZone(this, "hand", false, PlayerZone::PrivateZone));
|
||||
addZone(new PlayerZone(this, "grave", false, PlayerZone::PublicZone));
|
||||
addZone(new PlayerZone(this, "rfg", false, PlayerZone::PublicZone));
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
// Assign card ids and create deck from decklist
|
||||
QListIterator<QString> DeckIterator(DeckList);
|
||||
int i = 0;
|
||||
while (DeckIterator.hasNext())
|
||||
deck->cards.append(new Card(DeckIterator.next(), i++, 0, 0));
|
||||
deck->shuffle();
|
||||
|
||||
QListIterator<QString> SBIterator(SideboardList);
|
||||
while (SBIterator.hasNext())
|
||||
sb->cards.append(new Card(SBIterator.next(), i++, 0, 0));
|
||||
|
||||
nextCardId = i;
|
||||
|
||||
PlayerStatus = StatusPlaying;
|
||||
game->broadcastEvent(QString("setup_zones|%1|%2").arg(deck->cards.size())
|
||||
.arg(sb->cards.size()), this);
|
||||
}
|
||||
|
||||
void Player::clearZones()
|
||||
{
|
||||
QMapIterator<QString, PlayerZone *> zoneIterator(zones);
|
||||
while (zoneIterator.hasNext())
|
||||
delete zoneIterator.next().value();
|
||||
zones.clear();
|
||||
|
||||
QMapIterator<int, Counter *> counterIterator(counters);
|
||||
while (counterIterator.hasNext())
|
||||
delete counterIterator.next().value();
|
||||
counters.clear();
|
||||
|
||||
QMapIterator<int, Arrow *> arrowIterator(arrows);
|
||||
while (arrowIterator.hasNext())
|
||||
delete arrowIterator.next().value();
|
||||
arrows.clear();
|
||||
}
|
||||
|
||||
void Player::addZone(PlayerZone *zone)
|
||||
{
|
||||
zones.insert(zone->getName(), zone);
|
||||
}
|
||||
|
||||
void Player::addArrow(Arrow *arrow)
|
||||
{
|
||||
arrows.insert(arrow->getId(), arrow);
|
||||
}
|
||||
|
||||
bool Player::deleteArrow(int arrowId)
|
||||
{
|
||||
Arrow *arrow = arrows.value(arrowId, 0);
|
||||
if (!arrow)
|
||||
return false;
|
||||
arrows.remove(arrowId);
|
||||
delete arrow;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Player::addCounter(Counter *counter)
|
||||
{
|
||||
counters.insert(counter->getId(), counter);
|
||||
}
|
||||
|
||||
bool Player::deleteCounter(int counterId)
|
||||
{
|
||||
Counter *counter = counters.value(counterId, 0);
|
||||
if (!counter)
|
||||
return false;
|
||||
counters.remove(counterId);
|
||||
delete counter;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Player::privateEvent(const QString &line)
|
||||
{
|
||||
if (!socket)
|
||||
return;
|
||||
socket->msg(QString("private|%1|%2|%3").arg(playerId).arg(playerName).arg(line));
|
||||
}
|
||||
|
||||
void Player::publicEvent(const QString &line, Player *player)
|
||||
{
|
||||
if (!socket)
|
||||
return;
|
||||
if (player)
|
||||
socket->msg(QString("public|%1|%2|%3").arg(player->getPlayerId()).arg(player->getPlayerName()).arg(line));
|
||||
else
|
||||
socket->msg(QString("public|||%1").arg(line));
|
||||
}
|
66
servatrice/src/player.h
Normal file
66
servatrice/src/player.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
#ifndef PLAYER_H
|
||||
#define PLAYER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
|
||||
class ServerSocket;
|
||||
class ServerGame;
|
||||
class PlayerZone;
|
||||
class Counter;
|
||||
class Arrow;
|
||||
|
||||
enum PlayerStatusEnum { StatusNormal, StatusSubmitDeck, StatusReadyStart, StatusPlaying };
|
||||
|
||||
class Player : public QObject {
|
||||
Q_OBJECT
|
||||
private:
|
||||
ServerGame *game;
|
||||
ServerSocket *socket;
|
||||
QMap<QString, PlayerZone *> zones;
|
||||
QMap<int, Counter *> counters;
|
||||
QMap<int, Arrow *> arrows;
|
||||
int playerId;
|
||||
QString playerName;
|
||||
bool spectator;
|
||||
int nextCardId;
|
||||
void clearZones();
|
||||
PlayerStatusEnum PlayerStatus;
|
||||
public:
|
||||
// Pfusch
|
||||
QList<QString> DeckList;
|
||||
QList<QString> SideboardList;
|
||||
// Pfusch Ende
|
||||
|
||||
Player(ServerGame *_game, int _playerId, const QString &_playerName, bool _spectator);
|
||||
void setSocket(ServerSocket *_socket) { socket = _socket; }
|
||||
|
||||
void setStatus(PlayerStatusEnum _status) { PlayerStatus = _status; }
|
||||
void setPlayerId(int _id) { playerId = _id; }
|
||||
PlayerStatusEnum getStatus() { return PlayerStatus; }
|
||||
int getPlayerId() const { return playerId; }
|
||||
bool getSpectator() const { return spectator; }
|
||||
QString getPlayerName() const { return playerName; }
|
||||
const QMap<QString, PlayerZone *> &getZones() const { return zones; }
|
||||
const QMap<int, Counter *> &getCounters() const { return counters; }
|
||||
const QMap<int, Arrow *> &getArrows() const { return arrows; }
|
||||
|
||||
int newCardId();
|
||||
int newCounterId() const;
|
||||
int newArrowId() const;
|
||||
|
||||
void addZone(PlayerZone *zone);
|
||||
void addArrow(Arrow *arrow);
|
||||
bool deleteArrow(int arrowId);
|
||||
void addCounter(Counter *counter);
|
||||
bool deleteCounter(int counterId);
|
||||
|
||||
void setupZones();
|
||||
|
||||
void privateEvent(const QString &line);
|
||||
void publicEvent(const QString &line, Player *player = 0);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -21,7 +21,7 @@
|
|||
#include "abstractrng.h"
|
||||
#include "card.h"
|
||||
|
||||
PlayerZone::PlayerZone(ServerSocket *_player, const QString &_name, bool _has_coords, ZoneType _type)
|
||||
PlayerZone::PlayerZone(Player *_player, const QString &_name, bool _has_coords, ZoneType _type)
|
||||
: player(_player), name(_name), has_coords(_has_coords), type(_type), cardsBeingLookedAt(0)
|
||||
{
|
||||
}
|
||||
|
@ -32,11 +32,11 @@ PlayerZone::~PlayerZone()
|
|||
clear();
|
||||
}
|
||||
|
||||
void PlayerZone::shuffle(AbstractRNG *rnd)
|
||||
void PlayerZone::shuffle()
|
||||
{
|
||||
QList<Card *> temp;
|
||||
for (int i = cards.size(); i; i--)
|
||||
temp.append(cards.takeAt(rnd->getNumber(0, i - 1)));
|
||||
temp.append(cards.takeAt(rng->getNumber(0, i - 1)));
|
||||
cards = temp;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
class Card;
|
||||
class ServerSocket;
|
||||
class AbstractRNG;
|
||||
class Player;
|
||||
|
||||
class PlayerZone {
|
||||
public:
|
||||
|
@ -39,13 +39,13 @@ public:
|
|||
// list index, whereas cards in any other zone are referenced by their ids.
|
||||
enum ZoneType { PrivateZone, PublicZone, HiddenZone };
|
||||
private:
|
||||
ServerSocket *player;
|
||||
Player *player;
|
||||
QString name;
|
||||
bool has_coords;
|
||||
ZoneType type;
|
||||
int cardsBeingLookedAt;
|
||||
public:
|
||||
PlayerZone(ServerSocket *_player, const QString &_name, bool _has_coords, ZoneType _type);
|
||||
PlayerZone(Player *_player, const QString &_name, bool _has_coords, ZoneType _type);
|
||||
~PlayerZone();
|
||||
|
||||
Card *getCard(int id, bool remove, int *position = NULL);
|
||||
|
@ -55,11 +55,11 @@ public:
|
|||
bool hasCoords() const { return has_coords; }
|
||||
ZoneType getType() const { return type; }
|
||||
QString getName() const { return name; }
|
||||
ServerSocket *getPlayer() const { return player; }
|
||||
Player *getPlayer() const { return player; }
|
||||
|
||||
QList<Card *> cards;
|
||||
void insertCard(Card *card, int x, int y);
|
||||
void shuffle(AbstractRNG *rnd);
|
||||
void shuffle();
|
||||
void clear();
|
||||
};
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include "servergame.h"
|
||||
#include "serversocket.h"
|
||||
#include "counter.h"
|
||||
#include "rng_qt.h"
|
||||
#include "chatchannel.h"
|
||||
#include <QtSql>
|
||||
#include <QSettings>
|
||||
|
@ -29,8 +28,6 @@
|
|||
Server::Server(QObject *parent)
|
||||
: QTcpServer(parent), nextGameId(0)
|
||||
{
|
||||
rng = new RNG_Qt(this);
|
||||
|
||||
settings = new QSettings("servatrice.ini", QSettings::IniFormat, this);
|
||||
|
||||
QString dbType = settings->value("database/type").toString();
|
||||
|
@ -40,16 +37,15 @@ Server::Server(QObject *parent)
|
|||
int size = settings->beginReadArray("chatchannels");
|
||||
for (int i = 0; i < size; ++i) {
|
||||
settings->setArrayIndex(i);
|
||||
chatChannelList << new ChatChannel(settings->value("name").toString(),
|
||||
ChatChannel *newChannel = new ChatChannel(settings->value("name").toString(),
|
||||
settings->value("description").toString(),
|
||||
settings->value("autojoin").toBool(),
|
||||
settings->value("joinmessage").toStringList());
|
||||
chatChannels.insert(newChannel->getName(), newChannel);
|
||||
connect(newChannel, SIGNAL(channelInfoChanged()), this, SLOT(broadcastChannelUpdate()));
|
||||
}
|
||||
settings->endArray();
|
||||
|
||||
for (int i = 0; i < chatChannelList.size(); ++i)
|
||||
connect(chatChannelList[i], SIGNAL(channelInfoChanged()), this, SLOT(broadcastChannelUpdate()));
|
||||
|
||||
loginMessage = settings->value("messages/login").toStringList();
|
||||
}
|
||||
|
||||
|
@ -85,14 +81,15 @@ bool Server::openDatabase()
|
|||
return true;
|
||||
}
|
||||
|
||||
void Server::addGame(const QString description, const QString password, int maxPlayers, bool spectatorsAllowed, ServerSocket *creator)
|
||||
ServerGame *Server::createGame(const QString &description, const QString &password, int maxPlayers, bool spectatorsAllowed, const QString &creator)
|
||||
{
|
||||
ServerGame *newGame = new ServerGame(creator, nextGameId++, description, password, maxPlayers, spectatorsAllowed, this);
|
||||
games.insert(newGame->getGameId(), newGame);
|
||||
connect(newGame, SIGNAL(gameClosing()), this, SLOT(gameClosing()));
|
||||
newGame->addPlayer(creator, false);
|
||||
|
||||
broadcastGameListUpdate(newGame);
|
||||
|
||||
return newGame;
|
||||
}
|
||||
|
||||
void Server::incomingConnection(int socketId)
|
||||
|
|
|
@ -27,7 +27,6 @@ class ServerGame;
|
|||
class ServerSocket;
|
||||
class QSqlDatabase;
|
||||
class QSettings;
|
||||
class AbstractRNG;
|
||||
class ChatChannel;
|
||||
|
||||
enum AuthenticationResult { PasswordWrong = 0, PasswordRight = 1, UnknownUser = 2 };
|
||||
|
@ -36,7 +35,6 @@ class Server : public QTcpServer
|
|||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void addGame(const QString description, const QString password, int maxPlayers, bool spectatorsAllowed, ServerSocket *creator);
|
||||
void gameClosing();
|
||||
void broadcastChannelUpdate();
|
||||
public:
|
||||
|
@ -47,19 +45,18 @@ public:
|
|||
AuthenticationResult checkUserPassword(const QString &user, const QString &password);
|
||||
QList<ServerGame *> getGames() const { return games.values(); }
|
||||
ServerGame *getGame(int gameId) const;
|
||||
QList<ChatChannel *> getChatChannelList() { return chatChannelList; }
|
||||
AbstractRNG *getRNG() const { return rng; }
|
||||
const QMap<QString, ChatChannel *> &getChatChannels() { return chatChannels; }
|
||||
void broadcastGameListUpdate(ServerGame *game);
|
||||
void removePlayer(ServerSocket *player);
|
||||
const QStringList &getLoginMessage() const { return loginMessage; }
|
||||
ServerGame *createGame(const QString &description, const QString &password, int maxPlayers, bool spectatorsAllowed, const QString &playerName);
|
||||
private:
|
||||
void incomingConnection(int SocketId);
|
||||
QMap<int, ServerGame *> games;
|
||||
QList<ServerSocket *> players;
|
||||
QList<ChatChannel *> chatChannelList;
|
||||
QMap<QString, ChatChannel *> chatChannels;
|
||||
int nextGameId;
|
||||
QStringList loginMessage;
|
||||
AbstractRNG *rng;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -23,20 +23,22 @@
|
|||
#include "arrow.h"
|
||||
#include <QSqlQuery>
|
||||
|
||||
ServerGame::ServerGame(ServerSocket *_creator, int _gameId, const QString &_description, const QString &_password, int _maxPlayers, bool _spectatorsAllowed, QObject *parent)
|
||||
: QObject(parent), creator(_creator), gameStarted(false), gameId(_gameId), description(_description), password(_password), maxPlayers(_maxPlayers), spectatorsAllowed(_spectatorsAllowed)
|
||||
ServerGame::ServerGame(const QString &_creator, int _gameId, const QString &_description, const QString &_password, int _maxPlayers, bool _spectatorsAllowed, QObject *parent)
|
||||
: QObject(parent), gameStarted(false), gameId(_gameId), description(_description), password(_password), maxPlayers(_maxPlayers), spectatorsAllowed(_spectatorsAllowed)
|
||||
{
|
||||
creator = addPlayer(_creator, false);
|
||||
}
|
||||
|
||||
ServerGame::~ServerGame()
|
||||
{
|
||||
broadcastEvent("game_closed", 0);
|
||||
|
||||
for (int i = 0; i < players.size(); ++i)
|
||||
players[i]->leaveGame();
|
||||
QMapIterator<int, Player *> playerIterator(players);
|
||||
while (playerIterator.hasNext())
|
||||
delete playerIterator.next().value();
|
||||
players.clear();
|
||||
for (int i = 0; i < spectators.size(); ++i)
|
||||
spectators[i]->leaveGame();
|
||||
delete spectators[i];
|
||||
spectators.clear();
|
||||
|
||||
emit gameClosing();
|
||||
|
@ -60,20 +62,9 @@ QString ServerGame::getGameListLine() const
|
|||
}
|
||||
}
|
||||
|
||||
ServerSocket *ServerGame::getPlayer(int playerId)
|
||||
void ServerGame::broadcastEvent(const QString &eventStr, Player *player)
|
||||
{
|
||||
QListIterator<ServerSocket *> i(players);
|
||||
while (i.hasNext()) {
|
||||
ServerSocket *tmp = i.next();
|
||||
if (tmp->getPlayerId() == playerId)
|
||||
return tmp;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ServerGame::broadcastEvent(const QString &eventStr, ServerSocket *player)
|
||||
{
|
||||
QList<ServerSocket *> allClients = QList<ServerSocket *>() << players << spectators;
|
||||
QList<Player *> allClients = QList<Player *>() << players.values() << spectators;
|
||||
for (int i = 0; i < allClients.size(); ++i)
|
||||
allClients[i]->publicEvent(eventStr, player);
|
||||
}
|
||||
|
@ -82,8 +73,9 @@ void ServerGame::startGameIfReady()
|
|||
{
|
||||
if (players.size() < maxPlayers)
|
||||
return;
|
||||
for (int i = 0; i < players.size(); i++)
|
||||
if (players.at(i)->getStatus() != StatusReadyStart)
|
||||
QMapIterator<int, Player *> playerIterator(players);
|
||||
while (playerIterator.hasNext())
|
||||
if (playerIterator.next().value()->getStatus() != StatusReadyStart)
|
||||
return;
|
||||
|
||||
QSqlQuery query;
|
||||
|
@ -93,16 +85,17 @@ void ServerGame::startGameIfReady()
|
|||
query.bindValue(":password", !password.isEmpty());
|
||||
query.exec();
|
||||
|
||||
for (int i = 0; i < players.size(); i++) {
|
||||
QMapIterator<int, Player *> playerIterator2(players);
|
||||
while (playerIterator2.hasNext()) {
|
||||
Player *player = playerIterator2.next().value();
|
||||
query.prepare("insert into games_players (id_game, player) values(:id, :player)");
|
||||
query.bindValue(":id", gameId);
|
||||
query.bindValue(":player", players.at(i)->getPlayerName());
|
||||
query.bindValue(":player", player->getPlayerName());
|
||||
query.exec();
|
||||
|
||||
player->setupZones();
|
||||
}
|
||||
|
||||
for (int i = 0; i < players.size(); i++)
|
||||
players.at(i)->setupZones();
|
||||
|
||||
gameStarted = true;
|
||||
broadcastEvent("game_start", NULL);
|
||||
setActivePlayer(0);
|
||||
|
@ -121,41 +114,42 @@ ReturnMessage::ReturnCode ServerGame::checkJoin(const QString &_password, bool s
|
|||
return ReturnMessage::ReturnOk;
|
||||
}
|
||||
|
||||
void ServerGame::addPlayer(ServerSocket *player, bool spectator)
|
||||
Player *ServerGame::addPlayer(const QString &playerName, bool spectator)
|
||||
{
|
||||
int playerId;
|
||||
if (!spectator) {
|
||||
int max = -1;
|
||||
QListIterator<ServerSocket *> i(players);
|
||||
QMapIterator<int, Player *> i(players);
|
||||
while (i.hasNext()) {
|
||||
int tmp = i.next()->getPlayerId();
|
||||
int tmp = i.next().value()->getPlayerId();
|
||||
if (tmp > max)
|
||||
max = tmp;
|
||||
}
|
||||
player->setPlayerId(max + 1);
|
||||
playerId = max + 1;
|
||||
} else
|
||||
player->setPlayerId(-1);
|
||||
playerId = -1;
|
||||
|
||||
player->setGame(this);
|
||||
broadcastEvent(QString("join|%1").arg(spectator ? 1 : 0), player);
|
||||
Player *newPlayer = new Player(this, playerId, playerName, spectator);
|
||||
broadcastEvent(QString("join|%1").arg(spectator ? 1 : 0), newPlayer);
|
||||
|
||||
if (spectator)
|
||||
spectators << player;
|
||||
spectators << newPlayer;
|
||||
else
|
||||
players << player;
|
||||
|
||||
connect(player, SIGNAL(broadcastEvent(const QString &, ServerSocket *)), this, SLOT(broadcastEvent(const QString &, ServerSocket *)));
|
||||
players.insert(playerId, newPlayer);
|
||||
|
||||
qobject_cast<Server *>(parent())->broadcastGameListUpdate(this);
|
||||
|
||||
return newPlayer;
|
||||
}
|
||||
|
||||
void ServerGame::removePlayer(ServerSocket *player)
|
||||
void ServerGame::removePlayer(Player *player)
|
||||
{
|
||||
if (player->getSpectator())
|
||||
spectators.removeAt(spectators.indexOf(player));
|
||||
else
|
||||
players.removeAt(players.indexOf(player));
|
||||
players.remove(player->getPlayerId());
|
||||
broadcastEvent("leave", player);
|
||||
disconnect(player, 0, this, 0);
|
||||
delete player;
|
||||
|
||||
if (!players.size())
|
||||
deleteLater();
|
||||
|
@ -171,12 +165,14 @@ void ServerGame::setActivePlayer(int _activePlayer)
|
|||
|
||||
void ServerGame::setActivePhase(int _activePhase)
|
||||
{
|
||||
for (int i = 0; i < players.size(); ++i) {
|
||||
QMapIterator<int, Arrow *> arrowIterator(players[i]->getArrows());
|
||||
while (arrowIterator.hasNext()) {
|
||||
Arrow *a = arrowIterator.next().value();
|
||||
broadcastEvent(QString("delete_arrow|%1").arg(a->getId()), players[i]);
|
||||
players[i]->deleteArrow(a->getId());
|
||||
QMapIterator<int, Player *> playerIterator(players);
|
||||
while (playerIterator.hasNext()) {
|
||||
Player *player = playerIterator.next().value();
|
||||
QList<Arrow *> toDelete = player->getArrows().values();
|
||||
for (int i = 0; i < toDelete.size(); ++i) {
|
||||
Arrow *a = toDelete[i];
|
||||
broadcastEvent(QString("delete_arrow|%1").arg(a->getId()), player);
|
||||
player->deleteArrow(a->getId());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,15 +22,16 @@
|
|||
|
||||
#include <QStringList>
|
||||
#include <QPointer>
|
||||
#include "player.h"
|
||||
#include "returnmessage.h"
|
||||
#include "serversocket.h"
|
||||
|
||||
class ServerGame : public QObject {
|
||||
Q_OBJECT
|
||||
private:
|
||||
QPointer<ServerSocket> creator;
|
||||
QList<ServerSocket *> players;
|
||||
QList<ServerSocket *> spectators;
|
||||
QPointer<Player> creator;
|
||||
QMap<int, Player *> players;
|
||||
QList<Player *> spectators;
|
||||
bool gameStarted;
|
||||
int gameId;
|
||||
QString description;
|
||||
|
@ -40,16 +41,14 @@ private:
|
|||
bool spectatorsAllowed;
|
||||
signals:
|
||||
void gameClosing();
|
||||
public slots:
|
||||
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(const QString &_creator, int _gameId, const QString &_description, const QString &_password, int _maxPlayers, bool _spectatorsAllowed, QObject *parent = 0);
|
||||
~ServerGame();
|
||||
ServerSocket *getCreator() const { return creator; }
|
||||
Player *getCreator() const { return creator; }
|
||||
bool getGameStarted() const { return gameStarted; }
|
||||
int getPlayerCount() const { return players.size(); }
|
||||
const QList<ServerSocket *> &getPlayers() const { return players; }
|
||||
ServerSocket *getPlayer(int playerId);
|
||||
QList<Player *> getPlayers() const { return players.values(); }
|
||||
Player *getPlayer(int playerId) const { return players.value(playerId, 0); }
|
||||
int getGameId() const { return gameId; }
|
||||
QString getDescription() const { return description; }
|
||||
QString getPassword() const { return password; }
|
||||
|
@ -57,13 +56,15 @@ public:
|
|||
bool getSpectatorsAllowed() const { return spectatorsAllowed; }
|
||||
QString getGameListLine() const;
|
||||
ReturnMessage::ReturnCode checkJoin(const QString &_password, bool spectator);
|
||||
void addPlayer(ServerSocket *player, bool spectator);
|
||||
void removePlayer(ServerSocket *player);
|
||||
Player *addPlayer(const QString &playerName, bool spectator);
|
||||
void removePlayer(Player *player);
|
||||
void startGameIfReady();
|
||||
int getActivePlayer() const { return activePlayer; }
|
||||
int getActivePhase() const { return activePhase; }
|
||||
void setActivePlayer(int _activePlayer);
|
||||
void setActivePhase(int _activePhase);
|
||||
|
||||
void broadcastEvent(const QString &eventStr, Player *player);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -28,12 +28,11 @@
|
|||
|
||||
class Server;
|
||||
class ServerGame;
|
||||
class Player;
|
||||
class PlayerZone;
|
||||
class Counter;
|
||||
class Arrow;
|
||||
|
||||
enum PlayerStatusEnum { StatusNormal, StatusSubmitDeck, StatusReadyStart, StatusPlaying };
|
||||
|
||||
class ServerSocket : public QTcpSocket
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -41,92 +40,112 @@ private slots:
|
|||
void readClient();
|
||||
void catchSocketError(QAbstractSocket::SocketError socketError);
|
||||
signals:
|
||||
void createGame(const QString description, const QString password, int maxPlayers, bool spectatorsAllowed, ServerSocket *creator);
|
||||
void commandReceived(QString cmd, ServerSocket *player);
|
||||
void broadcastEvent(const QString &event, ServerSocket *player);
|
||||
void startGameIfReady();
|
||||
private:
|
||||
typedef ReturnMessage::ReturnCode (ServerSocket::*CommandHandler)(const QList<QVariant> &);
|
||||
typedef ReturnMessage::ReturnCode (ServerSocket::*GameCommandHandler)(ServerGame *game, Player *player, const QList<QVariant> &);
|
||||
typedef ReturnMessage::ReturnCode (ServerSocket::*ChatCommandHandler)(ChatChannel *channel, const QList<QVariant> &);
|
||||
typedef ReturnMessage::ReturnCode (ServerSocket::*GenericCommandHandler)(const QList<QVariant> &);
|
||||
|
||||
class CommandProperties {
|
||||
public:
|
||||
enum CommandType { ChatCommand, GameCommand, GenericCommand };
|
||||
private:
|
||||
CommandType type;
|
||||
bool needsLogin;
|
||||
bool needsGame;
|
||||
QList<QVariant::Type> paramTypes;
|
||||
protected:
|
||||
QList<QVariant> getParamList(const QStringList ¶ms) const;
|
||||
public:
|
||||
CommandProperties(CommandType _type, bool _needsLogin, const QList<QVariant::Type> &_paramTypes)
|
||||
: type(_type), needsLogin(_needsLogin), paramTypes(_paramTypes) { }
|
||||
bool getNeedsLogin() const { return needsLogin; }
|
||||
CommandType getType() const { return type; }
|
||||
const QList<QVariant::Type> &getParamTypes() const { return paramTypes; }
|
||||
virtual ReturnMessage::ReturnCode exec(ServerSocket *s, QStringList ¶ms) = 0;
|
||||
};
|
||||
class ChatCommandProperties : public CommandProperties {
|
||||
private:
|
||||
ChatCommandHandler handler;
|
||||
public:
|
||||
ChatCommandProperties(const QList<QVariant::Type> &_paramTypes, ChatCommandHandler _handler)
|
||||
: CommandProperties(ChatCommand, true, _paramTypes), handler(_handler) { }
|
||||
ReturnMessage::ReturnCode exec(ServerSocket *s, QStringList ¶ms);
|
||||
};
|
||||
class GameCommandProperties : public CommandProperties {
|
||||
private:
|
||||
bool needsStartedGame;
|
||||
bool allowedToSpectator;
|
||||
QList<QVariant::Type> paramTypes;
|
||||
CommandHandler handler;
|
||||
GameCommandHandler handler;
|
||||
public:
|
||||
CommandProperties(bool _needsLogin = false, bool _needsGame = false, bool _needsStartedGame = false, bool _allowedToSpectator = false, const QList<QVariant::Type> &_paramTypes = QList<QVariant::Type>(), CommandHandler _handler = 0)
|
||||
: needsLogin(_needsLogin), needsGame(_needsGame), needsStartedGame(_needsStartedGame), allowedToSpectator(_allowedToSpectator), paramTypes(_paramTypes), handler(_handler) { }
|
||||
bool getNeedsLogin() const { return needsLogin; }
|
||||
bool getNeedsGame() const { return needsGame; }
|
||||
GameCommandProperties(bool _needsStartedGame, bool _allowedToSpectator, const QList<QVariant::Type> &_paramTypes, GameCommandHandler _handler)
|
||||
: CommandProperties(GameCommand, true, _paramTypes), needsStartedGame(_needsStartedGame), allowedToSpectator(_allowedToSpectator), handler(_handler) { }
|
||||
bool getNeedsStartedGame() const { return needsStartedGame; }
|
||||
bool getAllowedToSpectator() const { return allowedToSpectator; }
|
||||
const QList<QVariant::Type> &getParamTypes() const { return paramTypes; }
|
||||
CommandHandler getHandler() const { return handler; }
|
||||
ReturnMessage::ReturnCode exec(ServerSocket *s, QStringList ¶ms);
|
||||
};
|
||||
static QHash<QString, CommandProperties> commandHash;
|
||||
class GenericCommandProperties : public CommandProperties {
|
||||
private:
|
||||
GenericCommandHandler handler;
|
||||
public:
|
||||
GenericCommandProperties(bool _needsLogin, const QList<QVariant::Type> &_paramTypes, GenericCommandHandler _handler)
|
||||
: CommandProperties(GenericCommand, _needsLogin, _paramTypes), handler(_handler) { }
|
||||
ReturnMessage::ReturnCode exec(ServerSocket *s, QStringList ¶ms);
|
||||
};
|
||||
static QHash<QString, CommandProperties *> commandHash;
|
||||
|
||||
QStringList listPlayersHelper();
|
||||
QStringList listZonesHelper(ServerSocket *player);
|
||||
QStringList dumpZoneHelper(ServerSocket *player, PlayerZone *zone, int numberCards);
|
||||
QStringList listCountersHelper(ServerSocket *player);
|
||||
QStringList listArrowsHelper(ServerSocket *player);
|
||||
QStringList listPlayersHelper(ServerGame *game, Player *player);
|
||||
QStringList listZonesHelper(Player *player);
|
||||
QStringList dumpZoneHelper(Player *player, PlayerZone *zone, int numberCards);
|
||||
QStringList listCountersHelper(Player *player);
|
||||
QStringList listArrowsHelper(Player *player);
|
||||
|
||||
ReturnMessage::ReturnCode cmdPing(const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdLogin(const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdChatListChannels(const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdChatJoinChannel(const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdChatLeaveChannel(const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdChatSay(const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdListGames(const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdCreateGame(const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdJoinGame(const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdLeaveGame(const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdListPlayers(const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdSay(const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdSubmitDeck(const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdReadyStart(const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdShuffle(const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdDrawCards(const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdRevealCard(const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdMoveCard(const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdCreateToken(const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdCreateArrow(const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdDeleteArrow(const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdSetCardAttr(const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdIncCounter(const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdAddCounter(const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdSetCounter(const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdDelCounter(const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdListCounters(const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdListZones(const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdDumpZone(const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdStopDumpZone(const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdRollDie(const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdNextTurn(const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdSetActivePhase(const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdDumpAll(const QList<QVariant> ¶ms);
|
||||
|
||||
ReturnMessage::ReturnCode cmdChatLeaveChannel(ChatChannel *channel, const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdChatSay(ChatChannel *channel, const QList<QVariant> ¶ms);
|
||||
|
||||
ReturnMessage::ReturnCode cmdLeaveGame(ServerGame *game, Player *player, const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdListPlayers(ServerGame *game, Player *player, const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdSay(ServerGame *game, Player *player, const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdSubmitDeck(ServerGame *game, Player *player, const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdReadyStart(ServerGame *game, Player *player, const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdShuffle(ServerGame *game, Player *player, const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdDrawCards(ServerGame *game, Player *player, const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdRevealCard(ServerGame *game, Player *player, const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdMoveCard(ServerGame *game, Player *player, const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdCreateToken(ServerGame *game, Player *player, const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdCreateArrow(ServerGame *game, Player *player, const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdDeleteArrow(ServerGame *game, Player *player, const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdSetCardAttr(ServerGame *game, Player *player, const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdIncCounter(ServerGame *game, Player *player, const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdAddCounter(ServerGame *game, Player *player, const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdSetCounter(ServerGame *game, Player *player, const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdDelCounter(ServerGame *game, Player *player, const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdListCounters(ServerGame *game, Player *player, const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdListZones(ServerGame *game, Player *player, const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdDumpZone(ServerGame *game, Player *player, const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdStopDumpZone(ServerGame *game, Player *player, const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdRollDie(ServerGame *game, Player *player, const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdNextTurn(ServerGame *game, Player *player, const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdSetActivePhase(ServerGame *game, Player *player, const QList<QVariant> ¶ms);
|
||||
ReturnMessage::ReturnCode cmdDumpAll(ServerGame *game, Player *player, const QList<QVariant> ¶ms);
|
||||
|
||||
Server *server;
|
||||
ServerGame *game;
|
||||
QList<ChatChannel *> chatChannels;
|
||||
QList<QString> DeckList;
|
||||
QList<QString> SideboardList;
|
||||
QList<PlayerZone *> zones;
|
||||
QMap<int, Counter *> counters;
|
||||
QMap<int, Arrow *> arrows;
|
||||
int playerId;
|
||||
QMap<int, QPair<ServerGame *, Player *> > games;
|
||||
QMap<QString, ChatChannel *> chatChannels;
|
||||
QString playerName;
|
||||
bool spectator;
|
||||
int nextCardId;
|
||||
int newCardId();
|
||||
int newCounterId() const;
|
||||
int newArrowId() const;
|
||||
PlayerZone *getZone(const QString &name) const;
|
||||
void clearZones();
|
||||
bool parseCommand(QString line);
|
||||
PlayerStatusEnum PlayerStatus;
|
||||
|
||||
Server *getServer() const { return server; }
|
||||
QPair<ServerGame *, Player *> getGame(int gameId) const;
|
||||
|
||||
bool parseCommand(const QString &line);
|
||||
ReturnMessage *remsg;
|
||||
AuthenticationResult authState;
|
||||
bool acceptsGameListChanges;
|
||||
|
@ -135,24 +154,10 @@ public:
|
|||
ServerSocket(Server *_server, QObject *parent = 0);
|
||||
~ServerSocket();
|
||||
void msg(const QString &s);
|
||||
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();
|
||||
int getPlayerId() const { return playerId; }
|
||||
void setPlayerId(int _id) { playerId = _id; }
|
||||
bool getSpectator() const { return spectator; }
|
||||
QString getPlayerName() const { return playerName; }
|
||||
bool getAcceptsGameListChanges() const { return acceptsGameListChanges; }
|
||||
bool getAcceptsChatChannelListChanges() const { return acceptsChatChannelListChanges; }
|
||||
const QList<PlayerZone *> &getZones() const { return zones; }
|
||||
const QMap<int, Counter *> &getCounters() const { return counters; }
|
||||
const QMap<int, Arrow *> &getArrows() const { return arrows; }
|
||||
bool deleteArrow(int arrowId);
|
||||
void setupZones();
|
||||
const QString &getPlayerName() const { return playerName; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue