Merge branch 'master' of git://cockatrice.git.sourceforge.net/gitroot/cockatrice/cockatrice into translation

This commit is contained in:
Army Frank 2011-01-05 08:42:03 +09:00
commit a1028e927a
69 changed files with 4118 additions and 3090 deletions

View file

@ -7,7 +7,8 @@ OBJECTS_DIR = build
RESOURCES = cockatrice.qrc
QT += network svg
HEADERS += src/counter.h \
HEADERS += src/abstractcounter.h \
src/counter_general.h \
src/dlg_creategame.h \
src/dlg_connect.h \
src/dlg_create_token.h \
@ -52,11 +53,12 @@ HEADERS += src/counter.h \
src/arrowtarget.h \
src/tab.h \
src/tab_server.h \
src/tab_chatchannel.h \
src/tab_room.h \
src/tab_message.h \
src/tab_game.h \
src/tab_deck_storage.h \
src/tab_supervisor.h \
src/userlist.h \
src/remotedecklist_treewidget.h \
src/deckview.h \
src/playerlistwidget.h \
@ -78,14 +80,15 @@ HEADERS += src/counter.h \
../common/server_arrow.h \
../common/server_card.h \
../common/server_cardzone.h \
../common/server_chatchannel.h \
../common/server_room.h \
../common/server_counter.h \
../common/server_game.h \
../common/server_player.h \
../common/server_protocolhandler.h \
../common/server_arrowtarget.h
SOURCES += src/counter.cpp \
SOURCES += src/abstractcounter.cpp \
src/counter_general.cpp \
src/dlg_creategame.cpp \
src/dlg_connect.cpp \
src/dlg_create_token.cpp \
@ -130,11 +133,12 @@ SOURCES += src/counter.cpp \
src/arrowitem.cpp \
src/arrowtarget.cpp \
src/tab_server.cpp \
src/tab_chatchannel.cpp \
src/tab_room.cpp \
src/tab_message.cpp \
src/tab_game.cpp \
src/tab_deck_storage.cpp \
src/tab_supervisor.cpp \
src/userlist.cpp \
src/remotedecklist_treewidget.cpp \
src/deckview.cpp \
src/playerlistwidget.cpp \
@ -154,7 +158,7 @@ SOURCES += src/counter.cpp \
../common/server.cpp \
../common/server_card.cpp \
../common/server_cardzone.cpp \
../common/server_chatchannel.cpp \
../common/server_room.cpp \
../common/server_game.cpp \
../common/server_player.cpp \
../common/server_protocolhandler.cpp

View file

