Skip to content

Commit

Permalink
Allow admins to clear user avatars/textures.
Browse files Browse the repository at this point in the history
  • Loading branch information
Tim Cooper authored and mkrautz committed Apr 15, 2014
1 parent 02ddd91 commit 52d19ac
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 50 deletions.
23 changes: 21 additions & 2 deletions src/mumble/MainWindow.cpp
Expand Up @@ -1131,11 +1131,11 @@ void MainWindow::on_qaServerTexture_triggered() {
const QImage &img = choice.second; const QImage &img = choice.second;


if ((img.height() <= 1024) && (img.width() <= 1024)) if ((img.height() <= 1024) && (img.width() <= 1024))
g.sh->setTexture(choice.first); g.sh->setUserTexture(g.uiSession, choice.first);
} }


void MainWindow::on_qaServerTextureRemove_triggered() { void MainWindow::on_qaServerTextureRemove_triggered() {
g.sh->setTexture(QByteArray()); g.sh->setUserTexture(g.uiSession, QByteArray());
} }


void MainWindow::on_qaServerTokens_triggered() { void MainWindow::on_qaServerTokens_triggered() {
Expand Down Expand Up @@ -1193,6 +1193,7 @@ void MainWindow::qmUser_aboutToShow() {
else { else {
qmUser->addAction(qaUserCommentView); qmUser->addAction(qaUserCommentView);
qmUser->addAction(qaUserCommentReset); qmUser->addAction(qaUserCommentReset);
qmUser->addAction(qaUserTextureReset);
} }


qmUser->addAction(qaUserTextMessage); qmUser->addAction(qaUserTextMessage);
Expand Down Expand Up @@ -1244,6 +1245,7 @@ void MainWindow::qmUser_aboutToShow() {
qaUserLocalMute->setEnabled(false); qaUserLocalMute->setEnabled(false);
qaUserLocalIgnore->setEnabled(false); qaUserLocalIgnore->setEnabled(false);
qaUserCommentReset->setEnabled(false); qaUserCommentReset->setEnabled(false);
qaUserTextureReset->setEnabled(false);
qaUserCommentView->setEnabled(false); qaUserCommentView->setEnabled(false);
} else { } else {
qaUserKick->setEnabled(! self); qaUserKick->setEnabled(! self);
Expand All @@ -1252,6 +1254,7 @@ void MainWindow::qmUser_aboutToShow() {
qaUserLocalMute->setEnabled(! self); qaUserLocalMute->setEnabled(! self);
qaUserLocalIgnore->setEnabled(! self); qaUserLocalIgnore->setEnabled(! self);
qaUserCommentReset->setEnabled(! p->qbaCommentHash.isEmpty() && (g.pPermissions & (ChanACL::Move | ChanACL::Write))); qaUserCommentReset->setEnabled(! p->qbaCommentHash.isEmpty() && (g.pPermissions & (ChanACL::Move | ChanACL::Write)));
qaUserTextureReset->setEnabled(! p->qbaTextureHash.isEmpty() && (g.pPermissions & (ChanACL::Move | ChanACL::Write)));
qaUserCommentView->setEnabled(! p->qbaCommentHash.isEmpty()); qaUserCommentView->setEnabled(! p->qbaCommentHash.isEmpty());


qaUserMute->setChecked(p->bMute || p->bSuppress); qaUserMute->setChecked(p->bMute || p->bSuppress);
Expand Down Expand Up @@ -1493,6 +1496,22 @@ void MainWindow::on_qaUserCommentReset_triggered() {
} }
} }


void MainWindow::on_qaUserTextureReset_triggered() {
ClientUser *p = getContextMenuUser();

if (!p)
return;

unsigned int session = p->uiSession;

int ret = QMessageBox::question(this, QLatin1String("Mumble"),
tr("Are you sure you want to reset the avatar of user %1?").arg(Qt::escape(p->qsName)),
QMessageBox::Yes, QMessageBox::No);
if (ret == QMessageBox::Yes) {
g.sh->setUserTexture(session, QByteArray());
}
}

void MainWindow::on_qaUserInformation_triggered() { void MainWindow::on_qaUserInformation_triggered() {
ClientUser *p = getContextMenuUser(); ClientUser *p = getContextMenuUser();


Expand Down
1 change: 1 addition & 0 deletions src/mumble/MainWindow.h
Expand Up @@ -187,6 +187,7 @@ class MainWindow : public QMainWindow, public MessageHandler, public Ui::MainWin
void on_qaSelfRegister_triggered(); void on_qaSelfRegister_triggered();
void qmUser_aboutToShow(); void qmUser_aboutToShow();
void on_qaUserCommentReset_triggered(); void on_qaUserCommentReset_triggered();
void on_qaUserTextureReset_triggered();
void on_qaUserCommentView_triggered(); void on_qaUserCommentView_triggered();
void on_qaUserKick_triggered(); void on_qaUserKick_triggered();
void on_qaUserBan_triggered(); void on_qaUserBan_triggered();
Expand Down
8 changes: 8 additions & 0 deletions src/mumble/MainWindow.ui
Expand Up @@ -788,6 +788,14 @@ the channel's context menu.</string>
<string>Reset the comment of the selected user.</string> <string>Reset the comment of the selected user.</string>
</property> </property>
</action> </action>
<action name="qaUserTextureReset">
<property name="text">
<string>Reset &amp;Avatar</string>
</property>
<property name="toolTip">
<string>Reset the avatar of the selected user.</string>
</property>
</action>
<action name="qaChannelJoin"> <action name="qaChannelJoin">
<property name="text"> <property name="text">
<string>&amp;Join Channel</string> <string>&amp;Join Channel</string>
Expand Down
89 changes: 46 additions & 43 deletions src/mumble/ServerHandler.cpp
Expand Up @@ -680,49 +680,6 @@ void ServerHandler::createChannel(unsigned int parent_, const QString &name, con
sendMessage(mpcs); sendMessage(mpcs);
} }


void ServerHandler::setTexture(const QByteArray &qba) {
QByteArray texture;
if ((uiVersion >= 0x010202) || qba.isEmpty()) {
texture = qba;
} else {
QByteArray raw = qba;
QBuffer qb(& raw);
qb.open(QIODevice::ReadOnly);
QImageReader qir;
if (qba.startsWith("<?xml"))
qir.setFormat("svg");
qir.setDevice(&qb);

QSize sz = qir.size();
sz.scale(600, 60, Qt::KeepAspectRatio);
qir.setScaledSize(sz);

QImage tex = qir.read();

if (tex.isNull())
return;

qWarning() << tex.width() << tex.height();

raw = QByteArray(600*60*4, 0);
QImage img(reinterpret_cast<unsigned char *>(raw.data()), 600, 60, QImage::Format_ARGB32);

QPainter imgp(&img);
imgp.setRenderHint(QPainter::Antialiasing);
imgp.setRenderHint(QPainter::TextAntialiasing);
imgp.setCompositionMode(QPainter::CompositionMode_SourceOver);
imgp.drawImage(0, 0, tex);

texture = qCompress(QByteArray(reinterpret_cast<const char *>(img.bits()), 600*60*4));
}
MumbleProto::UserState mpus;
mpus.set_texture(blob(texture));
sendMessage(mpus);

if (! texture.isEmpty())
Database::setBlob(sha1(texture), texture);
}

void ServerHandler::requestBanList() { void ServerHandler::requestBanList() {
MumbleProto::BanList mpbl; MumbleProto::BanList mpbl;
mpbl.set_query(true); mpbl.set_query(true);
Expand Down Expand Up @@ -783,6 +740,52 @@ void ServerHandler::setUserComment(unsigned int uiSession, const QString &commen
sendMessage(mpus); sendMessage(mpus);
} }


void ServerHandler::setUserTexture(unsigned int uiSession, const QByteArray &qba) {
QByteArray texture;

if ((uiVersion >= 0x010202) || qba.isEmpty()) {
texture = qba;
} else {
QByteArray raw = qba;
QBuffer qb(& raw);
qb.open(QIODevice::ReadOnly);
QImageReader qir;
if (qba.startsWith("<?xml")) {
qir.setFormat("svg");
}
qir.setDevice(&qb);

QSize sz = qir.size();
sz.scale(600, 60, Qt::KeepAspectRatio);
qir.setScaledSize(sz);

QImage tex = qir.read();
if (tex.isNull()) {
return;
}

raw = QByteArray(600*60*4, 0);
QImage img(reinterpret_cast<unsigned char *>(raw.data()), 600, 60, QImage::Format_ARGB32);

QPainter imgp(&img);
imgp.setRenderHint(QPainter::Antialiasing);
imgp.setRenderHint(QPainter::TextAntialiasing);
imgp.setCompositionMode(QPainter::CompositionMode_SourceOver);
imgp.drawImage(0, 0, tex);

texture = qCompress(QByteArray(reinterpret_cast<const char *>(img.bits()), 600*60*4));
}

MumbleProto::UserState mpus;
mpus.set_session(uiSession);
mpus.set_texture(blob(texture));
sendMessage(mpus);

if (! texture.isEmpty()) {
Database::setBlob(sha1(texture), texture);
}
}

void ServerHandler::removeChannel(unsigned int channel) { void ServerHandler::removeChannel(unsigned int channel) {
MumbleProto::ChannelRemove mpcr; MumbleProto::ChannelRemove mpcr;
mpcr.set_channel_id(channel); mpcr.set_channel_id(channel);
Expand Down
2 changes: 1 addition & 1 deletion src/mumble/ServerHandler.h
Expand Up @@ -130,7 +130,6 @@ class ServerHandler : public QThread {
void requestUserStats(unsigned int uiSession, bool statsOnly); void requestUserStats(unsigned int uiSession, bool statsOnly);
void joinChannel(unsigned int channel); void joinChannel(unsigned int channel);
void createChannel(unsigned int parent_, const QString &name, const QString &description, unsigned int position, bool temporary); void createChannel(unsigned int parent_, const QString &name, const QString &description, unsigned int position, bool temporary);
void setTexture(const QByteArray &qba);
void requestBanList(); void requestBanList();
void requestUserList(); void requestUserList();
void requestACL(unsigned int channel); void requestACL(unsigned int channel);
Expand All @@ -139,6 +138,7 @@ class ServerHandler : public QThread {
void sendUserTextMessage(unsigned int uiSession, const QString &message_); void sendUserTextMessage(unsigned int uiSession, const QString &message_);
void sendChannelTextMessage(unsigned int channel, const QString &message_, bool tree); void sendChannelTextMessage(unsigned int channel, const QString &message_, bool tree);
void setUserComment(unsigned int uiSession, const QString &comment); void setUserComment(unsigned int uiSession, const QString &comment);
void setUserTexture(unsigned int uiSession, const QByteArray &qba);
void removeChannel(unsigned int channel); void removeChannel(unsigned int channel);
void addChannelLink(unsigned int channel, unsigned int link); void addChannelLink(unsigned int channel, unsigned int link);
void removeChannelLink(unsigned int channel, unsigned int link); void removeChannelLink(unsigned int channel, unsigned int link);
Expand Down
20 changes: 16 additions & 4 deletions src/murmur/Messages.cpp
Expand Up @@ -562,6 +562,16 @@ void Server::msgUserState(ServerUser *uSource, MumbleProto::UserState &msg) {
PERM_DENIED_TYPE(TextTooLong); PERM_DENIED_TYPE(TextTooLong);
return; return;
} }
if (uSource != pDstServerUser) {
if (! hasPermission(uSource, root, ChanACL::Move)) {
PERM_DENIED(uSource, root, ChanACL::Move);
return;
}
if (msg.texture().length() > 0) {
PERM_DENIED_TYPE(TextTooLong);
return;
}
}
} }




Expand All @@ -578,8 +588,9 @@ void Server::msgUserState(ServerUser *uSource, MumbleProto::UserState &msg) {
} }


// Prevent self-targeting state changes from being applied to others // Prevent self-targeting state changes from being applied to others
if ((pDstServerUser != uSource) && (msg.has_self_deaf() || msg.has_self_mute() || msg.has_texture() || msg.has_plugin_context() || msg.has_plugin_identity() || msg.has_recording())) if ((pDstServerUser != uSource) && (msg.has_self_deaf() || msg.has_self_mute() || msg.has_plugin_context() || msg.has_plugin_identity() || msg.has_recording())) {
return; return;
}


/* /*
-------------------- Permission checks done. Now act -------------------- -------------------- Permission checks done. Now act --------------------
Expand All @@ -588,13 +599,14 @@ void Server::msgUserState(ServerUser *uSource, MumbleProto::UserState &msg) {


if (msg.has_texture()) { if (msg.has_texture()) {
QByteArray qba = blob(msg.texture()); QByteArray qba = blob(msg.texture());
if (uSource->iId > 0) { if (pDstServerUser->iId > 0) {
// For registered users store the texture we just received in the database // For registered users store the texture we just received in the database
if (! setTexture(uSource->iId, qba)) if (! setTexture(pDstServerUser->iId, qba)) {
return; return;
}
} else { } else {
// For unregistered users or SuperUser only get the hash // For unregistered users or SuperUser only get the hash
hashAssign(uSource->qbaTexture, uSource->qbaTextureHash, qba); hashAssign(pDstServerUser->qbaTexture, pDstServerUser->qbaTextureHash, qba);
} }


// The texture will be sent out later in this function // The texture will be sent out later in this function
Expand Down

0 comments on commit 52d19ac

Please sign in to comment.