Skip to content

Commit

Permalink
Add per-channel user limit
Browse files Browse the repository at this point in the history
  • Loading branch information
Tim Cooper authored and mkrautz committed Nov 22, 2015
1 parent 07a142d commit 84b1bce
Show file tree
Hide file tree
Showing 9 changed files with 77 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/Channel.cpp
Expand Up @@ -45,6 +45,7 @@ Channel::Channel(int id, const QString &name, QObject *p) : QObject(p) {
iPosition = 0; iPosition = 0;
qsName = name; qsName = name;
bInheritACL = true; bInheritACL = true;
uiMaxUsers = 0;
bTemporary = false; bTemporary = false;
cParent = qobject_cast<Channel *>(p); cParent = qobject_cast<Channel *>(p);
if (cParent) if (cParent)
Expand Down
6 changes: 6 additions & 0 deletions src/Channel.h
Expand Up @@ -68,6 +68,12 @@ class Channel : public QObject {


bool bInheritACL; bool bInheritACL;


/// Maximum number of users allowed in the channel. If this
/// value is zero, the maximum number of users allowed in the
/// channel is given by the server's "usersperchannel"
/// setting.
unsigned int uiMaxUsers;

Channel(int id, const QString &name, QObject *p = NULL); Channel(int id, const QString &name, QObject *p = NULL);
~Channel(); ~Channel();


Expand Down
4 changes: 4 additions & 0 deletions src/Mumble.proto
Expand Up @@ -134,6 +134,10 @@ message ChannelState {
optional int32 position = 9 [default = 0]; optional int32 position = 9 [default = 0];
// SHA1 hash of the description if the description is 128 bytes or more. // SHA1 hash of the description if the description is 128 bytes or more.
optional bytes description_hash = 10; optional bytes description_hash = 10;
// Maximum number of users allowed in the channel. If this value is zero,
// the maximum number of users allowed in the channel is given by the
// server's "usersperchannel" setting.
optional uint32 max_users = 11;
} }


// Used to communicate user leaving or being kicked. May be sent by the client // Used to communicate user leaving or being kicked. May be sent by the client
Expand Down
16 changes: 16 additions & 0 deletions src/mumble/ACLEditor.cpp
Expand Up @@ -63,6 +63,9 @@ ACLEditor::ACLEditor(int channelparentid, QWidget *p) : QDialog(p) {
qleChannelPassword->hide(); qleChannelPassword->hide();
qlChannelPassword->hide(); qlChannelPassword->hide();


qlChannelMaxUsers->hide();
qsbChannelMaxUsers->hide();

qlChannelID->hide(); qlChannelID->hide();


qleChannelName->setFocus(); qleChannelName->setFocus();
Expand Down Expand Up @@ -104,6 +107,15 @@ ACLEditor::ACLEditor(int channelid, const MumbleProto::ACL &mea, QWidget *p) : Q
qsbChannelPosition->setRange(INT_MIN, INT_MAX); qsbChannelPosition->setRange(INT_MIN, INT_MAX);
qsbChannelPosition->setValue(pChannel->iPosition); qsbChannelPosition->setValue(pChannel->iPosition);


if (g.sh->uiVersion >= 0x010300) {
qsbChannelMaxUsers->setRange(0, INT_MAX);
qsbChannelMaxUsers->setValue(pChannel->uiMaxUsers);
qsbChannelMaxUsers->setSpecialValueText(tr("Default server value"));
} else {
qlChannelMaxUsers->hide();
qsbChannelMaxUsers->hide();
}

QGridLayout *grid = new QGridLayout(qgbACLpermissions); QGridLayout *grid = new QGridLayout(qgbACLpermissions);


l = new QLabel(tr("Deny"), qgbACLpermissions); l = new QLabel(tr("Deny"), qgbACLpermissions);
Expand Down Expand Up @@ -282,6 +294,10 @@ void ACLEditor::accept() {
mpcs.set_position(qsbChannelPosition->value()); mpcs.set_position(qsbChannelPosition->value());
needs_update = true; needs_update = true;
} }
if (pChannel->uiMaxUsers != static_cast<unsigned int>(qsbChannelMaxUsers->value())) {
mpcs.set_max_users(qsbChannelMaxUsers->value());
needs_update = true;
}
if (needs_update) if (needs_update)
g.sh->sendMessage(mpcs); g.sh->sendMessage(mpcs);


Expand Down
25 changes: 25 additions & 0 deletions src/mumble/ACLEditor.ui
Expand Up @@ -88,6 +88,30 @@ This value enables you to change the way Mumble arranges the channels in the tre
</property> </property>
</widget> </widget>
</item> </item>
<item row="8" column="0">
<widget class="QLabel" name="qlChannelMaxUsers">
<property name="text">
<string>Maximum Users</string>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QSpinBox" name="qsbChannelMaxUsers">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Maximum number of users allowed in the channel</string>
</property>
<property name="whatsThis">
<string>&lt;b&gt;Maximum Users&lt;/b&gt;&lt;br /&gt;
This value allows you to set the maximum number of users allowed in the channel. If the value is above zero, only that number of users will be allowed to enter the channel. If the value is zero, the maximum number of users in the channel is given by the server's default limit.</string>
</property>
</widget>
</item>
<item row="10" column="1"> <item row="10" column="1">
<widget class="QCheckBox" name="qcbChannelTemporary"> <widget class="QCheckBox" name="qcbChannelTemporary">
<property name="toolTip"> <property name="toolTip">
Expand Down Expand Up @@ -668,6 +692,7 @@ Contains the list of members inherited by the current channel. Uncheck &lt;i&gt;
<tabstops> <tabstops>
<tabstop>qleChannelPassword</tabstop> <tabstop>qleChannelPassword</tabstop>
<tabstop>qsbChannelPosition</tabstop> <tabstop>qsbChannelPosition</tabstop>
<tabstop>qsbChannelMaxUsers</tabstop>
<tabstop>qcbChannelTemporary</tabstop> <tabstop>qcbChannelTemporary</tabstop>
<tabstop>qcbGroupList</tabstop> <tabstop>qcbGroupList</tabstop>
<tabstop>qpbGroupAdd</tabstop> <tabstop>qpbGroupAdd</tabstop>
Expand Down
4 changes: 4 additions & 0 deletions src/mumble/Messages.cpp
Expand Up @@ -674,6 +674,10 @@ void MainWindow::msgChannelState(const MumbleProto::ChannelState &msg) {
if (! ql.isEmpty()) if (! ql.isEmpty())
pmModel->linkChannels(c, ql); pmModel->linkChannels(c, ql);
} }

