minor improvements

This commit is contained in:
Max-Wilhelm Bruker 2009-04-08 21:49:16 +02:00
parent a429a4a004
commit 792a400a3d
30 changed files with 1022 additions and 829 deletions

View file

@ -148,7 +148,7 @@ void CardItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
if ((event->screenPos() - event->buttonDownScreenPos(Qt::LeftButton)).manhattanLength() < QApplication::startDragDistance())
return;
bool faceDown = event->modifiers().testFlag(Qt::ShiftModifier);
bool faceDown = event->modifiers().testFlag(Qt::ShiftModifier) || facedown;
createDragItem((CardZone *) parentItem(), id, event->pos(), event->scenePos(), faceDown);
dragItem->grabMouse();

View file

@ -155,7 +155,7 @@ void Client::readLine()
else if (!prefix.compare("welcome")) {
emit welcomeMsgReceived(welcomemsg);
setStatus(StatusConnected);
setName(PlayerName);
login(PlayerName, password);
}
msgbuf.clear();
} else
@ -189,9 +189,10 @@ int Client::cmd(const QString &s)
return MsgId;
}
void Client::connectToServer(const QString &hostname, unsigned int port, const QString &playername)
void Client::connectToServer(const QString &hostname, unsigned int port, const QString &playername, const QString &_password)
{
PlayerName = playername;
password = _password;
socket->connectToHost(hostname, port);
setStatus(StatusConnecting);
}
@ -229,9 +230,9 @@ int Client::leaveGame()
return cmd("leave_game");
}
int Client::setName(const QString &name)
int Client::login(const QString &name, const QString &pass)
{
return cmd(QString("set_name|%1").arg(name));
return cmd(QString("login|%1|%2").arg(name).arg(pass));
}
int Client::say(const QString &s)

View file

@ -48,6 +48,7 @@ private:
ProtocolStatus status;
QList<QStringList> msgbuf;
QString PlayerName;
QString password;
unsigned int MsgId;
void msg(const QString &s);
int cmd(const QString &s);
@ -58,14 +59,14 @@ public:
ProtocolStatus getStatus() { return status; }
QString peerName() const { return socket->peerName(); }
void connectToServer(const QString &hostname, unsigned int port, const QString &playername);
void connectToServer(const QString &hostname, unsigned int port, const QString &playername, const QString &password);
void disconnectFromServer();
int listGames();
int listPlayers();
int createGame(const QString &name, const QString &description, const QString &password, unsigned int maxPlayers);
int joinGame(const QString &name, const QString &password);
int leaveGame();
int setName(const QString &name);
int login(const QString &name, const QString &pass);
int say(const QString &s);
int shuffle();
int rollDice(unsigned int sides);

View file

@ -16,6 +16,11 @@ DlgConnect::DlgConnect(QWidget *parent)
playernameEdit = new QLineEdit("Player");
playernameLabel->setBuddy(playernameEdit);
passwordLabel = new QLabel(tr("P&assword:"));
passwordEdit = new QLineEdit;
passwordLabel->setBuddy(passwordEdit);
passwordEdit->setEchoMode(QLineEdit::Password);
okButton = new QPushButton(tr("&OK"));
okButton->setDefault(true);
cancelButton = new QPushButton(tr("&Cancel"));
@ -27,6 +32,8 @@ DlgConnect::DlgConnect(QWidget *parent)
grid->addWidget(portEdit, 1, 1);
grid->addWidget(playernameLabel, 2, 0);
grid->addWidget(playernameEdit, 2, 1);
grid->addWidget(passwordLabel, 3, 0);
grid->addWidget(passwordEdit, 3, 1);
QHBoxLayout *buttonLayout = new QHBoxLayout;
buttonLayout->addStretch();
@ -59,3 +66,8 @@ QString DlgConnect::getPlayerName()
{
return playernameEdit->text();
}
QString DlgConnect::getPassword()
{
return passwordEdit->text();
}

View file

@ -14,9 +14,10 @@ public:
QString getHost();
int getPort();
QString getPlayerName();
QString getPassword();
private:
QLabel *hostLabel, *portLabel, *playernameLabel;
QLineEdit *hostEdit, *portEdit, *playernameEdit;
QLabel *hostLabel, *portLabel, *playernameLabel, *passwordLabel;
QLineEdit *hostEdit, *portEdit, *playernameEdit, *passwordEdit;
QPushButton *okButton, *cancelButton;
};

View file

