This commit is contained in:
Max-Wilhelm Bruker 2009-10-29 17:13:37 +01:00
parent d329376e93
commit 1c2aa15b22
38 changed files with 638 additions and 1651 deletions

3
common/.directory Normal file
View file

@ -0,0 +1,3 @@
[Dolphin]
Timestamp=2009,10,26,13,45,44
ViewMode=1

View file

@ -1,16 +0,0 @@
######################################################################
# Automatically generated by qmake (2.01a) So. Okt 25 12:02:12 2009
######################################################################
TEMPLATE = app
TARGET =
DEPENDPATH += .
INCLUDEPATH += .
MOC_DIR = build
OBJECTS_DIR = build
# Input
HEADERS += protocol.h widget.h protocol_items.h
SOURCES += main.cpp protocol.cpp widget.cpp protocol_items.cpp
CONFIG += qt debug

View file

@ -1,17 +0,0 @@
#include <QApplication>
#include <QTextCodec>
#include "widget.h"
int main(int argc, char *argv[])
{
// qInstallMsgHandler(myMessageOutput);
QApplication app(argc, argv);
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
Widget *widget = new Widget;
widget->show();
return app.exec();
}

View file

@ -63,6 +63,9 @@ ProtocolItem *ProtocolItem::getNewItem(const QString &name)
void ProtocolItem::initializeHash()
{
if (!itemNameHash.isEmpty())
return;
initializeHashAuto();
itemNameHash.insert("resp", ProtocolResponse::newItem);
ProtocolResponse::initializeHash();

View file

@ -28,6 +28,7 @@ protected:
private:
static void initializeHashAuto();
public:
static const int protocolVersion = 4;
ProtocolItem(const QString &_itemName);
static void initializeHash();
static ProtocolItem *getNewItem(const QString &name);
@ -36,6 +37,7 @@ public:
};
class Command : public ProtocolItem {
Q_OBJECT
private:
int cmdId;
static int lastCmdId;

4
common/rng_abstract.cpp Normal file
View file

@ -0,0 +1,4 @@
#include "rng_abstract.h"
#include "rng_qt.h"
RNG_Abstract *rng = new RNG_Qt;

15
common/rng_abstract.h Normal file
View file

@ -0,0 +1,15 @@
#ifndef RNG_ABSTRACT_H
#define RNG_ABSTRACT_H
#include <QObject>
class RNG_Abstract : public QObject {
Q_OBJECT
public:
RNG_Abstract(QObject *parent = 0) : QObject(parent) { }
virtual unsigned int getNumber(unsigned int min, unsigned int max) = 0;
};
extern RNG_Abstract *rng;
#endif

17
common/rng_qt.cpp Normal file
View file

@ -0,0 +1,17 @@
#include "rng_qt.h"
#include <QDateTime>
#include <stdlib.h>
RNG_Qt::RNG_Qt(QObject *parent)
: RNG_Abstract(parent)
{
int seed = QDateTime::currentDateTime().toTime_t();
qDebug(QString("qsrand(%1)").arg(seed).toLatin1());
qsrand(seed);
}
unsigned int RNG_Qt::getNumber(unsigned int min, unsigned int max)
{
int r = qrand();
return min + (unsigned int) (((double) (max + 1 - min)) * r / (RAND_MAX + 1.0));
}

13
common/rng_qt.h Normal file
View file

@ -0,0 +1,13 @@
#ifndef RNG_QT_H
#define RNG_QT_H
#include "rng_abstract.h"
class RNG_Qt : public RNG_Abstract {
Q_OBJECT
public:
RNG_Qt(QObject *parent = 0);
unsigned int getNumber(unsigned int min, unsigned int max);
};
#endif

89
common/server.cpp Normal file
View file

@ -0,0 +1,89 @@
/***************************************************************************
* Copyright (C) 2008 by Max-Wilhelm Bruker *
* brukie@laptop *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "server.h"
#include "server_game.h"
#include "server_counter.h"
#include "server_chatchannel.h"
Server::Server(QObject *parent)
: QObject(parent), nextGameId(0)
{
}
Server::~Server()
{
}
Server_Game *Server::createGame(const QString &description, const QString &password, int maxPlayers, bool spectatorsAllowed, const QString &creator)
{
Server_Game *newGame = new Server_Game(creator, nextGameId++, description, password, maxPlayers, spectatorsAllowed, this);
games.insert(newGame->getGameId(), newGame);
connect(newGame, SIGNAL(gameClosing()), this, SLOT(gameClosing()));
broadcastGameListUpdate(newGame);
return newGame;
}
void Server::addClient(Server_ProtocolHandler *client)
{
clients << client;
}
void Server::removeClient(Server_ProtocolHandler *client)
{
clients.removeAt(clients.indexOf(client));
qDebug(QString("Server::removeClient: %1 clients left").arg(clients.size()).toLatin1());
}
Server_Game *Server::getGame(int gameId) const
{
return games.value(gameId);
}
void Server::broadcastGameListUpdate(Server_Game *game)
{
/* QString line = game->getGameListLine();
for (int i = 0; i < clients.size(); i++)
if (clients[i]->getAcceptsGameListChanges())
clients[i]->msg(line);
*/}
void Server::broadcastChannelUpdate()
{
/* QString line = qobject_cast<Server_ChatChannel *>(sender())->getChannelListLine();
for (int i = 0; i < players.size(); ++i)
if (players[i]->getAcceptsChatChannelListChanges())
players[i]->msg(line);
*/}
void Server::gameClosing()
{
qDebug("Server::gameClosing");
Server_Game *game = static_cast<Server_Game *>(sender());
broadcastGameListUpdate(game);
games.remove(games.key(game));
}
void Server::addChatChannel(Server_ChatChannel *newChannel)
{
chatChannels.insert(newChannel->getName(), newChannel);
connect(newChannel, SIGNAL(channelInfoChanged()), this, SLOT(broadcastChannelUpdate()));
}

