initial commit for chat channels

This commit is contained in:
Max-Wilhelm Bruker 2009-08-22 19:34:48 +02:00
parent 0d84de2384
commit 947cd1736c
23 changed files with 408 additions and 66 deletions

View file

@ -44,7 +44,8 @@ HEADERS += src/counter.h \
src/window_sets.h \ src/window_sets.h \
src/abstractgraphicsitem.h \ src/abstractgraphicsitem.h \
src/dlg_settings.h \ src/dlg_settings.h \
src/phasestoolbar.h src/phasestoolbar.h \
src/chatwidget.h
SOURCES += src/counter.cpp \ SOURCES += src/counter.cpp \
src/gameselector.cpp \ src/gameselector.cpp \
src/dlg_creategame.cpp \ src/dlg_creategame.cpp \
@ -82,5 +83,6 @@ SOURCES += src/counter.cpp \
src/window_sets.cpp \ src/window_sets.cpp \
src/abstractgraphicsitem.cpp \ src/abstractgraphicsitem.cpp \
src/dlg_settings.cpp \ src/dlg_settings.cpp \
src/phasestoolbar.cpp src/phasestoolbar.cpp \
src/chatwidget.cpp
TRANSLATIONS += translations/cockatrice_de.ts translations/cockatrice_en.ts TRANSLATIONS += translations/cockatrice_de.ts translations/cockatrice_en.ts

View file

@ -0,0 +1,85 @@
#include <QtGui>
#include "chatwidget.h"
#include "client.h"
ChannelWidget::ChannelWidget(QWidget *parent)
: QWidget(parent)
{
playerList = new QListWidget;
textEdit = new QTextEdit;
sayEdit = new QLineEdit;
QVBoxLayout *vbox = new QVBoxLayout;
vbox->addWidget(textEdit);
vbox->addWidget(sayEdit);
QHBoxLayout *hbox = new QHBoxLayout;
hbox->addLayout(vbox);
hbox->addWidget(playerList);
setLayout(hbox);
}
ChatWidget::ChatWidget(Client *_client, QWidget *parent)
: QWidget(parent), client(_client)
{
channelList = new QTreeWidget;
tab = new QTabWidget;
QHBoxLayout *hbox = new QHBoxLayout;
hbox->addWidget(channelList);
hbox->addWidget(tab, 1);
retranslateUi();
setLayout(hbox);
}
void ChatWidget::retranslateUi()
{
QTreeWidgetItem *header = channelList->headerItem();
Q_ASSERT(header != 0);
header->setText(0, tr("Channel"));
header->setText(1, tr("Description"));
header->setText(2, tr("Players"));
}
void ChatWidget::enableChat()
{
connect(client, SIGNAL(chatEvent(const ChatEventData &)), this, SLOT(chatEvent(const ChatEventData &)));
client->chatListChannels();
show();
}
void ChatWidget::disableChat()
{
disconnect(client, 0, this, 0);
hide();
}
void ChatWidget::chatEvent(const ChatEventData &data)
{
const QStringList &msg = data.getEventData();
switch (data.getEventType()) {
case eventChatListChannels: {
if (msg.size() != 3)
break;
channelList->addTopLevelItem(new QTreeWidgetItem(QStringList() << msg[0] << msg[1] << msg[2]));
break;
}
case eventChatJoinChannel: {
break;
}
case eventChatListPlayers: {
break;
}
case eventChatLeaveChannel: {
break;
}
case eventChatSay: {
break;
}
default: {
}
}
}

View file

@ -0,0 +1,38 @@
#ifndef CHATWIDGET_H
#define CHATWIDGET_H
#include <QWidget>
#include "servereventdata.h"
class QListWidget;
class QTextEdit;
class QLineEdit;
class QTreeWidget;
class QTabWidget;
class Client;
class ChannelWidget : public QWidget {
private:
QListWidget *playerList;
QTextEdit *textEdit;
QLineEdit *sayEdit;
public:
ChannelWidget(QWidget *parent = 0);
};
class ChatWidget : public QWidget {
Q_OBJECT
private:
QTreeWidget *channelList;
QTabWidget *tab;
Client *client;
private slots:
void chatEvent(const ChatEventData &data);
public:
ChatWidget(Client *_client, QWidget *parent = 0);
void retranslateUi();
void enableChat();
void disableChat();
};
#endif

View file

