diff --git a/cockatrice/cockatrice.pro b/cockatrice/cockatrice.pro index 0862062d..6b6aff36 100644 --- a/cockatrice/cockatrice.pro +++ b/cockatrice/cockatrice.pro @@ -58,7 +58,7 @@ HEADERS += src/counter.h \ src/remotedecklist_treewidget.h \ src/deckview.h \ src/playerlistwidget.h \ - src/pingpixmapgenerator.h \ + src/pixmapgenerator.h \ src/settingscache.h \ src/localserver.h \ src/localserverinterface.h \ @@ -131,7 +131,7 @@ SOURCES += src/counter.cpp \ src/remotedecklist_treewidget.cpp \ src/deckview.cpp \ src/playerlistwidget.cpp \ - src/pingpixmapgenerator.cpp \ + src/pixmapgenerator.cpp \ src/settingscache.cpp \ src/localserver.cpp \ src/localserverinterface.cpp \ diff --git a/cockatrice/cockatrice.qrc b/cockatrice/cockatrice.qrc index dd3217a6..21c2eb76 100644 --- a/cockatrice/cockatrice.qrc +++ b/cockatrice/cockatrice.qrc @@ -37,5 +37,32 @@ resources/icon_conceded.svg resources/icon_player.svg resources/icon_spectator.svg + + resources/countries/at.svg + resources/countries/au.svg + resources/countries/be.svg + resources/countries/br.svg + resources/countries/ca.svg + resources/countries/ch.svg + resources/countries/cn.svg + resources/countries/de.svg + resources/countries/dk.svg + resources/countries/es.svg + resources/countries/fi.svg + resources/countries/fr.svg + resources/countries/gr.svg + resources/countries/hu.svg + resources/countries/ie.svg + resources/countries/il.svg + resources/countries/it.svg + resources/countries/jp.svg + resources/countries/mx.svg + resources/countries/nl.svg + resources/countries/pl.svg + resources/countries/ru.svg + resources/countries/se.svg + resources/countries/tr.svg + resources/countries/uk.svg + resources/countries/us.svg diff --git a/cockatrice/resources/countries/at.svg b/cockatrice/resources/countries/at.svg new file mode 100644 index 00000000..83eddedf --- /dev/null +++ b/cockatrice/resources/countries/at.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/cockatrice/resources/countries/au.svg b/cockatrice/resources/countries/au.svg new file mode 100644 index 00000000..043b7a92 --- /dev/null +++ b/cockatrice/resources/countries/au.svg @@ -0,0 +1 @@ + diff --git a/cockatrice/resources/countries/be.svg b/cockatrice/resources/countries/be.svg new file mode 100644 index 00000000..8e6d9191 --- /dev/null +++ b/cockatrice/resources/countries/be.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/cockatrice/resources/countries/br.svg b/cockatrice/resources/countries/br.svg new file mode 100644 index 00000000..213c362f --- /dev/null +++ b/cockatrice/resources/countries/br.svg @@ -0,0 +1,112 @@ + + + + Flag of Brazil + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cockatrice/resources/countries/ca.svg b/cockatrice/resources/countries/ca.svg new file mode 100644 index 00000000..137eced6 --- /dev/null +++ b/cockatrice/resources/countries/ca.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/cockatrice/resources/countries/ch.svg b/cockatrice/resources/countries/ch.svg new file mode 100644 index 00000000..8f524ce7 --- /dev/null +++ b/cockatrice/resources/countries/ch.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/cockatrice/resources/countries/cn.svg b/cockatrice/resources/countries/cn.svg new file mode 100644 index 00000000..7c7e50ef --- /dev/null +++ b/cockatrice/resources/countries/cn.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/cockatrice/resources/countries/de.svg b/cockatrice/resources/countries/de.svg new file mode 100644 index 00000000..65e9a01a --- /dev/null +++ b/cockatrice/resources/countries/de.svg @@ -0,0 +1,9 @@ + + + + Flag of Germany + + + + diff --git a/cockatrice/resources/countries/dk.svg b/cockatrice/resources/countries/dk.svg new file mode 100644 index 00000000..4e9f58a5 --- /dev/null +++ b/cockatrice/resources/countries/dk.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/cockatrice/resources/countries/es.svg b/cockatrice/resources/countries/es.svg new file mode 100644 index 00000000..872f198b --- /dev/null +++ b/cockatrice/resources/countries/es.svg @@ -0,0 +1,631 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/cockatrice/resources/countries/fi.svg b/cockatrice/resources/countries/fi.svg new file mode 100644 index 00000000..e7f293bf --- /dev/null +++ b/cockatrice/resources/countries/fi.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/cockatrice/resources/countries/fr.svg b/cockatrice/resources/countries/fr.svg new file mode 100644 index 00000000..0baf7f3b --- /dev/null +++ b/cockatrice/resources/countries/fr.svg @@ -0,0 +1 @@ + diff --git a/cockatrice/resources/countries/gr.svg b/cockatrice/resources/countries/gr.svg new file mode 100644 index 00000000..59e1b1d8 --- /dev/null +++ b/cockatrice/resources/countries/gr.svg @@ -0,0 +1 @@ + diff --git a/cockatrice/resources/countries/hu.svg b/cockatrice/resources/countries/hu.svg new file mode 100644 index 00000000..7345483c --- /dev/null +++ b/cockatrice/resources/countries/hu.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/cockatrice/resources/countries/ie.svg b/cockatrice/resources/countries/ie.svg new file mode 100644 index 00000000..b14caef2 --- /dev/null +++ b/cockatrice/resources/countries/ie.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/cockatrice/resources/countries/il.svg b/cockatrice/resources/countries/il.svg new file mode 100644 index 00000000..295d4f9d --- /dev/null +++ b/cockatrice/resources/countries/il.svg @@ -0,0 +1,35 @@ + + + + Flag of Israel + + + + + + + + + + + + diff --git a/cockatrice/resources/countries/it.svg b/cockatrice/resources/countries/it.svg new file mode 100644 index 00000000..9ee60031 --- /dev/null +++ b/cockatrice/resources/countries/it.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/cockatrice/resources/countries/jp.svg b/cockatrice/resources/countries/jp.svg new file mode 100644 index 00000000..8f454752 --- /dev/null +++ b/cockatrice/resources/countries/jp.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/cockatrice/resources/countries/mx.svg b/cockatrice/resources/countries/mx.svg new file mode 100644 index 00000000..70bfc196 --- /dev/null +++ b/cockatrice/resources/countries/mx.svg @@ -0,0 +1,2487 @@ + + + + + \ No newline at end of file diff --git a/cockatrice/resources/countries/nl.svg b/cockatrice/resources/countries/nl.svg new file mode 100644 index 00000000..f19bd004 --- /dev/null +++ b/cockatrice/resources/countries/nl.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/cockatrice/resources/countries/pl.svg b/cockatrice/resources/countries/pl.svg new file mode 100644 index 00000000..18041ff2 --- /dev/null +++ b/cockatrice/resources/countries/pl.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/cockatrice/resources/countries/ru.svg b/cockatrice/resources/countries/ru.svg new file mode 100644 index 00000000..4b73ce49 --- /dev/null +++ b/cockatrice/resources/countries/ru.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/cockatrice/resources/countries/se.svg b/cockatrice/resources/countries/se.svg new file mode 100644 index 00000000..65db1571 --- /dev/null +++ b/cockatrice/resources/countries/se.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/cockatrice/resources/countries/tr.svg b/cockatrice/resources/countries/tr.svg new file mode 100644 index 00000000..623ecb06 --- /dev/null +++ b/cockatrice/resources/countries/tr.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/cockatrice/resources/countries/uk.svg b/cockatrice/resources/countries/uk.svg new file mode 100644 index 00000000..36c98897 --- /dev/null +++ b/cockatrice/resources/countries/uk.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/cockatrice/resources/countries/us.svg b/cockatrice/resources/countries/us.svg new file mode 100644 index 00000000..f02c7a82 --- /dev/null +++ b/cockatrice/resources/countries/us.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/cockatrice/src/gamesmodel.cpp b/cockatrice/src/gamesmodel.cpp index 14c45ea5..a448d078 100644 --- a/cockatrice/src/gamesmodel.cpp +++ b/cockatrice/src/gamesmodel.cpp @@ -26,7 +26,7 @@ QVariant GamesModel::data(const QModelIndex &index, int role) const ServerInfo_Game *g = gameList[index.row()]; switch (index.column()) { case 0: return g->getDescription(); - case 1: return g->getCreatorName(); + case 1: return g->getCreatorInfo()->getName(); case 2: return g->getHasPassword() ? (g->getSpectatorsNeedPassword() ? tr("yes") : tr("yes, free for spectators")) : tr("no"); case 3: return QString("%1/%2").arg(g->getPlayerCount()).arg(g->getMaxPlayers()); case 4: return g->getSpectatorsAllowed() ? QVariant(g->getSpectatorCount()) : QVariant(tr("not allowed")); @@ -56,7 +56,7 @@ ServerInfo_Game *GamesModel::getGame(int row) void GamesModel::updateGameList(ServerInfo_Game *_game) { - ServerInfo_Game *game = new ServerInfo_Game(_game->getGameId(), _game->getDescription(), _game->getHasPassword(), _game->getPlayerCount(), _game->getMaxPlayers(), _game->getCreatorName(), _game->getSpectatorsAllowed(), _game->getSpectatorsNeedPassword(), _game->getSpectatorCount()); + ServerInfo_Game *game = new ServerInfo_Game(_game->getGameId(), _game->getDescription(), _game->getHasPassword(), _game->getPlayerCount(), _game->getMaxPlayers(), new ServerInfo_User(_game->getCreatorInfo()), _game->getSpectatorsAllowed(), _game->getSpectatorsNeedPassword(), _game->getSpectatorCount()); for (int i = 0; i < gameList.size(); i++) if (gameList[i]->getGameId() == game->getGameId()) { if (game->getPlayerCount() == 0) { diff --git a/cockatrice/src/localserver.cpp b/cockatrice/src/localserver.cpp index e1e98b47..1af04676 100644 --- a/cockatrice/src/localserver.cpp +++ b/cockatrice/src/localserver.cpp @@ -16,3 +16,8 @@ LocalServerInterface *LocalServer::newConnection() addClient(lsi); return lsi; } + +ServerInfo_User *LocalServer::getUserData(const QString &name) +{ + return new ServerInfo_User(name); +} \ No newline at end of file diff --git a/cockatrice/src/localserver.h b/cockatrice/src/localserver.h index 90d304b0..ebdb32e2 100644 --- a/cockatrice/src/localserver.h +++ b/cockatrice/src/localserver.h @@ -18,6 +18,8 @@ public: int getMaxPlayerInactivityTime() const { return 9999999; } LocalServerInterface *newConnection(); +protected: + ServerInfo_User *getUserData(const QString &name); }; #endif \ No newline at end of file diff --git a/cockatrice/src/main.cpp b/cockatrice/src/main.cpp index a19f60ba..a6245684 100644 --- a/cockatrice/src/main.cpp +++ b/cockatrice/src/main.cpp @@ -34,14 +34,12 @@ #include "dlg_settings.h" #include "carddatabase.h" #include "settingscache.h" -#include "pingpixmapgenerator.h" //Q_IMPORT_PLUGIN(qjpeg) CardDatabase *db; QTranslator *translator, *qtTranslator; SettingsCache *settingsCache; -PingPixmapGenerator *pingPixmapGenerator; void myMessageOutput(QtMsgType /*type*/, const char *msg) { @@ -87,7 +85,6 @@ int main(int argc, char *argv[]) settingsCache = new SettingsCache; db = new CardDatabase; - pingPixmapGenerator = new PingPixmapGenerator; qtTranslator = new QTranslator; translator = new QTranslator; @@ -125,7 +122,6 @@ int main(int argc, char *argv[]) app.exec(); } - delete pingPixmapGenerator; delete db; delete settingsCache; diff --git a/cockatrice/src/pingpixmapgenerator.cpp b/cockatrice/src/pingpixmapgenerator.cpp deleted file mode 100644 index 85f0f881..00000000 --- a/cockatrice/src/pingpixmapgenerator.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "pingpixmapgenerator.h" -#include - -QPixmap PingPixmapGenerator::generatePixmap(int size, int value, int max) -{ - int key = size * 1000000 + max * 1000 + value; - if (pmCache.contains(key)) - return pmCache.value(key); - - QPixmap pixmap(size, size); - pixmap.fill(Qt::transparent); - QPainter painter(&pixmap); - QColor color; - if ((max == -1) || (value == -1)) - color = Qt::black; - else - color.setHsv(120 * (1.0 - ((double) value / max)), 255, 255); - - QRadialGradient g(QPointF((double) pixmap.width() / 2, (double) pixmap.height() / 2), qMin(pixmap.width(), pixmap.height()) / 2.0); - g.setColorAt(0, color); - g.setColorAt(1, Qt::transparent); - painter.fillRect(0, 0, pixmap.width(), pixmap.height(), QBrush(g)); - - pmCache.insert(key, pixmap); - - return pixmap; -} diff --git a/cockatrice/src/pingpixmapgenerator.h b/cockatrice/src/pingpixmapgenerator.h deleted file mode 100644 index 7d6cf274..00000000 --- a/cockatrice/src/pingpixmapgenerator.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef PINGPIXMAPGENERATOR_H -#define PINGPIXMAPGENERATOR_H - -#include -#include - -class PingPixmapGenerator { -private: - QMap pmCache; -public: - QPixmap generatePixmap(int size, int value, int max); -}; - -extern PingPixmapGenerator *pingPixmapGenerator; - -#endif diff --git a/cockatrice/src/pixmapgenerator.cpp b/cockatrice/src/pixmapgenerator.cpp new file mode 100644 index 00000000..70fffb23 --- /dev/null +++ b/cockatrice/src/pixmapgenerator.cpp @@ -0,0 +1,52 @@ +#include "pixmapgenerator.h" +#include +#include +#include + +QPixmap PingPixmapGenerator::generatePixmap(int size, int value, int max) +{ + int key = size * 1000000 + max * 1000 + value; + if (pmCache.contains(key)) + return pmCache.value(key); + + QPixmap pixmap(size, size); + pixmap.fill(Qt::transparent); + QPainter painter(&pixmap); + QColor color; + if ((max == -1) || (value == -1)) + color = Qt::black; + else + color.setHsv(120 * (1.0 - ((double) value / max)), 255, 255); + + QRadialGradient g(QPointF((double) pixmap.width() / 2, (double) pixmap.height() / 2), qMin(pixmap.width(), pixmap.height()) / 2.0); + g.setColorAt(0, color); + g.setColorAt(1, Qt::transparent); + painter.fillRect(0, 0, pixmap.width(), pixmap.height(), QBrush(g)); + + pmCache.insert(key, pixmap); + + return pixmap; +} + +QMap PingPixmapGenerator::pmCache; + +QPixmap CountryPixmapGenerator::generatePixmap(int height, const QString &countryCode) +{ + if (countryCode.size() != 2) + return QPixmap(); + QString key = countryCode + QString::number(height); + if (pmCache.contains(key)) + return pmCache.value(key); + + QSvgRenderer svg(QString(":/resources/countries/" + countryCode + ".svg")); + double aspect = (double) svg.defaultSize().width() / (double) svg.defaultSize().height(); + QPixmap pixmap((int) round(aspect * height), height); + pixmap.fill(Qt::transparent); + QPainter painter(&pixmap); + svg.render(&painter, QRectF(0, 0, aspect * height, height)); + + pmCache.insert(key, pixmap); + return pixmap; +} + +QMap CountryPixmapGenerator::pmCache; \ No newline at end of file diff --git a/cockatrice/src/pixmapgenerator.h b/cockatrice/src/pixmapgenerator.h new file mode 100644 index 00000000..ee70a0fa --- /dev/null +++ b/cockatrice/src/pixmapgenerator.h @@ -0,0 +1,21 @@ +#ifndef PINGPIXMAPGENERATOR_H +#define PINGPIXMAPGENERATOR_H + +#include +#include + +class PingPixmapGenerator { +private: + static QMap pmCache; +public: + static QPixmap generatePixmap(int size, int value, int max); +}; + +class CountryPixmapGenerator { +private: + static QMap pmCache; +public: + static QPixmap generatePixmap(int height, const QString &countryCode); +}; + +#endif diff --git a/cockatrice/src/playerlistwidget.cpp b/cockatrice/src/playerlistwidget.cpp index 002e8fc7..8fcbce65 100644 --- a/cockatrice/src/playerlistwidget.cpp +++ b/cockatrice/src/playerlistwidget.cpp @@ -1,7 +1,8 @@ #include #include "playerlistwidget.h" #include "protocol_datastructures.h" -#include "pingpixmapgenerator.h" +#include "pixmapgenerator.h" +#include PlayerListWidget::PlayerListWidget(QWidget *parent) : QTreeWidget(parent), gameStarted(false) @@ -44,14 +45,16 @@ void PlayerListWidget::updatePlayerProperties(ServerInfo_PlayerProperties *prop) player->setIcon(1, prop->getSpectator() ? spectatorIcon : playerIcon); player->setIcon(2, gameStarted ? (prop->getConceded() ? concededIcon : QIcon()) : (prop->getReadyStart() ? readyIcon : notReadyIcon)); - player->setText(3, prop->getName()); + player->setText(3, prop->getUserInfo()->getName()); + if (!prop->getUserInfo()->getCountry().isEmpty()) + player->setIcon(3, QIcon(CountryPixmapGenerator::generatePixmap(10, prop->getUserInfo()->getCountry()))); QString deckText; if (!prop->getSpectator()) switch (prop->getDeckId()) { - case -2: deckText = tr("no deck"); break; - case -1: deckText = tr("local deck"); break; - default: deckText = tr("ID #%1").arg(prop->getDeckId()); + case -2: deckText = tr("---"); break; + case -1: deckText = tr("local"); break; + default: deckText = tr("#%1").arg(prop->getDeckId()); } player->setText(4, deckText); } @@ -81,7 +84,7 @@ void PlayerListWidget::updatePing(int playerId, int pingTime) QTreeWidgetItem *twi = players.value(playerId, 0); if (!twi) return; - twi->setIcon(0, QIcon(pingPixmapGenerator->generatePixmap(10, pingTime, 10))); + twi->setIcon(0, QIcon(PingPixmapGenerator::generatePixmap(10, pingTime, 10))); } void PlayerListWidget::setGameStarted(bool _gameStarted) diff --git a/cockatrice/src/tab_chatchannel.cpp b/cockatrice/src/tab_chatchannel.cpp index fd3b036d..979618c8 100644 --- a/cockatrice/src/tab_chatchannel.cpp +++ b/cockatrice/src/tab_chatchannel.cpp @@ -77,15 +77,15 @@ void TabChatChannel::processChatEvent(ChatEvent *event) void TabChatChannel::processListPlayersEvent(Event_ChatListPlayers *event) { - const QList &players = event->getPlayerList(); + 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()); + textEdit->append(tr("%1 has joined the channel.").arg(event->getUserInfo()->getName())); + playerList->addItem(event->getUserInfo()->getName()); emit userEvent(); } diff --git a/cockatrice/src/tab_game.cpp b/cockatrice/src/tab_game.cpp index 78c686f1..d0c75ef8 100644 --- a/cockatrice/src/tab_game.cpp +++ b/cockatrice/src/tab_game.cpp @@ -488,13 +488,13 @@ void TabGame::eventGameStateChanged(Event_GameStateChanged *event, GameEventCont ServerInfo_PlayerProperties *prop = pl->getProperties(); if (prop->getSpectator()) { if (!spectators.contains(prop->getPlayerId())) { - spectators.insert(prop->getPlayerId(), prop->getName()); + spectators.insert(prop->getPlayerId(), prop->getUserInfo()->getName()); playerListWidget->addPlayer(prop); } } else { Player *player = players.value(prop->getPlayerId(), 0); if (!player) { - player = addPlayer(prop->getPlayerId(), prop->getName()); + player = addPlayer(prop->getPlayerId(), prop->getUserInfo()->getName()); playerListWidget->addPlayer(prop); } player->processPlayerInfo(pl); @@ -554,11 +554,11 @@ void TabGame::eventJoin(Event_Join *event, GameEventContext * /*context*/) { ServerInfo_PlayerProperties *playerInfo = event->getPlayer(); if (playerInfo->getSpectator()) { - spectators.insert(playerInfo->getPlayerId(), playerInfo->getName()); - messageLog->logJoinSpectator(playerInfo->getName()); + spectators.insert(playerInfo->getPlayerId(), playerInfo->getUserInfo()->getName()); + messageLog->logJoinSpectator(playerInfo->getUserInfo()->getName()); playerListWidget->addPlayer(playerInfo); } else { - Player *newPlayer = addPlayer(playerInfo->getPlayerId(), playerInfo->getName()); + Player *newPlayer = addPlayer(playerInfo->getPlayerId(), playerInfo->getUserInfo()->getName()); messageLog->logJoin(newPlayer); playerListWidget->addPlayer(playerInfo); } diff --git a/cockatrice/src/tab_supervisor.cpp b/cockatrice/src/tab_supervisor.cpp index 5effbee6..84d6446d 100644 --- a/cockatrice/src/tab_supervisor.cpp +++ b/cockatrice/src/tab_supervisor.cpp @@ -6,7 +6,7 @@ #include "tab_game.h" #include "tab_deck_storage.h" #include "protocol_items.h" -#include "pingpixmapgenerator.h" +#include "pixmapgenerator.h" #include TabSupervisor:: TabSupervisor(QWidget *parent) @@ -97,10 +97,10 @@ void TabSupervisor::stop() clear(); - delete tabServer; + tabServer->deleteLater(); tabServer = 0; - delete tabDeckStorage; + tabDeckStorage->deleteLater(); tabDeckStorage = 0; QMapIterator chatChannelIterator(chatChannelTabs); @@ -119,7 +119,7 @@ void TabSupervisor::updatePingTime(int value, int max) if (!tabServer) return; - setTabIcon(0, QIcon(pingPixmapGenerator->generatePixmap(15, value, max))); + setTabIcon(0, QIcon(PingPixmapGenerator::generatePixmap(15, value, max))); } void TabSupervisor::gameJoined(Event_GameJoined *event) diff --git a/common/protocol.cpp b/common/protocol.cpp index 30434a5e..7b320242 100644 --- a/common/protocol.cpp +++ b/common/protocol.cpp @@ -15,7 +15,7 @@ void ProtocolItem::initializeHash() registerSerializableItem("move_card_to_zone", MoveCardToZone::newItem); registerSerializableItem("chat_channel", ServerInfo_ChatChannel::newItem); - registerSerializableItem("chat_user", ServerInfo_ChatUser::newItem); + registerSerializableItem("user", ServerInfo_User::newItem); registerSerializableItem("game", ServerInfo_Game::newItem); registerSerializableItem("card_counter", ServerInfo_CardCounter::newItem); registerSerializableItem("card", ServerInfo_Card::newItem); @@ -52,6 +52,7 @@ void ProtocolItem::initializeHash() registerSerializableItem("game_eventdraw_cards", Event_DrawCards::newItem); registerSerializableItem("game_eventping", Event_Ping::newItem); registerSerializableItem("chat_eventchat_list_players", Event_ChatListPlayers::newItem); + registerSerializableItem("chat_eventchat_join_channel", Event_ChatJoinChannel::newItem); } TopLevelProtocolItem::TopLevelProtocolItem() @@ -275,13 +276,21 @@ Event_ListChatChannels::Event_ListChatChannels(const QList &_playerList) +Event_ChatListPlayers::Event_ChatListPlayers(const QString &_channel, const QList &_playerList) : ChatEvent("chat_list_players", _channel) { for (int i = 0; i < _playerList.size(); ++i) itemList.append(_playerList[i]); } +Event_ChatJoinChannel::Event_ChatJoinChannel(const QString &_channel, ServerInfo_User *_info) + : ChatEvent("chat_join_channel", _channel) +{ + if (!_info) + _info = new ServerInfo_User; + insertItem(_info); +} + Event_ListGames::Event_ListGames(const QList &_gameList) : GenericEvent("list_games") { diff --git a/common/protocol.h b/common/protocol.h index bdf0897a..e6599069 100644 --- a/common/protocol.h +++ b/common/protocol.h @@ -27,14 +27,15 @@ enum ItemId { ItemId_Command_SetSideboardPlan = ItemId_Other + 102, ItemId_Event_ListChatChannels = ItemId_Other + 200, ItemId_Event_ChatListPlayers = ItemId_Other + 201, - ItemId_Event_ListGames = ItemId_Other + 202, - ItemId_Event_GameStateChanged = ItemId_Other + 203, - ItemId_Event_PlayerPropertiesChanged = ItemId_Other + 204, - ItemId_Event_CreateArrows = ItemId_Other + 205, - ItemId_Event_CreateCounters = ItemId_Other + 206, - ItemId_Event_DrawCards = ItemId_Other + 207, - ItemId_Event_Join = ItemId_Other + 208, - ItemId_Event_Ping = ItemId_Other + 209, + ItemId_Event_ChatJoinChannel = ItemId_Other + 202, + ItemId_Event_ListGames = ItemId_Other + 203, + ItemId_Event_GameStateChanged = ItemId_Other + 204, + ItemId_Event_PlayerPropertiesChanged = ItemId_Other + 205, + ItemId_Event_CreateArrows = ItemId_Other + 206, + ItemId_Event_CreateCounters = ItemId_Other + 207, + ItemId_Event_DrawCards = ItemId_Other + 208, + ItemId_Event_Join = ItemId_Other + 209, + ItemId_Event_Ping = ItemId_Other + 210, ItemId_Response_DeckList = ItemId_Other + 300, ItemId_Response_DeckDownload = ItemId_Other + 301, ItemId_Response_DeckUpload = ItemId_Other + 302, @@ -298,10 +299,19 @@ public: class Event_ChatListPlayers : public ChatEvent { Q_OBJECT public: - Event_ChatListPlayers(const QString &_channel = QString(), const QList &_playerList = QList()); + Event_ChatListPlayers(const QString &_channel = QString(), const QList &_playerList = QList()); int getItemId() const { return ItemId_Event_ChatListPlayers; } static SerializableItem *newItem() { return new Event_ChatListPlayers; } - QList getPlayerList() const { return typecastItemList(); } + QList getPlayerList() const { return typecastItemList(); } +}; + +class Event_ChatJoinChannel : public ChatEvent { + Q_OBJECT +public: + Event_ChatJoinChannel(const QString &_channel = QString(), ServerInfo_User *_info = 0); + int getItemId() const { return ItemId_Event_ChatJoinChannel; } + static SerializableItem *newItem() { return new Event_ChatJoinChannel; } + ServerInfo_User *getUserInfo() const { return static_cast(itemMap.value("user")); } }; class Event_ListGames : public GenericEvent { diff --git a/common/protocol_datastructures.cpp b/common/protocol_datastructures.cpp index f5d606ac..a8f7a71f 100644 --- a/common/protocol_datastructures.cpp +++ b/common/protocol_datastructures.cpp @@ -12,13 +12,23 @@ ServerInfo_ChatChannel::ServerInfo_ChatChannel(const QString &_name, const QStri insertItem(new SerializableItem_Bool("auto_join", _autoJoin)); } -ServerInfo_ChatUser::ServerInfo_ChatUser(const QString &_name) - : SerializableItem_Map("chat_user") +ServerInfo_User::ServerInfo_User(const QString &_name, int _userLevel, const QString &_country) + : SerializableItem_Map("user") { insertItem(new SerializableItem_String("name", _name)); + insertItem(new SerializableItem_Int("userlevel", _userLevel)); + insertItem(new SerializableItem_String("country", _country)); } -ServerInfo_Game::ServerInfo_Game(int _gameId, const QString &_description, bool _hasPassword, int _playerCount, int _maxPlayers, const QString &_creatorName, bool _spectatorsAllowed, bool _spectatorsNeedPassword, int _spectatorCount) +ServerInfo_User::ServerInfo_User(const ServerInfo_User *other) + : SerializableItem_Map("user") +{ + insertItem(new SerializableItem_String("name", other->getName())); + insertItem(new SerializableItem_Int("userlevel", other->getUserLevel())); + insertItem(new SerializableItem_String("country", other->getCountry())); +} + +ServerInfo_Game::ServerInfo_Game(int _gameId, const QString &_description, bool _hasPassword, int _playerCount, int _maxPlayers, ServerInfo_User *_creatorInfo, bool _spectatorsAllowed, bool _spectatorsNeedPassword, int _spectatorCount) : SerializableItem_Map("game") { insertItem(new SerializableItem_Int("game_id", _gameId)); @@ -26,7 +36,9 @@ ServerInfo_Game::ServerInfo_Game(int _gameId, const QString &_description, bool insertItem(new SerializableItem_Bool("has_password", _hasPassword)); insertItem(new SerializableItem_Int("player_count", _playerCount)); insertItem(new SerializableItem_Int("max_players", _maxPlayers)); - insertItem(new SerializableItem_String("creator_name", _creatorName)); + if (!_creatorInfo) + _creatorInfo = new ServerInfo_User; + insertItem(_creatorInfo); insertItem(new SerializableItem_Bool("spectators_allowed", _spectatorsAllowed)); insertItem(new SerializableItem_Bool("spectators_need_password", _spectatorsNeedPassword)); insertItem(new SerializableItem_Int("spectator_count", _spectatorCount)); @@ -124,11 +136,13 @@ ServerInfo_Arrow::ServerInfo_Arrow(int _id, int _startPlayerId, const QString &_ insertItem(new SerializableItem_Color("color", _color)); } -ServerInfo_PlayerProperties::ServerInfo_PlayerProperties(int _playerId, const QString &_name, bool _spectator, bool _conceded, bool _readyStart, int _deckId) +ServerInfo_PlayerProperties::ServerInfo_PlayerProperties(int _playerId, ServerInfo_User *_userInfo, bool _spectator, bool _conceded, bool _readyStart, int _deckId) : SerializableItem_Map("player_properties") { insertItem(new SerializableItem_Int("player_id", _playerId)); - insertItem(new SerializableItem_String("name", _name)); + if (!_userInfo) + _userInfo = new ServerInfo_User; + insertItem(_userInfo); insertItem(new SerializableItem_Bool("spectator", _spectator)); insertItem(new SerializableItem_Bool("conceded", _conceded)); insertItem(new SerializableItem_Bool("ready_start", _readyStart)); diff --git a/common/protocol_datastructures.h b/common/protocol_datastructures.h index 147cc97e..697ea76f 100644 --- a/common/protocol_datastructures.h +++ b/common/protocol_datastructures.h @@ -30,23 +30,33 @@ public: bool getAutoJoin() const { return static_cast(itemMap.value("auto_join"))->getData(); } }; -class ServerInfo_ChatUser : public SerializableItem_Map { +class ServerInfo_User : public SerializableItem_Map { public: - ServerInfo_ChatUser(const QString &_name = QString()); - static SerializableItem *newItem() { return new ServerInfo_ChatUser; } + enum UserLevelFlags { + IsNothing = 0x00, + IsUser = 0x01, + IsRegistered = 0x02, + IsAdmin = 0x04 + }; + ServerInfo_User(const QString &_name = QString(), int _userLevel = IsNothing, const QString &_country = QString()); + ServerInfo_User(const ServerInfo_User *other); + static SerializableItem *newItem() { return new ServerInfo_User; } QString getName() const { return static_cast(itemMap.value("name"))->getData(); } + int getUserLevel() const { return static_cast(itemMap.value("userlevel"))->getData(); } + void setUserLevel(int _userLevel) { static_cast(itemMap.value("userlevel"))->setData(_userLevel); } + QString getCountry() const { return static_cast(itemMap.value("country"))->getData(); } }; class ServerInfo_Game : public SerializableItem_Map { public: - ServerInfo_Game(int _gameId = -1, const QString &_description = QString(), bool _hasPassword = false, int _playerCount = -1, int _maxPlayers = -1, const QString &_creatorName = QString(), bool _spectatorsAllowed = false, bool _spectatorsNeedPassword = false, int _spectatorCount = -1); + ServerInfo_Game(int _gameId = -1, const QString &_description = QString(), bool _hasPassword = false, int _playerCount = -1, int _maxPlayers = -1, ServerInfo_User *creatorInfo = 0, bool _spectatorsAllowed = false, bool _spectatorsNeedPassword = false, int _spectatorCount = -1); static SerializableItem *newItem() { return new ServerInfo_Game; } int getGameId() const { return static_cast(itemMap.value("game_id"))->getData(); } QString getDescription() const { return static_cast(itemMap.value("description"))->getData(); } bool getHasPassword() const { return static_cast(itemMap.value("has_password"))->getData(); } int getPlayerCount() const { return static_cast(itemMap.value("player_count"))->getData(); } int getMaxPlayers() const { return static_cast(itemMap.value("max_players"))->getData(); } - QString getCreatorName() const { return static_cast(itemMap.value("creator_name"))->getData(); } + ServerInfo_User *getCreatorInfo() const { return static_cast(itemMap.value("user")); } bool getSpectatorsAllowed() const { return static_cast(itemMap.value("spectators_allowed"))->getData(); } bool getSpectatorsNeedPassword() const { return static_cast(itemMap.value("spectators_need_password"))->getData(); } int getSpectatorCount() const { return static_cast(itemMap.value("spectator_count"))->getData(); } @@ -121,10 +131,10 @@ public: class ServerInfo_PlayerProperties : public SerializableItem_Map { public: - ServerInfo_PlayerProperties(int _playerId = -1, const QString &_name = QString(), bool _spectator = false, bool _conceded = false, bool _readyStart = false, int _deckId = -1); + ServerInfo_PlayerProperties(int _playerId = -1, ServerInfo_User *_userInfo = 0, bool _spectator = false, bool _conceded = false, bool _readyStart = false, int _deckId = -1); static SerializableItem *newItem() { return new ServerInfo_PlayerProperties; } int getPlayerId() const { return static_cast(itemMap.value("player_id"))->getData(); } - QString getName() const { return static_cast(itemMap.value("name"))->getData(); } + ServerInfo_User *getUserInfo() const { return static_cast(itemMap.value("user")); } bool getSpectator() const { return static_cast(itemMap.value("spectator"))->getData(); } bool getConceded() const { return static_cast(itemMap.value("conceded"))->getData(); } bool getReadyStart() const { return static_cast(itemMap.value("ready_start"))->getData(); } diff --git a/common/protocol_item_ids.h b/common/protocol_item_ids.h index e7a95a09..c9bc9b9d 100644 --- a/common/protocol_item_ids.h +++ b/common/protocol_item_ids.h @@ -59,11 +59,10 @@ ItemId_Event_DumpZone = 1057, ItemId_Event_StopDumpZone = 1058, ItemId_Event_ServerMessage = 1059, ItemId_Event_GameJoined = 1060, -ItemId_Event_ChatJoinChannel = 1061, -ItemId_Event_ChatLeaveChannel = 1062, -ItemId_Event_ChatSay = 1063, -ItemId_Context_ReadyStart = 1064, -ItemId_Context_Concede = 1065, -ItemId_Context_DeckSelect = 1066, -ItemId_Other = 1067 +ItemId_Event_ChatLeaveChannel = 1061, +ItemId_Event_ChatSay = 1062, +ItemId_Context_ReadyStart = 1063, +ItemId_Context_Concede = 1064, +ItemId_Context_DeckSelect = 1065, +ItemId_Other = 1066 }; diff --git a/common/protocol_items.cpp b/common/protocol_items.cpp index c4e4e14c..3d3cca24 100644 --- a/common/protocol_items.cpp +++ b/common/protocol_items.cpp @@ -381,11 +381,6 @@ Event_GameJoined::Event_GameJoined(int _gameId, const QString &_gameDescription, insertItem(new SerializableItem_Bool("spectators_see_everything", _spectatorsSeeEverything)); insertItem(new SerializableItem_Bool("resuming", _resuming)); } -Event_ChatJoinChannel::Event_ChatJoinChannel(const QString &_channel, const QString &_playerName) - : ChatEvent("chat_join_channel", _channel) -{ - insertItem(new SerializableItem_String("player_name", _playerName)); -} Event_ChatLeaveChannel::Event_ChatLeaveChannel(const QString &_channel, const QString &_playerName) : ChatEvent("chat_leave_channel", _channel) { @@ -472,7 +467,6 @@ void ProtocolItem::initializeHashAuto() itemNameHash.insert("game_eventstop_dump_zone", Event_StopDumpZone::newItem); itemNameHash.insert("generic_eventserver_message", Event_ServerMessage::newItem); itemNameHash.insert("generic_eventgame_joined", Event_GameJoined::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); itemNameHash.insert("game_event_contextready_start", Context_ReadyStart::newItem); diff --git a/common/protocol_items.dat b/common/protocol_items.dat index e07eb6ac..45f6b533 100644 --- a/common/protocol_items.dat +++ b/common/protocol_items.dat @@ -58,7 +58,6 @@ 3:stop_dump_zone:i,zone_owner_id:s,zone 4:server_message:s,message 4:game_joined:i,game_id:s,game_description:i,player_id:b,spectator:b,spectators_can_talk:b,spectators_see_everything:b,resuming -5:chat_join_channel:s,player_name 5:chat_leave_channel:s,player_name 5:chat_say:s,player_name:s,message 6:ready_start diff --git a/common/protocol_items.h b/common/protocol_items.h index 2d60ec31..b94c7afb 100644 --- a/common/protocol_items.h +++ b/common/protocol_items.h @@ -563,14 +563,6 @@ public: static SerializableItem *newItem() { return new Event_GameJoined; } int getItemId() const { return ItemId_Event_GameJoined; } }; -class Event_ChatJoinChannel : public ChatEvent { - Q_OBJECT -public: - Event_ChatJoinChannel(const QString &_channel = QString(), const QString &_playerName = QString()); - QString getPlayerName() const { return static_cast(itemMap.value("player_name"))->getData(); }; - static SerializableItem *newItem() { return new Event_ChatJoinChannel; } - int getItemId() const { return ItemId_Event_ChatJoinChannel; } -}; class Event_ChatLeaveChannel : public ChatEvent { Q_OBJECT public: diff --git a/common/server.cpp b/common/server.cpp index 9471dc4f..5a1fa3a1 100644 --- a/common/server.cpp +++ b/common/server.cpp @@ -22,6 +22,7 @@ #include "server_counter.h" #include "server_chatchannel.h" #include "server_protocolhandler.h" +#include "protocol_datastructures.h" #include Server::Server(QObject *parent) @@ -35,6 +36,35 @@ Server::~Server() delete clients.takeFirst(); } +AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString &name, const QString &password) +{ + AuthenticationResult authState = checkUserPassword(name, password); + if (authState == PasswordWrong) + return authState; + + if (authState == PasswordRight) { + Server_ProtocolHandler *oldSession = users.value(name); + if (oldSession) + delete oldSession; // ~Server_ProtocolHandler() will call Server::removeClient + } else if (authState == UnknownUser) { + // Change user name so that no two users have the same names + QString tempName = name; + int i = 0; + while (users.contains(tempName)) + tempName = name + "_" + QString::number(++i); + name = tempName; + } + + ServerInfo_User *data = getUserData(name); + if (authState == PasswordRight) + data->setUserLevel(data->getUserLevel() | ServerInfo_User::IsRegistered); + session->setUserInfo(data); + + users.insert(name, session); + + return authState; +} + Server_Game *Server::createGame(const QString &description, const QString &password, int maxPlayers, bool spectatorsAllowed, bool spectatorsNeedPassword, bool spectatorsCanTalk, bool spectatorsSeeEverything, Server_ProtocolHandler *creator) { Server_Game *newGame = new Server_Game(creator, nextGameId++, description, password, maxPlayers, spectatorsAllowed, spectatorsNeedPassword, spectatorsCanTalk, spectatorsSeeEverything, this); @@ -54,19 +84,10 @@ void Server::addClient(Server_ProtocolHandler *client) void Server::removeClient(Server_ProtocolHandler *client) { clients.removeAt(clients.indexOf(client)); - qDebug(QString("Server::removeClient: %1 clients left").arg(clients.size()).toLatin1()); -} - -void Server::closeOldSession(const QString &playerName) -{ - Server_ProtocolHandler *session = 0; - for (int i = 0; i < clients.size(); ++i) - if (clients[i]->getPlayerName() == playerName) { - session = clients[i]; - break; - } - if (session) - delete session; // ~Server_ProtocolHandler() will call Server::removeClient + ServerInfo_User *data = client->getUserInfo(); + if (data) + users.remove(data->getName()); + qDebug() << "Server::removeClient: " << clients.size() << "clients; " << users.size() << "users left"; } Server_Game *Server::getGame(int gameId) const @@ -85,14 +106,14 @@ void Server::broadcastGameListUpdate(Server_Game *game) !game->getPassword().isEmpty(), game->getPlayerCount(), game->getMaxPlayers(), - game->getCreatorName(), + new ServerInfo_User(game->getCreatorInfo()), game->getSpectatorsAllowed(), game->getSpectatorsNeedPassword(), game->getSpectatorCount() )); else // Game is closing - eventGameList.append(new ServerInfo_Game(game->getGameId(), QString(), false, 0, game->getMaxPlayers(), QString(), false, 0)); + eventGameList.append(new ServerInfo_Game(game->getGameId(), QString(), false, 0, game->getMaxPlayers(), 0, false, 0)); Event_ListGames *event = new Event_ListGames(eventGameList); for (int i = 0; i < clients.size(); i++) diff --git a/common/server.h b/common/server.h index ff29b82f..c5ad1cd8 100644 --- a/common/server.h +++ b/common/server.h @@ -8,6 +8,7 @@ class Server_Game; class Server_ChatChannel; class Server_ProtocolHandler; +class ServerInfo_User; enum AuthenticationResult { PasswordWrong = 0, PasswordRight = 1, UnknownUser = 2 }; @@ -22,7 +23,7 @@ private slots: public: Server(QObject *parent = 0); ~Server(); - virtual AuthenticationResult checkUserPassword(const QString &user, const QString &password) = 0; + AuthenticationResult loginUser(Server_ProtocolHandler *session, QString &name, const QString &password); QList getGames() const { return games.values(); } Server_Game *getGame(int gameId) const; const QMap &getChatChannels() { return chatChannels; } @@ -30,7 +31,6 @@ public: void addClient(Server_ProtocolHandler *player); void removeClient(Server_ProtocolHandler *player); - void closeOldSession(const QString &playerName); virtual QString getLoginMessage() const = 0; Server_Game *createGame(const QString &description, const QString &password, int maxPlayers, bool spectatorsAllowed, bool spectatorsNeedPassword, bool spectatorsCanTalk, bool spectatorsSeeEverything, Server_ProtocolHandler *creator); @@ -40,8 +40,11 @@ public: private: QMap games; QList clients; + QMap users; QMap chatChannels; protected: + virtual AuthenticationResult checkUserPassword(const QString &user, const QString &password) = 0; + virtual ServerInfo_User *getUserData(const QString &name) = 0; int nextGameId; void addChatChannel(Server_ChatChannel *newChannel); }; diff --git a/common/server_chatchannel.cpp b/common/server_chatchannel.cpp index f88a517e..2bdd8574 100644 --- a/common/server_chatchannel.cpp +++ b/common/server_chatchannel.cpp @@ -8,12 +8,12 @@ Server_ChatChannel::Server_ChatChannel(const QString &_name, const QString &_des void Server_ChatChannel::addClient(Server_ProtocolHandler *client) { - sendChatEvent(new Event_ChatJoinChannel(name, client->getPlayerName())); + sendChatEvent(new Event_ChatJoinChannel(name, new ServerInfo_User(client->getUserInfo()))); append(client); - QList eventUserList; + QList eventUserList; for (int i = 0; i < size(); ++i) - eventUserList.append(new ServerInfo_ChatUser(at(i)->getPlayerName())); + eventUserList.append(new ServerInfo_User(at(i)->getUserInfo())); Event_ChatListPlayers *eventCLP = new Event_ChatListPlayers(name, eventUserList); client->enqueueProtocolItem(eventCLP); @@ -25,13 +25,13 @@ void Server_ChatChannel::addClient(Server_ProtocolHandler *client) void Server_ChatChannel::removeClient(Server_ProtocolHandler *client) { removeAt(indexOf(client)); - sendChatEvent(new Event_ChatLeaveChannel(name, client->getPlayerName())); + sendChatEvent(new Event_ChatLeaveChannel(name, client->getUserInfo()->getName())); emit channelInfoChanged(); } void Server_ChatChannel::say(Server_ProtocolHandler *client, const QString &s) { - sendChatEvent(new Event_ChatSay(name, client->getPlayerName(), s)); + sendChatEvent(new Event_ChatSay(name, client->getUserInfo()->getName(), s)); } void Server_ChatChannel::sendChatEvent(ChatEvent *event) diff --git a/common/server_game.cpp b/common/server_game.cpp index 396a09af..2b9add86 100644 --- a/common/server_game.cpp +++ b/common/server_game.cpp @@ -28,9 +28,9 @@ #include Server_Game::Server_Game(Server_ProtocolHandler *_creator, int _gameId, const QString &_description, const QString &_password, int _maxPlayers, bool _spectatorsAllowed, bool _spectatorsNeedPassword, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, Server *parent) - : QObject(parent), gameStarted(false), gameId(_gameId), description(_description), password(_password), maxPlayers(_maxPlayers), activePlayer(-1), activePhase(-1), spectatorsAllowed(_spectatorsAllowed), spectatorsNeedPassword(_spectatorsNeedPassword), spectatorsCanTalk(_spectatorsCanTalk), spectatorsSeeEverything(_spectatorsSeeEverything), inactivityCounter(0) + : QObject(parent), creatorInfo(new ServerInfo_User(_creator->getUserInfo())), gameStarted(false), gameId(_gameId), description(_description), password(_password), maxPlayers(_maxPlayers), activePlayer(-1), activePhase(-1), spectatorsAllowed(_spectatorsAllowed), spectatorsNeedPassword(_spectatorsNeedPassword), spectatorsCanTalk(_spectatorsCanTalk), spectatorsSeeEverything(_spectatorsSeeEverything), inactivityCounter(0) { - creator = addPlayer(_creator, false, false); + addPlayer(_creator, false, false); if (parent->getGameShouldPing()) { pingClock = new QTimer(this); @@ -49,6 +49,7 @@ Server_Game::~Server_Game() players.clear(); emit gameClosing(); + delete creatorInfo; qDebug("Server_Game destructor"); } @@ -187,7 +188,7 @@ Server_Player *Server_Game::addPlayer(Server_ProtocolHandler *handler, bool spec const QList &keyList = players.keys(); int playerId = keyList.isEmpty() ? 0 : (keyList.last() + 1); - Server_Player *newPlayer = new Server_Player(this, playerId, handler->getPlayerName(), spectator, handler); + Server_Player *newPlayer = new Server_Player(this, playerId, handler->getUserInfo(), spectator, handler); sendGameEvent(new Event_Join(newPlayer->getProperties())); players.insert(playerId, newPlayer); @@ -350,8 +351,7 @@ QList Server_Game::getGameState(Server_Player *playerWhosAs zoneList.append(new ServerInfo_Zone(zone->getName(), zone->getType(), zone->hasCoords(), zone->cards.size(), cardList)); } - ServerInfo_PlayerProperties *properties = new ServerInfo_PlayerProperties(player->getPlayerId(), player->getPlayerName(), player->getSpectator(), player->getConceded(), player->getReadyStart(), player->getDeckId()); - result.append(new ServerInfo_Player(properties, player == playerWhosAsking ? player->getDeck() : 0, zoneList, counterList, arrowList)); + result.append(new ServerInfo_Player(player->getProperties(), player == playerWhosAsking ? player->getDeck() : 0, zoneList, counterList, arrowList)); } return result; } diff --git a/common/server_game.h b/common/server_game.h index 6badea77..41c52698 100644 --- a/common/server_game.h +++ b/common/server_game.h @@ -28,11 +28,12 @@ class QTimer; class Server; +class ServerInfo_User; class Server_Game : public QObject { Q_OBJECT private: - QPointer creator; + ServerInfo_User *creatorInfo; QMap players; bool gameStarted; int gameId; @@ -53,8 +54,7 @@ private slots: public: Server_Game(Server_ProtocolHandler *_creator, int _gameId, const QString &_description, const QString &_password, int _maxPlayers, bool _spectatorsAllowed, bool _spectatorsNeedPassword, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, Server *parent); ~Server_Game(); - Server_Player *getCreator() const { return creator; } - QString getCreatorName() const { return creator ? creator->getPlayerName() : QString(); } + ServerInfo_User *getCreatorInfo() const { return creatorInfo; } bool getGameStarted() const { return gameStarted; } int getPlayerCount() const; int getSpectatorCount() const; diff --git a/common/server_player.cpp b/common/server_player.cpp index 818433c0..daed7b1a 100644 --- a/common/server_player.cpp +++ b/common/server_player.cpp @@ -9,8 +9,8 @@ #include "protocol_items.h" #include "decklist.h" -Server_Player::Server_Player(Server_Game *_game, int _playerId, const QString &_playerName, bool _spectator, Server_ProtocolHandler *_handler) - : game(_game), handler(_handler), deck(0), playerId(_playerId), playerName(_playerName), spectator(_spectator), nextCardId(0), readyStart(false), conceded(false), deckId(-2) +Server_Player::Server_Player(Server_Game *_game, int _playerId, ServerInfo_User *_userInfo, bool _spectator, Server_ProtocolHandler *_handler) + : game(_game), handler(_handler), userInfo(new ServerInfo_User(_userInfo)), deck(0), playerId(_playerId), spectator(_spectator), nextCardId(0), readyStart(false), conceded(false), deckId(-2) { } @@ -20,6 +20,7 @@ Server_Player::~Server_Player() if (handler) handler->playerRemovedFromGame(game); + delete userInfo; } int Server_Player::newCardId() @@ -151,7 +152,7 @@ void Server_Player::clearZones() ServerInfo_PlayerProperties *Server_Player::getProperties() { - return new ServerInfo_PlayerProperties(playerId, playerName, spectator, conceded, readyStart, deckId); + return new ServerInfo_PlayerProperties(playerId, new ServerInfo_User(userInfo), spectator, conceded, readyStart, deckId); } void Server_Player::setDeck(DeckList *_deck, int _deckId) diff --git a/common/server_player.h b/common/server_player.h index 70ed9e4a..2381a836 100644 --- a/common/server_player.h +++ b/common/server_player.h @@ -13,6 +13,7 @@ class Server_Counter; class Server_Arrow; class Server_ProtocolHandler; class ProtocolItem; +class ServerInfo_User; class ServerInfo_PlayerProperties; class Server_Player : public Server_ArrowTarget { @@ -20,12 +21,12 @@ class Server_Player : public Server_ArrowTarget { private: Server_Game *game; Server_ProtocolHandler *handler; + ServerInfo_User *userInfo; DeckList *deck; QMap zones; QMap counters; QMap arrows; int playerId; - QString playerName; bool spectator; int initialCards; int nextCardId; @@ -33,7 +34,7 @@ private: bool conceded; int deckId; public: - Server_Player(Server_Game *_game, int _playerId, const QString &_playerName, bool _spectator, Server_ProtocolHandler *_handler); + Server_Player(Server_Game *_game, int _playerId, ServerInfo_User *_userInfo, bool _spectator, Server_ProtocolHandler *_handler); ~Server_Player(); Server_ProtocolHandler *getProtocolHandler() const { return handler; } void setProtocolHandler(Server_ProtocolHandler *_handler) { handler = _handler; } @@ -48,7 +49,7 @@ public: bool getConceded() const { return conceded; } void setConceded(bool _conceded) { conceded = _conceded; } int getDeckId() const { return deckId; } - QString getPlayerName() const { return playerName; } + ServerInfo_User *getUserInfo() const { return userInfo; } void setDeck(DeckList *_deck, int _deckId); DeckList *getDeck() const { return deck; } const QMap &getZones() const { return zones; } diff --git a/common/server_protocolhandler.cpp b/common/server_protocolhandler.cpp index 8974cf41..9e0339c8 100644 --- a/common/server_protocolhandler.cpp +++ b/common/server_protocolhandler.cpp @@ -14,7 +14,7 @@ #include Server_ProtocolHandler::Server_ProtocolHandler(Server *_server, QObject *parent) - : QObject(parent), server(_server), authState(PasswordWrong), acceptsGameListChanges(false), lastCommandTime(QDateTime::currentDateTime()) + : QObject(parent), server(_server), authState(PasswordWrong), acceptsGameListChanges(false), userInfo(0), lastCommandTime(QDateTime::currentDateTime()) { connect(server, SIGNAL(pingClockTimeout()), this, SLOT(pingClockTimeout())); } @@ -40,6 +40,8 @@ Server_ProtocolHandler::~Server_ProtocolHandler() QMapIterator chatChannelIterator(chatChannels); while (chatChannelIterator.hasNext()) chatChannelIterator.next().value()->removeClient(this); + + delete userInfo; } void Server_ProtocolHandler::playerRemovedFromGame(Server_Game *game) @@ -200,15 +202,12 @@ ResponseCode Server_ProtocolHandler::cmdPing(Command_Ping * /*cmd*/, CommandCont ResponseCode Server_ProtocolHandler::cmdLogin(Command_Login *cmd, CommandContainer *cont) { QString userName = cmd->getUsername().simplified(); - if (userName.isEmpty()) + if (userName.isEmpty() || (userInfo != 0)) return RespContextError; - authState = server->checkUserPassword(userName, cmd->getPassword()); + authState = server->loginUser(this, userName, cmd->getPassword()); if (authState == PasswordWrong) return RespWrongPassword; - if (authState == PasswordRight) - server->closeOldSession(userName); - playerName = userName; enqueueProtocolItem(new Event_ServerMessage(server->getLoginMessage())); if (authState == PasswordRight) { @@ -217,7 +216,7 @@ ResponseCode Server_ProtocolHandler::cmdLogin(Command_Login *cmd, CommandContain for (int i = 0; i < serverGames.size(); ++i) { const QList &gamePlayers = serverGames[i]->getPlayers().values(); for (int j = 0; j < gamePlayers.size(); ++j) - if (gamePlayers[j]->getPlayerName() == playerName) { + if (gamePlayers[j]->getUserInfo()->getName() == userInfo->getName()) { gamePlayers[j]->setProtocolHandler(this); games.insert(serverGames[i]->getGameId(), QPair(serverGames[i], gamePlayers[j])); @@ -293,7 +292,7 @@ ResponseCode Server_ProtocolHandler::cmdListGames(Command_ListGames * /*cmd*/, C !g->getPassword().isEmpty(), g->getPlayerCount(), g->getMaxPlayers(), - g->getCreatorName(), + g->getCreatorInfo(), g->getSpectatorsAllowed(), g->getSpectatorsNeedPassword(), g->getSpectatorCount() @@ -311,7 +310,7 @@ ResponseCode Server_ProtocolHandler::cmdCreateGame(Command_CreateGame *cmd, Comm return RespLoginNeeded; Server_Game *game = server->createGame(cmd->getDescription(), cmd->getPassword(), cmd->getMaxPlayers(), cmd->getSpectatorsAllowed(), cmd->getSpectatorsNeedPassword(), cmd->getSpectatorsCanTalk(), cmd->getSpectatorsSeeEverything(), this); - Server_Player *creator = game->getCreator(); + Server_Player *creator = game->getPlayers().values().first(); games.insert(game->getGameId(), QPair(game, creator)); enqueueProtocolItem(new Event_GameJoined(game->getGameId(), game->getDescription(), creator->getPlayerId(), false, game->getSpectatorsCanTalk(), game->getSpectatorsSeeEverything(), false)); diff --git a/common/server_protocolhandler.h b/common/server_protocolhandler.h index 637f3503..78a87c10 100644 --- a/common/server_protocolhandler.h +++ b/common/server_protocolhandler.h @@ -9,6 +9,7 @@ class Server_Player; class Server_Card; +class ServerInfo_User; class QTimer; class Server_ProtocolHandler : public QObject { @@ -17,7 +18,6 @@ protected: Server *server; QMap > games; QMap chatChannels; - QString playerName; Server *getServer() const { return server; } QPair getGame(int gameId) const; @@ -25,6 +25,7 @@ protected: AuthenticationResult authState; bool acceptsGameListChanges; bool acceptsChatChannelListChanges; + ServerInfo_User *userInfo; private: QList itemQueue; @@ -91,7 +92,8 @@ public: bool getAcceptsGameListChanges() const { return acceptsGameListChanges; } bool getAcceptsChatChannelListChanges() const { return acceptsChatChannelListChanges; } - const QString &getPlayerName() const { return playerName; } + ServerInfo_User *getUserInfo() const { return userInfo; } + void setUserInfo(ServerInfo_User *_userInfo) { userInfo = _userInfo; } const QDateTime &getLastCommandTime() const { return lastCommandTime; } void processCommandContainer(CommandContainer *cont); diff --git a/servatrice/src/main.cpp b/servatrice/src/main.cpp index 2d16cb20..00920757 100644 --- a/servatrice/src/main.cpp +++ b/servatrice/src/main.cpp @@ -48,7 +48,6 @@ void testRNG() numbers[max - minMax] = rng->makeNumbersVector(n * (max - min + 1), min, max); chisq[max - minMax] = rng->testRandom(numbers[max - minMax]); } - qDebug() << numbers; for (int i = 0; i <= maxMax - min; ++i) { std::cerr << (min + i); for (int j = 0; j < numbers.size(); ++j) { diff --git a/servatrice/src/servatrice.cpp b/servatrice/src/servatrice.cpp index 66774339..f7d49336 100644 --- a/servatrice/src/servatrice.cpp +++ b/servatrice/src/servatrice.cpp @@ -19,6 +19,7 @@ ***************************************************************************/ #include #include +#include #include "servatrice.h" #include "server_chatchannel.h" #include "serversocketinterface.h" @@ -88,7 +89,7 @@ bool Servatrice::openDatabase() if (!query.next()) return false; nextGameId = query.value(0).toInt() + 1; - qDebug(QString("set nextGameId to %1").arg(nextGameId).toLatin1()); + qDebug() << "set nextGameId to " << nextGameId; } return true; } @@ -103,7 +104,7 @@ bool Servatrice::execSqlQuery(QSqlQuery &query) { if (query.exec()) return true; - qCritical(QString("Database error: %1").arg(query.lastError().text()).toLatin1()); + qCritical() << "Database error:" << query.lastError().text(); return false; } @@ -139,4 +140,35 @@ AuthenticationResult Servatrice::checkUserPassword(const QString &user, const QS return UnknownUser; } -const QString Servatrice::versionString = "Servatrice 0.20100915"; +ServerInfo_User *Servatrice::getUserData(const QString &name) +{ + const QString method = settings->value("authentication/method").toString(); + if (method == "sql") { + checkSql(); + + QSqlQuery query; + query.prepare("select admin, country from users where name = :name"); + query.bindValue(":name", name); + if (!execSqlQuery(query)) + return new ServerInfo_User(name); + + if (query.next()) { + bool is_admin = query.value(0).toInt(); + QString country = query.value(1).toString(); + + int userLevel = ServerInfo_User::IsUser; + if (is_admin) + userLevel |= ServerInfo_User::IsAdmin; + + return new ServerInfo_User( + name, + userLevel, + country + ); + } else + return new ServerInfo_User(name); + } else + return new ServerInfo_User(name); +} + +const QString Servatrice::versionString = "Servatrice 0.20100918"; diff --git a/servatrice/src/servatrice.h b/servatrice/src/servatrice.h index a7c72a6e..055f2510 100644 --- a/servatrice/src/servatrice.h +++ b/servatrice/src/servatrice.h @@ -40,11 +40,13 @@ public: bool openDatabase(); void checkSql(); bool execSqlQuery(QSqlQuery &query); - AuthenticationResult checkUserPassword(const QString &user, const QString &password); QString getLoginMessage() const { return loginMessage; } bool getGameShouldPing() const { return true; } int getMaxGameInactivityTime() const { return maxGameInactivityTime; } int getMaxPlayerInactivityTime() const { return maxPlayerInactivityTime; } +protected: + AuthenticationResult checkUserPassword(const QString &user, const QString &password); + ServerInfo_User *getUserData(const QString &name); private: QTimer *pingClock; QTcpServer *tcpServer; diff --git a/servatrice/src/serversocketinterface.cpp b/servatrice/src/serversocketinterface.cpp index 52a75b54..aa80b95b 100644 --- a/servatrice/src/serversocketinterface.cpp +++ b/servatrice/src/serversocketinterface.cpp @@ -109,7 +109,7 @@ int ServerSocketInterface::getDeckPathId(int basePathId, QStringList path) query.prepare("select id from decklist_folders where id_parent = :id_parent and name = :name and user = :user"); query.bindValue(":id_parent", basePathId); query.bindValue(":name", path.takeFirst()); - query.bindValue(":user", playerName); + query.bindValue(":user", userInfo->getName()); if (!servatrice->execSqlQuery(query)) return -1; if (!query.next()) @@ -131,7 +131,7 @@ bool ServerSocketInterface::deckListHelper(DeckList_Directory *folder) QSqlQuery query; query.prepare("select id, name from decklist_folders where id_parent = :id_parent and user = :user"); query.bindValue(":id_parent", folder->getId()); - query.bindValue(":user", playerName); + query.bindValue(":user", userInfo->getName()); if (!servatrice->execSqlQuery(query)) return false; @@ -144,7 +144,7 @@ bool ServerSocketInterface::deckListHelper(DeckList_Directory *folder) query.prepare("select id, name, upload_time from decklist_files where id_folder = :id_folder and user = :user"); query.bindValue(":id_folder", folder->getId()); - query.bindValue(":user", playerName); + query.bindValue(":user", userInfo->getName()); if (!servatrice->execSqlQuery(query)) return false; @@ -190,7 +190,7 @@ ResponseCode ServerSocketInterface::cmdDeckNewDir(Command_DeckNewDir *cmd, Comma QSqlQuery query; query.prepare("insert into decklist_folders (id_parent, user, name) values(:id_parent, :user, :name)"); query.bindValue(":id_parent", folderId); - query.bindValue(":user", playerName); + query.bindValue(":user", userInfo->getName()); query.bindValue(":name", cmd->getDirName()); if (!servatrice->execSqlQuery(query)) return RespContextError; @@ -243,7 +243,7 @@ ResponseCode ServerSocketInterface::cmdDeckDel(Command_DeckDel *cmd, CommandCont query.prepare("select id from decklist_files where id = :id and user = :user"); query.bindValue(":id", cmd->getDeckId()); - query.bindValue(":user", playerName); + query.bindValue(":user", userInfo->getName()); servatrice->execSqlQuery(query); if (!query.next()) return RespNameNotFound; @@ -281,7 +281,7 @@ ResponseCode ServerSocketInterface::cmdDeckUpload(Command_DeckUpload *cmd, Comma QSqlQuery query; query.prepare("insert into decklist_files (id_folder, user, name, upload_time, content) values(:id_folder, :user, :name, NOW(), :content)"); query.bindValue(":id_folder", folderId); - query.bindValue(":user", playerName); + query.bindValue(":user", userInfo->getName()); query.bindValue(":name", deckName); query.bindValue(":content", deckContents); servatrice->execSqlQuery(query); @@ -298,7 +298,7 @@ DeckList *ServerSocketInterface::getDeckFromDatabase(int deckId) query.prepare("select content from decklist_files where id = :id and user = :user"); query.bindValue(":id", deckId); - query.bindValue(":user", playerName); + query.bindValue(":user", userInfo->getName()); servatrice->execSqlQuery(query); if (!query.next()) throw RespNameNotFound;