@ -68,6 +68,8 @@ Game::Game(CardDatabase *_db, Client *_client, QGraphicsScene *_scene, QMenu *_a
connect(aUntap, SIGNAL(triggered()), this, SLOT(actUntap()));
aDoesntUntap = new QAction(tr("Toggle &normal untapping"), this);
connect(aDoesntUntap, SIGNAL(triggered()), this, SLOT(actDoesntUntap()));
aFlip = new QAction(tr("&Flip"), this);
connect(aFlip, SIGNAL(triggered()), this, SLOT(actFlip()));
aAddCounter = new QAction(tr("&Add counter"), this);
connect(aAddCounter, SIGNAL(triggered()), this, SLOT(actAddCounter()));
aRemoveCounter = new QAction(tr("&Remove counter"), this);
@ -81,6 +83,8 @@ Game::Game(CardDatabase *_db, Client *_client, QGraphicsScene *_scene, QMenu *_a
cardMenu->addAction(aUntap);
cardMenu->addAction(aDoesntUntap);
cardMenu->addSeparator();
cardMenu->addAction(aFlip);
cardMenu->addSeparator();
cardMenu->addAction(aAddCounter);
cardMenu->addAction(aRemoveCounter);
cardMenu->addAction(aSetCounters);
@ -321,6 +325,16 @@ void Game::actDoesntUntap()
}
}
void Game::actFlip()
{
QListIterator<QGraphicsItem *> i(scene->selectedItems());
while (i.hasNext()) {
CardItem *temp = (CardItem *) i.next();
QString zone = qgraphicsitem_cast<CardZone *>(temp->parentItem())->getName();
client->moveCard(temp->getId(), zone, zone, temp->pos().x(), temp->pos().y(), !temp->getFaceDown());
}
}
void Game::actAddCounter()
{
QListIterator<QGraphicsItem *> i(scene->selectedItems());

View file

@ -15,7 +15,7 @@ class Game : public QObject {
Q_OBJECT
private:
QMenu *actionsMenu, *cardMenu;
QAction *aTap, *aUntap, *aDoesntUntap, *aAddCounter, *aRemoveCounter, *aSetCounters, *aRearrange,
QAction *aTap, *aUntap, *aDoesntUntap, *aFlip, *aAddCounter, *aRemoveCounter, *aSetCounters, *aRearrange,
*aUntapAll, *aDecLife, *aIncLife, *aSetLife, *aShuffle, *aDraw, *aDrawCards, *aRollDice, *aCreateToken;
DlgStartGame *dlgStartGame;
@ -41,6 +41,7 @@ private slots:
void actTap();
void actUntap();
void actDoesntUntap();
void actFlip();
void actAddCounter();
void actRemoveCounter();
void actSetCounters();

View file

@ -82,7 +82,7 @@ void MainWindow::actConnect()
{
DlgConnect dlg(this);
if (dlg.exec())
client->connectToServer(dlg.getHost(), dlg.getPort(), dlg.getPlayerName());
client->connectToServer(dlg.getHost(), dlg.getPort(), dlg.getPlayerName(), dlg.getPassword());
}
void MainWindow::actDisconnect()

View file

@ -8,25 +8,25 @@ DEPENDPATH += . src
INCLUDEPATH += . src
CONFIG += qt thread
QT += network
QT += network sql
QT -= gui
# Input
HEADERS += src/testserver.h src/testservergame.h src/testserversocket.h \
HEADERS += src/server.h src/servergame.h src/serversocket.h \
src/playerzone.h \
src/testcard.h \
src/card.h \
src/version.h \
src/counter.h \
src/testrandom.h \
src/testservergamethread.h \
src/random.h \
src/servergamethread.h \
src/returnmessage.h
SOURCES += src/main.cpp \
src/testserver.cpp \
src/testservergame.cpp \
src/testserversocket.cpp \
src/server.cpp \
src/servergame.cpp \
src/serversocket.cpp \
src/playerzone.cpp \
src/testcard.cpp \
src/card.cpp \
src/counter.cpp \
src/testrandom.cpp \
src/testservergamethread.cpp \
src/random.cpp \
src/servergamethread.cpp \
src/returnmessage.cpp

View file

@ -17,19 +17,19 @@
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "testcard.h"
#include "card.h"
TestCard::TestCard(QString _name, int _id, int _coord_x, int _coord_y)
Card::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)
{
}
TestCard::~TestCard()
Card::~Card()
{
}
void TestCard::resetState()
void Card::resetState()
{
setCoords(0, 0);
setCounters(0);
@ -40,7 +40,7 @@ void TestCard::resetState()
setDoesntUntap(false);
}
bool TestCard::setAttribute(const QString &aname, const QString &avalue, bool allCards)
bool Card::setAttribute(const QString &aname, const QString &avalue, bool allCards)
{
if (!aname.compare("counters")) {
bool ok;

View file

@ -17,12 +17,12 @@
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef TESTCARD_H
#define TESTCARD_H
#ifndef CARD_H
#define CARD_H
#include <QString>
class TestCard {
class Card {
private:
int id;
int coord_x, coord_y;
@ -34,8 +34,8 @@ private:
QString annotation;
bool doesntUntap;
public:
TestCard(QString _name, int _id, int _coord_x, int _coord_y);
~TestCard();
Card(QString _name, int _id, int _coord_x, int _coord_y);
~Card();
int getId() { return id; }
int getX() { return coord_x; }

View file

@ -20,14 +20,18 @@
#include <QCoreApplication>
#include "testserver.h"
#include "server.h"
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
TestServer server;
server.listen(QHostAddress::Any, 4747);
QCoreApplication app(argc, argv);
return app.exec();
Server server;
if (!server.openDatabase()) {
qCritical("Database error");
return -1;
}
server.listen(QHostAddress::Any, 4747);
return app.exec();
}

View file

@ -18,6 +18,8 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "playerzone.h"
#include "random.h"
#include "card.h"
PlayerZone::PlayerZone(QString _name, bool _has_coords, bool _is_public, bool _is_private, bool _id_access)
: name(_name), has_coords(_has_coords), is_public(_is_public), is_private(_is_private), id_access(_id_access)
@ -30,21 +32,21 @@ PlayerZone::~PlayerZone()
clear();
}
void PlayerZone::shuffle(TestRandom *rnd)
void PlayerZone::shuffle(Random *rnd)
{
QList<TestCard *> temp;
QList<Card *> temp;
for (int i = cards.size(); i; i--)
temp.append(cards.takeAt(rnd->getNumber(0, i - 1)));
cards = temp;
}
TestCard *PlayerZone::getCard(int id, bool remove, int *position)
Card *PlayerZone::getCard(int id, bool remove, int *position)
{
if (hasIdAccess()) {
QListIterator<TestCard *> CardIterator(cards);
QListIterator<Card *> CardIterator(cards);
int i = 0;
while (CardIterator.hasNext()) {
TestCard *tmp = CardIterator.next();
Card *tmp = CardIterator.next();
if (tmp->getId() == id) {
if (remove)
cards.removeAt(i);
@ -58,7 +60,7 @@ TestCard *PlayerZone::getCard(int id, bool remove, int *position)
} else {
if (id >= cards.size())
return NULL;
TestCard *tmp = cards[id];
Card *tmp = cards[id];
if (remove)
cards.removeAt(id);
if (position)
@ -67,7 +69,7 @@ TestCard *PlayerZone::getCard(int id, bool remove, int *position)
}
}
void PlayerZone::insertCard(TestCard *card, int x, int y)
void PlayerZone::insertCard(Card *card, int x, int y)
{
if (hasCoords()) {
card->setCoords(x, y);

View file

@ -21,8 +21,10 @@
#define PLAYERZONE_H
#include <QList>
#include "testcard.h"
#include "testrandom.h"
#include <QString>
class Card;
class Random;
class PlayerZone {
private:
@ -40,7 +42,7 @@ public:
PlayerZone(QString _name, bool _has_coords, bool _is_public, bool _is_private, bool _id_access);
~PlayerZone();
TestCard *getCard(int id, bool remove, int *position = NULL);
Card *getCard(int id, bool remove, int *position = NULL);
bool isPublic() { return is_public; }
bool isPrivate() { return is_private; }
@ -48,9 +50,9 @@ public:
bool hasIdAccess() { return id_access; }
QString getName() { return name; }
QList<TestCard *> cards;
void insertCard(TestCard *card, int x, int y);
void shuffle(TestRandom *rnd);
QList<Card *> cards;
void insertCard(Card *card, int x, int y);
void shuffle(Random *rnd);
void clear();
};

View file

@ -1,7 +1,7 @@
#include "testrandom.h"
#include "random.h"
#include <QThread>
void TestRandom::init()
void Random::init()
{
if (initialized)
return;
@ -11,7 +11,7 @@ void TestRandom::init()
initialized = true;
}
unsigned int TestRandom::getNumber(unsigned int min, unsigned int max)
unsigned int Random::getNumber(unsigned int min, unsigned int max)
{
int r = qrand();
return min + (unsigned int) (((double) (max + 1 - min)) * r / (RAND_MAX + 1.0));

View file

@ -1,16 +1,16 @@
#ifndef TESTRANDOM_H
#define TESTRANDOM_H
#ifndef RANDOM_H
#define RANDOM_H
#include <QObject>
#include <QDateTime>
#include <stdlib.h>
class TestRandom : public QObject {
class Random : public QObject {
Q_OBJECT
private:
bool initialized;
public:
TestRandom(QObject *parent) : QObject(parent), initialized(false) { }
Random(QObject *parent) : QObject(parent), initialized(false) { }
void init();
unsigned int getNumber(unsigned int min, unsigned int max);
};

View file

@ -1,25 +1,36 @@
#include "returnmessage.h"
#include "testserversocket.h"
#include "serversocket.h"
void ReturnMessage::setMsgId(unsigned int _msg_id)
{
msg_id = _msg_id;
}
bool ReturnMessage::send(const QString &args, bool success)
bool ReturnMessage::send(ReturnCode code)
{
TestServerSocket *s = qobject_cast<TestServerSocket *>(parent());
ServerSocket *s = qobject_cast<ServerSocket *>(parent());
if (!s)
return false;
bool success = (code == ReturnOk);
QString returnCodeString;
switch (code) {
case ReturnNothing: return true;
case ReturnOk: break;
case ReturnLoginNeeded: returnCodeString = "login_needed"; break;
case ReturnSyntaxError: returnCodeString = "syntax"; break;
case ReturnContextError: returnCodeString = "context"; break;
case ReturnPasswordWrong: returnCodeString = "password"; break;
case ReturnNameNotFound: returnCodeString = "name_not_found"; break;
}
s->msg(QString("resp|%1|%2|%3").arg(msg_id)
.arg(success ? "ok" : "err")
.arg(args));
.arg(returnCodeString));
return success;
}
bool ReturnMessage::sendList(const QStringList &args)
{
TestServerSocket *s = qobject_cast<TestServerSocket *>(parent());
ServerSocket *s = qobject_cast<ServerSocket *>(parent());
if (!s)
return false;

View file

@ -1,8 +1,7 @@
#ifndef RETURNMESSAGE_H
#define RETURNMESSAGE_H
#include <QString>
#include <QObject>
#include <QStringList>
class ReturnMessage : public QObject {
Q_OBJECT
@ -10,11 +9,12 @@ private:
unsigned int msg_id;
QString cmd;
public:
enum ReturnCode { ReturnNothing, ReturnOk, ReturnLoginNeeded, ReturnSyntaxError, ReturnContextError, ReturnPasswordWrong, ReturnNameNotFound };
ReturnMessage(QObject *parent = 0) : QObject(parent), msg_id(0) { }
unsigned int getMsgId() const { return msg_id; }
void setMsgId(unsigned int _msg_id);
void setCmd(const QString &_cmd) { cmd = _cmd; }
bool send(const QString &args = QString(), bool success = true);
bool send(ReturnCode code);
bool sendList(const QStringList &args);
};

View file

@ -17,58 +17,91 @@
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "testserver.h"
#include "server.h"
#include "servergamethread.h"
#include "servergame.h"
#include "serversocket.h"
#include "counter.h"
#include <QtSql>
TestServer::TestServer(QObject *parent)
Server::Server(QObject *parent)
: QTcpServer(parent)
{
}
TestServer::~TestServer()
Server::~Server()
{
}
void TestServer::gameCreated(TestServerGame *_game, TestServerSocket *_creator)
bool Server::openDatabase()
{
QSqlDatabase sqldb = QSqlDatabase::addDatabase("QMYSQL");
sqldb.setHostName("localhost");
sqldb.setDatabaseName("cockatrice");
sqldb.setUserName("cockatrice");
sqldb.setPassword("45CdX6rmd");
return sqldb.open();
}
void Server::gameCreated(ServerGame *_game, ServerSocket *_creator)
{
games << _game;
_creator->moveToThread(_game->thread());
_game->addPlayer(_creator);
}
void TestServer::addGame(const QString name, const QString description, const QString password, const int maxPlayers, TestServerSocket *creator)
void Server::addGame(const QString name, const QString description, const QString password, const int maxPlayers, ServerSocket *creator)
{
TestServerGameThread *newThread = new TestServerGameThread(name, description, password, maxPlayers, creator);
connect(newThread, SIGNAL(gameCreated(TestServerGame *, TestServerSocket *)), this, SLOT(gameCreated(TestServerGame *, TestServerSocket *)));
ServerGameThread *newThread = new ServerGameThread(name, description, password, maxPlayers, creator);
connect(newThread, SIGNAL(gameCreated(ServerGame *, ServerSocket *)), this, SLOT(gameCreated(ServerGame *, ServerSocket *)));
connect(newThread, SIGNAL(finished()), this, SLOT(gameClosed()));
newThread->start();
}
void TestServer::incomingConnection(int socketId)
void Server::incomingConnection(int socketId)
{
TestServerSocket *socket = new TestServerSocket(this);
ServerSocket *socket = new ServerSocket(this);
socket->setSocketDescriptor(socketId);
connect(socket, SIGNAL(createGame(const QString, const QString, const QString, const int, TestServerSocket *)), this, SLOT(addGame(const QString, const QString, const QString, const int, TestServerSocket *)));
connect(socket, SIGNAL(joinGame(const QString, TestServerSocket *)), this, SLOT(addClientToGame(const QString, TestServerSocket *)));
connect(socket, SIGNAL(createGame(const QString, const QString, const QString, const int, ServerSocket *)), this, SLOT(addGame(const QString, const QString, const QString, const int, ServerSocket *)));
connect(socket, SIGNAL(joinGame(const QString, ServerSocket *)), this, SLOT(addClientToGame(const QString, ServerSocket *)));
socket->initConnection();
}
TestServerGame *TestServer::getGame(const QString &name)
AuthenticationResult Server::checkUserPassword(const QString &user, const QString &password)
{
QListIterator<TestServerGame *> i(games);
QSqlQuery query;
query.prepare("select password from users where name = :name");
query.bindValue(":name", user);
if (!query.exec()) {
qCritical(QString("Database error: %1").arg(query.lastError().text()).toLatin1());
exit(-1);
}
if (query.next()) {
if (query.value(0).toString() == password)
return PasswordRight;
else
return PasswordWrong;
} else
return UnknownUser;
}
ServerGame *Server::getGame(const QString &name)
{
QListIterator<ServerGame *> i(games);
while (i.hasNext()) {
TestServerGame *tmp = i.next();
ServerGame *tmp = i.next();
if ((!tmp->name.compare(name, Qt::CaseSensitive)) && !tmp->getGameStarted())
return tmp;
}
return NULL;
}
QList<TestServerGame *> TestServer::listOpenGames()
QList<ServerGame *> Server::listOpenGames()
{
QList<TestServerGame *> result;
QListIterator<TestServerGame *> i(games);
QList<ServerGame *> result;
QListIterator<ServerGame *> i(games);
while (i.hasNext()) {
TestServerGame *tmp = i.next();
ServerGame *tmp = i.next();
tmp->mutex->lock();
if ((!tmp->getGameStarted())
&& (tmp->getPlayerCount() < tmp->maxPlayers))
@ -78,9 +111,9 @@ QList<TestServerGame *> TestServer::listOpenGames()
return result;
}
bool TestServer::checkGamePassword(const QString &name, const QString &password)
bool Server::checkGamePassword(const QString &name, const QString &password)
{
TestServerGame *tmp;
ServerGame *tmp;
if ((tmp = getGame(name))) {
QMutexLocker locker(tmp->mutex);
if ((!tmp->getGameStarted())
@ -91,17 +124,17 @@ bool TestServer::checkGamePassword(const QString &name, const QString &password)
return false;
}
void TestServer::addClientToGame(const QString name, TestServerSocket *client)
void Server::addClientToGame(const QString name, ServerSocket *client)
{
TestServerGame *tmp = getGame(name);
ServerGame *tmp = getGame(name);
client->moveToThread(tmp->thread());
tmp->addPlayer(client);
}
void TestServer::gameClosed()
void Server::gameClosed()
{
qDebug("TestServer::gameClosed");
TestServerGameThread *t = qobject_cast<TestServerGameThread *>(sender());
qDebug("Server::gameClosed");
ServerGameThread *t = qobject_cast<ServerGameThread *>(sender());
games.removeAt(games.indexOf(t->getGame()));
delete t;
}

View file

@ -17,33 +17,36 @@
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef TESTSERVER_H
#define TESTSERVER_H
#ifndef SERVER_H
#define SERVER_H
#include <QTcpServer>
#include "testservergamethread.h"
#include "testservergame.h"
class TestServerGame;
class TestServerSocket;
class ServerGame;
class ServerSocket;
class QSqlDatabase;
class TestServer : public QTcpServer
enum AuthenticationResult { PasswordWrong = 0, PasswordRight = 1, UnknownUser = 2 };
class Server : public QTcpServer
{
Q_OBJECT
private slots:
void addGame(const QString name, const QString description, const QString password, const int maxPlayers, TestServerSocket *creator);
void addClientToGame(const QString name, TestServerSocket *client);
void gameCreated(TestServerGame *_game, TestServerSocket *_creator);
void addGame(const QString name, const QString description, const QString password, const int maxPlayers, ServerSocket *creator);
void addClientToGame(const QString name, ServerSocket *client);
void gameCreated(ServerGame *_game, ServerSocket *_creator);
void gameClosed();
public:
TestServer(QObject *parent = 0);
~TestServer();
Server(QObject *parent = 0);
~Server();
bool openDatabase();
bool checkGamePassword(const QString &name, const QString &password);
QList<TestServerGame *> listOpenGames();
TestServerGame *getGame(const QString &name);
AuthenticationResult checkUserPassword(const QString &user, const QString &password);
QList<ServerGame *> listOpenGames();
ServerGame *getGame(const QString &name);
private:
void incomingConnection(int SocketId);
QList<TestServerGame *> games;
QList<ServerGame *> games;
};
#endif

View file

@ -17,9 +17,11 @@
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "testservergame.h"
#include "servergame.h"
#include "random.h"
#include "serversocket.h"
TestServerGame::TestServerGame(QString _name, QString _description, QString _password, int _maxPlayers, QObject *parent)
ServerGame::ServerGame(QString _name, QString _description, QString _password, int _maxPlayers, QObject *parent)
: QObject(parent), name(_name), description(_description), password(_password), maxPlayers(_maxPlayers)
{
gameStarted = false;
@ -27,59 +29,59 @@ TestServerGame::TestServerGame(QString _name, QString _description, QString _pas
rnd = NULL;
}
TestServerGame::~TestServerGame()
ServerGame::~ServerGame()
{
if (rnd)
delete rnd;
delete mutex;
qDebug("TestServerGame destructor");
qDebug("ServerGame destructor");
}
bool TestServerGame::getGameStarted()
bool ServerGame::getGameStarted()
{
return gameStarted;
}
int TestServerGame::getPlayerCount()
int ServerGame::getPlayerCount()
{
QMutexLocker locker(mutex);
return players.size();
}
QStringList TestServerGame::getPlayerNames()
QStringList ServerGame::getPlayerNames()
{
QMutexLocker locker(mutex);
QStringList result;
QListIterator<TestServerSocket *> i(players);
QListIterator<ServerSocket *> i(players);
while (i.hasNext()) {
TestServerSocket *tmp = i.next();
ServerSocket *tmp = i.next();
result << QString("%1|%2").arg(tmp->getPlayerId()).arg(tmp->PlayerName);
}
return result;
}
TestServerSocket *TestServerGame::getPlayer(int player_id)
ServerSocket *ServerGame::getPlayer(int player_id)
{
QListIterator<TestServerSocket *> i(players);
QListIterator<ServerSocket *> i(players);
while (i.hasNext()) {
TestServerSocket *tmp = i.next();
ServerSocket *tmp = i.next();
if (tmp->getPlayerId() == player_id)
return tmp;
}
return NULL;
}
void TestServerGame::msg(const QString &s)
void ServerGame::msg(const QString &s)
{
QMutexLocker locker(mutex);
QListIterator<TestServerSocket *> i(players);
QListIterator<ServerSocket *> i(players);
while (i.hasNext())
i.next()->msg(s);
}
void TestServerGame::broadcastEvent(const QString &cmd, TestServerSocket *player)
void ServerGame::broadcastEvent(const QString &cmd, ServerSocket *player)
{
if (player)
msg(QString("public|%1|%2|%3").arg(player->getPlayerId()).arg(player->PlayerName).arg(cmd));
@ -87,7 +89,7 @@ void TestServerGame::broadcastEvent(const QString &cmd, TestServerSocket *player
msg(QString("public|||%1").arg(cmd));
}
void TestServerGame::startGameIfReady()
void ServerGame::startGameIfReady()
{
QMutexLocker locker(mutex);
@ -98,7 +100,7 @@ void TestServerGame::startGameIfReady()
return;
if (!rnd) {
rnd = new TestRandom(this);
rnd = new Random(this);
rnd->init();
}
@ -111,12 +113,12 @@ void TestServerGame::startGameIfReady()
broadcastEvent("game_start", NULL);
}
void TestServerGame::addPlayer(TestServerSocket *player)
void ServerGame::addPlayer(ServerSocket *player)
{
QMutexLocker locker(mutex);
int max = -1;
QListIterator<TestServerSocket *> i(players);
QListIterator<ServerSocket *> i(players);
while (i.hasNext()) {
int tmp = i.next()->getPlayerId();
if (tmp > max)
@ -130,10 +132,10 @@ void TestServerGame::addPlayer(TestServerSocket *player)
players << player;
connect(player, SIGNAL(broadcastEvent(const QString &, TestServerSocket *)), this, SLOT(broadcastEvent(const QString &, TestServerSocket *)));
connect(player, SIGNAL(broadcastEvent(const QString &, ServerSocket *)), this, SLOT(broadcastEvent(const QString &, ServerSocket *)));
}
void TestServerGame::removePlayer(TestServerSocket *player)
void ServerGame::removePlayer(ServerSocket *player)
{
QMutexLocker locker(mutex);
@ -143,14 +145,14 @@ void TestServerGame::removePlayer(TestServerSocket *player)
thread()->quit();
}
void TestServerGame::setActivePlayer(int _activePlayer)
void ServerGame::setActivePlayer(int _activePlayer)
{
activePlayer = _activePlayer;
broadcastEvent(QString("set_active_player|%1").arg(_activePlayer), NULL);
setActivePhase(0);
}
void TestServerGame::setActivePhase(int _activePhase)
void ServerGame::setActivePhase(int _activePhase)
{
activePhase = _activePhase;
broadcastEvent(QString("set_active_phase|%1").arg(_activePhase), NULL);

View file

@ -17,41 +17,40 @@
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef TESTSERVERGAME_H
#define TESTSERVERGAME_H
#ifndef SERVERGAME_H
#define SERVERGAME_H
#include <QThread>
#include <QMutex>
#include <QStringList>
#include "testserversocket.h"
#include "testrandom.h"
class TestServerSocket;
class ServerSocket;
class Random;
class TestServerGame : public QObject {
class ServerGame : public QObject {
Q_OBJECT
private:
QList<TestServerSocket *> players;
QList<ServerSocket *> players;
bool gameStarted;
int activePlayer;
int activePhase;
public slots:
void broadcastEvent(const QString &event, TestServerSocket *player);
void broadcastEvent(const QString &event, ServerSocket *player);
public:
QMutex *mutex;
TestRandom *rnd;
Random *rnd;
QString name;
QString description;
QString password;
int maxPlayers;
TestServerGame(QString _name, QString _description, QString _password, int _maxPlayers, QObject *parent = 0);
~TestServerGame();
ServerGame(QString _name, QString _description, QString _password, int _maxPlayers, QObject *parent = 0);
~ServerGame();
bool getGameStarted();
int getPlayerCount();
QStringList getPlayerNames();
TestServerSocket *getPlayer(int player_id);
void addPlayer(TestServerSocket *player);
void removePlayer(TestServerSocket *player);
ServerSocket *getPlayer(int player_id);
void addPlayer(ServerSocket *player);
void removePlayer(ServerSocket *player);
void startGameIfReady();
void msg(const QString &s);
int getActivePlayer() { return activePlayer; }

View file

@ -0,0 +1,21 @@
#include "servergamethread.h"
#include "servergame.h"
ServerGameThread::ServerGameThread(const QString _name, const QString _description, const QString _password, const int _maxPlayers, ServerSocket *_creator, QObject *parent)
: QThread(parent), name(_name), description(_description), password(_password), maxPlayers(_maxPlayers), creator(_creator), game(0)
{
}
ServerGameThread::~ServerGameThread()
{
if (game)
delete game;
}
void ServerGameThread::run()
{
game = new ServerGame(name, description, password, maxPlayers);
emit gameCreated(game, creator);
exec();
}

View file

@ -0,0 +1,28 @@
#ifndef SERVERGAMETHREAD_H
#define SERVERGAMETHREAD_H
#include <QThread>
#include <QMutex>
class ServerGame;
class ServerSocket;
class ServerGameThread : public QThread {
Q_OBJECT
signals:
void gameCreated(ServerGame *_game, ServerSocket *creator);
private:
QString name;
QString description;
QString password;
int maxPlayers;
ServerSocket *creator;
ServerGame *game;
public:
ServerGameThread(const QString _name, const QString _description, const QString _password, const int _maxPlayers, ServerSocket *_creator, QObject *parent = 0);
~ServerGameThread();
ServerGame *getGame() { return game; }
void run();
};
#endif

View file

@ -0,0 +1,690 @@
/***************************************************************************
* 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 <QStringList>
#include "server.h"
#include "serversocket.h"
#include "servergame.h"
#include "version.h"
#include "returnmessage.h"
#include "playerzone.h"
#include "counter.h"
#include "card.h"
#include "random.h"
ServerSocket::ServerSocket(Server *_server, QObject *parent)
: QTcpSocket(parent), server(_server), game(0), authState(PasswordWrong)
{
remsg = new ReturnMessage(this);
connect(this, SIGNAL(readyRead()), this, SLOT(readClient()));
connect(this, SIGNAL(disconnected()), this, SLOT(deleteLater()));
connect(this, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(catchSocketError(QAbstractSocket::SocketError)));
setTextModeEnabled(true);
PlayerStatus = StatusNormal;
}
ServerSocket::~ServerSocket()
{
qDebug("ServerSocket destructor");
if (game)
game->removePlayer(this);
}
int ServerSocket::newCardId()
{
return nextCardId++;
}
void ServerSocket::setName(const QString &name)
{
emit broadcastEvent(QString("name|%1|%2").arg(PlayerName).arg(name), this);
PlayerName = name;
}
PlayerZone *ServerSocket::getZone(const QString &name)
{
QListIterator<PlayerZone *> ZoneIterator(zones);
while (ZoneIterator.hasNext()) {
PlayerZone *temp = ZoneIterator.next();
if (!temp->getName().compare(name))
return temp;
}
return NULL;
}
Counter *ServerSocket::getCounter(const QString &name)
{
QListIterator<Counter *> CounterIterator(counters);
while (CounterIterator.hasNext()) {
Counter *temp = CounterIterator.next();
if (!temp->getName().compare(name))
return temp;
}
return NULL;
}
void ServerSocket::setupZones()
{
// Delete existing zones and counters
clearZones();
// This may need to be customized according to the game rules.
// ------------------------------------------------------------------
// Create zones
PlayerZone *deck = new PlayerZone("deck", false, false, false, false);
zones << deck;
PlayerZone *sb = new PlayerZone("sb", false, false, false, false);
zones << sb;
zones << new PlayerZone("table", true, true, false, true);
zones << new PlayerZone("hand", false, false, true, true);
zones << new PlayerZone("grave", false, true, false, true);
zones << new PlayerZone("rfg", false, true, false, true);
// Create life counter
Counter *life = new Counter("life", 20);
counters << life;
// ------------------------------------------------------------------
// 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(game->rnd);
QListIterator<QString> SBIterator(SideboardList);
while (SBIterator.hasNext())
sb->cards.append(new Card(SBIterator.next(), i++, 0, 0));
nextCardId = i;
PlayerStatus = StatusPlaying;
broadcastEvent(QString("setup_zones|%1|%2|%3").arg(getCounter("life")->getCount())
.arg(deck->cards.size())
.arg(getZone("sb")->cards.size()), this);
}
void ServerSocket::clearZones()
{
for (int i = 0; i < zones.size(); i++)
delete zones.at(i);
zones.clear();
for (int i = 0; i < counters.size(); i++)
delete counters.at(i);
counters.clear();
}
void ServerSocket::leaveGame()
{
if (!game)
return;
game->removePlayer(this);
game = 0;
PlayerStatus = StatusNormal;
clearZones();
moveToThread(server->thread());
}
void ServerSocket::readClient()
{
QTextStream *stream = new QTextStream(this);
stream->setCodec("UTF-8");
QStringList lines;
// Before parsing, everything has to be buffered so that the stream
// can be deleted in order to avoid problems when moving the object
// to another thread while this function is still running.
for (;;) {
QString line = stream->readLine();
if (line.isNull())
break;
lines << line;
}
delete stream;
QStringListIterator i(lines);
while (i.hasNext()) {
QString line = i.next();
qDebug(QString("<<< %1").arg(line).toLatin1());
switch (PlayerStatus) {
case StatusNormal:
case StatusReadyStart:
case StatusPlaying:
parseCommand(line);
break;
case StatusSubmitDeck:
QString card = line;
if (!card.compare(".")) {
PlayerStatus = StatusNormal;
remsg->send(ReturnMessage::ReturnOk);
} else if (card.startsWith("SB:"))
SideboardList << card.mid(3);
else
DeckList << card;
}
}
}
const ServerSocket::CommandProperties ServerSocket::commandList[ServerSocket::numberCommands] = {
{"login", 2, false, false, false, &ServerSocket::cmdLogin},
{"list_games", 0, true, false, false, &ServerSocket::cmdListGames},
{"create_game", 4, true, false, false, &ServerSocket::cmdCreateGame},
{"join_game", 2, true, false, false, &ServerSocket::cmdJoinGame},
{"leave_game", 0, true, true, false, &ServerSocket::cmdLeaveGame},
{"list_players", 0, true, true, false, &ServerSocket::cmdListPlayers},
{"say", 1, true, true, false, &ServerSocket::cmdSay},
{"submit_deck", 0, true, true, false, &ServerSocket::cmdSubmitDeck},
{"ready_start", 0, true, true, false, &ServerSocket::cmdReadyStart},
{"shuffle", 0, true, true, true, &ServerSocket::cmdShuffle},
{"draw_cards", 1, true, true, true, &ServerSocket::cmdDrawCards},
{"move_card", 6, true, true, true, &ServerSocket::cmdMoveCard},
{"create_token", 5, true, true, true, &ServerSocket::cmdCreateToken},
{"set_card_attr", 4, true, true, true, &ServerSocket::cmdSetCardAttr},
{"inc_counter", 2, true, true, true, &ServerSocket::cmdIncCounter},
{"set_counter", 2, true, true, true, &ServerSocket::cmdSetCounter},
{"del_counter", 1, true, true, true, &ServerSocket::cmdDelCounter},
{"list_counters", 2, true, true, true, &ServerSocket::cmdListCounters},
{"list_zones", 1, true, true, true, &ServerSocket::cmdListZones},
{"dump_zone", 3, true, true, true, &ServerSocket::cmdDumpZone},
{"roll_dice", 1, true, true, true, &ServerSocket::cmdRollDice},
{"set_active_player", 1, true, true, true, &ServerSocket::cmdSetActivePlayer},
{"set_active_phase", 1, true, true, true, &ServerSocket::cmdSetActivePhase}
};
ReturnMessage::ReturnCode ServerSocket::cmdLogin(const QStringList &params)
{
authState = server->checkUserPassword(params[0], params[1]);
if (authState == PasswordWrong)
return ReturnMessage::ReturnPasswordWrong;
PlayerName = params[0];
return ReturnMessage::ReturnOk;
}
ReturnMessage::ReturnCode ServerSocket::cmdListGames(const QStringList &params)
{
QList<ServerGame *> gameList = server->listOpenGames();
QListIterator<ServerGame *> gameListIterator(gameList);
QStringList result;
while (gameListIterator.hasNext()) {
ServerGame *tmp = gameListIterator.next();
tmp->mutex->lock();
result << QString("%1|%2|%3|%4|%5").arg(tmp->name)
.arg(tmp->description)
.arg(tmp->password == "" ? 0 : 1)
.arg(tmp->getPlayerCount())
.arg(tmp->maxPlayers);
tmp->mutex->unlock();
}
remsg->sendList(result);
return ReturnMessage::ReturnOk;
}
ReturnMessage::ReturnCode ServerSocket::cmdCreateGame(const QStringList &params)
{
QString name = params[0];
QString description = params[1];
QString password = params[2];
int maxPlayers = params[3].toInt();
if (server->getGame(name))
return ReturnMessage::ReturnNameNotFound;
leaveGame();
emit createGame(name, description, password, maxPlayers, this);
return ReturnMessage::ReturnOk;
}
ReturnMessage::ReturnCode ServerSocket::cmdJoinGame(const QStringList &params)
{
QString name = params[0];
QString password = params[1];
if (!server->checkGamePassword(name, password))
return ReturnMessage::ReturnPasswordWrong;
leaveGame();
emit joinGame(name, this);
return ReturnMessage::ReturnOk;
}
ReturnMessage::ReturnCode ServerSocket::cmdLeaveGame(const QStringList &params)
{
leaveGame();
return ReturnMessage::ReturnOk;
}
ReturnMessage::ReturnCode ServerSocket::cmdListPlayers(const QStringList &params)
{
remsg->sendList(game->getPlayerNames());
return ReturnMessage::ReturnOk;
}
ReturnMessage::ReturnCode ServerSocket::cmdSay(const QStringList &params)
{
emit broadcastEvent(QString("say|%1").arg(params[0]), this);
return ReturnMessage::ReturnOk;
}
ReturnMessage::ReturnCode ServerSocket::cmdSubmitDeck(const QStringList &params)
{
PlayerStatus = StatusSubmitDeck;
DeckList.clear();
SideboardList.clear();
return ReturnMessage::ReturnNothing;
}
ReturnMessage::ReturnCode ServerSocket::cmdReadyStart(const QStringList &params)
{
PlayerStatus = StatusReadyStart;
emit broadcastEvent(QString("ready_start"), this);
game->startGameIfReady();
return ReturnMessage::ReturnOk;
}
ReturnMessage::ReturnCode ServerSocket::cmdShuffle(const QStringList &params)
{
getZone("deck")->shuffle(game->rnd);
emit broadcastEvent("shuffle", this);
return ReturnMessage::ReturnOk;
}
ReturnMessage::ReturnCode ServerSocket::cmdDrawCards(const QStringList &params)
{
bool ok;
int number = params[0].toInt(&ok);
if (!ok)
return ReturnMessage::ReturnSyntaxError;
PlayerZone *deck = getZone("deck");
PlayerZone *hand = getZone("hand");
if (deck->cards.size() < number)
return ReturnMessage::ReturnContextError;
for (int i = 0; i < number; ++i) {
Card *card = deck->cards.first();
deck->cards.removeFirst();
hand->cards.append(card);
msg(QString("private|||draw|%1|%2").arg(card->getId()).arg(card->getName()));
}
emit broadcastEvent(QString("draw|%1").arg(number), this);
return ReturnMessage::ReturnOk;
}
ReturnMessage::ReturnCode ServerSocket::cmdMoveCard(const QStringList &params)
{
// ID Karte, Startzone, Zielzone, Koordinaten X, Y, Facedown
bool ok;
int cardid = params[0].toInt(&ok);
if (!ok)
return ReturnMessage::ReturnSyntaxError;
PlayerZone *startzone = getZone(params[1]);
PlayerZone *targetzone = getZone(params[2]);
if ((!startzone) || (!targetzone))
return ReturnMessage::ReturnContextError;
int position = -1;
Card *card = startzone->getCard(cardid, true, &position);
if (!card)
return ReturnMessage::ReturnContextError;
int x = params[3].toInt(&ok);
if (!ok)
return ReturnMessage::ReturnSyntaxError;
int y = 0;
if (targetzone->hasCoords()) {
y = params[4].toInt(&ok);
if (!ok)
return ReturnMessage::ReturnSyntaxError;
}
bool facedown = params[5].toInt(&ok);
if (!ok)
return ReturnMessage::ReturnSyntaxError;
targetzone->insertCard(card, x, y);
QString privateCardName, publicCardName;
if (facedown)
card->setId(newCardId());
if ((!facedown && !card->getFaceDown())
|| (card->getFaceDown() && !facedown && startzone->isPublic() && targetzone->isPublic()))
publicCardName = card->getName();
if ((!facedown && !card->getFaceDown())
|| (card->getFaceDown() && !facedown && startzone->isPublic() && targetzone->isPublic())
|| (!facedown && targetzone->isPrivate()))
privateCardName = card->getName();
card->setFaceDown(facedown);
msg(QString("private|||move_card|%1|%2|%3|%4|%5|%6|%7|%8").arg(card->getId())
.arg(privateCardName)
.arg(startzone->getName())
.arg(position)
.arg(targetzone->getName())
.arg(x)
.arg(y)
.arg(facedown ? 1 : 0));
if ((startzone->isPublic()) || (targetzone->isPublic()))
emit broadcastEvent(QString("move_card|%1|%2|%3|%4|%5|%6|%7|%8").arg(card->getId())
.arg(publicCardName)
.arg(startzone->getName())
.arg(position)
.arg(targetzone->getName())
.arg(x)
.arg(y)
.arg(facedown ? 1 : 0), this);
else
emit broadcastEvent(QString("move_card|||%1|%2|%3|%4|%5|0").arg(startzone->getName())
.arg(position)
.arg(targetzone->getName())
.arg(x)
.arg(y), this);
return ReturnMessage::ReturnOk;
}
ReturnMessage::ReturnCode ServerSocket::cmdCreateToken(const QStringList &params)
{
// zone, cardname, powtough, x, y
// powtough wird erst mal ignoriert
PlayerZone *zone = getZone(params[0]);
if (!zone)
return ReturnMessage::ReturnContextError;
QString cardname = params[1];
int x = params[3].toInt();
int y = params[4].toInt();
int cardid = newCardId();
QString powtough = params[2];
Card *card = new Card(cardname, cardid, x, y);
zone->insertCard(card, x, y);
emit broadcastEvent(QString("create_token|%1|%2|%3|%4|%5|%6").arg(zone->getName())
.arg(cardid)
.arg(cardname)
.arg(powtough)
.arg(x)
.arg(y), this);
return ReturnMessage::ReturnOk;
}
ReturnMessage::ReturnCode ServerSocket::cmdSetCardAttr(const QStringList &params)
{
// zone, card id, attr name, attr value
// card id = -1 => affects all cards in the specified zone
PlayerZone *zone = getZone(params[0]);
if (!zone)
return ReturnMessage::ReturnContextError;
bool ok;
int cardid = params[1].toInt(&ok);
if (!ok)
return ReturnMessage::ReturnSyntaxError;
if (cardid == -1) {
QListIterator<Card *> CardIterator(zone->cards);
while (CardIterator.hasNext())
if (!CardIterator.next()->setAttribute(params[2], params[3], true))
return ReturnMessage::ReturnSyntaxError;
} else {
Card *card = zone->getCard(cardid, false);
if (!card)
return ReturnMessage::ReturnContextError;
if (!card->setAttribute(params[2], params[3], false))
return ReturnMessage::ReturnSyntaxError;
}
emit broadcastEvent(QString("set_card_attr|%1|%2|%3|%4").arg(zone->getName()).arg(cardid).arg(params[2]).arg(params[3]), this);
return ReturnMessage::ReturnOk;
}
ReturnMessage::ReturnCode ServerSocket::cmdIncCounter(const QStringList &params)
{
Counter *c = getCounter(params[0]);
if (!c)
return ReturnMessage::ReturnContextError;
bool ok;
int delta = params[1].toInt(&ok);
if (!ok)
return ReturnMessage::ReturnSyntaxError;
c->setCount(c->getCount() + delta);
emit broadcastEvent(QString("set_counter|%1|%2").arg(params[0]).arg(c->getCount()), this);
return ReturnMessage::ReturnOk;
}
ReturnMessage::ReturnCode ServerSocket::cmdSetCounter(const QStringList &params)
{
Counter *c = getCounter(params[0]);
bool ok;
int count = params[1].toInt(&ok);
if (!ok)
return ReturnMessage::ReturnSyntaxError;
if (!c) {
c = new Counter(params[0], count);
counters << c;
} else
c->setCount(count);
emit broadcastEvent(QString("set_counter|%1|%2").arg(params[0]).arg(count), this);
return ReturnMessage::ReturnOk;
}
ReturnMessage::ReturnCode ServerSocket::cmdDelCounter(const QStringList &params)
{
Counter *c = getCounter(params[0]);
if (!c)
return ReturnMessage::ReturnContextError;
delete c;
counters.removeAt(counters.indexOf(c));
emit broadcastEvent(QString("del_counter|%1").arg(params[0]), this);
return ReturnMessage::ReturnOk;
}
ReturnMessage::ReturnCode ServerSocket::cmdListCounters(const QStringList &params)
{
bool ok;
int player_id = params[0].toInt(&ok);
if (!ok)
return ReturnMessage::ReturnSyntaxError;
ServerSocket *player = game->getPlayer(player_id);
if (!player)
return ReturnMessage::ReturnContextError;
remsg->sendList(player->listCounters());
return ReturnMessage::ReturnOk;
}
ReturnMessage::ReturnCode ServerSocket::cmdListZones(const QStringList &params)
{
bool ok;
int player_id = params[0].toInt(&ok);
if (!ok)
return ReturnMessage::ReturnSyntaxError;
ServerSocket *player = game->getPlayer(player_id);
if (!player)
return ReturnMessage::ReturnContextError;
remsg->sendList(player->listZones());
return ReturnMessage::ReturnOk;
}
ReturnMessage::ReturnCode ServerSocket::cmdDumpZone(const QStringList &params)
{
bool ok;
int player_id = params[0].toInt(&ok);
if (!ok)
return ReturnMessage::ReturnSyntaxError;
int number_cards = params[2].toInt(&ok);
if (!ok)
return ReturnMessage::ReturnSyntaxError;
ServerSocket *player = game->getPlayer(player_id);
if (!player)
return ReturnMessage::ReturnContextError;
PlayerZone *zone = player->getZone(params[1]);
if (!zone)
return ReturnMessage::ReturnContextError;
if (!(zone->isPublic() || (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 == 0); i++) {
Card *tmp = card_iterator.next();
// XXX Face down cards
if (zone->hasIdAccess())
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
result << QString("%1|%2||||||").arg(i).arg(tmp->getName());
}
remsg->sendList(result);
emit broadcastEvent(QString("dump_zone|%1|%2|%3").arg(player_id).arg(zone->getName()).arg(number_cards), this);
return ReturnMessage::ReturnOk;
}
ReturnMessage::ReturnCode ServerSocket::cmdRollDice(const QStringList &params)
{
bool ok;
int sides = params[0].toInt(&ok);
if (!ok)
return ReturnMessage::ReturnSyntaxError;
emit broadcastEvent(QString("roll_dice|%1|%2").arg(sides).arg(game->rnd->getNumber(1, sides)), this);
return ReturnMessage::ReturnOk;
}
ReturnMessage::ReturnCode ServerSocket::cmdSetActivePlayer(const QStringList &params)
{
bool ok;
int active_player = params[0].toInt(&ok);
if (!ok)
return ReturnMessage::ReturnSyntaxError;
if (!game->getPlayer(active_player))
return ReturnMessage::ReturnContextError;
game->setActivePlayer(active_player);
return ReturnMessage::ReturnOk;
}
ReturnMessage::ReturnCode ServerSocket::cmdSetActivePhase(const QStringList &params)
{
bool ok;
int active_phase = params[0].toInt(&ok);
if (!ok)
return ReturnMessage::ReturnSyntaxError;
// XXX Überprüfung, ob die Phase existiert...
game->setActivePhase(active_phase);
return ReturnMessage::ReturnOk;
}
bool ServerSocket::parseCommand(QString line)
{
QStringList params = line.split("|");
// Extract message id
bool conv_ok;
int msgId = params.takeFirst().toInt(&conv_ok);
if (!conv_ok) {
remsg->setMsgId(0);
return remsg->send(ReturnMessage::ReturnSyntaxError);
}
remsg->setMsgId(msgId);
if (params.empty()) {
remsg->setMsgId(0);
return remsg->send(ReturnMessage::ReturnSyntaxError);
}
// Extract command
QString cmd = params.takeFirst();
remsg->setCmd(cmd);
for (int i = 0; i < numberCommands; i++)
if (commandList[i].name == cmd) {
// Check login
if (commandList[i].needsLogin && (authState == PasswordWrong))
return remsg->send(ReturnMessage::ReturnLoginNeeded);
// Check context
if (commandList[i].needsGame && !game)
return remsg->send(ReturnMessage::ReturnContextError);
if (commandList[i].needsStartedGame && !game->getGameStarted())
return remsg->send(ReturnMessage::ReturnContextError);
// Check parameter count
if (commandList[i].numberParams != params.size())
return remsg->send(ReturnMessage::ReturnSyntaxError);
// Call handler function
CommandHandler handler = commandList[i].handler;
return remsg->send((this->*handler)(params));
}
return remsg->send(ReturnMessage::ReturnSyntaxError);
}
PlayerStatusEnum ServerSocket::getStatus()
{
return PlayerStatus;
}
void ServerSocket::setStatus(PlayerStatusEnum status)
{
PlayerStatus = status;
}
void ServerSocket::setGame(ServerGame *g)
{
game = g;
}
QStringList ServerSocket::listCounters()
{
QStringList counter_list;
QListIterator<Counter *> i(counters);
while (i.hasNext()) {
Counter *tmp = i.next();
counter_list << QString("%1|%2").arg(tmp->getName()).arg(tmp->getCount());
}
return counter_list;
}
QStringList ServerSocket::listZones()
{
QStringList zone_list;
QListIterator<PlayerZone *> i(zones);
while (i.hasNext()) {
PlayerZone *tmp = i.next();
zone_list << QString("%1|%2|%3|%4").arg(tmp->getName()).arg(tmp->isPublic()).arg(tmp->hasCoords()).arg(tmp->cards.size());
}
return zone_list;
}
void ServerSocket::msg(const QString &s)
{
qDebug(QString(">>> %1").arg(s).toLatin1());
QTextStream stream(this);
stream.setCodec("UTF-8");
stream << s << endl;
stream.flush();
flush();
}
void ServerSocket::initConnection()
{
msg(QString("welcome||%1").arg(VERSION_STRING));
msg("welcome||.");
}
void ServerSocket::catchSocketError(QAbstractSocket::SocketError socketError)
{
qDebug(QString("socket error: %1").arg(socketError).toLatin1());
deleteLater();
}

View file

@ -17,37 +17,71 @@
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef TESTSERVERSOCKET_H
#define TESTSERVERSOCKET_H
#ifndef SERVERSOCKET_H
#define SERVERSOCKET_H
#include <QTcpSocket>
#include "testserver.h"
#include "testservergame.h"
#include "playerzone.h"
#include "server.h"
#include "returnmessage.h"
#include "counter.h"
class TestServer;
class TestServerGame;
class Server;
class ServerGame;
class PlayerZone;
class Counter;
enum PlayerStatusEnum { StatusNormal, StatusSubmitDeck, StatusReadyStart, StatusPlaying };
class TestServerSocket : public QTcpSocket
class ServerSocket : public QTcpSocket
{
Q_OBJECT
private slots:
void readClient();
void catchSocketError(QAbstractSocket::SocketError socketError);
signals:
void createGame(const QString name, const QString description, const QString password, const int maxPlayers, TestServerSocket *creator);
void joinGame(const QString name, TestServerSocket *player);
void commandReceived(QString cmd, TestServerSocket *player);
void broadcastEvent(const QString &event, TestServerSocket *player);
void createGame(const QString name, const QString description, const QString password, const int maxPlayers, ServerSocket *creator);
void joinGame(const QString name, ServerSocket *player);
void commandReceived(QString cmd, ServerSocket *player);
void broadcastEvent(const QString &event, ServerSocket *player);
void startGameIfReady();
private:
TestServer *server;
TestServerGame *game;
typedef ReturnMessage::ReturnCode (ServerSocket::*CommandHandler)(const QStringList &);
struct CommandProperties {
QString name;
int numberParams;
bool needsLogin;
bool needsGame;
bool needsStartedGame;
CommandHandler handler;
};
static const int numberCommands = 23;
static const CommandProperties commandList[numberCommands];
ReturnMessage::ReturnCode cmdLogin(const QStringList &params);
ReturnMessage::ReturnCode cmdListGames(const QStringList &params);
ReturnMessage::ReturnCode cmdCreateGame(const QStringList &params);
ReturnMessage::ReturnCode cmdJoinGame(const QStringList &params);
ReturnMessage::ReturnCode cmdLeaveGame(const QStringList &params);
ReturnMessage::ReturnCode cmdListPlayers(const QStringList &params);
ReturnMessage::ReturnCode cmdSay(const QStringList &params);
ReturnMessage::ReturnCode cmdSubmitDeck(const QStringList &params);
ReturnMessage::ReturnCode cmdReadyStart(const QStringList &params);
ReturnMessage::ReturnCode cmdShuffle(const QStringList &params);
ReturnMessage::ReturnCode cmdDrawCards(const QStringList &params);
ReturnMessage::ReturnCode cmdMoveCard(const QStringList &params);
ReturnMessage::ReturnCode cmdCreateToken(const QStringList &params);
ReturnMessage::ReturnCode cmdSetCardAttr(const QStringList &params);
ReturnMessage::ReturnCode cmdIncCounter(const QStringList &params);
ReturnMessage::ReturnCode cmdSetCounter(const QStringList &params);
ReturnMessage::ReturnCode cmdDelCounter(const QStringList &params);
ReturnMessage::ReturnCode cmdListCounters(const QStringList &params);
ReturnMessage::ReturnCode cmdListZones(const QStringList &params);
ReturnMessage::ReturnCode cmdDumpZone(const QStringList &params);
ReturnMessage::ReturnCode cmdRollDice(const QStringList &params);
ReturnMessage::ReturnCode cmdSetActivePlayer(const QStringList &params);
ReturnMessage::ReturnCode cmdSetActivePhase(const QStringList &params);
Server *server;
ServerGame *game;
QList<QString> DeckList;
QList<QString> SideboardList;
QList<PlayerZone *> zones;
@ -63,12 +97,13 @@ private:
bool parseCommand(QString line);
PlayerStatusEnum PlayerStatus;
ReturnMessage *remsg;
AuthenticationResult authState;
public:
QString PlayerName;
TestServerSocket(TestServer *_server, QObject *parent = 0);
~TestServerSocket();
ServerSocket(Server *_server, QObject *parent = 0);
~ServerSocket();
void msg(const QString &s);
void setGame(TestServerGame *g);
void setGame(ServerGame *g);
PlayerStatusEnum getStatus();
void setStatus(PlayerStatusEnum status);
void initConnection();

View file

@ -1,20 +0,0 @@
#include "testservergamethread.h"
TestServerGameThread::TestServerGameThread(const QString _name, const QString _description, const QString _password, const int _maxPlayers, TestServerSocket *_creator, QObject *parent)
: QThread(parent), name(_name), description(_description), password(_password), maxPlayers(_maxPlayers), creator(_creator), game(0)
{
}
TestServerGameThread::~TestServerGameThread()
{
if (game)
delete game;
}
void TestServerGameThread::run()
{
game = new TestServerGame(name, description, password, maxPlayers);
emit gameCreated(game, creator);
exec();
}

View file

@ -1,30 +0,0 @@
#ifndef TESTSERVERGAMETHREAD_H
#define TESTSERVERGAMETHREAD_H
#include <QThread>
#include <QMutex>
#include "testservergame.h"
#include "testserversocket.h"
class TestServerGame;
class TestServerSocket;
class TestServerGameThread : public QThread {
Q_OBJECT
signals:
void gameCreated(TestServerGame *_game, TestServerSocket *creator);
private:
QString name;
QString description;
QString password;
int maxPlayers;
TestServerSocket *creator;
TestServerGame *game;
public:
TestServerGameThread(const QString _name, const QString _description, const QString _password, const int _maxPlayers, TestServerSocket *_creator, QObject *parent = 0);
~TestServerGameThread();
TestServerGame *getGame() { return game; }
void run();
};
#endif

View file

@ -1,617 +0,0 @@
/***************************************************************************
* 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 <QStringList>
#include "testserver.h"
#include "testserversocket.h"
#include "version.h"
TestServerSocket::TestServerSocket(TestServer *_server, QObject *parent)
: QTcpSocket(parent), server(_server)
{
remsg = new ReturnMessage(this);
connect(this, SIGNAL(readyRead()), this, SLOT(readClient()));
connect(this, SIGNAL(disconnected()), this, SLOT(deleteLater()));
connect(this, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(catchSocketError(QAbstractSocket::SocketError)));
setTextModeEnabled(true);
PlayerStatus = StatusNormal;
game = 0;
}
TestServerSocket::~TestServerSocket()
{
qDebug("TestServerSocket destructor");
if (game)
game->removePlayer(this);
}
int TestServerSocket::newCardId()
{
return nextCardId++;
}
void TestServerSocket::setName(const QString &name)
{
emit broadcastEvent(QString("name|%1|%2").arg(PlayerName).arg(name), this);
PlayerName = name;
}
PlayerZone *TestServerSocket::getZone(const QString &name)
{
QListIterator<PlayerZone *> ZoneIterator(zones);
while (ZoneIterator.hasNext()) {
PlayerZone *temp = ZoneIterator.next();
if (!temp->getName().compare(name))
return temp;
}
return NULL;
}
Counter *TestServerSocket::getCounter(const QString &name)
{
QListIterator<Counter *> CounterIterator(counters);
while (CounterIterator.hasNext()) {
Counter *temp = CounterIterator.next();
if (!temp->getName().compare(name))
return temp;
}
return NULL;
}
void TestServerSocket::setupZones()
{
// Delete existing zones and counters
clearZones();
// This may need to be customized according to the game rules.
// ------------------------------------------------------------------
// Create zones
PlayerZone *deck = new PlayerZone("deck", false, false, false, false);
zones << deck;
PlayerZone *sb = new PlayerZone("sb", false, false, false, false);
zones << sb;
zones << new PlayerZone("table", true, true, false, true);
zones << new PlayerZone("hand", false, false, true, true);
zones << new PlayerZone("grave", false, true, false, true);
zones << new PlayerZone("rfg", false, true, false, true);
// Create life counter
Counter *life = new Counter("life", 20);
counters << life;
// ------------------------------------------------------------------
// Assign card ids and create deck from decklist
QListIterator<QString> DeckIterator(DeckList);
int i = 0;
while (DeckIterator.hasNext())
deck->cards.append(new TestCard(DeckIterator.next(), i++, 0, 0));
deck->shuffle(game->rnd);
QListIterator<QString> SBIterator(SideboardList);
while (SBIterator.hasNext())
sb->cards.append(new TestCard(SBIterator.next(), i++, 0, 0));
nextCardId = i;
PlayerStatus = StatusPlaying;
broadcastEvent(QString("setup_zones|%1|%2|%3").arg(getCounter("life")->getCount())
.arg(deck->cards.size())
.arg(getZone("sb")->cards.size()), this);
}
void TestServerSocket::clearZones()
{
for (int i = 0; i < zones.size(); i++)
delete zones.at(i);
zones.clear();
for (int i = 0; i < counters.size(); i++)
delete counters.at(i);
counters.clear();
}
void TestServerSocket::leaveGame()
{
if (!game)
return;
game->removePlayer(this);
game = 0;
PlayerStatus = StatusNormal;
clearZones();
moveToThread(server->thread());
}
void TestServerSocket::readClient()
{
QTextStream *stream = new QTextStream(this);
stream->setCodec("UTF-8");
QStringList lines;
// Before parsing, everything has to be buffered so that the stream
// can be deleted in order to avoid problems when moving the object
// to another thread while this function is still running.
for (;;) {
QString line = stream->readLine();
if (line.isNull())
break;
lines << line;
}
delete stream;
QStringListIterator i(lines);
while (i.hasNext()) {
QString line = i.next();
qDebug(QString("<<< %1").arg(line).toLatin1());
switch (PlayerStatus) {
case StatusNormal:
case StatusReadyStart:
case StatusPlaying:
parseCommand(line);
break;
case StatusSubmitDeck:
QString card = line;
if (!card.compare(".")) {
PlayerStatus = StatusNormal;
remsg->send();
} else if (card.startsWith("SB:"))
SideboardList << card.mid(3);
else
DeckList << card;
}
}
}
bool TestServerSocket::parseCommand(QString line)
{
QStringList params = line.split("|");
// Extract message id
bool conv_ok;
int msgId = params.takeFirst().toInt(&conv_ok);
if (!conv_ok) {
remsg->setMsgId(0);
return remsg->send("syntax", false);
}
remsg->setMsgId(msgId);
if (params.empty()) {
remsg->setMsgId(0);
return remsg->send("syntax", false);
}
// Extract command
QString cmd = params.takeFirst();
remsg->setCmd(cmd);
// parse command
if (!cmd.compare("list_games", Qt::CaseInsensitive)) {
remsg->send();
QList<TestServerGame *> gameList = server->listOpenGames();
QListIterator<TestServerGame *> gameListIterator(gameList);
QStringList result;
while (gameListIterator.hasNext()) {
TestServerGame *tmp = gameListIterator.next();
tmp->mutex->lock();
result << QString("%1|%2|%3|%4|%5").arg(tmp->name)
.arg(tmp->description)
.arg(tmp->password == "" ? 0 : 1)
.arg(tmp->getPlayerCount())
.arg(tmp->maxPlayers);
tmp->mutex->unlock();
}
remsg->sendList(result);
} else if (!cmd.compare("create_game", Qt::CaseInsensitive)) {
if (params.size() != 4)
return remsg->send("syntax", false);
QString name = params[0];
QString description = params[1];
QString password = params[2];
int maxPlayers = params[3].toInt();
if (server->getGame(name))
return remsg->send("name_not_found", false);
remsg->send();
leaveGame();
emit createGame(name, description, password, maxPlayers, this);
} else if (!cmd.compare("join_game", Qt::CaseInsensitive)) {
if (params.size() != 2)
return remsg->send("syntax", false);
QString name = params[0];
QString password = params[1];
if (!server->checkGamePassword(name, password))
return remsg->send("wrong_password", false);
remsg->send();
leaveGame();
emit joinGame(name, this);
} else if (!cmd.compare("leave_game", Qt::CaseInsensitive)) {
remsg->send();
leaveGame();
} else if (!cmd.compare("set_name", Qt::CaseInsensitive)) {
if (params.size() != 1)
return remsg->send("syntax", false);
remsg->send();
setName(params[0]);
} else if (!cmd.compare("list_players", Qt::CaseInsensitive)) {
if (!game)
return remsg->send("game_state", false);
remsg->send();
remsg->sendList(game->getPlayerNames());
} else if (!cmd.compare("say", Qt::CaseInsensitive)) {
if (params.size() != 1)
return remsg->send("syntax", false);
remsg->send();
emit broadcastEvent(QString("say|%1").arg(params[0]), this);
} else if (!cmd.compare("submit_deck", Qt::CaseInsensitive)) {
PlayerStatus = StatusSubmitDeck;
DeckList.clear();
SideboardList.clear();
} else if (!cmd.compare("shuffle", Qt::CaseInsensitive)) {
if (!game)
return remsg->send("game_state", false);
if (!game->getGameStarted())
return remsg->send("game_state", false);
getZone("deck")->shuffle(game->rnd);
remsg->send();
emit broadcastEvent("shuffle", this);
} else if (!cmd.compare("ready_start", Qt::CaseInsensitive)) {
if (!game)
return remsg->send("game_state", false);
remsg->send();
PlayerStatus = StatusReadyStart;
emit broadcastEvent(QString("ready_start"), this);
game->startGameIfReady();
} else if (!cmd.compare("draw_cards", Qt::CaseInsensitive)) {
if (params.size() != 1)
return remsg->send("syntax", false);
bool ok;
int number = params[0].toInt(&ok);
if (!ok)
return remsg->send("syntax", false);
PlayerZone *deck = getZone("deck");
PlayerZone *hand = getZone("hand");
if (deck->cards.size() < number)
return remsg->send("game_state", false);
remsg->send();
for (int i = 0; i < number; ++i) {
TestCard *card = deck->cards.first();
deck->cards.removeFirst();
hand->cards.append(card);
msg(QString("private|||draw|%1|%2").arg(card->getId()).arg(card->getName()));
}
emit broadcastEvent(QString("draw|%1").arg(number), this);
} else if (!cmd.compare("move_card", Qt::CaseInsensitive)) {
// ID Karte, Startzone, Zielzone, Koordinaten X, Y, Facedown
if (params.size() != 6)
return remsg->send("syntax", false);
bool ok;
int cardid = params[0].toInt(&ok);
if (!ok)
return remsg->send("syntax", false);
PlayerZone *startzone = getZone(params[1]);
PlayerZone *targetzone = getZone(params[2]);
if ((!startzone) || (!targetzone))
return remsg->send("game_state", false);
int position = -1;
TestCard *card = startzone->getCard(cardid, true, &position);
if (!card)
return remsg->send("game_state", false);
int x = params[3].toInt(&ok);
if (!ok)
return remsg->send("syntax", false);
int y = 0;
if (targetzone->hasCoords()) {
y = params[4].toInt(&ok);
if (!ok)
return remsg->send("syntax", false);
}
bool facedown = params[5].toInt(&ok);
if (!ok)
return remsg->send("syntax", false);
remsg->send();
targetzone->insertCard(card, x, y);
QString privateCardName, publicCardName;
if (facedown)
card->setId(newCardId());
if ((!facedown && !card->getFaceDown())
|| (card->getFaceDown() && !facedown && startzone->isPublic() && targetzone->isPublic()))
publicCardName = card->getName();
if ((!facedown && !card->getFaceDown())
|| (card->getFaceDown() && !facedown && startzone->isPublic() && targetzone->isPublic())
|| (!facedown && targetzone->isPrivate()))
privateCardName = card->getName();
card->setFaceDown(facedown);
msg(QString("private|||move_card|%1|%2|%3|%4|%5|%6|%7|%8").arg(card->getId())
.arg(privateCardName)
.arg(startzone->getName())
.arg(position)
.arg(targetzone->getName())
.arg(x)
.arg(y)
.arg(facedown ? 1 : 0));
if ((startzone->isPublic()) || (targetzone->isPublic()))
emit broadcastEvent(QString("move_card|%1|%2|%3|%4|%5|%6|%7|%8").arg(card->getId())
.arg(publicCardName)
.arg(startzone->getName())
.arg(position)
.arg(targetzone->getName())
.arg(x)
.arg(y)
.arg(facedown ? 1 : 0), this);
else
emit broadcastEvent(QString("move_card|||%1|%2|%3|%4|%5|0").arg(startzone->getName())
.arg(position)
.arg(targetzone->getName())
.arg(x)
.arg(y), this);
} else if (!cmd.compare("create_token", Qt::CaseInsensitive)) {
// zone, cardname, powtough, x, y
// powtough wird erst mal ignoriert
if (params.size() != 5)
return remsg->send("syntax", false);
PlayerZone *zone = getZone(params[0]);
if (!zone)
return remsg->send("game_state", false);
QString cardname = params[1];
int x = params[3].toInt();
int y = params[4].toInt();
int cardid = newCardId();
QString powtough = params[2];
remsg->send();
TestCard *card = new TestCard(cardname, cardid, x, y);
zone->insertCard(card, x, y);
emit broadcastEvent(QString("create_token|%1|%2|%3|%4|%5|%6").arg(zone->getName())
.arg(cardid)
.arg(cardname)
.arg(powtough)
.arg(x)
.arg(y), this);
} else if (!cmd.compare("set_card_attr", Qt::CaseInsensitive)) {
if (params.size() != 4)
return remsg->send("syntax", false);
// zone, card id, attr name, attr value
// card id = -1 => affects all cards in the specified zone
PlayerZone *zone = getZone(params[0]);
if (!zone)
return remsg->send("game_state", false);
bool ok;
int cardid = params[1].toInt(&ok);
if (!ok)
return remsg->send("syntax", false);
if (cardid == -1) {
QListIterator<TestCard *> CardIterator(zone->cards);
while (CardIterator.hasNext())
if (!CardIterator.next()->setAttribute(params[2], params[3], true))
return remsg->send("syntax", false);
} else {
TestCard *card = zone->getCard(cardid, false);
if (!card)
return remsg->send("game_state", false);
if (!card->setAttribute(params[2], params[3], false))
return remsg->send("syntax", false);
}
remsg->send();
emit broadcastEvent(QString("set_card_attr|%1|%2|%3|%4").arg(zone->getName()).arg(cardid).arg(params[2]).arg(params[3]), this);
} else if (!cmd.compare("inc_counter", Qt::CaseInsensitive)) {
if (params.size() != 2)
return remsg->send("syntax", false);
Counter *c = getCounter(params[0]);
if (!c)
return remsg->send("game_state", false);
bool ok;
int delta = params[1].toInt(&ok);
if (!ok)
return remsg->send("syntax", false);
remsg->send();
c->setCount(c->getCount() + delta);
emit broadcastEvent(QString("set_counter|%1|%2").arg(params[0]).arg(c->getCount()), this);
} else if (!cmd.compare("set_counter", Qt::CaseInsensitive)) {
if (params.size() != 2)
return remsg->send("syntax", false);
Counter *c = getCounter(params[0]);
bool ok;
int count = params[1].toInt(&ok);
if (!ok)
return remsg->send("syntax", false);
if (!c) {
c = new Counter(params[0], count);
counters << c;
} else
c->setCount(count);
remsg->send();
emit broadcastEvent(QString("set_counter|%1|%2").arg(params[0]).arg(count), this);
} else if (!cmd.compare("del_counter", Qt::CaseInsensitive)) {
if (params.size() != 1)
return remsg->send("syntax", false);
Counter *c = getCounter(params[0]);
if (!c)
return remsg->send("game_state", false);
delete c;
counters.removeAt(counters.indexOf(c));
remsg->send();
emit broadcastEvent(QString("del_counter|%1").arg(params[0]), this);
} else if (!cmd.compare("list_counters", Qt::CaseInsensitive)) {
if (params.size() != 1)
return remsg->send("syntax", false);
bool ok;
int player_id = params[0].toInt(&ok);
if (!ok)
return remsg->send("syntax", false);
TestServerSocket *player = game->getPlayer(player_id);
if (!player)
return remsg->send("game_state", false);
remsg->send();
remsg->sendList(player->listCounters());
} else if (!cmd.compare("list_zones", Qt::CaseInsensitive)) {
if (params.size() != 1)
return remsg->send("syntax", false);
bool ok;
int player_id = params[0].toInt(&ok);
if (!ok)
return remsg->send("syntax", false);
TestServerSocket *player = game->getPlayer(player_id);
if (!player)
return remsg->send("game_state", false);
remsg->send();
remsg->sendList(player->listZones());
} else if (!cmd.compare("dump_zone", Qt::CaseInsensitive)) {
if (params.size() != 3)
return remsg->send("syntax", false);
bool ok;
int player_id = params[0].toInt(&ok);
if (!ok)
return remsg->send("syntax", false);
int number_cards = params[2].toInt(&ok);
if (!ok)
return remsg->send("syntax", false);
TestServerSocket *player = game->getPlayer(player_id);
if (!player)
return remsg->send("game_state", false);
PlayerZone *zone = player->getZone(params[1]);
if (!zone)
return remsg->send("game_state", false);
if (!(zone->isPublic() || (player_id == PlayerId)))
return remsg->send("game_state", false);
remsg->send();
QListIterator<TestCard *> card_iterator(zone->cards);
QStringList result;
for (int i = 0; card_iterator.hasNext() && (i < number_cards || number_cards == 0); i++) {
TestCard *tmp = card_iterator.next();
// XXX Face down cards
if (zone->hasIdAccess())
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
result << QString("%1|%2||||||").arg(i).arg(tmp->getName());
}
remsg->sendList(result);
emit broadcastEvent(QString("dump_zone|%1|%2|%3").arg(player_id).arg(zone->getName()).arg(number_cards), this);
} else if (!cmd.compare("roll_dice", Qt::CaseInsensitive)) {
if (params.size() != 1)
return remsg->send("syntax", false);
bool ok;
int sides = params[0].toInt(&ok);
if (!ok)
return remsg->send("syntax", false);
remsg->send();
emit broadcastEvent(QString("roll_dice|%1|%2").arg(sides).arg(game->rnd->getNumber(1, sides)), this);
} else if (!cmd.compare("set_active_player", Qt::CaseInsensitive)) {
if (params.size() != 1)
return remsg->send("syntax", false);
bool ok;
int active_player = params[0].toInt(&ok);
if (!ok)
return remsg->send("syntax", false);
if (!game->getPlayer(active_player))
return remsg->send("game_state", false);
remsg->send();
game->setActivePlayer(active_player);
} else if (!cmd.compare("set_active_phase", Qt::CaseInsensitive)) {
if (params.size() != 1)
return remsg->send("syntax", false);
bool ok;
int active_phase = params[0].toInt(&ok);
if (!ok)
return remsg->send("syntax", false);
// XXX Überprüfung, ob die Phase existiert...
remsg->send();
game->setActivePhase(active_phase);
} else
return remsg->send("syntax", false);
return true;
}
PlayerStatusEnum TestServerSocket::getStatus()
{
return PlayerStatus;
}
void TestServerSocket::setStatus(PlayerStatusEnum status)
{
PlayerStatus = status;
}
void TestServerSocket::setGame(TestServerGame *g)
{
game = g;
}
QStringList TestServerSocket::listCounters()
{
QStringList counter_list;
QListIterator<Counter *> i(counters);
while (i.hasNext()) {
Counter *tmp = i.next();
counter_list << QString("%1|%2").arg(tmp->getName()).arg(tmp->getCount());
}
return counter_list;
}
QStringList TestServerSocket::listZones()
{
QStringList zone_list;
QListIterator<PlayerZone *> i(zones);
while (i.hasNext()) {
PlayerZone *tmp = i.next();
zone_list << QString("%1|%2|%3|%4").arg(tmp->getName()).arg(tmp->isPublic()).arg(tmp->hasCoords()).arg(tmp->cards.size());
}
return zone_list;
}
void TestServerSocket::msg(const QString &s)
{
qDebug(QString(">>> %1").arg(s).toLatin1());
QTextStream stream(this);
stream.setCodec("UTF-8");
stream << s << endl;
stream.flush();
flush();
}
void TestServerSocket::initConnection()
{
msg(QString("welcome||%1").arg(VERSION_STRING));
msg("welcome||.");
}
void TestServerSocket::catchSocketError(QAbstractSocket::SocketError socketError)
{
qDebug(QString("socket error: %1").arg(socketError).toLatin1());
deleteLater();
}

View file

@ -18,4 +18,4 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
const char *VERSION_STRING = "Testserver 0.20090407";
const char *VERSION_STRING = "Testserver 0.20090408";