42
common/server.h Normal file
View file

@ -0,0 +1,42 @@
#ifndef SERVER_H
#define SERVER_H
#include <QObject>
#include <QStringList>
#include <QMap>
class Server_Game;
class Server_ChatChannel;
class Server_ProtocolHandler;
enum AuthenticationResult { PasswordWrong = 0, PasswordRight = 1, UnknownUser = 2 };
class Server : public QObject
{
Q_OBJECT
private slots:
void gameClosing();
void broadcastChannelUpdate();
public:
Server(QObject *parent = 0);
~Server();
virtual AuthenticationResult checkUserPassword(const QString &user, const QString &password) = 0;
QList<Server_Game *> getGames() const { return games.values(); }
Server_Game *getGame(int gameId) const;
const QMap<QString, Server_ChatChannel *> &getChatChannels() { return chatChannels; }
void broadcastGameListUpdate(Server_Game *game);
void addClient(Server_ProtocolHandler *player);
void removeClient(Server_ProtocolHandler *player);
virtual QStringList getLoginMessage() const = 0;
Server_Game *createGame(const QString &description, const QString &password, int maxPlayers, bool spectatorsAllowed, const QString &playerName);
private:
QMap<int, Server_Game *> games;
QList<Server_ProtocolHandler *> clients;
QMap<QString, Server_ChatChannel *> chatChannels;
protected:
int nextGameId;
void addChatChannel(Server_ChatChannel *newChannel);
};
#endif

20
common/server_arrow.h Normal file
View file

@ -0,0 +1,20 @@
#ifndef SERVER_ARROW_H
#define SERVER_ARROW_H
class Server_Card;
class Server_Arrow {
private:
int id;
Server_Card *startCard, *targetCard;
int color;
public:
Server_Arrow(int _id, Server_Card *_startCard, Server_Card *_targetCard, int _color)
: id(_id), startCard(_startCard), targetCard(_targetCard), color(_color) { }
int getId() const { return id; }
Server_Card *getStartCard() const { return startCard; }
Server_Card *getTargetCard() const { return targetCard; }
int getColor() const { return color; }
};
#endif

67
common/server_card.cpp Normal file
View file