@ -110,6 +110,8 @@ void Client::readLine()
emit playerIdReceived(id, data[1]); emit playerIdReceived(id, data[1]);
} else } else
emit gameEvent(event); emit gameEvent(event);
} else if (prefix == "chat") {
emit chatEvent(ChatEventData(line));
} else if (prefix == "resp") { } else if (prefix == "resp") {
if (values.size() != 2) { if (values.size() != 2) {
// XXX // XXX
@ -231,6 +233,26 @@ void Client::ping()
cmd("ping"); cmd("ping");
} }
PendingCommand *Client::chatListChannels()
{
return cmd("chat_list_channels");
}
PendingCommand *Client::chatJoinChannel(const QString &name)
{
return cmd(QString("chat_join_channel|%1").arg(name));
}
PendingCommand *Client::chatLeaveChannel(const QString &name)
{
return cmd(QString("chat_leave_channel|%1").arg(name));
}
PendingCommand *Client::chatSay(const QString &channel, const QString &s)
{
return cmd(QString("chat_say|%1|%2").arg(channel).arg(s));
}
PendingCommand *Client::listGames() PendingCommand *Client::listGames()
{ {
return cmd("list_games"); return cmd("list_games");

View file

@ -57,6 +57,7 @@ signals:
void responseReceived(int msgid, ServerResponse resp); void responseReceived(int msgid, ServerResponse resp);
void playerIdReceived(int id, QString name); void playerIdReceived(int id, QString name);
void gameEvent(const ServerEventData &msg); void gameEvent(const ServerEventData &msg);
void chatEvent(const ChatEventData &msg);
void serverTimeout(); void serverTimeout();
void logSocketError(const QString &errorString); void logSocketError(const QString &errorString);
void serverError(ServerResponse resp); void serverError(ServerResponse resp);
@ -90,6 +91,10 @@ public:
void connectToServer(const QString &hostname, unsigned int port, const QString &_playerName, const QString &_password); void connectToServer(const QString &hostname, unsigned int port, const QString &_playerName, const QString &_password);
void disconnectFromServer(); void disconnectFromServer();
public slots: public slots:
PendingCommand *chatListChannels();
PendingCommand *chatJoinChannel(const QString &name);
PendingCommand *chatLeaveChannel(const QString &name);
PendingCommand *chatSay(const QString &name, const QString &s);
PendingCommand *listGames(); PendingCommand *listGames();
PendingCommand *listPlayers(); PendingCommand *listPlayers();
PendingCommand *createGame(const QString &description, const QString &password, unsigned int maxPlayers); PendingCommand *createGame(const QString &description, const QString &password, unsigned int maxPlayers);

View file

@ -300,9 +300,12 @@ void Game::gameEvent(const ServerEventData &msg)
p->gameEvent(msg); p->gameEvent(msg);
break; break;
} }
case eventInvalid: case eventInvalid: {
qDebug("Unhandled global event"); qDebug("Unhandled global event");
} }
default: {
}
}
} }
} }

View file

@ -27,18 +27,13 @@ GameSelector::GameSelector(Client *_client, QWidget *parent)
connect(createButton, SIGNAL(clicked()), this, SLOT(actCreate())); connect(createButton, SIGNAL(clicked()), this, SLOT(actCreate()));
connect(joinButton, SIGNAL(clicked()), this, SLOT(actJoin())); connect(joinButton, SIGNAL(clicked()), this, SLOT(actJoin()));
connect(client, SIGNAL(gameListEvent(ServerGame *)), gameListModel, SLOT(updateGameList(ServerGame *)));
connect(client, SIGNAL(statusChanged(ProtocolStatus)), this, SLOT(statusChanged(ProtocolStatus)));
client->listGames();
} }
void GameSelector::actCreate() void GameSelector::actCreate()
{ {
DlgCreateGame dlg(client, this); DlgCreateGame dlg(client, this);
if (dlg.exec()) if (dlg.exec())
deleteLater(); disableGameList();
} }
void GameSelector::actRefresh() void GameSelector::actRefresh()
@ -49,7 +44,7 @@ void GameSelector::actRefresh()
void GameSelector::statusChanged(ProtocolStatus status) void GameSelector::statusChanged(ProtocolStatus status)
{ {
if (status == StatusDisconnected) if (status == StatusDisconnected)
deleteLater(); disableGameList();
} }
void GameSelector::checkResponse(ServerResponse response) void GameSelector::checkResponse(ServerResponse response)
@ -58,7 +53,7 @@ void GameSelector::checkResponse(ServerResponse response)
joinButton->setEnabled(true); joinButton->setEnabled(true);
if (response == RespOk) if (response == RespOk)
deleteLater(); disableGameList();
else { else {
QMessageBox::critical(this, tr("Error"), tr("XXX")); QMessageBox::critical(this, tr("Error"), tr("XXX"));
return; return;
@ -84,3 +79,18 @@ void GameSelector::actJoin()
createButton->setEnabled(false); createButton->setEnabled(false);
joinButton->setEnabled(false); joinButton->setEnabled(false);
} }
void GameSelector::enableGameList()
{
connect(client, SIGNAL(gameListEvent(ServerGame *)), gameListModel, SLOT(updateGameList(ServerGame *)));
connect(client, SIGNAL(statusChanged(ProtocolStatus)), this, SLOT(statusChanged(ProtocolStatus)));
client->listGames();
show();
}
void GameSelector::disableGameList()
{
disconnect(client, 0, this, 0);
hide();
gameListModel->cleanList();
}

