rooms work mostly

This commit is contained in:
Max-Wilhelm Bruker 2011-01-02 16:13:07 +01:00
parent b73001e9fd
commit 80277ff573
25 changed files with 726 additions and 576 deletions

View file

@ -52,11 +52,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 \
@ -130,11 +131,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 \

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,16 +35,15 @@ 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);
protected slots:

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

@ -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

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

@ -0,0 +1,243 @@
#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 "dlg_creategame.h"
#include "tab_room.h"
#include "userlist.h"
#include "abstractclient.h"
#include "protocol_items.h"
#include "gamesmodel.h"
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);
}
TabRoom::TabRoom(AbstractClient *_client, ServerInfo_Room *info)
: Tab(), client(_client), roomId(info->getRoomId()), roomName(info->getName())
{
gameSelector = new GameSelector(client, roomId);
userList = new UserList(false);
textEdit = new QTextEdit;
textEdit->setReadOnly(true);
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(textEdit);
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]);
}
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)
{
textEdit->append(tr("%1 has joined the room.").arg(sanitizeHtml(event->getUserInfo()->getName())));
userList->processUserInfo(event->getUserInfo());
emit userEvent();
}
void TabRoom::processLeaveRoomEvent(Event_LeaveRoom *event)
{
textEdit->append(tr("%1 has left the room.").arg(sanitizeHtml(event->getPlayerName())));
userList->deleteUser(event->getPlayerName());
emit userEvent();
}
void TabRoom::processSayEvent(Event_RoomSay *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();
}

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

@ -0,0 +1,86 @@
#ifndef TAB_ROOM_H
#define TAB_ROOM_H
#include "tab.h"
#include "protocol_datastructures.h"
#include <QGroupBox>
class AbstractClient;
class UserList;
class QLabel;
class QTextEdit;
class QLineEdit;
class QTreeView;
class QPushButton;
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 TabRoom : public Tab {
Q_OBJECT
private:
AbstractClient *client;
int roomId;
QString roomName;
GameSelector *gameSelector;
UserList *userList;
QTextEdit *textEdit;
QLabel *sayLabel;
QLineEdit *sayEdit;
QGroupBox *chatGroupBox;
QAction *aLeaveRoom;
QString sanitizeHtml(QString dirty) const;
signals:
void roomClosing(TabRoom *tab);
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, 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,79 +35,85 @@ 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());
}
}
void ChatChannelSelector::joinChannel(const QString &channelName)
void RoomSelector::joinRoom(int id)
{
Command_ChatJoinChannel *command = new Command_ChatJoinChannel(channelName);
connect(command, SIGNAL(finished(ResponseCode)), this, SLOT(joinFinished(ResponseCode)));
Command_JoinRoom *command = new Command_JoinRoom(id);
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());
}
void ChatChannelSelector::joinFinished(ResponseCode resp)
void RoomSelector::joinFinished(ProtocolResponse *r)
{
if (resp != RespOk)
if (r->getResponseCode() != RespOk)
return;
Response_JoinRoom *resp = qobject_cast<Response_JoinRoom *>(r);
if (!resp)
return;
Command_ChatJoinChannel *command = qobject_cast<Command_ChatJoinChannel *>(sender());
QString channelName = command->getChannel();
emit channelJoined(channelName);
emit roomJoined(resp->getRoomInfo());
}
ServerMessageLog::ServerMessageLog(AbstractClient *_client, QWidget *parent)
@ -237,108 +141,6 @@ 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);
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);
}
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)
: QWidget(parent)
{
@ -409,24 +211,26 @@ void UserInfoBox::processResponse(ProtocolResponse *response)
TabServer::TabServer(AbstractClient *_client, QWidget *parent)
: Tab(parent), client(_client)
{
gameSelector = new GameSelector(client);
chatChannelSelector = new ChatChannelSelector(client);
roomSelector = new RoomSelector(client);
serverMessageLog = new ServerMessageLog(client);
userInfoBox = new UserInfoBox(client);
userList = new UserList(client);
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(gameSelector, SIGNAL(gameJoined(int)), this, SIGNAL(gameJoined(int)));
connect(roomSelector, SIGNAL(roomJoined(ServerInfo_Room *)), this, SIGNAL(roomJoined(ServerInfo_Room *)));
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 *)));
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(serverMessageLog);
QVBoxLayout *vbox2 = new QVBoxLayout;
vbox2->addWidget(userInfoBox);
@ -441,9 +245,33 @@ TabServer::TabServer(AbstractClient *_client, QWidget *parent)
void TabServer::retranslateUi()
{
gameSelector->retranslateUi();
chatChannelSelector->retranslateUi();
roomSelector->retranslateUi();
serverMessageLog->retranslateUi();
userInfoBox->retranslateUi();
userList->retranslateUi();
}
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