@ -0,0 +1,67 @@
/***************************************************************************
* Copyright (C) 2008 by Max-Wilhelm Bruker *
* brukie@laptop *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "server_card.h"
Server_Card::Server_Card(QString _name, int _id, int _coord_x, int _coord_y)
: id(_id), coord_x(_coord_x), coord_y(_coord_y), name(_name), counters(0), tapped(false), attacking(false), facedown(false), annotation(QString()), doesntUntap(false)
{
}
Server_Card::~Server_Card()
{
}
void Server_Card::resetState()
{
setCoords(0, 0);
setCounters(0);
setTapped(false);
setAttacking(false);
setFaceDown(false);
setAnnotation(QString());
setDoesntUntap(false);
}
bool Server_Card::setAttribute(const QString &aname, const QString &avalue, bool allCards)
{
if (aname == "counters") {
bool ok;
int tmp_int = avalue.toInt(&ok);
if (!ok)
return false;
setCounters(tmp_int);
} else if (aname == "tapped") {
bool value = avalue == "1";
if (!(!value && allCards && doesntUntap))
setTapped(value);
} else if (aname == "attacking") {
setAttacking(avalue == "1");
} else if (aname == "facedown") {
setFaceDown(avalue == "1");
} else if (aname == "annotation") {
setAnnotation(avalue);
} else if (aname == "doesnt_untap") {
setDoesntUntap(avalue == "1");
} else
return false;
return true;
}

71
common/server_card.h Normal file
View file

@ -0,0 +1,71 @@
/***************************************************************************
* Copyright (C) 2008 by Max-Wilhelm Bruker *
* brukie@laptop *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef SERVER_CARD_H
#define SERVER_CARD_H
#include <QString>
class Server_CardZone;
class Server_Card {
private:
Server_CardZone *zone;
int id;
int coord_x, coord_y;
QString name;
int counters;
bool tapped;
bool attacking;
bool facedown;
QString annotation;
bool doesntUntap;
public:
Server_Card(QString _name, int _id, int _coord_x, int _coord_y);
~Server_Card();
Server_CardZone *getZone() const { return zone; }
void setZone(Server_CardZone *_zone) { zone = _zone; }
int getId() const { return id; }
int getX() const { return coord_x; }
int getY() const { return coord_y; }
QString getName() const { return name; }
int getCounters() const { return counters; }
bool getTapped() const { return tapped; }
bool getAttacking() const { return attacking; }
bool getFaceDown() const { return facedown; }
QString getAnnotation() const { return annotation; }
bool getDoesntUntap() const { return doesntUntap; }
void setId(int _id) { id = _id; }
void setCoords(int x, int y) { coord_x = x; coord_y = y; }
void setName(const QString &_name) { name = _name; }
void setCounters(int _counters) { counters = _counters; }
void setTapped(bool _tapped) { tapped = _tapped; }
void setAttacking(bool _attacking) { attacking = _attacking; }
void setFaceDown(bool _facedown) { facedown = _facedown; }
void setAnnotation(const QString &_annotation) { annotation = _annotation; }
void setDoesntUntap(bool _doesntUntap) { doesntUntap = _doesntUntap; }
void resetState();
bool setAttribute(const QString &aname, const QString &avalue, bool allCards);
};
#endif

View file

@ -0,0 +1,93 @@
/***************************************************************************
* Copyright (C) 2008 by Max-Wilhelm Bruker *
* brukie@laptop *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "server_cardzone.h"
#include "server_card.h"
#include "rng_abstract.h"
Server_CardZone::Server_CardZone(Server_Player *_player, const QString &_name, bool _has_coords, ZoneType _type)
: player(_player), name(_name), has_coords(_has_coords), type(_type), cardsBeingLookedAt(0)
{
}
Server_CardZone::~Server_CardZone()
{
qDebug(QString("Server_CardZone destructor: %1").arg(name).toLatin1());
clear();
}
void Server_CardZone::shuffle()
{
QList<Server_Card *> temp;
for (int i = cards.size(); i; i--)
temp.append(cards.takeAt(rng->getNumber(0, i - 1)));
cards = temp;
}
Server_Card *Server_CardZone::getCard(int id, bool remove, int *position)
{
if (type != HiddenZone) {
QListIterator<Server_Card *> CardIterator(cards);
int i = 0;
while (CardIterator.hasNext()) {
Server_Card *tmp = CardIterator.next();
if (tmp->getId() == id) {
if (remove) {
cards.removeAt(i);
tmp->setZone(0);
}
if (position)
*position = i;
return tmp;
}
i++;
}
return NULL;
} else {
if ((id >= cards.size()) || (id < 0))
return NULL;
Server_Card *tmp = cards[id];
if (remove) {
cards.removeAt(id);
tmp->setZone(0);
}
if (position)
*position = id;
return tmp;
}
}
void Server_CardZone::insertCard(Server_Card *card, int x, int y)
{
if (hasCoords()) {
card->setCoords(x, y);
cards.append(card);
} else {
card->setCoords(0, 0);
cards.insert(x, card);
}
card->setZone(this);
}
void Server_CardZone::clear()
{
for (int i = 0; i < cards.size(); i++)
delete cards.at(i);
cards.clear();
}

65
common/server_cardzone.h Normal file
View file

@ -0,0 +1,65 @@
/***************************************************************************
* Copyright (C) 2008 by Max-Wilhelm Bruker *
* brukie@laptop *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef SERVER_CARDZONE_H
#define SERVER_CARDZONE_H
#include <QList>
#include <QString>
class Server_Card;
class Server_Player;
class Server_CardZone {
public:
// PrivateZone: Contents of the zone are always visible to the owner,
// but not to anyone else.
// PublicZone: Contents of the zone are always visible to anyone.
// HiddenZone: Contents of the zone are never visible to anyone.
// However, the owner of the zone can issue a dump_zone command,
// setting beingLookedAt to true.
// Cards in a zone with the type HiddenZone are referenced by their
// list index, whereas cards in any other zone are referenced by their ids.
enum ZoneType { PrivateZone, PublicZone, HiddenZone };
private:
Server_Player *player;
QString name;
bool has_coords;
ZoneType type;
int cardsBeingLookedAt;
public:
Server_CardZone(Server_Player *_player, const QString &_name, bool _has_coords, ZoneType _type);
~Server_CardZone();
Server_Card *getCard(int id, bool remove, int *position = NULL);
int getCardsBeingLookedAt() const { return cardsBeingLookedAt; }
void setCardsBeingLookedAt(int _cardsBeingLookedAt) { cardsBeingLookedAt = _cardsBeingLookedAt; }
bool hasCoords() const { return has_coords; }
ZoneType getType() const { return type; }
QString getName() const { return name; }
Server_Player *getPlayer() const { return player; }
QList<Server_Card *> cards;
void insertCard(Server_Card *card, int x, int y);
void shuffle();
void clear();
};
#endif

View file

@ -0,0 +1,46 @@
#include "server_chatchannel.h"
#include "server_protocolhandler.h"
Server_ChatChannel::Server_ChatChannel(const QString &_name, const QString &_description, bool _autoJoin, const QStringList &_joinMessage)
: name(_name), description(_description), autoJoin(_autoJoin), joinMessage(_joinMessage)
{
}
void Server_ChatChannel::addClient(Server_ProtocolHandler *client)
{
/* QString str = QString("chat|join_channel|%1|%2").arg(name).arg(player->getPlayerName());
for (int i = 0; i < size(); ++i)
at(i)->msg(str);
append(player);
for (int i = 0; i < size(); ++i)
player->msg(QString("chat|list_players|%1|%2").arg(name).arg(at(i)->getPlayerName()));
for (int i = 0; i < joinMessage.size(); ++i)
player->msg(QString("chat|server_message|%1|%2").arg(name).arg(joinMessage[i]));
emit channelInfoChanged();
*/}
void Server_ChatChannel::removeClient(Server_ProtocolHandler *client)
{
/* QString str = QString("chat|leave_channel|%1|%2").arg(name).arg(player->getPlayerName());
removeAt(indexOf(player));
for (int i = 0; i < size(); ++i)
at(i)->msg(str);
emit channelInfoChanged();
*/}
void Server_ChatChannel::say(Server_ProtocolHandler *client, const QString &s)
{
/* QString str = QString("chat|say|%1|%2|%3").arg(name).arg(player->getPlayerName()).arg(s);
for (int i = 0; i < size(); ++i)
at(i)->msg(str);
*/}
QString Server_ChatChannel::getChannelListLine() const
{
// return QString("chat|list_channels|%1|%2|%3|%4").arg(name).arg(description).arg(size()).arg(autoJoin ? 1 : 0);
}