@ -11,7 +11,7 @@ class QTimer;
const int CARD_WIDTH = 72;
const int CARD_HEIGHT = 102;
class AbstractCardItem : public QObject, public ArrowTarget {
class AbstractCardItem : public ArrowTarget {
Q_OBJECT
protected:
CardInfo *info;

View file

@ -32,11 +32,10 @@ void AbstractClient::processProtocolItem(ProtocolItem *item)
GenericEvent *genericEvent = qobject_cast<GenericEvent *>(item);
if (genericEvent) {
switch (genericEvent->getItemId()) {
case ItemId_Event_ListGames: emit listGamesEventReceived(qobject_cast<Event_ListGames *>(item)); break;
case ItemId_Event_UserJoined: emit userJoinedEventReceived(qobject_cast<Event_UserJoined *>(item)); break;
case ItemId_Event_UserLeft: emit userLeftEventReceived(qobject_cast<Event_UserLeft *>(item)); break;
case ItemId_Event_ServerMessage: emit serverMessageEventReceived(qobject_cast<Event_ServerMessage *>(item)); break;
case ItemId_Event_ListChatChannels: emit listChatChannelsEventReceived(qobject_cast<Event_ListChatChannels *>(item)); break;
case ItemId_Event_ListRooms: emit listRoomsEventReceived(qobject_cast<Event_ListRooms *>(item)); break;
case ItemId_Event_GameJoined: emit gameJoinedEventReceived(qobject_cast<Event_GameJoined *>(item)); break;
case ItemId_Event_Message: emit messageEventReceived(qobject_cast<Event_Message *>(item)); break;
}
@ -53,11 +52,11 @@ void AbstractClient::processProtocolItem(ProtocolItem *item)
return;
}
ChatEvent *chatEvent = qobject_cast<ChatEvent *>(item);
if (chatEvent) {
emit chatEventReceived(chatEvent);
if (chatEvent->getReceiverMayDelete())
delete chatEvent;
RoomEvent *roomEvent = qobject_cast<RoomEvent *>(item);
if (roomEvent) {
emit roomEventReceived(roomEvent);
if (roomEvent->getReceiverMayDelete())
delete roomEvent;
return;
}
}
@ -75,4 +74,3 @@ void AbstractClient::sendCommand(Command *cmd)
{
sendCommandContainer(new CommandContainer(QList<Command *>() << cmd));
}

View file

@ -10,13 +10,13 @@ class ProtocolItem;
class ProtocolResponse;
class TopLevelProtocolItem;
class CommandContainer;
class ChatEvent;
class RoomEvent;
class GameEventContainer;
class Event_ListGames;
class Event_UserJoined;
class Event_UserLeft;
class Event_ServerMessage;
class Event_ListChatChannels;
class Event_ListRooms;
class Event_GameJoined;
class Event_Message;
@ -35,18 +35,18 @@ signals:
void statusChanged(ClientStatus _status);
void serverError(ResponseCode resp);
// Chat events
void chatEventReceived(ChatEvent *event);
// Room events
void roomEventReceived(RoomEvent *event);
// Game events
void gameEventContainerReceived(GameEventContainer *event);
// Generic events
void listGamesEventReceived(Event_ListGames *event);
void userJoinedEventReceived(Event_UserJoined *event);
void userLeftEventReceived(Event_UserLeft *event);
void serverMessageEventReceived(Event_ServerMessage *event);
void listChatChannelsEventReceived(Event_ListChatChannels *event);
void listRoomsEventReceived(Event_ListRooms *event);
void gameJoinedEventReceived(Event_GameJoined *event);
void messageEventReceived(Event_Message *event);
void userInfoChanged(ServerInfo_User *userInfo);
protected slots:
void processProtocolItem(ProtocolItem *item);
protected:

View file

@ -1,16 +1,17 @@
#include "counter.h"
#include "abstractcounter.h"
#include "player.h"
#include "protocol_items.h"
#include <QPainter>
#include <QMenu>
#include <QAction>
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsSceneHoverEvent>
Counter::Counter(Player *_player, int _id, const QString &_name, QColor _color, int _radius, int _value, QGraphicsItem *parent)
: QGraphicsItem(parent), player(_player), id(_id), name(_name), color(_color), radius(_radius), value(_value), aDec(0), aInc(0), dialogSemaphore(false), deleteAfterDialog(false)
AbstractCounter::AbstractCounter(Player *_player, int _id, const QString &_name, bool _shownInCounterArea, int _value, QGraphicsItem *parent)
: QGraphicsItem(parent), player(_player), id(_id), name(_name), value(_value), hovered(false), aDec(0), aInc(0), dialogSemaphore(false), deleteAfterDialog(false), shownInCounterArea(_shownInCounterArea)
{
if (radius > Player::counterAreaWidth / 2)
radius = Player::counterAreaWidth / 2;
setAcceptsHoverEvents(true);
if (player->getLocal()) {
menu = new QMenu(name);
aSet = new QAction(this);
@ -36,12 +37,12 @@ Counter::Counter(Player *_player, int _id, const QString &_name, QColor _color,
retranslateUi();
}
Counter::~Counter()
AbstractCounter::~AbstractCounter()
{
delete menu;
}
void Counter::delCounter()
void AbstractCounter::delCounter()
{
if (dialogSemaphore)
deleteAfterDialog = true;
@ -49,14 +50,14 @@ void Counter::delCounter()
deleteLater();
}
void Counter::retranslateUi()
void AbstractCounter::retranslateUi()
{
if (menu) {
aSet->setText(tr("&Set counter..."));
}
}
void Counter::setShortcutsActive()
void AbstractCounter::setShortcutsActive()
{
if (name == "life") {
aSet->setShortcut(tr("Ctrl+L"));
@ -65,7 +66,7 @@ void Counter::setShortcutsActive()
}
}
void Counter::setShortcutsInactive()
void AbstractCounter::setShortcutsInactive()
{
if (name == "life") {
aSet->setShortcut(QKeySequence());
@ -74,31 +75,13 @@ void Counter::setShortcutsInactive()
}
}
QRectF Counter::boundingRect() const
{
return QRectF(0, 0, radius * 2, radius * 2);
}
void Counter::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/)
{
painter->setBrush(QBrush(color));
painter->drawEllipse(boundingRect());
if (value) {
QFont f("Serif");
f.setPixelSize(radius * 0.8);
f.setWeight(QFont::Bold);
painter->setFont(f);
painter->drawText(boundingRect(), Qt::AlignCenter, QString::number(value));
}
}
void Counter::setValue(int _value)
void AbstractCounter::setValue(int _value)
{
value = _value;
update();
}
void Counter::mousePressEvent(QGraphicsSceneMouseEvent *event)
void AbstractCounter::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
player->sendGameCommand(new Command_IncCounter(-1, id, 1));
@ -114,13 +97,25 @@ void Counter::mousePressEvent(QGraphicsSceneMouseEvent *event)
event->ignore();
}
void Counter::incrementCounter()
void AbstractCounter::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
hovered = true;
update();
}
void AbstractCounter::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
hovered = false;
update();
}
void AbstractCounter::incrementCounter()
{
int delta = static_cast<QAction *>(sender())->data().toInt();
player->sendGameCommand(new Command_IncCounter(-1, id, delta));
}
void Counter::setCounter()
void AbstractCounter::setCounter()
{
bool ok;
dialogSemaphore = true;

View file

@ -7,35 +7,36 @@ class Player;
class QMenu;
class QAction;
class Counter : public QObject, public QGraphicsItem {
class AbstractCounter : public QObject, public QGraphicsItem {
Q_OBJECT
private:
protected:
Player *player;
int id;
QString name;
QColor color;
int radius;
int value;
bool hovered;
void mousePressEvent(QGraphicsSceneMouseEvent *event);
void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
private:
QAction *aSet, *aDec, *aInc;
QMenu *menu;
bool dialogSemaphore, deleteAfterDialog;
bool shownInCounterArea;
private slots:
void incrementCounter();
void setCounter();
protected:
void mousePressEvent(QGraphicsSceneMouseEvent *event);
public:
Counter(Player *_player, int _id, const QString &_name, QColor _color, int _radius, int _value, QGraphicsItem *parent = 0);
~Counter();
QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
AbstractCounter(Player *_player, int _id, const QString &_name, bool _shownInCounterArea, int _value, QGraphicsItem *parent = 0);
~AbstractCounter();
QMenu *getMenu() const { return menu; }
void retranslateUi();
int getId() const { return id; }
QString getName() const { return name; }
bool getShownInCounterArea() const { return shownInCounterArea; }
int getValue() const { return value; }
void setValue(int _value);
void delCounter();

View file

@ -12,11 +12,12 @@ enum GraphicsItemType {
typeOther = QGraphicsItem::UserType + 6
};
class AbstractGraphicsItem : public QGraphicsItem {
class AbstractGraphicsItem : public QObject, public QGraphicsItem {
Q_OBJECT
protected:
void paintNumberEllipse(int number, int radius, const QColor &color, int position, int count, QPainter *painter);
public:
AbstractGraphicsItem(QGraphicsItem *parent = 0) : QGraphicsItem(parent) { }
AbstractGraphicsItem(QGraphicsItem *parent = 0) : QObject(), QGraphicsItem(parent) { }
};
#endif

View file

@ -13,7 +13,7 @@
ArrowItem::ArrowItem(Player *_player, int _id, ArrowTarget *_startItem, ArrowTarget *_targetItem, const QColor &_color)
: QGraphicsItem(), player(_player), id(_id), startItem(_startItem), targetItem(_targetItem), color(_color), fullColor(true)
{
qDebug() << "ArrowItem constructor: startItem=" << startItem;
qDebug() << "ArrowItem constructor: startItem=" << static_cast<QGraphicsItem *>(startItem);
setZValue(2000000005);
if (startItem)

View file

@ -14,7 +14,7 @@ class QAction;
class QPainter;
class CardDragItem;
class CardZone : public QObject, public AbstractGraphicsItem {
class CardZone : public AbstractGraphicsItem {
Q_OBJECT
protected:
Player *player;

View file

@ -0,0 +1,26 @@
#include "counter_general.h"
#include <QPainter>
GeneralCounter::GeneralCounter(Player *_player, int _id, const QString &_name, const QColor &_color, int _radius, int _value, QGraphicsItem *parent)
: AbstractCounter(_player, _id, _name, true, _value, parent), color(_color), radius(_radius)
{
}
QRectF GeneralCounter::boundingRect() const
{
return QRectF(0, 0, radius * 2, radius * 2);
}
void GeneralCounter::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/)
{
painter->setBrush(QBrush(color));
painter->drawEllipse(boundingRect());
if (value) {
QFont f("Serif");
f.setPixelSize(radius * 0.8);
f.setWeight(QFont::Bold);
painter->setFont(f);
painter->drawText(boundingRect(), Qt::AlignCenter, QString::number(value));
}
}

View file

@ -0,0 +1,17 @@
#ifndef COUNTER_GENERAL_H
#define COUNTER_GENERAL_H
#include "abstractcounter.h"
class GeneralCounter : public AbstractCounter {
Q_OBJECT
private:
QColor color;
int radius;
public:
GeneralCounter(Player *_player, int _id, const QString &_name, const QColor &_color, int _radius, int _value, QGraphicsItem *parent = 0);
QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
};
#endif

View file

@ -11,8 +11,8 @@
#include "dlg_creategame.h"
#include "protocol_items.h"
DlgCreateGame::DlgCreateGame(AbstractClient *_client, QWidget *parent)
: QDialog(parent), client(_client)
DlgCreateGame::DlgCreateGame(AbstractClient *_client, int _roomId, QWidget *parent)
: QDialog(parent), client(_client), roomId(_roomId)
{
descriptionLabel = new QLabel(tr("&Description:"));
descriptionEdit = new QLineEdit;
@ -77,6 +77,7 @@ DlgCreateGame::DlgCreateGame(AbstractClient *_client, QWidget *parent)
void DlgCreateGame::actOK()
{
Command_CreateGame *createCommand = new Command_CreateGame(
roomId,
descriptionEdit->text(),
passwordEdit->text(),
maxPlayersEdit->value(),

View file

@ -14,13 +14,14 @@ class QSpinBox;
class DlgCreateGame : public QDialog {
Q_OBJECT
public:
DlgCreateGame(AbstractClient *_client, QWidget *parent = 0);
DlgCreateGame(AbstractClient *_client, int _roomId, QWidget *parent = 0);
private slots:
void actOK();
void checkResponse(ResponseCode response);
void spectatorsAllowedChanged(int state);
private:
AbstractClient *client;
int roomId;
QGroupBox *spectatorsGroupBox;
QLabel *descriptionLabel, *passwordLabel, *maxPlayersLabel;

View file

@ -82,7 +82,7 @@ void GameScene::toggleZoneView(Player *player, const QString &zoneName, int numb
}
}
ZoneViewWidget *item = new ZoneViewWidget(player, player->getZones().value(zoneName), numberCards);
ZoneViewWidget *item = new ZoneViewWidget(player, player->getZones().value(zoneName), numberCards, false);
views.append(item);
connect(item, SIGNAL(closePressed(ZoneViewWidget *)), this, SLOT(removeZoneView(ZoneViewWidget *)));
addItem(item);
@ -91,7 +91,7 @@ void GameScene::toggleZoneView(Player *player, const QString &zoneName, int numb
void GameScene::addRevealedZoneView(Player *player, CardZone *zone, const QList<ServerInfo_Card *> &cardList)
{
ZoneViewWidget *item = new ZoneViewWidget(player, zone, -2, cardList);
ZoneViewWidget *item = new ZoneViewWidget(player, zone, -2, true, cardList);
views.append(item);
connect(item, SIGNAL(closePressed(ZoneViewWidget *)), this, SLOT(removeZoneView(ZoneViewWidget *)));
addItem(item);

View file

@ -7,7 +7,7 @@
class QPainter;
class QPixmap;
class HandCounter : public QObject, public AbstractGraphicsItem {
class HandCounter : public AbstractGraphicsItem {
Q_OBJECT
private:
int number;

View file

@ -66,6 +66,9 @@ void HandZone::reorganizeCards()
const int xPadding = 5;
qreal totalWidth = boundingRect().width() - 2 * xPadding;
qreal cardWidth = cards.at(0)->boundingRect().width();
if (cardWidth * cardCount < totalWidth)
cardWidth += 5;
for (int i = 0; i < cardCount; i++) {
CardItem *c = cards.at(i);

View file

@ -7,6 +7,7 @@ LocalClient::LocalClient(LocalServerInterface *_lsi, const QString &_playerName,
{
connect(lsi, SIGNAL(itemToClient(ProtocolItem *)), this, SLOT(itemFromServer(ProtocolItem *)));
sendCommand(new Command_Login(_playerName, QString()));
sendCommand(new Command_JoinRoom(0));
}
LocalClient::~LocalClient()

View file

@ -1,9 +1,11 @@
#include "localserver.h"
#include "localserverinterface.h"
#include "server_room.h"
LocalServer::LocalServer(QObject *parent)
: Server(parent)
{
addRoom(new Server_Room(0, QString(), QString(), false, QString(), this));
}
LocalServer::~LocalServer()

View file

@ -181,7 +181,7 @@ void MessageLogWidget::logMoveCard(Player *player, QString cardName, CardZone *s
{
QString startName = startZone->getName();
QString targetName = targetZone->getName();
if (((startName == "table") && (targetName == "table")) || ((startName == "hand") && (targetName == "hand")))
if (((startName == "table") && (targetName == "table") && (startZone == targetZone)) || ((startName == "hand") && (targetName == "hand")))
return;
QPair<QString, QString> temp = getFromStr(startZone, cardName, oldX);
bool cardNameContainsStartZone = false;
@ -190,6 +190,18 @@ void MessageLogWidget::logMoveCard(Player *player, QString cardName, CardZone *s
cardName = temp.first;
}
QString fromStr = temp.second;
QString cardStr;
if (cardNameContainsStartZone)
cardStr = cardName;
else if (cardName.isEmpty())
cardStr = tr("a card");
else
cardStr = QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(cardName));
if ((startName == "table") && (targetName == "table")) {
append(tr("%1 gives %2 control over %3.").arg(sanitizeHtml(player->getName())).arg(sanitizeHtml(targetZone->getPlayer()->getName())).arg(cardStr));
return;
}
QString finalStr;
if (targetName == "table")
@ -214,14 +226,6 @@ void MessageLogWidget::logMoveCard(Player *player, QString cardName, CardZone *s
else if (targetName == "stack")
finalStr = tr("%1 plays %2%3.");
QString cardStr;
if (cardNameContainsStartZone)
cardStr = cardName;
else if (cardName.isEmpty())
cardStr = tr("a card");
else
cardStr = QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(cardName));
append(finalStr.arg(sanitizeHtml(player->getName())).arg(cardStr).arg(fromStr).arg(newX));
}

View file

@ -1,7 +1,7 @@
#include "player.h"
#include "cardzone.h"
#include "playertarget.h"
#include "counter.h"
#include "counter_general.h"
#include "arrowitem.h"
#include "zoneviewzone.h"
#include "zoneviewwidget.h"
@ -32,26 +32,28 @@ Player::Player(ServerInfo_User *info, int _id, bool _local, TabGame *_parent)
updateBgPixmap();
playerTarget = new PlayerTarget(this);
playerTarget->setPos(QPointF(counterAreaWidth + (CARD_HEIGHT + 5 - playerTarget->boundingRect().width()) / 2.0, 5));
qreal avatarMargin = (counterAreaWidth + CARD_HEIGHT + 15 - playerTarget->boundingRect().width()) / 2.0;
playerTarget->setPos(QPointF(avatarMargin, avatarMargin));
PileZone *deck = new PileZone(this, "deck", true, false, this);
QPointF base = QPointF(counterAreaWidth + (CARD_HEIGHT - CARD_WIDTH + 5) / 2.0, 5 + playerTarget->boundingRect().height() + 5 - (CARD_HEIGHT - CARD_WIDTH) / 2.0);
QPointF base = QPointF(counterAreaWidth + (CARD_HEIGHT - CARD_WIDTH + 15) / 2.0, 10 + playerTarget->boundingRect().height() + 5 - (CARD_HEIGHT - CARD_WIDTH) / 2.0);
deck->setPos(base);
qreal h = deck->boundingRect().width() + 5;
HandCounter *handCounter = new HandCounter(this);
handCounter->setPos(base + QPointF(0, h + 10));
qreal h2 = handCounter->boundingRect().height();
PileZone *grave = new PileZone(this, "grave", false, true, this);
grave->setPos(base + QPointF(0, h));
grave->setPos(base + QPointF(0, h + h2 + 10));
PileZone *rfg = new PileZone(this, "rfg", false, true, this);
rfg->setPos(base + QPointF(0, 2 * h));
rfg->setPos(base + QPointF(0, 2 * h + h2 + 10));
PileZone *sb = new PileZone(this, "sb", false, false, this);
sb->setVisible(false);
HandCounter *handCounter = new HandCounter(this);
handCounter->setPos(base + QPointF(0, 3 * h + 7));
table = new TableZone(this, this);
connect(table, SIGNAL(sizeChanged()), this, SLOT(updateBoundingRect()));
@ -312,7 +314,7 @@ void Player::playerListActionTriggered()
void Player::rearrangeZones()
{
QPointF base = QPointF(CARD_HEIGHT + counterAreaWidth + 5, 0);
QPointF base = QPointF(CARD_HEIGHT + counterAreaWidth + 15, 0);
if (settingsCache->getHorizontalHand()) {
if (mirrored) {
@ -370,7 +372,7 @@ void Player::updateBgPixmap()
void Player::updateBoundingRect()
{
prepareGeometryChange();
qreal width = CARD_HEIGHT + 5 + counterAreaWidth + stack->boundingRect().width();
qreal width = CARD_HEIGHT + 15 + counterAreaWidth + stack->boundingRect().width();
if (settingsCache->getHorizontalHand()) {
qreal handHeight = hand->isVisible() ? hand->boundingRect().height() : 0;
bRect = QRectF(0, 0, width + table->boundingRect().width(), table->boundingRect().height() + handHeight);
@ -426,7 +428,7 @@ void Player::retranslateUi()
aCreateAnotherToken->setText(tr("C&reate another token"));
sayMenu->setTitle(tr("S&ay"));
QMapIterator<int, Counter *> counterIterator(counters);
QMapIterator<int, AbstractCounter *> counterIterator(counters);
while (counterIterator.hasNext())
counterIterator.next().value()->retranslateUi();
@ -457,7 +459,7 @@ void Player::setShortcutsActive()
aCreateToken->setShortcut(tr("Ctrl+T"));
aCreateAnotherToken->setShortcut(tr("Ctrl+G"));
QMapIterator<int, Counter *> counterIterator(counters);
QMapIterator<int, AbstractCounter *> counterIterator(counters);
while (counterIterator.hasNext())
counterIterator.next().value()->setShortcutsActive();
}
@ -478,7 +480,7 @@ void Player::setShortcutsInactive()
aCreateToken->setShortcut(QKeySequence());
aCreateAnotherToken->setShortcut(QKeySequence());
QMapIterator<int, Counter *> counterIterator(counters);
QMapIterator<int, AbstractCounter *> counterIterator(counters);
while (counterIterator.hasNext())
counterIterator.next().value()->setShortcutsInactive();
}
@ -752,7 +754,7 @@ void Player::eventCreateCounters(Event_CreateCounters *event)
void Player::eventSetCounter(Event_SetCounter *event)
{
Counter *c = counters.value(event->getCounterId(), 0);
AbstractCounter *c = counters.value(event->getCounterId(), 0);
if (!c)
return;
int oldValue = c->getValue();
@ -1011,7 +1013,7 @@ QRectF Player::boundingRect() const
void Player::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/)
{
int totalWidth = CARD_HEIGHT + counterAreaWidth + 5;
int totalWidth = CARD_HEIGHT + counterAreaWidth + 15;
if (bgPixmap.isNull())
painter->fillRect(QRectF(0, 0, totalWidth, boundingRect().height()), QColor(200, 200, 200));
else
@ -1111,14 +1113,22 @@ void Player::addZone(CardZone *z)
zones.insert(z->getName(), z);
}
Counter *Player::addCounter(ServerInfo_Counter *counter)
AbstractCounter *Player::addCounter(ServerInfo_Counter *counter)
{
return addCounter(counter->getId(), counter->getName(), counter->getColor().getQColor(), counter->getRadius(), counter->getCount());
}
Counter *Player::addCounter(int counterId, const QString &name, QColor color, int radius, int value)
AbstractCounter *Player::addCounter(int counterId, const QString &name, QColor color, int radius, int value)
{
Counter *c = new Counter(this, counterId, name, color, radius, value, this);
qDebug() << "addCounter:" << getName() << counterId << name;
if (counters.contains(counterId))
return 0;
AbstractCounter *c;
if (name == "life")
c = playerTarget->addCounter(counterId, name, value);
else
c = new GeneralCounter(this, counterId, name, color, radius, value, this);
counters.insert(counterId, c);
if (countersMenu)
countersMenu->addMenu(c->getMenu());
@ -1130,9 +1140,11 @@ Counter *Player::addCounter(int counterId, const QString &name, QColor color, in
void Player::delCounter(int counterId)
{
Counter *c = counters.value(counterId, 0);
AbstractCounter *c = counters.value(counterId, 0);
if (!c)
return;
if (c->getName() == "life")
playerTarget->delCounter();
counters.remove(counterId);
c->delCounter();
rearrangeCounters();
@ -1140,10 +1152,11 @@ void Player::delCounter(int counterId)
void Player::clearCounters()
{
QMapIterator<int, Counter *> counterIterator(counters);
QMapIterator<int, AbstractCounter *> counterIterator(counters);
while (counterIterator.hasNext())
counterIterator.next().value()->delCounter();
counters.clear();
playerTarget->delCounter();
}
ArrowItem *Player::addArrow(ServerInfo_Arrow *arrow)
@ -1204,15 +1217,16 @@ void Player::clearArrows()
void Player::rearrangeCounters()
{
qreal marginTop = 15;
qreal marginBottom = 15;
qreal marginTop = 80;
qreal marginBottom = 10;
// Determine total height of bounding rectangles
qreal totalHeight = 0;
QMapIterator<int, Counter *> counterIterator(counters);
QMapIterator<int, AbstractCounter *> counterIterator(counters);
while (counterIterator.hasNext()) {
counterIterator.next();
totalHeight += counterIterator.value()->boundingRect().height();
if (counterIterator.value()->getShownInCounterArea())
totalHeight += counterIterator.value()->boundingRect().height();
}
// Determine free space between objects
@ -1226,8 +1240,11 @@ void Player::rearrangeCounters()
// Place objects
for (counterIterator.toFront(); counterIterator.hasNext(); ) {
Counter *c = counterIterator.next().value();
AbstractCounter *c = counterIterator.next().value();
if (!c->getShownInCounterArea())
continue;
QRectF br = c->boundingRect();
c->setPos((counterAreaWidth - br.width()) / 2, y);
y += br.height() + padding;
@ -1282,7 +1299,7 @@ void Player::cardMenuAction(QAction *a)
break;
}
case 4:
commandList.append(new Command_CreateToken(-1, card->getZone()->getName(), card->getName(), card->getColor(), card->getPT(), card->getAnnotation(), card->getDestroyOnZoneChange(), -1, card->getGridPoint().y()));
commandList.append(new Command_CreateToken(-1, card->getZone()->getName(), card->getName(), card->getColor(), card->getPT(), card->getAnnotation(), true, -1, card->getGridPoint().y()));
break;
case 5:
commandList.append(new Command_MoveCard(-1, card->getZone()->getName(), card->getId(), getId(), "deck", 0, 0, false));
@ -1431,7 +1448,7 @@ QString Player::getName() const
qreal Player::getMinimumWidth() const
{
qreal result = table->getMinimumWidth() + CARD_HEIGHT + 5 + counterAreaWidth + stack->boundingRect().width();
qreal result = table->getMinimumWidth() + CARD_HEIGHT + 15 + counterAreaWidth + stack->boundingRect().width();
if (!settingsCache->getHorizontalHand())
result += hand->boundingRect().width();
return result;
@ -1450,7 +1467,7 @@ void Player::processSceneSizeChange(const QSizeF &newSize)
// This will need to be changed if player areas are displayed side by side (e.g. 2x2 for a 4-player game)
qreal fullPlayerWidth = newSize.width();
qreal tableWidth = fullPlayerWidth - CARD_HEIGHT - 5 - counterAreaWidth - stack->boundingRect().width();
qreal tableWidth = fullPlayerWidth - CARD_HEIGHT - 15 - counterAreaWidth - stack->boundingRect().width();
if (!settingsCache->getHorizontalHand())
tableWidth -= hand->boundingRect().width();

View file

@ -11,7 +11,7 @@ class QMenu;
class QAction;
class ZoneViewZone;
class TabGame;
class Counter;
class AbstractCounter;
class ArrowItem;
class CardZone;
class StackZone;
@ -148,7 +148,7 @@ private:
QPixmap bgPixmap;
QRectF bRect;
QMap<int, Counter *> counters;
QMap<int, AbstractCounter *> counters;
QMap<int, ArrowItem *> arrows;
void rearrangeCounters();
@ -174,7 +174,7 @@ private:
void eventDrawCards(Event_DrawCards *event);
void eventRevealCards(Event_RevealCards *event);
public:
static const int counterAreaWidth = 65;
static const int counterAreaWidth = 55;
enum { Type = typeOther };
int type() const { return Type; }
@ -186,8 +186,8 @@ public:
void deleteCard(CardItem *c);
void addZone(CardZone *z);
Counter *addCounter(ServerInfo_Counter *counter);
Counter *addCounter(int counterId, const QString &name, QColor color, int radius, int value);
AbstractCounter *addCounter(ServerInfo_Counter *counter);
AbstractCounter *addCounter(int counterId, const QString &name, QColor color, int radius, int value);
void delCounter(int counterId);
void clearCounters();

View file

@ -5,9 +5,49 @@
#include <QPainter>
#include <QPixmapCache>
#include <QDebug>
#include <math.h>
PlayerCounter::PlayerCounter(Player *_player, int _id, const QString &_name, int _value, QGraphicsItem *parent)
: AbstractCounter(_player, _id, _name, false, _value, parent)
{
}
QRectF PlayerCounter::boundingRect() const
{
return QRectF(0, 0, 50, 30);
}
void PlayerCounter::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
{
const int radius = 8;
const qreal border = 1;
QPainterPath path(QPointF(50 - border / 2, border / 2));
path.lineTo(radius, border / 2);
path.arcTo(border / 2, border / 2, 2 * radius, 2 * radius, 90, 90);
path.lineTo(border / 2, 30 - border / 2);
path.lineTo(50 - border / 2, 30 - border / 2);
path.closeSubpath();
QPen pen(QColor(100, 100, 100));
pen.setWidth(border);
painter->setPen(pen);
painter->setBrush(hovered ? QColor(50, 50, 50, 160) : QColor(0, 0, 0, 160));
painter->drawPath(path);
QRectF translatedRect = painter->combinedTransform().mapRect(boundingRect());
QSize translatedSize = translatedRect.size().toSize();
painter->resetTransform();
QFont font("Serif");
font.setWeight(QFont::Bold);
font.setPixelSize(qMax((int) round(translatedSize.height() / 1.3), 9));
painter->setFont(font);
painter->setPen(Qt::white);
painter->drawText(translatedRect, Qt::AlignCenter, QString::number(value));
}
PlayerTarget::PlayerTarget(Player *_owner)
: ArrowTarget(_owner, _owner)
: ArrowTarget(_owner, _owner), playerCounter(0)
{
setCacheMode(DeviceCoordinateCache);
@ -17,15 +57,17 @@ PlayerTarget::PlayerTarget(Player *_owner)
QRectF PlayerTarget::boundingRect() const
{
return QRectF(0, 0, 100, 64);
return QRectF(0, 0, 160, 64);
}
void PlayerTarget::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
{
ServerInfo_User *info = owner->getUserInfo();
painter->save();
QRectF translatedRect = painter->combinedTransform().mapRect(boundingRect());
const qreal border = 2;
QRectF avatarBoundingRect = boundingRect().adjusted(border, border, -border, -border);
QRectF translatedRect = painter->combinedTransform().mapRect(avatarBoundingRect);
QSize translatedSize = translatedRect.size().toSize();
QPixmap cachedPixmap;
const QString cacheKey = "avatar" + QString::number(translatedSize.width()) + "_" + QString::number(info->getUserLevel()) + "_" + QString::number(fullPixmap.cacheKey());
@ -34,16 +76,35 @@ void PlayerTarget::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*o
#else
if (!QPixmapCache::find(cacheKey, cachedPixmap)) {
#endif
cachedPixmap = QPixmap(translatedSize.width(), translatedSize.height());
QPainter tempPainter(&cachedPixmap);
QRadialGradient grad(translatedRect.center(), sqrt(translatedSize.width() * translatedSize.width() + translatedSize.height() * translatedSize.height()) / 2);
grad.setColorAt(1, Qt::black);
grad.setColorAt(0, QColor(180, 180, 180));
tempPainter.fillRect(QRectF(0, 0, translatedSize.width(), translatedSize.height()), grad);
QPixmap tempPixmap;
if (fullPixmap.isNull())
cachedPixmap = UserLevelPixmapGenerator::generatePixmap(translatedSize.height(), info->getUserLevel());
tempPixmap = UserLevelPixmapGenerator::generatePixmap(translatedSize.height(), info->getUserLevel());
else
cachedPixmap = fullPixmap.scaled(translatedSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
tempPixmap = fullPixmap.scaled(translatedSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
tempPainter.drawPixmap((translatedSize.width() - tempPixmap.width()) / 2, (translatedSize.height() - tempPixmap.height()) / 2, tempPixmap);
QPixmapCache::insert(cacheKey, cachedPixmap);
}
painter->resetTransform();
painter->save();
painter->resetTransform();
painter->translate((translatedSize.width() - cachedPixmap.width()) / 2.0, 0);
painter->drawPixmap(cachedPixmap.rect(), cachedPixmap, cachedPixmap.rect());
painter->drawPixmap(translatedRect, cachedPixmap, cachedPixmap.rect());
painter->restore();
QRectF nameRect = QRectF(0, boundingRect().height() - 20, 110, 20);
painter->fillRect(nameRect, QColor(0, 0, 0, 160));
QRectF translatedNameRect = painter->combinedTransform().mapRect(nameRect);
painter->save();
painter->resetTransform();
QString name = info->getName();
@ -51,14 +112,35 @@ void PlayerTarget::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*o
name = name.mid(0, 10) + "...";
QFont font;
font.setPixelSize(qMax(translatedSize.height() / 4, 9));
font.setPixelSize(qMax((int) round(translatedNameRect.height() / 1.5), 9));
painter->setFont(font);
painter->setBackgroundMode(Qt::OpaqueMode);
painter->setBackground(QColor(0, 0, 0, 100));
painter->setPen(Qt::white);
painter->drawText(translatedRect, Qt::AlignHCenter | Qt::AlignTop | Qt::TextWrapAnywhere, name);
painter->drawText(translatedNameRect, Qt::AlignVCenter | Qt::AlignLeft, " " + name);
painter->restore();
QPen pen(QColor(100, 100, 100));
pen.setWidth(border);
pen.setJoinStyle(Qt::RoundJoin);
painter->setPen(pen);
painter->drawRect(boundingRect().adjusted(border / 2, border / 2, -border / 2, -border / 2));
if (getBeingPointedAt())
painter->fillRect(boundingRect(), QBrush(QColor(255, 0, 0, 100)));
}
AbstractCounter *PlayerTarget::addCounter(int _counterId, const QString &_name, int _value)
{
if (playerCounter)
return 0;
playerCounter = new PlayerCounter(owner, _counterId, _name, _value, this);
playerCounter->setPos(boundingRect().width() - playerCounter->boundingRect().width(), boundingRect().height() - playerCounter->boundingRect().height());
connect(playerCounter, SIGNAL(destroyed()), this, SLOT(delCounter()));
return playerCounter;
}
void PlayerTarget::delCounter()
{
playerCounter = 0;
}

View file

@ -2,14 +2,27 @@
#define PLAYERTARGET_H
#include "arrowtarget.h"
#include "abstractcounter.h"
#include <QFont>
#include <QPixmap>
class Player;
class PlayerCounter : public AbstractCounter {
Q_OBJECT
public:
PlayerCounter(Player *_player, int _id, const QString &_name, int _value, QGraphicsItem *parent = 0);
QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
};
class PlayerTarget : public ArrowTarget {
Q_OBJECT
private:
QPixmap fullPixmap;
PlayerCounter *playerCounter;
public slots:
void delCounter();
public:
enum { Type = typePlayerTarget };
int type() const { return Type; }
@ -17,6 +30,8 @@ public:
PlayerTarget(Player *parent = 0);
QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
AbstractCounter *addCounter(int _counterId, const QString &_name, int _value);
};
#endif

View file

@ -42,12 +42,17 @@ void RemoteClient::slotConnected()
setStatus(StatusAwaitingWelcome);
}
void RemoteClient::loginResponse(ResponseCode response)
void RemoteClient::loginResponse(ProtocolResponse *response)
{
if (response == RespOk)
Response_Login *resp = qobject_cast<Response_Login *>(response);
if (!resp)
disconnectFromServer();
if (resp->getResponseCode() == RespOk) {
setStatus(StatusLoggedIn);
else {
emit serverError(response);
emit userInfoChanged(resp->getUserInfo());
} else {
emit serverError(resp->getResponseCode());
setStatus(StatusDisconnecting);
}
}
@ -78,7 +83,7 @@ void RemoteClient::readData()
setStatus(StatusLoggingIn);
Command_Login *cmdLogin = new Command_Login(userName, password);
connect(cmdLogin, SIGNAL(finished(ResponseCode)), this, SLOT(loginResponse(ResponseCode)));
connect(cmdLogin, SIGNAL(finished(ProtocolResponse *)), this, SLOT(loginResponse(ProtocolResponse *)));
sendCommand(cmdLogin);
}
}

View file

@ -2,7 +2,6 @@
#define REMOTECLIENT_H
#include <QTcpSocket>
#include "protocol_datastructures.h"
#include "abstractclient.h"
class QTimer;
@ -22,7 +21,7 @@ private slots:
void readData();
void slotSocketError(QAbstractSocket::SocketError error);
void ping();
void loginResponse(ResponseCode response);
void loginResponse(ProtocolResponse *response);
private:
static const int maxTimeout = 10;

View file

@ -1,118 +0,0 @@
#include <QListWidget>
#include <QTextEdit>
#include <QLineEdit>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QMenu>
#include <QAction>
#include "tab_chatchannel.h"
#include "abstractclient.h"
#include "protocol_items.h"
TabChatChannel::TabChatChannel(AbstractClient *_client, const QString &_channelName)
: Tab(), client(_client), channelName(_channelName)
{
playerList = new QListWidget;
playerList->setFixedWidth(150);
textEdit = new QTextEdit;
textEdit->setReadOnly(true);
sayEdit = new QLineEdit;
connect(sayEdit, SIGNAL(returnPressed()), this, SLOT(sendMessage()));
QVBoxLayout *vbox = new QVBoxLayout;
vbox->addWidget(textEdit);
vbox->addWidget(sayEdit);
QHBoxLayout *hbox = new QHBoxLayout;
hbox->addLayout(vbox);
hbox->addWidget(playerList);
aLeaveChannel = new QAction(this);
connect(aLeaveChannel, SIGNAL(triggered()), this, SLOT(actLeaveChannel()));
tabMenu = new QMenu(this);
tabMenu->addAction(aLeaveChannel);
retranslateUi();
setLayout(hbox);
}
TabChatChannel::~TabChatChannel()
{
emit channelClosing(this);
}
void TabChatChannel::retranslateUi()
{
tabMenu->setTitle(tr("C&hat channel"));
aLeaveChannel->setText(tr("&Leave channel"));
}
QString TabChatChannel::sanitizeHtml(QString dirty) const
{
return dirty
.replace("&", "&amp;")
.replace("<", "&lt;")
.replace(">", "&gt;");
}
void TabChatChannel::sendMessage()
{
if (sayEdit->text().isEmpty())
return;
client->sendCommand(new Command_ChatSay(channelName, sayEdit->text()));
sayEdit->clear();
}
void TabChatChannel::actLeaveChannel()
{
client->sendCommand(new Command_ChatLeaveChannel(channelName));
deleteLater();
}
void TabChatChannel::processChatEvent(ChatEvent *event)
{
switch (event->getItemId()) {
case ItemId_Event_ChatListPlayers: processListPlayersEvent(qobject_cast<Event_ChatListPlayers *>(event)); break;
case ItemId_Event_ChatJoinChannel: processJoinChannelEvent(qobject_cast<Event_ChatJoinChannel *>(event)); break;
case ItemId_Event_ChatLeaveChannel: processLeaveChannelEvent(qobject_cast<Event_ChatLeaveChannel *>(event)); break;
case ItemId_Event_ChatSay: processSayEvent(qobject_cast<Event_ChatSay *>(event)); break;
default: ;
}
}
void TabChatChannel::processListPlayersEvent(Event_ChatListPlayers *event)
{
const QList<ServerInfo_User *> &players = event->getPlayerList();
for (int i = 0; i < players.size(); ++i)
playerList->addItem(players[i]->getName());
}
void TabChatChannel::processJoinChannelEvent(Event_ChatJoinChannel *event)
{
textEdit->append(tr("%1 has joined the channel.").arg(sanitizeHtml(event->getUserInfo()->getName())));
playerList->addItem(event->getUserInfo()->getName());
emit userEvent();
}
void TabChatChannel::processLeaveChannelEvent(Event_ChatLeaveChannel *event)
{
textEdit->append(tr("%1 has left the channel.").arg(sanitizeHtml(event->getPlayerName())));
for (int i = 0; i < playerList->count(); ++i)
if (playerList->item(i)->text() == event->getPlayerName()) {
delete playerList->takeItem(i);
break;
}
emit userEvent();
}
void TabChatChannel::processSayEvent(Event_ChatSay *event)
{
if (event->getPlayerName().isEmpty())
textEdit->append(QString("<font color=\"blue\">%1</font").arg(sanitizeHtml(event->getMessage())));
else
textEdit->append(QString("<font color=\"red\">%1:</font> %2").arg(sanitizeHtml(event->getPlayerName())).arg(sanitizeHtml(event->getMessage())));
emit userEvent();
}

View file

@ -1,47 +0,0 @@
#ifndef TAB_CHATCHANNEL_H
#define TAB_CHATCHANNEL_H
#include "tab.h"
class AbstractClient;
class QListWidget;
class QTextEdit;
class QLineEdit;
class ChatEvent;
class Event_ChatListPlayers;
class Event_ChatJoinChannel;
class Event_ChatLeaveChannel;
class Event_ChatSay;
class TabChatChannel : public Tab {
Q_OBJECT
private:
AbstractClient *client;
QString channelName;
QListWidget *playerList;
QTextEdit *textEdit;
QLineEdit *sayEdit;
QAction *aLeaveChannel;
QString sanitizeHtml(QString dirty) const;
signals:
void channelClosing(TabChatChannel *tab);
private slots:
void sendMessage();
void actLeaveChannel();
void processListPlayersEvent(Event_ChatListPlayers *event);
void processJoinChannelEvent(Event_ChatJoinChannel *event);
void processLeaveChannelEvent(Event_ChatLeaveChannel *event);
void processSayEvent(Event_ChatSay *event);
public:
TabChatChannel(AbstractClient *_client, const QString &_channelName);
~TabChatChannel();
void retranslateUi();
void processChatEvent(ChatEvent *event);
QString getChannelName() const { return channelName; }
QString getTabText() const { return channelName; }
};
#endif

282
cockatrice/src/tab_room.cpp Normal file
View file

@ -0,0 +1,282 @@
#include <QTextEdit>
#include <QLineEdit>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QMenu>
#include <QAction>
#include <QPushButton>
#include <QHeaderView>
#include <QMessageBox>
#include <QCheckBox>
#include <QInputDialog>
#include <QLabel>
#include <QScrollBar>
#include "dlg_creategame.h"
#include "tab_room.h"
#include "userlist.h"
#include "abstractclient.h"
#include "protocol_items.h"
#include "gamesmodel.h"
#include <QTextTable>
GameSelector::GameSelector(AbstractClient *_client, int _roomId, QWidget *parent)
: QGroupBox(parent), client(_client), roomId(_roomId)
{
gameListView = new QTreeView;
gameListModel = new GamesModel(this);
gameListProxyModel = new GamesProxyModel(this);
gameListProxyModel->setSourceModel(gameListModel);
gameListView->setModel(gameListProxyModel);
gameListView->header()->setResizeMode(0, QHeaderView::ResizeToContents);
showFullGamesCheckBox = new QCheckBox;
createButton = new QPushButton;
joinButton = new QPushButton;
spectateButton = new QPushButton;
QHBoxLayout *buttonLayout = new QHBoxLayout;
buttonLayout->addWidget(showFullGamesCheckBox);
buttonLayout->addStretch();
buttonLayout->addWidget(createButton);
buttonLayout->addWidget(joinButton);
buttonLayout->addWidget(spectateButton);
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addWidget(gameListView);
mainLayout->addLayout(buttonLayout);
retranslateUi();
setLayout(mainLayout);
setMinimumWidth(gameListView->columnWidth(0) * gameListModel->columnCount());
setMinimumHeight(400);
connect(showFullGamesCheckBox, SIGNAL(stateChanged(int)), this, SLOT(showFullGamesChanged(int)));
connect(createButton, SIGNAL(clicked()), this, SLOT(actCreate()));
connect(joinButton, SIGNAL(clicked()), this, SLOT(actJoin()));
connect(spectateButton, SIGNAL(clicked()), this, SLOT(actJoin()));
}
void GameSelector::showFullGamesChanged(int state)
{
gameListProxyModel->setFullGamesVisible(state);
}
void GameSelector::actCreate()
{
DlgCreateGame dlg(client, roomId, this);
dlg.exec();
}
void GameSelector::checkResponse(ResponseCode response)
{
createButton->setEnabled(true);
joinButton->setEnabled(true);
spectateButton->setEnabled(true);
switch (response) {
case RespWrongPassword: QMessageBox::critical(this, tr("Error"), tr("Wrong password.")); break;
case RespSpectatorsNotAllowed: QMessageBox::critical(this, tr("Error"), tr("Spectators are not allowed in this game.")); break;
case RespGameFull: QMessageBox::critical(this, tr("Error"), tr("The game is already full.")); break;
case RespNameNotFound: QMessageBox::critical(this, tr("Error"), tr("The game does not exist any more.")); break;
default: ;
}
}
void GameSelector::actJoin()
{
bool spectator = sender() == spectateButton;
QModelIndex ind = gameListView->currentIndex();
if (!ind.isValid())
return;
ServerInfo_Game *game = gameListModel->getGame(ind.data(Qt::UserRole).toInt());
QString password;
if (game->getHasPassword() && !(spectator && !game->getSpectatorsNeedPassword())) {
bool ok;
password = QInputDialog::getText(this, tr("Join game"), tr("Password:"), QLineEdit::Password, QString(), &ok);
if (!ok)
return;
}
Command_JoinGame *commandJoinGame = new Command_JoinGame(roomId, game->getGameId(), password, spectator);
connect(commandJoinGame, SIGNAL(finished(ResponseCode)), this, SLOT(checkResponse(ResponseCode)));
client->sendCommand(commandJoinGame);
createButton->setEnabled(false);
joinButton->setEnabled(false);
spectateButton->setEnabled(false);
}
void GameSelector::retranslateUi()
{
setTitle(tr("Games"));
showFullGamesCheckBox->setText(tr("Show &full games"));
createButton->setText(tr("C&reate"));
joinButton->setText(tr("&Join"));
spectateButton->setText(tr("J&oin as spectator"));
}
void GameSelector::processGameInfo(ServerInfo_Game *info)
{
gameListModel->updateGameList(info);
}
ChatView::ChatView(const QString &_ownName, QWidget *parent)
: QTextEdit(parent), ownName(_ownName)
{
setTextInteractionFlags(Qt::TextSelectableByMouse);
QTextTableFormat format;
format.setBorderStyle(QTextFrameFormat::BorderStyle_None);
table = textCursor().insertTable(1, 3, format);
}
void ChatView::appendMessage(const QString &sender, const QString &message)
{
QTextCursor cellCursor = table->cellAt(table->rows() - 1, 0).lastCursorPosition();
cellCursor.insertText(QDateTime::currentDateTime().toString("[hh:mm]"));
QTextTableCell senderCell = table->cellAt(table->rows() - 1, 1);
QTextCharFormat senderFormat;
if (sender == ownName) {
senderFormat.setFontWeight(QFont::Bold);
senderFormat.setForeground(Qt::red);
} else
senderFormat.setForeground(Qt::blue);
senderCell.setFormat(senderFormat);
cellCursor = senderCell.lastCursorPosition();
cellCursor.insertText(sender);
QTextTableCell messageCell = table->cellAt(table->rows() - 1, 2);
QTextCharFormat messageFormat;
if (sender.isEmpty())
messageFormat.setForeground(Qt::darkGreen);
messageCell.setFormat(messageFormat);
cellCursor = messageCell.lastCursorPosition();
cellCursor.insertText(message);
table->appendRows(1);
verticalScrollBar()->setValue(verticalScrollBar()->maximum());
}
TabRoom::TabRoom(AbstractClient *_client, const QString &_ownName, ServerInfo_Room *info)
: Tab(), client(_client), roomId(info->getRoomId()), roomName(info->getName()), ownName(_ownName)
{
gameSelector = new GameSelector(client, roomId);
userList = new UserList(false);
connect(userList, SIGNAL(openMessageDialog(const QString &, bool)), this, SIGNAL(openMessageDialog(const QString &, bool)));
chatView = new ChatView(ownName);
sayLabel = new QLabel;
sayEdit = new QLineEdit;
sayLabel->setBuddy(sayEdit);
connect(sayEdit, SIGNAL(returnPressed()), this, SLOT(sendMessage()));
QHBoxLayout *sayHbox = new QHBoxLayout;
sayHbox->addWidget(sayLabel);
sayHbox->addWidget(sayEdit);
QVBoxLayout *chatVbox = new QVBoxLayout;
chatVbox->addWidget(chatView);
chatVbox->addLayout(sayHbox);
chatGroupBox = new QGroupBox;
chatGroupBox->setLayout(chatVbox);
QVBoxLayout *vbox = new QVBoxLayout;
vbox->addWidget(gameSelector);
vbox->addWidget(chatGroupBox);
QHBoxLayout *hbox = new QHBoxLayout;
hbox->addLayout(vbox, 3);
hbox->addWidget(userList, 1);
aLeaveRoom = new QAction(this);
connect(aLeaveRoom, SIGNAL(triggered()), this, SLOT(actLeaveRoom()));
tabMenu = new QMenu(this);
tabMenu->addAction(aLeaveRoom);
retranslateUi();
setLayout(hbox);
const QList<ServerInfo_User *> users = info->getUserList();
for (int i = 0; i < users.size(); ++i)
userList->processUserInfo(users[i]);
const QList<ServerInfo_Game *> games = info->getGameList();
for (int i = 0; i < games.size(); ++i)
gameSelector->processGameInfo(games[i]);
}
TabRoom::~TabRoom()
{
emit roomClosing(this);
}
void TabRoom::retranslateUi()
{
sayLabel->setText(tr("&Say:"));
chatGroupBox->setTitle(tr("Chat"));
tabMenu->setTitle(tr("&Room"));
aLeaveRoom->setText(tr("&Leave room"));
}
QString TabRoom::sanitizeHtml(QString dirty) const
{
return dirty
.replace("&", "&amp;")
.replace("<", "&lt;")
.replace(">", "&gt;");
}
void TabRoom::sendMessage()
{
if (sayEdit->text().isEmpty())
return;
client->sendCommand(new Command_RoomSay(roomId, sayEdit->text()));
sayEdit->clear();
}
void TabRoom::actLeaveRoom()
{
client->sendCommand(new Command_LeaveRoom(roomId));
deleteLater();
}
void TabRoom::processRoomEvent(RoomEvent *event)
{
switch (event->getItemId()) {
case ItemId_Event_ListGames: processListGamesEvent(qobject_cast<Event_ListGames *>(event)); break;
case ItemId_Event_JoinRoom: processJoinRoomEvent(qobject_cast<Event_JoinRoom *>(event)); break;
case ItemId_Event_LeaveRoom: processLeaveRoomEvent(qobject_cast<Event_LeaveRoom *>(event)); break;
case ItemId_Event_RoomSay: processSayEvent(qobject_cast<Event_RoomSay *>(event)); break;
default: ;
}
}
void TabRoom::processListGamesEvent(Event_ListGames *event)
{
const QList<ServerInfo_Game *> &gameList = event->getGameList();
for (int i = 0; i < gameList.size(); ++i)
gameSelector->processGameInfo(gameList[i]);
}
void TabRoom::processJoinRoomEvent(Event_JoinRoom *event)
{
chatView->appendMessage(QString(), tr("%1 has joined the room.").arg(event->getUserInfo()->getName()));
userList->processUserInfo(event->getUserInfo());
}
void TabRoom::processLeaveRoomEvent(Event_LeaveRoom *event)
{
chatView->appendMessage(QString(), tr("%1 has left the room.").arg(event->getPlayerName()));
userList->deleteUser(event->getPlayerName());
}
void TabRoom::processSayEvent(Event_RoomSay *event)
{
chatView->appendMessage(event->getPlayerName(), event->getMessage());
emit userEvent();
}

100
cockatrice/src/tab_room.h Normal file
View file

@ -0,0 +1,100 @@
#ifndef TAB_ROOM_H
#define TAB_ROOM_H
#include "tab.h"
#include "protocol_datastructures.h"
#include <QGroupBox>
#include <QTextEdit>
class AbstractClient;
class UserList;
class QLabel;
class QTextEdit;
class QLineEdit;
class QTreeView;
class QPushButton;
class QTextTable;
class QCheckBox;
class GamesModel;
class GamesProxyModel;
class RoomEvent;
class ServerInfo_Room;
class ServerInfo_Game;
class Event_ListGames;
class Event_JoinRoom;
class Event_LeaveRoom;
class Event_RoomSay;
class GameSelector : public QGroupBox {
Q_OBJECT
private slots:
void showFullGamesChanged(int state);
void actCreate();
void actJoin();
void checkResponse(ResponseCode response);
signals:
void gameJoined(int gameId);
private:
AbstractClient *client;
int roomId;
QTreeView *gameListView;
GamesModel *gameListModel;
GamesProxyModel *gameListProxyModel;
QPushButton *createButton, *joinButton, *spectateButton;
QCheckBox *showFullGamesCheckBox;
public:
GameSelector(AbstractClient *_client, int _roomId, QWidget *parent = 0);
void retranslateUi();
void processGameInfo(ServerInfo_Game *info);
};
class ChatView : public QTextEdit {
Q_OBJECT;
private:
QTextTable *table;
QString ownName;
public:
ChatView(const QString &_ownName, QWidget *parent = 0);
void appendMessage(const QString &sender, const QString &message);
};
class TabRoom : public Tab {
Q_OBJECT
private:
AbstractClient *client;
int roomId;
QString roomName;
QString ownName;
GameSelector *gameSelector;
UserList *userList;
ChatView *chatView;
QLabel *sayLabel;
QLineEdit *sayEdit;
QGroupBox *chatGroupBox;
QAction *aLeaveRoom;
QString sanitizeHtml(QString dirty) const;
signals:
void roomClosing(TabRoom *tab);
void openMessageDialog(const QString &userName, bool focus);
private slots:
void sendMessage();
void actLeaveRoom();
void processListGamesEvent(Event_ListGames *event);
void processJoinRoomEvent(Event_JoinRoom *event);
void processLeaveRoomEvent(Event_LeaveRoom *event);
void processSayEvent(Event_RoomSay *event);
public:
TabRoom(AbstractClient *_client, const QString &_ownName, ServerInfo_Room *info);
~TabRoom();
void retranslateUi();
void processRoomEvent(RoomEvent *event);
int getRoomId() const { return roomId; }
QString getChannelName() const { return roomName; }
QString getTabText() const { return roomName; }
};
#endif

View file

@ -10,126 +10,24 @@
#include <QHeaderView>
#include <QInputDialog>
#include "tab_server.h"
#include "gamesmodel.h"
#include "dlg_creategame.h"
#include "abstractclient.h"
#include "protocol.h"
#include "protocol_items.h"
#include "userlist.h"
#include "pixmapgenerator.h"
#include <QDebug>
GameSelector::GameSelector(AbstractClient *_client, QWidget *parent)
RoomSelector::RoomSelector(AbstractClient *_client, QWidget *parent)
: QGroupBox(parent), client(_client)
{
gameListView = new QTreeView;
gameListModel = new GamesModel(this);
gameListProxyModel = new GamesProxyModel(this);
gameListProxyModel->setSourceModel(gameListModel);
gameListView->setModel(gameListProxyModel);
gameListView->header()->setResizeMode(0, QHeaderView::ResizeToContents);
showFullGamesCheckBox = new QCheckBox;
createButton = new QPushButton;
joinButton = new QPushButton;
spectateButton = new QPushButton;
QHBoxLayout *buttonLayout = new QHBoxLayout;
buttonLayout->addWidget(showFullGamesCheckBox);
buttonLayout->addStretch();
buttonLayout->addWidget(createButton);
buttonLayout->addWidget(joinButton);
buttonLayout->addWidget(spectateButton);
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addWidget(gameListView);
mainLayout->addLayout(buttonLayout);
retranslateUi();
setLayout(mainLayout);
setMinimumWidth(gameListView->columnWidth(0) * gameListModel->columnCount());
setMinimumHeight(400);
connect(showFullGamesCheckBox, SIGNAL(stateChanged(int)), this, SLOT(showFullGamesChanged(int)));
connect(createButton, SIGNAL(clicked()), this, SLOT(actCreate()));
connect(joinButton, SIGNAL(clicked()), this, SLOT(actJoin()));
connect(spectateButton, SIGNAL(clicked()), this, SLOT(actJoin()));
connect(client, SIGNAL(listGamesEventReceived(Event_ListGames *)), this, SLOT(processListGamesEvent(Event_ListGames *)));
client->sendCommand(new Command_ListGames);
}
void GameSelector::showFullGamesChanged(int state)
{
gameListProxyModel->setFullGamesVisible(state);
}
void GameSelector::actCreate()
{
DlgCreateGame dlg(client, this);
dlg.exec();
}
void GameSelector::checkResponse(ResponseCode response)
{
createButton->setEnabled(true);
joinButton->setEnabled(true);
spectateButton->setEnabled(true);
switch (response) {
case RespWrongPassword: QMessageBox::critical(this, tr("Error"), tr("Wrong password.")); break;
case RespSpectatorsNotAllowed: QMessageBox::critical(this, tr("Error"), tr("Spectators are not allowed in this game.")); break;
case RespGameFull: QMessageBox::critical(this, tr("Error"), tr("The game is already full.")); break;
case RespNameNotFound: QMessageBox::critical(this, tr("Error"), tr("The game does not exist any more.")); break;
default: ;
}
}
void GameSelector::actJoin()
{
bool spectator = sender() == spectateButton;
QModelIndex ind = gameListView->currentIndex();
if (!ind.isValid())
return;
ServerInfo_Game *game = gameListModel->getGame(ind.data(Qt::UserRole).toInt());
QString password;
if (game->getHasPassword() && !(spectator && !game->getSpectatorsNeedPassword())) {
bool ok;
password = QInputDialog::getText(this, tr("Join game"), tr("Password:"), QLineEdit::Password, QString(), &ok);
if (!ok)
return;
}
Command_JoinGame *commandJoinGame = new Command_JoinGame(game->getGameId(), password, spectator);
connect(commandJoinGame, SIGNAL(finished(ResponseCode)), this, SLOT(checkResponse(ResponseCode)));
client->sendCommand(commandJoinGame);
createButton->setEnabled(false);
joinButton->setEnabled(false);
spectateButton->setEnabled(false);
}
void GameSelector::retranslateUi()
{
setTitle(tr("Games"));
showFullGamesCheckBox->setText(tr("&Show full games"));
createButton->setText(tr("C&reate"));
joinButton->setText(tr("&Join"));
spectateButton->setText(tr("J&oin as spectator"));
}
void GameSelector::processListGamesEvent(Event_ListGames *event)
{
const QList<ServerInfo_Game *> &gamesToUpdate = event->getGameList();
for (int i = 0; i < gamesToUpdate.size(); ++i)
gameListModel->updateGameList(gamesToUpdate[i]);
}
ChatChannelSelector::ChatChannelSelector(AbstractClient *_client, QWidget *parent)
: QGroupBox(parent), client(_client)
{
channelList = new QTreeWidget;
channelList->setRootIsDecorated(false);
roomList = new QTreeWidget;
roomList->setRootIsDecorated(false);
roomList->setColumnCount(4);
roomList->header()->setStretchLastSection(false);
roomList->header()->setResizeMode(0, QHeaderView::ResizeToContents);
roomList->header()->setResizeMode(1, QHeaderView::Stretch);
roomList->header()->setResizeMode(2, QHeaderView::ResizeToContents);
roomList->header()->setResizeMode(3, QHeaderView::ResizeToContents);
joinButton = new QPushButton;
connect(joinButton, SIGNAL(clicked()), this, SLOT(joinClicked()));
@ -137,209 +35,89 @@ ChatChannelSelector::ChatChannelSelector(AbstractClient *_client, QWidget *paren
buttonLayout->addStretch();
buttonLayout->addWidget(joinButton);
QVBoxLayout *vbox = new QVBoxLayout;
vbox->addWidget(channelList);
vbox->addWidget(roomList);
vbox->addLayout(buttonLayout);
retranslateUi();
setLayout(vbox);
connect(client, SIGNAL(listChatChannelsEventReceived(Event_ListChatChannels *)), this, SLOT(processListChatChannelsEvent(Event_ListChatChannels *)));
client->sendCommand(new Command_ListChatChannels);
connect(client, SIGNAL(listRoomsEventReceived(Event_ListRooms *)), this, SLOT(processListRoomsEvent(Event_ListRooms *)));
client->sendCommand(new Command_ListRooms);
}
void ChatChannelSelector::retranslateUi()
void RoomSelector::retranslateUi()
{
setTitle(tr("Chat channels"));
setTitle(tr("Rooms"));
joinButton->setText(tr("Joi&n"));
QTreeWidgetItem *header = channelList->headerItem();
header->setText(0, tr("Channel"));
QTreeWidgetItem *header = roomList->headerItem();
header->setText(0, tr("Room"));
header->setText(1, tr("Description"));
header->setText(2, tr("Players"));
header->setText(3, tr("Games"));
header->setTextAlignment(2, Qt::AlignRight);
header->setTextAlignment(3, Qt::AlignRight);
}
void ChatChannelSelector::processListChatChannelsEvent(Event_ListChatChannels *event)
void RoomSelector::processListRoomsEvent(Event_ListRooms *event)
{
const QList<ServerInfo_ChatChannel *> &channelsToUpdate = event->getChannelList();
for (int i = 0; i < channelsToUpdate.size(); ++i) {
ServerInfo_ChatChannel *channel = channelsToUpdate[i];
const QList<ServerInfo_Room *> &roomsToUpdate = event->getRoomList();
for (int i = 0; i < roomsToUpdate.size(); ++i) {
ServerInfo_Room *room = roomsToUpdate[i];
for (int j = 0; j < channelList->topLevelItemCount(); ++j) {
QTreeWidgetItem *twi = channelList->topLevelItem(j);
if (twi->text(0) == channel->getName()) {
twi->setText(1, channel->getDescription());
twi->setText(2, QString::number(channel->getPlayerCount()));
for (int j = 0; j < roomList->topLevelItemCount(); ++j) {
QTreeWidgetItem *twi = roomList->topLevelItem(j);
if (twi->data(0, Qt::UserRole).toInt() == room->getRoomId()) {
twi->setData(0, Qt::DisplayRole, room->getName());
twi->setData(1, Qt::DisplayRole, room->getDescription());
twi->setData(2, Qt::DisplayRole, room->getPlayerCount());
twi->setData(3, Qt::DisplayRole, room->getGameCount());
return;
}
}
QTreeWidgetItem *twi = new QTreeWidgetItem(QStringList() << channel->getName() << channel->getDescription() << QString::number(channel->getPlayerCount()));
QTreeWidgetItem *twi = new QTreeWidgetItem;
twi->setData(0, Qt::UserRole, room->getRoomId());
twi->setData(0, Qt::DisplayRole, room->getName());
twi->setData(1, Qt::DisplayRole, room->getDescription());
twi->setData(2, Qt::DisplayRole, room->getPlayerCount());
twi->setData(3, Qt::DisplayRole, room->getGameCount());
twi->setTextAlignment(2, Qt::AlignRight);
channelList->addTopLevelItem(twi);
channelList->resizeColumnToContents(0);
channelList->resizeColumnToContents(1);
channelList->resizeColumnToContents(2);
if (channel->getAutoJoin())
joinChannel(channel->getName());
twi->setTextAlignment(3, Qt::AlignRight);
roomList->addTopLevelItem(twi);
if (room->getAutoJoin())
joinRoom(room->getRoomId(), false);
}
}
void ChatChannelSelector::joinChannel(const QString &channelName)
void RoomSelector::joinRoom(int id, bool setCurrent)
{
Command_ChatJoinChannel *command = new Command_ChatJoinChannel(channelName);
connect(command, SIGNAL(finished(ResponseCode)), this, SLOT(joinFinished(ResponseCode)));
Command_JoinRoom *command = new Command_JoinRoom(id);
command->setExtraData(setCurrent);
connect(command, SIGNAL(finished(ProtocolResponse *)), this, SLOT(joinFinished(ProtocolResponse *)));
client->sendCommand(command);
}
void ChatChannelSelector::joinClicked()
void RoomSelector::joinClicked()
{
QTreeWidgetItem *twi = channelList->currentItem();
QTreeWidgetItem *twi = roomList->currentItem();
if (!twi)
return;
QString channelName = twi->text(0);
joinChannel(channelName);
joinRoom(twi->data(0, Qt::UserRole).toInt(), true);
}
void ChatChannelSelector::joinFinished(ResponseCode resp)
void RoomSelector::joinFinished(ProtocolResponse *r)
{
if (resp != RespOk)
if (r->getResponseCode() != RespOk)
return;
Command_ChatJoinChannel *command = qobject_cast<Command_ChatJoinChannel *>(sender());
QString channelName = command->getChannel();
emit channelJoined(channelName);
}
ServerMessageLog::ServerMessageLog(AbstractClient *_client, QWidget *parent)
: QGroupBox(parent)
{
textEdit = new QTextEdit;
textEdit->setReadOnly(true);
QVBoxLayout *vbox = new QVBoxLayout;
vbox->addWidget(textEdit);
setLayout(vbox);
retranslateUi();
connect(_client, SIGNAL(serverMessageEventReceived(Event_ServerMessage *)), this, SLOT(processServerMessageEvent(Event_ServerMessage *)));
}
void ServerMessageLog::retranslateUi()
{
setTitle(tr("Server messages"));
}
void ServerMessageLog::processServerMessageEvent(Event_ServerMessage *event)
{
textEdit->append(event->getMessage());
}
UserListTWI::UserListTWI()
: QTreeWidgetItem(Type)
{
}
bool UserListTWI::operator<(const QTreeWidgetItem &other) const
{
// Equal user level => sort by name
if (data(0, Qt::UserRole) == other.data(0, Qt::UserRole))
return data(2, Qt::UserRole).toString().toLower() < other.data(2, Qt::UserRole).toString().toLower();
// Else sort by user level
return data(0, Qt::UserRole).toInt() > other.data(0, Qt::UserRole).toInt();
}
UserList::UserList(AbstractClient *_client, QWidget *parent)
: QGroupBox(parent)
{
userTree = new QTreeWidget;
userTree->setColumnCount(3);
userTree->header()->setResizeMode(QHeaderView::ResizeToContents);
userTree->setHeaderHidden(true);
userTree->setRootIsDecorated(false);
userTree->setIconSize(QSize(20, 12));
connect(userTree, SIGNAL(itemActivated(QTreeWidgetItem *, int)), this, SLOT(userClicked(QTreeWidgetItem *, int)));
QVBoxLayout *vbox = new QVBoxLayout;
vbox->addWidget(userTree);
setLayout(vbox);
retranslateUi();
connect(_client, SIGNAL(userJoinedEventReceived(Event_UserJoined *)), this, SLOT(processUserJoinedEvent(Event_UserJoined *)));
connect(_client, SIGNAL(userLeftEventReceived(Event_UserLeft *)), this, SLOT(processUserLeftEvent(Event_UserLeft *)));
Command_ListUsers *cmd = new Command_ListUsers;
connect(cmd, SIGNAL(finished(ProtocolResponse *)), this, SLOT(processResponse(ProtocolResponse *)));
_client->sendCommand(cmd);
}
void UserList::retranslateUi()
{
setTitle(tr("Users online: %1").arg(userTree->topLevelItemCount()));
}
void UserList::processUserInfo(ServerInfo_User *user)
{
QTreeWidgetItem *item = 0;
for (int i = 0; i < userTree->topLevelItemCount(); ++i) {
QTreeWidgetItem *temp = userTree->topLevelItem(i);
if (temp->data(2, Qt::UserRole) == user->getName()) {
item = temp;
break;
}
}
if (!item) {
item = new UserListTWI;
userTree->addTopLevelItem(item);
retranslateUi();
}
item->setData(0, Qt::UserRole, user->getUserLevel());
item->setIcon(0, QIcon(UserLevelPixmapGenerator::generatePixmap(12, user->getUserLevel())));
item->setIcon(1, QIcon(CountryPixmapGenerator::generatePixmap(12, user->getCountry())));
item->setData(2, Qt::UserRole, user->getName());
item->setData(2, Qt::DisplayRole, user->getName());
}
void UserList::processResponse(ProtocolResponse *response)
{
Response_ListUsers *resp = qobject_cast<Response_ListUsers *>(response);
Response_JoinRoom *resp = qobject_cast<Response_JoinRoom *>(r);
if (!resp)
return;
const QList<ServerInfo_User *> &respList = resp->getUserList();
for (int i = 0; i < respList.size(); ++i)
processUserInfo(respList[i]);
userTree->sortItems(1, Qt::AscendingOrder);
emit roomJoined(resp->getRoomInfo(), static_cast<Command *>(sender())->getExtraData().toBool());
}
void UserList::processUserJoinedEvent(Event_UserJoined *event)
{
processUserInfo(event->getUserInfo());
userTree->sortItems(1, Qt::AscendingOrder);
}
void UserList::processUserLeftEvent(Event_UserLeft *event)
{
for (int i = 0; i < userTree->topLevelItemCount(); ++i)
if (userTree->topLevelItem(i)->data(2, Qt::UserRole) == event->getUserName()) {
emit userLeft(event->getUserName());
delete userTree->takeTopLevelItem(i);
retranslateUi();
break;
}
}
void UserList::userClicked(QTreeWidgetItem *item, int /*column*/)
{
emit openMessageDialog(item->data(2, Qt::UserRole).toString(), true);
}
UserInfoBox::UserInfoBox(AbstractClient *_client, QWidget *parent)
UserInfoBox::UserInfoBox(ServerInfo_User *userInfo, QWidget *parent)
: QWidget(parent)
{
avatarLabel = new QLabel;
@ -367,9 +145,7 @@ UserInfoBox::UserInfoBox(AbstractClient *_client, QWidget *parent)
setLayout(mainLayout);
Command_GetUserInfo *cmd = new Command_GetUserInfo;
connect(cmd, SIGNAL(finished(ProtocolResponse *)), this, SLOT(processResponse(ProtocolResponse *)));
_client->sendCommand(cmd);
updateInfo(userInfo);
}
void UserInfoBox::retranslateUi()
@ -378,12 +154,8 @@ void UserInfoBox::retranslateUi()
userLevelLabel1->setText(tr("User level:"));
}
void UserInfoBox::processResponse(ProtocolResponse *response)
void UserInfoBox::updateInfo(ServerInfo_User *user)
{
Response_GetUserInfo *resp = qobject_cast<Response_GetUserInfo *>(response);
if (!resp)
return;
ServerInfo_User *user = resp->getUserInfo();
int userLevel = user->getUserLevel();
QPixmap avatarPixmap;
@ -406,27 +178,28 @@ void UserInfoBox::processResponse(ProtocolResponse *response)
userLevelLabel3->setText(userLevelText);
}
TabServer::TabServer(AbstractClient *_client, QWidget *parent)
TabServer::TabServer(AbstractClient *_client, ServerInfo_User *userInfo, QWidget *parent)
: Tab(parent), client(_client)
{
gameSelector = new GameSelector(client);
chatChannelSelector = new ChatChannelSelector(client);
serverMessageLog = new ServerMessageLog(client);
userInfoBox = new UserInfoBox(client);
userList = new UserList(client);
roomSelector = new RoomSelector(client);
serverInfoBox = new QTextBrowser;
userInfoBox = new UserInfoBox(userInfo);
userList = new UserList(true);
connect(gameSelector, SIGNAL(gameJoined(int)), this, SIGNAL(gameJoined(int)));
connect(chatChannelSelector, SIGNAL(channelJoined(const QString &)), this, SIGNAL(chatChannelJoined(const QString &)));
connect(roomSelector, SIGNAL(roomJoined(ServerInfo_Room *, bool)), this, SIGNAL(roomJoined(ServerInfo_Room *, bool)));
connect(userList, SIGNAL(openMessageDialog(const QString &, bool)), this, SIGNAL(openMessageDialog(const QString &, bool)));
connect(userList, SIGNAL(userLeft(const QString &)), this, SIGNAL(userLeft(const QString &)));
QHBoxLayout *hbox = new QHBoxLayout;
hbox->addWidget(chatChannelSelector);
hbox->addWidget(serverMessageLog);
connect(client, SIGNAL(userJoinedEventReceived(Event_UserJoined *)), this, SLOT(processUserJoinedEvent(Event_UserJoined *)));
connect(client, SIGNAL(userLeftEventReceived(Event_UserLeft *)), this, SLOT(processUserLeftEvent(Event_UserLeft *)));
connect(client, SIGNAL(serverMessageEventReceived(Event_ServerMessage *)), this, SLOT(processServerMessageEvent(Event_ServerMessage *)));
Command_ListUsers *cmd = new Command_ListUsers;
connect(cmd, SIGNAL(finished(ProtocolResponse *)), this, SLOT(processListUsersResponse(ProtocolResponse *)));
client->sendCommand(cmd);
QVBoxLayout *vbox = new QVBoxLayout;
vbox->addWidget(gameSelector);
vbox->addLayout(hbox);
vbox->addWidget(roomSelector);
vbox->addWidget(serverInfoBox);
QVBoxLayout *vbox2 = new QVBoxLayout;
vbox2->addWidget(userInfoBox);
@ -441,9 +214,37 @@ TabServer::TabServer(AbstractClient *_client, QWidget *parent)
void TabServer::retranslateUi()
{
gameSelector->retranslateUi();
chatChannelSelector->retranslateUi();
serverMessageLog->retranslateUi();
roomSelector->retranslateUi();
userInfoBox->retranslateUi();
userList->retranslateUi();
}
void TabServer::processServerMessageEvent(Event_ServerMessage *event)
{
serverInfoBox->setHtml(event->getMessage());
}
void TabServer::processListUsersResponse(ProtocolResponse *response)
{
Response_ListUsers *resp = qobject_cast<Response_ListUsers *>(response);
if (!resp)
return;
const QList<ServerInfo_User *> &respList = resp->getUserList();
for (int i = 0; i < respList.size(); ++i)
userList->processUserInfo(respList[i]);
userList->sortItems();
}
void TabServer::processUserJoinedEvent(Event_UserJoined *event)
{
userList->processUserInfo(event->getUserInfo());
userList->sortItems();
}
void TabServer::processUserLeftEvent(Event_UserLeft *event)
{
if (userList->deleteUser(event->getUserName()))
emit userLeft(event->getUserName());
}

View file

@ -3,102 +3,39 @@
#include <QGroupBox>
#include <QTreeWidget>
#include <QTextBrowser>
#include "tab.h"
#include "protocol_datastructures.h"
class AbstractClient;
class QTreeView;
class QTreeWidget;
class QTreeWidgetItem;
class QPushButton;
class QCheckBox;
class QTextEdit;
class QLabel;
class UserList;
class QPushButton;
class GamesModel;
class GamesProxyModel;
class Event_ListGames;
class Event_ListChatChannels;
class Event_ListRooms;
class Event_ServerMessage;
class Event_UserJoined;
class Event_UserLeft;
class ProtocolResponse;
class ServerInfo_User;
class ServerInfo_Room;
class GameSelector : public QGroupBox {
Q_OBJECT
public:
GameSelector(AbstractClient *_client, QWidget *parent = 0);
void retranslateUi();
private slots:
void processListGamesEvent(Event_ListGames *event);
void showFullGamesChanged(int state);
void actCreate();
void actJoin();
void checkResponse(ResponseCode response);
signals:
void gameJoined(int gameId);
private:
AbstractClient *client;
QTreeView *gameListView;
GamesModel *gameListModel;
GamesProxyModel *gameListProxyModel;
QPushButton *createButton, *joinButton, *spectateButton;
QCheckBox *showFullGamesCheckBox;
};
class ChatChannelSelector : public QGroupBox {
class RoomSelector : public QGroupBox {
Q_OBJECT
private:
QTreeWidget *channelList;
QTreeWidget *roomList;
QPushButton *joinButton;
AbstractClient *client;
void joinChannel(const QString &channelName);
void joinRoom(int id, bool setCurrent);
private slots:
void processListChatChannelsEvent(Event_ListChatChannels *event);
void processListRoomsEvent(Event_ListRooms *event);
void joinClicked();
void joinFinished(ResponseCode resp);
void joinFinished(ProtocolResponse *resp);
signals:
void channelJoined(const QString &channelName);
void roomJoined(ServerInfo_Room *info, bool setCurrent);
public:
ChatChannelSelector(AbstractClient *_client, QWidget *parent = 0);
void retranslateUi();
};
class ServerMessageLog : public QGroupBox {
Q_OBJECT
private:
QTextEdit *textEdit;
private slots:
void processServerMessageEvent(Event_ServerMessage *event);
public:
ServerMessageLog(AbstractClient *_client, QWidget *parent = 0);
void retranslateUi();
};
class UserListTWI : public QTreeWidgetItem {
public:
UserListTWI();
bool operator<(const QTreeWidgetItem &other) const;
};
class UserList : public QGroupBox {
Q_OBJECT
private:
QTreeWidget *userTree;
void processUserInfo(ServerInfo_User *user);
private slots:
void processResponse(ProtocolResponse *response);
void processUserJoinedEvent(Event_UserJoined *event);
void processUserLeftEvent(Event_UserLeft *event);
void userClicked(QTreeWidgetItem *item, int column);
signals:
void openMessageDialog(const QString &userName, bool focus);
void userLeft(const QString &userName);
public:
UserList(AbstractClient *_client, QWidget *parent = 0);
RoomSelector(AbstractClient *_client, QWidget *parent = 0);
void retranslateUi();
};
@ -106,29 +43,31 @@ class UserInfoBox : public QWidget {
Q_OBJECT
private:
QLabel *avatarLabel, *nameLabel, *countryLabel1, *countryLabel2, *userLevelLabel1, *userLevelLabel2, *userLevelLabel3;
private slots:
void processResponse(ProtocolResponse *response);
void updateInfo(ServerInfo_User *user);
public:
UserInfoBox(AbstractClient *_client, QWidget *parent = 0);
UserInfoBox(ServerInfo_User *userInfo, QWidget *parent = 0);
void retranslateUi();
};
class TabServer : public Tab {
Q_OBJECT
signals:
void chatChannelJoined(const QString &channelName);
void gameJoined(int gameId);
void roomJoined(ServerInfo_Room *info, bool setCurrent);
void openMessageDialog(const QString &userName, bool focus);
void userLeft(const QString &userName);
private slots:
void processListUsersResponse(ProtocolResponse *response);
void processUserJoinedEvent(Event_UserJoined *event);
void processUserLeftEvent(Event_UserLeft *event);
void processServerMessageEvent(Event_ServerMessage *event);
private:
AbstractClient *client;
GameSelector *gameSelector;
ChatChannelSelector *chatChannelSelector;
ServerMessageLog *serverMessageLog;
RoomSelector *roomSelector;
QTextBrowser *serverInfoBox;
UserList *userList;
UserInfoBox *userInfoBox;
public:
TabServer(AbstractClient *_client, QWidget *parent = 0);
TabServer(AbstractClient *_client, ServerInfo_User *userInfo, QWidget *parent = 0);
void retranslateUi();
QString getTabText() const { return tr("Server"); }
};

View file

@ -2,7 +2,7 @@
#include "tab_supervisor.h"
#include "abstractclient.h"
#include "tab_server.h"
#include "tab_chatchannel.h"
#include "tab_room.h"
#include "tab_game.h"
#include "tab_deck_storage.h"
#include "tab_message.h"
@ -32,9 +32,9 @@ void TabSupervisor::retranslateUi()
tabs.append(tabServer);
if (tabDeckStorage)
tabs.append(tabDeckStorage);
QMapIterator<QString, TabChatChannel *> chatChannelIterator(chatChannelTabs);
while (chatChannelIterator.hasNext())
tabs.append(chatChannelIterator.next().value());
QMapIterator<int, TabRoom *> roomIterator(roomTabs);
while (roomIterator.hasNext())
tabs.append(roomIterator.next().value());
QMapIterator<int, TabGame *> gameIterator(gameTabs);
while (gameIterator.hasNext())
tabs.append(gameIterator.next().value());
@ -51,17 +51,19 @@ void TabSupervisor::myAddTab(Tab *tab)
addTab(tab, tab->getTabText());
}
void TabSupervisor::start(AbstractClient *_client)
void TabSupervisor::start(AbstractClient *_client, ServerInfo_User *userInfo)
{
client = _client;
connect(client, SIGNAL(chatEventReceived(ChatEvent *)), this, SLOT(processChatEvent(ChatEvent *)));
userName = userInfo->getName();
connect(client, SIGNAL(roomEventReceived(RoomEvent *)), this, SLOT(processRoomEvent(RoomEvent *)));
connect(client, SIGNAL(gameEventContainerReceived(GameEventContainer *)), this, SLOT(processGameEventContainer(GameEventContainer *)));
connect(client, SIGNAL(gameJoinedEventReceived(Event_GameJoined *)), this, SLOT(gameJoined(Event_GameJoined *)));
connect(client, SIGNAL(messageEventReceived(Event_Message *)), this, SLOT(processMessageEvent(Event_Message *)));
connect(client, SIGNAL(maxPingTime(int, int)), this, SLOT(updatePingTime(int, int)));
tabServer = new TabServer(client);
connect(tabServer, SIGNAL(chatChannelJoined(const QString &)), this, SLOT(addChatChannelTab(const QString &)));
tabServer = new TabServer(client, userInfo);
connect(tabServer, SIGNAL(roomJoined(ServerInfo_Room *, bool)), this, SLOT(addRoomTab(ServerInfo_Room *, bool)));
connect(tabServer, SIGNAL(openMessageDialog(const QString &, bool)), this, SLOT(addMessageTab(const QString &, bool)));
connect(tabServer, SIGNAL(userLeft(const QString &)), this, SLOT(processUserLeft(const QString &)));
myAddTab(tabServer);
@ -107,10 +109,10 @@ void TabSupervisor::stop()
tabDeckStorage->deleteLater();
tabDeckStorage = 0;
QMapIterator<QString, TabChatChannel *> chatChannelIterator(chatChannelTabs);
while (chatChannelIterator.hasNext())
chatChannelIterator.next().value()->deleteLater();
chatChannelTabs.clear();
QMapIterator<int, TabRoom *> roomIterator(roomTabs);
while (roomIterator.hasNext())
roomIterator.next().value()->deleteLater();
roomTabs.clear();
QMapIterator<int, TabGame *> gameIterator(gameTabs);
while (gameIterator.hasNext())
@ -144,7 +146,7 @@ void TabSupervisor::localGameJoined(Event_GameJoined *event)
setCurrentWidget(tab);
for (int i = 1; i < localClients.size(); ++i) {
Command_JoinGame *cmd = new Command_JoinGame(event->getGameId());
Command_JoinGame *cmd = new Command_JoinGame(0, event->getGameId());
localClients[i]->sendCommand(cmd);
}
}
@ -160,29 +162,33 @@ void TabSupervisor::gameLeft(TabGame *tab)
stop();
}
void TabSupervisor::addChatChannelTab(const QString &channelName)
void TabSupervisor::addRoomTab(ServerInfo_Room *info, bool setCurrent)
{
TabChatChannel *tab = new TabChatChannel(client, channelName);
connect(tab, SIGNAL(channelClosing(TabChatChannel *)), this, SLOT(chatChannelLeft(TabChatChannel *)));
TabRoom *tab = new TabRoom(client, userName, info);
connect(tab, SIGNAL(roomClosing(TabRoom *)), this, SLOT(roomLeft(TabRoom *)));
myAddTab(tab);
chatChannelTabs.insert(channelName, tab);
setCurrentWidget(tab);
roomTabs.insert(info->getRoomId(), tab);
if (setCurrent)
setCurrentWidget(tab);
}
void TabSupervisor::chatChannelLeft(TabChatChannel *tab)
void TabSupervisor::roomLeft(TabRoom *tab)
{
emit setMenu(0);
chatChannelTabs.remove(tab->getChannelName());
roomTabs.remove(tab->getRoomId());
removeTab(indexOf(tab));
}
TabMessage *TabSupervisor::addMessageTab(const QString &userName, bool focus)
TabMessage *TabSupervisor::addMessageTab(const QString &receiverName, bool focus)
{
TabMessage *tab = new TabMessage(client, userName);
if (receiverName == userName)
return 0;
TabMessage *tab = new TabMessage(client, receiverName);
connect(tab, SIGNAL(talkClosing(TabMessage *)), this, SLOT(talkLeft(TabMessage *)));
myAddTab(tab);
messageTabs.insert(userName, tab);
messageTabs.insert(receiverName, tab);
if (focus)
setCurrentWidget(tab);
return tab;
@ -206,11 +212,11 @@ void TabSupervisor::tabUserEvent()
QApplication::alert(this);
}
void TabSupervisor::processChatEvent(ChatEvent *event)
void TabSupervisor::processRoomEvent(RoomEvent *event)
{
TabChatChannel *tab = chatChannelTabs.value(event->getChannel(), 0);
TabRoom *tab = roomTabs.value(event->getRoomId(), 0);
if (tab)
tab->processChatEvent(event);
tab->processRoomEvent(event);
}
void TabSupervisor::processGameEventContainer(GameEventContainer *cont)
@ -230,6 +236,8 @@ void TabSupervisor::processMessageEvent(Event_Message *event)
tab = messageTabs.value(event->getReceiverName());
if (!tab)
tab = addMessageTab(event->getSenderName(), false);
if (!tab)
return;
tab->processMessageEvent(event);
}

View file

@ -8,24 +8,27 @@ class QMenu;
class AbstractClient;
class Tab;
class TabServer;
class TabChatChannel;
class TabRoom;
class TabGame;
class TabDeckStorage;
class TabMessage;
class ChatEvent;
class RoomEvent;
class GameEventContainer;
class Event_GameJoined;
class Event_Message;
class ServerInfo_Room;
class ServerInfo_User;
class TabSupervisor : public QTabWidget {
Q_OBJECT
private:
QString userName;
QIcon *tabChangedIcon;
AbstractClient *client;
QList<AbstractClient *> localClients;
TabServer *tabServer;
TabDeckStorage *tabDeckStorage;
QMap<QString, TabChatChannel *> chatChannelTabs;
QMap<int, TabRoom *> roomTabs;
QMap<int, TabGame *> gameTabs;
QMap<QString, TabMessage *> messageTabs;
void myAddTab(Tab *tab);
@ -33,7 +36,7 @@ public:
TabSupervisor(QWidget *parent = 0);
~TabSupervisor();
void retranslateUi();
void start(AbstractClient *_client);
void start(AbstractClient *_client, ServerInfo_User *userInfo);
void startLocal(const QList<AbstractClient *> &_clients);
void stop();
int getGameCount() const { return gameTabs.size(); }
@ -46,13 +49,13 @@ private slots:
void gameJoined(Event_GameJoined *event);
void localGameJoined(Event_GameJoined *event);
void gameLeft(TabGame *tab);
void addChatChannelTab(const QString &channelName);
void chatChannelLeft(TabChatChannel *tab);
void addRoomTab(ServerInfo_Room *info, bool setCurrent);
void roomLeft(TabRoom *tab);
TabMessage *addMessageTab(const QString &userName, bool focus);
void processUserLeft(const QString &userName);
void talkLeft(TabMessage *tab);
void tabUserEvent();
void processChatEvent(ChatEvent *event);
void processRoomEvent(RoomEvent *event);
void processGameEventContainer(GameEventContainer *cont);
void processMessageEvent(Event_Message *event);
};

View file

@ -0,0 +1,93 @@
#include "userlist.h"
#include "abstractclient.h"
#include "pixmapgenerator.h"
#include <QHeaderView>
#include <QVBoxLayout>
UserListTWI::UserListTWI()
: QTreeWidgetItem(Type)
{
}
bool UserListTWI::operator<(const QTreeWidgetItem &other) const
{
// Equal user level => sort by name
if (data(0, Qt::UserRole) == other.data(0, Qt::UserRole))
return data(2, Qt::UserRole).toString().toLower() < other.data(2, Qt::UserRole).toString().toLower();
// Else sort by user level
return data(0, Qt::UserRole).toInt() > other.data(0, Qt::UserRole).toInt();
}
UserList::UserList(bool _global, QWidget *parent)
: QGroupBox(parent), global(_global)
{
userTree = new QTreeWidget;
userTree->setColumnCount(3);
userTree->header()->setResizeMode(QHeaderView::ResizeToContents);
userTree->setHeaderHidden(true);
userTree->setRootIsDecorated(false);
userTree->setIconSize(QSize(20, 12));
connect(userTree, SIGNAL(itemActivated(QTreeWidgetItem *, int)), this, SLOT(userClicked(QTreeWidgetItem *, int)));
QVBoxLayout *vbox = new QVBoxLayout;
vbox->addWidget(userTree);
setLayout(vbox);
retranslateUi();
}
void UserList::retranslateUi()
{
titleStr = global ? tr("Users online: %1") : tr("Users in this room: %1");
updateCount();
}
void UserList::processUserInfo(ServerInfo_User *user)
{
QTreeWidgetItem *item = 0;
for (int i = 0; i < userTree->topLevelItemCount(); ++i) {
QTreeWidgetItem *temp = userTree->topLevelItem(i);
if (temp->data(2, Qt::UserRole) == user->getName()) {
item = temp;
break;
}
}
if (!item) {
item = new UserListTWI;
userTree->addTopLevelItem(item);
retranslateUi();
}
item->setData(0, Qt::UserRole, user->getUserLevel());
item->setIcon(0, QIcon(UserLevelPixmapGenerator::generatePixmap(12, user->getUserLevel())));
item->setIcon(1, QIcon(CountryPixmapGenerator::generatePixmap(12, user->getCountry())));
item->setData(2, Qt::UserRole, user->getName());
item->setData(2, Qt::DisplayRole, user->getName());
}
bool UserList::deleteUser(const QString &userName)
{
for (int i = 0; i < userTree->topLevelItemCount(); ++i)
if (userTree->topLevelItem(i)->data(2, Qt::UserRole) == userName) {
delete userTree->takeTopLevelItem(i);
updateCount();
return true;
}
return false;
}
void UserList::updateCount()
{
setTitle(titleStr.arg(userTree->topLevelItemCount()));
}
void UserList::userClicked(QTreeWidgetItem *item, int /*column*/)
{
emit openMessageDialog(item->data(2, Qt::UserRole).toString(), true);
}
void UserList::sortItems()
{
userTree->sortItems(1, Qt::AscendingOrder);
}

35
cockatrice/src/userlist.h Normal file
View file

@ -0,0 +1,35 @@
#ifndef USERLIST_H
#define USERLIST_H
#include <QGroupBox>
#include <QTreeWidgetItem>
class QTreeWidget;
class ServerInfo_User;
class UserListTWI : public QTreeWidgetItem {
public:
UserListTWI();
bool operator<(const QTreeWidgetItem &other) const;
};
class UserList : public QGroupBox {
Q_OBJECT
private:
QTreeWidget *userTree;
bool global;
QString titleStr;
void updateCount();
private slots:
void userClicked(QTreeWidgetItem *item, int column);
signals:
void openMessageDialog(const QString &userName, bool focus);
public:
UserList(bool _global, QWidget *parent = 0);
void retranslateUi();
void processUserInfo(ServerInfo_User *user);
bool deleteUser(const QString &userName);
void sortItems();
};
#endif

View file

@ -64,15 +64,18 @@ void MainWindow::statusChanged(ClientStatus _status)
aConnect->setEnabled(false);
aDisconnect->setEnabled(true);
break;
case StatusLoggedIn: {
tabSupervisor->start(client);
case StatusLoggedIn:
break;
}
default:
break;
}
}
void MainWindow::userInfoReceived(ServerInfo_User *info)
{
tabSupervisor->start(client, info);
}
// Actions
void MainWindow::actConnect()
@ -110,7 +113,7 @@ void MainWindow::actSinglePlayer()
}
tabSupervisor->startLocal(localClients);
Command_CreateGame *createCommand = new Command_CreateGame(QString(), QString(), numberPlayers, false, false, false, false);
Command_CreateGame *createCommand = new Command_CreateGame(0, QString(), QString(), numberPlayers, false, false, false, false);
mainClient->sendCommand(createCommand);
}
@ -150,7 +153,15 @@ void MainWindow::actExit()
void MainWindow::actAbout()
{
QMessageBox::about(this, tr("About Cockatrice"), trUtf8("<font size=\"8\"><b>Cockatrice</b></font><br>Version %1<br><br><br><b>Authors:</b><br>Max-Wilhelm Bruker<br>Marcus Schütz<br>Marius van Zundert<br><br><b>Translators:</b><br>Spanish: Gocho<br>Portugese: Milton Gonçalves<br>").arg(versionString));
QMessageBox::about(this, tr("About Cockatrice"), QString(
"<font size=\"8\"><b>Cockatrice</b></font><br>"
+ tr("Version %1").arg(versionString)
+ "<br><br><br><b>" + tr("Authors:") + "</b><br>Max-Wilhelm Bruker<br>Marcus Schütz<br><br>"
+ "<b>" + tr("Translators:") + "</b><br>"
+ tr("Spanish:") + " Víctor Martínez<br>"
+ tr("Portugese:") + " Milton Gonçalves<br>"
+ tr("French:") + " Yannick Hammer<br>"
));
}
void MainWindow::serverTimeout()
@ -260,6 +271,7 @@ MainWindow::MainWindow(QWidget *parent)
connect(client, SIGNAL(serverTimeout()), this, SLOT(serverTimeout()));
connect(client, SIGNAL(statusChanged(ClientStatus)), this, SLOT(statusChanged(ClientStatus)));
connect(client, SIGNAL(protocolVersionMismatch(int, int)), this, SLOT(protocolVersionMismatch(int, int)));
connect(client, SIGNAL(userInfoChanged(ServerInfo_User *)), this, SLOT(userInfoReceived(ServerInfo_User *)));
tabSupervisor = new TabSupervisor;
connect(tabSupervisor, SIGNAL(setMenu(QMenu *)), this, SLOT(updateTabMenu(QMenu *)));

View file

@ -28,6 +28,7 @@ class TabSupervisor;
class RemoteClient;
class LocalClient;
class LocalServer;
class ServerInfo_User;
class MainWindow : public QMainWindow {
Q_OBJECT
@ -38,6 +39,7 @@ private slots:
void serverError(ResponseCode r);
void socketError(const QString &errorStr);
void protocolVersionMismatch(int localVersion, int remoteVersion);
void userInfoReceived(ServerInfo_User *userInfo);
void localGameEnded();
void actConnect();

View file

@ -9,7 +9,7 @@
#include "protocol_items.h"
#include "settingscache.h"
ZoneViewWidget::ZoneViewWidget(Player *_player, CardZone *_origZone, int numberCards, const QList<ServerInfo_Card *> &cardList)
ZoneViewWidget::ZoneViewWidget(Player *_player, CardZone *_origZone, int numberCards, bool _revealZone, const QList<ServerInfo_Card *> &cardList)
: QGraphicsWidget(0, Qt::Tool | Qt::CustomizeWindowHint | Qt::WindowSystemMenuHint | Qt::WindowTitleHint/* | Qt::WindowCloseButtonHint*/), player(_player)
{
setAttribute(Qt::WA_DeleteOnClose);
@ -48,7 +48,7 @@ ZoneViewWidget::ZoneViewWidget(Player *_player, CardZone *_origZone, int numberC
extraHeight = vbox->sizeHint(Qt::PreferredSize).height();
resize(150, 150);
zone = new ZoneViewZone(player, _origZone, numberCards, this);
zone = new ZoneViewZone(player, _origZone, numberCards, _revealZone, this);
connect(zone, SIGNAL(optimumRectChanged()), this, SLOT(resizeToZoneContents()));
connect(zone, SIGNAL(beingDeleted()), this, SLOT(zoneDeleted()));
vbox->addItem(zone);

View file

@ -30,7 +30,7 @@ private slots:
void resizeToZoneContents();
void zoneDeleted();
public:
ZoneViewWidget(Player *_player, CardZone *_origZone, int numberCards = 0, const QList<ServerInfo_Card *> &cardList = QList<ServerInfo_Card *>());
ZoneViewWidget(Player *_player, CardZone *_origZone, int numberCards = 0, bool _revealZone = false, const QList<ServerInfo_Card *> &cardList = QList<ServerInfo_Card *>());
ZoneViewZone *getZone() const { return zone; }
void retranslateUi();
protected:

View file

@ -5,17 +5,19 @@
#include "protocol_items.h"
#include "carddragitem.h"
ZoneViewZone::ZoneViewZone(Player *_p, CardZone *_origZone, int _numberCards, QGraphicsItem *parent)
: SelectZone(_p, _origZone->getName(), false, false, true, parent, true), bRect(QRectF()), minRows(0), numberCards(_numberCards), origZone(_origZone), sortByName(false), sortByType(false)
ZoneViewZone::ZoneViewZone(Player *_p, CardZone *_origZone, int _numberCards, bool _revealZone, QGraphicsItem *parent)
: SelectZone(_p, _origZone->getName(), false, false, true, parent, true), bRect(QRectF()), minRows(0), numberCards(_numberCards), origZone(_origZone), revealZone(_revealZone), sortByName(false), sortByType(false)
{
origZone->setView(this);
if (!revealZone)
origZone->setView(this);
}
ZoneViewZone::~ZoneViewZone()
{
emit beingDeleted();
qDebug("ZoneViewZone destructor");
origZone->setView(NULL);
if (!revealZone)
origZone->setView(NULL);
}
QRectF ZoneViewZone::boundingRect() const

View file

@ -15,9 +15,10 @@ private:
int minRows, numberCards;
void handleDropEvent(CardDragItem *dragItem, CardZone *startZone, const QPoint &dropPoint, bool faceDown);
CardZone *origZone;
bool revealZone;
bool sortByName, sortByType;
public:
ZoneViewZone(Player *_p, CardZone *_origZone, int _numberCards = -1, QGraphicsItem *parent = 0);
ZoneViewZone(Player *_p, CardZone *_origZone, int _numberCards = -1, bool _revealZone = false, QGraphicsItem *parent = 0);
~ZoneViewZone();
QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -14,7 +14,7 @@ void ProtocolItem::initializeHash()
initializeHashAuto();
registerSerializableItem("move_card_to_zone", MoveCardToZone::newItem);
registerSerializableItem("chat_channel", ServerInfo_ChatChannel::newItem);
registerSerializableItem("room", ServerInfo_Room::newItem);
registerSerializableItem("user", ServerInfo_User::newItem);
registerSerializableItem("game", ServerInfo_Game::newItem);
registerSerializableItem("card_counter", ServerInfo_CardCounter::newItem);
@ -37,16 +37,19 @@ void ProtocolItem::initializeHash()
registerSerializableItem("resp", ProtocolResponse::newItem);
ProtocolResponse::initializeHash();
registerSerializableItem("respjoin_room", Response_JoinRoom::newItem);
registerSerializableItem("resplist_users", Response_ListUsers::newItem);
registerSerializableItem("respget_user_info", Response_GetUserInfo::newItem);
registerSerializableItem("respdeck_list", Response_DeckList::newItem);
registerSerializableItem("respdeck_download", Response_DeckDownload::newItem);
registerSerializableItem("respdeck_upload", Response_DeckUpload::newItem);
registerSerializableItem("respdump_zone", Response_DumpZone::newItem);
registerSerializableItem("resplogin", Response_Login::newItem);
registerSerializableItem("generic_eventlist_games", Event_ListGames::newItem);
registerSerializableItem("room_eventlist_games", Event_ListGames::newItem);
registerSerializableItem("room_eventjoin_room", Event_JoinRoom::newItem);
registerSerializableItem("generic_eventuser_joined", Event_UserJoined::newItem);
registerSerializableItem("generic_eventlist_chat_channels", Event_ListChatChannels::newItem);
registerSerializableItem("generic_eventlist_rooms", Event_ListRooms::newItem);
registerSerializableItem("game_eventjoin", Event_Join::newItem);
registerSerializableItem("game_eventgame_state_changed", Event_GameStateChanged::newItem);
registerSerializableItem("game_eventplayer_properties_changed", Event_PlayerPropertiesChanged::newItem);
@ -55,8 +58,6 @@ void ProtocolItem::initializeHash()
registerSerializableItem("game_eventdraw_cards", Event_DrawCards::newItem);
registerSerializableItem("game_eventreveal_cards", Event_RevealCards::newItem);
registerSerializableItem("game_eventping", Event_Ping::newItem);
registerSerializableItem("chat_eventchat_list_players", Event_ChatListPlayers::newItem);
registerSerializableItem("chat_eventchat_join_channel", Event_ChatJoinChannel::newItem);
}
TopLevelProtocolItem::TopLevelProtocolItem()
@ -221,6 +222,14 @@ void ProtocolResponse::initializeHash()
responseHash.insert("spectators_not_allowed", RespSpectatorsNotAllowed);
}
Response_JoinRoom::Response_JoinRoom(int _cmdId, ResponseCode _responseCode, ServerInfo_Room *_roomInfo)
: ProtocolResponse(_cmdId, _responseCode, "join_room")
{
if (!_roomInfo)
_roomInfo = new ServerInfo_Room;
insertItem(_roomInfo);
}
Response_ListUsers::Response_ListUsers(int _cmdId, ResponseCode _responseCode, const QList<ServerInfo_User *> &_userList)
: ProtocolResponse(_cmdId, _responseCode, "list_users")
{
@ -273,6 +282,14 @@ Response_DumpZone::Response_DumpZone(int _cmdId, ResponseCode _responseCode, Ser
insertItem(_zone);
}
Response_Login::Response_Login(int _cmdId, ResponseCode _responseCode, ServerInfo_User *_userInfo)
: ProtocolResponse(_cmdId, _responseCode, "login")
{
if (!_userInfo)
_userInfo = new ServerInfo_User;
insertItem(_userInfo);
}
GameEvent::GameEvent(const QString &_eventName, int _playerId)
: ProtocolItem("game_event", _eventName)
{
@ -284,36 +301,29 @@ GameEventContext::GameEventContext(const QString &_contextName)
{
}
ChatEvent::ChatEvent(const QString &_eventName, const QString &_channel)
: ProtocolItem("chat_event", _eventName)
RoomEvent::RoomEvent(const QString &_eventName, int _roomId)
: ProtocolItem("room_event", _eventName)
{
insertItem(new SerializableItem_String("channel", _channel));
insertItem(new SerializableItem_Int("room_id", _roomId));
}
Event_ListChatChannels::Event_ListChatChannels(const QList<ServerInfo_ChatChannel *> &_channelList)
: GenericEvent("list_chat_channels")
Event_ListRooms::Event_ListRooms(const QList<ServerInfo_Room *> &_roomList)
: GenericEvent("list_rooms")
{
for (int i = 0; i < _channelList.size(); ++i)
itemList.append(_channelList[i]);
for (int i = 0; i < _roomList.size(); ++i)
itemList.append(_roomList[i]);
}
Event_ChatListPlayers::Event_ChatListPlayers(const QString &_channel, const QList<ServerInfo_User *> &_playerList)
: ChatEvent("chat_list_players", _channel)
{
for (int i = 0; i < _playerList.size(); ++i)
itemList.append(_playerList[i]);
}
Event_ChatJoinChannel::Event_ChatJoinChannel(const QString &_channel, ServerInfo_User *_info)
: ChatEvent("chat_join_channel", _channel)
Event_JoinRoom::Event_JoinRoom(int _roomId, ServerInfo_User *_info)
: RoomEvent("join_room", _roomId)
{
if (!_info)
_info = new ServerInfo_User;
insertItem(_info);
}
Event_ListGames::Event_ListGames(const QList<ServerInfo_Game *> &_gameList)
: GenericEvent("list_games")
Event_ListGames::Event_ListGames(int _roomId, const QList<ServerInfo_Game *> &_gameList)
: RoomEvent("list_games", _roomId)
{
for (int i = 0; i < _gameList.size(); ++i)
itemList.append(_gameList[i]);

View file

@ -25,9 +25,8 @@ enum ItemId {
ItemId_Command_DeckUpload = ItemId_Other + 100,
ItemId_Command_DeckSelect = ItemId_Other + 101,
ItemId_Command_SetSideboardPlan = ItemId_Other + 102,
ItemId_Event_ListChatChannels = ItemId_Other + 200,
ItemId_Event_ChatListPlayers = ItemId_Other + 201,
ItemId_Event_ChatJoinChannel = ItemId_Other + 202,
ItemId_Event_ListRooms = ItemId_Other + 200,
ItemId_Event_JoinRoom = ItemId_Other + 201,
ItemId_Event_ListGames = ItemId_Other + 203,
ItemId_Event_UserJoined = ItemId_Other + 204,
ItemId_Event_GameStateChanged = ItemId_Other + 205,
@ -44,6 +43,8 @@ enum ItemId {
ItemId_Response_DeckDownload = ItemId_Other + 303,
ItemId_Response_DeckUpload = ItemId_Other + 304,
ItemId_Response_DumpZone = ItemId_Other + 305,
ItemId_Response_JoinRoom = ItemId_Other + 306,
ItemId_Response_Login = ItemId_Other + 307,
ItemId_Invalid = ItemId_Other + 1000
};
@ -53,7 +54,7 @@ private:
static void initializeHashAuto();
bool receiverMayDelete;
public:
static const int protocolVersion = 10;
static const int protocolVersion = 11;
static void initializeHash();
virtual int getItemId() const = 0;
bool getReceiverMayDelete() const { return receiverMayDelete; }
@ -136,15 +137,15 @@ public:
int getPrivatePlayerId() const { return privatePlayerId; }
};
class ChatCommand : public Command {
class RoomCommand : public Command {
Q_OBJECT
public:
ChatCommand(const QString &_cmdName, const QString &_channel)
RoomCommand(const QString &_cmdName, int _roomId)
: Command(_cmdName)
{
insertItem(new SerializableItem_String("channel", _channel));
insertItem(new SerializableItem_Int("room_id", _roomId));
}
QString getChannel() const { return static_cast<SerializableItem_String *>(itemMap.value("channel"))->getData(); }
int getRoomId() const { return static_cast<SerializableItem_Int *>(itemMap.value("room_id"))->getData(); }
};
class GameCommand : public Command {
@ -205,6 +206,15 @@ public:
ResponseCode getResponseCode() const { return responseHash.value(static_cast<SerializableItem_String *>(itemMap.value("response_code"))->getData(), RespOk); }
};
class Response_JoinRoom : public ProtocolResponse {
Q_OBJECT
public:
Response_JoinRoom(int _cmdId = -1, ResponseCode _responseCode = RespOk, ServerInfo_Room *_roomInfo = 0);
int getItemId() const { return ItemId_Response_JoinRoom; }
static SerializableItem *newItem() { return new Response_JoinRoom; }
ServerInfo_Room *getRoomInfo() const { return static_cast<ServerInfo_Room *>(itemMap.value("room")); }
};
class Response_ListUsers : public ProtocolResponse {
Q_OBJECT
public:
@ -259,6 +269,15 @@ public:
ServerInfo_Zone *getZone() const { return static_cast<ServerInfo_Zone *>(itemMap.value("zone")); }
};
class Response_Login : public ProtocolResponse {
Q_OBJECT
public:
Response_Login(int _cmdId = -1, ResponseCode _responseCode = RespOk, ServerInfo_User *_userInfo = 0);
int getItemId() const { return ItemId_Response_Login; }
static SerializableItem *newItem() { return new Response_Login; }
ServerInfo_User *getUserInfo() const { return static_cast<ServerInfo_User *>(itemMap.value("user")); }
};
// --------------
// --- EVENTS ---
// --------------
@ -304,44 +323,35 @@ public:
void setGameId(int _gameId) { static_cast<SerializableItem_Int *>(itemMap.value("game_id"))->setData(_gameId); }
};
class ChatEvent : public ProtocolItem {
class RoomEvent : public ProtocolItem {
Q_OBJECT
public:
ChatEvent(const QString &_eventName, const QString &_channel);
QString getChannel() const { return static_cast<SerializableItem_String *>(itemMap.value("channel"))->getData(); }
RoomEvent(const QString &_eventName, int _roomId);
int getRoomId() const { return static_cast<SerializableItem_Int *>(itemMap.value("room_id"))->getData(); }
};
class Event_ListChatChannels : public GenericEvent {
class Event_ListRooms : public GenericEvent {
Q_OBJECT
public:
Event_ListChatChannels(const QList<ServerInfo_ChatChannel *> &_channelList = QList<ServerInfo_ChatChannel *>());
int getItemId() const { return ItemId_Event_ListChatChannels; }
static SerializableItem *newItem() { return new Event_ListChatChannels; }
QList<ServerInfo_ChatChannel *> getChannelList() const { return typecastItemList<ServerInfo_ChatChannel *>(); }
Event_ListRooms(const QList<ServerInfo_Room *> &_roomList = QList<ServerInfo_Room *>());
int getItemId() const { return ItemId_Event_ListRooms; }
static SerializableItem *newItem() { return new Event_ListRooms; }
QList<ServerInfo_Room *> getRoomList() const { return typecastItemList<ServerInfo_Room *>(); }
};
class Event_ChatListPlayers : public ChatEvent {
class Event_JoinRoom : public RoomEvent {
Q_OBJECT
public:
Event_ChatListPlayers(const QString &_channel = QString(), const QList<ServerInfo_User *> &_playerList = QList<ServerInfo_User *>());
int getItemId() const { return ItemId_Event_ChatListPlayers; }
static SerializableItem *newItem() { return new Event_ChatListPlayers; }
QList<ServerInfo_User *> getPlayerList() const { return typecastItemList<ServerInfo_User *>(); }
};
class Event_ChatJoinChannel : public ChatEvent {
Q_OBJECT
public:
Event_ChatJoinChannel(const QString &_channel = QString(), ServerInfo_User *_info = 0);
int getItemId() const { return ItemId_Event_ChatJoinChannel; }
static SerializableItem *newItem() { return new Event_ChatJoinChannel; }
Event_JoinRoom(int _roomId = -1, ServerInfo_User *_info = 0);
int getItemId() const { return ItemId_Event_JoinRoom; }
static SerializableItem *newItem() { return new Event_JoinRoom; }
ServerInfo_User *getUserInfo() const { return static_cast<ServerInfo_User *>(itemMap.value("user")); }
};
class Event_ListGames : public GenericEvent {
class Event_ListGames : public RoomEvent {
Q_OBJECT
public:
Event_ListGames(const QList<ServerInfo_Game *> &_gameList = QList<ServerInfo_Game *>());
Event_ListGames(int _roomId = -1, const QList<ServerInfo_Game *> &_gameList = QList<ServerInfo_Game *>());
int getItemId() const { return ItemId_Event_ListGames; }
static SerializableItem *newItem() { return new Event_ListGames; }
QList<ServerInfo_Game *> getGameList() const { return typecastItemList<ServerInfo_Game *>(); }

View file

@ -3,15 +3,6 @@
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
ServerInfo_ChatChannel::ServerInfo_ChatChannel(const QString &_name, const QString &_description, int _playerCount, bool _autoJoin)
: SerializableItem_Map("chat_channel")
{
insertItem(new SerializableItem_String("name", _name));
insertItem(new SerializableItem_String("description", _description));
insertItem(new SerializableItem_Int("player_count", _playerCount));
insertItem(new SerializableItem_Bool("auto_join", _autoJoin));
}
ServerInfo_User::ServerInfo_User(const QString &_name, int _userLevel, const QString &_country, const QByteArray &_avatarBmp)
: SerializableItem_Map("user")
{
@ -21,13 +12,13 @@ ServerInfo_User::ServerInfo_User(const QString &_name, int _userLevel, const QSt
insertItem(new SerializableItem_ByteArray("avatar_bmp", _avatarBmp));
}
ServerInfo_User::ServerInfo_User(const ServerInfo_User *other)
ServerInfo_User::ServerInfo_User(const ServerInfo_User *other, bool complete)
: SerializableItem_Map("user")
{
insertItem(new SerializableItem_String("name", other->getName()));
insertItem(new SerializableItem_Int("userlevel", other->getUserLevel()));
insertItem(new SerializableItem_String("country", other->getCountry()));
insertItem(new SerializableItem_ByteArray("avatar_bmp", other->getAvatarBmp()));
insertItem(new SerializableItem_ByteArray("avatar_bmp", complete ? other->getAvatarBmp() : QByteArray()));
}
ServerInfo_Game::ServerInfo_Game(int _gameId, const QString &_description, bool _hasPassword, int _playerCount, int _maxPlayers, ServerInfo_User *_creatorInfo, bool _spectatorsAllowed, bool _spectatorsNeedPassword, int _spectatorCount)
@ -46,6 +37,40 @@ ServerInfo_Game::ServerInfo_Game(int _gameId, const QString &_description, bool
insertItem(new SerializableItem_Int("spectator_count", _spectatorCount));
}
ServerInfo_Room::ServerInfo_Room(int _roomId, const QString &_name, const QString &_description, int _gameCount, int _playerCount, bool _autoJoin, const QList<ServerInfo_Game *> &_gameList, const QList<ServerInfo_User *> &_userList)
: SerializableItem_Map("room")
{
insertItem(new SerializableItem_Int("room_id", _roomId));
insertItem(new SerializableItem_String("name", _name));
insertItem(new SerializableItem_String("description", _description));
insertItem(new SerializableItem_Int("game_count", _gameCount));
insertItem(new SerializableItem_Int("player_count", _playerCount));
insertItem(new SerializableItem_Bool("auto_join", _autoJoin));
gameList = _gameList;
for (int i = 0; i < _gameList.size(); ++i)
itemList.append(_gameList[i]);
userList = _userList;
for (int i = 0; i < _userList.size(); ++i)
itemList.append(_userList[i]);
}
void ServerInfo_Room::extractData()
{
for (int i = 0; i < itemList.size(); ++i) {
ServerInfo_User *user = dynamic_cast<ServerInfo_User *>(itemList[i]);
if (user) {
userList.append(user);
continue;
}
ServerInfo_Game *game = dynamic_cast<ServerInfo_Game *>(itemList[i]);
if (game) {
gameList.append(game);
continue;
}
}
}
ServerInfo_CardCounter::ServerInfo_CardCounter(int _id, int _value)
: SerializableItem_Map("card_counter")
{

View file

@ -20,16 +20,6 @@ enum ResponseCode { RespNothing, RespOk, RespInvalidCommand, RespInvalidData, Re
// list index, whereas cards in any other zone are referenced by their ids.
enum ZoneType { PrivateZone, PublicZone, HiddenZone };
class ServerInfo_ChatChannel : public SerializableItem_Map {
public:
ServerInfo_ChatChannel(const QString &_name = QString(), const QString &_description = QString(), int _playerCount = -1, bool _autoJoin = false);
static SerializableItem *newItem() { return new ServerInfo_ChatChannel; }
QString getName() const { return static_cast<SerializableItem_String *>(itemMap.value("name"))->getData(); }
QString getDescription() const { return static_cast<SerializableItem_String *>(itemMap.value("description"))->getData(); }
int getPlayerCount() const { return static_cast<SerializableItem_Int *>(itemMap.value("player_count"))->getData(); }
bool getAutoJoin() const { return static_cast<SerializableItem_Bool *>(itemMap.value("auto_join"))->getData(); }
};
class ServerInfo_User : public SerializableItem_Map {
public:
enum UserLevelFlags {
@ -40,7 +30,7 @@ public:
IsAdmin = 0x08
};
ServerInfo_User(const QString &_name = QString(), int _userLevel = IsNothing, const QString &_country = QString(), const QByteArray &_avatarBmp = QByteArray());
ServerInfo_User(const ServerInfo_User *other);
ServerInfo_User(const ServerInfo_User *other, bool complete = true);
static SerializableItem *newItem() { return new ServerInfo_User; }
QString getName() const { return static_cast<SerializableItem_String *>(itemMap.value("name"))->getData(); }
int getUserLevel() const { return static_cast<SerializableItem_Int *>(itemMap.value("userlevel"))->getData(); }
@ -64,6 +54,25 @@ public:
int getSpectatorCount() const { return static_cast<SerializableItem_Int *>(itemMap.value("spectator_count"))->getData(); }
};
class ServerInfo_Room : public SerializableItem_Map {
private:
QList<ServerInfo_Game *> gameList;
QList<ServerInfo_User *> userList;
protected:
void extractData();
public:
ServerInfo_Room(int _id = -1, const QString &_name = QString(), const QString &_description = QString(), int _gameCount = -1, int _playerCount = -1, bool _autoJoin = false, const QList<ServerInfo_Game *> &_gameList = QList<ServerInfo_Game *>(), const QList<ServerInfo_User *> &_userList = QList<ServerInfo_User *>());
static SerializableItem *newItem() { return new ServerInfo_Room; }
int getRoomId() const { return static_cast<SerializableItem_Int *>(itemMap.value("room_id"))->getData(); }
QString getName() const { return static_cast<SerializableItem_String *>(itemMap.value("name"))->getData(); }
QString getDescription() const { return static_cast<SerializableItem_String *>(itemMap.value("description"))->getData(); }
int getGameCount() const { return static_cast<SerializableItem_Int *>(itemMap.value("game_count"))->getData(); }
int getPlayerCount() const { return static_cast<SerializableItem_Int *>(itemMap.value("player_count"))->getData(); }
bool getAutoJoin() const { return static_cast<SerializableItem_Bool *>(itemMap.value("auto_join"))->getData(); }
const QList<ServerInfo_Game *> &getGameList() const { return gameList; }
const QList<ServerInfo_User *> &getUserList() const { return userList; }
};
class ServerInfo_CardCounter : public SerializableItem_Map {
public:
ServerInfo_CardCounter(int _id = -1, int _value = 0);

View file

@ -2,73 +2,72 @@ enum AutoItemId {
ItemId_Command_Ping = 1001,
ItemId_Command_Login = 1002,
ItemId_Command_Message = 1003,
ItemId_Command_GetUserInfo = 1004,
ItemId_Command_DeckList = 1005,
ItemId_Command_DeckNewDir = 1006,
ItemId_Command_DeckDelDir = 1007,
ItemId_Command_DeckDel = 1008,
ItemId_Command_DeckDownload = 1009,
ItemId_Command_ListChatChannels = 1010,
ItemId_Command_ChatJoinChannel = 1011,
ItemId_Command_ChatLeaveChannel = 1012,
ItemId_Command_ChatSay = 1013,
ItemId_Command_ListGames = 1014,
ItemId_Command_ListUsers = 1015,
ItemId_Command_CreateGame = 1016,
ItemId_Command_JoinGame = 1017,
ItemId_Command_LeaveGame = 1018,
ItemId_Command_Say = 1019,
ItemId_Command_Shuffle = 1020,
ItemId_Command_Mulligan = 1021,
ItemId_Command_RollDie = 1022,
ItemId_Command_DrawCards = 1023,
ItemId_Command_MoveCard = 1024,
ItemId_Command_FlipCard = 1025,
ItemId_Command_AttachCard = 1026,
ItemId_Command_CreateToken = 1027,
ItemId_Command_CreateArrow = 1028,
ItemId_Command_DeleteArrow = 1029,
ItemId_Command_SetCardAttr = 1030,
ItemId_Command_SetCardCounter = 1031,
ItemId_Command_IncCardCounter = 1032,
ItemId_Command_ReadyStart = 1033,
ItemId_Command_Concede = 1034,
ItemId_Command_IncCounter = 1035,
ItemId_Command_CreateCounter = 1036,
ItemId_Command_SetCounter = 1037,
ItemId_Command_DelCounter = 1038,
ItemId_Command_NextTurn = 1039,
ItemId_Command_SetActivePhase = 1040,
ItemId_Command_DumpZone = 1041,
ItemId_Command_StopDumpZone = 1042,
ItemId_Command_RevealCards = 1043,
ItemId_Event_Say = 1044,
ItemId_Event_Leave = 1045,
ItemId_Event_GameClosed = 1046,
ItemId_Event_Shuffle = 1047,
ItemId_Event_RollDie = 1048,
ItemId_Event_MoveCard = 1049,
ItemId_Event_FlipCard = 1050,
ItemId_Event_DestroyCard = 1051,
ItemId_Event_AttachCard = 1052,
ItemId_Event_CreateToken = 1053,
ItemId_Event_DeleteArrow = 1054,
ItemId_Event_SetCardAttr = 1055,
ItemId_Event_SetCardCounter = 1056,
ItemId_Event_SetCounter = 1057,
ItemId_Event_DelCounter = 1058,
ItemId_Event_SetActivePlayer = 1059,
ItemId_Event_SetActivePhase = 1060,
ItemId_Event_DumpZone = 1061,
ItemId_Event_StopDumpZone = 1062,
ItemId_Event_ServerMessage = 1063,
ItemId_Event_Message = 1064,
ItemId_Event_GameJoined = 1065,
ItemId_Event_UserLeft = 1066,
ItemId_Event_ChatLeaveChannel = 1067,
ItemId_Event_ChatSay = 1068,
ItemId_Context_ReadyStart = 1069,
ItemId_Context_Concede = 1070,
ItemId_Context_DeckSelect = 1071,
ItemId_Other = 1072
ItemId_Command_ListUsers = 1004,
ItemId_Command_GetUserInfo = 1005,
ItemId_Command_DeckList = 1006,
ItemId_Command_DeckNewDir = 1007,
ItemId_Command_DeckDelDir = 1008,
ItemId_Command_DeckDel = 1009,
ItemId_Command_DeckDownload = 1010,
ItemId_Command_ListRooms = 1011,
ItemId_Command_JoinRoom = 1012,
ItemId_Command_LeaveRoom = 1013,
ItemId_Command_RoomSay = 1014,
ItemId_Command_CreateGame = 1015,
ItemId_Command_JoinGame = 1016,
ItemId_Command_LeaveGame = 1017,
ItemId_Command_Say = 1018,
ItemId_Command_Shuffle = 1019,
ItemId_Command_Mulligan = 1020,
ItemId_Command_RollDie = 1021,
ItemId_Command_DrawCards = 1022,
ItemId_Command_MoveCard = 1023,
ItemId_Command_FlipCard = 1024,
ItemId_Command_AttachCard = 1025,
ItemId_Command_CreateToken = 1026,
ItemId_Command_CreateArrow = 1027,
ItemId_Command_DeleteArrow = 1028,
ItemId_Command_SetCardAttr = 1029,
ItemId_Command_SetCardCounter = 1030,
ItemId_Command_IncCardCounter = 1031,
ItemId_Command_ReadyStart = 1032,
ItemId_Command_Concede = 1033,
ItemId_Command_IncCounter = 1034,
ItemId_Command_CreateCounter = 1035,
ItemId_Command_SetCounter = 1036,
ItemId_Command_DelCounter = 1037,
ItemId_Command_NextTurn = 1038,
ItemId_Command_SetActivePhase = 1039,
ItemId_Command_DumpZone = 1040,
ItemId_Command_StopDumpZone = 1041,
ItemId_Command_RevealCards = 1042,
ItemId_Event_Say = 1043,
ItemId_Event_Leave = 1044,
ItemId_Event_GameClosed = 1045,
ItemId_Event_Shuffle = 1046,
ItemId_Event_RollDie = 1047,
ItemId_Event_MoveCard = 1048,
ItemId_Event_FlipCard = 1049,
ItemId_Event_DestroyCard = 1050,
ItemId_Event_AttachCard = 1051,
ItemId_Event_CreateToken = 1052,
ItemId_Event_DeleteArrow = 1053,
ItemId_Event_SetCardAttr = 1054,
ItemId_Event_SetCardCounter = 1055,
ItemId_Event_SetCounter = 1056,
ItemId_Event_DelCounter = 1057,
ItemId_Event_SetActivePlayer = 1058,
ItemId_Event_SetActivePhase = 1059,
ItemId_Event_DumpZone = 1060,
ItemId_Event_StopDumpZone = 1061,
ItemId_Event_ServerMessage = 1062,
ItemId_Event_Message = 1063,
ItemId_Event_GameJoined = 1064,
ItemId_Event_UserLeft = 1065,
ItemId_Event_LeaveRoom = 1066,
ItemId_Event_RoomSay = 1067,
ItemId_Context_ReadyStart = 1068,
ItemId_Context_Concede = 1069,
ItemId_Context_DeckSelect = 1070,
ItemId_Other = 1071
};

View file

@ -17,6 +17,10 @@ Command_Message::Command_Message(const QString &_userName, const QString &_text)
insertItem(new SerializableItem_String("user_name", _userName));
insertItem(new SerializableItem_String("text", _text));
}
Command_ListUsers::Command_ListUsers()
: Command("list_users")
{
}
Command_GetUserInfo::Command_GetUserInfo(const QString &_userName)
: Command("get_user_info")
{
@ -47,34 +51,26 @@ Command_DeckDownload::Command_DeckDownload(int _deckId)
{
insertItem(new SerializableItem_Int("deck_id", _deckId));
}
Command_ListChatChannels::Command_ListChatChannels()
: Command("list_chat_channels")
Command_ListRooms::Command_ListRooms()
: Command("list_rooms")
{
}
Command_ChatJoinChannel::Command_ChatJoinChannel(const QString &_channel)
: Command("chat_join_channel")
Command_JoinRoom::Command_JoinRoom(int _roomId)
: Command("join_room")
{
insertItem(new SerializableItem_String("channel", _channel));
insertItem(new SerializableItem_Int("room_id", _roomId));
}
Command_ChatLeaveChannel::Command_ChatLeaveChannel(const QString &_channel)
: ChatCommand("chat_leave_channel", _channel)
Command_LeaveRoom::Command_LeaveRoom(int _roomId)
: RoomCommand("leave_room", _roomId)
{
}
Command_ChatSay::Command_ChatSay(const QString &_channel, const QString &_message)
: ChatCommand("chat_say", _channel)
Command_RoomSay::Command_RoomSay(int _roomId, const QString &_message)
: RoomCommand("room_say", _roomId)
{
insertItem(new SerializableItem_String("message", _message));
}
Command_ListGames::Command_ListGames()
: Command("list_games")
{
}
Command_ListUsers::Command_ListUsers()
: Command("list_users")
{
}
Command_CreateGame::Command_CreateGame(const QString &_description, const QString &_password, int _maxPlayers, bool _spectatorsAllowed, bool _spectatorsNeedPassword, bool _spectatorsCanTalk, bool _spectatorsSeeEverything)
: Command("create_game")
Command_CreateGame::Command_CreateGame(int _roomId, const QString &_description, const QString &_password, int _maxPlayers, bool _spectatorsAllowed, bool _spectatorsNeedPassword, bool _spectatorsCanTalk, bool _spectatorsSeeEverything)
: RoomCommand("create_game", _roomId)
{
insertItem(new SerializableItem_String("description", _description));
insertItem(new SerializableItem_String("password", _password));
@ -84,8 +80,8 @@ Command_CreateGame::Command_CreateGame(const QString &_description, const QStrin
insertItem(new SerializableItem_Bool("spectators_can_talk", _spectatorsCanTalk));
insertItem(new SerializableItem_Bool("spectators_see_everything", _spectatorsSeeEverything));
}
Command_JoinGame::Command_JoinGame(int _gameId, const QString &_password, bool _spectator)
: Command("join_game")
Command_JoinGame::Command_JoinGame(int _roomId, int _gameId, const QString &_password, bool _spectator)
: RoomCommand("join_game", _roomId)
{
insertItem(new SerializableItem_Int("game_id", _gameId));
insertItem(new SerializableItem_String("password", _password));
@ -417,13 +413,13 @@ Event_UserLeft::Event_UserLeft(const QString &_userName)
{
insertItem(new SerializableItem_String("user_name", _userName));
}
Event_ChatLeaveChannel::Event_ChatLeaveChannel(const QString &_channel, const QString &_playerName)
: ChatEvent("chat_leave_channel", _channel)
Event_LeaveRoom::Event_LeaveRoom(int _roomId, const QString &_playerName)
: RoomEvent("leave_room", _roomId)
{
insertItem(new SerializableItem_String("player_name", _playerName));
}
Event_ChatSay::Event_ChatSay(const QString &_channel, const QString &_playerName, const QString &_message)
: ChatEvent("chat_say", _channel)
Event_RoomSay::Event_RoomSay(int _roomId, const QString &_playerName, const QString &_message)
: RoomEvent("room_say", _roomId)
{
insertItem(new SerializableItem_String("player_name", _playerName));
insertItem(new SerializableItem_String("message", _message));
@ -446,18 +442,17 @@ void ProtocolItem::initializeHashAuto()
itemNameHash.insert("cmdping", Command_Ping::newItem);
itemNameHash.insert("cmdlogin", Command_Login::newItem);
itemNameHash.insert("cmdmessage", Command_Message::newItem);
itemNameHash.insert("cmdlist_users", Command_ListUsers::newItem);
itemNameHash.insert("cmdget_user_info", Command_GetUserInfo::newItem);
itemNameHash.insert("cmddeck_list", Command_DeckList::newItem);
itemNameHash.insert("cmddeck_new_dir", Command_DeckNewDir::newItem);
itemNameHash.insert("cmddeck_del_dir", Command_DeckDelDir::newItem);
itemNameHash.insert("cmddeck_del", Command_DeckDel::newItem);
itemNameHash.insert("cmddeck_download", Command_DeckDownload::newItem);
itemNameHash.insert("cmdlist_chat_channels", Command_ListChatChannels::newItem);
itemNameHash.insert("cmdchat_join_channel", Command_ChatJoinChannel::newItem);
itemNameHash.insert("cmdchat_leave_channel", Command_ChatLeaveChannel::newItem);
itemNameHash.insert("cmdchat_say", Command_ChatSay::newItem);
itemNameHash.insert("cmdlist_games", Command_ListGames::newItem);
itemNameHash.insert("cmdlist_users", Command_ListUsers::newItem);
itemNameHash.insert("cmdlist_rooms", Command_ListRooms::newItem);
itemNameHash.insert("cmdjoin_room", Command_JoinRoom::newItem);
itemNameHash.insert("cmdleave_room", Command_LeaveRoom::newItem);
itemNameHash.insert("cmdroom_say", Command_RoomSay::newItem);
itemNameHash.insert("cmdcreate_game", Command_CreateGame::newItem);
itemNameHash.insert("cmdjoin_game", Command_JoinGame::newItem);
itemNameHash.insert("cmdleave_game", Command_LeaveGame::newItem);
@ -509,8 +504,8 @@ void ProtocolItem::initializeHashAuto()
itemNameHash.insert("generic_eventmessage", Event_Message::newItem);
itemNameHash.insert("generic_eventgame_joined", Event_GameJoined::newItem);
itemNameHash.insert("generic_eventuser_left", Event_UserLeft::newItem);
itemNameHash.insert("chat_eventchat_leave_channel", Event_ChatLeaveChannel::newItem);
itemNameHash.insert("chat_eventchat_say", Event_ChatSay::newItem);
itemNameHash.insert("room_eventleave_room", Event_LeaveRoom::newItem);
itemNameHash.insert("room_eventroom_say", Event_RoomSay::newItem);
itemNameHash.insert("game_event_contextready_start", Context_ReadyStart::newItem);
itemNameHash.insert("game_event_contextconcede", Context_Concede::newItem);
itemNameHash.insert("game_event_contextdeck_select", Context_DeckSelect::newItem);

View file

@ -1,20 +1,19 @@
0:ping
0:login:s,username:s,password
0:message:s,user_name:s,text
0:list_users
0:get_user_info:s,user_name
0:deck_list
0:deck_new_dir:s,path:s,dir_name
0:deck_del_dir:s,path
0:deck_del:i,deck_id
0:deck_download:i,deck_id
0:list_chat_channels
0:chat_join_channel:s,channel
1:chat_leave_channel
1:chat_say:s,message
0:list_games
0:list_users
0:create_game:s,description:s,password:i,max_players:b,spectators_allowed:b,spectators_need_password:b,spectators_can_talk:b,spectators_see_everything
0:join_game:i,game_id:s,password:b,spectator
0:list_rooms
0:join_room:i,room_id
1:leave_room
1:room_say:s,message
1:create_game:s,description:s,password:i,max_players:b,spectators_allowed:b,spectators_need_password:b,spectators_can_talk:b,spectators_see_everything
1:join_game:i,game_id:s,password:b,spectator
2:leave_game
2:say:s,message
2:shuffle
@ -64,8 +63,8 @@
4:message:s,sender_name:s,receiver_name:s,text
4:game_joined:i,game_id:s,game_description:i,player_id:b,spectator:b,spectators_can_talk:b,spectators_see_everything:b,resuming
4:user_left:s,user_name
5:chat_leave_channel:s,player_name
5:chat_say:s,player_name:s,message
5:leave_room:s,player_name
5:room_say:s,player_name:s,message
6:ready_start
6:concede
6:deck_select:i,deck_id

View file

@ -28,6 +28,13 @@ public:
static SerializableItem *newItem() { return new Command_Message; }
int getItemId() const { return ItemId_Command_Message; }
};
class Command_ListUsers : public Command {
Q_OBJECT
public:
Command_ListUsers();
static SerializableItem *newItem() { return new Command_ListUsers; }
int getItemId() const { return ItemId_Command_ListUsers; }
};
class Command_GetUserInfo : public Command {
Q_OBJECT
public:
@ -76,54 +83,40 @@ public:
static SerializableItem *newItem() { return new Command_DeckDownload; }
int getItemId() const { return ItemId_Command_DeckDownload; }
};
class Command_ListChatChannels : public Command {
class Command_ListRooms : public Command {
Q_OBJECT
public:
Command_ListChatChannels();
static SerializableItem *newItem() { return new Command_ListChatChannels; }
int getItemId() const { return ItemId_Command_ListChatChannels; }
Command_ListRooms();
static SerializableItem *newItem() { return new Command_ListRooms; }
int getItemId() const { return ItemId_Command_ListRooms; }
};
class Command_ChatJoinChannel : public Command {
class Command_JoinRoom : public Command {
Q_OBJECT
public:
Command_ChatJoinChannel(const QString &_channel = QString());
QString getChannel() const { return static_cast<SerializableItem_String *>(itemMap.value("channel"))->getData(); };
static SerializableItem *newItem() { return new Command_ChatJoinChannel; }
int getItemId() const { return ItemId_Command_ChatJoinChannel; }
Command_JoinRoom(int _roomId = -1);
int getRoomId() const { return static_cast<SerializableItem_Int *>(itemMap.value("room_id"))->getData(); };
static SerializableItem *newItem() { return new Command_JoinRoom; }
int getItemId() const { return ItemId_Command_JoinRoom; }
};
class Command_ChatLeaveChannel : public ChatCommand {
class Command_LeaveRoom : public RoomCommand {
Q_OBJECT
public:
Command_ChatLeaveChannel(const QString &_channel = QString());
static SerializableItem *newItem() { return new Command_ChatLeaveChannel; }
int getItemId() const { return ItemId_Command_ChatLeaveChannel; }
Command_LeaveRoom(int _roomId = -1);
static SerializableItem *newItem() { return new Command_LeaveRoom; }
int getItemId() const { return ItemId_Command_LeaveRoom; }
};
class Command_ChatSay : public ChatCommand {
class Command_RoomSay : public RoomCommand {
Q_OBJECT
public:
Command_ChatSay(const QString &_channel = QString(), const QString &_message = QString());
Command_RoomSay(int _roomId = -1, const QString &_message = QString());
QString getMessage() const { return static_cast<SerializableItem_String *>(itemMap.value("message"))->getData(); };
static SerializableItem *newItem() { return new Command_ChatSay; }
int getItemId() const { return ItemId_Command_ChatSay; }
static SerializableItem *newItem() { return new Command_RoomSay; }
int getItemId() const { return ItemId_Command_RoomSay; }
};
class Command_ListGames : public Command {
class Command_CreateGame : public RoomCommand {
Q_OBJECT
public:
Command_ListGames();
static SerializableItem *newItem() { return new Command_ListGames; }
int getItemId() const { return ItemId_Command_ListGames; }
};
class Command_ListUsers : public Command {
Q_OBJECT
public:
Command_ListUsers();
static SerializableItem *newItem() { return new Command_ListUsers; }
int getItemId() const { return ItemId_Command_ListUsers; }
};
class Command_CreateGame : public Command {
Q_OBJECT
public:
Command_CreateGame(const QString &_description = QString(), const QString &_password = QString(), int _maxPlayers = -1, bool _spectatorsAllowed = false, bool _spectatorsNeedPassword = false, bool _spectatorsCanTalk = false, bool _spectatorsSeeEverything = false);
Command_CreateGame(int _roomId = -1, const QString &_description = QString(), const QString &_password = QString(), int _maxPlayers = -1, bool _spectatorsAllowed = false, bool _spectatorsNeedPassword = false, bool _spectatorsCanTalk = false, bool _spectatorsSeeEverything = false);
QString getDescription() const { return static_cast<SerializableItem_String *>(itemMap.value("description"))->getData(); };
QString getPassword() const { return static_cast<SerializableItem_String *>(itemMap.value("password"))->getData(); };
int getMaxPlayers() const { return static_cast<SerializableItem_Int *>(itemMap.value("max_players"))->getData(); };
@ -134,10 +127,10 @@ public:
static SerializableItem *newItem() { return new Command_CreateGame; }
int getItemId() const { return ItemId_Command_CreateGame; }
};
class Command_JoinGame : public Command {
class Command_JoinGame : public RoomCommand {
Q_OBJECT
public:
Command_JoinGame(int _gameId = -1, const QString &_password = QString(), bool _spectator = false);
Command_JoinGame(int _roomId = -1, int _gameId = -1, const QString &_password = QString(), bool _spectator = false);
int getGameId() const { return static_cast<SerializableItem_Int *>(itemMap.value("game_id"))->getData(); };
QString getPassword() const { return static_cast<SerializableItem_String *>(itemMap.value("password"))->getData(); };
bool getSpectator() const { return static_cast<SerializableItem_Bool *>(itemMap.value("spectator"))->getData(); };
@ -617,22 +610,22 @@ public:
static SerializableItem *newItem() { return new Event_UserLeft; }
int getItemId() const { return ItemId_Event_UserLeft; }
};
class Event_ChatLeaveChannel : public ChatEvent {
class Event_LeaveRoom : public RoomEvent {
Q_OBJECT
public:
Event_ChatLeaveChannel(const QString &_channel = QString(), const QString &_playerName = QString());
Event_LeaveRoom(int _roomId = -1, const QString &_playerName = QString());
QString getPlayerName() const { return static_cast<SerializableItem_String *>(itemMap.value("player_name"))->getData(); };
static SerializableItem *newItem() { return new Event_ChatLeaveChannel; }
int getItemId() const { return ItemId_Event_ChatLeaveChannel; }
static SerializableItem *newItem() { return new Event_LeaveRoom; }
int getItemId() const { return ItemId_Event_LeaveRoom; }
};
class Event_ChatSay : public ChatEvent {
class Event_RoomSay : public RoomEvent {
Q_OBJECT
public:
Event_ChatSay(const QString &_channel = QString(), const QString &_playerName = QString(), const QString &_message = QString());
Event_RoomSay(int _roomId = -1, const QString &_playerName = QString(), const QString &_message = QString());
QString getPlayerName() const { return static_cast<SerializableItem_String *>(itemMap.value("player_name"))->getData(); };
QString getMessage() const { return static_cast<SerializableItem_String *>(itemMap.value("message"))->getData(); };
static SerializableItem *newItem() { return new Event_ChatSay; }
int getItemId() const { return ItemId_Event_ChatSay; }
static SerializableItem *newItem() { return new Event_RoomSay; }
int getItemId() const { return ItemId_Event_RoomSay; }
};
class Context_ReadyStart : public GameEventContext {
Q_OBJECT

View file

@ -34,10 +34,10 @@ while (<file>) {
} elsif ($type == 1) {
$type = 'cmd';
$namePrefix = 'Command';
$baseClass = 'ChatCommand';
$parentConstructorCall = "$baseClass(\"$name1\", _channel)";
$constructorParamsH = "const QString &_channel = QString()";
$constructorParamsCpp = "const QString &_channel";
$baseClass = 'RoomCommand';
$parentConstructorCall = "$baseClass(\"$name1\", _roomId)";
$constructorParamsH = "int _roomId = -1";
$constructorParamsCpp = "int _roomId";
} elsif ($type == 2) {
$type = 'cmd';
$namePrefix = 'Command';
@ -60,12 +60,12 @@ while (<file>) {
$constructorParamsH = "";
$constructorParamsCpp = "";
} elsif ($type == 5) {
$type = 'chat_event';
$type = 'room_event';
$namePrefix = 'Event';
$baseClass = 'ChatEvent';
$parentConstructorCall = "$baseClass(\"$name1\", _channel)";
$constructorParamsH = "const QString &_channel = QString()";
$constructorParamsCpp = "const QString &_channel";
$baseClass = 'RoomEvent';
$parentConstructorCall = "$baseClass(\"$name1\", _roomId)";
$constructorParamsH = "int _roomId = -1";
$constructorParamsCpp = "int _roomId";
} elsif ($type == 6) {
$type = 'game_event_context';
$namePrefix = 'Context';

View file

@ -20,7 +20,7 @@
#include "server.h"
#include "server_game.h"
#include "server_counter.h"
#include "server_chatchannel.h"
#include "server_room.h"
#include "server_protocolhandler.h"
#include "protocol_datastructures.h"
#include <QDebug>
@ -69,17 +69,6 @@ AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString
return authState;
}
Server_Game *Server::createGame(const QString &description, const QString &password, int maxPlayers, bool spectatorsAllowed, bool spectatorsNeedPassword, bool spectatorsCanTalk, bool spectatorsSeeEverything, Server_ProtocolHandler *creator)
{
Server_Game *newGame = new Server_Game(creator, nextGameId++, description, password, maxPlayers, spectatorsAllowed, spectatorsNeedPassword, spectatorsCanTalk, spectatorsSeeEverything, 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;
@ -106,56 +95,34 @@ Server_Game *Server::getGame(int gameId) const
return games.value(gameId);
}
void Server::broadcastGameListUpdate(Server_Game *game)
void Server::broadcastRoomUpdate()
{
QList<ServerInfo_Game *> eventGameList;
if (game->getPlayerCount())
// Game is open
eventGameList.append(new ServerInfo_Game(
game->getGameId(),
game->getDescription(),
!game->getPassword().isEmpty(),
game->getPlayerCount(),
game->getMaxPlayers(),
new ServerInfo_User(game->getCreatorInfo()),
game->getSpectatorsAllowed(),
game->getSpectatorsNeedPassword(),
game->getSpectatorCount()
));
else
// Game is closing
eventGameList.append(new ServerInfo_Game(game->getGameId(), QString(), false, 0, game->getMaxPlayers(), 0, false, 0));
Event_ListGames *event = new Event_ListGames(eventGameList);
for (int i = 0; i < clients.size(); i++)
if (clients[i]->getAcceptsGameListChanges())
clients[i]->sendProtocolItem(event, false);
delete event;
}
void Server::broadcastChannelUpdate()
{
Server_ChatChannel *channel = static_cast<Server_ChatChannel *>(sender());
QList<ServerInfo_ChatChannel *> eventChannelList;
eventChannelList.append(new ServerInfo_ChatChannel(channel->getName(), channel->getDescription(), channel->size(), channel->getAutoJoin()));
Event_ListChatChannels *event = new Event_ListChatChannels(eventChannelList);
Server_Room *room = static_cast<Server_Room *>(sender());
QList<ServerInfo_Room *> eventRoomList;
eventRoomList.append(new ServerInfo_Room(room->getId(), room->getName(), room->getDescription(), room->getGames().size(), room->size(), room->getAutoJoin()));
Event_ListRooms *event = new Event_ListRooms(eventRoomList);
for (int i = 0; i < clients.size(); ++i)
if (clients[i]->getAcceptsChatChannelListChanges())
if (clients[i]->getAcceptsRoomListChanges())
clients[i]->sendProtocolItem(event, false);
delete event;
}
void Server::gameClosing()
void Server::gameCreated(Server_Game *game)
{
qDebug("Server::gameClosing");
Server_Game *game = static_cast<Server_Game *>(sender());
broadcastGameListUpdate(game);
games.remove(games.key(game));
games.insert(game->getGameId(), game);
}
void Server::addChatChannel(Server_ChatChannel *newChannel)
void Server::gameClosing(int gameId)
{
chatChannels.insert(newChannel->getName(), newChannel);
connect(newChannel, SIGNAL(channelInfoChanged()), this, SLOT(broadcastChannelUpdate()));
qDebug("Server::gameClosing");
games.remove(gameId);
}
void Server::addRoom(Server_Room *newRoom)
{
rooms.insert(newRoom->getId(), newRoom);
connect(newRoom, SIGNAL(roomInfoChanged()), this, SLOT(broadcastRoomUpdate()));
connect(newRoom, SIGNAL(gameCreated(Server_Game *)), this, SLOT(gameCreated(Server_Game *)));
connect(newRoom, SIGNAL(gameClosing(int)), this, SLOT(gameClosing(int)));
}

View file

@ -6,7 +6,7 @@
#include <QMap>
class Server_Game;
class Server_ChatChannel;
class Server_Room;
class Server_ProtocolHandler;
class ServerInfo_User;
@ -18,22 +18,22 @@ class Server : public QObject
signals:
void pingClockTimeout();
private slots:
void gameClosing();
void broadcastChannelUpdate();
void gameCreated(Server_Game *game);
void gameClosing(int gameId);
void broadcastRoomUpdate();
public:
Server(QObject *parent = 0);
~Server();
AuthenticationResult loginUser(Server_ProtocolHandler *session, QString &name, const QString &password);
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);
const QMap<int, Server_Room *> &getRooms() { return rooms; }
int getNextGameId() { return nextGameId++; }
const QMap<QString, Server_ProtocolHandler *> &getUsers() const { return users; }
void addClient(Server_ProtocolHandler *player);
void removeClient(Server_ProtocolHandler *player);
virtual QString getLoginMessage() const = 0;
Server_Game *createGame(const QString &description, const QString &password, int maxPlayers, bool spectatorsAllowed, bool spectatorsNeedPassword, bool spectatorsCanTalk, bool spectatorsSeeEverything, Server_ProtocolHandler *creator);
virtual bool getGameShouldPing() const = 0;
virtual int getMaxGameInactivityTime() const = 0;
@ -42,12 +42,12 @@ protected:
QMap<int, Server_Game *> games;
QList<Server_ProtocolHandler *> clients;
QMap<QString, Server_ProtocolHandler *> users;
QMap<QString, Server_ChatChannel *> chatChannels;
QMap<int, Server_Room *> rooms;
virtual AuthenticationResult checkUserPassword(const QString &user, const QString &password) = 0;
virtual ServerInfo_User *getUserData(const QString &name) = 0;
int nextGameId;
void addChatChannel(Server_ChatChannel *newChannel);
void addRoom(Server_Room *newRoom);
};
#endif

View file

@ -1,42 +0,0 @@
#include "server_chatchannel.h"
#include "server_protocolhandler.h"
Server_ChatChannel::Server_ChatChannel(const QString &_name, const QString &_description, bool _autoJoin, const QString &_joinMessage)
: name(_name), description(_description), autoJoin(_autoJoin), joinMessage(_joinMessage)
{
}
void Server_ChatChannel::addClient(Server_ProtocolHandler *client)
{
sendChatEvent(new Event_ChatJoinChannel(name, new ServerInfo_User(client->getUserInfo())));
append(client);
QList<ServerInfo_User *> eventUserList;
for (int i = 0; i < size(); ++i)
eventUserList.append(new ServerInfo_User(at(i)->getUserInfo()));
Event_ChatListPlayers *eventCLP = new Event_ChatListPlayers(name, eventUserList);
client->enqueueProtocolItem(eventCLP);
client->enqueueProtocolItem(new Event_ChatSay(name, QString(), joinMessage));
emit channelInfoChanged();
}
void Server_ChatChannel::removeClient(Server_ProtocolHandler *client)
{
removeAt(indexOf(client));
sendChatEvent(new Event_ChatLeaveChannel(name, client->getUserInfo()->getName()));
emit channelInfoChanged();
}
void Server_ChatChannel::say(Server_ProtocolHandler *client, const QString &s)
{
sendChatEvent(new Event_ChatSay(name, client->getUserInfo()->getName(), s));
}
void Server_ChatChannel::sendChatEvent(ChatEvent *event)
{
for (int i = 0; i < size(); ++i)
at(i)->sendProtocolItem(event, false);
delete event;
}

View file

@ -1,32 +0,0 @@
#ifndef CHATCHANNEL_H
#define CHATCHANNEL_H
#include <QList>
#include <QObject>
#include <QStringList>
class Server_ProtocolHandler;
class ChatEvent;
class Server_ChatChannel : public QObject, public QList<Server_ProtocolHandler *> {
Q_OBJECT
signals:
void channelInfoChanged();
private:
QString name;
QString description;
bool autoJoin;
QString joinMessage;
public:
Server_ChatChannel(const QString &_name, const QString &_description, bool _autoJoin, const QString &_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);
void sendChatEvent(ChatEvent *event);
};
#endif

View file

@ -18,6 +18,7 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "server.h"
#include "server_room.h"
#include "server_game.h"
#include "server_protocolhandler.h"
#include "server_arrow.h"
@ -27,12 +28,12 @@
#include <QTimer>
#include <QDebug>
Server_Game::Server_Game(Server_ProtocolHandler *_creator, int _gameId, const QString &_description, const QString &_password, int _maxPlayers, bool _spectatorsAllowed, bool _spectatorsNeedPassword, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, Server *parent)
Server_Game::Server_Game(Server_ProtocolHandler *_creator, int _gameId, const QString &_description, const QString &_password, int _maxPlayers, bool _spectatorsAllowed, bool _spectatorsNeedPassword, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, Server_Room *parent)
: QObject(parent), creatorInfo(new ServerInfo_User(_creator->getUserInfo())), gameStarted(false), gameId(_gameId), description(_description), password(_password), maxPlayers(_maxPlayers), activePlayer(-1), activePhase(-1), spectatorsAllowed(_spectatorsAllowed), spectatorsNeedPassword(_spectatorsNeedPassword), spectatorsCanTalk(_spectatorsCanTalk), spectatorsSeeEverything(_spectatorsSeeEverything), inactivityCounter(0)
{
addPlayer(_creator, false, false);
if (parent->getGameShouldPing()) {
if (parent->getServer()->getGameShouldPing()) {
pingClock = new QTimer(this);
connect(pingClock, SIGNAL(timeout()), this, SLOT(pingClockTimeout()));
pingClock->start(1000);
@ -71,7 +72,7 @@ void Server_Game::pingClockTimeout()
}
sendGameEvent(new Event_Ping(pingList));
const int maxTime = static_cast<Server *>(parent())->getMaxGameInactivityTime();
const int maxTime = static_cast<Server_Room *>(parent())->getServer()->getMaxGameInactivityTime();
if (allPlayersInactive) {
if ((++inactivityCounter >= maxTime) && (maxTime > 0))
deleteLater();
@ -193,7 +194,7 @@ Server_Player *Server_Game::addPlayer(Server_ProtocolHandler *handler, bool spec
players.insert(playerId, newPlayer);
if (broadcastUpdate)
qobject_cast<Server *>(parent())->broadcastGameListUpdate(this);
qobject_cast<Server_Room *>(parent())->broadcastGameListUpdate(this);
return newPlayer;
}
@ -231,7 +232,7 @@ void Server_Game::removePlayer(Server_Player *player)
deleteLater();
else if (!spectator)
stopGameIfFinished();
qobject_cast<Server *>(parent())->broadcastGameListUpdate(this);
qobject_cast<Server_Room *>(parent())->broadcastGameListUpdate(this);
}
void Server_Game::setActivePlayer(int _activePlayer)
@ -391,3 +392,23 @@ void Server_Game::sendGameEventToPlayer(Server_Player *player, GameEvent *event)
{
player->sendProtocolItem(new GameEventContainer(QList<GameEvent *>() << event, gameId));
}
ServerInfo_Game *Server_Game::getInfo() const
{
if (players.isEmpty())
// Game is open
return new ServerInfo_Game(getGameId(), QString(), false, 0, getMaxPlayers(), 0, false, 0);
else
// Game is closing
return new ServerInfo_Game(
getGameId(),
getDescription(),
!getPassword().isEmpty(),
getPlayerCount(),
getMaxPlayers(),
new ServerInfo_User(getCreatorInfo()),
getSpectatorsAllowed(),
getSpectatorsNeedPassword(),
getSpectatorCount()
);
}

View file

@ -27,7 +27,7 @@
#include "protocol.h"
class QTimer;
class Server;
class Server_Room;
class ServerInfo_User;
class Server_Game : public QObject {
@ -52,8 +52,9 @@ signals:
private slots:
void pingClockTimeout();
public:
Server_Game(Server_ProtocolHandler *_creator, int _gameId, const QString &_description, const QString &_password, int _maxPlayers, bool _spectatorsAllowed, bool _spectatorsNeedPassword, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, Server *parent);
Server_Game(Server_ProtocolHandler *_creator, int _gameId, const QString &_description, const QString &_password, int _maxPlayers, bool _spectatorsAllowed, bool _spectatorsNeedPassword, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, Server_Room *parent);
~Server_Game();
ServerInfo_Game *getInfo() const;
ServerInfo_User *getCreatorInfo() const { return creatorInfo; }
bool getGameStarted() const { return gameStarted; }
int getPlayerCount() const;

View file

@ -3,7 +3,7 @@
#include "server_protocolhandler.h"
#include "protocol.h"
#include "protocol_items.h"
#include "server_chatchannel.h"
#include "server_room.h"
#include "server_card.h"
#include "server_arrow.h"
#include "server_cardzone.h"
@ -14,7 +14,7 @@
#include <QDateTime>
Server_ProtocolHandler::Server_ProtocolHandler(Server *_server, QObject *parent)
: QObject(parent), server(_server), authState(PasswordWrong), acceptsGameListChanges(false), acceptsUserListChanges(false), acceptsChatChannelListChanges(false), userInfo(0), lastCommandTime(QDateTime::currentDateTime())
: QObject(parent), server(_server), authState(PasswordWrong), acceptsUserListChanges(false), acceptsRoomListChanges(false), userInfo(0), lastCommandTime(QDateTime::currentDateTime())
{
connect(server, SIGNAL(pingClockTimeout()), this, SLOT(pingClockTimeout()));
}
@ -25,6 +25,10 @@ Server_ProtocolHandler::~Server_ProtocolHandler()
// so it will not receive the game update event.
server->removeClient(this);
QMapIterator<int, Server_Room *> roomIterator(rooms);
while (roomIterator.hasNext())
roomIterator.next().value()->removeClient(this);
QMapIterator<int, QPair<Server_Game *, Server_Player *> > gameIterator(games);
while (gameIterator.hasNext()) {
gameIterator.next();
@ -37,10 +41,6 @@ Server_ProtocolHandler::~Server_ProtocolHandler()
p->setProtocolHandler(0);
}
QMapIterator<QString, Server_ChatChannel *> chatChannelIterator(chatChannels);
while (chatChannelIterator.hasNext())
chatChannelIterator.next().value()->removeClient(this);
delete userInfo;
}
@ -54,20 +54,22 @@ ResponseCode Server_ProtocolHandler::processCommandHelper(Command *command, Comm
{
lastCommandTime = QDateTime::currentDateTime();
ChatCommand *chatCommand = qobject_cast<ChatCommand *>(command);
RoomCommand *roomCommand = qobject_cast<RoomCommand *>(command);
GameCommand *gameCommand = qobject_cast<GameCommand *>(command);
if (chatCommand) {
qDebug() << "received ChatCommand: channel =" << chatCommand->getChannel();
if (roomCommand) {
qDebug() << "received RoomCommand: roomId =" << roomCommand->getRoomId();
if (authState == PasswordWrong)
return RespLoginNeeded;
Server_ChatChannel *channel = chatChannels.value(chatCommand->getChannel(), 0);
if (!channel)
Server_Room *room = rooms.value(roomCommand->getRoomId(), 0);
if (!room)
return RespNameNotFound;
switch (command->getItemId()) {
case ItemId_Command_ChatLeaveChannel: return cmdChatLeaveChannel(qobject_cast<Command_ChatLeaveChannel *>(command), cont, channel);
case ItemId_Command_ChatSay: return cmdChatSay(qobject_cast<Command_ChatSay *>(command), cont, channel);
case ItemId_Command_LeaveRoom: return cmdLeaveRoom(qobject_cast<Command_LeaveRoom *>(command), cont, room);
case ItemId_Command_RoomSay: return cmdRoomSay(qobject_cast<Command_RoomSay *>(command), cont, room);
case ItemId_Command_CreateGame: return cmdCreateGame(qobject_cast<Command_CreateGame *>(command), cont, room);
case ItemId_Command_JoinGame: return cmdJoinGame(qobject_cast<Command_JoinGame *>(command), cont, room);
}
} else if (gameCommand) {
qDebug() << "received GameCommand: game =" << gameCommand->getGameId();
@ -125,12 +127,9 @@ ResponseCode Server_ProtocolHandler::processCommandHelper(Command *command, Comm
case ItemId_Command_DeckUpload: return cmdDeckUpload(qobject_cast<Command_DeckUpload *>(command), cont);
case ItemId_Command_DeckDownload: return cmdDeckDownload(qobject_cast<Command_DeckDownload *>(command), cont);
case ItemId_Command_GetUserInfo: return cmdGetUserInfo(qobject_cast<Command_GetUserInfo *>(command), cont);
case ItemId_Command_ListChatChannels: return cmdListChatChannels(qobject_cast<Command_ListChatChannels *>(command), cont);
case ItemId_Command_ChatJoinChannel: return cmdChatJoinChannel(qobject_cast<Command_ChatJoinChannel *>(command), cont);
case ItemId_Command_ListRooms: return cmdListRooms(qobject_cast<Command_ListRooms *>(command), cont);
case ItemId_Command_JoinRoom: return cmdJoinRoom(qobject_cast<Command_JoinRoom *>(command), cont);
case ItemId_Command_ListUsers: return cmdListUsers(qobject_cast<Command_ListUsers *>(command), cont);
case ItemId_Command_ListGames: return cmdListGames(qobject_cast<Command_ListGames *>(command), cont);
case ItemId_Command_CreateGame: return cmdCreateGame(qobject_cast<Command_CreateGame *>(command), cont);
case ItemId_Command_JoinGame: return cmdJoinGame(qobject_cast<Command_JoinGame *>(command), cont);
}
}
return RespInvalidCommand;
@ -235,8 +234,9 @@ ResponseCode Server_ProtocolHandler::cmdLogin(Command_Login *cmd, CommandContain
}
}
}
return RespOk;
cont->setResponse(new Response_Login(cont->getCmdId(), RespOk, new ServerInfo_User(userInfo, true)));
return RespNothing;
}
ResponseCode Server_ProtocolHandler::cmdMessage(Command_Message *cmd, CommandContainer *cont)
@ -273,51 +273,52 @@ ResponseCode Server_ProtocolHandler::cmdGetUserInfo(Command_GetUserInfo *cmd, Co
return RespNothing;
}
ResponseCode Server_ProtocolHandler::cmdListChatChannels(Command_ListChatChannels * /*cmd*/, CommandContainer *cont)
ResponseCode Server_ProtocolHandler::cmdListRooms(Command_ListRooms * /*cmd*/, CommandContainer *cont)
{
if (authState == PasswordWrong)
return RespLoginNeeded;
QList<ServerInfo_ChatChannel *> eventChannelList;
QMapIterator<QString, Server_ChatChannel *> channelIterator(server->getChatChannels());
while (channelIterator.hasNext()) {
Server_ChatChannel *c = channelIterator.next().value();
eventChannelList.append(new ServerInfo_ChatChannel(c->getName(), c->getDescription(), c->size(), c->getAutoJoin()));
}
cont->enqueueItem(new Event_ListChatChannels(eventChannelList));
QList<ServerInfo_Room *> eventRoomList;
QMapIterator<int, Server_Room *> roomIterator(server->getRooms());
while (roomIterator.hasNext())
eventRoomList.append(roomIterator.next().value()->getInfo(false));
cont->enqueueItem(new Event_ListRooms(eventRoomList));
acceptsChatChannelListChanges = true;
acceptsRoomListChanges = true;
return RespOk;
}
ResponseCode Server_ProtocolHandler::cmdChatJoinChannel(Command_ChatJoinChannel *cmd, CommandContainer *cont)
ResponseCode Server_ProtocolHandler::cmdJoinRoom(Command_JoinRoom *cmd, CommandContainer *cont)
{
if (authState == PasswordWrong)
return RespLoginNeeded;
if (chatChannels.contains(cmd->getChannel()))
if (rooms.contains(cmd->getRoomId()))
return RespContextError;
QMap<QString, Server_ChatChannel *> allChannels = server->getChatChannels();
Server_ChatChannel *c = allChannels.value(cmd->getChannel(), 0);
if (!c)
Server_Room *r = server->getRooms().value(cmd->getRoomId(), 0);
if (!r)
return RespNameNotFound;
c->addClient(this);
chatChannels.insert(cmd->getChannel(), c);
r->addClient(this);
rooms.insert(r->getId(), r);
enqueueProtocolItem(new Event_RoomSay(r->getId(), QString(), r->getJoinMessage()));
cont->setResponse(new Response_JoinRoom(cont->getCmdId(), RespOk, r->getInfo(true)));
return RespNothing;
}
ResponseCode Server_ProtocolHandler::cmdLeaveRoom(Command_LeaveRoom * /*cmd*/, CommandContainer *cont, Server_Room *room)
{
rooms.remove(room->getId());
room->removeClient(this);
return RespOk;
}
ResponseCode Server_ProtocolHandler::cmdChatLeaveChannel(Command_ChatLeaveChannel * /*cmd*/, CommandContainer *cont, Server_ChatChannel *channel)
ResponseCode Server_ProtocolHandler::cmdRoomSay(Command_RoomSay *cmd, CommandContainer *cont, Server_Room *room)
{
chatChannels.remove(channel->getName());
channel->removeClient(this);
return RespOk;
}
ResponseCode Server_ProtocolHandler::cmdChatSay(Command_ChatSay *cmd, CommandContainer *cont, Server_ChatChannel *channel)
{
channel->say(this, cmd->getMessage());
room->say(this, cmd->getMessage());
return RespOk;
}
@ -337,39 +338,12 @@ ResponseCode Server_ProtocolHandler::cmdListUsers(Command_ListUsers * /*cmd*/, C
return RespNothing;
}
ResponseCode Server_ProtocolHandler::cmdListGames(Command_ListGames * /*cmd*/, CommandContainer *cont)
ResponseCode Server_ProtocolHandler::cmdCreateGame(Command_CreateGame *cmd, CommandContainer *cont, Server_Room *room)
{
if (authState == PasswordWrong)
return RespLoginNeeded;
const QList<Server_Game *> &gameList = server->getGames();
QList<ServerInfo_Game *> eventGameList;
for (int i = 0; i < gameList.size(); ++i) {
Server_Game *g = gameList[i];
eventGameList.append(new ServerInfo_Game(
g->getGameId(),
g->getDescription(),
!g->getPassword().isEmpty(),
g->getPlayerCount(),
g->getMaxPlayers(),
new ServerInfo_User(g->getCreatorInfo()),
g->getSpectatorsAllowed(),
g->getSpectatorsNeedPassword(),
g->getSpectatorCount()
));
}
cont->enqueueItem(new Event_ListGames(eventGameList));
acceptsGameListChanges = true;
return RespOk;
}
ResponseCode Server_ProtocolHandler::cmdCreateGame(Command_CreateGame *cmd, CommandContainer *cont)
{
if (authState == PasswordWrong)
return RespLoginNeeded;
Server_Game *game = server->createGame(cmd->getDescription(), cmd->getPassword(), cmd->getMaxPlayers(), cmd->getSpectatorsAllowed(), cmd->getSpectatorsNeedPassword(), cmd->getSpectatorsCanTalk(), cmd->getSpectatorsSeeEverything(), this);
Server_Game *game = room->createGame(cmd->getDescription(), cmd->getPassword(), cmd->getMaxPlayers(), cmd->getSpectatorsAllowed(), cmd->getSpectatorsNeedPassword(), cmd->getSpectatorsCanTalk(), cmd->getSpectatorsSeeEverything(), this);
Server_Player *creator = game->getPlayers().values().first();
games.insert(game->getGameId(), QPair<Server_Game *, Server_Player *>(game, creator));
@ -378,7 +352,7 @@ ResponseCode Server_ProtocolHandler::cmdCreateGame(Command_CreateGame *cmd, Comm
return RespOk;
}
ResponseCode Server_ProtocolHandler::cmdJoinGame(Command_JoinGame *cmd, CommandContainer *cont)
ResponseCode Server_ProtocolHandler::cmdJoinGame(Command_JoinGame *cmd, CommandContainer *cont, Server_Room *room)
{
if (authState == PasswordWrong)
return RespLoginNeeded;
@ -386,7 +360,7 @@ ResponseCode Server_ProtocolHandler::cmdJoinGame(Command_JoinGame *cmd, CommandC
if (games.contains(cmd->getGameId()))
return RespContextError;
Server_Game *g = server->getGame(cmd->getGameId());
Server_Game *g = room->getGames().value(cmd->getGameId());
if (!g)
return RespNameNotFound;
@ -503,12 +477,10 @@ ResponseCode Server_ProtocolHandler::cmdMulligan(Command_Mulligan * /*cmd*/, Com
if (!game->getGameStarted())
return RespGameNotStarted;
int number = player->getInitialCards();
if (!number)
return RespContextError;
Server_CardZone *hand = player->getZones().value("hand");
int number = (hand->cards.size() <= 1) ? player->getInitialCards() : hand->cards.size() - 1;
Server_CardZone *deck = player->getZones().value("deck");
while (!hand->cards.isEmpty())
player->moveCard(cont, hand, hand->cards.first()->getId(), deck, 0, 0, false, false);
@ -518,7 +490,6 @@ ResponseCode Server_ProtocolHandler::cmdMulligan(Command_Mulligan * /*cmd*/, Com
cont->enqueueGameEventPublic(new Event_Shuffle(player->getPlayerId()), game->getGameId());
drawCards(game, player, cont, number);
player->setInitialCards(number - 1);
return RespOk;
}

View file

@ -10,6 +10,7 @@
class Server_Player;
class Server_Card;
class ServerInfo_User;
class Server_Room;
class QTimer;
class Server_ProtocolHandler : public QObject {
@ -17,15 +18,14 @@ class Server_ProtocolHandler : public QObject {
protected:
Server *server;
QMap<int, QPair<Server_Game *, Server_Player *> > games;
QMap<QString, Server_ChatChannel *> chatChannels;
QMap<int, Server_Room *> rooms;
Server *getServer() const { return server; }
QPair<Server_Game *, Server_Player *> getGame(int gameId) const;
AuthenticationResult authState;
bool acceptsGameListChanges;
bool acceptsUserListChanges;
bool acceptsChatChannelListChanges;
bool acceptsRoomListChanges;
ServerInfo_User *userInfo;
private:
@ -45,14 +45,13 @@ private:
virtual ResponseCode cmdDeckUpload(Command_DeckUpload *cmd, CommandContainer *cont) = 0;
virtual ResponseCode cmdDeckDownload(Command_DeckDownload *cmd, CommandContainer *cont) = 0;
ResponseCode cmdGetUserInfo(Command_GetUserInfo *cmd, CommandContainer *cont);
ResponseCode cmdListChatChannels(Command_ListChatChannels *cmd, CommandContainer *cont);
ResponseCode cmdChatJoinChannel(Command_ChatJoinChannel *cmd, CommandContainer *cont);
ResponseCode cmdChatLeaveChannel(Command_ChatLeaveChannel *cmd, CommandContainer *cont, Server_ChatChannel *channel);
ResponseCode cmdChatSay(Command_ChatSay *cmd, CommandContainer *cont, Server_ChatChannel *channel);
ResponseCode cmdListRooms(Command_ListRooms *cmd, CommandContainer *cont);
ResponseCode cmdJoinRoom(Command_JoinRoom *cmd, CommandContainer *cont);
ResponseCode cmdLeaveRoom(Command_LeaveRoom *cmd, CommandContainer *cont, Server_Room *room);
ResponseCode cmdRoomSay(Command_RoomSay *cmd, CommandContainer *cont, Server_Room *room);
ResponseCode cmdListUsers(Command_ListUsers *cmd, CommandContainer *cont);
ResponseCode cmdListGames(Command_ListGames *cmd, CommandContainer *cont);
ResponseCode cmdCreateGame(Command_CreateGame *cmd, CommandContainer *cont);
ResponseCode cmdJoinGame(Command_JoinGame *cmd, CommandContainer *cont);
ResponseCode cmdCreateGame(Command_CreateGame *cmd, CommandContainer *cont, Server_Room *room);
ResponseCode cmdJoinGame(Command_JoinGame *cmd, CommandContainer *cont, Server_Room *room);
ResponseCode cmdLeaveGame(Command_LeaveGame *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player);
ResponseCode cmdConcede(Command_Concede *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player);
ResponseCode cmdReadyStart(Command_ReadyStart *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player);
@ -91,9 +90,8 @@ public:
~Server_ProtocolHandler();
void playerRemovedFromGame(Server_Game *game);
bool getAcceptsGameListChanges() const { return acceptsGameListChanges; }
bool getAcceptsUserListChanges() const { return acceptsUserListChanges; }
bool getAcceptsChatChannelListChanges() const { return acceptsChatChannelListChanges; }
bool getAcceptsRoomListChanges() const { return acceptsRoomListChanges; }
ServerInfo_User *getUserInfo() const { return userInfo; }
void setUserInfo(ServerInfo_User *_userInfo) { userInfo = _userInfo; }
const QDateTime &getLastCommandTime() const { return lastCommandTime; }

94
common/server_room.cpp Normal file
View file

@ -0,0 +1,94 @@
#include "server_room.h"
#include "server_protocolhandler.h"
#include "server_game.h"
#include <QDebug>
Server_Room::Server_Room(int _id, const QString &_name, const QString &_description, bool _autoJoin, const QString &_joinMessage, Server *parent)
: QObject(parent), id(_id), name(_name), description(_description), autoJoin(_autoJoin), joinMessage(_joinMessage)
{
}
Server *Server_Room::getServer() const
{
return static_cast<Server *>(parent());
}
ServerInfo_Room *Server_Room::getInfo(bool complete) const
{
QList<ServerInfo_Game *> gameList;
QList<ServerInfo_User *> userList;
if (complete) {
QMapIterator<int, Server_Game *> gameIterator(games);
while (gameIterator.hasNext())
gameList.append(gameIterator.next().value()->getInfo());
for (int i = 0; i < size(); ++i)
userList.append(new ServerInfo_User(at(i)->getUserInfo(), false));
}
return new ServerInfo_Room(id, name, description, games.size(), size(), autoJoin, gameList, userList);
}
void Server_Room::addClient(Server_ProtocolHandler *client)
{
sendRoomEvent(new Event_JoinRoom(id, new ServerInfo_User(client->getUserInfo())));
append(client);
QList<ServerInfo_User *> eventUserList;
for (int i = 0; i < size(); ++i)
eventUserList.append(new ServerInfo_User(at(i)->getUserInfo()));
emit roomInfoChanged();
}
void Server_Room::removeClient(Server_ProtocolHandler *client)
{
removeAt(indexOf(client));
sendRoomEvent(new Event_LeaveRoom(id, client->getUserInfo()->getName()));
emit roomInfoChanged();
}
void Server_Room::say(Server_ProtocolHandler *client, const QString &s)
{
sendRoomEvent(new Event_RoomSay(id, client->getUserInfo()->getName(), s));
}
void Server_Room::sendRoomEvent(RoomEvent *event)
{
for (int i = 0; i < size(); ++i)
at(i)->sendProtocolItem(event, false);
delete event;
}
void Server_Room::broadcastGameListUpdate(Server_Game *game)
{
Event_ListGames *event = new Event_ListGames(id, QList<ServerInfo_Game *>() << game->getInfo());
for (int i = 0; i < size(); i++)
at(i)->sendProtocolItem(event, false);
delete event;
}
Server_Game *Server_Room::createGame(const QString &description, const QString &password, int maxPlayers, bool spectatorsAllowed, bool spectatorsNeedPassword, bool spectatorsCanTalk, bool spectatorsSeeEverything, Server_ProtocolHandler *creator)
{
Server_Game *newGame = new Server_Game(creator, static_cast<Server *>(parent())->getNextGameId(), description, password, maxPlayers, spectatorsAllowed, spectatorsNeedPassword, spectatorsCanTalk, spectatorsSeeEverything, this);
games.insert(newGame->getGameId(), newGame);
connect(newGame, SIGNAL(gameClosing()), this, SLOT(removeGame()));
broadcastGameListUpdate(newGame);
emit gameCreated(newGame);
emit roomInfoChanged();
return newGame;
}
void Server_Room::removeGame()
{
Server_Game *game = static_cast<Server_Game *>(sender());
broadcastGameListUpdate(game);
games.remove(game->getGameId());
emit gameClosing(game->getGameId());
emit roomInfoChanged();
}

51
common/server_room.h Normal file
View file

@ -0,0 +1,51 @@
#ifndef SERVER_ROOM_H
#define SERVER_ROOM_H
#include <QList>
#include <QMap>
#include <QObject>
#include <QStringList>
class Server_ProtocolHandler;
class RoomEvent;
class ServerInfo_User;
class ServerInfo_Room;
class Server_Game;
class Server;
class Server_Room : public QObject, public QList<Server_ProtocolHandler *> {
Q_OBJECT
signals:
void roomInfoChanged();
void gameCreated(Server_Game *game);
void gameClosing(int gameId);
private:
int id;
QString name;
QString description;
bool autoJoin;
QString joinMessage;
QMap<int, Server_Game *> games;
private slots:
void removeGame();
public:
Server_Room(int _id, const QString &_name, const QString &_description, bool _autoJoin, const QString &_joinMessage, Server *parent);
int getId() const { return id; }
QString getName() const { return name; }
QString getDescription() const { return description; }
bool getAutoJoin() const { return autoJoin; }
QString getJoinMessage() const { return joinMessage; }
const QMap<int, Server_Game *> &getGames() const { return games; }
Server *getServer() const;
ServerInfo_Room *getInfo(bool complete) const;
void addClient(Server_ProtocolHandler *client);
void removeClient(Server_ProtocolHandler *client);
void say(Server_ProtocolHandler *client, const QString &s);
void broadcastGameListUpdate(Server_Game *game);
Server_Game *createGame(const QString &description, const QString &password, int maxPlayers, bool spectatorsAllowed, bool spectatorsNeedPassword, bool spectatorsCanTalk, bool spectatorsSeeEverything, Server_ProtocolHandler *creator);
void sendRoomEvent(RoomEvent *event);
};
#endif

View file

@ -1,5 +1,6 @@
[server]
port=4747
statusupdate=15000
[authentication]
method=none
@ -12,15 +13,12 @@ database=servatrice
user=servatrice
password=foobar
[messages]
login="Example line"
[chatchannels]
[rooms]
size=1
1\name="General Chat"
1\description="Discuss anything here."
1\name="General room"
1\description="Play anything here."
1\autojoin=true
1\joinmessage="This is the general chat channel. This message is only here to show that channels can have a join message."
1\joinmessage="This message is only here to show that rooms can have a join message."
[game]
max_game_inactivity_time=120

View file

@ -27,7 +27,7 @@ HEADERS += src/servatrice.h \
../common/server_arrow.h \
../common/server_card.h \
../common/server_cardzone.h \
../common/server_chatchannel.h \
../common/server_room.h \
../common/server_counter.h \
../common/server_game.h \
../common/server_player.h \
@ -48,7 +48,7 @@ SOURCES += src/main.cpp \
../common/server.cpp \
../common/server_card.cpp \
../common/server_cardzone.cpp \
../common/server_chatchannel.cpp \
../common/server_room.cpp \
../common/server_game.cpp \
../common/server_player.cpp \
../common/server_protocolhandler.cpp

View file

@ -22,7 +22,7 @@
#include <QDebug>
#include <iostream>
#include "servatrice.h"
#include "server_chatchannel.h"
#include "server_room.h"
#include "serversocketinterface.h"
#include "protocol.h"
@ -33,36 +33,44 @@ Servatrice::Servatrice(QObject *parent)
connect(pingClock, SIGNAL(timeout()), this, SIGNAL(pingClockTimeout()));
pingClock->start(1000);
statusUpdateClock = new QTimer(this);
connect(statusUpdateClock, SIGNAL(timeout()), this, SLOT(statusUpdate()));
statusUpdateClock->start(15000);
ProtocolItem::initializeHash();
settings = new QSettings("servatrice.ini", QSettings::IniFormat, this);
int statusUpdateTime = settings->value("server/statusupdate").toInt();
statusUpdateClock = new QTimer(this);
connect(statusUpdateClock, SIGNAL(timeout()), this, SLOT(statusUpdate()));
if (statusUpdateTime != 0) {
qDebug() << "Starting status update clock, interval " << statusUpdateTime << " ms";
statusUpdateClock->start(statusUpdateTime);
}
tcpServer = new QTcpServer(this);
connect(tcpServer, SIGNAL(newConnection()), this, SLOT(newConnection()));
tcpServer->listen(QHostAddress::Any, settings->value("server/port", 4747).toInt());
int port = settings->value("server/port", 4747).toInt();
qDebug() << "Starting server on port" << port;
tcpServer->listen(QHostAddress::Any, port);
QString dbType = settings->value("database/type").toString();
dbPrefix = settings->value("database/prefix").toString();
if (dbType == "mysql")
openDatabase();
int size = settings->beginReadArray("chatchannels");
int size = settings->beginReadArray("rooms");
for (int i = 0; i < size; ++i) {
settings->setArrayIndex(i);
Server_ChatChannel *newChannel = new Server_ChatChannel(
Server_Room *newRoom = new Server_Room(
i,
settings->value("name").toString(),
settings->value("description").toString(),
settings->value("autojoin").toBool(),
settings->value("joinmessage").toString()
settings->value("joinmessage").toString(),
this
);
addChatChannel(newChannel);
addRoom(newRoom);
}
settings->endArray();
loginMessage = settings->value("messages/login").toString();
updateLoginMessage();
maxGameInactivityTime = settings->value("game/max_game_inactivity_time").toInt();
maxPlayerInactivityTime = settings->value("game/max_player_inactivity_time").toInt();
@ -183,6 +191,16 @@ ServerInfo_User *Servatrice::getUserData(const QString &name)
return new ServerInfo_User(name, ServerInfo_User::IsUser);
}
void Servatrice::updateLoginMessage()
{
checkSql();
QSqlQuery query;
query.prepare("select message from " + dbPrefix + "_servermessages order by timest desc limit 1");
if (execSqlQuery(query))
if (query.next())
loginMessage = query.value(0).toString();
}
void Servatrice::statusUpdate()
{
uptime += statusUpdateClock->interval() / 1000;
@ -197,4 +215,4 @@ void Servatrice::statusUpdate()
execSqlQuery(query);
}
const QString Servatrice::versionString = "Servatrice 0.20101116";
const QString Servatrice::versionString = "Servatrice 0.20110103";

View file

@ -46,6 +46,7 @@ public:
int getMaxGameInactivityTime() const { return maxGameInactivityTime; }
int getMaxPlayerInactivityTime() const { return maxPlayerInactivityTime; }
QString getDbPrefix() const { return dbPrefix; }
void updateLoginMessage();
protected:
AuthenticationResult checkUserPassword(const QString &user, const QString &password);
ServerInfo_User *getUserData(const QString &name);