Merge branch 'devel' into servernetwork
This commit is contained in:
commit
6bbc76af2b
39 changed files with 658 additions and 147 deletions
|
@ -1,6 +1,7 @@
|
|||
<RCC>
|
||||
<qresource prefix="/" >
|
||||
<file alias="back.svg" >resources/back.svg</file>
|
||||
<file>resources/lock.svg</file>
|
||||
<file>resources/icon_delete.svg</file>
|
||||
<file>resources/icon_tab_changed.svg</file>
|
||||
<file>resources/icon_config_general.svg</file>
|
||||
|
|
103
cockatrice/resources/lock.svg
Normal file
103
cockatrice/resources/lock.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 316 KiB |
|
@ -14,6 +14,7 @@
|
|||
#include "pb/event_user_joined.pb.h"
|
||||
#include "pb/event_user_left.pb.h"
|
||||
#include "pb/event_game_joined.pb.h"
|
||||
#include "pb/event_replay_added.pb.h"
|
||||
#include "get_pb_extension.h"
|
||||
#include <google/protobuf/descriptor.h>
|
||||
|
||||
|
@ -55,6 +56,7 @@ void AbstractClient::processProtocolItem(const ServerMessage &item)
|
|||
case SessionEvent::USER_JOINED: emit userJoinedEventReceived(event.GetExtension(Event_UserJoined::ext)); break;
|
||||
case SessionEvent::USER_LEFT: emit userLeftEventReceived(event.GetExtension(Event_UserLeft::ext)); break;
|
||||
case SessionEvent::GAME_JOINED: emit gameJoinedEventReceived(event.GetExtension(Event_GameJoined::ext)); break;
|
||||
case SessionEvent::REPLAY_ADDED: emit replayAddedEventReceived(event.GetExtension(Event_ReplayAdded::ext)); break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ class Event_GameJoined;
|
|||
class Event_UserMessage;
|
||||
class Event_ConnectionClosed;
|
||||
class Event_ServerShutdown;
|
||||
class Event_ReplayAdded;
|
||||
|
||||
enum ClientStatus {
|
||||
StatusDisconnected,
|
||||
|
@ -57,6 +58,7 @@ signals:
|
|||
void userInfoChanged(const ServerInfo_User &userInfo);
|
||||
void buddyListReceived(const QList<ServerInfo_User> &buddyList);
|
||||
void ignoreListReceived(const QList<ServerInfo_User> &ignoreList);
|
||||
void replayAddedEventReceived(const Event_ReplayAdded &event);
|
||||
private:
|
||||
int nextCmdId;
|
||||
protected slots:
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include <QSettings>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QCheckBox>
|
||||
#include <QGridLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include "dlg_connect.h"
|
||||
|
@ -27,6 +28,9 @@ DlgConnect::DlgConnect(QWidget *parent)
|
|||
passwordEdit = new QLineEdit(settings.value("password").toString());
|
||||
passwordLabel->setBuddy(passwordEdit);
|
||||
passwordEdit->setEchoMode(QLineEdit::Password);
|
||||
|
||||
savePasswordCheckBox = new QCheckBox(tr("&Save password"));
|
||||
savePasswordCheckBox->setChecked(settings.value("save_password", 1).toInt());
|
||||
|
||||
okButton = new QPushButton(tr("&OK"));
|
||||
okButton->setDefault(true);
|
||||
|
@ -41,6 +45,7 @@ DlgConnect::DlgConnect(QWidget *parent)
|
|||
grid->addWidget(playernameEdit, 2, 1);
|
||||
grid->addWidget(passwordLabel, 3, 0);
|
||||
grid->addWidget(passwordEdit, 3, 1);
|
||||
grid->addWidget(savePasswordCheckBox, 4, 0, 1, 2);
|
||||
|
||||
QHBoxLayout *buttonLayout = new QHBoxLayout;
|
||||
buttonLayout->addStretch();
|
||||
|
@ -67,7 +72,8 @@ void DlgConnect::actOk()
|
|||
settings.setValue("hostname", hostEdit->text());
|
||||
settings.setValue("port", portEdit->text());
|
||||
settings.setValue("playername", playernameEdit->text());
|
||||
settings.setValue("password", passwordEdit->text());
|
||||
settings.setValue("password", savePasswordCheckBox->isChecked() ? passwordEdit->text() : QString());
|
||||
settings.setValue("save_password", savePasswordCheckBox->isChecked() ? 1 : 0);
|
||||
settings.endGroup();
|
||||
|
||||
accept();
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
class QLabel;
|
||||
class QPushButton;
|
||||
class QCheckBox;
|
||||
|
||||
class DlgConnect : public QDialog {
|
||||
Q_OBJECT
|
||||
|
@ -20,6 +21,7 @@ private slots:
|
|||
private:
|
||||
QLabel *hostLabel, *portLabel, *playernameLabel, *passwordLabel;
|
||||
QLineEdit *hostEdit, *portEdit, *playernameEdit, *passwordEdit;
|
||||
QCheckBox *savePasswordCheckBox;
|
||||
QPushButton *okButton, *cancelButton;
|
||||
};
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ private:
|
|||
Response::ResponseCode cmdDeckDownload(const Command_DeckDownload & /*cmd*/, ResponseContainer & /*rc*/) { return Response::RespFunctionNotAllowed; }
|
||||
Response::ResponseCode cmdReplayList(const Command_ReplayList & /*cmd*/, ResponseContainer & /*rc*/) { return Response::RespFunctionNotAllowed; }
|
||||
Response::ResponseCode cmdReplayDownload(const Command_ReplayDownload & /*cmd*/, ResponseContainer & /*rc*/) { return Response::RespFunctionNotAllowed; }
|
||||
Response::ResponseCode cmdReplayModifyMatch(const Command_ReplayModifyMatch &cmd, ResponseContainer &rc) { return Response::RespFunctionNotAllowed; }
|
||||
Response::ResponseCode cmdBanFromServer(const Command_BanFromServer & /*cmd*/, ResponseContainer & /*rc*/) { return Response::RespFunctionNotAllowed; }
|
||||
Response::ResponseCode cmdShutdownServer(const Command_ShutdownServer & /*cmd*/, ResponseContainer & /*rc*/) { return Response::RespFunctionNotAllowed; }
|
||||
Response::ResponseCode cmdUpdateServerMessage(const Command_UpdateServerMessage & /*cmd*/, ResponseContainer & /*rc*/) { return Response::RespFunctionNotAllowed; }
|
||||
|
|
|
@ -9,58 +9,106 @@
|
|||
#include "pb/response_replay_list.pb.h"
|
||||
#include "pb/serverinfo_replay.pb.h"
|
||||
|
||||
const int RemoteReplayList_TreeModel::numberOfColumns = 6;
|
||||
|
||||
RemoteReplayList_TreeModel::MatchNode::MatchNode(const ServerInfo_ReplayMatch &_matchInfo)
|
||||
: RemoteReplayList_TreeModel::Node(QString::fromStdString(_matchInfo.game_name())), matchInfo(_matchInfo)
|
||||
{
|
||||
for (int i = 0; i < matchInfo.replay_list_size(); ++i)
|
||||
append(new ReplayNode(matchInfo.replay_list(i), this));
|
||||
}
|
||||
|
||||
RemoteReplayList_TreeModel::MatchNode::~MatchNode()
|
||||
{
|
||||
for (int i = 0; i < size(); ++i)
|
||||
delete at(i);
|
||||
}
|
||||
|
||||
void RemoteReplayList_TreeModel::MatchNode::updateMatchInfo(const ServerInfo_ReplayMatch &_matchInfo)
|
||||
{
|
||||
matchInfo.MergeFrom(_matchInfo);
|
||||
}
|
||||
|
||||
RemoteReplayList_TreeModel::RemoteReplayList_TreeModel(AbstractClient *_client, QObject *parent)
|
||||
: QAbstractItemModel(parent), client(_client)
|
||||
{
|
||||
QFileIconProvider fip;
|
||||
dirIcon = fip.icon(QFileIconProvider::Folder);
|
||||
fileIcon = fip.icon(QFileIconProvider::File);
|
||||
lockIcon = QIcon(":/resources/lock.svg");
|
||||
|
||||
refreshTree();
|
||||
}
|
||||
|
||||
RemoteReplayList_TreeModel::~RemoteReplayList_TreeModel()
|
||||
{
|
||||
clearTree();
|
||||
}
|
||||
|
||||
int RemoteReplayList_TreeModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
return parent.isValid() ? 0 : replays.size();
|
||||
}
|
||||
|
||||
int RemoteReplayList_TreeModel::columnCount(const QModelIndex &/*parent*/) const
|
||||
{
|
||||
return 6;
|
||||
if (!parent.isValid())
|
||||
return replayMatches.size();
|
||||
|
||||
MatchNode *matchNode = dynamic_cast<MatchNode *>(static_cast<Node *>(parent.internalPointer()));
|
||||
if (matchNode)
|
||||
return matchNode->size();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
QVariant RemoteReplayList_TreeModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
if (index.column() > 5)
|
||||
if (index.column() >= numberOfColumns)
|
||||
return QVariant();
|
||||
|
||||
ServerInfo_Replay *replayInfo = static_cast<ServerInfo_Replay *>(index.internalPointer());
|
||||
switch (role) {
|
||||
case Qt::TextAlignmentRole:
|
||||
return index.column() == 0 ? Qt::AlignRight : Qt::AlignLeft;
|
||||
case Qt::DisplayRole: {
|
||||
switch (index.column()) {
|
||||
case 0: return replayInfo->game_id();
|
||||
case 1: return QString::fromStdString(replayInfo->game_name());
|
||||
case 2: return QString::fromStdString(replayInfo->replay_name());
|
||||
case 3: {
|
||||
QStringList playerList;
|
||||
for (int i = 0; i < replayInfo->player_names_size(); ++i)
|
||||
playerList.append(QString::fromStdString(replayInfo->player_names(i)));
|
||||
return playerList.join(", ");
|
||||
ReplayNode *replayNode = dynamic_cast<ReplayNode *>(static_cast<Node *>(index.internalPointer()));
|
||||
if (replayNode) {
|
||||
const ServerInfo_Replay &replayInfo = replayNode->getReplayInfo();
|
||||
switch (role) {
|
||||
case Qt::TextAlignmentRole:
|
||||
return index.column() == 0 ? Qt::AlignRight : Qt::AlignLeft;
|
||||
case Qt::DisplayRole: {
|
||||
switch (index.column()) {
|
||||
case 0: return replayInfo.replay_id();
|
||||
case 1: return QString::fromStdString(replayInfo.replay_name());
|
||||
case 5: return replayInfo.duration();
|
||||
default: return QVariant();
|
||||
}
|
||||
case 4: return QDateTime::fromTime_t(replayInfo->time_started());
|
||||
case 5: return replayInfo->length();
|
||||
default: return QVariant();
|
||||
}
|
||||
case Qt::DecorationRole:
|
||||
return index.column() == 0 ? fileIcon : QVariant();
|
||||
}
|
||||
} else {
|
||||
MatchNode *matchNode = dynamic_cast<MatchNode *>(static_cast<Node *>(index.internalPointer()));
|
||||
const ServerInfo_ReplayMatch &matchInfo = matchNode->getMatchInfo();
|
||||
switch (role) {
|
||||
case Qt::TextAlignmentRole:
|
||||
return index.column() == 0 ? Qt::AlignRight : Qt::AlignLeft;
|
||||
case Qt::DisplayRole: {
|
||||
switch (index.column()) {
|
||||
case 0: return matchInfo.game_id();
|
||||
case 1: return QString::fromStdString(matchInfo.game_name());
|
||||
case 2: {
|
||||
QStringList playerList;
|
||||
for (int i = 0; i < matchInfo.player_names_size(); ++i)
|
||||
playerList.append(QString::fromStdString(matchInfo.player_names(i)));
|
||||
return playerList.join(", ");
|
||||
}
|
||||
case 4: return QDateTime::fromTime_t(matchInfo.time_started());
|
||||
case 5: return matchInfo.length();
|
||||
default: return QVariant();
|
||||
}
|
||||
}
|
||||
case Qt::DecorationRole:
|
||||
switch (index.column()) {
|
||||
case 0: return dirIcon;
|
||||
case 3: return matchInfo.do_not_hide() ? lockIcon : QVariant();
|
||||
default: return QVariant();
|
||||
}
|
||||
}
|
||||
case Qt::DecorationRole:
|
||||
return index.column() == 0 ? fileIcon : QVariant();
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
@ -74,10 +122,10 @@ QVariant RemoteReplayList_TreeModel::headerData(int section, Qt::Orientation ori
|
|||
return section == 0 ? Qt::AlignRight : Qt::AlignLeft;
|
||||
case Qt::DisplayRole: {
|
||||
switch (section) {
|
||||
case 0: return tr("Game ID");
|
||||
case 1: return tr("Game name");
|
||||
case 2: return tr("Replay name");
|
||||
case 3: return tr("Players");
|
||||
case 0: return tr("ID");
|
||||
case 1: return tr("Name");
|
||||
case 2: return tr("Players");
|
||||
case 3: return tr("Keep");
|
||||
case 4: return tr("Time started");
|
||||
case 5: return tr("Duration (sec)");
|
||||
default: return QVariant();
|
||||
|
@ -91,13 +139,28 @@ QModelIndex RemoteReplayList_TreeModel::index(int row, int column, const QModelI
|
|||
{
|
||||
if (!hasIndex(row, column, parent))
|
||||
return QModelIndex();
|
||||
|
||||
return createIndex(row, column, (void *) &(replays[row]));
|
||||
|
||||
MatchNode *matchNode = dynamic_cast<MatchNode *>(static_cast<Node *>(parent.internalPointer()));
|
||||
if (matchNode) {
|
||||
if (row >= matchNode->size())
|
||||
return QModelIndex();
|
||||
return createIndex(row, column, (void *) matchNode->at(row));
|
||||
} else {
|
||||
if (row >= replayMatches.size())
|
||||
return QModelIndex();
|
||||
return createIndex(row, column, (void *) replayMatches[row]);
|
||||
}
|
||||
}
|
||||
|
||||
QModelIndex RemoteReplayList_TreeModel::parent(const QModelIndex &ind) const
|
||||
{
|
||||
return QModelIndex();
|
||||
MatchNode const *matchNode = dynamic_cast<MatchNode *>(static_cast<Node *>(ind.internalPointer()));
|
||||
if (matchNode)
|
||||
return QModelIndex();
|
||||
else {
|
||||
ReplayNode *replayNode = dynamic_cast<ReplayNode *>(static_cast<Node *>(ind.internalPointer()));
|
||||
return createIndex(replayNode->getParent()->indexOf(replayNode), 0, replayNode);
|
||||
}
|
||||
}
|
||||
|
||||
Qt::ItemFlags RemoteReplayList_TreeModel::flags(const QModelIndex &index) const
|
||||
|
@ -108,12 +171,37 @@ Qt::ItemFlags RemoteReplayList_TreeModel::flags(const QModelIndex &index) const
|
|||
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
||||
}
|
||||
|
||||
ServerInfo_Replay const* RemoteReplayList_TreeModel::getNode(const QModelIndex &index) const
|
||||
ServerInfo_Replay const* RemoteReplayList_TreeModel::getReplay(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return 0;
|
||||
|
||||
return &(replays[index.row()]);
|
||||
ReplayNode *node = dynamic_cast<ReplayNode *>(static_cast<Node *>(index.internalPointer()));
|
||||
if (!node)
|
||||
return 0;
|
||||
return &node->getReplayInfo();
|
||||
}
|
||||
|
||||
ServerInfo_ReplayMatch const* RemoteReplayList_TreeModel::getReplayMatch(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return 0;
|
||||
|
||||
MatchNode *node = dynamic_cast<MatchNode *>(static_cast<Node *>(index.internalPointer()));
|
||||
if (!node) {
|
||||
ReplayNode *node = dynamic_cast<ReplayNode *>(static_cast<Node *>(index.internalPointer()));
|
||||
if (!node)
|
||||
return 0;
|
||||
return &node->getParent()->getMatchInfo();
|
||||
} else
|
||||
return &node->getMatchInfo();
|
||||
}
|
||||
|
||||
void RemoteReplayList_TreeModel::clearTree()
|
||||
{
|
||||
for (int i = 0; i < replayMatches.size(); ++i)
|
||||
delete replayMatches[i];
|
||||
replayMatches.clear();
|
||||
}
|
||||
|
||||
void RemoteReplayList_TreeModel::refreshTree()
|
||||
|
@ -124,15 +212,34 @@ void RemoteReplayList_TreeModel::refreshTree()
|
|||
client->sendCommand(pend);
|
||||
}
|
||||
|
||||
void RemoteReplayList_TreeModel::addMatchInfo(const ServerInfo_ReplayMatch &matchInfo)
|
||||
{
|
||||
beginInsertRows(QModelIndex(), replayMatches.size(), replayMatches.size());
|
||||
replayMatches.append(new MatchNode(matchInfo));
|
||||
endInsertRows();
|
||||
|
||||
emit treeRefreshed();
|
||||
}
|
||||
|
||||
void RemoteReplayList_TreeModel::updateMatchInfo(int gameId, const ServerInfo_ReplayMatch &matchInfo)
|
||||
{
|
||||
for (int i = 0; i < replayMatches.size(); ++i)
|
||||
if (replayMatches[i]->getMatchInfo().game_id() == gameId) {
|
||||
replayMatches[i]->updateMatchInfo(matchInfo);
|
||||
emit dataChanged(createIndex(i, 0, (void *) replayMatches[i]), createIndex(i, numberOfColumns - 1, (void *) replayMatches[i]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteReplayList_TreeModel::replayListFinished(const Response &r)
|
||||
{
|
||||
const Response_ReplayList &resp = r.GetExtension(Response_ReplayList::ext);
|
||||
|
||||
beginResetModel();
|
||||
replays.clear();
|
||||
clearTree();
|
||||
|
||||
for (int i = 0; i < resp.replay_list_size(); ++i)
|
||||
replays.append(resp.replay_list(i));
|
||||
for (int i = 0; i < resp.match_list_size(); ++i)
|
||||
replayMatches.append(new MatchNode(resp.match_list(i)));
|
||||
|
||||
endResetModel();
|
||||
emit treeRefreshed();
|
||||
|
@ -156,12 +263,12 @@ RemoteReplayList_TreeWidget::RemoteReplayList_TreeWidget(AbstractClient *_client
|
|||
header()->setSortIndicator(0, Qt::AscendingOrder);
|
||||
}
|
||||
|
||||
ServerInfo_Replay const *RemoteReplayList_TreeWidget::getNode(const QModelIndex &ind) const
|
||||
ServerInfo_Replay const *RemoteReplayList_TreeWidget::getCurrentReplay() const
|
||||
{
|
||||
return treeModel->getNode(proxyModel->mapToSource(ind));
|
||||
return treeModel->getReplay(proxyModel->mapToSource(selectionModel()->currentIndex()));
|
||||
}
|
||||
|
||||
ServerInfo_Replay const *RemoteReplayList_TreeWidget::getCurrentItem() const
|
||||
ServerInfo_ReplayMatch const *RemoteReplayList_TreeWidget::getCurrentReplayMatch() const
|
||||
{
|
||||
return getNode(selectionModel()->currentIndex());
|
||||
return treeModel->getReplayMatch(proxyModel->mapToSource(selectionModel()->currentIndex()));
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <QDateTime>
|
||||
#include <QTreeView>
|
||||
#include "pb/serverinfo_replay.pb.h"
|
||||
#include "pb/serverinfo_replay_match.pb.h"
|
||||
|
||||
class Response;
|
||||
class AbstractClient;
|
||||
|
@ -13,10 +14,45 @@ class QSortFilterProxyModel;
|
|||
class RemoteReplayList_TreeModel : public QAbstractItemModel {
|
||||
Q_OBJECT
|
||||
private:
|
||||
AbstractClient *client;
|
||||
QList<ServerInfo_Replay> replays;
|
||||
class MatchNode;
|
||||
class ReplayNode;
|
||||
class Node {
|
||||
protected:
|
||||
QString name;
|
||||
public:
|
||||
Node(const QString &_name)
|
||||
: name(_name) { }
|
||||
virtual ~Node() { };
|
||||
QString getName() const { return name; }
|
||||
};
|
||||
class MatchNode : public Node, public QList<ReplayNode *> {
|
||||
private:
|
||||
ServerInfo_ReplayMatch matchInfo;
|
||||
public:
|
||||
MatchNode(const ServerInfo_ReplayMatch &_matchInfo);
|
||||
~MatchNode();
|
||||
void clearTree();
|
||||
const ServerInfo_ReplayMatch &getMatchInfo() { return matchInfo; }
|
||||
void updateMatchInfo(const ServerInfo_ReplayMatch &_matchInfo);
|
||||
};
|
||||
class ReplayNode : public Node {
|
||||
private:
|
||||
MatchNode *parent;
|
||||
ServerInfo_Replay replayInfo;
|
||||
public:
|
||||
ReplayNode(const ServerInfo_Replay &_replayInfo, MatchNode *_parent)
|
||||
: Node(QString::fromStdString(_replayInfo.replay_name())), parent(_parent), replayInfo(_replayInfo) { }
|
||||
MatchNode *getParent() const { return parent; }
|
||||
const ServerInfo_Replay &getReplayInfo() { return replayInfo; }
|
||||
};
|
||||
|
||||
QIcon fileIcon;
|
||||
AbstractClient *client;
|
||||
QList<MatchNode *> replayMatches;
|
||||
|
||||
QIcon dirIcon, fileIcon, lockIcon;
|
||||
void clearTree();
|
||||
|
||||
static const int numberOfColumns;
|
||||
signals:
|
||||
void treeRefreshed();
|
||||
private slots:
|
||||
|
@ -25,14 +61,17 @@ public:
|
|||
RemoteReplayList_TreeModel(AbstractClient *_client, QObject *parent = 0);
|
||||
~RemoteReplayList_TreeModel();
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
int columnCount(const QModelIndex &/*parent*/ = QModelIndex()) const;
|
||||
int columnCount(const QModelIndex &/*parent*/ = QModelIndex()) const { return numberOfColumns; }
|
||||
QVariant data(const QModelIndex &index, int role) const;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
|
||||
QModelIndex parent(const QModelIndex &index) const;
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||
void refreshTree();
|
||||
ServerInfo_Replay const *getNode(const QModelIndex &index) const;
|
||||
ServerInfo_Replay const* getReplay(const QModelIndex &index) const;
|
||||
ServerInfo_ReplayMatch const* getReplayMatch(const QModelIndex &index) const;
|
||||
void addMatchInfo(const ServerInfo_ReplayMatch &matchInfo);
|
||||
void updateMatchInfo(int gameId, const ServerInfo_ReplayMatch &matchInfo);
|
||||
};
|
||||
|
||||
class RemoteReplayList_TreeWidget : public QTreeView {
|
||||
|
@ -42,8 +81,11 @@ private:
|
|||
ServerInfo_Replay const *getNode(const QModelIndex &ind) const;
|
||||
public:
|
||||
RemoteReplayList_TreeWidget(AbstractClient *_client, QWidget *parent = 0);
|
||||
ServerInfo_Replay const *getCurrentItem() const;
|
||||
ServerInfo_Replay const *getCurrentReplay() const;
|
||||
ServerInfo_ReplayMatch const *getCurrentReplayMatch() const;
|
||||
void refreshTree();
|
||||
void addMatchInfo(const ServerInfo_ReplayMatch &matchInfo) { treeModel->addMatchInfo(matchInfo); }
|
||||
void updateMatchInfo(int gameId, const ServerInfo_ReplayMatch &matchInfo) { treeModel->updateMatchInfo(gameId, matchInfo); }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -63,6 +63,11 @@ QSize ReplayTimelineWidget::sizeHint() const
|
|||
return QSize(-1, 50);
|
||||
}
|
||||
|
||||
QSize ReplayTimelineWidget::minimumSizeHint() const
|
||||
{
|
||||
return QSize(400, 50);
|
||||
}
|
||||
|
||||
void ReplayTimelineWidget::replayTimerTimeout()
|
||||
{
|
||||
currentTime += 200;
|
||||
|
|
|
@ -27,6 +27,7 @@ public:
|
|||
ReplayTimelineWidget(QWidget *parent = 0);
|
||||
void setTimeline(const QList<int> &_replayTimeline);
|
||||
QSize sizeHint() const;
|
||||
QSize minimumSizeHint() const;
|
||||
void setTimeScaleFactor(qreal _timeScaleFactor);
|
||||
int getCurrentEvent() const { return currentEvent; }
|
||||
public slots:
|
||||
|
|
|
@ -198,7 +198,7 @@ void DeckViewContainer::setDeck(DeckList *deck)
|
|||
deckView->setDeck(deck);
|
||||
readyStartButton->setEnabled(true);
|
||||
}
|
||||
#include <QDebug>
|
||||
|
||||
TabGame::TabGame(GameReplay *_replay)
|
||||
: Tab(0),
|
||||
hostId(-1),
|
||||
|
@ -213,6 +213,8 @@ TabGame::TabGame(GameReplay *_replay)
|
|||
replay(_replay),
|
||||
currentReplayStep(0)
|
||||
{
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
gameId = replay->game_info().game_id();
|
||||
gameDescription = QString::fromStdString(replay->game_info().description());
|
||||
|
||||
|
@ -323,12 +325,13 @@ TabGame::TabGame(GameReplay *_replay)
|
|||
aNextTurn = 0;
|
||||
aRemoveLocalArrows = 0;
|
||||
aConcede = 0;
|
||||
aLeaveGame = new QAction(this);
|
||||
connect(aLeaveGame, SIGNAL(triggered()), this, SLOT(actLeaveGame()));
|
||||
aLeaveGame = 0;
|
||||
aCloseReplay = new QAction(this);
|
||||
connect(aCloseReplay, SIGNAL(triggered()), this, SLOT(actLeaveGame()));
|
||||
|
||||
phasesMenu = 0;
|
||||
tabMenu = new QMenu(this);
|
||||
tabMenu->addAction(aLeaveGame);
|
||||
tabMenu->addAction(aCloseReplay);
|
||||
|
||||
retranslateUi();
|
||||
setLayout(superMainLayout);
|
||||
|
@ -424,6 +427,7 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, QList<AbstractClient *> &_client
|
|||
connect(aConcede, SIGNAL(triggered()), this, SLOT(actConcede()));
|
||||
aLeaveGame = new QAction(this);
|
||||
connect(aLeaveGame, SIGNAL(triggered()), this, SLOT(actLeaveGame()));
|
||||
aCloseReplay = 0;
|
||||
|
||||
phasesMenu = new QMenu(this);
|
||||
for (int i = 0; i < phasesToolbar->phaseCount(); ++i) {
|
||||
|
@ -502,8 +506,14 @@ void TabGame::retranslateUi()
|
|||
aConcede->setText(tr("&Concede"));
|
||||
aConcede->setShortcut(tr("F2"));
|
||||
}
|
||||
aLeaveGame->setText(tr("&Leave game"));
|
||||
aLeaveGame->setShortcut(tr("Ctrl+Q"));
|
||||
if (aLeaveGame) {
|
||||
aLeaveGame->setText(tr("&Leave game"));
|
||||
aLeaveGame->setShortcut(tr("Ctrl+Q"));
|
||||
}
|
||||
if (aCloseReplay) {
|
||||
aCloseReplay->setText(tr("C&lose replay"));
|
||||
aCloseReplay->setShortcut(tr("Ctrl+Q"));
|
||||
}
|
||||
|
||||
if (sayLabel)
|
||||
sayLabel->setText(tr("&Say:"));
|
||||
|
@ -613,8 +623,9 @@ void TabGame::actLeaveGame()
|
|||
if (!spectator)
|
||||
if (QMessageBox::question(this, tr("Leave game"), tr("Are you sure you want to leave this game?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) != QMessageBox::Yes)
|
||||
return;
|
||||
|
||||
sendGameCommand(Command_LeaveGame());
|
||||
|
||||
if (!replay)
|
||||
sendGameCommand(Command_LeaveGame());
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
|
|
|
@ -134,7 +134,7 @@ private:
|
|||
ZoneViewLayout *zoneLayout;
|
||||
QAction *playersSeparator;
|
||||
QMenu *phasesMenu;
|
||||
QAction *aConcede, *aLeaveGame, *aNextPhase, *aNextTurn, *aRemoveLocalArrows;
|
||||
QAction *aConcede, *aLeaveGame, *aCloseReplay, *aNextPhase, *aNextTurn, *aRemoveLocalArrows;
|
||||
QList<QAction *> phaseActions;
|
||||
|
||||
Player *addPlayer(int playerId, const ServerInfo_User &info);
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include "pb/response.pb.h"
|
||||
#include "pb/response_replay_download.pb.h"
|
||||
#include "pb/command_replay_download.pb.h"
|
||||
#include "pb/command_replay_modify_match.pb.h"
|
||||
#include "pb/event_replay_added.pb.h"
|
||||
|
||||
TabReplays::TabReplays(TabSupervisor *_tabSupervisor, AbstractClient *_client)
|
||||
: Tab(_tabSupervisor), client(_client)
|
||||
|
@ -83,13 +85,19 @@ TabReplays::TabReplays(TabSupervisor *_tabSupervisor, AbstractClient *_client)
|
|||
aDownload = new QAction(this);
|
||||
aDownload->setIcon(QIcon(":/resources/arrow_left_green.svg"));
|
||||
connect(aDownload, SIGNAL(triggered()), this, SLOT(actDownload()));
|
||||
aKeep = new QAction(this);
|
||||
aKeep->setIcon(QIcon(":/resources/lock.svg"));
|
||||
connect(aKeep, SIGNAL(triggered()), this, SLOT(actKeepRemoteReplay()));
|
||||
|
||||
leftToolBar->addAction(aOpenLocalReplay);
|
||||
rightToolBar->addAction(aOpenRemoteReplay);
|
||||
rightToolBar->addAction(aDownload);
|
||||
rightToolBar->addAction(aKeep);
|
||||
|
||||
retranslateUi();
|
||||
setLayout(hbox);
|
||||
|
||||
connect(client, SIGNAL(replayAddedEventReceived(const Event_ReplayAdded &)), this, SLOT(replayAddedEventReceived(const Event_ReplayAdded &)));
|
||||
}
|
||||
|
||||
void TabReplays::retranslateUi()
|
||||
|
@ -100,6 +108,7 @@ void TabReplays::retranslateUi()
|
|||
aOpenLocalReplay->setText(tr("Watch replay"));
|
||||
aOpenRemoteReplay->setText(tr("Watch replay"));
|
||||
aDownload->setText(tr("Download replay"));
|
||||
aKeep->setText(tr("Toggle expiration lock"));
|
||||
}
|
||||
|
||||
void TabReplays::actOpenLocalReplay()
|
||||
|
@ -123,12 +132,12 @@ void TabReplays::actOpenLocalReplay()
|
|||
|
||||
void TabReplays::actOpenRemoteReplay()
|
||||
{
|
||||
ServerInfo_Replay const *curRight = serverDirView->getCurrentItem();
|
||||
ServerInfo_Replay const *curRight = serverDirView->getCurrentReplay();
|
||||
if (!curRight)
|
||||
return;
|
||||
|
||||
Command_ReplayDownload cmd;
|
||||
cmd.set_game_id(curRight->game_id());
|
||||
cmd.set_replay_id(curRight->replay_id());
|
||||
|
||||
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
||||
connect(pend, SIGNAL(finished(const Response &)), this, SLOT(openRemoteReplayFinished(const Response &)));
|
||||
|
@ -156,13 +165,13 @@ void TabReplays::actDownload()
|
|||
filePath = localDirModel->filePath(curLeft);
|
||||
}
|
||||
|
||||
ServerInfo_Replay const *curRight = serverDirView->getCurrentItem();
|
||||
ServerInfo_Replay const *curRight = serverDirView->getCurrentReplay();
|
||||
if (!curRight)
|
||||
return;
|
||||
filePath += QString("/game_%1.cor").arg(curRight->game_id());
|
||||
filePath += QString("/replay_%1.cor").arg(curRight->replay_id());
|
||||
|
||||
Command_ReplayDownload cmd;
|
||||
cmd.set_game_id(curRight->game_id());
|
||||
cmd.set_replay_id(curRight->replay_id());
|
||||
|
||||
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
||||
pend->setExtraData(filePath);
|
||||
|
@ -183,3 +192,37 @@ void TabReplays::downloadFinished(const Response &r)
|
|||
f.write((const char *) data.data(), data.size());
|
||||
f.close();
|
||||
}
|
||||
|
||||
void TabReplays::actKeepRemoteReplay()
|
||||
{
|
||||
ServerInfo_ReplayMatch const *curRight = serverDirView->getCurrentReplayMatch();
|
||||
if (!curRight)
|
||||
return;
|
||||
|
||||
Command_ReplayModifyMatch cmd;
|
||||
cmd.set_game_id(curRight->game_id());
|
||||
cmd.set_do_not_hide(!curRight->do_not_hide());
|
||||
|
||||
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
||||
connect(pend, SIGNAL(finished(const Response &)), this, SLOT(keepRemoteReplayFinished(const Response &)));
|
||||
client->sendCommand(pend);
|
||||
}
|
||||
|
||||
void TabReplays::keepRemoteReplayFinished(const Response &r)
|
||||
{
|
||||
if (r.response_code() != Response::RespOk)
|
||||
return;
|
||||
|
||||
PendingCommand *pend = static_cast<PendingCommand *>(sender());
|
||||
const Command_ReplayModifyMatch &cmd = pend->getCommandContainer().session_command(0).GetExtension(Command_ReplayModifyMatch::ext);
|
||||
|
||||
ServerInfo_ReplayMatch temp;
|
||||
temp.set_do_not_hide(cmd.do_not_hide());
|
||||
|
||||
serverDirView->updateMatchInfo(cmd.game_id(), temp);
|
||||
}
|
||||
|
||||
void TabReplays::replayAddedEventReceived(const Event_ReplayAdded &event)
|
||||
{
|
||||
serverDirView->addMatchInfo(event.match_info());
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
#define TAB_REPLAYS_H
|
||||
|
||||
#include "tab.h"
|
||||
#include "pb/response.pb.h"
|
||||
|
||||
class Response;
|
||||
class AbstractClient;
|
||||
class QTreeView;
|
||||
class QFileSystemModel;
|
||||
|
@ -12,6 +12,7 @@ class QToolBar;
|
|||
class QGroupBox;
|
||||
class RemoteReplayList_TreeWidget;
|
||||
class GameReplay;
|
||||
class Event_ReplayAdded;
|
||||
|
||||
class TabReplays : public Tab {
|
||||
Q_OBJECT
|
||||
|
@ -24,7 +25,7 @@ private:
|
|||
RemoteReplayList_TreeWidget *serverDirView;
|
||||
QGroupBox *leftGroupBox, *rightGroupBox;
|
||||
|
||||
QAction *aOpenLocalReplay, *aOpenRemoteReplay, *aDownload;
|
||||
QAction *aOpenLocalReplay, *aOpenRemoteReplay, *aDownload, *aKeep;
|
||||
private slots:
|
||||
void actOpenLocalReplay();
|
||||
|
||||
|
@ -33,6 +34,11 @@ private slots:
|
|||
|
||||
void actDownload();
|
||||
void downloadFinished(const Response &r);
|
||||
|
||||
void actKeepRemoteReplay();
|
||||
void keepRemoteReplayFinished(const Response &r);
|
||||
|
||||
void replayAddedEventReceived(const Event_ReplayAdded &event);
|
||||
signals:
|
||||
void openReplay(GameReplay *replay);
|
||||
public:
|
||||
|
|
|
@ -209,6 +209,11 @@ void TabSupervisor::stop()
|
|||
gameIterator.next().value()->deleteLater();
|
||||
gameTabs.clear();
|
||||
|
||||
QListIterator<TabGame *> replayIterator(replayTabs);
|
||||
while (replayIterator.hasNext())
|
||||
replayIterator.next()->deleteLater();
|
||||
replayTabs.clear();
|
||||
|
||||
QMapIterator<QString, TabMessage *> messageIterator(messageTabs);
|
||||
while (messageIterator.hasNext())
|
||||
messageIterator.next().value()->deleteLater();
|
||||
|
@ -272,7 +277,8 @@ void TabSupervisor::localGameJoined(const Event_GameJoined &event)
|
|||
|
||||
void TabSupervisor::gameLeft(TabGame *tab)
|
||||
{
|
||||
emit setMenu(0);
|
||||
if (tab == currentWidget())
|
||||
emit setMenu(0);
|
||||
|
||||
gameTabs.remove(tab->getGameId());
|
||||
removeTab(indexOf(tab));
|
||||
|
@ -295,12 +301,31 @@ void TabSupervisor::addRoomTab(const ServerInfo_Room &info, bool setCurrent)
|
|||
|
||||
void TabSupervisor::roomLeft(TabRoom *tab)
|
||||
{
|
||||
emit setMenu(0);
|
||||
|
||||
if (tab == currentWidget())
|
||||
emit setMenu(0);
|
||||
|
||||
roomTabs.remove(tab->getRoomId());
|
||||
removeTab(indexOf(tab));
|
||||
}
|
||||
|
||||
void TabSupervisor::openReplay(GameReplay *replay)
|
||||
{
|
||||
TabGame *replayTab = new TabGame(replay);
|
||||
connect(replayTab, SIGNAL(gameClosing(TabGame *)), this, SLOT(replayLeft(TabGame *)));
|
||||
int tabIndex = myAddTab(replayTab);
|
||||
addCloseButtonToTab(replayTab, tabIndex);
|
||||
replayTabs.append(replayTab);
|
||||
setCurrentWidget(replayTab);
|
||||
}
|
||||
|
||||
void TabSupervisor::replayLeft(TabGame *tab)
|
||||
{
|
||||
if (tab == currentWidget())
|
||||
emit setMenu(0);
|
||||
|
||||
replayTabs.removeAt(replayTabs.indexOf(tab));
|
||||
}
|
||||
|
||||
TabMessage *TabSupervisor::addMessageTab(const QString &receiverName, bool focus)
|
||||
{
|
||||
if (receiverName == QString::fromStdString(userInfo->name()))
|
||||
|
@ -316,15 +341,10 @@ TabMessage *TabSupervisor::addMessageTab(const QString &receiverName, bool focus
|
|||
return tab;
|
||||
}
|
||||
|
||||
void TabSupervisor::openReplay(GameReplay *replay)
|
||||
{
|
||||
TabGame *replayTab = new TabGame(replay);
|
||||
myAddTab(replayTab);
|
||||
}
|
||||
|
||||
void TabSupervisor::talkLeft(TabMessage *tab)
|
||||
{
|
||||
emit setMenu(0);
|
||||
if (tab == currentWidget())
|
||||
emit setMenu(0);
|
||||
|
||||
messageTabs.remove(tab->getUserName());
|
||||
removeTab(indexOf(tab));
|
||||
|
|
|
@ -50,6 +50,7 @@ private:
|
|||
TabAdmin *tabAdmin;
|
||||
QMap<int, TabRoom *> roomTabs;
|
||||
QMap<int, TabGame *> gameTabs;
|
||||
QList<TabGame *> replayTabs;
|
||||
QMap<QString, TabMessage *> messageTabs;
|
||||
int myAddTab(Tab *tab);
|
||||
void addCloseButtonToTab(Tab *tab, int tabIndex);
|
||||
|
@ -81,6 +82,7 @@ private slots:
|
|||
void roomLeft(TabRoom *tab);
|
||||
TabMessage *addMessageTab(const QString &userName, bool focus);
|
||||
void openReplay(GameReplay *replay);
|
||||
void replayLeft(TabGame *tab);
|
||||
void processUserLeft(const QString &userName);
|
||||
void processUserJoined(const QString &userName);
|
||||
void talkLeft(TabMessage *tab);
|
||||
|
|
|
@ -38,6 +38,8 @@ void SearchLineEdit::keyPressEvent(QKeyEvent *event)
|
|||
WndDeckEditor::WndDeckEditor(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
{
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
aSearch = new QAction(tr("&Search..."), this);
|
||||
aSearch->setIcon(QIcon(":/resources/icon_search.svg"));
|
||||
connect(aSearch, SIGNAL(triggered()), this, SLOT(actSearch()));
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
[Dolphin]
|
||||
Timestamp=2012,1,1,23,11,32
|
||||
Timestamp=2012,3,4,11,22,24
|
||||
Version=2
|
||||
ViewMode=1
|
||||
|
|
|
@ -32,6 +32,7 @@ SET(PROTO_FILES
|
|||
command_ready_start.proto
|
||||
command_replay_list.proto
|
||||
command_replay_download.proto
|
||||
command_replay_modify_match.proto
|
||||
command_reveal_cards.proto
|
||||
command_roll_die.proto
|
||||
command_set_active_phase.proto
|
||||
|
@ -78,6 +79,7 @@ SET(PROTO_FILES
|
|||
event_move_card.proto
|
||||
event_player_properties_changed.proto
|
||||
event_remove_from_list.proto
|
||||
event_replay_added.proto
|
||||
event_reveal_cards.proto
|
||||
event_roll_die.proto
|
||||
event_room_say.proto
|
||||
|
@ -126,6 +128,7 @@ SET(PROTO_FILES
|
|||
serverinfo_playerproperties.proto
|
||||
serverinfo_player.proto
|
||||
serverinfo_replay.proto
|
||||
serverinfo_replay_match.proto
|
||||
serverinfo_room.proto
|
||||
serverinfo_user.proto
|
||||
serverinfo_zone.proto
|
||||
|
|
|
@ -4,5 +4,5 @@ message Command_ReplayDownload {
|
|||
extend SessionCommand {
|
||||
optional Command_ReplayDownload ext = 1101;
|
||||
}
|
||||
optional sint32 game_id = 1 [default = -1];
|
||||
optional sint32 replay_id = 1 [default = -1];
|
||||
}
|
||||
|
|
10
common/pb/command_replay_modify_match.proto
Normal file
10
common/pb/command_replay_modify_match.proto
Normal file
|
@ -0,0 +1,10 @@
|
|||
import "session_commands.proto";
|
||||
|
||||
message Command_ReplayModifyMatch {
|
||||
extend SessionCommand {
|
||||
optional Command_ReplayModifyMatch ext = 1102;
|
||||
}
|
||||
optional sint32 game_id = 1 [default = -1];
|
||||
optional bool do_not_hide = 2;
|
||||
}
|
||||
|
9
common/pb/event_replay_added.proto
Normal file
9
common/pb/event_replay_added.proto
Normal file
|
@ -0,0 +1,9 @@
|
|||
import "session_event.proto";
|
||||
import "serverinfo_replay_match.proto";
|
||||
|
||||
message Event_ReplayAdded {
|
||||
extend SessionEvent {
|
||||
optional Event_ReplayAdded ext = 1100;
|
||||
}
|
||||
optional ServerInfo_ReplayMatch match_info = 1;
|
||||
}
|
|
@ -2,6 +2,8 @@ import "serverinfo_game.proto";
|
|||
import "game_event_container.proto";
|
||||
|
||||
message GameReplay {
|
||||
optional ServerInfo_Game game_info = 1;
|
||||
repeated GameEventContainer event_list = 2;
|
||||
optional uint64 replay_id = 1;
|
||||
optional ServerInfo_Game game_info = 2;
|
||||
repeated GameEventContainer event_list = 3;
|
||||
optional uint32 duration_seconds = 4;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import "response.proto";
|
||||
import "serverinfo_replay.proto";
|
||||
import "serverinfo_replay_match.proto";
|
||||
|
||||
message Response_ReplayList {
|
||||
extend Response {
|
||||
optional Response_ReplayList ext = 1100;
|
||||
}
|
||||
repeated ServerInfo_Replay replay_list = 1;
|
||||
repeated ServerInfo_ReplayMatch match_list = 1;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
message ServerInfo_Replay {
|
||||
optional sint32 game_id = 1 [default = -1];
|
||||
optional string room_name = 2;
|
||||
optional uint32 time_started = 3;
|
||||
optional uint32 length = 4;
|
||||
optional string game_name = 5;
|
||||
optional string replay_name = 6;
|
||||
repeated string player_names = 7;
|
||||
optional sint32 replay_id = 1 [default = -1];
|
||||
optional string replay_name = 2;
|
||||
optional uint32 duration = 3;
|
||||
}
|
||||
|
|
13
common/pb/serverinfo_replay_match.proto
Normal file
13
common/pb/serverinfo_replay_match.proto
Normal file
|
@ -0,0 +1,13 @@
|
|||
import "serverinfo_replay.proto";
|
||||
|
||||
message ServerInfo_ReplayMatch {
|
||||
repeated ServerInfo_Replay replay_list = 1;
|
||||
|
||||
optional sint32 game_id = 2 [default = -1];
|
||||
optional string room_name = 3;
|
||||
optional uint32 time_started = 4;
|
||||
optional uint32 length = 5;
|
||||
optional string game_name = 6;
|
||||
repeated string player_names = 7;
|
||||
optional bool do_not_hide = 8;
|
||||
}
|
|
@ -18,6 +18,7 @@ message SessionCommand {
|
|||
JOIN_ROOM = 1015;
|
||||
REPLAY_LIST = 1100;
|
||||
REPLAY_DOWNLOAD = 1101;
|
||||
REPLAY_MODIFY_MATCH = 1102;
|
||||
}
|
||||
extensions 100 to max;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ message SessionEvent {
|
|||
USER_JOINED = 1007;
|
||||
USER_LEFT = 1008;
|
||||
GAME_JOINED = 1009;
|
||||
REPLAY_ADDED = 1100;
|
||||
}
|
||||
extensions 100 to max;
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#include <QDebug>
|
||||
|
||||
Server::Server(QObject *parent)
|
||||
: QObject(parent), serverMutex(QMutex::Recursive), nextGameId(0)
|
||||
: QObject(parent), serverMutex(QMutex::Recursive), nextGameId(0), nextReplayId(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ public:
|
|||
AuthenticationResult loginUser(Server_ProtocolHandler *session, QString &name, const QString &password, QString &reason);
|
||||
const QMap<int, Server_Room *> &getRooms() { return rooms; }
|
||||
int getNextGameId() { return nextGameId++; }
|
||||
int getNextReplayId() { return nextReplayId++; }
|
||||
|
||||
const QMap<QString, Server_ProtocolHandler *> &getUsers() const { return users; }
|
||||
void addClient(Server_ProtocolHandler *player);
|
||||
|
@ -48,7 +49,7 @@ public:
|
|||
virtual bool isInBuddyList(const QString &whoseList, const QString &who) { return false; }
|
||||
virtual bool isInIgnoreList(const QString &whoseList, const QString &who) { return false; }
|
||||
|
||||
virtual void storeGameInformation(int secondsElapsed, const QSet<QString> &allPlayersEver, const QSet<QString> &allSpectatorsEver, const GameReplay &replay) { }
|
||||
virtual void storeGameInformation(int secondsElapsed, const QSet<QString> &allPlayersEver, const QSet<QString> &allSpectatorsEver, const QList<GameReplay *> &replays) { }
|
||||
protected:
|
||||
void prepareDestroy();
|
||||
QList<Server_ProtocolHandler *> clients;
|
||||
|
@ -62,7 +63,7 @@ protected:
|
|||
virtual ServerInfo_User getUserData(const QString &name, bool withId = false) = 0;
|
||||
int getUsersCount() const;
|
||||
int getGamesCount() const;
|
||||
int nextGameId;
|
||||
int nextGameId, nextReplayId;
|
||||
void addRoom(Server_Room *newRoom);
|
||||
};
|
||||
|
||||
|
|
|
@ -45,14 +45,16 @@
|
|||
#include <QDebug>
|
||||
|
||||
Server_Game::Server_Game(Server_ProtocolHandler *_creator, int _gameId, const QString &_description, const QString &_password, int _maxPlayers, const QList<int> &_gameTypes, bool _onlyBuddies, bool _onlyRegistered, bool _spectatorsAllowed, bool _spectatorsNeedPassword, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, Server_Room *_room)
|
||||
: QObject(), room(_room), hostId(0), creatorInfo(new ServerInfo_User(_creator->copyUserInfo(false))), gameStarted(false), gameId(_gameId), description(_description), password(_password), maxPlayers(_maxPlayers), gameTypes(_gameTypes), activePlayer(-1), activePhase(-1), onlyBuddies(_onlyBuddies), onlyRegistered(_onlyRegistered), spectatorsAllowed(_spectatorsAllowed), spectatorsNeedPassword(_spectatorsNeedPassword), spectatorsCanTalk(_spectatorsCanTalk), spectatorsSeeEverything(_spectatorsSeeEverything), inactivityCounter(0), secondsElapsed(0), startTime(QDateTime::currentDateTime()), gameMutex(QMutex::Recursive)
|
||||
: QObject(), room(_room), hostId(0), creatorInfo(new ServerInfo_User(_creator->copyUserInfo(false))), gameStarted(false), gameId(_gameId), description(_description), password(_password), maxPlayers(_maxPlayers), gameTypes(_gameTypes), activePlayer(-1), activePhase(-1), onlyBuddies(_onlyBuddies), onlyRegistered(_onlyRegistered), spectatorsAllowed(_spectatorsAllowed), spectatorsNeedPassword(_spectatorsNeedPassword), spectatorsCanTalk(_spectatorsCanTalk), spectatorsSeeEverything(_spectatorsSeeEverything), inactivityCounter(0), startTimeOfThisGame(0), secondsElapsed(0), firstGameStarted(false), startTime(QDateTime::currentDateTime()), gameMutex(QMutex::Recursive)
|
||||
{
|
||||
replay = new GameReplay;
|
||||
currentReplay = new GameReplay;
|
||||
currentReplay->set_replay_id(room->getServer()->getNextReplayId());
|
||||
|
||||
connect(this, SIGNAL(sigStartGameIfReady()), this, SLOT(doStartGameIfReady()), Qt::QueuedConnection);
|
||||
|
||||
addPlayer(_creator, false, false);
|
||||
replay->mutable_game_info()->CopyFrom(getInfo());
|
||||
|
||||
currentReplay->mutable_game_info()->CopyFrom(getInfo());
|
||||
|
||||
if (room->getServer()->getGameShouldPing()) {
|
||||
pingClock = new QTimer(this);
|
||||
|
@ -80,8 +82,12 @@ Server_Game::~Server_Game()
|
|||
gameMutex.unlock();
|
||||
room->roomMutex.unlock();
|
||||
|
||||
room->getServer()->storeGameInformation(secondsElapsed, allPlayersEver, allSpectatorsEver, *replay);
|
||||
delete replay;
|
||||
currentReplay->set_duration_seconds(secondsElapsed - startTimeOfThisGame);
|
||||
replayList.append(currentReplay);
|
||||
room->getServer()->storeGameInformation(secondsElapsed, allPlayersEver, allSpectatorsEver, replayList);
|
||||
|
||||
for (int i = 0; i < replayList.size(); ++i)
|
||||
delete replayList[i];
|
||||
|
||||
qDebug() << "Server_Game destructor: gameId=" << gameId;
|
||||
}
|
||||
|
@ -176,9 +182,9 @@ void Server_Game::sendGameStateToPlayers()
|
|||
omniscientEvent.add_player_list()->CopyFrom(omniscientGameStateIterator.next());
|
||||
|
||||
GameEventContainer *replayCont = prepareGameEvent(omniscientEvent, -1);
|
||||
replayCont->set_seconds_elapsed(secondsElapsed);
|
||||
replayCont->set_seconds_elapsed(secondsElapsed - startTimeOfThisGame);
|
||||
replayCont->clear_game_id();
|
||||
replay->add_event_list()->CopyFrom(*replayCont);
|
||||
currentReplay->add_event_list()->CopyFrom(*replayCont);
|
||||
delete replayCont;
|
||||
|
||||
// If spectators are not omniscient, we need an additional getGameState call, otherwise we can use the data we used for the replay.
|
||||
|
@ -237,6 +243,28 @@ void Server_Game::doStartGameIfReady()
|
|||
player->setReadyStart(false);
|
||||
}
|
||||
|
||||
if (firstGameStarted) {
|
||||
currentReplay->set_duration_seconds(secondsElapsed - startTimeOfThisGame);
|
||||
replayList.append(currentReplay);
|
||||
currentReplay = new GameReplay;
|
||||
currentReplay->set_replay_id(room->getServer()->getNextReplayId());
|
||||
currentReplay->mutable_game_info()->CopyFrom(getInfo());
|
||||
|
||||
Event_GameStateChanged omniscientEvent;
|
||||
QListIterator<ServerInfo_Player> omniscientGameStateIterator(getGameState(0, true, true));
|
||||
while (omniscientGameStateIterator.hasNext())
|
||||
omniscientEvent.add_player_list()->CopyFrom(omniscientGameStateIterator.next());
|
||||
|
||||
GameEventContainer *replayCont = prepareGameEvent(omniscientEvent, -1);
|
||||
replayCont->set_seconds_elapsed(0);
|
||||
replayCont->clear_game_id();
|
||||
currentReplay->add_event_list()->CopyFrom(*replayCont);
|
||||
delete replayCont;
|
||||
|
||||
startTimeOfThisGame = secondsElapsed;
|
||||
} else
|
||||
firstGameStarted = true;
|
||||
|
||||
sendGameStateToPlayers();
|
||||
|
||||
activePlayer = -1;
|
||||
|
@ -624,9 +652,9 @@ void Server_Game::sendGameEventContainer(GameEventContainer *cont, GameEventStor
|
|||
p->sendGameEvent(*cont);
|
||||
}
|
||||
if (recipients.testFlag(GameEventStorageItem::SendToPrivate)) {
|
||||
cont->set_seconds_elapsed(secondsElapsed);
|
||||
cont->set_seconds_elapsed(secondsElapsed - startTimeOfThisGame);
|
||||
cont->clear_game_id();
|
||||
replay->add_event_list()->CopyFrom(*cont);
|
||||
currentReplay->add_event_list()->CopyFrom(*cont);
|
||||
}
|
||||
|
||||
delete cont;
|
||||
|
|
|
@ -59,10 +59,12 @@ private:
|
|||
bool spectatorsCanTalk;
|
||||
bool spectatorsSeeEverything;
|
||||
int inactivityCounter;
|
||||
int secondsElapsed;
|
||||
int startTimeOfThisGame, secondsElapsed;
|
||||
bool firstGameStarted;
|
||||
QDateTime startTime;
|
||||
QTimer *pingClock;
|
||||
GameReplay *replay;
|
||||
QList<GameReplay *> replayList;
|
||||
GameReplay *currentReplay;
|
||||
signals:
|
||||
void sigStartGameIfReady();
|
||||
private slots:
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include "pb/command_deck_del.pb.h"
|
||||
#include "pb/command_replay_list.pb.h"
|
||||
#include "pb/command_replay_download.pb.h"
|
||||
#include "pb/command_replay_modify_match.pb.h"
|
||||
#include "pb/response.pb.h"
|
||||
#include "pb/response_login.pb.h"
|
||||
#include "pb/response_list_users.pb.h"
|
||||
|
@ -241,6 +242,7 @@ Response::ResponseCode Server_ProtocolHandler::processSessionCommandContainer(co
|
|||
case SessionCommand::DECK_DOWNLOAD: resp = cmdDeckDownload(sc.GetExtension(Command_DeckDownload::ext), rc); break;
|
||||
case SessionCommand::REPLAY_LIST: resp = cmdReplayList(sc.GetExtension(Command_ReplayList::ext), rc); break;
|
||||
case SessionCommand::REPLAY_DOWNLOAD: resp = cmdReplayDownload(sc.GetExtension(Command_ReplayDownload::ext), rc); break;
|
||||
case SessionCommand::REPLAY_MODIFY_MATCH: resp = cmdReplayModifyMatch(sc.GetExtension(Command_ReplayModifyMatch::ext), rc); break;
|
||||
case SessionCommand::GET_GAMES_OF_USER: resp = cmdGetGamesOfUser(sc.GetExtension(Command_GetGamesOfUser::ext), rc); break;
|
||||
case SessionCommand::GET_USER_INFO: resp = cmdGetUserInfo(sc.GetExtension(Command_GetUserInfo::ext), rc); break;
|
||||
case SessionCommand::LIST_ROOMS: resp = cmdListRooms(sc.GetExtension(Command_ListRooms::ext), rc); break;
|
||||
|
|
|
@ -41,6 +41,7 @@ class Command_DeckDownload;
|
|||
class Command_DeckUpload;
|
||||
class Command_ReplayList;
|
||||
class Command_ReplayDownload;
|
||||
class Command_ReplayModifyMatch;
|
||||
class Command_ListRooms;
|
||||
class Command_JoinRoom;
|
||||
class Command_LeaveRoom;
|
||||
|
@ -123,6 +124,7 @@ private:
|
|||
virtual Response::ResponseCode cmdDeckDownload(const Command_DeckDownload &cmd, ResponseContainer &rc) = 0;
|
||||
virtual Response::ResponseCode cmdReplayList(const Command_ReplayList &cmd, ResponseContainer &rc) = 0;
|
||||
virtual Response::ResponseCode cmdReplayDownload(const Command_ReplayDownload &cmd, ResponseContainer &rc) = 0;
|
||||
virtual Response::ResponseCode cmdReplayModifyMatch(const Command_ReplayModifyMatch &cmd, ResponseContainer &rc) = 0;
|
||||
Response::ResponseCode cmdGetGamesOfUser(const Command_GetGamesOfUser &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdGetUserInfo(const Command_GetUserInfo &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdListRooms(const Command_ListRooms &cmd, ResponseContainer &rc);
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "main.h"
|
||||
#include "passwordhasher.h"
|
||||
#include "pb/game_replay.pb.h"
|
||||
#include "pb/event_replay_added.pb.h"
|
||||
#include "pb/event_server_message.pb.h"
|
||||
#include "pb/event_server_shutdown.pb.h"
|
||||
#include "pb/event_connection_closed.pb.h"
|
||||
|
@ -203,6 +204,15 @@ bool Servatrice::openDatabase()
|
|||
nextGameId = query.value(0).toInt() + 1;
|
||||
qDebug() << "set nextGameId to " << nextGameId;
|
||||
}
|
||||
if (!nextReplayId) {
|
||||
QSqlQuery query;
|
||||
if (!query.exec("select max(id) from " + dbPrefix + "_replays"))
|
||||
return false;
|
||||
if (!query.next())
|
||||
return false;
|
||||
nextReplayId = query.value(0).toInt() + 1;
|
||||
qDebug() << "set nextReplayId to " << nextReplayId;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -582,43 +592,32 @@ void Servatrice::statusUpdate()
|
|||
execSqlQuery(query);
|
||||
}
|
||||
|
||||
void Servatrice::storeGameInformation(int secondsElapsed, const QSet<QString> &allPlayersEver, const QSet<QString> &allSpectatorsEver, const GameReplay &replay)
|
||||
void Servatrice::storeGameInformation(int secondsElapsed, const QSet<QString> &allPlayersEver, const QSet<QString> &allSpectatorsEver, const QList<GameReplay *> &replayList)
|
||||
{
|
||||
Server_Room *room = rooms.value(replay.game_info().room_id());
|
||||
const ServerInfo_Game &gameInfo = replayList.first()->game_info();
|
||||
|
||||
Server_Room *room = rooms.value(gameInfo.room_id());
|
||||
|
||||
Event_ReplayAdded replayEvent;
|
||||
ServerInfo_ReplayMatch *replayMatchInfo = replayEvent.mutable_match_info();
|
||||
replayMatchInfo->set_game_id(gameInfo.game_id());
|
||||
replayMatchInfo->set_room_name(room->getName().toStdString());
|
||||
replayMatchInfo->set_time_started(QDateTime::currentDateTime().addSecs(-secondsElapsed).toTime_t());
|
||||
replayMatchInfo->set_length(secondsElapsed);
|
||||
replayMatchInfo->set_game_name(gameInfo.description());
|
||||
|
||||
const QStringList &allGameTypes = room->getGameTypes();
|
||||
QStringList gameTypes;
|
||||
for (int i = replay.game_info().game_types_size() - 1; i >= 0; --i)
|
||||
gameTypes.append(allGameTypes[replay.game_info().game_types(i)]);
|
||||
|
||||
QByteArray replayBlob;
|
||||
const unsigned int size = replay.ByteSize();
|
||||
replayBlob.resize(size);
|
||||
replay.SerializeToArray(replayBlob.data(), size);
|
||||
|
||||
QMutexLocker locker(&dbMutex);
|
||||
if (!checkSql())
|
||||
return;
|
||||
|
||||
QSqlQuery query1;
|
||||
query1.prepare("insert into " + dbPrefix + "_games (room_name, id, descr, creator_name, password, game_types, player_count, time_started, time_finished, replay) values (:id_room, :id_game, :descr, :creator_name, :password, :game_types, :player_count, date_sub(now(), interval :seconds second), now(), :replay)");
|
||||
query1.bindValue(":room_name", room->getName());
|
||||
query1.bindValue(":id_game", replay.game_info().game_id());
|
||||
query1.bindValue(":descr", QString::fromStdString(replay.game_info().description()));
|
||||
query1.bindValue(":creator_name", QString::fromStdString(replay.game_info().creator_info().name()));
|
||||
query1.bindValue(":password", replay.game_info().with_password() ? 1 : 0);
|
||||
query1.bindValue(":game_types", gameTypes.isEmpty() ? QString("") : gameTypes.join(", "));
|
||||
query1.bindValue(":player_count", replay.game_info().max_players());
|
||||
query1.bindValue(":seconds", secondsElapsed);
|
||||
query1.bindValue(":replay", replayBlob);
|
||||
if (!execSqlQuery(query1))
|
||||
return;
|
||||
for (int i = gameInfo.game_types_size() - 1; i >= 0; --i)
|
||||
gameTypes.append(allGameTypes[gameInfo.game_types(i)]);
|
||||
|
||||
QVariantList gameIds1, playerNames, gameIds2, userIds, replayNames;
|
||||
QSetIterator<QString> playerIterator(allPlayersEver);
|
||||
while (playerIterator.hasNext()) {
|
||||
gameIds1.append(replay.game_info().game_id());
|
||||
playerNames.append(playerIterator.next());
|
||||
gameIds1.append(gameInfo.game_id());
|
||||
const QString &playerName = playerIterator.next();
|
||||
playerNames.append(playerName);
|
||||
replayMatchInfo->add_player_names(playerName.toStdString());
|
||||
}
|
||||
QSet<QString> allUsersInGame = allPlayersEver + allSpectatorsEver;
|
||||
QSetIterator<QString> allUsersIterator(allUsersInGame);
|
||||
|
@ -626,17 +625,71 @@ void Servatrice::storeGameInformation(int secondsElapsed, const QSet<QString> &a
|
|||
int id = getUserIdInDB(allUsersIterator.next());
|
||||
if (id == -1)
|
||||
continue;
|
||||
gameIds2.append(replay.game_info().game_id());
|
||||
gameIds2.append(gameInfo.game_id());
|
||||
userIds.append(id);
|
||||
replayNames.append(QString::fromStdString(replay.game_info().description()));
|
||||
replayNames.append(QString::fromStdString(gameInfo.description()));
|
||||
}
|
||||
|
||||
QVariantList replayIds, replayGameIds, replayDurations, replayBlobs;
|
||||
for (int i = 0; i < replayList.size(); ++i) {
|
||||
QByteArray blob;
|
||||
const unsigned int size = replayList[i]->ByteSize();
|
||||
blob.resize(size);
|
||||
replayList[i]->SerializeToArray(blob.data(), size);
|
||||
|
||||
replayIds.append(QVariant((qulonglong) replayList[i]->replay_id()));
|
||||
replayGameIds.append(gameInfo.game_id());
|
||||
replayDurations.append(replayList[i]->duration_seconds());
|
||||
replayBlobs.append(blob);
|
||||
|
||||
ServerInfo_Replay *replayInfo = replayMatchInfo->add_replay_list();
|
||||
replayInfo->set_replay_id(replayList[i]->replay_id());
|
||||
replayInfo->set_replay_name(gameInfo.description());
|
||||
replayInfo->set_duration(replayList[i]->duration_seconds());
|
||||
}
|
||||
|
||||
SessionEvent *sessionEvent = Server_ProtocolHandler::prepareSessionEvent(replayEvent);
|
||||
allUsersIterator.toFront();
|
||||
serverMutex.lock();
|
||||
while (allUsersIterator.hasNext()) {
|
||||
Server_ProtocolHandler *userHandler = users.value(allUsersIterator.next());
|
||||
if (userHandler)
|
||||
userHandler->sendProtocolItem(*sessionEvent);
|
||||
}
|
||||
serverMutex.unlock();
|
||||
delete sessionEvent;
|
||||
|
||||
QMutexLocker locker(&dbMutex);
|
||||
if (!checkSql())
|
||||
return;
|
||||
|
||||
QSqlQuery query1;
|
||||
query1.prepare("insert into " + dbPrefix + "_games (room_name, id, descr, creator_name, password, game_types, player_count, time_started, time_finished) values (:id_room, :id_game, :descr, :creator_name, :password, :game_types, :player_count, date_sub(now(), interval :seconds second), now())");
|
||||
query1.bindValue(":room_name", room->getName());
|
||||
query1.bindValue(":id_game", gameInfo.game_id());
|
||||
query1.bindValue(":descr", QString::fromStdString(gameInfo.description()));
|
||||
query1.bindValue(":creator_name", QString::fromStdString(gameInfo.creator_info().name()));
|
||||
query1.bindValue(":password", gameInfo.with_password() ? 1 : 0);
|
||||
query1.bindValue(":game_types", gameTypes.isEmpty() ? QString("") : gameTypes.join(", "));
|
||||
query1.bindValue(":player_count", gameInfo.max_players());
|
||||
query1.bindValue(":seconds", secondsElapsed);
|
||||
if (!execSqlQuery(query1))
|
||||
return;
|
||||
|
||||
QSqlQuery query2;
|
||||
query2.prepare("insert into " + dbPrefix + "_games_players (id_game, player_name) values (:id_game, :player_name)");
|
||||
query2.bindValue(":id_game", gameIds1);
|
||||
query2.bindValue(":player_name", playerNames);
|
||||
query2.execBatch();
|
||||
|
||||
QSqlQuery replayQuery1;
|
||||
replayQuery1.prepare("insert into " + dbPrefix + "_replays (id, id_game, duration, replay) values (:id_replay, :id_game, :duration, :replay)");
|
||||
replayQuery1.bindValue(":id_replay", replayIds);
|
||||
replayQuery1.bindValue(":id_game", replayGameIds);
|
||||
replayQuery1.bindValue(":duration", replayDurations);
|
||||
replayQuery1.bindValue(":replay", replayBlobs);
|
||||
replayQuery1.execBatch();
|
||||
|
||||
QSqlQuery query3;
|
||||
query3.prepare("insert into " + dbPrefix + "_replays_access (id_game, id_player, replay_name) values (:id_game, :id_player, :replay_name)");
|
||||
query3.bindValue(":id_game", gameIds2);
|
||||
|
|
|
@ -97,7 +97,7 @@ public:
|
|||
void incTxBytes(quint64 num);
|
||||
void incRxBytes(quint64 num);
|
||||
int getUserIdInDB(const QString &name);
|
||||
void storeGameInformation(int secondsElapsed, const QSet<QString> &allPlayersEver, const QSet<QString> &allSpectatorsEver, const GameReplay &replay);
|
||||
void storeGameInformation(int secondsElapsed, const QSet<QString> &allPlayersEver, const QSet<QString> &allSpectatorsEver, const QList<GameReplay *> &replays);
|
||||
protected:
|
||||
int startSession(const QString &userName, const QString &address);
|
||||
void endSession(int sessionId);
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "pb/command_deck_del.pb.h"
|
||||
#include "pb/command_replay_list.pb.h"
|
||||
#include "pb/command_replay_download.pb.h"
|
||||
#include "pb/command_replay_modify_match.pb.h"
|
||||
#include "pb/event_connection_closed.pb.h"
|
||||
#include "pb/event_server_message.pb.h"
|
||||
#include "pb/event_server_identification.pb.h"
|
||||
|
@ -499,27 +500,40 @@ Response::ResponseCode ServerSocketInterface::cmdReplayList(const Command_Replay
|
|||
|
||||
servatrice->dbMutex.lock();
|
||||
QSqlQuery query1;
|
||||
query1.prepare("select a.id_game, a.replay_name, b.room_name, b.time_started, b.time_finished, b.descr from cockatrice_replays_access a left join cockatrice_games b on b.id = a.id_game where a.id_player = :id_player");
|
||||
query1.prepare("select a.id_game, a.replay_name, b.room_name, b.time_started, b.time_finished, b.descr, a.do_not_hide from cockatrice_replays_access a left join cockatrice_games b on b.id = a.id_game where a.id_player = :id_player and (a.do_not_hide = 1 or date_add(b.time_started, interval 14 day) > now())");
|
||||
query1.bindValue(":id_player", userInfo->id());
|
||||
servatrice->execSqlQuery(query1);
|
||||
while (query1.next()) {
|
||||
ServerInfo_Replay *replayInfo = re->add_replay_list();
|
||||
ServerInfo_ReplayMatch *matchInfo = re->add_match_list();
|
||||
|
||||
const int gameId = query1.value(0).toInt();
|
||||
replayInfo->set_game_id(gameId);
|
||||
replayInfo->set_room_name(query1.value(2).toString().toStdString());
|
||||
matchInfo->set_game_id(gameId);
|
||||
matchInfo->set_room_name(query1.value(2).toString().toStdString());
|
||||
const int timeStarted = query1.value(3).toDateTime().toTime_t();
|
||||
const int timeFinished = query1.value(4).toDateTime().toTime_t();
|
||||
replayInfo->set_time_started(timeStarted);
|
||||
replayInfo->set_length(timeFinished - timeStarted);
|
||||
replayInfo->set_game_name(query1.value(5).toString().toStdString());
|
||||
replayInfo->set_replay_name(query1.value(1).toString().toStdString());
|
||||
matchInfo->set_time_started(timeStarted);
|
||||
matchInfo->set_length(timeFinished - timeStarted);
|
||||
matchInfo->set_game_name(query1.value(5).toString().toStdString());
|
||||
const QString replayName = query1.value(1).toString();
|
||||
matchInfo->set_do_not_hide(query1.value(6).toBool());
|
||||
|
||||
QSqlQuery query2;
|
||||
query2.prepare("select player_name from cockatrice_games_players where id_game = :id_game");
|
||||
query2.bindValue(":id_game", gameId);
|
||||
servatrice->execSqlQuery(query2);
|
||||
while (query2.next())
|
||||
replayInfo->add_player_names(query2.value(0).toString().toStdString());
|
||||
matchInfo->add_player_names(query2.value(0).toString().toStdString());
|
||||
|
||||
QSqlQuery query3;
|
||||
query3.prepare("select id, duration from " + servatrice->getDbPrefix() + "_replays where id_game = :id_game");
|
||||
query3.bindValue(":id_game", gameId);
|
||||
servatrice->execSqlQuery(query3);
|
||||
while (query3.next()) {
|
||||
ServerInfo_Replay *replayInfo = matchInfo->add_replay_list();
|
||||
replayInfo->set_replay_id(query3.value(0).toInt());
|
||||
replayInfo->set_replay_name(replayName.toStdString());
|
||||
replayInfo->set_duration(query3.value(1).toInt());
|
||||
}
|
||||
}
|
||||
servatrice->dbMutex.unlock();
|
||||
|
||||
|
@ -535,8 +549,8 @@ Response::ResponseCode ServerSocketInterface::cmdReplayDownload(const Command_Re
|
|||
QMutexLocker dbLocker(&servatrice->dbMutex);
|
||||
|
||||
QSqlQuery query1;
|
||||
query1.prepare("select 1 from " + servatrice->getDbPrefix() + "_replays_access where id_game = :id_game and id_player = :id_player");
|
||||
query1.bindValue(":id_game", cmd.game_id());
|
||||
query1.prepare("select 1 from " + servatrice->getDbPrefix() + "_replays_access a left join " + servatrice->getDbPrefix() + "_replays b on a.id_game = b.id_game where b.id = :id_replay and a.id_player = :id_player");
|
||||
query1.bindValue(":id_replay", cmd.replay_id());
|
||||
query1.bindValue(":id_player", userInfo->id());
|
||||
if (!servatrice->execSqlQuery(query1))
|
||||
return Response::RespInternalError;
|
||||
|
@ -544,8 +558,8 @@ Response::ResponseCode ServerSocketInterface::cmdReplayDownload(const Command_Re
|
|||
return Response::RespAccessDenied;
|
||||
|
||||
QSqlQuery query2;
|
||||
query2.prepare("select replay from " + servatrice->getDbPrefix() + "_games where id = :id_game");
|
||||
query2.bindValue(":id_game", cmd.game_id());
|
||||
query2.prepare("select replay from " + servatrice->getDbPrefix() + "_replays where id = :id_replay");
|
||||
query2.bindValue(":id_replay", cmd.replay_id());
|
||||
if (!servatrice->execSqlQuery(query2))
|
||||
return Response::RespInternalError;
|
||||
if (!query2.next())
|
||||
|
@ -560,6 +574,22 @@ Response::ResponseCode ServerSocketInterface::cmdReplayDownload(const Command_Re
|
|||
return Response::RespOk;
|
||||
}
|
||||
|
||||
Response::ResponseCode ServerSocketInterface::cmdReplayModifyMatch(const Command_ReplayModifyMatch &cmd, ResponseContainer & /*rc*/)
|
||||
{
|
||||
if (authState != PasswordRight)
|
||||
return Response::RespFunctionNotAllowed;
|
||||
|
||||
QMutexLocker dbLocker(&servatrice->dbMutex);
|
||||
|
||||
QSqlQuery query1;
|
||||
query1.prepare("update " + servatrice->getDbPrefix() + "_replays_access set do_not_hide=:do_not_hide where id_player = :id_player and id_game = :id_game");
|
||||
query1.bindValue(":id_player", userInfo->id());
|
||||
query1.bindValue(":id_game", cmd.game_id());
|
||||
query1.bindValue(":do_not_hide", cmd.do_not_hide());
|
||||
|
||||
return servatrice->execSqlQuery(query1) ? Response::RespOk : Response::RespNameNotFound;
|
||||
}
|
||||
|
||||
|
||||
// MODERATOR FUNCTIONS.
|
||||
// May be called by admins and moderators. Permission is checked by the calling function.
|
||||
|
|
|
@ -63,6 +63,7 @@ private:
|
|||
Response::ResponseCode cmdDeckDownload(const Command_DeckDownload &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdReplayList(const Command_ReplayList &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdReplayDownload(const Command_ReplayDownload &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdReplayModifyMatch(const Command_ReplayModifyMatch &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdBanFromServer(const Command_BanFromServer &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdShutdownServer(const Command_ShutdownServer &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdUpdateServerMessage(const Command_UpdateServerMessage &cmd, ResponseContainer &rc);
|
||||
|
|
Loading…
Reference in a new issue