View file

@ -0,0 +1,30 @@
#ifndef CHATCHANNEL_H
#define CHATCHANNEL_H
#include <QList>
#include <QObject>
#include <QStringList>
class Server_ProtocolHandler;
class Server_ChatChannel : public QObject, public QList<Server_ProtocolHandler *> {
Q_OBJECT
signals:
void channelInfoChanged();
private:
QString name;
QString description;
bool autoJoin;
QStringList joinMessage;
public:
Server_ChatChannel(const QString &_name, const QString &_description, bool _autoJoin, const QStringList &_joinMessage);
QString getName() const { return name; }
QString getDescription() const { return description; }
bool getAutoJoin() const { return autoJoin; }
void addClient(Server_ProtocolHandler *client);
void removeClient(Server_ProtocolHandler *client);
void say(Server_ProtocolHandler *client, const QString &s);
QString getChannelListLine() const;
};
#endif

43
common/server_counter.h Normal file
View file

@ -0,0 +1,43 @@
/***************************************************************************
* Copyright (C) 2008 by Max-Wilhelm Bruker *
* brukie@laptop *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef SERVER_COUNTER_H
#define SERVER_COUNTER_H
#include <QString>
class Server_Counter {
protected:
int id;
QString name;
int color;
int radius;
int count;
public:
Server_Counter(int _id, const QString &_name, int _color, int _radius, int _count = 0) : id(_id), name(_name), color(_color), radius(_radius), count(_count) { }
~Server_Counter() { }
int getId() const { return id; }
QString getName() const { return name; }
int getColor() const { return color; }
int getRadius() const { return radius; }
int getCount() const { return count; }
void setCount(int _count) { count = _count; }
};
#endif

181
common/server_game.cpp Normal file
View file

@ -0,0 +1,181 @@
/***************************************************************************
* Copyright (C) 2008 by Max-Wilhelm Bruker *
* brukie@laptop *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "server.h"
#include "server_game.h"
#include "server_protocolhandler.h"
#include "server_arrow.h"
#include <QSqlQuery>
Server_Game::Server_Game(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);
}
Server_Game::~Server_Game()
{
broadcastEvent("game_closed", 0);
QMapIterator<int, Server_Player *> playerIterator(players);
while (playerIterator.hasNext())
delete playerIterator.next().value();
players.clear();
for (int i = 0; i < spectators.size(); ++i)
delete spectators[i];
spectators.clear();
emit gameClosing();
qDebug("Server_Game destructor");
}
QString Server_Game::getGameListLine() const
{
if (players.isEmpty())
return QString("list_games|%1|||0|%2||0|0").arg(gameId).arg(maxPlayers);
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(creatorName)
.arg(spectatorsAllowed ? 1 : 0)
.arg(spectators.size());
}
}
void Server_Game::broadcastEvent(const QString &eventStr, Server_Player *player)
{
QList<Server_Player *> allClients = QList<Server_Player *>() << players.values() << spectators;
for (int i = 0; i < allClients.size(); ++i)
allClients[i]->publicEvent(eventStr, player);
}
void Server_Game::startGameIfReady()
{
if (players.size() < maxPlayers)
return;
QMapIterator<int, Server_Player *> playerIterator(players);
while (playerIterator.hasNext())
if (playerIterator.next().value()->getStatus() != StatusReadyStart)
return;
/* QSqlQuery query;
query.prepare("insert into games (id, descr, password, time_started) values(:id, :descr, :password, now())");
query.bindValue(":id", gameId);
query.bindValue(":descr", description);
query.bindValue(":password", !password.isEmpty());
query.exec();
QMapIterator<int, Server_Player *> playerIterator2(players);
while (playerIterator2.hasNext()) {
Server_Player *player = playerIterator2.next().value();
query.prepare("insert into games_players (id_game, player) values(:id, :player)");
query.bindValue(":id", gameId);
query.bindValue(":player", player->getPlayerName());
query.exec();
player->setupZones();
}
*/
gameStarted = true;
broadcastEvent("game_start", NULL);
setActivePlayer(0);
}
ReturnMessage::ReturnCode Server_Game::checkJoin(const QString &_password, bool spectator)
{
if (_password != password)
return ReturnMessage::ReturnPasswordWrong;
if (spectator) {
if (!spectatorsAllowed)
return ReturnMessage::ReturnSpectatorsNotAllowed;
} else if (gameStarted || (getPlayerCount() >= getMaxPlayers()))
return ReturnMessage::ReturnContextError;
return ReturnMessage::ReturnOk;
}
Server_Player *Server_Game::addPlayer(const QString &playerName, bool spectator)
{
int playerId;
if (!spectator) {
int max = -1;
QMapIterator<int, Server_Player *> i(players);
while (i.hasNext()) {
int tmp = i.next().value()->getPlayerId();
if (tmp > max)
max = tmp;
}
playerId = max + 1;
} else
playerId = -1;
Server_Player *newPlayer = new Server_Player(this, playerId, playerName, spectator);
broadcastEvent(QString("join|%1").arg(spectator ? 1 : 0), newPlayer);
if (spectator)
spectators << newPlayer;
else
players.insert(playerId, newPlayer);
qobject_cast<Server *>(parent())->broadcastGameListUpdate(this);
return newPlayer;
}
void Server_Game::removePlayer(Server_Player *player)
{
if (player->getSpectator())
spectators.removeAt(spectators.indexOf(player));
else
players.remove(player->getPlayerId());
broadcastEvent("leave", player);
delete player;
if (!players.size())
deleteLater();
qobject_cast<Server *>(parent())->broadcastGameListUpdate(this);
}
void Server_Game::setActivePlayer(int _activePlayer)
{
activePlayer = _activePlayer;
broadcastEvent(QString("set_active_player|%1").arg(_activePlayer), NULL);
setActivePhase(0);
}
void Server_Game::setActivePhase(int _activePhase)
{
QMapIterator<int, Server_Player *> playerIterator(players);
while (playerIterator.hasNext()) {
Server_Player *player = playerIterator.next().value();
QList<Server_Arrow *> toDelete = player->getArrows().values();
for (int i = 0; i < toDelete.size(); ++i) {
Server_Arrow *a = toDelete[i];
broadcastEvent(QString("delete_arrow|%1").arg(a->getId()), player);
player->deleteArrow(a->getId());
}
}
activePhase = _activePhase;
broadcastEvent(QString("set_active_phase|%1").arg(_activePhase), NULL);
}

