From 64aa68cd260b531c2074a65cf05f52c8cbd31b6d Mon Sep 17 00:00:00 2001 From: Max-Wilhelm Bruker Date: Fri, 13 Nov 2009 18:27:06 +0100 Subject: [PATCH] Chat works! --- cockatrice/cockatrice.pro | 4 +- cockatrice/src/client.cpp | 185 +------------ cockatrice/src/client.h | 13 +- cockatrice/src/gameselector.cpp | 119 --------- cockatrice/src/gameselector.h | 36 --- cockatrice/src/gamesmodel.cpp | 17 +- cockatrice/src/gamesmodel.h | 2 - cockatrice/src/tab_chatchannel.cpp | 79 +++++- cockatrice/src/tab_chatchannel.h | 38 ++- cockatrice/src/tab_server.cpp | 327 ++++++++++++++++++++++- cockatrice/src/tab_server.h | 79 +++++- cockatrice/src/tab_supervisor.cpp | 62 +++++ cockatrice/src/tab_supervisor.h | 33 +++ cockatrice/src/window_main.cpp | 33 +-- cockatrice/src/window_main.h | 3 + common/protocol.cpp | 10 +- common/protocol.h | 14 +- common/protocol_item_ids.h | 4 +- common/protocol_items.cpp | 16 +- common/protocol_items.dat | 4 +- common/protocol_items.h | 16 +- common/server.cpp | 2 +- common/server_chatchannel.cpp | 2 +- common/server_protocolhandler.cpp | 17 +- common/server_protocolhandler.h | 2 +- servatrice/servatrice.ini.example | 6 +- servatrice/src/servatrice.cpp | 2 +- servatrice/src/serversocketinterface.cpp | 13 +- 28 files changed, 714 insertions(+), 424 deletions(-) delete mode 100644 cockatrice/src/gameselector.cpp delete mode 100644 cockatrice/src/gameselector.h create mode 100644 cockatrice/src/tab_supervisor.cpp create mode 100644 cockatrice/src/tab_supervisor.h diff --git a/cockatrice/cockatrice.pro b/cockatrice/cockatrice.pro index 4d5158e9..5fca990d 100644 --- a/cockatrice/cockatrice.pro +++ b/cockatrice/cockatrice.pro @@ -8,7 +8,6 @@ RESOURCES = cockatrice.qrc QT += network svg HEADERS += src/counter.h \ - src/gameselector.h \ src/dlg_creategame.h \ src/dlg_connect.h \ src/gamesmodel.h \ @@ -46,12 +45,12 @@ HEADERS += src/counter.h \ src/tab_server.h \ src/tab_chatchannel.h \ src/tab_game.h \ + src/tab_supervisor.h \ ../common/protocol.h \ ../common/protocol_items.h \ ../common/protocol_datastructures.h SOURCES += src/counter.cpp \ - src/gameselector.cpp \ src/dlg_creategame.cpp \ src/dlg_connect.cpp \ src/client.cpp \ @@ -90,6 +89,7 @@ SOURCES += src/counter.cpp \ src/tab_server.cpp \ src/tab_chatchannel.cpp \ src/tab_game.cpp \ + src/tab_supervisor.cpp \ ../common/protocol.cpp \ ../common/protocol_items.cpp diff --git a/cockatrice/src/client.cpp b/cockatrice/src/client.cpp index 42a3c83d..e809649d 100644 --- a/cockatrice/src/client.cpp +++ b/cockatrice/src/client.cpp @@ -285,6 +285,9 @@ void Client::processProtocolItem(ProtocolItem *item) GenericEvent *genericEvent = qobject_cast(item); if (genericEvent) { switch (genericEvent->getItemId()) { + case ItemId_Event_ListGames: emit listGamesEventReceived(qobject_cast(item)); break; + case ItemId_Event_ServerMessage: emit serverMessageEventReceived(qobject_cast(item)); break; + case ItemId_Event_ListChatChannels: emit listChatChannelsEventReceived(qobject_cast(item)); break; } delete genericEvent; return; @@ -362,188 +365,6 @@ void Client::ping() sendCommand(new Command_Ping); } /* -PendingCommand *Client::chatListChannels() -{ - return cmd("chat_list_channels"); -} - -PendingCommand_ChatJoinChannel *Client::chatJoinChannel(const QString &name) -{ - return static_cast(cmd(QString("chat_join_channel|%1").arg(name), new PendingCommand_ChatJoinChannel(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() -{ - return cmd("list_games"); -} - -PendingCommand_ListPlayers *Client::listPlayers() -{ - return static_cast(cmd("list_players", new PendingCommand_ListPlayers)); -} - -PendingCommand *Client::createGame(const QString &description, const QString &password, unsigned int maxPlayers, bool spectatorsAllowed) -{ - PendingCommand *pc = cmd(QString("create_game|%1|%2|%3|%4").arg(description).arg(password).arg(maxPlayers).arg(spectatorsAllowed ? 1 : 0)); - connect(pc, SIGNAL(finished(ServerResponse)), this, SLOT(enterGameResponse(ServerResponse))); - return pc; -} - -PendingCommand *Client::joinGame(int gameId, const QString &password, bool spectator) -{ - PendingCommand *pc = cmd(QString("join_game|%1|%2|%3").arg(gameId).arg(password).arg(spectator ? 1 : 0)); - connect(pc, SIGNAL(finished(ServerResponse)), this, SLOT(enterGameResponse(ServerResponse))); - return pc; -} - -PendingCommand *Client::leaveGame() -{ - PendingCommand *pc = cmd("leave_game"); - connect(pc, SIGNAL(finished(ServerResponse)), this, SLOT(leaveGameResponse(ServerResponse))); - return pc; -} - -PendingCommand *Client::login(const QString &name, const QString &pass) -{ - PendingCommand *pc = cmd(QString("login|%1|%2").arg(name).arg(pass)); - connect(pc, SIGNAL(finished(ServerResponse)), this, SLOT(loginResponse(ServerResponse))); - return pc; -} - -PendingCommand *Client::say(const QString &s) -{ - return cmd(QString("say|%1").arg(s)); -} - -PendingCommand *Client::shuffle() -{ - return cmd("shuffle"); -} - -PendingCommand *Client::rollDie(unsigned int sides) -{ - return cmd(QString("roll_die|%1").arg(sides)); -} - -PendingCommand *Client::drawCards(unsigned int number) -{ - return cmd(QString("draw_cards|%1").arg(number)); -} - -PendingCommand *Client::moveCard(int cardid, const QString &startzone, const QString &targetzone, int x, int y, bool faceDown) -{ - // if startzone is public: cardid is the card's id - // else: cardid is the position of the card in the zone (e.g. deck) - return cmd(QString("move_card|%1|%2|%3|%4|%5|%6").arg(cardid).arg(startzone).arg(targetzone).arg(x).arg(y).arg(faceDown ? 1 : 0)); -} - -PendingCommand *Client::createToken(const QString &zone, const QString &name, const QString &powtough, int x, int y) -{ - return cmd(QString("create_token|%1|%2|%3|%4|%5").arg(zone).arg(name).arg(powtough).arg(x).arg(y)); -} - -PendingCommand *Client::createArrow(int startPlayerId, const QString &startZone, int startCardId, int targetPlayerId, const QString &targetPlayerZone, int targetCardId, const QColor &color) -{ - return cmd(QString("create_arrow|%1|%2|%3|%4|%5|%6|%7").arg(startPlayerId).arg(startZone).arg(startCardId).arg(targetPlayerId).arg(targetPlayerZone).arg(targetCardId).arg(colorToNumber(color))); -} - -PendingCommand *Client::deleteArrow(int arrowId) -{ - return cmd(QString("delete_arrow|%1").arg(arrowId)); -} - -PendingCommand *Client::setCardAttr(const QString &zone, int cardid, const QString &aname, const QString &avalue) -{ - return cmd(QString("set_card_attr|%1|%2|%3|%4").arg(zone).arg(cardid).arg(aname).arg(avalue)); -} - -void Client::submitDeck(const QStringList &deck) -{ - cmd("submit_deck"); - QStringListIterator i(deck); - while (i.hasNext()) - msg(i.next()); - msg("."); -} - -PendingCommand *Client::readyStart() -{ - return cmd("ready_start"); -} - -PendingCommand *Client::incCounter(int counterId, int delta) -{ - return cmd(QString("inc_counter|%1|%2").arg(counterId).arg(delta)); -} - -PendingCommand *Client::addCounter(const QString &counterName, QColor color, int radius, int value) -{ - return cmd(QString("add_counter|%1|%2|%3|%4").arg(counterName).arg(colorToNumber(color)).arg(radius).arg(value)); -} - -PendingCommand *Client::setCounter(int counterId, int value) -{ - return cmd(QString("set_counter|%1|%2").arg(counterId).arg(value)); -} - -PendingCommand *Client::delCounter(int counterId) -{ - return cmd(QString("del_counter|%1").arg(counterId)); -} - -PendingCommand_ListCounters *Client::listCounters(int playerId) -{ - PendingCommand_ListCounters *pc = new PendingCommand_ListCounters(playerId); - cmd(QString("list_counters|%1").arg(playerId), pc); - return pc; -} - -PendingCommand *Client::nextTurn() -{ - return cmd(QString("next_turn")); -} - -PendingCommand *Client::setActivePhase(int phase) -{ - return cmd(QString("set_active_phase|%1").arg(phase)); -} - -PendingCommand_ListZones *Client::listZones(int playerId) -{ - PendingCommand_ListZones *pc = new PendingCommand_ListZones(playerId); - cmd(QString("list_zones|%1").arg(playerId), pc); - return pc; -} - -PendingCommand_DumpZone *Client::dumpZone(int player, const QString &zone, int numberCards) -{ - PendingCommand_DumpZone *pc = new PendingCommand_DumpZone(player, zone, numberCards); - cmd(QString("dump_zone|%1|%2|%3").arg(player).arg(zone).arg(numberCards), pc); - return pc; -} - -PendingCommand *Client::stopDumpZone(int player, const QString &zone) -{ - return cmd(QString("stop_dump_zone|%1|%2").arg(player).arg(zone)); -} - -PendingCommand_DumpAll *Client::dumpAll() -{ - PendingCommand_DumpAll *pc = new PendingCommand_DumpAll; - cmd("dump_all", pc); - return pc; -} - QColor Client::numberToColor(int colorValue) const { return QColor(colorValue / 65536, (colorValue % 65536) / 256, colorValue % 256); diff --git a/cockatrice/src/client.h b/cockatrice/src/client.h index 81497665..52dd023a 100644 --- a/cockatrice/src/client.h +++ b/cockatrice/src/client.h @@ -14,6 +14,10 @@ class QXmlStreamWriter; class ProtocolItem; class ChatEvent; +class GameEvent; +class Event_ListGames; +class Event_ServerMessage; +class Event_ListChatChannels; enum ClientStatus { StatusDisconnected, @@ -27,7 +31,6 @@ class Client : public QObject { Q_OBJECT signals: void statusChanged(ClientStatus _status); -// void gameListEvent(const ServerGame &game); // void playerIdReceived(int id, QString name); // void gameEvent(const ServerEventData &msg); void maxPingTime(int seconds, int maxSeconds); @@ -37,7 +40,15 @@ signals: void protocolVersionMismatch(int clientVersion, int serverVersion); void protocolError(); + // Chat events void chatEventReceived(ChatEvent *event); + // Game events + void gameEventReceived(GameEvent *event); + // Generic events + void listGamesEventReceived(Event_ListGames *event); + void serverMessageEventReceived(Event_ServerMessage *event); + void listChatChannelsEventReceived(Event_ListChatChannels *event); + private slots: void slotConnected(); void readData(); diff --git a/cockatrice/src/gameselector.cpp b/cockatrice/src/gameselector.cpp deleted file mode 100644 index a69719c7..00000000 --- a/cockatrice/src/gameselector.cpp +++ /dev/null @@ -1,119 +0,0 @@ -#include -#include "gameselector.h" -#include "dlg_creategame.h" -#include "gamesmodel.h" - -GameSelector::GameSelector(Client *_client, QWidget *parent) - : QWidget(parent), client(_client) -{ - gameListView = new QTreeView; - gameListModel = new GamesModel(this); - gameListProxyModel = new GamesProxyModel(this); - gameListProxyModel->setSourceModel(gameListModel); - gameListView->setModel(gameListProxyModel); - - 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, this); - if (dlg.exec()) - disableGameList(); -} - -/*void GameSelector::checkResponse(ServerResponse response) -{ - createButton->setEnabled(true); - joinButton->setEnabled(true); - spectateButton->setEnabled(true); - - switch (response) { - case RespOk: disableGameList(); break; - case RespPasswordWrong: 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 RespContextError: 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; - const ServerGameInfo &game = gameListModel->getGame(ind.data(Qt::UserRole).toInt()); - QString password; - if (game.getHasPassword()) { - bool ok; - password = QInputDialog::getText(this, tr("Join game"), tr("Password:"), QLineEdit::Password, QString(), &ok); - if (!ok) - return; - } - -// PendingCommand *joinCommand = client->joinGame(game.getGameId(), password, spectator); -// connect(joinCommand, SIGNAL(finished(ServerResponse)), this, SLOT(checkResponse(ServerResponse))); - createButton->setEnabled(false); - joinButton->setEnabled(false); - spectateButton->setEnabled(false); -} - -void GameSelector::enableGameList() -{ - if (isVisible()) - return; - - connect(client, SIGNAL(gameListEvent(const ServerGameInfo &)), gameListModel, SLOT(updateGameList(const ServerGameInfo &))); - client->listGames(); - show(); -} - -void GameSelector::disableGameList() -{ - if (!isVisible()) - return; - - disconnect(client, 0, gameListModel, 0); - hide(); - gameListModel->cleanList(); -} - -void GameSelector::retranslateUi() -{ - showFullGamesCheckBox->setText(tr("&Show full games")); - createButton->setText(tr("C&reate")); - joinButton->setText(tr("&Join")); - spectateButton->setText(tr("J&oin as spectator")); -} \ No newline at end of file diff --git a/cockatrice/src/gameselector.h b/cockatrice/src/gameselector.h deleted file mode 100644 index 5882f915..00000000 --- a/cockatrice/src/gameselector.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef GAMESELECTOR_H -#define GAMESELECTOR_H - -#include -#include "client.h" - -class QPushButton; -class QCheckBox; -class QTreeView; -class GamesModel; -class GamesProxyModel; - -class GameSelector : public QWidget { - Q_OBJECT -public: - GameSelector(Client *_client, QWidget *parent = 0); - void enableGameList(); - void disableGameList(); - void retranslateUi(); -private slots: - void showFullGamesChanged(int state); - void actCreate(); - void actJoin(); -// void checkResponse(ServerResponse response); -private: - Client *client; - - QTreeView *gameListView; - GamesModel *gameListModel; - GamesProxyModel *gameListProxyModel; - QPushButton *createButton, *joinButton, *spectateButton; - QCheckBox *showFullGamesCheckBox; -}; - -#endif - diff --git a/cockatrice/src/gamesmodel.cpp b/cockatrice/src/gamesmodel.cpp index fa1c0aab..5182263f 100644 --- a/cockatrice/src/gamesmodel.cpp +++ b/cockatrice/src/gamesmodel.cpp @@ -1,9 +1,12 @@ #include "gamesmodel.h" -#include "protocol_datastructures.h" GamesModel::~GamesModel() { - cleanList(); + if (!gameList.isEmpty()) { + beginRemoveRows(QModelIndex(), 0, gameList.size() - 1); + gameList.clear(); + endRemoveRows(); + } } QVariant GamesModel::data(const QModelIndex &index, int role) const @@ -69,16 +72,6 @@ void GamesModel::updateGameList(const ServerGameInfo &game) endInsertRows(); } -void GamesModel::cleanList() -{ - if (gameList.isEmpty()) - return; - - beginRemoveRows(QModelIndex(), 0, gameList.size() - 1); - gameList.clear(); - endRemoveRows(); -} - GamesProxyModel::GamesProxyModel(QObject *parent) : QSortFilterProxyModel(parent), fullGamesVisible(false) { diff --git a/cockatrice/src/gamesmodel.h b/cockatrice/src/gamesmodel.h index 895701e1..6f5b2a6b 100644 --- a/cockatrice/src/gamesmodel.h +++ b/cockatrice/src/gamesmodel.h @@ -17,8 +17,6 @@ public: QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; const ServerGameInfo &getGame(int row); - void cleanList(); -public slots: void updateGameList(const ServerGameInfo &game); private: QList gameList; diff --git a/cockatrice/src/tab_chatchannel.cpp b/cockatrice/src/tab_chatchannel.cpp index 8d1c8b69..0bebdd56 100644 --- a/cockatrice/src/tab_chatchannel.cpp +++ b/cockatrice/src/tab_chatchannel.cpp @@ -1 +1,78 @@ - +#include +#include "tab_chatchannel.h" +#include "client.h" +#include "protocol_items.h" + +TabChatChannel::TabChatChannel(Client *_client, const QString &_channelName) + : QWidget(), 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); + + setLayout(hbox); +} + +void TabChatChannel::sendMessage() +{ + if (sayEdit->text().isEmpty()) + return; + + client->sendCommand(new Command_ChatSay(channelName, sayEdit->text())); + sayEdit->clear(); +} + +void TabChatChannel::processChatEvent(ChatEvent *event) +{ + switch (event->getItemId()) { + case ItemId_Event_ChatListPlayers: processListPlayersEvent(qobject_cast(event)); break; + case ItemId_Event_ChatJoinChannel: processJoinChannelEvent(qobject_cast(event)); break; + case ItemId_Event_ChatLeaveChannel: processLeaveChannelEvent(qobject_cast(event)); break; + case ItemId_Event_ChatSay: processSayEvent(qobject_cast(event)); break; + default: ; + } +} + +void TabChatChannel::processListPlayersEvent(Event_ChatListPlayers *event) +{ + const QList &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(event->getPlayerName())); + playerList->addItem(event->getPlayerName()); +} + +void TabChatChannel::processLeaveChannelEvent(Event_ChatLeaveChannel *event) +{ + textEdit->append(tr("%1 has left the channel.").arg(event->getPlayerName())); + for (int i = 0; i < playerList->count(); ++i) + if (playerList->item(i)->text() == event->getPlayerName()) { + delete playerList->takeItem(i); + break; + } +} + +void TabChatChannel::processSayEvent(Event_ChatSay *event) +{ + if (event->getPlayerName().isEmpty()) + textEdit->append(QString("%1getMessage())); + else + textEdit->append(QString("%1: %2").arg(event->getPlayerName()).arg(event->getMessage())); + QApplication::alert(this); +} diff --git a/cockatrice/src/tab_chatchannel.h b/cockatrice/src/tab_chatchannel.h index 8d1c8b69..2c663281 100644 --- a/cockatrice/src/tab_chatchannel.h +++ b/cockatrice/src/tab_chatchannel.h @@ -1 +1,37 @@ - +#ifndef TAB_CHATCHANNEL_H +#define TAB_CHATCHANNEL_H + +#include + +class Client; +class QListWidget; +class QTextEdit; +class QLineEdit; +class ChatEvent; +class Event_ChatListPlayers; +class Event_ChatJoinChannel; +class Event_ChatLeaveChannel; +class Event_ChatSay; + +class TabChatChannel : public QWidget { + Q_OBJECT +private: + Client *client; + QString channelName; + + QListWidget *playerList; + QTextEdit *textEdit; + QLineEdit *sayEdit; +private slots: + void sendMessage(); + + void processListPlayersEvent(Event_ChatListPlayers *event); + void processJoinChannelEvent(Event_ChatJoinChannel *event); + void processLeaveChannelEvent(Event_ChatLeaveChannel *event); + void processSayEvent(Event_ChatSay *event); +public: + TabChatChannel(Client *_client, const QString &_channelName); + void processChatEvent(ChatEvent *event); +}; + +#endif \ No newline at end of file diff --git a/cockatrice/src/tab_server.cpp b/cockatrice/src/tab_server.cpp index a84b62a6..879190b6 100644 --- a/cockatrice/src/tab_server.cpp +++ b/cockatrice/src/tab_server.cpp @@ -1,6 +1,329 @@ +#include #include "tab_server.h" +#include "gamesmodel.h" +#include "dlg_creategame.h" +#include "client.h" +#include "protocol.h" +#include "protocol_items.h" -TabServer::TabServer(QWidget *parent) - : QWidget(parent) +GameSelector::GameSelector(Client *_client, QWidget *parent) + : QGroupBox(parent), client(_client) { + gameListView = new QTreeView; + gameListModel = new GamesModel(this); + gameListProxyModel = new GamesProxyModel(this); + gameListProxyModel->setSourceModel(gameListModel); + gameListView->setModel(gameListProxyModel); + + 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 RespOk: /* HIER CODE FÜR NEUEN GAME_TAB EINFÜGEN */ break; + 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 RespContextError: 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; + const ServerGameInfo &game = gameListModel->getGame(ind.data(Qt::UserRole).toInt()); + QString password; + if (game.getHasPassword()) { + 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 &gamesToUpdate = event->getGameList(); + for (int i = 0; i < gamesToUpdate.size(); ++i) + gameListModel->updateGameList(gamesToUpdate[i]); +} + +ChatChannelSelector::ChatChannelSelector(Client *_client, QWidget *parent) + : QGroupBox(parent), client(_client) +{ + channelList = new QTreeWidget; + channelList->setRootIsDecorated(false); + + joinButton = new QPushButton; + connect(joinButton, SIGNAL(clicked()), this, SLOT(joinClicked())); + QHBoxLayout *buttonLayout = new QHBoxLayout; + buttonLayout->addStretch(); + buttonLayout->addWidget(joinButton); + QVBoxLayout *vbox = new QVBoxLayout; + vbox->addWidget(channelList); + vbox->addLayout(buttonLayout); + + retranslateUi(); + setLayout(vbox); + + connect(client, SIGNAL(listChatChannelsEventReceived(Event_ListChatChannels *)), this, SLOT(processListChatChannelsEvent(Event_ListChatChannels *))); + client->sendCommand(new Command_ListChatChannels); +} + +void ChatChannelSelector::retranslateUi() +{ + setTitle(tr("Chat channels")); + joinButton->setText(tr("Joi&n")); + + QTreeWidgetItem *header = channelList->headerItem(); + header->setText(0, tr("Channel")); + header->setText(1, tr("Description")); + header->setText(2, tr("Players")); + header->setTextAlignment(2, Qt::AlignRight); +} + +void ChatChannelSelector::processListChatChannelsEvent(Event_ListChatChannels *event) +{ + const QList &channelsToUpdate = event->getChannelList(); + for (int i = 0; i < channelsToUpdate.size(); ++i) { + const ServerChatChannelInfo &channel = channelsToUpdate[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())); + return; + } + } + QTreeWidgetItem *twi = new QTreeWidgetItem(QStringList() << channel.getName() << channel.getDescription() << QString::number(channel.getPlayerCount())); + twi->setTextAlignment(2, Qt::AlignRight); + channelList->addTopLevelItem(twi); + channelList->resizeColumnToContents(0); + channelList->resizeColumnToContents(1); + channelList->resizeColumnToContents(2); + if (channel.getAutoJoin()) + joinChannel(channel.getName()); + } +} + +/* +void ChatWidget::chatEvent(const ChatEventData &data) +{ + const QStringList &msg = data.getEventData(); + switch (data.getEventType()) { + case eventListChatChannels: { + if (msg.size() != 4) + break; + for (int i = 0; i < channelList->topLevelItemCount(); ++i) { + QTreeWidgetItem *twi = channelList->topLevelItem(i); + if (twi->text(0) == msg[0]) { + twi->setToolTip(0, msg[1]); + twi->setText(1, msg[2]); + return; + } + } + QTreeWidgetItem *twi = new QTreeWidgetItem(QStringList() << msg[0] << msg[2]); + twi->setTextAlignment(1, Qt::AlignRight); + twi->setToolTip(0, msg[1]); + channelList->addTopLevelItem(twi); + channelList->resizeColumnToContents(0); + channelList->resizeColumnToContents(1); + if (msg[3] == "1") + joinChannel(msg[0]); + break; + } + case eventChatJoinChannel: { + if (msg.size() != 2) + break; + ChannelWidget *w = getChannel(msg[0]); + if (!w) + break; + w->joinEvent(msg[1]); + break; + } + case eventChatListPlayers: { + if (msg.size() != 2) + break; + ChannelWidget *w = getChannel(msg[0]); + if (!w) + break; + w->listPlayersEvent(msg[1]); + break; + } + case eventChatLeaveChannel: { + if (msg.size() != 2) + break; + ChannelWidget *w = getChannel(msg[0]); + if (!w) + break; + w->leaveEvent(msg[1]); + break; + } + case eventChatSay: { + if (msg.size() != 3) + break; + ChannelWidget *w = getChannel(msg[0]); + if (!w) + break; + w->sayEvent(msg[1], msg[2]); + break; + } + case eventChatServerMessage: { + if (msg.size() != 2) + break; + ChannelWidget *w; + if (msg[0].isEmpty()) { + w = getChannel("Server"); + if (!w) { + w = new ChannelWidget(client, "Server", true, true); + tab->addTab(w, "Server"); + } + } else + w = getChannel(msg[0]); + w->serverMessageEvent(msg[1]); + break; + } + default: { + } + } +} +*/ +void ChatChannelSelector::joinChannel(const QString &channelName) +{ + Command_ChatJoinChannel *command = new Command_ChatJoinChannel(channelName); + connect(command, SIGNAL(finished(ResponseCode)), this, SLOT(joinFinished(ResponseCode))); + client->sendCommand(command); +} + +void ChatChannelSelector::joinClicked() +{ + QTreeWidgetItem *twi = channelList->currentItem(); + if (!twi) + return; + QString channelName = twi->text(0); + + joinChannel(channelName); +} + +void ChatChannelSelector::joinFinished(ResponseCode resp) +{ + if (resp != RespOk) + return; + + Command_ChatJoinChannel *command = qobject_cast(sender()); + QString channelName = command->getChannel(); + + emit channelJoined(channelName); +} + +ServerMessageLog::ServerMessageLog(Client *_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()); +} + +TabServer::TabServer(Client *_client, QWidget *parent) + : QWidget(parent), client(_client) +{ + gameSelector = new GameSelector(client); + chatChannelSelector = new ChatChannelSelector(client); + serverMessageLog = new ServerMessageLog(client); + + connect(gameSelector, SIGNAL(gameJoined(int)), this, SIGNAL(gameJoined(int))); + connect(chatChannelSelector, SIGNAL(channelJoined(const QString &)), this, SIGNAL(chatChannelJoined(const QString &))); + + QHBoxLayout *hbox = new QHBoxLayout; + hbox->addWidget(chatChannelSelector); + hbox->addWidget(serverMessageLog); + + QVBoxLayout *mainLayout = new QVBoxLayout; + mainLayout->addWidget(gameSelector); + mainLayout->addLayout(hbox); + + setLayout(mainLayout); } diff --git a/cockatrice/src/tab_server.h b/cockatrice/src/tab_server.h index 02fa4f50..04399979 100644 --- a/cockatrice/src/tab_server.h +++ b/cockatrice/src/tab_server.h @@ -1,13 +1,88 @@ #ifndef TAB_SERVER_H #define TAB_SERVER_H -#include +#include +#include "protocol_datastructures.h" + +class Client; +class QTreeView; +class QTreeWidget; +class QPushButton; +class QCheckBox; +class QTextEdit; + +class GamesModel; +class GamesProxyModel; + +class Event_ListGames; +class Event_ListChatChannels; +class Event_ServerMessage; + +class GameSelector : public QGroupBox { + Q_OBJECT +public: + GameSelector(Client *_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: + Client *client; + + QTreeView *gameListView; + GamesModel *gameListModel; + GamesProxyModel *gameListProxyModel; + QPushButton *createButton, *joinButton, *spectateButton; + QCheckBox *showFullGamesCheckBox; +}; + +class ChatChannelSelector : public QGroupBox { + Q_OBJECT +private: + QTreeWidget *channelList; + QPushButton *joinButton; + Client *client; + + void joinChannel(const QString &channelName); +private slots: + void processListChatChannelsEvent(Event_ListChatChannels *event); + void joinClicked(); + void joinFinished(ResponseCode resp); +signals: + void channelJoined(const QString &channelName); +public: + ChatChannelSelector(Client *_client, QWidget *parent = 0); + void retranslateUi(); +}; + +class ServerMessageLog : public QGroupBox { + Q_OBJECT +private: + QTextEdit *textEdit; +private slots: + void processServerMessageEvent(Event_ServerMessage *event); +public: + ServerMessageLog(Client *_client, QWidget *parent = 0); + void retranslateUi(); +}; class TabServer : public QWidget { Q_OBJECT +signals: + void chatChannelJoined(const QString &channelName); + void gameJoined(int gameId); private: + Client *client; + GameSelector *gameSelector; + ChatChannelSelector *chatChannelSelector; + ServerMessageLog *serverMessageLog; public: - TabServer(QWidget *parent = 0); + TabServer(Client *_client, QWidget *parent = 0); }; #endif diff --git a/cockatrice/src/tab_supervisor.cpp b/cockatrice/src/tab_supervisor.cpp new file mode 100644 index 00000000..dcc6659b --- /dev/null +++ b/cockatrice/src/tab_supervisor.cpp @@ -0,0 +1,62 @@ +#include "tab_supervisor.h" +#include "client.h" +#include "tab_server.h" +#include "tab_chatchannel.h" +#include "tab_game.h" +#include "protocol_items.h" + +TabSupervisor:: TabSupervisor(QWidget *parent) + : QTabWidget(parent), client(0), tabServer(0) +{ + +} + +void TabSupervisor::retranslateUi() +{ + if (tabServer) + setTabText(0, tr("Server")); +} + +void TabSupervisor::start(Client *_client) +{ + client = _client; + connect(client, SIGNAL(chatEventReceived(ChatEvent *)), this, SLOT(processChatEvent(ChatEvent *))); + connect(client, SIGNAL(gameEventReceived(GameEvent *)), this, SLOT(processGameEvent(GameEvent *))); + + tabServer = new TabServer(client); + connect(tabServer, SIGNAL(gameJoined(int)), this, SLOT(addGameTab(int))); + connect(tabServer, SIGNAL(chatChannelJoined(const QString &)), this, SLOT(addChatChannelTab(const QString &))); + + addTab(tabServer, QString()); + + retranslateUi(); +} + +void TabSupervisor::stop() +{ + +} + +void TabSupervisor::addGameTab(int gameId) +{ + +} + +void TabSupervisor::addChatChannelTab(const QString &channelName) +{ + TabChatChannel *tab = new TabChatChannel(client, channelName); + addTab(tab, channelName); + chatChannelTabs.insert(channelName, tab); +} + +void TabSupervisor::processChatEvent(ChatEvent *event) +{ + TabChatChannel *tab = chatChannelTabs.value(event->getChannel(), 0); + if (tab) + tab->processChatEvent(event); +} + +void TabSupervisor::processGameEvent(GameEvent *event) +{ + +} diff --git a/cockatrice/src/tab_supervisor.h b/cockatrice/src/tab_supervisor.h new file mode 100644 index 00000000..5b92d89f --- /dev/null +++ b/cockatrice/src/tab_supervisor.h @@ -0,0 +1,33 @@ +#ifndef TAB_SUPERVISOR_H +#define TAB_SUPERVISOR_H + +#include +#include + +class Client; +class TabServer; +class TabChatChannel; +class TabGame; +class ChatEvent; +class GameEvent; + +class TabSupervisor : public QTabWidget { + Q_OBJECT +private: + Client *client; + TabServer *tabServer; + QMap chatChannelTabs; + QMap gameTabs; +public: + TabSupervisor(QWidget *parent = 0); + void retranslateUi(); + void start(Client *_client); + void stop(); +private slots: + void addGameTab(int gameId); + void addChatChannelTab(const QString &channelName); + void processChatEvent(ChatEvent *event); + void processGameEvent(GameEvent *event); +}; + +#endif \ No newline at end of file diff --git a/cockatrice/src/window_main.cpp b/cockatrice/src/window_main.cpp index 4238540b..6f544e62 100644 --- a/cockatrice/src/window_main.cpp +++ b/cockatrice/src/window_main.cpp @@ -23,7 +23,6 @@ #include "window_main.h" #include "dlg_connect.h" #include "dlg_settings.h" -#include "gameselector.h" #include "window_deckeditor.h" #include "cardinfowidget.h" #include "messagelogwidget.h" @@ -37,6 +36,7 @@ #include "zoneviewwidget.h" #include "zoneviewlayout.h" #include "chatwidget.h" +#include "tab_supervisor.h" PingWidget::PingWidget(QWidget *parent) : QWidget(parent) @@ -86,15 +86,13 @@ void MainWindow::statusChanged(ClientStatus _status) delete game; game = 0; } - pingWidget->setPercentage(0, -1); +// pingWidget->setPercentage(0, -1); aConnect->setEnabled(true); aDisconnect->setEnabled(false); aRestartGame->setEnabled(false); aLeaveGame->setEnabled(false); - phasesToolbar->setActivePhase(-1); - phasesToolbar->hide(); - gameSelector->disableGameList(); - chatWidget->disableChat(); +// phasesToolbar->setActivePhase(-1); +// phasesToolbar->hide(); emit logDisconnected(); break; case StatusLoggingIn: @@ -103,6 +101,8 @@ void MainWindow::statusChanged(ClientStatus _status) aDisconnect->setEnabled(true); break; case StatusLoggedIn: { + tabSupervisor->start(client); + /* if (game) { zoneLayout->clear(); delete game; @@ -210,7 +210,7 @@ void MainWindow::serverTimeout() void MainWindow::retranslateUi() { setWindowTitle(tr("Cockatrice")); - + aConnect->setText(tr("&Connect...")); aDisconnect->setText(tr("&Disconnect")); aRestartGame->setText(tr("&Restart game...")); @@ -225,7 +225,7 @@ void MainWindow::retranslateUi() aCloseMostRecentZoneView->setShortcut(tr("Esc")); cockatriceMenu->setTitle(tr("&Cockatrice")); - +/* sayLabel->setText(tr("&Say:")); cardInfo->retranslateUi(); @@ -234,7 +234,7 @@ void MainWindow::retranslateUi() if (game) game->retranslateUi(); zoneLayout->retranslateUi(); -} +*/} void MainWindow::createActions() { @@ -260,7 +260,7 @@ void MainWindow::createActions() connect(aExit, SIGNAL(triggered()), this, SLOT(actExit())); aCloseMostRecentZoneView = new QAction(this); - connect(aCloseMostRecentZoneView, SIGNAL(triggered()), zoneLayout, SLOT(closeMostRecentZoneView())); +// connect(aCloseMostRecentZoneView, SIGNAL(triggered()), zoneLayout, SLOT(closeMostRecentZoneView())); addAction(aCloseMostRecentZoneView); } @@ -288,6 +288,11 @@ MainWindow::MainWindow(QTranslator *_translator, QWidget *parent) QPixmapCache::setCacheLimit(200000); db = new CardDatabase(this); + client = new Client(this); + tabSupervisor = new TabSupervisor; + + setCentralWidget(tabSupervisor); +/* zoneLayout = new ZoneViewLayout(db); scene = new GameScene(zoneLayout, this); @@ -302,7 +307,6 @@ MainWindow::MainWindow(QTranslator *_translator, QWidget *parent) sayLabel->setBuddy(sayEdit); pingWidget = new PingWidget; - client = new Client(this); gameSelector = new GameSelector(client); gameSelector->hide(); chatWidget = new ChatWidget(client); @@ -338,8 +342,6 @@ MainWindow::MainWindow(QTranslator *_translator, QWidget *parent) connect(sayEdit, SIGNAL(returnPressed()), this, SLOT(actSay())); connect(client, SIGNAL(maxPingTime(int, int)), pingWidget, SLOT(setPercentage(int, int))); - connect(client, SIGNAL(serverTimeout()), this, SLOT(serverTimeout())); - connect(client, SIGNAL(statusChanged(ClientStatus)), this, SLOT(statusChanged(ClientStatus))); connect(this, SIGNAL(logConnecting(QString)), messageLog, SLOT(logConnecting(QString))); connect(this, SIGNAL(logConnected()), messageLog, SLOT(logConnected())); @@ -350,6 +352,9 @@ MainWindow::MainWindow(QTranslator *_translator, QWidget *parent) connect(client, SIGNAL(protocolError()), messageLog, SLOT(logProtocolError())); connect(phasesToolbar, SIGNAL(signalSetPhase(int)), client, SLOT(setActivePhase(int))); connect(phasesToolbar, SIGNAL(signalNextTurn()), client, SLOT(nextTurn())); +*/ + connect(client, SIGNAL(serverTimeout()), this, SLOT(serverTimeout())); + connect(client, SIGNAL(statusChanged(ClientStatus)), this, SLOT(statusChanged(ClientStatus))); createActions(); createMenus(); @@ -362,8 +367,6 @@ MainWindow::MainWindow(QTranslator *_translator, QWidget *parent) void MainWindow::closeEvent(QCloseEvent */*event*/) { delete game; - chatWidget->disableChat(); - gameSelector->disableGameList(); } void MainWindow::changeEvent(QEvent *event) diff --git a/cockatrice/src/window_main.h b/cockatrice/src/window_main.h index 3f3fdaae..c1ee0f31 100644 --- a/cockatrice/src/window_main.h +++ b/cockatrice/src/window_main.h @@ -36,12 +36,14 @@ class MessageLogWidget; class QLabel; class QLineEdit; class QPushButton; +class QTabWidget; class ServerZoneCard; class ZoneViewLayout; class ZoneViewWidget; class PhasesToolbar; class GameSelector; class ChatWidget; +class TabSupervisor; class PingWidget : public QWidget { Q_OBJECT @@ -84,6 +86,7 @@ private: QMenu *cockatriceMenu; QAction *aConnect, *aDisconnect, *aRestartGame, *aLeaveGame, *aDeckEditor, *aFullScreen, *aSettings, *aExit; QAction *aCloseMostRecentZoneView; + TabSupervisor *tabSupervisor; QVBoxLayout *viewLayout; PingWidget *pingWidget; diff --git a/common/protocol.cpp b/common/protocol.cpp index 8697e812..c1d22de2 100644 --- a/common/protocol.cpp +++ b/common/protocol.cpp @@ -25,6 +25,7 @@ bool ProtocolItem::read(QXmlStreamReader *xml) QString tagName = xml->name().toString(); if (parameters.contains(tagName)) parameters[tagName] = currentElementText; + currentElementText.clear(); } } else if (xml->isCharacters() && !xml->isWhitespace()) currentElementText = xml->text().toString(); @@ -62,8 +63,13 @@ void ProtocolItem::initializeHash() return; initializeHashAuto(); + itemNameHash.insert("resp", ProtocolResponse::newItem); ProtocolResponse::initializeHash(); + + itemNameHash.insert("generic_eventlist_games", Event_ListGames::newItem); + itemNameHash.insert("generic_eventlist_chat_channels", Event_ListChatChannels::newItem); + itemNameHash.insert("chat_eventchat_list_players", Event_ChatListPlayers::newItem); } int Command::lastCmdId = 0; @@ -153,7 +159,7 @@ ChatEvent::ChatEvent(const QString &_eventName, const QString &_channel) setParameter("channel", channel); } -bool Event_ChatListChannels::readElement(QXmlStreamReader *xml) +bool Event_ListChatChannels::readElement(QXmlStreamReader *xml) { if (xml->isStartElement() && (xml->name() == "channel")) { channelList.append(ServerChatChannelInfo( @@ -167,7 +173,7 @@ bool Event_ChatListChannels::readElement(QXmlStreamReader *xml) return false; } -void Event_ChatListChannels::writeElement(QXmlStreamWriter *xml) +void Event_ListChatChannels::writeElement(QXmlStreamWriter *xml) { for (int i = 0; i < channelList.size(); ++i) { xml->writeStartElement("channel"); diff --git a/common/protocol.h b/common/protocol.h index 1a8a6f17..0c3f65c3 100644 --- a/common/protocol.h +++ b/common/protocol.h @@ -16,7 +16,7 @@ class QXmlStreamAttributes; class ProtocolResponse; enum ItemId { - ItemId_Event_ChatListChannels = ItemId_Other + 1, + ItemId_Event_ListChatChannels = ItemId_Other + 1, ItemId_Event_ChatListPlayers = ItemId_Other + 2, ItemId_Event_ListGames = ItemId_Other + 3 }; @@ -162,15 +162,17 @@ protected: void extractParameters(); public: ChatEvent(const QString &_eventName, const QString &_channel); + QString getChannel() const { return channel; } }; -class Event_ChatListChannels : public ChatEvent { +class Event_ListChatChannels : public GenericEvent { Q_OBJECT private: QList channelList; public: - Event_ChatListChannels() : ChatEvent("chat_list_channels", QString()) { } - int getItemId() const { return ItemId_Event_ChatListChannels; } + Event_ListChatChannels() : GenericEvent("list_chat_channels") { } + int getItemId() const { return ItemId_Event_ListChatChannels; } + static ProtocolItem *newItem() { return new Event_ListChatChannels; } void addChannel(const QString &_name, const QString &_description, int _playerCount, bool _autoJoin) { channelList.append(ServerChatChannelInfo(_name, _description, _playerCount, _autoJoin)); @@ -186,8 +188,9 @@ class Event_ChatListPlayers : public ChatEvent { private: QList playerList; public: - Event_ChatListPlayers(const QString &_channel) : ChatEvent("chat_list_players", _channel) { } + Event_ChatListPlayers(const QString &_channel = QString()) : ChatEvent("chat_list_players", _channel) { } int getItemId() const { return ItemId_Event_ChatListPlayers; } + static ProtocolItem *newItem() { return new Event_ChatListPlayers; } void addPlayer(const QString &_name) { playerList.append(ServerPlayerInfo(_name)); @@ -205,6 +208,7 @@ private: public: Event_ListGames() : GenericEvent("list_games") { } int getItemId() const { return ItemId_Event_ListGames; } + static ProtocolItem *newItem() { return new Event_ListGames; } void addGame(int _gameId, const QString &_description, bool _hasPassword, int _playerCount, int _maxPlayers, const QString &_creatorName, bool _spectatorsAllowed, int _spectatorCount) { gameList.append(ServerGameInfo(_gameId, _description, _hasPassword, _playerCount, _maxPlayers, _creatorName, _spectatorsAllowed, _spectatorCount)); diff --git a/common/protocol_item_ids.h b/common/protocol_item_ids.h index 5e6f7c30..b1eba59f 100644 --- a/common/protocol_item_ids.h +++ b/common/protocol_item_ids.h @@ -1,7 +1,7 @@ enum AutoItemId { ItemId_Command_Ping = 1001, ItemId_Command_Login = 1002, -ItemId_Command_ChatListChannels = 1003, +ItemId_Command_ListChatChannels = 1003, ItemId_Command_ChatJoinChannel = 1004, ItemId_Command_ChatLeaveChannel = 1005, ItemId_Command_ChatSay = 1006, @@ -50,7 +50,7 @@ ItemId_Event_SetActivePlayer = 1048, ItemId_Event_SetActivePhase = 1049, ItemId_Event_DumpZone = 1050, ItemId_Event_StopDumpZone = 1051, -ItemId_Event_ChatServerMessage = 1052, +ItemId_Event_ServerMessage = 1052, ItemId_Event_ChatJoinChannel = 1053, ItemId_Event_ChatLeaveChannel = 1054, ItemId_Event_ChatSay = 1055, diff --git a/common/protocol_items.cpp b/common/protocol_items.cpp index 0ed8c060..223a0474 100644 --- a/common/protocol_items.cpp +++ b/common/protocol_items.cpp @@ -17,8 +17,8 @@ void Command_Login::extractParameters() username = parameters["username"]; password = parameters["password"]; } -Command_ChatListChannels::Command_ChatListChannels() - : Command("chat_list_channels") +Command_ListChatChannels::Command_ListChatChannels() + : Command("list_chat_channels") { } Command_ChatJoinChannel::Command_ChatJoinChannel(const QString &_channel) @@ -551,14 +551,14 @@ void Event_StopDumpZone::extractParameters() zoneOwnerId = parameters["zone_owner_id"].toInt(); zone = parameters["zone"]; } -Event_ChatServerMessage::Event_ChatServerMessage(const QString &_channel, const QString &_message) - : ChatEvent("chat_server_message", _channel), message(_message) +Event_ServerMessage::Event_ServerMessage(const QString &_message) + : GenericEvent("server_message"), message(_message) { setParameter("message", message); } -void Event_ChatServerMessage::extractParameters() +void Event_ServerMessage::extractParameters() { - ChatEvent::extractParameters(); + GenericEvent::extractParameters(); message = parameters["message"]; } Event_ChatJoinChannel::Event_ChatJoinChannel(const QString &_channel, const QString &_playerName) @@ -597,7 +597,7 @@ void ProtocolItem::initializeHashAuto() { itemNameHash.insert("cmdping", Command_Ping::newItem); itemNameHash.insert("cmdlogin", Command_Login::newItem); - itemNameHash.insert("cmdchat_list_channels", Command_ChatListChannels::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); @@ -646,7 +646,7 @@ void ProtocolItem::initializeHashAuto() itemNameHash.insert("game_eventset_active_phase", Event_SetActivePhase::newItem); itemNameHash.insert("game_eventdump_zone", Event_DumpZone::newItem); itemNameHash.insert("game_eventstop_dump_zone", Event_StopDumpZone::newItem); - itemNameHash.insert("chat_eventchat_server_message", Event_ChatServerMessage::newItem); + itemNameHash.insert("generic_eventserver_message", Event_ServerMessage::newItem); itemNameHash.insert("chat_eventchat_join_channel", Event_ChatJoinChannel::newItem); itemNameHash.insert("chat_eventchat_leave_channel", Event_ChatLeaveChannel::newItem); itemNameHash.insert("chat_eventchat_say", Event_ChatSay::newItem); diff --git a/common/protocol_items.dat b/common/protocol_items.dat index e6ea4c5f..cd53d851 100644 --- a/common/protocol_items.dat +++ b/common/protocol_items.dat @@ -1,6 +1,6 @@ 0:ping 0:login:s,username:s,password -0:chat_list_channels +0:list_chat_channels 0:chat_join_channel:s,channel 1:chat_leave_channel 1:chat_say:s,message @@ -49,7 +49,7 @@ 3:set_active_phase:i,phase 3:dump_zone:i,zone_owner_id:s,zone:i,number_cards 3:stop_dump_zone:i,zone_owner_id:s,zone -5:chat_server_message:s,message +4:server_message:s,message 5:chat_join_channel:s,player_name 5:chat_leave_channel:s,player_name 5:chat_say:s,player_name:s,message \ No newline at end of file diff --git a/common/protocol_items.h b/common/protocol_items.h index dbe675ee..8d41bb46 100644 --- a/common/protocol_items.h +++ b/common/protocol_items.h @@ -25,13 +25,13 @@ public: protected: void extractParameters(); }; -class Command_ChatListChannels : public Command { +class Command_ListChatChannels : public Command { Q_OBJECT private: public: - Command_ChatListChannels(); - static ProtocolItem *newItem() { return new Command_ChatListChannels; } - int getItemId() const { return ItemId_Command_ChatListChannels; } + Command_ListChatChannels(); + static ProtocolItem *newItem() { return new Command_ListChatChannels; } + int getItemId() const { return ItemId_Command_ListChatChannels; } }; class Command_ChatJoinChannel : public Command { Q_OBJECT @@ -685,15 +685,15 @@ public: protected: void extractParameters(); }; -class Event_ChatServerMessage : public ChatEvent { +class Event_ServerMessage : public GenericEvent { Q_OBJECT private: QString message; public: - Event_ChatServerMessage(const QString &_channel = QString(), const QString &_message = QString()); + Event_ServerMessage(const QString &_message = QString()); QString getMessage() const { return message; } - static ProtocolItem *newItem() { return new Event_ChatServerMessage; } - int getItemId() const { return ItemId_Event_ChatServerMessage; } + static ProtocolItem *newItem() { return new Event_ServerMessage; } + int getItemId() const { return ItemId_Event_ServerMessage; } protected: void extractParameters(); }; diff --git a/common/server.cpp b/common/server.cpp index ceb0372f..86682a04 100644 --- a/common/server.cpp +++ b/common/server.cpp @@ -87,7 +87,7 @@ void Server::broadcastGameListUpdate(Server_Game *game) void Server::broadcastChannelUpdate() { Server_ChatChannel *channel = static_cast(sender()); - Event_ChatListChannels *event = new Event_ChatListChannels; + Event_ListChatChannels *event = new Event_ListChatChannels; event->addChannel(channel->getName(), channel->getDescription(), channel->size(), channel->getAutoJoin()); for (int i = 0; i < clients.size(); ++i) diff --git a/common/server_chatchannel.cpp b/common/server_chatchannel.cpp index 3aaaa42a..6a3679fc 100644 --- a/common/server_chatchannel.cpp +++ b/common/server_chatchannel.cpp @@ -16,7 +16,7 @@ void Server_ChatChannel::addClient(Server_ProtocolHandler *client) eventCLP->addPlayer(at(i)->getPlayerName()); client->enqueueProtocolItem(eventCLP); - client->enqueueProtocolItem(new Event_ChatServerMessage(name, joinMessage)); + client->enqueueProtocolItem(new Event_ChatSay(name, QString(), joinMessage)); emit channelInfoChanged(); } diff --git a/common/server_protocolhandler.cpp b/common/server_protocolhandler.cpp index 05b11896..2e0c87a0 100644 --- a/common/server_protocolhandler.cpp +++ b/common/server_protocolhandler.cpp @@ -18,6 +18,15 @@ Server_ProtocolHandler::Server_ProtocolHandler(Server *_server, QObject *parent) Server_ProtocolHandler::~Server_ProtocolHandler() { + // The socket has to be removed from the server's list before it is removed from the game's list + // so it will not receive the game update event. + server->removeClient(this); +// if (game) +// game->removePlayer(this); + + QMapIterator chatChannelIterator(chatChannels); + while (chatChannelIterator.hasNext()) + chatChannelIterator.next().value()->removeClient(this); } void Server_ProtocolHandler::processCommand(Command *command) @@ -75,7 +84,7 @@ void Server_ProtocolHandler::processCommand(Command *command) switch (command->getItemId()) { case ItemId_Command_Ping: response = cmdPing(qobject_cast(command)); break; case ItemId_Command_Login: response = cmdLogin(qobject_cast(command)); break; - case ItemId_Command_ChatListChannels: response = cmdChatListChannels(qobject_cast(command)); break; + case ItemId_Command_ListChatChannels: response = cmdListChatChannels(qobject_cast(command)); break; case ItemId_Command_ChatJoinChannel: response = cmdChatJoinChannel(qobject_cast(command)); break; case ItemId_Command_ListGames: response = cmdListGames(qobject_cast(command)); break; case ItemId_Command_CreateGame: response = cmdCreateGame(qobject_cast(command)); break; @@ -115,13 +124,13 @@ ResponseCode Server_ProtocolHandler::cmdLogin(Command_Login *cmd) return RespWrongPassword; playerName = cmd->getUsername(); - enqueueProtocolItem(new Event_ChatServerMessage(QString(), server->getLoginMessage())); + enqueueProtocolItem(new Event_ServerMessage(server->getLoginMessage())); return RespOk; } -ResponseCode Server_ProtocolHandler::cmdChatListChannels(Command_ChatListChannels * /*cmd*/) +ResponseCode Server_ProtocolHandler::cmdListChatChannels(Command_ListChatChannels * /*cmd*/) { - Event_ChatListChannels *event = new Event_ChatListChannels; + Event_ListChatChannels *event = new Event_ListChatChannels; QMapIterator channelIterator(server->getChatChannels()); while (channelIterator.hasNext()) { Server_ChatChannel *c = channelIterator.next().value(); diff --git a/common/server_protocolhandler.h b/common/server_protocolhandler.h index d9095be6..a081bbcc 100644 --- a/common/server_protocolhandler.h +++ b/common/server_protocolhandler.h @@ -28,7 +28,7 @@ private: ResponseCode cmdPing(Command_Ping *cmd); ResponseCode cmdLogin(Command_Login *cmd); - ResponseCode cmdChatListChannels(Command_ChatListChannels *cmd); + ResponseCode cmdListChatChannels(Command_ListChatChannels *cmd); ResponseCode cmdChatJoinChannel(Command_ChatJoinChannel *cmd); ResponseCode cmdChatLeaveChannel(Command_ChatLeaveChannel *cmd, Server_ChatChannel *channel); ResponseCode cmdChatSay(Command_ChatSay *cmd, Server_ChatChannel *channel); diff --git a/servatrice/servatrice.ini.example b/servatrice/servatrice.ini.example index 5a36553c..02e425d3 100644 --- a/servatrice/servatrice.ini.example +++ b/servatrice/servatrice.ini.example @@ -2,19 +2,19 @@ method=none [database] -type=mysql +type=none hostname=localhost database=servatrice user=servatrice password=foobar [messages] -login="Example line 1", "Example line 2" +login="Example line" [chatchannels] size=1 1\name="General Chat" 1\description="Discuss 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 is the general chat channel. This message is only here to show that channels can have a join message." diff --git a/servatrice/src/servatrice.cpp b/servatrice/src/servatrice.cpp index d5f6fcf0..344e1eb1 100644 --- a/servatrice/src/servatrice.cpp +++ b/servatrice/src/servatrice.cpp @@ -121,4 +121,4 @@ AuthenticationResult Servatrice::checkUserPassword(const QString &user, const QS return UnknownUser; } -const QString Servatrice::versionString = "Servatrice 0.20091103"; +const QString Servatrice::versionString = "Servatrice 0.20091113"; diff --git a/servatrice/src/serversocketinterface.cpp b/servatrice/src/serversocketinterface.cpp index 65dcdbd8..090a1a1f 100644 --- a/servatrice/src/serversocketinterface.cpp +++ b/servatrice/src/serversocketinterface.cpp @@ -42,7 +42,7 @@ ServerSocketInterface::ServerSocketInterface(Server *_server, QTcpSocket *_socke xmlWriter->writeStartElement("cockatrice_server_stream"); xmlWriter->writeAttribute("version", QString::number(ProtocolItem::protocolVersion)); - sendProtocolItem(new Event_ChatServerMessage(QString(), Servatrice::versionString)); + sendProtocolItem(new Event_ServerMessage(Servatrice::versionString)); } ServerSocketInterface::~ServerSocketInterface() @@ -52,19 +52,10 @@ ServerSocketInterface::~ServerSocketInterface() delete xmlWriter; delete xmlReader; delete socket; -/* clearZones(); - // The socket has to be removed from the server's list before it is removed from the game's list - // so it will not receive the game update event. - server->removePlayer(this); - if (game) - game->removePlayer(this); - for (int i = 0; i < chatChannels.size(); ++i) - chatChannels[i]->removePlayer(this); -*/} +} void ServerSocketInterface::readClient() { - qDebug() << "readClient"; xmlReader->addData(socket->readAll()); if (currentItem) {