View file

@ -13,6 +13,8 @@ class GameSelector : public QWidget {
Q_OBJECT Q_OBJECT
public: public:
GameSelector(Client *_client, QWidget *parent = 0); GameSelector(Client *_client, QWidget *parent = 0);
void enableGameList();
void disableGameList();
private slots: private slots:
void actCreate(); void actCreate();
void actRefresh(); void actRefresh();

View file

@ -69,8 +69,10 @@ void GamesModel::updateGameList(ServerGame *game)
void GamesModel::cleanList() void GamesModel::cleanList()
{ {
beginRemoveRows(QModelIndex(), 0, gameList.size() - 1);
QListIterator<ServerGame *> i(gameList); QListIterator<ServerGame *> i(gameList);
while (i.hasNext()) while (i.hasNext())
delete i.next(); delete i.next();
gameList.clear(); gameList.clear();
endRemoveRows();
} }

View file

@ -16,11 +16,11 @@ public:
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
ServerGame *getGame(int row); ServerGame *getGame(int row);
void cleanList();
public slots: public slots:
void updateGameList(ServerGame *game); void updateGameList(ServerGame *game);
private: private:
QList<ServerGame *> gameList; QList<ServerGame *> gameList;
void cleanList();
}; };
#endif #endif

View file

@ -3,49 +3,57 @@
// Message structure for server events: // Message structure for server events:
// {"private","public"}|PlayerId|PlayerName|EventType|EventData // {"private","public"}|PlayerId|PlayerName|EventType|EventData
const int event_count = 21; QHash<QString, ServerEventType> ServerEventData::eventHash;
const event_string event_strings[event_count] = {
{eventPlayerId, "player_id"},
{eventSay, "say"},
{eventName, "name"},
{eventJoin, "join"},
{eventLeave, "leave"},
{eventReadyStart, "ready_start"},
{eventSetupZones, "setup_zones"},
{eventGameStart, "game_start"},
{eventShuffle, "shuffle"},
{eventRollDice, "roll_dice"},
{eventDraw, "draw"},
{eventMoveCard, "move_card"},
{eventCreateToken, "create_token"},
{eventSetCardAttr, "set_card_attr"},
{eventAddCounter, "add_counter"},
{eventSetCounter, "set_counter"},
{eventDelCounter, "del_counter"},
{eventSetActivePlayer, "set_active_player"},
{eventSetActivePhase, "set_active_phase"},
{eventDumpZone, "dump_zone"},
{eventStopDumpZone, "stop_dump_zone"}
};
ServerEventData::ServerEventData(const QString &line) ServerEventData::ServerEventData(const QString &line)
{ {
QStringList values = line.split("|"); if (eventHash.isEmpty()) {
eventHash.insert("player_id", eventPlayerId);
eventHash.insert("say", eventSay);
eventHash.insert("name", eventName);
eventHash.insert("join", eventJoin);
eventHash.insert("leave", eventLeave);
eventHash.insert("ready_start", eventReadyStart);
eventHash.insert("setup_zones", eventSetupZones);
eventHash.insert("game_start", eventGameStart);
eventHash.insert("shuffle", eventShuffle);
eventHash.insert("roll_dice", eventRollDice);
eventHash.insert("draw", eventDraw);
eventHash.insert("move_card", eventMoveCard);
eventHash.insert("create_token", eventCreateToken);
eventHash.insert("set_card_attr", eventSetCardAttr);
eventHash.insert("add_counter", eventAddCounter);
eventHash.insert("set_counter", eventSetCounter);
eventHash.insert("del_counter", eventDelCounter);
eventHash.insert("set_active_player", eventSetActivePlayer);
eventHash.insert("set_active_phase", eventSetActivePhase);
eventHash.insert("dump_zone", eventDumpZone);
eventHash.insert("stop_dump_zone", eventStopDumpZone);
}
QStringList values = line.split('|');
IsPublic = !values.takeFirst().compare("public"); IsPublic = !values.takeFirst().compare("public");
PlayerId = values.takeFirst().toInt(); PlayerId = values.takeFirst().toInt();
PlayerName = values.takeFirst(); PlayerName = values.takeFirst();
EventType = eventHash.value(values.takeFirst(), eventInvalid);
QString type = values.takeFirst();
bool found = false;
for (int i = 0; i < event_count; i++)
if (!type.compare(event_strings[i].str)) {
EventType = event_strings[i].type;
found = true;
break;
}
if (!found)
EventType = eventInvalid;
EventData = values; EventData = values;
} }
QHash<QString, ChatEventType> ChatEventData::eventHash;
ChatEventData::ChatEventData(const QString &line)
{
if (eventHash.isEmpty()) {
eventHash.insert("list_channels", eventChatListChannels);
eventHash.insert("join_channel", eventChatJoinChannel);
eventHash.insert("list_players", eventChatListPlayers);
eventHash.insert("leave_channel", eventChatLeaveChannel);
eventHash.insert("say", eventChatSay);
}
QStringList values = line.split('|');
values.removeFirst();
eventType = eventHash.value(values.takeFirst(), eventChatInvalid);
eventData = values;
}