if (msg.has_max_users()) {
c->uiMaxUsers = msg.max_users();
}
} }


void MainWindow::msgChannelRemove(const MumbleProto::ChannelRemove &msg) { void MainWindow::msgChannelRemove(const MumbleProto::ChannelRemove &msg) {
Expand Down
12 changes: 11 additions & 1 deletion src/murmur/Messages.cpp
Expand Up @@ -257,6 +257,8 @@ void Server::msgAuthenticate(ServerUser *uSource, MumbleProto::Authenticate &msg
else if (! c->qsDesc.isEmpty()) else if (! c->qsDesc.isEmpty())
mpcs.set_description(u8(c->qsDesc)); mpcs.set_description(u8(c->qsDesc));


mpcs.set_max_users(c->uiMaxUsers);

sendMessage(uSource, mpcs); sendMessage(uSource, mpcs);


foreach(c, c->qlChannels) foreach(c, c->qlChannels)
Expand Down Expand Up @@ -518,7 +520,12 @@ void Server::msgUserState(ServerUser *uSource, MumbleProto::UserState &msg) {
PERM_DENIED(pDstServerUser, c, ChanACL::Enter); PERM_DENIED(pDstServerUser, c, ChanACL::Enter);
return; return;
} }
if (iMaxUsersPerChannel && (c->qlUsers.count() >= iMaxUsersPerChannel)) { if (c->uiMaxUsers) {
if (static_cast<unsigned int>(c->qlUsers.count()) >= c->uiMaxUsers) {
PERM_DENIED_FALLBACK(ChannelFull, 0x010201, QLatin1String("Channel is full"));
return;
}
} else if (iMaxUsersPerChannel && (c->qlUsers.count() >= iMaxUsersPerChannel)) {
PERM_DENIED_FALLBACK(ChannelFull, 0x010201, QLatin1String("Channel is full")); PERM_DENIED_FALLBACK(ChannelFull, 0x010201, QLatin1String("Channel is full"));
return; return;
} }
Expand Down Expand Up @@ -1061,6 +1068,9 @@ void Server::msgChannelState(ServerUser *uSource, MumbleProto::ChannelState &msg
removeLink(c, l); removeLink(c, l);
} }


if (msg.has_max_users())
c->uiMaxUsers = msg.max_users();

updateChannel(c); updateChannel(c);
emit channelStateChanged(c); emit channelStateChanged(c);


Expand Down
9 changes: 9 additions & 0 deletions src/murmur/ServerDB.cpp
Expand Up @@ -1401,6 +1401,13 @@ void Server::updateChannel(const Channel *c) {
query.addBindValue(QVariant(c->iPosition).toString()); query.addBindValue(QVariant(c->iPosition).toString());
SQLEXEC(); SQLEXEC();


// Update channel maximum users
query.addBindValue(iServerNum);
query.addBindValue(c->iId);
query.addBindValue(ServerDB::Channel_Max_Users);
query.addBindValue(QVariant(c->uiMaxUsers).toString());
SQLEXEC();

SQLPREP("DELETE FROM `%1groups` WHERE `server_id` = ? AND `channel_id` = ?"); SQLPREP("DELETE FROM `%1groups` WHERE `server_id` = ? AND `channel_id` = ?");
query.addBindValue(iServerNum); query.addBindValue(iServerNum);
query.addBindValue(c->iId); query.addBindValue(c->iId);
Expand Down Expand Up @@ -1480,6 +1487,8 @@ void Server::readChannelPrivs(Channel *c) {
hashAssign(c->qsDesc, c->qbaDescHash, value); hashAssign(c->qsDesc, c->qbaDescHash, value);
} else if (key == ServerDB::Channel_Position) { } else if (key == ServerDB::Channel_Position) {
c->iPosition = QVariant(value).toInt(); // If the conversion fails it'll return the default value 0 c->iPosition = QVariant(value).toInt(); // If the conversion fails it'll return the default value 0
} else if (key == ServerDB::Channel_Max_Users) {
c->uiMaxUsers = QVariant(value).toUInt(); // If the conversion fails it'll return the default value 0
} }
} }


Expand Down
2 changes: 1 addition & 1 deletion src/murmur/ServerDB.h
Expand Up @@ -43,7 +43,7 @@ class QSqlQuery;


class ServerDB { class ServerDB {
public: public:
enum ChannelInfo { Channel_Description, Channel_Position }; enum ChannelInfo { Channel_Description, Channel_Position, Channel_Max_Users };
enum UserInfo { User_Name, User_Email, User_Comment, User_Hash, User_Password, User_LastActive, User_KDFIterations }; enum UserInfo { User_Name, User_Email, User_Comment, User_Hash, User_Password, User_LastActive, User_KDFIterations };
ServerDB(); ServerDB();
~ServerDB(); ~ServerDB();
Expand Down

0 comments on commit 84b1bce

Please sign in to comment.