Temprary channels protocol changes

This commit is contained in:
Thorvald Natvig 2009-07-15 16:43:28 +02:00
parent 1ba33d093e
commit efbba85c60
13 changed files with 101 additions and 38 deletions

View File

@ -174,6 +174,9 @@ QString ChanACL::whatsThis(Perm p) {
case MakeChannel:
return tr("This represents the permission to make sub-channels. The user making the sub-channel will be added to the "
"admin group of the sub-channel.");
case MakeTempChannel:
return tr("This represents the permission to make a temporary subchannel. The user making the sub-channel will be added to the "
"admin group of the sub-channel. Temporary channels are not stored and disappear when the last user leaves.");
case LinkChannel:
return tr("This represents the permission to link channels. Users in linked channels hear each other, as long as "
"the speaking user has the <i>speak</i> privilege in the channel of the listener. You need the link "
@ -223,6 +226,8 @@ QString ChanACL::permName(Perm p) {
return tr("Move");
case MakeChannel:
return tr("Make channel");
case MakeTempChannel:
return tr("Make temporary channel");
case LinkChannel:
return tr("Link channel");
case TextMessage:

View File

@ -54,6 +54,7 @@ class ChanACL : public QObject {
LinkChannel = 0x80,
Whisper = 0x100,
TextMessage = 0x200,
MakeTempChannel = 0x400,
// Root channel only
Kick = 0x10000,

View File

@ -42,6 +42,7 @@ Channel::Channel(int id, const QString &name, QObject *p) : QObject(p) {
iId = id;
qsName = name;
bInheritACL = true;
bTemporary = false;
cParent = qobject_cast<Channel *>(p);
if (cParent)
cParent->addChannel(this);
@ -177,5 +178,5 @@ void Channel::removeUser(User *p) {
}
Channel::operator const QString() const {
return QString::fromLatin1("%1[%2:%3]").arg(qsName).arg(iId).arg(cParent ? cParent->iId : -1);
return QString::fromLatin1("%1[%2:%3%4]").arg(qsName).arg(iId).arg(cParent ? cParent->iId : -1).arg(bTemporary ? QLatin1String("*") : QLatin1String(""));
}

View File

@ -47,6 +47,7 @@ class Channel : public QObject {
QSet<Channel *> qsUnseen;
public:
int iId;
bool bTemporary;
Channel *cParent;
QString qsName;
QString qsDesc;

View File

@ -66,6 +66,7 @@ message ChannelState {
optional string description = 5;
repeated uint32 links_add = 6;
repeated uint32 links_remove = 7;
optional bool temporary = 8 [default = false];
}
message UserRemove {

View File

@ -321,6 +321,7 @@ void MainWindow::msgChannelState(const MumbleProto::ChannelState &msg) {
if (!c) {
if (msg.has_parent() && p && msg.has_name()) {
c = pmModel->addChannel(msg.channel_id(), p, u8(msg.name()));
c->bTemporary = msg.temporary();
p = NULL;
} else {
return;

View File

@ -412,7 +412,7 @@ void MurmurDBus::removeChannel(int id, const QDBusMessage &msg) {
qdbc.send(msg.createErrorReply("net.sourceforge.mumble.Error.channel", "Invalid channel id"));
return;
}
server->removeChannel(cChannel, NULL);
server->removeChannel(cChannel);
}
void MurmurDBus::getChannelState(int id, const QDBusMessage &msg, ChannelInfo &state) {

View File

@ -598,12 +598,23 @@ void Server::msgChannelState(ServerUser *uSource, MumbleProto::ChannelState &msg
if (! c) {
if (! p || qsName.isNull())
return;
if (! hasPermission(uSource, p, ChanACL::MakeChannel)) {
PERM_DENIED(uSource, p, ChanACL::MakeChannel);
ChanACL::Perm perm = msg.temporary() ? ChanACL::MakeTempChannel : ChanACL::MakeChannel;
if (! hasPermission(uSource, p, perm)) {
PERM_DENIED(uSource, p, perm);
return;
}
Channel *tmp = p;
while (tmp) {
if (tmp->bTemporary) {
PERM_DENIED(uSource, tmp, perm);
return;
}
tmp = tmp->cParent;
}
c = addChannel(p, qsName);
c = addChannel(p, qsName, msg.temporary());
c->qsDesc = qsDesc;
if (uSource->iId >= 0) {
Group *g = new Group(c, "admin");
@ -614,6 +625,15 @@ void Server::msgChannelState(ServerUser *uSource, MumbleProto::ChannelState &msg
msg.set_channel_id(c->iId);
log(uSource, QString("Added channel %1 under %2").arg(*c).arg(*p));
emit channelCreated(c);
sendAll(msg);
if (c->bTemporary) {
MumbleProto::UserState mpus;
mpus.set_session(uSource->uiSession);
mpus.set_channel_id(c->iId);
sendAll(mpus);
userEnterChannel(uSource, c);
}
} else {
if (! qsName.isNull()) {
if (! hasPermission(uSource, c, ChanACL::Write) || (c->iId == 0)) {
@ -713,9 +733,8 @@ void Server::msgChannelState(ServerUser *uSource, MumbleProto::ChannelState &msg
updateChannel(c);
emit channelStateChanged(c);
sendAll(msg);
}
sendAll(msg);
}
void Server::msgChannelRemove(ServerUser *uSource, MumbleProto::ChannelRemove &msg) {
@ -732,7 +751,7 @@ void Server::msgChannelRemove(ServerUser *uSource, MumbleProto::ChannelRemove &m
log(uSource, QString("Removed channel %1").arg(*c));
removeChannel(c, uSource);
removeChannel(c);
}
void Server::msgTextMessage(ServerUser *uSource, MumbleProto::TextMessage &msg) {

View File

@ -75,6 +75,8 @@ module Murmur
IntList links;
/** Description of channel. Shown as tooltip for this channel. */
string description;
/** Channel is temporary, and will be removed when the last user leaves it. */
bool temporary;
};
/** A group. Groups are defined per channel, and can inherit members from parent channels.
@ -108,14 +110,23 @@ module Murmur
const int PermissionWhisper = 0x100;
/** Mute and deafen other users in this channel. */
const int PermissionMuteDeafen = 0x10;
/** Move and Kick users from channel. You need this permission in both the source and destination channel to move another user.
* If you have this privilege on the root channel, you can ban users.
*/
const int PermissionMoveKick = 0x20;
/** Move users from channel. You need this permission in both the source and destination channel to move another user. */
const int PermissionMove = 0x20;
/** Make new channel as a subchannel of this channel. */
const int PermissionMakeChannel = 0x40;
/** Make new temporary channel as a subchannel of this channel. */
const int PermissionMakeTempChannel = 0x400;
/** Link this channel. You need this permission in both the source and destination channel to link channels, or in either channel to unlink them. */
const int PermissionLinkChannel = 0x80;
/** Send text message to channel. */
const int PermissionTextMessage = 0x200;
/** Kick user from server. Only valid on root channel. */
const int PermissionKick = 0x10000;
/** Ban user from server. Only valid on root channel. */
const int PermissionBan = 0x20000;
/** Register and unregister users. Only valid on root channel. */
const int PermissionRegister = 0x40000;
/** Access Control List for a channel. ACLs are defined per channel, and can be inherited from parent channels.
**/

View File

@ -114,6 +114,7 @@ static void channelToChannel(const ::Channel *c, Murmur::Channel &mc) {
mc.description = u8(c->qsDesc);
foreach(::Channel *chn, c->qsPermLinks)
mc.links.push_back(chn->iId);
mc.temporary = c->bTemporary;
}
static void ACLtoACL(const ::ChanACL *acl, Murmur::ACL &ma) {
@ -1014,7 +1015,7 @@ static void impl_Server_removeChannel(const ::Murmur::AMD_Server_removeChannelPt
if (!channel->cParent) {
cb->ice_exception(::Murmur::InvalidChannelException());
} else {
server->removeChannel(channel, NULL);
server->removeChannel(channel);
cb->ice_response();
}
}

View File

@ -1015,7 +1015,7 @@ void Server::sendProtoExcept(ServerUser *u, const ::google::protobuf::Message &m
usr->sendMessage(msg, msgType, cache);
}
void Server::removeChannel(Channel *chan, User *src, Channel *dest) {
void Server::removeChannel(Channel *chan, Channel *dest) {
Channel *c;
User *p;
@ -1025,7 +1025,7 @@ void Server::removeChannel(Channel *chan, User *src, Channel *dest) {
chan->unlink(NULL);
foreach(c, chan->qlChannels) {
removeChannel(c, src, dest);
removeChannel(c, dest);
}
foreach(p, chan->qlUsers) {
@ -1036,7 +1036,7 @@ void Server::removeChannel(Channel *chan, User *src, Channel *dest) {
mpus.set_channel_id(dest->iId);
sendAll(mpus);
userEnterChannel(p, dest);
userEnterChannel(p, dest, true);
}
MumbleProto::ChannelRemove mpcr;
@ -1054,7 +1054,7 @@ void Server::removeChannel(Channel *chan, User *src, Channel *dest) {
delete chan;
}
void Server::userEnterChannel(User *p, Channel *c, bool quiet) {
void Server::userEnterChannel(User *p, Channel *c, bool quiet, bool ignoretemp) {
clearACLCache(p);
if (quiet && (p->cChannel == c))
@ -1067,7 +1067,9 @@ void Server::userEnterChannel(User *p, Channel *c, bool quiet) {
if (quiet)
return;
Channel *old = p->cChannel;
setLastChannel(p);
bool mayspeak = hasPermission(static_cast<ServerUser *>(p), c, ChanACL::Speak);
@ -1085,6 +1087,10 @@ void Server::userEnterChannel(User *p, Channel *c, bool quiet) {
}
}
emit userStateChanged(p);
if (old->bTemporary && old->qlUsers.isEmpty() && ! ignoretemp) {
removeChannel(old);
}
}
bool Server::hasPermission(ServerUser *p, Channel *c, QFlags<ChanACL::Perm> perm) {

View File

@ -268,8 +268,8 @@ class Server : public QThread {
void log(const QString &);
void log(ServerUser *u, const QString &);
void removeChannel(Channel *c, User *src, Channel *dest = NULL);
void userEnterChannel(User *u, Channel *c, bool quiet = false);
void removeChannel(Channel *c, Channel *dest = NULL);
void userEnterChannel(User *u, Channel *c, bool quiet = false, bool ignoretemp = false);
Server(int snum, QObject *parent = NULL);
~Server();
@ -308,7 +308,7 @@ class Server : public QThread {
// Database / DBus functions. Implementation in ServerDB.cpp
void initialize();
int authenticate(QString &name, const QString &pw, const QStringList &emails = QStringList(), const QString &certhash = QString(), bool bStrongCert = false);
Channel *addChannel(Channel *c, const QString &name);
Channel *addChannel(Channel *c, const QString &name, bool temporary = false);
void removeChannel(const Channel *c);
void readChannels(Channel *p = NULL);
void readLinks();

View File

@ -337,7 +337,7 @@ ServerDB::ServerDB() {
SQLDO("INSERT INTO `%1user_info` SELECT `server_id`,`player_id`,'email',email FROM `%1players_old` WHERE `email` IS NOT NULL");
if (version == 3) {
SQLDO("INSERT INTO `%1channel_info` SELECT `server_id`,`channel_id`,'description',description FROM `%1channels_old` WHERE `description` IS NOT NULL");
SQLDO("INSERT INTO `%1channel_info` SELECT `server_id`,`channel_id`,'description',`description` FROM `%1channels_old` WHERE `description` IS NOT NULL");
}
qWarning("Removing old tables...");
@ -999,6 +999,8 @@ QByteArray Server::getUserTexture(int id) {
}
void Server::addLink(Channel *c, Channel *l) {
if (c->bTemporary || l->bTemporary)
return;
TransactionHolder th;
QSqlQuery &query = *th.qsqQuery;
@ -1017,6 +1019,8 @@ void Server::addLink(Channel *c, Channel *l) {
}
void Server::removeLink(Channel *c, Channel *l) {
if (c->bTemporary || l->bTemporary)
return;
TransactionHolder th;
QSqlQuery &query = *th.qsqQuery;
@ -1045,7 +1049,7 @@ void Server::removeLink(Channel *c, Channel *l) {
}
}
Channel *Server::addChannel(Channel *p, const QString &name) {
Channel *Server::addChannel(Channel *p, const QString &name, bool temporary) {
TransactionHolder th;
QSqlQuery &query = *th.qsqQuery;
@ -1056,31 +1060,41 @@ Channel *Server::addChannel(Channel *p, const QString &name) {
int id = 0;
if (query.next())
id = query.value(0).toInt();
SQLPREP("INSERT INTO `%1channels` (`server_id`, `parent_id`, `channel_id`, `name`) VALUES (?,?,?,?)");
query.addBindValue(iServerNum);
query.addBindValue(p->iId);
query.addBindValue(id);
query.addBindValue(name);
SQLEXEC();
// Temporary channels might "complicate" this somewhat.
while (qhChannels.contains(id))
++id;
if (! temporary) {
SQLPREP("INSERT INTO `%1channels` (`server_id`, `parent_id`, `channel_id`, `name`) VALUES (?,?,?,?)");
query.addBindValue(iServerNum);
query.addBindValue(p->iId);
query.addBindValue(id);
query.addBindValue(name);
SQLEXEC();
}
Channel *c = new Channel(id, name, p);
c->bTemporary = temporary;
qhChannels.insert(id, c);
return c;
}
void Server::removeChannel(const Channel *c) {
TransactionHolder th;
if (! c->bTemporary) {
TransactionHolder th;
QSqlQuery &query = *th.qsqQuery;
SQLPREP("DELETE FROM `%1channels` WHERE `server_id` = ? AND `channel_id` = ?");
query.addBindValue(iServerNum);
query.addBindValue(c->iId);
SQLEXEC();
QSqlQuery &query = *th.qsqQuery;
SQLPREP("DELETE FROM `%1channels` WHERE `server_id` = ? AND `channel_id` = ?");
query.addBindValue(iServerNum);
query.addBindValue(c->iId);
SQLEXEC();
}
qhChannels.remove(c->iId);
}
void Server::updateChannel(const Channel *c) {
if (c->bTemporary)
return;
TransactionHolder th;
Group *g;
ChanACL *acl;
@ -1274,9 +1288,11 @@ void Server::readLinks() {
}
void Server::setLastChannel(const User *p) {
if (p->iId < 0)
return;
if (p->cChannel->bTemporary)
return;
TransactionHolder th;
QSqlQuery &query = *th.qsqQuery;