View file

@ -2,6 +2,7 @@
#define SERVEREVENTDATA_H #define SERVEREVENTDATA_H
#include <QStringList> #include <QStringList>
#include <QHash>
enum ServerEventType { enum ServerEventType {
eventInvalid, eventInvalid,
@ -28,16 +29,10 @@ enum ServerEventType {
eventStopDumpZone eventStopDumpZone
}; };
struct event_string {
ServerEventType type;
char *str;
};
extern const int event_count;
extern const event_string event_strings[];
class ServerEventData { class ServerEventData {
private: private:
static QHash<QString, ServerEventType> eventHash;
bool IsPublic; bool IsPublic;
int PlayerId; int PlayerId;
QString PlayerName; QString PlayerName;
@ -47,9 +42,30 @@ public:
ServerEventData(const QString &line); ServerEventData(const QString &line);
bool getPublic() const { return IsPublic; } bool getPublic() const { return IsPublic; }
int getPlayerId() const { return PlayerId; } int getPlayerId() const { return PlayerId; }
QString getPlayerName() const { return PlayerName; } const QString &getPlayerName() const { return PlayerName; }
ServerEventType getEventType() const { return EventType; } ServerEventType getEventType() const { return EventType; }
QStringList getEventData() const { return EventData; } const QStringList &getEventData() const { return EventData; }
};
enum ChatEventType {
eventChatInvalid,
eventChatListChannels,
eventChatJoinChannel,
eventChatListPlayers,
eventChatLeaveChannel,
eventChatSay
};
class ChatEventData {
private:
static QHash<QString, ChatEventType> eventHash;
ChatEventType eventType;
QStringList eventData;
public:
ChatEventData(const QString &line);
ChatEventType getEventType() const { return eventType; }
const QStringList &getEventData() const { return eventData; }
}; };
#endif #endif

View file

@ -35,6 +35,7 @@
#include "zoneviewzone.h" #include "zoneviewzone.h"
#include "zoneviewwidget.h" #include "zoneviewwidget.h"
#include "zoneviewlayout.h" #include "zoneviewlayout.h"
#include "chatwidget.h"
void MainWindow::hoverCard(QString name) void MainWindow::hoverCard(QString name)
{ {
@ -86,8 +87,8 @@ void MainWindow::statusChanged(ProtocolStatus _status)
phasesToolbar->setActivePhase(-1); phasesToolbar->setActivePhase(-1);
phasesToolbar->setEnabled(false); phasesToolbar->setEnabled(false);
GameSelector *gameSelector = new GameSelector(client); gameSelector->enableGameList();
viewLayout->insertWidget(0, gameSelector); chatWidget->enableChat();
break; break;
} }
case StatusPlaying: case StatusPlaying:
@ -211,6 +212,7 @@ void MainWindow::retranslateUi()
sayLabel->setText(tr("&Say:")); sayLabel->setText(tr("&Say:"));
cardInfo->retranslateUi(); cardInfo->retranslateUi();
chatWidget->retranslateUi();
} }
void MainWindow::createActions() void MainWindow::createActions()
@ -272,6 +274,7 @@ MainWindow::MainWindow(QTranslator *_translator, QWidget *parent)
scene = new QGraphicsScene(0, 0, 1096, 1160, this); scene = new QGraphicsScene(0, 0, 1096, 1160, this);
view = new GameView(scene); view = new GameView(scene);
view->hide();
// view->setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); // view->setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers)));
@ -285,6 +288,12 @@ MainWindow::MainWindow(QTranslator *_translator, QWidget *parent)
sayLabel = new QLabel; sayLabel = new QLabel;
sayEdit = new QLineEdit; sayEdit = new QLineEdit;
sayLabel->setBuddy(sayEdit); sayLabel->setBuddy(sayEdit);
client = new Client(this);
gameSelector = new GameSelector(client);
gameSelector->hide();
chatWidget = new ChatWidget(client);
chatWidget->hide();
QHBoxLayout *hLayout = new QHBoxLayout; QHBoxLayout *hLayout = new QHBoxLayout;
hLayout->addWidget(sayLabel); hLayout->addWidget(sayLabel);
@ -296,6 +305,8 @@ MainWindow::MainWindow(QTranslator *_translator, QWidget *parent)
verticalLayout->addLayout(hLayout); verticalLayout->addLayout(hLayout);
viewLayout = new QVBoxLayout; viewLayout = new QVBoxLayout;
viewLayout->addWidget(gameSelector);
viewLayout->addWidget(chatWidget);
viewLayout->addWidget(view); viewLayout->addWidget(view);
phasesToolbar = new PhasesToolbar; phasesToolbar = new PhasesToolbar;
@ -312,7 +323,6 @@ MainWindow::MainWindow(QTranslator *_translator, QWidget *parent)
connect(sayEdit, SIGNAL(returnPressed()), this, SLOT(actSay())); connect(sayEdit, SIGNAL(returnPressed()), this, SLOT(actSay()));
client = new Client(this);
connect(client, SIGNAL(serverTimeout()), this, SLOT(serverTimeout())); connect(client, SIGNAL(serverTimeout()), this, SLOT(serverTimeout()));
connect(client, SIGNAL(statusChanged(ProtocolStatus)), this, SLOT(statusChanged(ProtocolStatus))); connect(client, SIGNAL(statusChanged(ProtocolStatus)), this, SLOT(statusChanged(ProtocolStatus)));
connect(client, SIGNAL(playerIdReceived(int, QString)), this, SLOT(playerIdReceived(int, QString))); connect(client, SIGNAL(playerIdReceived(int, QString)), this, SLOT(playerIdReceived(int, QString)));

