Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mumble-voip/mumble.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThorvald Natvig <slicer@users.sourceforge.net>2010-01-17 05:49:32 +0300
committerThorvald Natvig <slicer@users.sourceforge.net>2010-01-17 05:49:40 +0300
commit60e71510bfc097b97ee77073db8a12663aca064a (patch)
tree72175fd1fb7215b677dcaa1e8744560bb6f10dca
parentad0f30f6d12d4bbf97d6b3a1b92ffbc3f61791da (diff)
Serverside comment/texture send-on-demand
-rw-r--r--src/Channel.h1
-rw-r--r--src/Message.h19
-rw-r--r--src/Mumble.proto9
-rw-r--r--src/User.h2
-rw-r--r--src/murmur/Messages.cpp123
-rw-r--r--src/murmur/Server.cpp28
-rw-r--r--src/murmur/Server.h11
-rw-r--r--src/murmur/ServerDB.cpp8
8 files changed, 168 insertions, 33 deletions
diff --git a/src/Channel.h b/src/Channel.h
index 36d377517..b2c682844 100644
--- a/src/Channel.h
+++ b/src/Channel.h
@@ -52,6 +52,7 @@ class Channel : public QObject {
Channel *cParent;
QString qsName;
QString qsDesc;
+ QByteArray qbaDescHash;
QList<Channel *> qlChannels;
QList<User *> qlUsers;
QHash<QString, Group *> qhGroups;
diff --git a/src/Message.h b/src/Message.h
index 17c0a3baf..7980606ca 100644
--- a/src/Message.h
+++ b/src/Message.h
@@ -57,7 +57,8 @@
MUMBLE_MH_MSG(VoiceTarget) \
MUMBLE_MH_MSG(PermissionQuery) \
MUMBLE_MH_MSG(CodecVersion) \
- MUMBLE_MH_MSG(UserStats)
+ MUMBLE_MH_MSG(UserStats) \
+ MUMBLE_MH_MSG(RequestBlob)
class MessageHandler {
public:
@@ -83,6 +84,22 @@ inline ::std::string u8(const QString &str) {
return ::std::string(qba.constData(), qba.length());
}
+inline QByteArray blob(const ::std::string &str) {
+ return QByteArray(str.data(), static_cast<int>(str.length()));
+}
+
+inline ::std::string blob(const QByteArray &str) {
+ return ::std::string(str.constData(), str.length());
+}
+
+inline QByteArray sha1(const QByteArray &blob) {
+ return QCryptographicHash::hash(blob, QCryptographicHash::Sha1);
+}
+
+inline QByteArray sha1(const QString &str) {
+ return QCryptographicHash::hash(str.toUtf8(), QCryptographicHash::Sha1);
+}
+
#else
class Message;
#endif
diff --git a/src/Mumble.proto b/src/Mumble.proto
index b329c696c..071b5e992 100644
--- a/src/Mumble.proto
+++ b/src/Mumble.proto
@@ -71,6 +71,7 @@ message ChannelState {
repeated uint32 links_remove = 7;
optional bool temporary = 8 [default = false];
optional int32 position = 9 [default = 0];
+ optional bytes description_hash = 10;
}
message UserRemove {
@@ -96,6 +97,8 @@ message UserState {
optional string plugin_identity = 13;
optional string comment = 14;
optional string hash = 15;
+ optional bytes comment_hash = 16;
+ optional bytes texture_hash = 17;
}
message BanList {
@@ -256,3 +259,9 @@ message UserStats {
optional uint32 idlesecs = 17;
optional bool strong_certificate = 18 [default = false];
}
+
+message RequestBlob {
+ repeated uint32 session_texture = 1;
+ repeated uint32 session_comment = 2;
+ repeated uint32 channel_description = 3;
+}
diff --git a/src/User.h b/src/User.h
index d47862a07..30acb0238 100644
--- a/src/User.h
+++ b/src/User.h
@@ -43,11 +43,13 @@ class User {
int iId;
QString qsName;
QString qsComment;
+ QByteArray qbaCommentHash;
QString qsHash;
bool bMute, bDeaf, bSuppress;
bool bSelfMute, bSelfDeaf;
Channel *cChannel;
QByteArray qbaTexture;
+ QByteArray qbaTextureHash;
User();
virtual ~User() {};
diff --git a/src/murmur/Messages.cpp b/src/murmur/Messages.cpp
index 416e8df48..0bb4a7867 100644
--- a/src/murmur/Messages.cpp
+++ b/src/murmur/Messages.cpp
@@ -220,7 +220,7 @@ void Server::msgAuthenticate(ServerUser *uSource, MumbleProto::Authenticate &msg
uSource->qlCodecs.append(static_cast<qint32>(0x8000000a));
}
recheckCodecVersions();
-
+
MumbleProto::CodecVersion mpcv;
mpcv.set_alpha(iCodecAlpha);
mpcv.set_beta(iCodecBeta);
@@ -245,10 +245,14 @@ void Server::msgAuthenticate(ServerUser *uSource, MumbleProto::Authenticate &msg
mpcs.set_name(u8(qsRegName.isEmpty() ? QLatin1String("Root") : qsRegName));
else
mpcs.set_name(u8(c->qsName));
- if (! c->qsDesc.isEmpty())
- mpcs.set_description(u8(c->qsDesc));
+
mpcs.set_position(c->iPosition);
+ if ((uSource->uiVersion >= 0x010202) && ! c->qbaDescHash.isEmpty())
+ mpcs.set_description_hash(blob(c->qbaDescHash));
+ else if (! c->qsDesc.isEmpty())
+ mpcs.set_description(u8(c->qsDesc));
+
sendMessage(uSource, mpcs);
foreach(c, c->qlChannels)
@@ -281,20 +285,27 @@ void Server::msgAuthenticate(ServerUser *uSource, MumbleProto::Authenticate &msg
lc = root;
userEnterChannel(uSource, lc, mpus);
-
+
uSource->sState = ServerUser::Authenticated;
mpus.set_session(uSource->uiSession);
mpus.set_name(u8(uSource->qsName));
if (uSource->iId >= 0) {
- uSource->qbaTexture = getUserTexture(uSource->iId);
mpus.set_user_id(uSource->iId);
- if (! uSource->qbaTexture.isEmpty())
+
+ hashAssign(uSource->qbaTexture, uSource->qbaTextureHash, getUserTexture(uSource->iId));
+
+ if (! uSource->qbaTextureHash.isEmpty())
+ mpus.set_texture_hash(blob(uSource->qbaTextureHash));
+ else if (! uSource->qbaTexture.isEmpty())
mpus.set_texture(std::string(uSource->qbaTexture.constData(), uSource->qbaTexture.size()));
const QMap<int, QString> &info = getRegistration(uSource->iId);
if (info.contains(ServerDB::User_Comment)) {
- uSource->qsComment = info.value(ServerDB::User_Comment);
- mpus.set_comment(u8(uSource->qsComment));
+ hashAssign(uSource->qsComment, uSource->qbaCommentHash, info.value(ServerDB::User_Comment));
+ if (! uSource->qbaCommentHash.isEmpty())
+ mpus.set_comment_hash(blob(uSource->qbaCommentHash));
+ else if (! uSource->qsComment.isEmpty())
+ mpus.set_comment(u8(uSource->qsComment));
}
}
if (! uSource->qsHash.isEmpty())
@@ -302,7 +313,13 @@ void Server::msgAuthenticate(ServerUser *uSource, MumbleProto::Authenticate &msg
if (uSource->cChannel->iId != 0)
mpus.set_channel_id(uSource->cChannel->iId);
- sendAll(mpus);
+ sendAll(mpus, 0x010202);
+
+ if (! uSource->qbaTexture.isEmpty())
+ mpus.set_texture(blob(uSource->qbaTexture));
+ if (! uSource->qsComment.isEmpty())
+ mpus.set_comment(u8(uSource->qsComment));
+ sendAll(mpus, ~ 0x010202);
// Transmit other users profiles
foreach(ServerUser *u, qhUsers) {
@@ -333,7 +350,9 @@ void Server::msgAuthenticate(ServerUser *uSource, MumbleProto::Authenticate &msg
mpus.set_self_deaf(true);
else if (u->bSelfMute)
mpus.set_self_mute(true);
- if (! u->qsComment.isEmpty())
+ if ((uSource->uiVersion >= 0x010202) && ! u->qbaCommentHash.isEmpty())
+ mpus.set_comment_hash(blob(u->qbaCommentHash));
+ else if (! u->qsComment.isEmpty())
mpus.set_comment(u8(u->qsComment));
if (! u->qsHash.isEmpty())
mpus.set_hash(u8(u->qsHash));
@@ -543,9 +562,11 @@ void Server::msgUserState(ServerUser *uSource, MumbleProto::UserState &msg) {
if (msg.has_comment()) {
pDstServerUser->qsComment = u8(msg.comment());
-
- if (! bAllowHTML) {
- pDstServerUser->qsComment = toPlainText(pDstServerUser->qsComment);
+
+ if (bAllowHTML) {
+ hashAssign(pDstServerUser->qsComment, pDstServerUser->qbaCommentHash, u8(msg.comment()));
+ } else {
+ hashAssign(pDstServerUser->qsComment, pDstServerUser->qbaCommentHash, toPlainText(u8(msg.comment())));
msg.set_comment(u8(pDstServerUser->qsComment));
}
@@ -603,8 +624,18 @@ void Server::msgUserState(ServerUser *uSource, MumbleProto::UserState &msg) {
}
}
- if (! bNoBroadcast)
- sendAll(msg);
+ if (! bNoBroadcast) {
+ sendAll(msg, ~ 0x010202);
+ if (msg.has_texture() && ! pDstServerUser->qbaTextureHash.isEmpty()) {
+ msg.clear_texture();
+ msg.set_texture_hash(blob(pDstServerUser->qbaTextureHash));
+ }
+ if (msg.has_comment() && ! pDstServerUser->qbaCommentHash.isEmpty()) {
+ msg.clear_comment();
+ msg.set_comment_hash(blob(pDstServerUser->qbaCommentHash));
+ }
+ sendAll(msg, 0x010202);
+ }
emit userStateChanged(pDstServerUser);
}
@@ -732,7 +763,7 @@ void Server::msgChannelState(ServerUser *uSource, MumbleProto::ChannelState &msg
}
c = addChannel(p, qsName, msg.temporary(), msg.position());
- c->qsDesc = qsDesc;
+ hashAssign(c->qsDesc, c->qbaDescHash, qsDesc);
if (uSource->iId >= 0) {
Group *g = new Group(c, "admin");
@@ -757,7 +788,13 @@ void Server::msgChannelState(ServerUser *uSource, MumbleProto::ChannelState &msg
msg.set_channel_id(c->iId);
log(uSource, QString("Added channel %1 under %2").arg(QString(*c), QString(*p)));
emit channelCreated(c);
- sendAll(msg);
+
+ sendAll(msg, ~ 0x010202);
+ if (! c->qbaDescHash.isEmpty()) {
+ msg.clear_description();
+ msg.set_description_hash(blob(c->qbaDescHash));
+ }
+ sendAll(msg, 0x010202);
if (c->bTemporary) {
// If a temporary channel has been created move the creator right in there
@@ -875,7 +912,7 @@ void Server::msgChannelState(ServerUser *uSource, MumbleProto::ChannelState &msg
c->qsName = qsName;
}
if (! qsDesc.isNull())
- c->qsDesc = qsDesc;
+ hashAssign(c->qsDesc, c->qbaDescHash, qsDesc);
if (msg.has_position())
c->iPosition = msg.position();
@@ -889,7 +926,13 @@ void Server::msgChannelState(ServerUser *uSource, MumbleProto::ChannelState &msg
updateChannel(c);
emit channelStateChanged(c);
- sendAll(msg);
+
+ sendAll(msg, ~ 0x010202);
+ if (msg.has_description() && ! c->qbaDescHash.isEmpty()) {
+ msg.clear_description();
+ msg.set_description_hash(blob(c->qbaDescHash));
+ }
+ sendAll(msg, 0x010202);
}
}
@@ -1444,3 +1487,45 @@ void Server::msgUserStats(ServerUser*uSource, MumbleProto::UserStats &msg) {
sendMessage(uSource, msg);
}
+
+void Server::msgRequestBlob(ServerUser *uSource, MumbleProto::RequestBlob &msg) {
+ int ntextures = msg.session_texture_size();
+ int ncomments = msg.session_comment_size();
+ int ndescriptions = msg.channel_description_size();
+
+ if (ndescriptions) {
+ MumbleProto::ChannelState mpcs;
+ for(int i=0;i<ndescriptions;++i) {
+ int id = msg.channel_description(i);
+ Channel *c = qhChannels.value(id);
+ if (c && ! c->qsDesc.isEmpty()) {
+ mpcs.set_channel_id(id);
+ mpcs.set_description(u8(c->qsDesc));
+ sendMessage(uSource, mpcs);
+ }
+ }
+ }
+ if (ntextures || ncomments) {
+ MumbleProto::UserState mpus;
+ for(int i=0;i<ntextures;++i) {
+ int session = msg.session_texture(i);
+ ServerUser *su = qhUsers.value(session);
+ if (su && ! su->qbaTexture.isEmpty()) {
+ mpus.set_session(session);
+ mpus.set_texture(std::string(su->qbaTexture.constData(), su->qbaTexture.length()));
+ sendMessage(uSource, mpus);
+ }
+ }
+ if (ntextures)
+ mpus.clear_texture();
+ for(int i=0;i<ncomments;++i) {
+ int session = msg.session_comment(i);
+ ServerUser *su = qhUsers.value(session);
+ if (su && ! su->qsComment.isEmpty()) {
+ mpus.set_session(session);
+ mpus.set_comment(u8(su->qsComment));
+ sendMessage(uSource, mpus);
+ }
+ }
+ }
+}
diff --git a/src/murmur/Server.cpp b/src/murmur/Server.cpp
index c9f041776..f42683d2f 100644
--- a/src/murmur/Server.cpp
+++ b/src/murmur/Server.cpp
@@ -108,7 +108,7 @@ Server::Server(int snum, QObject *p) : QThread(p) {
iCodecAlpha = iCodecBeta = 0;
bPreferAlpha = false;
-
+
qnamNetwork = NULL;
readParams();
@@ -1230,15 +1230,16 @@ void Server::sendProtoMessage(ServerUser *u, const ::google::protobuf::Message &
u->sendMessage(msg, msgType, cache);
}
-void Server::sendProtoAll(const ::google::protobuf::Message &msg, unsigned int msgType) {
- sendProtoExcept(NULL, msg, msgType);
+void Server::sendProtoAll(const ::google::protobuf::Message &msg, unsigned int msgType, unsigned int minversion) {
+ sendProtoExcept(NULL, msg, msgType, minversion);
}
-void Server::sendProtoExcept(ServerUser *u, const ::google::protobuf::Message &msg, unsigned int msgType) {
+void Server::sendProtoExcept(ServerUser *u, const ::google::protobuf::Message &msg, unsigned int msgType, unsigned int minversion) {
QByteArray cache;
foreach(ServerUser *usr, qhUsers)
if ((usr != u) && (usr->sState == ServerUser::Authenticated))
- usr->sendMessage(msg, msgType, cache);
+ if ((minversion == 0) || (usr->uiVersion >= minversion) || ((minversion & 0x80000000) && (usr->uiVersion < (~minversion))))
+ usr->sendMessage(msg, msgType, cache);
}
void Server::removeChannel(int id) {
@@ -1501,6 +1502,7 @@ void Server::recheckCodecVersions() {
QMap<int, unsigned int> qmCodecUsercount;
QMap<int, unsigned int>::const_iterator i;
int users = 0;
+
// Count how many users use which codec
foreach(ServerUser *u, qhUsers) {
if (u->qlCodecs.isEmpty())
@@ -1553,3 +1555,19 @@ void Server::recheckCodecVersions() {
log(QString::fromLatin1("CELT codec switch %1 %2 (prefer %3)").arg(iCodecAlpha,0,16).arg(iCodecBeta,0,16).arg(bPreferAlpha ? iCodecAlpha : iCodecBeta,0,16));
}
+
+void Server::hashAssign(QString &dest, QByteArray &hash, const QString &src) {
+ dest = src;
+ if (src.length() > 128)
+ hash = sha1(dest);
+ else
+ hash = QByteArray();
+}
+
+void Server::hashAssign(QByteArray &dest, QByteArray &hash, const QByteArray &src) {
+ dest = src;
+ if (src.length() > 128)
+ hash = sha1(dest);
+ else
+ hash = QByteArray();
+}
diff --git a/src/murmur/Server.h b/src/murmur/Server.h
index 2a78a0b79..e202b6146 100644
--- a/src/murmur/Server.h
+++ b/src/murmur/Server.h
@@ -294,18 +294,21 @@ class Server : public QThread {
void flushClientPermissionCache(ServerUser *u, MumbleProto::PermissionQuery &mpqq);
void clearACLCache(User *p = NULL);
- void sendProtoAll(const ::google::protobuf::Message &msg, unsigned int msgType);
- void sendProtoExcept(ServerUser *, const ::google::protobuf::Message &msg, unsigned int msgType);
+ void sendProtoAll(const ::google::protobuf::Message &msg, unsigned int msgType, unsigned int minversion);
+ void sendProtoExcept(ServerUser *, const ::google::protobuf::Message &msg, unsigned int msgType, unsigned int minversion);
void sendProtoMessage(ServerUser *, const ::google::protobuf::Message &msg, unsigned int msgType);
#define MUMBLE_MH_MSG(x) \
- void sendAll(const MumbleProto:: x &msg) { sendProtoAll(msg, MessageHandler:: x); } \
- void sendExcept(ServerUser *u, const MumbleProto:: x &msg) { sendProtoExcept(u, msg, MessageHandler:: x); } \
+ void sendAll(const MumbleProto:: x &msg, unsigned int v = 0) { sendProtoAll(msg, MessageHandler:: x, v); } \
+ void sendExcept(ServerUser *u, const MumbleProto:: x &msg, unsigned int v = 0) { sendProtoExcept(u, msg, MessageHandler:: x, v); } \
void sendMessage(ServerUser *u, const MumbleProto:: x &msg) { sendProtoMessage(u, msg, MessageHandler:: x); }
MUMBLE_MH_ALL
#undef MUMBLE_MH_MSG
+ static void hashAssign(QString &destination, QByteArray &hash, const QString &str);
+ static void hashAssign(QByteArray &destination, QByteArray &hash, const QByteArray &source);
+
void setLiveConf(const QString &key, const QString &value);
QString addressToString(const QHostAddress &, unsigned short port);
diff --git a/src/murmur/ServerDB.cpp b/src/murmur/ServerDB.cpp
index d78f4f0fe..dc1b66750 100644
--- a/src/murmur/ServerDB.cpp
+++ b/src/murmur/ServerDB.cpp
@@ -762,7 +762,7 @@ int Server::authenticate(QString &name, const QString &pw, const QStringList &em
if (query.next()) {
res = -1;
QString storedpw = query.value(2).toString();
- QString hashedpw = QString::fromLatin1(QCryptographicHash::hash(pw.toUtf8(), QCryptographicHash::Sha1).toHex());
+ QString hashedpw = QString::fromLatin1(sha1(pw).toHex());
if (! storedpw.isEmpty() && (storedpw == hashedpw)) {
name = query.value(1).toString();
@@ -932,8 +932,8 @@ bool Server::setTexture(int id, const QByteArray &texture) {
tex = qCompress(tex);
ServerUser *u = qhUsers.value(id);
- if (u)
- u->qbaTexture = tex;
+ if (u)
+ hashAssign(u->qbaTexture, u->qbaTextureHash, tex);
int res = -2;
emit setTextureSig(res, id, tex);
@@ -1248,7 +1248,7 @@ void Server::readChannelPrivs(Channel *c) {
int key = query.value(0).toInt();
const QString &value = query.value(1).toString();
if (key == ServerDB::Channel_Description) {
- c->qsDesc = value;
+ hashAssign(c->qsDesc, c->qbaDescHash, value);
} else if (key == ServerDB::Channel_Position) {
c->iPosition = QVariant(value).toInt(); // If the conversion fails it'll return the default value 0
}