improved banning; added [url] and [card] tags for chat
This commit is contained in:
parent
4b84168bda
commit
05ebb83ba4
36 changed files with 2501 additions and 2073 deletions
|
@ -136,6 +136,7 @@ SOURCES += src/abstractcounter.cpp \
|
||||||
src/gamescene.cpp \
|
src/gamescene.cpp \
|
||||||
src/arrowitem.cpp \
|
src/arrowitem.cpp \
|
||||||
src/arrowtarget.cpp \
|
src/arrowtarget.cpp \
|
||||||
|
src/tab.cpp \
|
||||||
src/tab_server.cpp \
|
src/tab_server.cpp \
|
||||||
src/tab_room.cpp \
|
src/tab_room.cpp \
|
||||||
src/tab_message.cpp \
|
src/tab_message.cpp \
|
||||||
|
|
|
@ -2,34 +2,41 @@
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QTextTable>
|
#include <QTextTable>
|
||||||
#include <QScrollBar>
|
#include <QScrollBar>
|
||||||
|
#include <QMouseEvent>
|
||||||
|
#include <QDesktopServices>
|
||||||
#include "chatview.h"
|
#include "chatview.h"
|
||||||
|
|
||||||
ChatView::ChatView(const QString &_ownName, QWidget *parent)
|
ChatView::ChatView(const QString &_ownName, bool _showTimestamps, QWidget *parent)
|
||||||
: QTextEdit(parent), ownName(_ownName)
|
: QTextBrowser(parent), ownName(_ownName), showTimestamps(_showTimestamps)
|
||||||
{
|
{
|
||||||
setTextInteractionFlags(Qt::TextSelectableByMouse);
|
setReadOnly(true);
|
||||||
|
setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse);
|
||||||
|
setOpenLinks(false);
|
||||||
|
connect(this, SIGNAL(anchorClicked(const QUrl &)), this, SLOT(openLink(const QUrl &)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatView::appendMessage(QString sender, const QString &message)
|
void ChatView::appendMessage(QString sender, QString message)
|
||||||
{
|
{
|
||||||
QTextCursor cursor(document()->lastBlock());
|
QTextCursor cursor(document()->lastBlock());
|
||||||
cursor.movePosition(QTextCursor::End);
|
cursor.movePosition(QTextCursor::End);
|
||||||
|
|
||||||
QTextBlockFormat blockFormat;
|
QTextBlockFormat blockFormat;
|
||||||
blockFormat.setBottomMargin(3);
|
blockFormat.setBottomMargin(2);
|
||||||
cursor.insertBlock(blockFormat);
|
cursor.insertBlock(blockFormat);
|
||||||
|
|
||||||
QTextCharFormat timeFormat;
|
if (showTimestamps) {
|
||||||
timeFormat.setForeground(Qt::black);
|
QTextCharFormat timeFormat;
|
||||||
cursor.setCharFormat(timeFormat);
|
timeFormat.setForeground(Qt::black);
|
||||||
cursor.insertText(QDateTime::currentDateTime().toString("[hh:mm] "));
|
cursor.setCharFormat(timeFormat);
|
||||||
|
cursor.insertText(QDateTime::currentDateTime().toString("[hh:mm] "));
|
||||||
|
}
|
||||||
|
|
||||||
QTextCharFormat senderFormat;
|
QTextCharFormat senderFormat;
|
||||||
if (sender == ownName) {
|
if (sender == ownName) {
|
||||||
senderFormat.setFontWeight(QFont::Bold);
|
senderFormat.setFontWeight(QFont::Bold);
|
||||||
senderFormat.setForeground(Qt::red);
|
senderFormat.setForeground(Qt::red);
|
||||||
} else
|
} else
|
||||||
senderFormat.setForeground(Qt::blue);
|
senderFormat.setForeground(QColor(0, 0, 254));
|
||||||
cursor.setCharFormat(senderFormat);
|
cursor.setCharFormat(senderFormat);
|
||||||
if (!sender.isEmpty())
|
if (!sender.isEmpty())
|
||||||
sender.append(": ");
|
sender.append(": ");
|
||||||
|
@ -39,7 +46,122 @@ void ChatView::appendMessage(QString sender, const QString &message)
|
||||||
if (sender.isEmpty())
|
if (sender.isEmpty())
|
||||||
messageFormat.setForeground(Qt::darkGreen);
|
messageFormat.setForeground(Qt::darkGreen);
|
||||||
cursor.setCharFormat(messageFormat);
|
cursor.setCharFormat(messageFormat);
|
||||||
cursor.insertText(message);
|
|
||||||
|
int from = 0, index = 0;
|
||||||
|
while ((index = message.indexOf('[', from)) != -1) {
|
||||||
|
cursor.insertText(message.left(index));
|
||||||
|
message = message.mid(index);
|
||||||
|
if (message.isEmpty())
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (message.startsWith("[card]")) {
|
||||||
|
message = message.mid(6);
|
||||||
|
QTextCharFormat tempFormat = messageFormat;
|
||||||
|
tempFormat.setForeground(Qt::blue);
|
||||||
|
cursor.setCharFormat(tempFormat);
|
||||||
|
int closeTagIndex = message.indexOf("[/card]");
|
||||||
|
cursor.insertText(message.left(closeTagIndex));
|
||||||
|
cursor.setCharFormat(messageFormat);
|
||||||
|
if (closeTagIndex == -1)
|
||||||
|
message.clear();
|
||||||
|
else
|
||||||
|
message = message.mid(closeTagIndex + 7);
|
||||||
|
} else if (message.startsWith("[url]")) {
|
||||||
|
message = message.mid(5);
|
||||||
|
int closeTagIndex = message.indexOf("[/url]");
|
||||||
|
QString url = message.left(closeTagIndex);
|
||||||
|
if (!url.startsWith("http://"))
|
||||||
|
url.prepend("http://");
|
||||||
|
QTextCharFormat tempFormat = messageFormat;
|
||||||
|
tempFormat.setForeground(QColor(0, 0, 254));
|
||||||
|
tempFormat.setAnchor(true);
|
||||||
|
tempFormat.setAnchorHref(url);
|
||||||
|
cursor.setCharFormat(tempFormat);
|
||||||
|
cursor.insertText(url);
|
||||||
|
cursor.setCharFormat(messageFormat);
|
||||||
|
if (closeTagIndex == -1)
|
||||||
|
message.clear();
|
||||||
|
else
|
||||||
|
message = message.mid(closeTagIndex + 6);
|
||||||
|
} else
|
||||||
|
from = 1;
|
||||||
|
}
|
||||||
|
if (!message.isEmpty())
|
||||||
|
cursor.insertText(message);
|
||||||
|
|
||||||
verticalScrollBar()->setValue(verticalScrollBar()->maximum());
|
verticalScrollBar()->setValue(verticalScrollBar()->maximum());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChatView::enterEvent(QEvent * /*event*/)
|
||||||
|
{
|
||||||
|
setMouseTracking(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatView::leaveEvent(QEvent * /*event*/)
|
||||||
|
{
|
||||||
|
setMouseTracking(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
QTextFragment ChatView::getFragmentUnderMouse(const QPoint &pos) const
|
||||||
|
{
|
||||||
|
QTextCursor cursor(cursorForPosition(pos));
|
||||||
|
QTextBlock block(cursor.block());
|
||||||
|
QTextBlock::iterator it;
|
||||||
|
for (it = block.begin(); !(it.atEnd()); ++it) {
|
||||||
|
QTextFragment frag = it.fragment();
|
||||||
|
if (frag.contains(cursor.position()))
|
||||||
|
return frag;
|
||||||
|
}
|
||||||
|
return QTextFragment();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ChatView::getCardNameUnderMouse(QTextFragment frag) const
|
||||||
|
{
|
||||||
|
if (frag.charFormat().foreground().color() == Qt::blue)
|
||||||
|
return frag.text();
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ChatView::getCardNameUnderMouse(const QPoint &pos) const
|
||||||
|
{
|
||||||
|
return getCardNameUnderMouse(getFragmentUnderMouse(pos));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatView::mouseMoveEvent(QMouseEvent *event)
|
||||||
|
{
|
||||||
|
QTextFragment frag = getFragmentUnderMouse(event->pos());
|
||||||
|
QString cardName = getCardNameUnderMouse(frag);
|
||||||
|
if (!cardName.isEmpty()) {
|
||||||
|
viewport()->setCursor(Qt::PointingHandCursor);
|
||||||
|
emit cardNameHovered(cardName);
|
||||||
|
} else if (frag.charFormat().isAnchor())
|
||||||
|
viewport()->setCursor(Qt::PointingHandCursor);
|
||||||
|
else
|
||||||
|
viewport()->setCursor(Qt::IBeamCursor);
|
||||||
|
|
||||||
|
QTextBrowser::mouseMoveEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatView::mousePressEvent(QMouseEvent *event)
|
||||||
|
{
|
||||||
|
if (event->button() == Qt::MidButton) {
|
||||||
|
QString cardName = getCardNameUnderMouse(event->pos());
|
||||||
|
if (!cardName.isEmpty())
|
||||||
|
emit showCardInfoPopup(event->globalPos(), cardName);
|
||||||
|
}
|
||||||
|
|
||||||
|
QTextBrowser::mousePressEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatView::mouseReleaseEvent(QMouseEvent *event)
|
||||||
|
{
|
||||||
|
if (event->button() == Qt::MidButton)
|
||||||
|
emit deleteCardInfoPopup();
|
||||||
|
|
||||||
|
QTextBrowser::mouseReleaseEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatView::openLink(const QUrl &link)
|
||||||
|
{
|
||||||
|
QDesktopServices::openUrl(link);
|
||||||
|
}
|
||||||
|
|
|
@ -1,18 +1,36 @@
|
||||||
#ifndef CHATVIEW_H
|
#ifndef CHATVIEW_H
|
||||||
#define CHATVIEW_H
|
#define CHATVIEW_H
|
||||||
|
|
||||||
#include <QTextEdit>
|
#include <QTextBrowser>
|
||||||
|
#include <QTextFragment>
|
||||||
|
|
||||||
class QTextTable;
|
class QTextTable;
|
||||||
|
class QMouseEvent;
|
||||||
|
|
||||||
class ChatView : public QTextEdit {
|
class ChatView : public QTextBrowser {
|
||||||
Q_OBJECT;
|
Q_OBJECT;
|
||||||
private:
|
private:
|
||||||
QTextTable *table;
|
QTextTable *table;
|
||||||
QString ownName;
|
QString ownName;
|
||||||
|
bool showTimestamps;
|
||||||
|
QTextFragment getFragmentUnderMouse(const QPoint &pos) const;
|
||||||
|
QString getCardNameUnderMouse(QTextFragment frag) const;
|
||||||
|
QString getCardNameUnderMouse(const QPoint &pos) const;
|
||||||
|
private slots:
|
||||||
|
void openLink(const QUrl &link);
|
||||||
public:
|
public:
|
||||||
ChatView(const QString &_ownName, QWidget *parent = 0);
|
ChatView(const QString &_ownName, bool _showTimestamps, QWidget *parent = 0);
|
||||||
void appendMessage(QString sender, const QString &message);
|
void appendMessage(QString sender, QString message);
|
||||||
|
protected:
|
||||||
|
void enterEvent(QEvent *event);
|
||||||
|
void leaveEvent(QEvent *event);
|
||||||
|
void mouseMoveEvent(QMouseEvent *event);
|
||||||
|
void mousePressEvent(QMouseEvent *event);
|
||||||
|
void mouseReleaseEvent(QMouseEvent *event);
|
||||||
|
signals:
|
||||||
|
void cardNameHovered(QString cardName);
|
||||||
|
void showCardInfoPopup(QPoint pos, QString cardName);
|
||||||
|
void deleteCardInfoPopup();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -11,7 +11,7 @@ class LocalServer : public Server
|
||||||
public:
|
public:
|
||||||
LocalServer(QObject *parent = 0);
|
LocalServer(QObject *parent = 0);
|
||||||
~LocalServer();
|
~LocalServer();
|
||||||
AuthenticationResult checkUserPassword(const QString & /*user*/, const QString & /*password*/) { return UnknownUser; }
|
AuthenticationResult checkUserPassword(Server_ProtocolHandler * /*handler*/, const QString & /*user*/, const QString & /*password*/) { return UnknownUser; }
|
||||||
QString getLoginMessage() const { return QString(); }
|
QString getLoginMessage() const { return QString(); }
|
||||||
bool getGameShouldPing() const { return false; }
|
bool getGameShouldPing() const { return false; }
|
||||||
int getMaxGameInactivityTime() const { return 9999999; }
|
int getMaxGameInactivityTime() const { return 9999999; }
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
#include "messagelogwidget.h"
|
#include "messagelogwidget.h"
|
||||||
#include "player.h"
|
#include "player.h"
|
||||||
#include "cardzone.h"
|
#include "cardzone.h"
|
||||||
#include "cardinfowidget.h"
|
|
||||||
#include "protocol_items.h"
|
#include "protocol_items.h"
|
||||||
#include "soundengine.h"
|
#include "soundengine.h"
|
||||||
#include <QMouseEvent>
|
#include <QScrollBar>
|
||||||
#include <QTextBlock>
|
|
||||||
|
|
||||||
QString MessageLogWidget::sanitizeHtml(QString dirty) const
|
QString MessageLogWidget::sanitizeHtml(QString dirty) const
|
||||||
{
|
{
|
||||||
|
@ -15,6 +13,20 @@ QString MessageLogWidget::sanitizeHtml(QString dirty) const
|
||||||
.replace(">", ">");
|
.replace(">", ">");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MessageLogWidget::myAppend(const QString &message)
|
||||||
|
{
|
||||||
|
QTextCursor cursor(document()->lastBlock());
|
||||||
|
cursor.movePosition(QTextCursor::End);
|
||||||
|
|
||||||
|
QTextBlockFormat blockFormat;
|
||||||
|
blockFormat.setBottomMargin(2);
|
||||||
|
cursor.insertBlock(blockFormat);
|
||||||
|
|
||||||
|
cursor.insertHtml(message);
|
||||||
|
|
||||||
|
verticalScrollBar()->setValue(verticalScrollBar()->maximum());
|
||||||
|
}
|
||||||
|
|
||||||
bool MessageLogWidget::isFemale(Player *player) const
|
bool MessageLogWidget::isFemale(Player *player) const
|
||||||
{
|
{
|
||||||
return player->getUserInfo()->getGender() == ServerInfo_User::Female;
|
return player->getUserInfo()->getGender() == ServerInfo_User::Female;
|
||||||
|
@ -22,129 +34,129 @@ bool MessageLogWidget::isFemale(Player *player) const
|
||||||
|
|
||||||
void MessageLogWidget::logConnecting(QString hostname)
|
void MessageLogWidget::logConnecting(QString hostname)
|
||||||
{
|
{
|
||||||
append(tr("Connecting to %1...").arg(sanitizeHtml(hostname)));
|
myAppend(tr("Connecting to %1...").arg(sanitizeHtml(hostname)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logConnected()
|
void MessageLogWidget::logConnected()
|
||||||
{
|
{
|
||||||
append(tr("Connected."));
|
myAppend(tr("Connected."));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logDisconnected()
|
void MessageLogWidget::logDisconnected()
|
||||||
{
|
{
|
||||||
append(tr("Disconnected from server."));
|
myAppend(tr("Disconnected from server."));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logSocketError(const QString &errorString)
|
void MessageLogWidget::logSocketError(const QString &errorString)
|
||||||
{
|
{
|
||||||
append(sanitizeHtml(errorString));
|
myAppend(sanitizeHtml(errorString));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logServerError(ResponseCode response)
|
void MessageLogWidget::logServerError(ResponseCode response)
|
||||||
{
|
{
|
||||||
switch (response) {
|
switch (response) {
|
||||||
case RespWrongPassword: append(tr("Invalid password.")); break;
|
case RespWrongPassword: myAppend(tr("Invalid password.")); break;
|
||||||
default: ;
|
default: ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logProtocolVersionMismatch(int clientVersion, int serverVersion)
|
void MessageLogWidget::logProtocolVersionMismatch(int clientVersion, int serverVersion)
|
||||||
{
|
{
|
||||||
append(tr("Protocol version mismatch. Client: %1, Server: %2").arg(clientVersion).arg(serverVersion));
|
myAppend(tr("Protocol version mismatch. Client: %1, Server: %2").arg(clientVersion).arg(serverVersion));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logProtocolError()
|
void MessageLogWidget::logProtocolError()
|
||||||
{
|
{
|
||||||
append(tr("Protocol error."));
|
myAppend(tr("Protocol error."));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logGameJoined(int gameId)
|
void MessageLogWidget::logGameJoined(int gameId)
|
||||||
{
|
{
|
||||||
append(tr("You have joined game #%1.").arg(gameId));
|
myAppend(tr("You have joined game #%1.").arg(gameId));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logJoin(Player *player)
|
void MessageLogWidget::logJoin(Player *player)
|
||||||
{
|
{
|
||||||
soundEngine->notification();
|
soundEngine->notification();
|
||||||
append(tr("%1 has joined the game.").arg(sanitizeHtml(player->getName())));
|
myAppend(tr("%1 has joined the game.").arg(sanitizeHtml(player->getName())));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logLeave(Player *player)
|
void MessageLogWidget::logLeave(Player *player)
|
||||||
{
|
{
|
||||||
append(tr("%1 has left the game.").arg(sanitizeHtml(player->getName())));
|
myAppend(tr("%1 has left the game.").arg(sanitizeHtml(player->getName())));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logGameClosed()
|
void MessageLogWidget::logGameClosed()
|
||||||
{
|
{
|
||||||
append(tr("The game has been closed."));
|
myAppend(tr("The game has been closed."));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logJoinSpectator(QString name)
|
void MessageLogWidget::logJoinSpectator(QString name)
|
||||||
{
|
{
|
||||||
append(tr("%1 is now watching the game.").arg(sanitizeHtml(name)));
|
myAppend(tr("%1 is now watching the game.").arg(sanitizeHtml(name)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logLeaveSpectator(QString name)
|
void MessageLogWidget::logLeaveSpectator(QString name)
|
||||||
{
|
{
|
||||||
append(tr("%1 is not watching the game any more.").arg(sanitizeHtml(name)));
|
myAppend(tr("%1 is not watching the game any more.").arg(sanitizeHtml(name)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logDeckSelect(Player *player, int deckId)
|
void MessageLogWidget::logDeckSelect(Player *player, int deckId)
|
||||||
{
|
{
|
||||||
if (deckId == -1)
|
if (deckId == -1)
|
||||||
append(tr("%1 has loaded a local deck.").arg(sanitizeHtml(player->getName())));
|
myAppend(tr("%1 has loaded a local deck.").arg(sanitizeHtml(player->getName())));
|
||||||
else
|
else
|
||||||
append(tr("%1 has loaded deck #%2.").arg(sanitizeHtml(player->getName())).arg(deckId));
|
myAppend(tr("%1 has loaded deck #%2.").arg(sanitizeHtml(player->getName())).arg(deckId));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logReadyStart(Player *player)
|
void MessageLogWidget::logReadyStart(Player *player)
|
||||||
{
|
{
|
||||||
append(tr("%1 is ready to start the game.").arg(sanitizeHtml(player->getName())));
|
myAppend(tr("%1 is ready to start the game.").arg(sanitizeHtml(player->getName())));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logNotReadyStart(Player *player)
|
void MessageLogWidget::logNotReadyStart(Player *player)
|
||||||
{
|
{
|
||||||
append(tr("%1 is not ready to start the game any more.").arg(sanitizeHtml(player->getName())));
|
myAppend(tr("%1 is not ready to start the game any more.").arg(sanitizeHtml(player->getName())));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logConcede(Player *player)
|
void MessageLogWidget::logConcede(Player *player)
|
||||||
{
|
{
|
||||||
append(tr("%1 has conceded the game.").arg(sanitizeHtml(player->getName())));
|
myAppend(tr("%1 has conceded the game.").arg(sanitizeHtml(player->getName())));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logGameStart()
|
void MessageLogWidget::logGameStart()
|
||||||
{
|
{
|
||||||
append(tr("The game has started."));
|
myAppend(tr("The game has started."));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logConnectionStateChanged(Player *player, bool connectionState)
|
void MessageLogWidget::logConnectionStateChanged(Player *player, bool connectionState)
|
||||||
{
|
{
|
||||||
if (connectionState)
|
if (connectionState)
|
||||||
append(tr("%1 has restored connection to the game.").arg(sanitizeHtml(player->getName())));
|
myAppend(tr("%1 has restored connection to the game.").arg(sanitizeHtml(player->getName())));
|
||||||
else
|
else
|
||||||
append(tr("%1 has lost connection to the game.").arg(sanitizeHtml(player->getName())));
|
myAppend(tr("%1 has lost connection to the game.").arg(sanitizeHtml(player->getName())));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logSay(Player *player, QString message)
|
void MessageLogWidget::logSay(Player *player, QString message)
|
||||||
{
|
{
|
||||||
append(QString("<b><font color=\"") + (player->getLocal() ? "red" : "#0000fe") + QString("\">%1:</font></b> %2").arg(sanitizeHtml(player->getName())).arg(sanitizeHtml(message)));
|
appendMessage(player->getName(), message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logSpectatorSay(QString spectatorName, QString message)
|
void MessageLogWidget::logSpectatorSay(QString spectatorName, QString message)
|
||||||
{
|
{
|
||||||
append(QString("<font color=\"red\">%1:</font> %2").arg(sanitizeHtml(spectatorName)).arg(sanitizeHtml(message)));
|
myAppend(QString("<font color=\"red\">%1:</font> %2").arg(sanitizeHtml(spectatorName)).arg(sanitizeHtml(message)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logShuffle(Player *player, CardZone *zone)
|
void MessageLogWidget::logShuffle(Player *player, CardZone *zone)
|
||||||
{
|
{
|
||||||
soundEngine->shuffle();
|
soundEngine->shuffle();
|
||||||
if (currentContext != MessageContext_Mulligan)
|
if (currentContext != MessageContext_Mulligan)
|
||||||
append(tr("%1 shuffles %2.").arg(sanitizeHtml(player->getName())).arg(zone->getTranslatedName(true, CaseAccusative)));
|
myAppend(tr("%1 shuffles %2.").arg(sanitizeHtml(player->getName())).arg(zone->getTranslatedName(true, CaseAccusative)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logRollDie(Player *player, int sides, int roll)
|
void MessageLogWidget::logRollDie(Player *player, int sides, int roll)
|
||||||
{
|
{
|
||||||
append(tr("%1 rolls a %2 with a %3-sided die.").arg(sanitizeHtml(player->getName())).arg(roll).arg(sides));
|
myAppend(tr("%1 rolls a %2 with a %3-sided die.").arg(sanitizeHtml(player->getName())).arg(roll).arg(sides));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logDrawCards(Player *player, int number)
|
void MessageLogWidget::logDrawCards(Player *player, int number)
|
||||||
|
@ -153,16 +165,16 @@ void MessageLogWidget::logDrawCards(Player *player, int number)
|
||||||
mulliganPlayer = player;
|
mulliganPlayer = player;
|
||||||
else {
|
else {
|
||||||
soundEngine->draw();
|
soundEngine->draw();
|
||||||
append(tr("%1 draws %n card(s).", "", number).arg(sanitizeHtml(player->getName())));
|
myAppend(tr("%1 draws %n card(s).", "", number).arg(sanitizeHtml(player->getName())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logUndoDraw(Player *player, QString cardName)
|
void MessageLogWidget::logUndoDraw(Player *player, QString cardName)
|
||||||
{
|
{
|
||||||
if (cardName.isEmpty())
|
if (cardName.isEmpty())
|
||||||
append((isFemale(player) ? tr("%1 undoes her last draw.") : tr("%1 undoes his last draw.")).arg(sanitizeHtml(player->getName())));
|
myAppend((isFemale(player) ? tr("%1 undoes her last draw.") : tr("%1 undoes his last draw.")).arg(sanitizeHtml(player->getName())));
|
||||||
else
|
else
|
||||||
append((isFemale(player) ? tr("%1 undoes her last draw (%2).") : tr("%1 undoes his last draw (%2).")).arg(sanitizeHtml(player->getName())).arg(QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(cardName))));
|
myAppend((isFemale(player) ? tr("%1 undoes her last draw (%2).") : tr("%1 undoes his last draw (%2).")).arg(sanitizeHtml(player->getName())).arg(QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(cardName))));
|
||||||
}
|
}
|
||||||
|
|
||||||
QPair<QString, QString> MessageLogWidget::getFromStr(CardZone *zone, QString cardName, int position) const
|
QPair<QString, QString> MessageLogWidget::getFromStr(CardZone *zone, QString cardName, int position) const
|
||||||
|
@ -227,7 +239,7 @@ void MessageLogWidget::doMoveCard(LogMoveCard &attributes)
|
||||||
cardStr = QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(cardName));
|
cardStr = QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(cardName));
|
||||||
|
|
||||||
if (attributes.startZone->getPlayer() != attributes.targetZone->getPlayer()) {
|
if (attributes.startZone->getPlayer() != attributes.targetZone->getPlayer()) {
|
||||||
append(tr("%1 gives %2 control over %3.").arg(sanitizeHtml(attributes.player->getName())).arg(sanitizeHtml(attributes.targetZone->getPlayer()->getName())).arg(cardStr));
|
myAppend(tr("%1 gives %2 control over %3.").arg(sanitizeHtml(attributes.player->getName())).arg(sanitizeHtml(attributes.targetZone->getPlayer()->getName())).arg(cardStr));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,7 +272,7 @@ void MessageLogWidget::doMoveCard(LogMoveCard &attributes)
|
||||||
finalStr = tr("%1 plays %2%3.");
|
finalStr = tr("%1 plays %2%3.");
|
||||||
}
|
}
|
||||||
|
|
||||||
append(finalStr.arg(sanitizeHtml(attributes.player->getName())).arg(cardStr).arg(fromStr).arg(attributes.newX));
|
myAppend(finalStr.arg(sanitizeHtml(attributes.player->getName())).arg(cardStr).arg(fromStr).arg(attributes.newX));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logMoveCard(Player *player, CardItem *card, CardZone *startZone, int oldX, CardZone *targetZone, int newX)
|
void MessageLogWidget::logMoveCard(Player *player, CardItem *card, CardZone *startZone, int oldX, CardZone *targetZone, int newX)
|
||||||
|
@ -280,50 +292,50 @@ void MessageLogWidget::logMulligan(Player *player, int number)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (number > -1)
|
if (number > -1)
|
||||||
append(tr("%1 takes a mulligan to %n.", "", number).arg(sanitizeHtml(player->getName())));
|
myAppend(tr("%1 takes a mulligan to %n.", "", number).arg(sanitizeHtml(player->getName())));
|
||||||
else
|
else
|
||||||
append((isFemale(player) ? tr("%1 draws her initial hand.") : tr("%1 draws his initial hand.")).arg(sanitizeHtml(player->getName())));
|
myAppend((isFemale(player) ? tr("%1 draws her initial hand.") : tr("%1 draws his initial hand.")).arg(sanitizeHtml(player->getName())));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logFlipCard(Player *player, QString cardName, bool faceDown)
|
void MessageLogWidget::logFlipCard(Player *player, QString cardName, bool faceDown)
|
||||||
{
|
{
|
||||||
if (faceDown)
|
if (faceDown)
|
||||||
append(tr("%1 flips %2 face-down.").arg(sanitizeHtml(player->getName())).arg(cardName));
|
myAppend(tr("%1 flips %2 face-down.").arg(sanitizeHtml(player->getName())).arg(cardName));
|
||||||
else
|
else
|
||||||
append(tr("%1 flips %2 face-up.").arg(sanitizeHtml(player->getName())).arg(cardName));
|
myAppend(tr("%1 flips %2 face-up.").arg(sanitizeHtml(player->getName())).arg(cardName));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logDestroyCard(Player *player, QString cardName)
|
void MessageLogWidget::logDestroyCard(Player *player, QString cardName)
|
||||||
{
|
{
|
||||||
append(tr("%1 destroys %2.").arg(sanitizeHtml(player->getName())).arg(QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(cardName))));
|
myAppend(tr("%1 destroys %2.").arg(sanitizeHtml(player->getName())).arg(QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(cardName))));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logAttachCard(Player *player, QString cardName, Player *targetPlayer, QString targetCardName)
|
void MessageLogWidget::logAttachCard(Player *player, QString cardName, Player *targetPlayer, QString targetCardName)
|
||||||
{
|
{
|
||||||
append(tr("%1 attaches %2 to %3's %4.").arg(sanitizeHtml(player->getName())).arg(QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(cardName))).arg(sanitizeHtml(targetPlayer->getName())).arg(QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(targetCardName))));
|
myAppend(tr("%1 attaches %2 to %3's %4.").arg(sanitizeHtml(player->getName())).arg(QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(cardName))).arg(sanitizeHtml(targetPlayer->getName())).arg(QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(targetCardName))));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logUnattachCard(Player *player, QString cardName)
|
void MessageLogWidget::logUnattachCard(Player *player, QString cardName)
|
||||||
{
|
{
|
||||||
append(tr("%1 unattaches %2.").arg(sanitizeHtml(player->getName())).arg(QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(cardName))));
|
myAppend(tr("%1 unattaches %2.").arg(sanitizeHtml(player->getName())).arg(QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(cardName))));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logCreateToken(Player *player, QString cardName, QString pt)
|
void MessageLogWidget::logCreateToken(Player *player, QString cardName, QString pt)
|
||||||
{
|
{
|
||||||
append(tr("%1 creates token: %2%3.").arg(sanitizeHtml(player->getName())).arg(QString("<font color=\"blue\"><a name=\"foo\">%1</a></font>").arg(sanitizeHtml(cardName))).arg(pt.isEmpty() ? QString() : QString(" (%1)").arg(sanitizeHtml(pt))));
|
myAppend(tr("%1 creates token: %2%3.").arg(sanitizeHtml(player->getName())).arg(QString("<font color=\"blue\"><a name=\"foo\">%1</a></font>").arg(sanitizeHtml(cardName))).arg(pt.isEmpty() ? QString() : QString(" (%1)").arg(sanitizeHtml(pt))));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logCreateArrow(Player *player, Player *startPlayer, QString startCard, Player *targetPlayer, QString targetCard, bool playerTarget)
|
void MessageLogWidget::logCreateArrow(Player *player, Player *startPlayer, QString startCard, Player *targetPlayer, QString targetCard, bool playerTarget)
|
||||||
{
|
{
|
||||||
if (playerTarget)
|
if (playerTarget)
|
||||||
append(tr("%1 points from %2's %3 to %4.")
|
myAppend(tr("%1 points from %2's %3 to %4.")
|
||||||
.arg(sanitizeHtml(player->getName()))
|
.arg(sanitizeHtml(player->getName()))
|
||||||
.arg(sanitizeHtml(startPlayer->getName()))
|
.arg(sanitizeHtml(startPlayer->getName()))
|
||||||
.arg(sanitizeHtml(startCard))
|
.arg(sanitizeHtml(startCard))
|
||||||
.arg(sanitizeHtml(targetPlayer->getName()))
|
.arg(sanitizeHtml(targetPlayer->getName()))
|
||||||
);
|
);
|
||||||
else
|
else
|
||||||
append(tr("%1 points from %2's %3 to %4's %5.")
|
myAppend(tr("%1 points from %2's %3 to %4's %5.")
|
||||||
.arg(sanitizeHtml(player->getName()))
|
.arg(sanitizeHtml(player->getName()))
|
||||||
.arg(sanitizeHtml(startPlayer->getName()))
|
.arg(sanitizeHtml(startPlayer->getName()))
|
||||||
.arg(sanitizeHtml(startCard))
|
.arg(sanitizeHtml(startCard))
|
||||||
|
@ -349,7 +361,7 @@ void MessageLogWidget::logSetCardCounter(Player *player, QString cardName, int c
|
||||||
default: ;
|
default: ;
|
||||||
}
|
}
|
||||||
|
|
||||||
append(finalStr.arg(sanitizeHtml(player->getName())).arg(colorStr).arg(QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(cardName))).arg(value));
|
myAppend(finalStr.arg(sanitizeHtml(player->getName())).arg(colorStr).arg(QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(cardName))).arg(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logSetTapped(Player *player, CardItem *card, bool tapped)
|
void MessageLogWidget::logSetTapped(Player *player, CardItem *card, bool tapped)
|
||||||
|
@ -367,13 +379,13 @@ void MessageLogWidget::logSetTapped(Player *player, CardItem *card, bool tapped)
|
||||||
cardStr = isFemale(player) ? tr("her permanents") : tr("his permanents");
|
cardStr = isFemale(player) ? tr("her permanents") : tr("his permanents");
|
||||||
else
|
else
|
||||||
cardStr = QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(card->getName()));
|
cardStr = QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(card->getName()));
|
||||||
append(tr("%1 %2 %3.").arg(sanitizeHtml(player->getName())).arg(tapped ? tr("taps") : tr("untaps")).arg(cardStr));
|
myAppend(tr("%1 %2 %3.").arg(sanitizeHtml(player->getName())).arg(tapped ? tr("taps") : tr("untaps")).arg(cardStr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logSetCounter(Player *player, QString counterName, int value, int oldValue)
|
void MessageLogWidget::logSetCounter(Player *player, QString counterName, int value, int oldValue)
|
||||||
{
|
{
|
||||||
append(tr("%1 sets counter %2 to %3 (%4%5).").arg(sanitizeHtml(player->getName())).arg(QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(counterName))).arg(QString("<font color=\"blue\">%1</font>").arg(value)).arg(value > oldValue ? "+" : "").arg(value - oldValue));
|
myAppend(tr("%1 sets counter %2 to %3 (%4%5).").arg(sanitizeHtml(player->getName())).arg(QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(counterName))).arg(QString("<font color=\"blue\">%1</font>").arg(value)).arg(value > oldValue ? "+" : "").arg(value - oldValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logSetDoesntUntap(Player *player, CardItem *card, bool doesntUntap)
|
void MessageLogWidget::logSetDoesntUntap(Player *player, CardItem *card, bool doesntUntap)
|
||||||
|
@ -383,7 +395,7 @@ void MessageLogWidget::logSetDoesntUntap(Player *player, CardItem *card, bool do
|
||||||
finalStr = tr("%1 sets %2 to not untap normally.");
|
finalStr = tr("%1 sets %2 to not untap normally.");
|
||||||
else
|
else
|
||||||
finalStr = tr("%1 sets %2 to untap normally.");
|
finalStr = tr("%1 sets %2 to untap normally.");
|
||||||
append(finalStr.arg(sanitizeHtml(player->getName())).arg(QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(card->getName()))));
|
myAppend(finalStr.arg(sanitizeHtml(player->getName())).arg(QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(card->getName()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logSetPT(Player *player, CardItem *card, QString newPT)
|
void MessageLogWidget::logSetPT(Player *player, CardItem *card, QString newPT)
|
||||||
|
@ -391,26 +403,26 @@ void MessageLogWidget::logSetPT(Player *player, CardItem *card, QString newPT)
|
||||||
if (currentContext == MessageContext_MoveCard)
|
if (currentContext == MessageContext_MoveCard)
|
||||||
moveCardPT.insert(card, newPT);
|
moveCardPT.insert(card, newPT);
|
||||||
else
|
else
|
||||||
append(tr("%1 sets PT of %2 to %3.").arg(sanitizeHtml(player->getName())).arg(QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(card->getName()))).arg(QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(newPT))));
|
myAppend(tr("%1 sets PT of %2 to %3.").arg(sanitizeHtml(player->getName())).arg(QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(card->getName()))).arg(QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(newPT))));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logSetAnnotation(Player *player, CardItem *card, QString newAnnotation)
|
void MessageLogWidget::logSetAnnotation(Player *player, CardItem *card, QString newAnnotation)
|
||||||
{
|
{
|
||||||
append(tr("%1 sets annotation of %2 to %3.").arg(sanitizeHtml(player->getName())).arg(QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(card->getName()))).arg(QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(newAnnotation))));
|
myAppend(tr("%1 sets annotation of %2 to %3.").arg(sanitizeHtml(player->getName())).arg(QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(card->getName()))).arg(QString("<font color=\"blue\">%1</font>").arg(sanitizeHtml(newAnnotation))));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logDumpZone(Player *player, CardZone *zone, int numberCards)
|
void MessageLogWidget::logDumpZone(Player *player, CardZone *zone, int numberCards)
|
||||||
{
|
{
|
||||||
if (numberCards != -1)
|
if (numberCards != -1)
|
||||||
append(tr("%1 is looking at the top %2 cards %3.").arg(sanitizeHtml(player->getName())).arg(numberCards).arg(zone->getTranslatedName(zone->getPlayer() == player, CaseGenitive)));
|
myAppend(tr("%1 is looking at the top %2 cards %3.").arg(sanitizeHtml(player->getName())).arg(numberCards).arg(zone->getTranslatedName(zone->getPlayer() == player, CaseGenitive)));
|
||||||
else
|
else
|
||||||
append(tr("%1 is looking at %2.").arg(sanitizeHtml(player->getName())).arg(zone->getTranslatedName(zone->getPlayer() == player, CaseAccusative)));
|
myAppend(tr("%1 is looking at %2.").arg(sanitizeHtml(player->getName())).arg(zone->getTranslatedName(zone->getPlayer() == player, CaseAccusative)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logStopDumpZone(Player *player, CardZone *zone)
|
void MessageLogWidget::logStopDumpZone(Player *player, CardZone *zone)
|
||||||
{
|
{
|
||||||
QString zoneName = zone->getTranslatedName(zone->getPlayer() == player, CaseAccusative);
|
QString zoneName = zone->getTranslatedName(zone->getPlayer() == player, CaseAccusative);
|
||||||
append(tr("%1 stops looking at %2.").arg(sanitizeHtml(player->getName())).arg(zoneName));
|
myAppend(tr("%1 stops looking at %2.").arg(sanitizeHtml(player->getName())).arg(zoneName));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logRevealCards(Player *player, CardZone *zone, int cardId, QString cardName, Player *otherPlayer)
|
void MessageLogWidget::logRevealCards(Player *player, CardZone *zone, int cardId, QString cardName, Player *otherPlayer)
|
||||||
|
@ -433,28 +445,28 @@ void MessageLogWidget::logRevealCards(Player *player, CardZone *zone, int cardId
|
||||||
|
|
||||||
if (cardId == -1) {
|
if (cardId == -1) {
|
||||||
if (otherPlayer)
|
if (otherPlayer)
|
||||||
append(tr("%1 reveals %2 to %3.").arg(sanitizeHtml(player->getName())).arg(zone->getTranslatedName(true, CaseAccusative)).arg(sanitizeHtml(otherPlayer->getName())));
|
myAppend(tr("%1 reveals %2 to %3.").arg(sanitizeHtml(player->getName())).arg(zone->getTranslatedName(true, CaseAccusative)).arg(sanitizeHtml(otherPlayer->getName())));
|
||||||
else
|
else
|
||||||
append(tr("%1 reveals %2.").arg(sanitizeHtml(player->getName())).arg(zone->getTranslatedName(true, CaseAccusative)));
|
myAppend(tr("%1 reveals %2.").arg(sanitizeHtml(player->getName())).arg(zone->getTranslatedName(true, CaseAccusative)));
|
||||||
} else if (cardId == -2) {
|
} else if (cardId == -2) {
|
||||||
if (otherPlayer)
|
if (otherPlayer)
|
||||||
append(tr("%1 randomly reveals %2%3 to %4.").arg(sanitizeHtml(player->getName())).arg(cardStr).arg(fromStr).arg(sanitizeHtml(otherPlayer->getName())));
|
myAppend(tr("%1 randomly reveals %2%3 to %4.").arg(sanitizeHtml(player->getName())).arg(cardStr).arg(fromStr).arg(sanitizeHtml(otherPlayer->getName())));
|
||||||
else
|
else
|
||||||
append(tr("%1 randomly reveals %2%3.").arg(sanitizeHtml(player->getName())).arg(cardStr).arg(fromStr));
|
myAppend(tr("%1 randomly reveals %2%3.").arg(sanitizeHtml(player->getName())).arg(cardStr).arg(fromStr));
|
||||||
} else {
|
} else {
|
||||||
if (otherPlayer)
|
if (otherPlayer)
|
||||||
append(tr("%1 reveals %2%3 to %4.").arg(sanitizeHtml(player->getName())).arg(cardStr).arg(fromStr).arg(sanitizeHtml(otherPlayer->getName())));
|
myAppend(tr("%1 reveals %2%3 to %4.").arg(sanitizeHtml(player->getName())).arg(cardStr).arg(fromStr).arg(sanitizeHtml(otherPlayer->getName())));
|
||||||
else
|
else
|
||||||
append(tr("%1 reveals %2%3.").arg(sanitizeHtml(player->getName())).arg(cardStr).arg(fromStr));
|
myAppend(tr("%1 reveals %2%3.").arg(sanitizeHtml(player->getName())).arg(cardStr).arg(fromStr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logSetActivePlayer(Player *player)
|
void MessageLogWidget::logSetActivePlayer(Player *player)
|
||||||
{
|
{
|
||||||
soundEngine->notification();
|
soundEngine->notification();
|
||||||
append(QString());
|
myAppend(QString());
|
||||||
append("<font color=\"green\"><b>" + tr("It is now %1's turn.").arg(player->getName()) + "</b></font>");
|
myAppend("<font color=\"green\"><b>" + tr("It is now %1's turn.").arg(player->getName()) + "</b></font>");
|
||||||
append(QString());
|
myAppend(QString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::logSetActivePhase(int phase)
|
void MessageLogWidget::logSetActivePhase(int phase)
|
||||||
|
@ -474,7 +486,7 @@ void MessageLogWidget::logSetActivePhase(int phase)
|
||||||
case 9: phaseName = tr("second main phase"); break;
|
case 9: phaseName = tr("second main phase"); break;
|
||||||
case 10: phaseName = tr("ending phase"); break;
|
case 10: phaseName = tr("ending phase"); break;
|
||||||
}
|
}
|
||||||
append("<font color=\"green\"><b>" + tr("It is now the %1.").arg(phaseName) + "</b></font>");
|
myAppend("<font color=\"green\"><b>" + tr("It is now the %1.").arg(phaseName) + "</b></font>");
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLogWidget::containerProcessingStarted(GameEventContext *_context)
|
void MessageLogWidget::containerProcessingStarted(GameEventContext *_context)
|
||||||
|
@ -531,67 +543,7 @@ void MessageLogWidget::connectToPlayer(Player *player)
|
||||||
connect(player, SIGNAL(logRevealCards(Player *, CardZone *, int, QString, Player *)), this, SLOT(logRevealCards(Player *, CardZone *, int, QString, Player *)));
|
connect(player, SIGNAL(logRevealCards(Player *, CardZone *, int, QString, Player *)), this, SLOT(logRevealCards(Player *, CardZone *, int, QString, Player *)));
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageLogWidget::MessageLogWidget(QWidget *parent)
|
MessageLogWidget::MessageLogWidget(const QString &_ownName, QWidget *parent)
|
||||||
: QTextEdit(parent)
|
: ChatView(_ownName, false, parent)
|
||||||
{
|
{
|
||||||
setReadOnly(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MessageLogWidget::enterEvent(QEvent * /*event*/)
|
|
||||||
{
|
|
||||||
setMouseTracking(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MessageLogWidget::leaveEvent(QEvent * /*event*/)
|
|
||||||
{
|
|
||||||
setMouseTracking(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString MessageLogWidget::getCardNameUnderMouse(const QPoint &pos) const
|
|
||||||
{
|
|
||||||
QTextCursor cursor(cursorForPosition(pos));
|
|
||||||
QTextBlock block(cursor.block());
|
|
||||||
QTextBlock::iterator it;
|
|
||||||
for (it = block.begin(); !(it.atEnd()); ++it) {
|
|
||||||
QTextFragment frag = it.fragment();
|
|
||||||
if (!frag.contains(cursor.position()))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (frag.charFormat().foreground().color() == Qt::blue)
|
|
||||||
return frag.text();
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MessageLogWidget::mouseMoveEvent(QMouseEvent *event)
|
|
||||||
{
|
|
||||||
QString cardName = getCardNameUnderMouse(event->pos());
|
|
||||||
if (!cardName.isEmpty()) {
|
|
||||||
viewport()->setCursor(Qt::PointingHandCursor);
|
|
||||||
emit cardNameHovered(cardName);
|
|
||||||
} else
|
|
||||||
viewport()->setCursor(Qt::IBeamCursor);
|
|
||||||
|
|
||||||
QTextEdit::mouseMoveEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MessageLogWidget::mousePressEvent(QMouseEvent *event)
|
|
||||||
{
|
|
||||||
if (event->button() == Qt::MidButton) {
|
|
||||||
QString cardName = getCardNameUnderMouse(event->pos());
|
|
||||||
if (!cardName.isEmpty())
|
|
||||||
emit showCardInfoPopup(event->globalPos(), cardName);
|
|
||||||
}
|
|
||||||
|
|
||||||
QTextEdit::mousePressEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MessageLogWidget::mouseReleaseEvent(QMouseEvent *event)
|
|
||||||
{
|
|
||||||
if (event->button() == Qt::MidButton)
|
|
||||||
emit deleteCardInfoPopup();
|
|
||||||
|
|
||||||
QTextEdit::mouseReleaseEvent(event);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
#ifndef MESSAGELOGWIDGET_H
|
#ifndef MESSAGELOGWIDGET_H
|
||||||
#define MESSAGELOGWIDGET_H
|
#define MESSAGELOGWIDGET_H
|
||||||
|
|
||||||
#include <QTextEdit>
|
#include "chatview.h"
|
||||||
#include <QAbstractSocket>
|
#include <QAbstractSocket>
|
||||||
#include "translation.h"
|
#include "translation.h"
|
||||||
#include "protocol_datastructures.h"
|
#include "protocol_datastructures.h"
|
||||||
|
|
||||||
class Player;
|
class Player;
|
||||||
class CardZone;
|
class CardZone;
|
||||||
class QMouseEvent;
|
|
||||||
class QEvent;
|
|
||||||
class CardInfoWidget;
|
class CardInfoWidget;
|
||||||
class GameEventContext;
|
class GameEventContext;
|
||||||
class CardItem;
|
class CardItem;
|
||||||
|
@ -24,16 +22,15 @@ struct LogMoveCard {
|
||||||
int newX;
|
int newX;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MessageLogWidget : public QTextEdit {
|
class MessageLogWidget : public ChatView {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private:
|
private:
|
||||||
enum MessageContext { MessageContext_None, MessageContext_MoveCard, MessageContext_Mulligan };
|
enum MessageContext { MessageContext_None, MessageContext_MoveCard, MessageContext_Mulligan };
|
||||||
|
|
||||||
CardInfoWidget *infoWidget;
|
|
||||||
QString sanitizeHtml(QString dirty) const;
|
QString sanitizeHtml(QString dirty) const;
|
||||||
|
void myAppend(const QString &message);
|
||||||
bool isFemale(Player *player) const;
|
bool isFemale(Player *player) const;
|
||||||
QPair<QString, QString> getFromStr(CardZone *zone, QString cardName, int position) const;
|
QPair<QString, QString> getFromStr(CardZone *zone, QString cardName, int position) const;
|
||||||
QString getCardNameUnderMouse(const QPoint &pos) const;
|
|
||||||
MessageContext currentContext;
|
MessageContext currentContext;
|
||||||
|
|
||||||
QList<LogMoveCard> moveCardQueue;
|
QList<LogMoveCard> moveCardQueue;
|
||||||
|
@ -42,10 +39,6 @@ private:
|
||||||
|
|
||||||
Player *mulliganPlayer;
|
Player *mulliganPlayer;
|
||||||
int mulliganNumber;
|
int mulliganNumber;
|
||||||
signals:
|
|
||||||
void cardNameHovered(QString cardName);
|
|
||||||
void showCardInfoPopup(QPoint pos, QString cardName);
|
|
||||||
void deleteCardInfoPopup();
|
|
||||||
public slots:
|
public slots:
|
||||||
void logConnecting(QString hostname);
|
void logConnecting(QString hostname);
|
||||||
void logConnected();
|
void logConnected();
|
||||||
|
@ -96,13 +89,7 @@ public slots:
|
||||||
void containerProcessingDone();
|
void containerProcessingDone();
|
||||||
public:
|
public:
|
||||||
void connectToPlayer(Player *player);
|
void connectToPlayer(Player *player);
|
||||||
MessageLogWidget(QWidget *parent = 0);
|
MessageLogWidget(const QString &_ownName, QWidget *parent = 0);
|
||||||
protected:
|
|
||||||
void enterEvent(QEvent *event);
|
|
||||||
void leaveEvent(QEvent *event);
|
|
||||||
void mouseMoveEvent(QMouseEvent *event);
|
|
||||||
void mousePressEvent(QMouseEvent *event);
|
|
||||||
void mouseReleaseEvent(QMouseEvent *event);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
30
cockatrice/src/tab.cpp
Normal file
30
cockatrice/src/tab.cpp
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
#include "tab.h"
|
||||||
|
#include "cardinfowidget.h"
|
||||||
|
#include <QDesktopWidget>
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
Tab::Tab(TabSupervisor *_tabSupervisor, QWidget *parent)
|
||||||
|
: QWidget(parent), tabMenu(0), tabSupervisor(_tabSupervisor), contentsChanged(false), infoPopup(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tab::showCardInfoPopup(const QPoint &pos, const QString &cardName)
|
||||||
|
{
|
||||||
|
infoPopup = new CardInfoWidget(CardInfoWidget::ModePopUp, 0, Qt::Widget | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint | Qt::WindowStaysOnTopHint);
|
||||||
|
infoPopup->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
|
infoPopup->setCard(cardName);
|
||||||
|
QRect screenRect = qApp->desktop()->screenGeometry(this);
|
||||||
|
infoPopup->move(
|
||||||
|
qMax(screenRect.left(), qMin(pos.x() - infoPopup->width() / 2, screenRect.left() + screenRect.width() - infoPopup->width())),
|
||||||
|
qMax(screenRect.top(), qMin(pos.y() - infoPopup->height() / 2, screenRect.top() + screenRect.height() - infoPopup->height()))
|
||||||
|
);
|
||||||
|
infoPopup->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tab::deleteCardInfoPopup()
|
||||||
|
{
|
||||||
|
if (infoPopup) {
|
||||||
|
infoPopup->deleteLater();
|
||||||
|
infoPopup = 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
class QMenu;
|
class QMenu;
|
||||||
class TabSupervisor;
|
class TabSupervisor;
|
||||||
|
class CardInfoWidget;
|
||||||
|
|
||||||
class Tab : public QWidget {
|
class Tab : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -13,11 +14,14 @@ signals:
|
||||||
protected:
|
protected:
|
||||||
QMenu *tabMenu;
|
QMenu *tabMenu;
|
||||||
TabSupervisor *tabSupervisor;
|
TabSupervisor *tabSupervisor;
|
||||||
|
protected slots:
|
||||||
|
void showCardInfoPopup(const QPoint &pos, const QString &cardName);
|
||||||
|
void deleteCardInfoPopup();
|
||||||
private:
|
private:
|
||||||
bool contentsChanged;
|
bool contentsChanged;
|
||||||
|
CardInfoWidget *infoPopup;
|
||||||
public:
|
public:
|
||||||
Tab(TabSupervisor *_tabSupervisor, QWidget *parent = 0)
|
Tab(TabSupervisor *_tabSupervisor, QWidget *parent = 0);
|
||||||
: QWidget(parent), tabMenu(0), tabSupervisor(_tabSupervisor), contentsChanged(false) { }
|
|
||||||
QMenu *getTabMenu() const { return tabMenu; }
|
QMenu *getTabMenu() const { return tabMenu; }
|
||||||
bool getContentsChanged() const { return contentsChanged; }
|
bool getContentsChanged() const { return contentsChanged; }
|
||||||
void setContentsChanged(bool _contentsChanged) { contentsChanged = _contentsChanged; }
|
void setContentsChanged(bool _contentsChanged) { contentsChanged = _contentsChanged; }
|
||||||
|
|
|
@ -5,8 +5,6 @@
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QApplication>
|
|
||||||
#include <QDesktopWidget>
|
|
||||||
#include "tab_game.h"
|
#include "tab_game.h"
|
||||||
#include "cardinfowidget.h"
|
#include "cardinfowidget.h"
|
||||||
#include "playerlistwidget.h"
|
#include "playerlistwidget.h"
|
||||||
|
@ -160,8 +158,8 @@ void DeckViewContainer::setDeck(DeckList *deck)
|
||||||
readyStartButton->setEnabled(true);
|
readyStartButton->setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
TabGame::TabGame(TabSupervisor *_tabSupervisor, QList<AbstractClient *> &_clients, int _gameId, const QString &_gameDescription, int _localPlayerId, bool _spectator, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, bool _resuming)
|
TabGame::TabGame(TabSupervisor *_tabSupervisor, QList<AbstractClient *> &_clients, int _gameId, const QString &_gameDescription, int _localPlayerId, const QString &_userName, bool _spectator, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, bool _resuming)
|
||||||
: Tab(_tabSupervisor), clients(_clients), gameId(_gameId), gameDescription(_gameDescription), localPlayerId(_localPlayerId), spectator(_spectator), spectatorsCanTalk(_spectatorsCanTalk), spectatorsSeeEverything(_spectatorsSeeEverything), started(false), resuming(_resuming), currentPhase(-1), infoPopup(0)
|
: Tab(_tabSupervisor), clients(_clients), gameId(_gameId), gameDescription(_gameDescription), localPlayerId(_localPlayerId), spectator(_spectator), spectatorsCanTalk(_spectatorsCanTalk), spectatorsSeeEverything(_spectatorsSeeEverything), started(false), resuming(_resuming), currentPhase(-1)
|
||||||
{
|
{
|
||||||
phasesToolbar = new PhasesToolbar;
|
phasesToolbar = new PhasesToolbar;
|
||||||
phasesToolbar->hide();
|
phasesToolbar->hide();
|
||||||
|
@ -178,7 +176,7 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, QList<AbstractClient *> &_client
|
||||||
|
|
||||||
timeElapsedLabel = new QLabel;
|
timeElapsedLabel = new QLabel;
|
||||||
timeElapsedLabel->setAlignment(Qt::AlignCenter);
|
timeElapsedLabel->setAlignment(Qt::AlignCenter);
|
||||||
messageLog = new MessageLogWidget;
|
messageLog = new MessageLogWidget(_userName);
|
||||||
connect(messageLog, SIGNAL(cardNameHovered(QString)), cardInfo, SLOT(setCard(QString)));
|
connect(messageLog, SIGNAL(cardNameHovered(QString)), cardInfo, SLOT(setCard(QString)));
|
||||||
connect(messageLog, SIGNAL(showCardInfoPopup(QPoint, QString)), this, SLOT(showCardInfoPopup(QPoint, QString)));
|
connect(messageLog, SIGNAL(showCardInfoPopup(QPoint, QString)), this, SLOT(showCardInfoPopup(QPoint, QString)));
|
||||||
connect(messageLog, SIGNAL(deleteCardInfoPopup()), this, SLOT(deleteCardInfoPopup()));
|
connect(messageLog, SIGNAL(deleteCardInfoPopup()), this, SLOT(deleteCardInfoPopup()));
|
||||||
|
@ -779,24 +777,3 @@ Player *TabGame::getActiveLocalPlayer() const
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabGame::showCardInfoPopup(const QPoint &pos, const QString &cardName)
|
|
||||||
{
|
|
||||||
infoPopup = new CardInfoWidget(CardInfoWidget::ModePopUp, 0, Qt::Widget | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint | Qt::WindowStaysOnTopHint);
|
|
||||||
infoPopup->setAttribute(Qt::WA_TransparentForMouseEvents);
|
|
||||||
infoPopup->setCard(cardName);
|
|
||||||
QRect screenRect = qApp->desktop()->screenGeometry(this);
|
|
||||||
infoPopup->move(
|
|
||||||
qMax(screenRect.left(), qMin(pos.x() - infoPopup->width() / 2, screenRect.left() + screenRect.width() - infoPopup->width())),
|
|
||||||
qMax(screenRect.top(), qMin(pos.y() - infoPopup->height() / 2, screenRect.top() + screenRect.height() - infoPopup->height()))
|
|
||||||
);
|
|
||||||
infoPopup->show();
|
|
||||||
}
|
|
||||||
|
|
||||||
void TabGame::deleteCardInfoPopup()
|
|
||||||
{
|
|
||||||
if (infoPopup) {
|
|
||||||
infoPopup->deleteLater();
|
|
||||||
infoPopup = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -100,7 +100,6 @@ private:
|
||||||
int activePlayer;
|
int activePlayer;
|
||||||
|
|
||||||
QSplitter *splitter;
|
QSplitter *splitter;
|
||||||
CardInfoWidget *infoPopup;
|
|
||||||
CardInfoWidget *cardInfo;
|
CardInfoWidget *cardInfo;
|
||||||
PlayerListWidget *playerListWidget;
|
PlayerListWidget *playerListWidget;
|
||||||
QLabel *timeElapsedLabel;
|
QLabel *timeElapsedLabel;
|
||||||
|
@ -147,8 +146,6 @@ signals:
|
||||||
void openMessageDialog(const QString &userName, bool focus);
|
void openMessageDialog(const QString &userName, bool focus);
|
||||||
private slots:
|
private slots:
|
||||||
void newCardAdded(AbstractCardItem *card);
|
void newCardAdded(AbstractCardItem *card);
|
||||||
void showCardInfoPopup(const QPoint &pos, const QString &cardName);
|
|
||||||
void deleteCardInfoPopup();
|
|
||||||
|
|
||||||
void actConcede();
|
void actConcede();
|
||||||
void actLeaveGame();
|
void actLeaveGame();
|
||||||
|
@ -158,7 +155,7 @@ private slots:
|
||||||
void actNextPhase();
|
void actNextPhase();
|
||||||
void actNextTurn();
|
void actNextTurn();
|
||||||
public:
|
public:
|
||||||
TabGame(TabSupervisor *_tabSupervisor, QList<AbstractClient *> &_clients, int _gameId, const QString &_gameDescription, int _localPlayerId, bool _spectator, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, bool _resuming);
|
TabGame(TabSupervisor *_tabSupervisor, QList<AbstractClient *> &_clients, int _gameId, const QString &_gameDescription, int _localPlayerId, const QString &_userName, bool _spectator, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, bool _resuming);
|
||||||
~TabGame();
|
~TabGame();
|
||||||
void retranslateUi();
|
void retranslateUi();
|
||||||
void closeRequest();
|
void closeRequest();
|
||||||
|
|
|
@ -11,7 +11,9 @@
|
||||||
TabMessage::TabMessage(TabSupervisor *_tabSupervisor, AbstractClient *_client, const QString &_ownName, const QString &_userName)
|
TabMessage::TabMessage(TabSupervisor *_tabSupervisor, AbstractClient *_client, const QString &_ownName, const QString &_userName)
|
||||||
: Tab(_tabSupervisor), client(_client), userName(_userName), userOnline(true)
|
: Tab(_tabSupervisor), client(_client), userName(_userName), userOnline(true)
|
||||||
{
|
{
|
||||||
chatView = new ChatView(_ownName);
|
chatView = new ChatView(_ownName, true);
|
||||||
|
connect(chatView, SIGNAL(showCardInfoPopup(QPoint, QString)), this, SLOT(showCardInfoPopup(QPoint, QString)));
|
||||||
|
connect(chatView, SIGNAL(deleteCardInfoPopup()), this, SLOT(deleteCardInfoPopup()));
|
||||||
sayEdit = new QLineEdit;
|
sayEdit = new QLineEdit;
|
||||||
connect(sayEdit, SIGNAL(returnPressed()), this, SLOT(sendMessage()));
|
connect(sayEdit, SIGNAL(returnPressed()), this, SLOT(sendMessage()));
|
||||||
|
|
||||||
|
|
|
@ -137,7 +137,9 @@ TabRoom::TabRoom(TabSupervisor *_tabSupervisor, AbstractClient *_client, const Q
|
||||||
userList = new UserList(tabSupervisor, client, UserList::RoomList);
|
userList = new UserList(tabSupervisor, client, UserList::RoomList);
|
||||||
connect(userList, SIGNAL(openMessageDialog(const QString &, bool)), this, SIGNAL(openMessageDialog(const QString &, bool)));
|
connect(userList, SIGNAL(openMessageDialog(const QString &, bool)), this, SIGNAL(openMessageDialog(const QString &, bool)));
|
||||||
|
|
||||||
chatView = new ChatView(ownName);
|
chatView = new ChatView(ownName, true);
|
||||||
|
connect(chatView, SIGNAL(showCardInfoPopup(QPoint, QString)), this, SLOT(showCardInfoPopup(QPoint, QString)));
|
||||||
|
connect(chatView, SIGNAL(deleteCardInfoPopup()), this, SLOT(deleteCardInfoPopup()));
|
||||||
sayLabel = new QLabel;
|
sayLabel = new QLabel;
|
||||||
sayEdit = new QLineEdit;
|
sayEdit = new QLineEdit;
|
||||||
sayLabel->setBuddy(sayEdit);
|
sayLabel->setBuddy(sayEdit);
|
||||||
|
|
|
@ -221,7 +221,7 @@ void TabSupervisor::addCloseButtonToTab(Tab *tab, int tabIndex)
|
||||||
|
|
||||||
void TabSupervisor::gameJoined(Event_GameJoined *event)
|
void TabSupervisor::gameJoined(Event_GameJoined *event)
|
||||||
{
|
{
|
||||||
TabGame *tab = new TabGame(this, QList<AbstractClient *>() << client, event->getGameId(), event->getGameDescription(), event->getPlayerId(), event->getSpectator(), event->getSpectatorsCanTalk(), event->getSpectatorsSeeEverything(), event->getResuming());
|
TabGame *tab = new TabGame(this, QList<AbstractClient *>() << client, event->getGameId(), event->getGameDescription(), event->getPlayerId(), userName, event->getSpectator(), event->getSpectatorsCanTalk(), event->getSpectatorsSeeEverything(), event->getResuming());
|
||||||
connect(tab, SIGNAL(gameClosing(TabGame *)), this, SLOT(gameLeft(TabGame *)));
|
connect(tab, SIGNAL(gameClosing(TabGame *)), this, SLOT(gameLeft(TabGame *)));
|
||||||
connect(tab, SIGNAL(openMessageDialog(const QString &, bool)), this, SLOT(addMessageTab(const QString &, bool)));
|
connect(tab, SIGNAL(openMessageDialog(const QString &, bool)), this, SLOT(addMessageTab(const QString &, bool)));
|
||||||
int tabIndex = myAddTab(tab);
|
int tabIndex = myAddTab(tab);
|
||||||
|
@ -232,7 +232,7 @@ void TabSupervisor::gameJoined(Event_GameJoined *event)
|
||||||
|
|
||||||
void TabSupervisor::localGameJoined(Event_GameJoined *event)
|
void TabSupervisor::localGameJoined(Event_GameJoined *event)
|
||||||
{
|
{
|
||||||
TabGame *tab = new TabGame(this, localClients, event->getGameId(), event->getGameDescription(), event->getPlayerId(), event->getSpectator(), event->getSpectatorsCanTalk(), event->getSpectatorsSeeEverything(), event->getResuming());
|
TabGame *tab = new TabGame(this, localClients, event->getGameId(), event->getGameDescription(), event->getPlayerId(), QString(), event->getSpectator(), event->getSpectatorsCanTalk(), event->getSpectatorsSeeEverything(), event->getResuming());
|
||||||
connect(tab, SIGNAL(gameClosing(TabGame *)), this, SLOT(gameLeft(TabGame *)));
|
connect(tab, SIGNAL(gameClosing(TabGame *)), this, SLOT(gameLeft(TabGame *)));
|
||||||
int tabIndex = myAddTab(tab);
|
int tabIndex = myAddTab(tab);
|
||||||
addCloseButtonToTab(tab, tabIndex);
|
addCloseButtonToTab(tab, tabIndex);
|
||||||
|
|
|
@ -10,6 +10,53 @@
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QSpinBox>
|
||||||
|
#include <QPlainTextEdit>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
|
||||||
|
BanDialog::BanDialog(QWidget *parent)
|
||||||
|
: QDialog(parent)
|
||||||
|
{
|
||||||
|
QLabel *durationLabel = new QLabel(tr("Please enter the duration of the ban (in minutes).\nEnter 0 for an indefinite ban."));
|
||||||
|
durationEdit = new QSpinBox;
|
||||||
|
durationEdit->setMinimum(0);
|
||||||
|
durationEdit->setValue(5);
|
||||||
|
QLabel *reasonLabel = new QLabel(tr("Please enter the reason for the ban.\nThis is only saved for moderators and cannot be seen by the banned person."));
|
||||||
|
reasonEdit = new QPlainTextEdit;
|
||||||
|
|
||||||
|
QPushButton *okButton = new QPushButton(tr("&OK"));
|
||||||
|
okButton->setAutoDefault(true);
|
||||||
|
connect(okButton, SIGNAL(clicked()), this, SLOT(accept()));
|
||||||
|
QPushButton *cancelButton = new QPushButton(tr("&Cancel"));
|
||||||
|
connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
|
||||||
|
|
||||||
|
QHBoxLayout *buttonLayout = new QHBoxLayout;
|
||||||
|
buttonLayout->addStretch();
|
||||||
|
buttonLayout->addWidget(okButton);
|
||||||
|
buttonLayout->addWidget(cancelButton);
|
||||||
|
|
||||||
|
QVBoxLayout *vbox = new QVBoxLayout;
|
||||||
|
vbox->addWidget(durationLabel);
|
||||||
|
vbox->addWidget(durationEdit);
|
||||||
|
vbox->addWidget(reasonLabel);
|
||||||
|
vbox->addWidget(reasonEdit);
|
||||||
|
vbox->addLayout(buttonLayout);
|
||||||
|
|
||||||
|
setLayout(vbox);
|
||||||
|
setWindowTitle(tr("Ban user from server"));
|
||||||
|
}
|
||||||
|
|
||||||
|
int BanDialog::getMinutes() const
|
||||||
|
{
|
||||||
|
return durationEdit->value();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString BanDialog::getReason() const
|
||||||
|
{
|
||||||
|
return reasonEdit->toPlainText();
|
||||||
|
}
|
||||||
|
|
||||||
UserListItemDelegate::UserListItemDelegate(QObject *const parent)
|
UserListItemDelegate::UserListItemDelegate(QObject *const parent)
|
||||||
: QStyledItemDelegate(parent)
|
: QStyledItemDelegate(parent)
|
||||||
|
@ -215,10 +262,9 @@ void UserList::showContextMenu(const QPoint &pos, const QModelIndex &index)
|
||||||
else if (actionClicked == aRemoveFromIgnoreList)
|
else if (actionClicked == aRemoveFromIgnoreList)
|
||||||
client->sendCommand(new Command_RemoveFromList("ignore", userName));
|
client->sendCommand(new Command_RemoveFromList("ignore", userName));
|
||||||
else if (actionClicked == aBan) {
|
else if (actionClicked == aBan) {
|
||||||
bool ok;
|
BanDialog dlg(this);
|
||||||
int minutes = QInputDialog::getInt(this, tr("Duration"), tr("Please enter the duration of the ban (in minutes).\nEnter 0 for an indefinite ban."), 0, 0, 2147483647, 10, &ok);
|
if (dlg.exec())
|
||||||
if (ok)
|
client->sendCommand(new Command_BanFromServer(userName, dlg.getMinutes(), dlg.getReason()));
|
||||||
client->sendCommand(new Command_BanFromServer(userName, minutes));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
delete menu;
|
delete menu;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef USERLIST_H
|
#ifndef USERLIST_H
|
||||||
#define USERLIST_H
|
#define USERLIST_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
#include <QGroupBox>
|
#include <QGroupBox>
|
||||||
#include <QTreeWidgetItem>
|
#include <QTreeWidgetItem>
|
||||||
#include <QStyledItemDelegate>
|
#include <QStyledItemDelegate>
|
||||||
|
@ -9,6 +10,19 @@ class QTreeWidget;
|
||||||
class ServerInfo_User;
|
class ServerInfo_User;
|
||||||
class AbstractClient;
|
class AbstractClient;
|
||||||
class TabSupervisor;
|
class TabSupervisor;
|
||||||
|
class QSpinBox;
|
||||||
|
class QPlainTextEdit;
|
||||||
|
|
||||||
|
class BanDialog : public QDialog {
|
||||||
|
Q_OBJECT
|
||||||
|
private:
|
||||||
|
QSpinBox *durationEdit;
|
||||||
|
QPlainTextEdit *reasonEdit;
|
||||||
|
public:
|
||||||
|
BanDialog(QWidget *parent = 0);
|
||||||
|
int getMinutes() const;
|
||||||
|
QString getReason() const;
|
||||||
|
};
|
||||||
|
|
||||||
class UserListItemDelegate : public QStyledItemDelegate {
|
class UserListItemDelegate : public QStyledItemDelegate {
|
||||||
public:
|
public:
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -484,11 +484,12 @@ Command_ShutdownServer::Command_ShutdownServer(const QString &_reason, int _minu
|
||||||
insertItem(new SerializableItem_String("reason", _reason));
|
insertItem(new SerializableItem_String("reason", _reason));
|
||||||
insertItem(new SerializableItem_Int("minutes", _minutes));
|
insertItem(new SerializableItem_Int("minutes", _minutes));
|
||||||
}
|
}
|
||||||
Command_BanFromServer::Command_BanFromServer(const QString &_userName, int _minutes)
|
Command_BanFromServer::Command_BanFromServer(const QString &_userName, int _minutes, const QString &_reason)
|
||||||
: ModeratorCommand("ban_from_server")
|
: ModeratorCommand("ban_from_server")
|
||||||
{
|
{
|
||||||
insertItem(new SerializableItem_String("user_name", _userName));
|
insertItem(new SerializableItem_String("user_name", _userName));
|
||||||
insertItem(new SerializableItem_Int("minutes", _minutes));
|
insertItem(new SerializableItem_Int("minutes", _minutes));
|
||||||
|
insertItem(new SerializableItem_String("reason", _reason));
|
||||||
}
|
}
|
||||||
void ProtocolItem::initializeHashAuto()
|
void ProtocolItem::initializeHashAuto()
|
||||||
{
|
{
|
||||||
|
|
|
@ -80,4 +80,4 @@
|
||||||
6:mulligan:i,number
|
6:mulligan:i,number
|
||||||
7:update_server_message
|
7:update_server_message
|
||||||
7:shutdown_server:s,reason:i,minutes
|
7:shutdown_server:s,reason:i,minutes
|
||||||
8:ban_from_server:s,user_name:i,minutes
|
8:ban_from_server:s,user_name:i,minutes:s,reason
|
|
@ -735,9 +735,10 @@ public:
|
||||||
class Command_BanFromServer : public ModeratorCommand {
|
class Command_BanFromServer : public ModeratorCommand {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
Command_BanFromServer(const QString &_userName = QString(), int _minutes = -1);
|
Command_BanFromServer(const QString &_userName = QString(), int _minutes = -1, const QString &_reason = QString());
|
||||||
QString getUserName() const { return static_cast<SerializableItem_String *>(itemMap.value("user_name"))->getData(); };
|
QString getUserName() const { return static_cast<SerializableItem_String *>(itemMap.value("user_name"))->getData(); };
|
||||||
int getMinutes() const { return static_cast<SerializableItem_Int *>(itemMap.value("minutes"))->getData(); };
|
int getMinutes() const { return static_cast<SerializableItem_Int *>(itemMap.value("minutes"))->getData(); };
|
||||||
|
QString getReason() const { return static_cast<SerializableItem_String *>(itemMap.value("reason"))->getData(); };
|
||||||
static SerializableItem *newItem() { return new Command_BanFromServer; }
|
static SerializableItem *newItem() { return new Command_BanFromServer; }
|
||||||
int getItemId() const { return ItemId_Command_BanFromServer; }
|
int getItemId() const { return ItemId_Command_BanFromServer; }
|
||||||
};
|
};
|
||||||
|
|
|
@ -52,7 +52,7 @@ AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString
|
||||||
QMutexLocker locker(&serverMutex);
|
QMutexLocker locker(&serverMutex);
|
||||||
if (name.size() > 35)
|
if (name.size() > 35)
|
||||||
name = name.left(35);
|
name = name.left(35);
|
||||||
AuthenticationResult authState = checkUserPassword(name, password);
|
AuthenticationResult authState = checkUserPassword(session, name, password);
|
||||||
if (authState == PasswordWrong)
|
if (authState == PasswordWrong)
|
||||||
return authState;
|
return authState;
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,6 @@ public:
|
||||||
|
|
||||||
virtual QMap<QString, ServerInfo_User *> getBuddyList(const QString &name) = 0;
|
virtual QMap<QString, ServerInfo_User *> getBuddyList(const QString &name) = 0;
|
||||||
virtual QMap<QString, ServerInfo_User *> getIgnoreList(const QString &name) = 0;
|
virtual QMap<QString, ServerInfo_User *> getIgnoreList(const QString &name) = 0;
|
||||||
virtual bool getUserBanned(Server_ProtocolHandler * /*client*/, const QString & /*userName*/) const { return false; }
|
|
||||||
protected:
|
protected:
|
||||||
void prepareDestroy();
|
void prepareDestroy();
|
||||||
QList<Server_ProtocolHandler *> clients;
|
QList<Server_ProtocolHandler *> clients;
|
||||||
|
@ -51,7 +50,7 @@ protected:
|
||||||
QMap<int, Server_Room *> rooms;
|
QMap<int, Server_Room *> rooms;
|
||||||
|
|
||||||
virtual bool userExists(const QString &user) = 0;
|
virtual bool userExists(const QString &user) = 0;
|
||||||
virtual AuthenticationResult checkUserPassword(const QString &user, const QString &password) = 0;
|
virtual AuthenticationResult checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password) = 0;
|
||||||
virtual ServerInfo_User *getUserData(const QString &name) = 0;
|
virtual ServerInfo_User *getUserData(const QString &name) = 0;
|
||||||
int getUsersCount() const;
|
int getUsersCount() const;
|
||||||
int getGamesCount() const;
|
int getGamesCount() const;
|
||||||
|
|
|
@ -280,8 +280,6 @@ ResponseCode Server_ProtocolHandler::cmdLogin(Command_Login *cmd, CommandContain
|
||||||
QString userName = cmd->getUsername().simplified();
|
QString userName = cmd->getUsername().simplified();
|
||||||
if (userName.isEmpty() || (userInfo != 0))
|
if (userName.isEmpty() || (userInfo != 0))
|
||||||
return RespContextError;
|
return RespContextError;
|
||||||
if (server->getUserBanned(this, userName))
|
|
||||||
return RespWrongPassword;
|
|
||||||
authState = server->loginUser(this, userName, cmd->getPassword());
|
authState = server->loginUser(this, userName, cmd->getPassword());
|
||||||
if (authState == PasswordWrong)
|
if (authState == PasswordWrong)
|
||||||
return RespWrongPassword;
|
return RespWrongPassword;
|
||||||
|
|
|
@ -111,7 +111,6 @@ CREATE TABLE IF NOT EXISTS `cockatrice_users` (
|
||||||
`avatar_bmp` blob NOT NULL,
|
`avatar_bmp` blob NOT NULL,
|
||||||
`registrationDate` datetime NOT NULL,
|
`registrationDate` datetime NOT NULL,
|
||||||
`active` tinyint(1) NOT NULL,
|
`active` tinyint(1) NOT NULL,
|
||||||
`banned` tinyint(1) NOT NULL,
|
|
||||||
`token` char(32) NOT NULL,
|
`token` char(32) NOT NULL,
|
||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
UNIQUE KEY `name` (`name`)
|
UNIQUE KEY `name` (`name`)
|
||||||
|
@ -149,3 +148,12 @@ CREATE TABLE `cockatrice_buddylist` (
|
||||||
KEY `id_user2` (`id_user2`)
|
KEY `id_user2` (`id_user2`)
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
CREATE TABLE `cockatrice_bans` (
|
||||||
|
`id_user` int(7) unsigned zerofill NOT NULL,
|
||||||
|
`id_admin` int(7) unsigned zerofill NOT NULL,
|
||||||
|
`time_from` datetime NOT NULL,
|
||||||
|
`minutes` int(6) NOT NULL,
|
||||||
|
`reason` text NOT NULL,
|
||||||
|
KEY `id_user` (`id_user`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
|
|
@ -169,25 +169,32 @@ bool Servatrice::execSqlQuery(QSqlQuery &query)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
AuthenticationResult Servatrice::checkUserPassword(const QString &user, const QString &password)
|
AuthenticationResult Servatrice::checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password)
|
||||||
{
|
{
|
||||||
|
serverMutex.lock();
|
||||||
|
QHostAddress address = static_cast<ServerSocketInterface *>(handler)->getPeerAddress();
|
||||||
|
for (int i = 0; i < addressBanList.size(); ++i)
|
||||||
|
if (address == addressBanList[i].first)
|
||||||
|
return PasswordWrong;
|
||||||
|
serverMutex.unlock();
|
||||||
|
|
||||||
QMutexLocker locker(&dbMutex);
|
QMutexLocker locker(&dbMutex);
|
||||||
const QString method = settings->value("authentication/method").toString();
|
const QString method = settings->value("authentication/method").toString();
|
||||||
if (method == "none")
|
if (method == "none")
|
||||||
return UnknownUser;
|
return UnknownUser;
|
||||||
else if (method == "sql") {
|
else if (method == "sql") {
|
||||||
checkSql();
|
checkSql();
|
||||||
|
|
||||||
QSqlQuery query;
|
QSqlQuery query;
|
||||||
query.prepare("select banned, password from " + dbPrefix + "_users where name = :name and active = 1");
|
query.prepare("select a.password, timediff(now(), date_add(b.time_from, interval b.minutes minute)) < 0, b.minutes <=> 0 from " + dbPrefix + "_users a left join " + dbPrefix + "_bans b on b.id_user = a.id and b.time_from = (select max(c.time_from) from " + dbPrefix + "_bans c where c.id_user = a.id) where a.name = :name and a.active = 1");
|
||||||
query.bindValue(":name", user);
|
query.bindValue(":name", user);
|
||||||
if (!execSqlQuery(query))
|
if (!execSqlQuery(query))
|
||||||
return PasswordWrong;
|
return PasswordWrong;
|
||||||
|
|
||||||
if (query.next()) {
|
if (query.next()) {
|
||||||
if (query.value(0).toInt())
|
if (query.value(1).toInt() || query.value(2).toInt())
|
||||||
return PasswordWrong;
|
return PasswordWrong;
|
||||||
if (query.value(1).toString() == password)
|
if (query.value(0).toString() == password)
|
||||||
return PasswordRight;
|
return PasswordRight;
|
||||||
else
|
else
|
||||||
return PasswordWrong;
|
return PasswordWrong;
|
||||||
|
@ -325,19 +332,6 @@ QMap<QString, ServerInfo_User *> Servatrice::getIgnoreList(const QString &name)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Servatrice::getUserBanned(Server_ProtocolHandler *client, const QString &userName) const
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&serverMutex);
|
|
||||||
QHostAddress address = static_cast<ServerSocketInterface *>(client)->getPeerAddress();
|
|
||||||
for (int i = 0; i < addressBanList.size(); ++i)
|
|
||||||
if (address == addressBanList[i].first)
|
|
||||||
return true;
|
|
||||||
for (int i = 0; i < nameBanList.size(); ++i)
|
|
||||||
if (userName == nameBanList[i].first)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Servatrice::updateBanTimer()
|
void Servatrice::updateBanTimer()
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&serverMutex);
|
QMutexLocker locker(&serverMutex);
|
||||||
|
@ -346,11 +340,6 @@ void Servatrice::updateBanTimer()
|
||||||
addressBanList.removeAt(i);
|
addressBanList.removeAt(i);
|
||||||
else
|
else
|
||||||
++i;
|
++i;
|
||||||
for (int i = 0; i < nameBanList.size(); )
|
|
||||||
if (--(nameBanList[i].second) <= 0)
|
|
||||||
nameBanList.removeAt(i);
|
|
||||||
else
|
|
||||||
++i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Servatrice::updateLoginMessage()
|
void Servatrice::updateLoginMessage()
|
||||||
|
|
|
@ -74,13 +74,11 @@ public:
|
||||||
int getUsersWithAddress(const QHostAddress &address) const;
|
int getUsersWithAddress(const QHostAddress &address) const;
|
||||||
QMap<QString, ServerInfo_User *> getBuddyList(const QString &name);
|
QMap<QString, ServerInfo_User *> getBuddyList(const QString &name);
|
||||||
QMap<QString, ServerInfo_User *> getIgnoreList(const QString &name);
|
QMap<QString, ServerInfo_User *> getIgnoreList(const QString &name);
|
||||||
bool getUserBanned(Server_ProtocolHandler *client, const QString &userName) const;
|
|
||||||
void addAddressBan(const QHostAddress &address, int minutes) { addressBanList.append(QPair<QHostAddress, int>(address, minutes)); }
|
void addAddressBan(const QHostAddress &address, int minutes) { addressBanList.append(QPair<QHostAddress, int>(address, minutes)); }
|
||||||
void addNameBan(const QString &name, int minutes) { nameBanList.append(QPair<QString, int>(name, minutes)); }
|
|
||||||
void scheduleShutdown(const QString &reason, int minutes);
|
void scheduleShutdown(const QString &reason, int minutes);
|
||||||
protected:
|
protected:
|
||||||
bool userExists(const QString &user);
|
bool userExists(const QString &user);
|
||||||
AuthenticationResult checkUserPassword(const QString &user, const QString &password);
|
AuthenticationResult checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password);
|
||||||
private:
|
private:
|
||||||
QTimer *pingClock, *statusUpdateClock, *banTimeoutClock;
|
QTimer *pingClock, *statusUpdateClock, *banTimeoutClock;
|
||||||
QTcpServer *tcpServer;
|
QTcpServer *tcpServer;
|
||||||
|
@ -90,7 +88,6 @@ private:
|
||||||
int serverId;
|
int serverId;
|
||||||
int uptime;
|
int uptime;
|
||||||
QList<QPair<QHostAddress, int> > addressBanList;
|
QList<QPair<QHostAddress, int> > addressBanList;
|
||||||
QList<QPair<QString, int> > nameBanList;
|
|
||||||
int maxGameInactivityTime, maxPlayerInactivityTime;
|
int maxGameInactivityTime, maxPlayerInactivityTime;
|
||||||
int maxUsersPerAddress, messageCountingInterval, maxMessageCountPerInterval, maxMessageSizePerInterval, maxGamesPerUser;
|
int maxUsersPerAddress, messageCountingInterval, maxMessageCountPerInterval, maxMessageSizePerInterval, maxGamesPerUser;
|
||||||
ServerInfo_User *evalUserQueryResult(const QSqlQuery &query, bool complete);
|
ServerInfo_User *evalUserQueryResult(const QSqlQuery &query, bool complete);
|
||||||
|
|
|
@ -488,14 +488,14 @@ ResponseCode ServerSocketInterface::cmdBanFromServer(Command_BanFromServer *cmd,
|
||||||
ServerSocketInterface *user = static_cast<ServerSocketInterface *>(server->getUsers().value(userName));
|
ServerSocketInterface *user = static_cast<ServerSocketInterface *>(server->getUsers().value(userName));
|
||||||
if (user->getUserInfo()->getUserLevel() & ServerInfo_User::IsRegistered) {
|
if (user->getUserInfo()->getUserLevel() & ServerInfo_User::IsRegistered) {
|
||||||
// Registered users can be banned by name.
|
// Registered users can be banned by name.
|
||||||
if (minutes == 0) {
|
QMutexLocker locker(&servatrice->dbMutex);
|
||||||
QMutexLocker locker(&servatrice->dbMutex);
|
QSqlQuery query;
|
||||||
QSqlQuery query;
|
query.prepare("insert into " + servatrice->getDbPrefix() + "_bans (id_user, id_admin, time_from, minutes, reason) values(:id_user, :id_admin, NOW(), :minutes, :reason)");
|
||||||
query.prepare("update " + servatrice->getDbPrefix() + "_users set banned=1 where name = :name");
|
query.bindValue(":id_user", getUserIdInDB(userName));
|
||||||
query.bindValue(":name", userName);
|
query.bindValue(":id_admin", getUserIdInDB(userInfo->getName()));
|
||||||
servatrice->execSqlQuery(query);
|
query.bindValue(":minutes", minutes);
|
||||||
} else
|
query.bindValue(":reason", cmd->getReason());
|
||||||
servatrice->addNameBan(userName, minutes);
|
servatrice->execSqlQuery(query);
|
||||||
} else {
|
} else {
|
||||||
// Unregistered users must be banned by IP address.
|
// Unregistered users must be banned by IP address.
|
||||||
// Indefinite address bans are not reasonable -> default to 30 minutes.
|
// Indefinite address bans are not reasonable -> default to 30 minutes.
|
||||||
|
|
Loading…
Reference in a new issue