View file

@ -40,6 +40,8 @@ class ServerZoneCard;
class ZoneViewLayout; class ZoneViewLayout;
class ZoneViewWidget; class ZoneViewWidget;
class PhasesToolbar; class PhasesToolbar;
class GameSelector;
class ChatWidget;
class MainWindow : public QMainWindow { class MainWindow : public QMainWindow {
Q_OBJECT Q_OBJECT
@ -80,6 +82,8 @@ private:
QLabel *sayLabel; QLabel *sayLabel;
QLineEdit *sayEdit; QLineEdit *sayEdit;
PhasesToolbar *phasesToolbar; PhasesToolbar *phasesToolbar;
GameSelector *gameSelector;
ChatWidget *chatWidget;
Client *client; Client *client;
QGraphicsScene *scene; QGraphicsScene *scene;

View file

@ -21,7 +21,8 @@ HEADERS += src/server.h src/servergame.h src/serversocket.h \
src/counter.h \ src/counter.h \
src/abstractrng.h \ src/abstractrng.h \
src/rng_qt.h \ src/rng_qt.h \
src/returnmessage.h src/returnmessage.h \
src/chatchannel.h
SOURCES += src/main.cpp \ SOURCES += src/main.cpp \
src/server.cpp \ src/server.cpp \
src/servergame.cpp \ src/servergame.cpp \
@ -30,4 +31,5 @@ SOURCES += src/main.cpp \
src/card.cpp \ src/card.cpp \
src/counter.cpp \ src/counter.cpp \
src/rng_qt.cpp \ src/rng_qt.cpp \
src/returnmessage.cpp src/returnmessage.cpp \
src/chatchannel.cpp

View file

@ -0,0 +1,39 @@
#include "chatchannel.h"
#include "serversocket.h"
ChatChannel::ChatChannel(const QString &_name, const QString &_description)
: name(_name), description(_description)
{
}
void ChatChannel::addPlayer(ServerSocket *player)
{
QString str = QString("chat|join_channel|%1|%2").arg(name).arg(player->getPlayerName());
for (int i = 0; i < size(); ++i)
at(i)->msg(str);
append(player);
for (int i = 0; i < size(); ++i)
player->msg(QString("chat|list_players|%1|%2").arg(name).arg(at(i)->getPlayerName()));
emit channelInfoChanged();
}
void ChatChannel::removePlayer(ServerSocket *player)
{
QString str = QString("chat|leave_channel|%1|%2").arg(name).arg(player->getPlayerName());
removeAt(indexOf(player));
for (int i = 0; i < size(); ++i)
at(i)->msg(str);
emit channelInfoChanged();
}
void ChatChannel::say(ServerSocket *player, const QString &s)
{
QString str = QString("chat|say|%1|%2|%3").arg(name).arg(player->getPlayerName()).arg(s);
for (int i = 0; i < size(); ++i)
at(i)->msg(str);
}

View file

@ -0,0 +1,25 @@
#ifndef CHATCHANNEL_H
#define CHATCHANNEL_H
#include <QList>
#include <QObject>
class ServerSocket;
class ChatChannel : public QObject, public QList<ServerSocket *> {
Q_OBJECT
signals:
void channelInfoChanged();
private:
QString name;
QString description;
public:
ChatChannel(const QString &_name, const QString &_description);
QString getName() const { return name; }
QString getDescription() const { return description; }
void addPlayer(ServerSocket *player);
void removePlayer(ServerSocket *player);
void say(ServerSocket *player, const QString &s);
};
#endif

View file

@ -10,6 +10,7 @@ bool ReturnMessage::send(ReturnCode code)
switch (code) { switch (code) {
case ReturnNothing: return true; case ReturnNothing: return true;
case ReturnOk: returnCodeString = "ok"; break; case ReturnOk: returnCodeString = "ok"; break;
case ReturnNameNotFound: returnCodeString = "name_not_found"; break;
case ReturnLoginNeeded: returnCodeString = "login_needed"; break; case ReturnLoginNeeded: returnCodeString = "login_needed"; break;
case ReturnSyntaxError: returnCodeString = "syntax"; break; case ReturnSyntaxError: returnCodeString = "syntax"; break;
case ReturnContextError: returnCodeString = "context"; break; case ReturnContextError: returnCodeString = "context"; break;

View file

@ -9,7 +9,7 @@ private:
unsigned int msg_id; unsigned int msg_id;
QString cmd; QString cmd;
public: public:
enum ReturnCode { ReturnNothing, ReturnOk, ReturnLoginNeeded, ReturnSyntaxError, ReturnContextError, ReturnPasswordWrong }; enum ReturnCode { ReturnNothing, ReturnOk, ReturnNameNotFound, ReturnLoginNeeded, ReturnSyntaxError, ReturnContextError, ReturnPasswordWrong };
ReturnMessage(QObject *parent = 0) : QObject(parent), msg_id(0) { } ReturnMessage(QObject *parent = 0) : QObject(parent), msg_id(0) { }
unsigned int getMsgId() const { return msg_id; } unsigned int getMsgId() const { return msg_id; }
void setMsgId(unsigned int _msg_id) { msg_id = _msg_id; } void setMsgId(unsigned int _msg_id) { msg_id = _msg_id; }

View file

@ -22,6 +22,7 @@
#include "serversocket.h" #include "serversocket.h"
#include "counter.h" #include "counter.h"
#include "rng_qt.h" #include "rng_qt.h"
#include "chatchannel.h"
#include <QtSql> #include <QtSql>
#include <QSettings> #include <QSettings>
@ -35,6 +36,9 @@ Server::Server(QObject *parent)
QString dbType = settings->value("database/type").toString(); QString dbType = settings->value("database/type").toString();
if (dbType == "mysql") if (dbType == "mysql")
openDatabase(); openDatabase();
chatChannelList << new ChatChannel("channel1", "testchannel 1");
chatChannelList << new ChatChannel("channel2", "testchannel 2");
} }
Server::~Server() Server::~Server()

View file

@ -27,6 +27,7 @@ class ServerSocket;
class QSqlDatabase; class QSqlDatabase;
class QSettings; class QSettings;
class AbstractRNG; class AbstractRNG;
class ChatChannel;
enum AuthenticationResult { PasswordWrong = 0, PasswordRight = 1, UnknownUser = 2 }; enum AuthenticationResult { PasswordWrong = 0, PasswordRight = 1, UnknownUser = 2 };
@ -45,6 +46,7 @@ public:
bool checkGamePassword(int gameId, const QString &password); bool checkGamePassword(int gameId, const QString &password);
AuthenticationResult checkUserPassword(const QString &user, const QString &password); AuthenticationResult checkUserPassword(const QString &user, const QString &password);
QList<ServerGame *> listOpenGames(); QList<ServerGame *> listOpenGames();
QList<ChatChannel *> getChatChannelList() { return chatChannelList; }
ServerGame *getGame(int gameId); ServerGame *getGame(int gameId);
AbstractRNG *getRNG() const { return rng; } AbstractRNG *getRNG() const { return rng; }
void broadcastGameListUpdate(ServerGame *game); void broadcastGameListUpdate(ServerGame *game);
@ -53,6 +55,7 @@ private:
void incomingConnection(int SocketId); void incomingConnection(int SocketId);
QList<ServerGame *> games; QList<ServerGame *> games;
QList<ServerSocket *> players; QList<ServerSocket *> players;
QList<ChatChannel *> chatChannelList;
int nextGameId; int nextGameId;
AbstractRNG *rng; AbstractRNG *rng;
}; };