70
common/server_game.h Normal file
View file

@ -0,0 +1,70 @@
/***************************************************************************
* Copyright (C) 2008 by Max-Wilhelm Bruker *
* brukie@laptop *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef SERVERGAME_H
#define SERVERGAME_H
#include <QStringList>
#include <QPointer>
#include <QObject>
#include "server_player.h"
#include "returnmessage.h"
class Server_Game : public QObject {
Q_OBJECT
private:
QPointer<Server_Player> creator;
QMap<int, Server_Player *> players;
QList<Server_Player *> spectators;
bool gameStarted;
int gameId;
QString description;
QString password;
int maxPlayers;
int activePlayer, activePhase;
bool spectatorsAllowed;
signals:
void gameClosing();
public:
Server_Game(const QString &_creator, int _gameId, const QString &_description, const QString &_password, int _maxPlayers, bool _spectatorsAllowed, QObject *parent = 0);
~Server_Game();
Server_Player *getCreator() const { return creator; }
bool getGameStarted() const { return gameStarted; }
int getPlayerCount() const { return players.size(); }
QList<Server_Player *> getPlayers() const { return players.values(); }
Server_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; }
int getMaxPlayers() const { return maxPlayers; }
bool getSpectatorsAllowed() const { return spectatorsAllowed; }
QString getGameListLine() const;
ReturnMessage::ReturnCode checkJoin(const QString &_password, bool spectator);
Server_Player *addPlayer(const QString &playerName, bool spectator);
void removePlayer(Server_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, Server_Player *player);
};
#endif

148
common/server_player.cpp Normal file
View file

@ -0,0 +1,148 @@
#include "server_player.h"
#include "server_card.h"
#include "server_counter.h"
#include "server_arrow.h"
#include "server_cardzone.h"
#include "server_game.h"
Server_Player::Server_Player(Server_Game *_game, int _playerId, const QString &_playerName, bool _spectator)
: game(_game), socket(0), playerId(_playerId), playerName(_playerName), spectator(_spectator), nextCardId(0), PlayerStatus(StatusNormal)
{
}
int Server_Player::newCardId()
{
return nextCardId++;
}
int Server_Player::newCounterId() const
{
int id = 0;
QMapIterator<int, Server_Counter *> i(counters);
while (i.hasNext()) {
Server_Counter *c = i.next().value();
if (c->getId() > id)
id = c->getId();
}
return id + 1;
}
int Server_Player::newArrowId() const
{
int id = 0;
QMapIterator<int, Server_Arrow *> i(arrows);
while (i.hasNext()) {
Server_Arrow *a = i.next().value();
if (a->getId() > id)
id = a->getId();
}
return id + 1;
}
void Server_Player::setupZones()
{
// Delete existing zones and counters
clearZones();
// This may need to be customized according to the game rules.
// ------------------------------------------------------------------
// Create zones
Server_CardZone *deck = new Server_CardZone(this, "deck", false, Server_CardZone::HiddenZone);
addZone(deck);
Server_CardZone *sb = new Server_CardZone(this, "sb", false, Server_CardZone::HiddenZone);
addZone(sb);
addZone(new Server_CardZone(this, "table", true, Server_CardZone::PublicZone));
addZone(new Server_CardZone(this, "hand", false, Server_CardZone::PrivateZone));
addZone(new Server_CardZone(this, "grave", false, Server_CardZone::PublicZone));
addZone(new Server_CardZone(this, "rfg", false, Server_CardZone::PublicZone));
// ------------------------------------------------------------------
// Assign card ids and create deck from decklist
QListIterator<QString> DeckIterator(DeckList);
int i = 0;
while (DeckIterator.hasNext())
deck->cards.append(new Server_Card(DeckIterator.next(), i++, 0, 0));
deck->shuffle();
QListIterator<QString> SBIterator(SideboardList);
while (SBIterator.hasNext())
sb->cards.append(new Server_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 Server_Player::clearZones()
{
QMapIterator<QString, Server_CardZone *> zoneIterator(zones);
while (zoneIterator.hasNext())
delete zoneIterator.next().value();
zones.clear();
QMapIterator<int, Server_Counter *> counterIterator(counters);
while (counterIterator.hasNext())
delete counterIterator.next().value();
counters.clear();
QMapIterator<int, Server_Arrow *> arrowIterator(arrows);
while (arrowIterator.hasNext())
delete arrowIterator.next().value();
arrows.clear();
}
void Server_Player::addZone(Server_CardZone *zone)
{
zones.insert(zone->getName(), zone);
}
void Server_Player::addArrow(Server_Arrow *arrow)
{
arrows.insert(arrow->getId(), arrow);
}
bool Server_Player::deleteArrow(int arrowId)
{
Server_Arrow *arrow = arrows.value(arrowId, 0);
if (!arrow)
return false;
arrows.remove(arrowId);
delete arrow;
return true;
}
void Server_Player::addCounter(Server_Counter *counter)
{
counters.insert(counter->getId(), counter);
}
bool Server_Player::deleteCounter(int counterId)
{
Server_Counter *counter = counters.value(counterId, 0);
if (!counter)
return false;
counters.remove(counterId);
delete counter;
return true;
}
void Server_Player::privateEvent(const QString &line)
{
/* if (!socket)
return;
socket->msg(QString("private|%1|%2|%3").arg(playerId).arg(playerName).arg(line));
*/}
void Server_Player::publicEvent(const QString &line, Server_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
common/server_player.h Normal file
View file

@ -0,0 +1,66 @@
#ifndef PLAYER_H
#define PLAYER_H
#include <QObject>
#include <QString>
#include <QList>
#include <QMap>
class ServerSocket;
class Server_Game;
class Server_CardZone;
class Server_Counter;
class Server_Arrow;
enum PlayerStatusEnum { StatusNormal, StatusSubmitDeck, StatusReadyStart, StatusPlaying };
class Server_Player : public QObject {
Q_OBJECT
private:
Server_Game *game;
ServerSocket *socket;
QMap<QString, Server_CardZone *> zones;
QMap<int, Server_Counter *> counters;
QMap<int, Server_Arrow *> arrows;
int playerId;
QString playerName;
bool spectator;
int nextCardId;
void clearZones();
PlayerStatusEnum PlayerStatus;
public:
// Pfusch
QList<QString> DeckList;
QList<QString> SideboardList;
// Pfusch Ende
Server_Player(Server_Game *_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, Server_CardZone *> &getZones() const { return zones; }
const QMap<int, Server_Counter *> &getCounters() const { return counters; }
const QMap<int, Server_Arrow *> &getArrows() const { return arrows; }
int newCardId();
int newCounterId() const;
int newArrowId() const;
void addZone(Server_CardZone *zone);
void addArrow(Server_Arrow *arrow);
bool deleteArrow(int arrowId);
void addCounter(Server_Counter *counter);
bool deleteCounter(int counterId);
void setupZones();
void privateEvent(const QString &line);
void publicEvent(const QString &line, Server_Player *player = 0);
};
#endif

View file

@ -0,0 +1,33 @@
#include <QDebug>
#include "server_protocolhandler.h"
#include "protocol.h"
#include "protocol_items.h"
Server_ProtocolHandler::Server_ProtocolHandler(Server *_server, QObject *parent)
: QObject(parent), server(_server), authState(PasswordWrong), acceptsGameListChanges(false)
{
}
Server_ProtocolHandler::~Server_ProtocolHandler()
{
}
void Server_ProtocolHandler::processCommand(Command *command)
{
ChatCommand *chatCommand = qobject_cast<ChatCommand *>(command);
GameCommand *gameCommand = qobject_cast<GameCommand *>(command);
if (chatCommand) {
qDebug() << "received ChatCommand: channel =" << chatCommand->getChannel();
} else if (gameCommand) {
qDebug() << "received GameCommand: game =" << gameCommand->getGameId();
} else {
qDebug() << "received generic Command";
}
}
QPair<Server_Game *, Server_Player *> Server_ProtocolHandler::getGame(int gameId) const
{
if (games.contains(gameId))
return games.value(gameId);
return QPair<Server_Game *, Server_Player *>(0, 0);
}

View file

@ -0,0 +1,36 @@
#ifndef SERVER_PROTOCOLHANDLER_H
#define SERVER_PROTOCOLHANDLER_H
#include <QObject>
#include <QPair>
#include "server.h"
class Server_Player;
class Command;
class Server_ProtocolHandler : public QObject {
Q_OBJECT
private:
Server *server;
QMap<int, QPair<Server_Game *, Server_Player *> > games;
QMap<QString, Server_ChatChannel *> chatChannels;
QString playerName;
Server *getServer() const { return server; }
QPair<Server_Game *, Server_Player *> getGame(int gameId) const;
AuthenticationResult authState;
bool acceptsGameListChanges;
bool acceptsChatChannelListChanges;
public:
Server_ProtocolHandler(Server *_server, QObject *parent = 0);
~Server_ProtocolHandler();
bool getAcceptsGameListChanges() const { return acceptsGameListChanges; }
bool getAcceptsChatChannelListChanges() const { return acceptsChatChannelListChanges; }
const QString &getPlayerName() const { return playerName; }
void processCommand(Command *command);
};
#endif

View file

@ -1,104 +0,0 @@
#include <QtGui>
#include <QDebug>
#include "widget.h"
#include "protocol.h"
#include "protocol_items.h"
Widget::Widget()
: QMainWindow()
{
edit1 = new QTextEdit;
start = new QPushButton;
connect(start, SIGNAL(clicked()), this, SLOT(startClicked()));
buffer = new QBuffer;
buffer->open(QIODevice::ReadWrite);
connect(buffer, SIGNAL(readyRead()), this, SLOT(updateEdit()));
xmlWriter.setDevice(buffer);
xmlWriter.setAutoFormatting(true);
QVBoxLayout *vbox = new QVBoxLayout;
vbox->addWidget(edit1);
vbox->addWidget(start);
QWidget *central = new QWidget;
central->setLayout(vbox);
setCentralWidget(central);
resize(400, 500);
Command::initializeHash();
}
void Widget::startClicked()
{
currentItem = 0;
xmlWriter.writeStartDocument();
xmlWriter.writeStartElement("cockatrice_communication");
xmlWriter.writeAttribute("version", "4");
Command *test = new Command_Ping;
test->write(xmlWriter);
Command *test2 = new Command_ChatLeaveChannel("foobar");
test2->write(xmlWriter);
Command *test3 = new Command_ChatSay("foobar", "Hallo, dies ist ein Test");
test3->write(xmlWriter);
ProtocolResponse *test4 = new ProtocolResponse(123, ProtocolResponse::RespContextError);
test4->write(xmlWriter);
GameEvent *test5 = new Event_RollDie(1234, 1, 20, 13);
test5->write(xmlWriter);
}
bool Widget::readCurrentCommand()
{
if (!currentItem)
return false;
if (currentItem->read(xmlReader)) {
qDebug() << "setting to 0";
currentItem = 0;
}
return true;
}
void Widget::parseXml()
{
if (readCurrentCommand())
return;
while (!xmlReader.atEnd()) {
xmlReader.readNext();
if (xmlReader.isStartElement()) {
QString itemType = xmlReader.name().toString();
QString itemName = xmlReader.attributes().value("name").toString();
qDebug() << "parseXml: startElement: " << "type =" << itemType << ", name =" << itemName;
currentItem = ProtocolItem::getNewItem(itemType + itemName);
if (!currentItem)
qDebug() << "unrecognized item";
readCurrentCommand();
}
}
}
void Widget::parseBuffer()
{
xmlReader.clear();
buffer->seek(0);
while (!buffer->atEnd()) {
QByteArray oneByte = buffer->read(1);
xmlReader.addData(oneByte);
parseXml();
}
}
void Widget::updateEdit()
{
buffer->seek(0);
edit1->setText(buffer->readAll());
parseBuffer();
}

View file

@ -1,33 +0,0 @@
#ifndef WIDGET_H
#define WIDGET_H
#include <QMainWindow>
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
class QTextEdit;
class QPushButton;
class QBuffer;
class ProtocolItem;
class Widget : public QMainWindow {
Q_OBJECT
private:
QTextEdit *edit1;
QPushButton *start;
QBuffer *buffer;
QXmlStreamReader xmlReader;
QXmlStreamWriter xmlWriter;
ProtocolItem *currentItem;
bool readCurrentCommand();
void parseBuffer();
void parseXml();
private slots:
void startClicked();
void updateEdit();
public:
Widget();
};
#endif