@ -7,63 +7,33 @@
#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 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);
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);
public:
ChatChannelSelector(AbstractClient *_client, QWidget *parent = 0);
RoomSelector(AbstractClient *_client, QWidget *parent = 0);
void retranslateUi();
};
@ -78,30 +48,6 @@ public:
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);
void retranslateUi();
};
class UserInfoBox : public QWidget {
Q_OBJECT
private:
@ -116,14 +62,17 @@ public:
class TabServer : public Tab {
Q_OBJECT
signals:
void chatChannelJoined(const QString &channelName);
void gameJoined(int gameId);
void roomJoined(ServerInfo_Room *info);
// void gameJoined(int gameId);
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);
private:
AbstractClient *client;
GameSelector *gameSelector;
ChatChannelSelector *chatChannelSelector;
RoomSelector *roomSelector;
ServerMessageLog *serverMessageLog;
UserList *userList;
UserInfoBox *userInfoBox;

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());
@ -54,14 +54,14 @@ void TabSupervisor::myAddTab(Tab *tab)
void TabSupervisor::start(AbstractClient *_client)
{
client = _client;
connect(client, SIGNAL(chatEventReceived(ChatEvent *)), this, SLOT(processChatEvent(ChatEvent *)));
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 &)));
connect(tabServer, SIGNAL(roomJoined(ServerInfo_Room *)), this, SLOT(addRoomTab(ServerInfo_Room *)));
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 +107,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())
@ -160,20 +160,20 @@ void TabSupervisor::gameLeft(TabGame *tab)
stop();
}
void TabSupervisor::addChatChannelTab(const QString &channelName)
void TabSupervisor::addRoomTab(ServerInfo_Room *info)
{
TabChatChannel *tab = new TabChatChannel(client, channelName);
connect(tab, SIGNAL(channelClosing(TabChatChannel *)), this, SLOT(chatChannelLeft(TabChatChannel *)));
TabRoom *tab = new TabRoom(client, info);
connect(tab, SIGNAL(roomClosing(TabRoom *)), this, SLOT(roomLeft(TabRoom *)));
myAddTab(tab);
chatChannelTabs.insert(channelName, tab);
roomTabs.insert(info->getRoomId(), tab);
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));
}
@ -206,11 +206,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)

View file

@ -8,14 +8,15 @@ 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 TabSupervisor : public QTabWidget {
Q_OBJECT
@ -25,7 +26,7 @@ private:
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);
@ -46,13 +47,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);
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

@ -110,9 +110,9 @@ 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(QString(), QString(), numberPlayers, false, false, false, false);
mainClient->sendCommand(createCommand);
}
*/}
void MainWindow::localGameEnded()
{

View file

@ -37,6 +37,7 @@ 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);
@ -220,6 +221,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")
{

View file

@ -43,6 +43,7 @@ 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_Invalid = ItemId_Other + 1000
};
@ -204,6 +205,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:

View file

@ -3,17 +3,6 @@
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
ServerInfo_Room::ServerInfo_Room(int _roomId, const QString &_name, const QString &_description, int _gameCount, int _playerCount, bool _autoJoin)
: 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));
}
ServerInfo_User::ServerInfo_User(const QString &_name, int _userLevel, const QString &_country, const QByteArray &_avatarBmp)
: SerializableItem_Map("user")
{
@ -23,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)
@ -48,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,18 +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_Room : public SerializableItem_Map {
public:
ServerInfo_Room(int _id = -1, const QString &_name = QString(), const QString &_description = QString(), int _gameCount = -1, int _playerCount = -1, bool _autoJoin = false);
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(); }
};
class ServerInfo_User : public SerializableItem_Map {
public:
enum UserLevelFlags {
@ -42,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(); }
@ -66,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

@ -279,10 +279,8 @@ ResponseCode Server_ProtocolHandler::cmdListRooms(Command_ListRooms * /*cmd*/, C
QList<ServerInfo_Room *> eventRoomList;
QMapIterator<int, Server_Room *> roomIterator(server->getRooms());
while (roomIterator.hasNext()) {
Server_Room *r = roomIterator.next().value();
eventRoomList.append(new ServerInfo_Room(r->getId(), r->getName(), r->getDescription(), r->getGames().size(), r->size(), r->getAutoJoin()));
}
while (roomIterator.hasNext())
eventRoomList.append(roomIterator.next().value()->getInfo(false));
cont->enqueueItem(new Event_ListRooms(eventRoomList));
acceptsRoomListChanges = true;
@ -303,7 +301,9 @@ ResponseCode Server_ProtocolHandler::cmdJoinRoom(Command_JoinRoom *cmd, CommandC
r->addClient(this);
rooms.insert(r->getId(), r);
return RespOk;
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)

View file

@ -1,6 +1,7 @@
#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)
@ -12,7 +13,24 @@ Server *Server_Room::getServer() const
return static_cast<Server *>(parent());
}
QList<ServerInfo_User *> Server_Room::addClient(Server_ProtocolHandler *client)
ServerInfo_Room *Server_Room::getInfo(bool complete) const
{
QList<ServerInfo_Game *> gameList;
QList<ServerInfo_User *> userList;
qDebug() << "getInfo: complete=" << complete;
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);
@ -22,7 +40,6 @@ QList<ServerInfo_User *> Server_Room::addClient(Server_ProtocolHandler *client)
eventUserList.append(new ServerInfo_User(at(i)->getUserInfo()));
emit roomInfoChanged();
return eventUserList;
}
void Server_Room::removeClient(Server_ProtocolHandler *client)

View file

@ -9,6 +9,7 @@
class Server_ProtocolHandler;
class RoomEvent;
class ServerInfo_User;
class ServerInfo_Room;
class Server_Game;
class Server;
@ -35,8 +36,9 @@ public:
bool getAutoJoin() const { return autoJoin; }
const QMap<int, Server_Game *> &getGames() const { return games; }
Server *getServer() const;
ServerInfo_Room *getInfo(bool complete) const;
QList<ServerInfo_User *> addClient(Server_ProtocolHandler *client);
void addClient(Server_ProtocolHandler *client);
void removeClient(Server_ProtocolHandler *client);
void say(Server_ProtocolHandler *client, const QString &s);
void broadcastGameListUpdate(Server_Game *game);

View file

@ -64,7 +64,7 @@ Servatrice::Servatrice(QObject *parent)
}
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();
@ -185,6 +185,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;

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);