View file

@ -28,6 +28,7 @@
#include "counter.h" #include "counter.h"
#include "card.h" #include "card.h"
#include "abstractrng.h" #include "abstractrng.h"
#include "chatchannel.h"
ServerSocket::ServerSocket(Server *_server, QObject *parent) ServerSocket::ServerSocket(Server *_server, QObject *parent)
: QTcpSocket(parent), server(_server), game(0), PlayerStatus(StatusNormal), authState(PasswordWrong), acceptsGameListChanges(false) : QTcpSocket(parent), server(_server), game(0), PlayerStatus(StatusNormal), authState(PasswordWrong), acceptsGameListChanges(false)
@ -166,6 +167,11 @@ const ServerSocket::CommandProperties ServerSocket::commandList[ServerSocket::nu
{"ping", false, false, false, QList<QVariant::Type>(), &ServerSocket::cmdPing}, {"ping", false, false, false, QList<QVariant::Type>(), &ServerSocket::cmdPing},
{"login", false, false, false, QList<QVariant::Type>() << QVariant::String {"login", false, false, false, QList<QVariant::Type>() << QVariant::String
<< QVariant::String, &ServerSocket::cmdLogin}, << QVariant::String, &ServerSocket::cmdLogin},
{"chat_list_channels", true, false, false, QList<QVariant::Type>(), &ServerSocket::cmdChatListChannels},
{"chat_join_channel", true, false, false, QList<QVariant::Type>() << QVariant::String, &ServerSocket::cmdChatJoinChannel},
{"chat_leave_channel", true, false, false, QList<QVariant::Type>() << QVariant::String, &ServerSocket::cmdChatLeaveChannel},
{"chat_say", true, false, false, QList<QVariant::Type>() << QVariant::String
<< QVariant::String, &ServerSocket::cmdChatSay},
{"list_games", true, false, false, QList<QVariant::Type>(), &ServerSocket::cmdListGames}, {"list_games", true, false, false, QList<QVariant::Type>(), &ServerSocket::cmdListGames},
{"create_game", true, false, false, QList<QVariant::Type>() << QVariant::String {"create_game", true, false, false, QList<QVariant::Type>() << QVariant::String
<< QVariant::String << QVariant::String
@ -231,6 +237,55 @@ ReturnMessage::ReturnCode ServerSocket::cmdLogin(const QList<QVariant> &params)
return ReturnMessage::ReturnOk; return ReturnMessage::ReturnOk;
} }
ReturnMessage::ReturnCode ServerSocket::cmdChatListChannels(const QList<QVariant> &/*params*/)
{
QList<ChatChannel *> chatChannelList = server->getChatChannelList();
for (int i = 0; i < chatChannelList.size(); ++i)
msg(QString("chat|list_channels|%1|%2|%3").arg(chatChannelList[i]->getName()).arg(chatChannelList[i]->getDescription()).arg(chatChannelList[i]->size()));
acceptsChatChannelListChanges = true;
return ReturnMessage::ReturnOk;
}
ReturnMessage::ReturnCode ServerSocket::cmdChatJoinChannel(const QList<QVariant> &params)
{
for (int i = 0; i < chatChannels.size(); ++i)
if (chatChannels[i]->getName() == params[0])
return ReturnMessage::ReturnContextError;
QList<ChatChannel *> allChannels = server->getChatChannelList();
for (int i = 0; i < allChannels.size(); ++i)
if (allChannels[i]->getName() == params[0]) {
allChannels[i]->addPlayer(this);
chatChannels << allChannels[i];
return ReturnMessage::ReturnOk;
}
return ReturnMessage::ReturnNameNotFound;
}
ReturnMessage::ReturnCode ServerSocket::cmdChatLeaveChannel(const QList<QVariant> &params)
{
for (int i = 0; i < chatChannels.size(); ++i) {
ChatChannel *c = chatChannels[i];
if (c->getName() == params[0]) {
chatChannels.removeAt(i);
c->removePlayer(this);
return ReturnMessage::ReturnOk;
}
}
return ReturnMessage::ReturnNameNotFound;
}
ReturnMessage::ReturnCode ServerSocket::cmdChatSay(const QList<QVariant> &params)
{
for (int i = 0; i < chatChannels.size(); ++i)
if (chatChannels[i]->getName() == params[0]) {
chatChannels[i]->say(this, params[1].toString());
return ReturnMessage::ReturnOk;
}
return ReturnMessage::ReturnNameNotFound;
}
ReturnMessage::ReturnCode ServerSocket::cmdListGames(const QList<QVariant> &/*params*/) ReturnMessage::ReturnCode ServerSocket::cmdListGames(const QList<QVariant> &/*params*/)
{ {
QList<ServerGame *> gameList = server->listOpenGames(); QList<ServerGame *> gameList = server->listOpenGames();

View file

@ -55,11 +55,15 @@ private:
QList<QVariant::Type> paramTypes; QList<QVariant::Type> paramTypes;
CommandHandler handler; CommandHandler handler;
}; };
static const int numberCommands = 27; static const int numberCommands = 31;
static const CommandProperties commandList[numberCommands]; static const CommandProperties commandList[numberCommands];
ReturnMessage::ReturnCode cmdPing(const QList<QVariant> &params); ReturnMessage::ReturnCode cmdPing(const QList<QVariant> &params);
ReturnMessage::ReturnCode cmdLogin(const QList<QVariant> &params); ReturnMessage::ReturnCode cmdLogin(const QList<QVariant> &params);
ReturnMessage::ReturnCode cmdChatListChannels(const QList<QVariant> &params);
ReturnMessage::ReturnCode cmdChatJoinChannel(const QList<QVariant> &params);
ReturnMessage::ReturnCode cmdChatLeaveChannel(const QList<QVariant> &params);
ReturnMessage::ReturnCode cmdChatSay(const QList<QVariant> &params);
ReturnMessage::ReturnCode cmdListGames(const QList<QVariant> &params); ReturnMessage::ReturnCode cmdListGames(const QList<QVariant> &params);
ReturnMessage::ReturnCode cmdCreateGame(const QList<QVariant> &params); ReturnMessage::ReturnCode cmdCreateGame(const QList<QVariant> &params);
ReturnMessage::ReturnCode cmdJoinGame(const QList<QVariant> &params); ReturnMessage::ReturnCode cmdJoinGame(const QList<QVariant> &params);
@ -88,6 +92,7 @@ private:
Server *server; Server *server;
ServerGame *game; ServerGame *game;
QList<ChatChannel *> chatChannels;
QList<QString> DeckList; QList<QString> DeckList;
QList<QString> SideboardList; QList<QString> SideboardList;
QList<PlayerZone *> zones; QList<PlayerZone *> zones;
@ -105,6 +110,7 @@ private:
ReturnMessage *remsg; ReturnMessage *remsg;
AuthenticationResult authState; AuthenticationResult authState;
bool acceptsGameListChanges; bool acceptsGameListChanges;
bool acceptsChatChannelListChanges;
public: public:
ServerSocket(Server *_server, QObject *parent = 0); ServerSocket(Server *_server, QObject *parent = 0);
~ServerSocket(); ~ServerSocket();