diff options
-rw-r--r-- | src/ACL.cpp | 6 | ||||
-rw-r--r-- | src/ACL.h | 2 | ||||
-rw-r--r-- | src/Group.cpp | 4 | ||||
-rw-r--r-- | src/Group.h | 2 | ||||
-rw-r--r-- | src/Message.cpp | 18 | ||||
-rw-r--r-- | src/Message.h | 52 | ||||
-rw-r--r-- | src/Mumble.proto | 6 | ||||
-rw-r--r-- | src/PacketDataStream.h | 406 | ||||
-rw-r--r-- | src/Player.cpp | 18 | ||||
-rw-r--r-- | src/Player.h | 5 | ||||
-rw-r--r-- | src/mumble/ACLEditor.cpp | 413 | ||||
-rw-r--r-- | src/mumble/ACLEditor.h | 32 | ||||
-rw-r--r-- | src/mumble/AudioInput.cpp | 30 | ||||
-rw-r--r-- | src/mumble/AudioOutput.cpp | 8 | ||||
-rw-r--r-- | src/mumble/AudioOutput.h | 36 | ||||
-rw-r--r-- | src/mumble/BanEditor.cpp | 38 | ||||
-rw-r--r-- | src/mumble/BanEditor.h | 2 | ||||
-rw-r--r-- | src/mumble/MainWindow.cpp | 284 | ||||
-rw-r--r-- | src/mumble/MainWindow.h | 51 | ||||
-rw-r--r-- | src/mumble/Messages.cpp | 515 | ||||
-rw-r--r-- | src/mumble/Overlay.cpp | 9 | ||||
-rw-r--r-- | src/mumble/Overlay.h | 1 | ||||
-rw-r--r-- | src/mumble/PlayerModel.cpp | 16 | ||||
-rw-r--r-- | src/mumble/ServerHandler.cpp | 154 | ||||
-rw-r--r-- | src/mumble/ServerHandler.h | 14 | ||||
-rw-r--r-- | src/murmur/Messages.cpp | 1 | ||||
-rw-r--r-- | src/murmur/Server.cpp | 2 |
27 files changed, 1227 insertions, 898 deletions
diff --git a/src/ACL.cpp b/src/ACL.cpp index 70d88a30b..8c8fb9e57 100644 --- a/src/ACL.cpp +++ b/src/ACL.cpp @@ -33,14 +33,16 @@ #include "Group.h" #include "Player.h" -ChanACL::ChanACL(Channel *chan) { +ChanACL::ChanACL(Channel *chan) : QObject(chan) { bApplyHere = true; bApplySubs = true; + bInherited = false; iPlayerId = -1; c = chan; - c->qlACL << this; + if (c) + c->qlACL << this; } // Check permissions. @@ -65,6 +65,8 @@ class ChanACL : public QObject { bool bApplyHere; bool bApplySubs; + bool bInherited; + int iPlayerId; QString qsGroup; Permissions pAllow; diff --git a/src/Group.cpp b/src/Group.cpp index 6d972e2a8..a834efc35 100644 --- a/src/Group.cpp +++ b/src/Group.cpp @@ -36,8 +36,10 @@ Group::Group(Channel *assoc, QString name) { c = assoc; bInherit = true; bInheritable = true; + bInherited = false; qsName = name; - c->qhGroups[name] = this; + if (c) + c->qhGroups[name] = this; } QSet<int> Group::members() { diff --git a/src/Group.h b/src/Group.h index 724f1a00f..5a1fe8883 100644 --- a/src/Group.h +++ b/src/Group.h @@ -44,6 +44,8 @@ class Group { QString qsName; bool bInherit; bool bInheritable; + // TODO: Make local class for ACLEditor, inherited from this + bool bInherited; QSet<int> qsAdd; QSet<int> qsRemove; QSet<int> qsTemporary; diff --git a/src/Message.cpp b/src/Message.cpp index e26aa94d0..7e42de08a 100644 --- a/src/Message.cpp +++ b/src/Message.cpp @@ -31,7 +31,8 @@ #include "Message.h" #include "murmur_pch.h" -void MessageHandler::dispatch(Connection *cCon, int type, const QByteArray &msg) { +void MessageHandler::dispatch(Connection *cCon, const QByteArray &msg) { +/* switch (type) { case MessageHandler::Version: { MumbleProto::Version mpv; @@ -42,4 +43,19 @@ void MessageHandler::dispatch(Connection *cCon, int type, const QByteArray &msg) default: break; } +*/ +} + +void MessageHandler::messageToNetwork(const ::google::protobuf::Message &msg, unsigned int msgType, QByteArray &cache) { + int len = msg.ByteSize(); + if (len > 0x7fffff) + return; + cache.resize(len + 4); + unsigned char *uc = reinterpret_cast<unsigned char *>(cache.data()); + uc[0] = msgType; + uc[1] = (len >> 16) & 0xFF; + uc[2] = (len >> 8) & 0xFF; + uc[3] = len & 0xFF; + + msg.SerializeToArray(uc + 4, len); } diff --git a/src/Message.h b/src/Message.h index 5e2eb2f21..1cf5a5489 100644 --- a/src/Message.h +++ b/src/Message.h @@ -34,30 +34,42 @@ #include "Connection.h" #include "Mumble.pb.h" +#define MUMBLE_MH_ALL \ + MUMBLE_MH_MSG(Version) \ + MUMBLE_MH_MSG(UDPTunnel) \ + MUMBLE_MH_MSG(Authenticate) \ + MUMBLE_MH_MSG(Ping) \ + MUMBLE_MH_MSG(Reject) \ + MUMBLE_MH_MSG(ServerSync) \ + MUMBLE_MH_MSG(ChannelRemove) \ + MUMBLE_MH_MSG(ChannelState) \ + MUMBLE_MH_MSG(UserRemove) \ + MUMBLE_MH_MSG(UserState) \ + MUMBLE_MH_MSG(BanList) \ + MUMBLE_MH_MSG(TextMessage) \ + MUMBLE_MH_MSG(PermissionDenied) \ + MUMBLE_MH_MSG(ACL) \ + MUMBLE_MH_MSG(QueryUsers) \ + MUMBLE_MH_MSG(CryptSetup) \ + MUMBLE_MH_MSG(ContextActionAdd) \ + MUMBLE_MH_MSG(ContextAction) + class MessageHandler { public: enum UDPMessageType { UDPVoice, UDPPing }; - enum MessageType { Version, UDPTunnel, Authenticate, Ping, Reject, ServerSync, ChannelRemove, ChannelState, UserRemove, UserState, BanList, TextMessage, PermissionDenied, ACL, QueryUsers, CryptSetup, ContextActionAdd, ContextAction }; + +#define MUMBLE_MH_MSG(x) x, + enum MessageType { + MUMBLE_MH_ALL + }; +#undef MUMBLE_MH_MSG + static void messageToNetwork(const ::google::protobuf::Message &msg, unsigned int msgType, QByteArray &cache); + protected: - virtual void msgVersion(Connection *, MumbleProto::Version *) = 0; - virtual void msgUDPTunnel(Connection *, MumbleProto::UDPTunnel *) = 0; - virtual void msgAuthenticate(Connection *, MumbleProto::Authenticate *) = 0; - virtual void msgPing(Connection *, MumbleProto::Ping *) = 0; - virtual void msgReject(Connection *, MumbleProto::Reject *) = 0; - virtual void msgServerSync(Connection *, MumbleProto::ServerSync *) = 0; - virtual void msgChannelRemove(Connection *, MumbleProto::ChannelRemove *) = 0; - virtual void msgChannelState(Connection *, MumbleProto::ChannelState *) = 0; - virtual void msgUserRemove(Connection *, MumbleProto::UserRemove *) = 0; - virtual void msgUserState(Connection *, MumbleProto::UserState *) = 0; - virtual void msgBanList(Connection *, MumbleProto::BanList *) = 0; - virtual void msgTextMessage(Connection *, MumbleProto::TextMessage *) = 0; - virtual void msgPermissionDenied(Connection *, MumbleProto::PermissionDenied *) = 0; - virtual void msgACL(Connection *, MumbleProto::ACL *) = 0; - virtual void msgQueryUsers(Connection *, MumbleProto::QueryUsers *) = 0; - virtual void msgCryptSetup(Connection *, MumbleProto::CryptSetup *) = 0; - virtual void msgContextActionAdd(Connection *, MumbleProto::ContextActionAdd *) = 0; - virtual void msgContextAction(Connection *, MumbleProto::ContextAction *) = 0; - void dispatch(Connection *, int type, const QByteArray &); +#define MUMBLE_MH_MSG(x) virtual void msg##x(Connection *, MumbleProto::##x *) = 0; + MUMBLE_MH_ALL +#undef MUMBLE_MH_MSG + void dispatch(Connection *, const QByteArray &); virtual ~MessageHandler() { }; }; diff --git a/src/Mumble.proto b/src/Mumble.proto index 85f56ca80..9908c5156 100644 --- a/src/Mumble.proto +++ b/src/Mumble.proto @@ -147,9 +147,9 @@ message CryptSetup { message ContextActionAdd { enum Context { - CtxServer = 0x01; - CtxChannel = 0x02; - CtxUser = 0x04; + Server = 0x01; + Channel = 0x02; + User = 0x04; } required string action = 1; required string text = 2; diff --git a/src/PacketDataStream.h b/src/PacketDataStream.h new file mode 100644 index 000000000..948cb03dd --- /dev/null +++ b/src/PacketDataStream.h @@ -0,0 +1,406 @@ +/* Copyright (C) 2005-2009, Thorvald Natvig <thorvald@natvig.com> + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + - Neither the name of the Mumble Developers nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _PACKETDATASTREAM_H +#define _PACKETDATASTREAM_H + +/* + * GCC doesn't yet do inter-object-file inlining, so unfortunately, this all has to be defined here. + */ + +class PacketDataStream { + private: + Q_DISABLE_COPY(PacketDataStream) + private: + unsigned char *data; + quint32 maxsize; + quint32 offset; + quint32 overshoot; + bool ok; + public: + quint32 size() const { + return offset; + } + + quint32 capacity() const { + return maxsize; + } + + bool isValid() const { + return ok; + } + + quint32 left() const { + return maxsize - offset; + } + + quint32 undersize() const { + return overshoot; + } + + void append(const quint64 v) { +#ifndef QT_NO_DEBUG + Q_ASSERT(v <= 0xff); +#endif + if (offset < maxsize) + data[offset++] = static_cast<unsigned char>(v); + else { + ok = false; + overshoot++; + } + }; + + void append(const char *d, quint32 len) { + if (left() >= len) { + memcpy(& data[offset], d, len); + offset += len; + } else { + int l = left(); + memset(& data[offset], 0, l); + offset += l; + overshoot += len - l; + ok = false; + } + } + + void skip(quint32 len) { + if (left() >= len) + offset += len; + else + ok = false; + } + + quint64 next() { + if (offset < maxsize) + return data[offset++]; + else { + ok = false; + return 0; + } + }; + + void rewind() { + offset = 0; + } + + void truncate() { + maxsize = offset; + } + + const unsigned char *dataPtr() const { + return reinterpret_cast<const unsigned char *>(& data[offset]); + } + + const char *charPtr() const { + return reinterpret_cast<const char *>(& data[offset]); + } + + QByteArray dataBlock(quint32 len) { + if (len <= left()) { + QByteArray a(charPtr(), len); + offset +=len; + return a; + } else { + ok = false; + return QByteArray(); + } + } + + protected: + void setup(unsigned char *d, int msize) { + data = d; + offset = 0; + overshoot = 0; + maxsize = msize; + ok = true; + } + public: + PacketDataStream(const char *d, int msize) { + setup(const_cast<unsigned char *>(reinterpret_cast<const unsigned char *>(d)), msize); + }; + + PacketDataStream(char *d, int msize) { + setup(reinterpret_cast<unsigned char *>(d), msize); + }; + + PacketDataStream(unsigned char *d, int msize) { + setup(d, msize); + }; + + PacketDataStream &operator <<(const quint64 value) { + quint64 i = value; + + if ((i & 0x8000000000000000LL) && (~i < 0x100000000LL)) { + // Signed number. + i = ~i; + if (i <= 0x3) { + // Shortcase for -1 to -4 + append(0xFC | i); + return *this; + } else { + append(0xF8); + } + } + if (i < 0x80) { + // Need top bit clear + append(i); + } else if (i < 0x4000) { + // Need top two bits clear + append((i >> 8) | 0x80); + append(i & 0xFF); + } else if (i < 0x200000) { + // Need top three bits clear + append((i >> 16) | 0xC0); + append((i >> 8) & 0xFF); + append(i & 0xFF); + } else if (i < 0x10000000) { + // Need top four bits clear + append((i >> 24) | 0xE0); + append((i >> 16) & 0xFF); + append((i >> 8) & 0xFF); + append(i & 0xFF); + } else if (i < 0x100000000LL) { + // It's a full 32-bit integer. + append(0xF0); + append((i >> 24) & 0xFF); + append((i >> 16) & 0xFF); + append((i >> 8) & 0xFF); + append(i & 0xFF); + } else { + // It's a 64-bit value. + append(0xF4); + append((i >> 56) & 0xFF); + append((i >> 48) & 0xFF); + append((i >> 40) & 0xFF); + append((i >> 32) & 0xFF); + append((i >> 24) & 0xFF); + append((i >> 16) & 0xFF); + append((i >> 8) & 0xFF); + append(i & 0xFF); + } + return *this; + } + + PacketDataStream &operator >>(quint64 &i) { + quint64 v = next(); + + if ((v & 0x80) == 0x00) { + i=(v & 0x7F); + } else if ((v & 0xC0) == 0x80) { + i=(v & 0x3F) << 8 | next(); + } else if ((v & 0xF0) == 0xF0) { + switch (v & 0xFC) { + case 0xF0: + i=next() << 24 | next() << 16 | next() << 8 | next(); + break; + case 0xF4: + i=next() << 56 | next() << 48 | next() << 40 | next() << 32 | next() << 24 | next() << 16 | next() << 8 | next(); + break; + case 0xF8: + *this >> i; + i = ~i; + break; + case 0xFC: + i=v & 0x03; + i = ~i; + break; + default: + ok = false; + i = 0; + break; + } + } else if ((v & 0xF0) == 0xE0) { + i=(v & 0x0F) << 24 | next() << 16 | next() << 8 | next(); + } else if ((v & 0xE0) == 0xC0) { + i=(v & 0x1F) << 16 | next() << 8 | next(); + } + return *this; + } + + PacketDataStream &operator <<(const QByteArray &a) { + *this << a.size(); + append(a.constData(), a.size()); + return *this; + } + + PacketDataStream &operator >>(QByteArray &a) { + quint32 len; + *this >> len; + if (len > left()) { + len = left(); + ok = false; + } + a = QByteArray(reinterpret_cast<const char *>(& data[offset]), len); + offset+=len; + return *this; + } + + PacketDataStream &operator <<(const QString &s) { + return *this << s.toUtf8(); + } + + // Using the data directly instead of through qbuff avoids a copy. + PacketDataStream &operator >>(QString &s) { + quint32 len; + *this >> len; + if (len > left()) { + len = left(); + ok = false; + } + s = QString::fromUtf8(reinterpret_cast<const char *>(& data[offset]), len); + offset+=len; + return *this; + } + + PacketDataStream &operator <<(const bool b) { + quint32 v = b ? 1 : 0; + return *this << v; + } + + PacketDataStream &operator >>(bool &b) { + quint32 v; + *this >> v; + b = v ? true : false; + return *this; + } + +#define INTMAPOPERATOR(type) \ + PacketDataStream &operator <<(const type v) { \ + return *this << static_cast<quint64>(v); \ + } \ + PacketDataStream &operator >>(type &v) { \ + quint64 vv; \ + *this >> vv; \ + v = static_cast<type>(vv); \ + return *this; \ + } + + + INTMAPOPERATOR(int); + INTMAPOPERATOR(unsigned int); + INTMAPOPERATOR(short); + INTMAPOPERATOR(unsigned short); + INTMAPOPERATOR(char); + INTMAPOPERATOR(unsigned char); + + union double64u { + quint64 ui; + double d; + }; + + PacketDataStream &operator <<(const double v) { + double64u u; + u.d = v; + return *this << u.ui; + } + + PacketDataStream &operator >>(double &v) { + double64u u; + *this >> u.ui; + v = u.d; + return *this; + } + + template <typename T> + PacketDataStream &operator <<(const QList<T> &l) { + *this << l.size(); + for (int i=0;i < l.size();i++) + *this << l.at(i); + return *this; + } + + template <typename T> + PacketDataStream &operator >>(QList<T> &l) { + l.clear(); + quint32 len; + *this >> len; + if (len > left()) { + len = left(); + ok = false; + } + for (quint32 i=0;i<len;i++) { + if (left() == 0) { + ok = false; + break; + } + + T t; + *this >> t; + l.append(t); + } + return *this; + } + + + template <typename T> + PacketDataStream &operator <<(const QSet<T> &s) { + *this << s.size(); + for (typename QSet<T>::const_iterator i=s.constBegin();i!=s.constEnd();++i) + *this << *i; + return *this; + } + + template <typename T> + PacketDataStream &operator >>(QSet<T> &s) { + s.clear(); + quint32 len; + *this >> len; + if (len > left()) { + len = left(); + ok = false; + } + for (quint32 i=0;i<len;i++) { + if (left() == 0) { + ok = false; + break; + } + + T t; + *this >> t; + s.insert(t); + } + return *this; + } + + template <typename T,typename U> + PacketDataStream &operator <<(const QPair<T,U> &p) { + return *this << p.first << p.second; + } + + template <typename T,typename U> + PacketDataStream &operator >>(QPair<T,U> &p) { + return *this >> p.first >> p.second; + } + +}; + +#else +class PacketDataStream; +#endif diff --git a/src/Player.cpp b/src/Player.cpp index a6434c18d..5006ae46c 100644 --- a/src/Player.cpp +++ b/src/Player.cpp @@ -125,7 +125,7 @@ void ClientPlayer::setMute(bool mute) { if (bMute == mute) return; bMute = mute; - if (! bMute && bDeaf) + if (! bMute) bDeaf = false; emit muteDeafChanged(); } @@ -138,16 +138,22 @@ void ClientPlayer::setLocalMute(bool mute) { } void ClientPlayer::setDeaf(bool deaf) { - if (bDeaf == deaf) - return; bDeaf = deaf; - if (bDeaf && ! bMute) + if (bDeaf) bMute = true; emit muteDeafChanged(); } -void ClientPlayer::setSelfMuteDeaf(bool mute, bool deaf) { - bSelfDeaf = deaf; +void ClientPlayer::setSelfMute(bool mute) { bSelfMute = mute; + if (! mute) + bSelfDeaf = false; + emit muteDeafChanged(); +} + +void ClientPlayer::setSelfDeaf(bool deaf) { + bSelfDeaf = deaf; + if (deaf) + bSelfMute = true; emit muteDeafChanged(); } diff --git a/src/Player.h b/src/Player.h index 2153b7210..38f473710 100644 --- a/src/Player.h +++ b/src/Player.h @@ -49,6 +49,8 @@ class Player { bool bSelfMute, bSelfDeaf; bool bTalking, bAltSpeak; Channel *cChannel; + // TODO: Server-side precache + QByteArray qbaTexture; QString getFlagsString() const; Player(); @@ -75,7 +77,8 @@ class ClientPlayer : public QObject, public Player { void setMute(bool mute); void setDeaf(bool deaf); void setLocalMute(bool mute); - void setSelfMuteDeaf(bool mute, bool deaf); + void setSelfMute(bool mute); + void setSelfDeaf(bool deaf); signals: void talkingChanged(bool talking); void muteDeafChanged(); diff --git a/src/mumble/ACLEditor.cpp b/src/mumble/ACLEditor.cpp index cd30275ca..80d1eafb6 100644 --- a/src/mumble/ACLEditor.cpp +++ b/src/mumble/ACLEditor.cpp @@ -34,16 +34,14 @@ #include "Channel.h" #include "Global.h" -ACLEditor::ACLEditor(const MessageEditACL *mea, QWidget *p) : QDialog(p) { +ACLEditor::ACLEditor(const MumbleProto::ACL &mea, QWidget *p) : QDialog(p) { QLabel *l; - MessageEditACL::ACLStruct as; - MessageEditACL::GroupStruct gs; - MessageEditACL::ACLStruct *asp; - MessageEditACL::GroupStruct *gsp; + + msg = mea; setupUi(this); - iId = mea->iId; + iId = mea.channel_id(); setWindowTitle(tr("Mumble - Edit ACL for %1").arg(Channel::get(iId)->qsName)); QGridLayout *grid = new QGridLayout(qgbACLpermissions); @@ -73,7 +71,8 @@ ACLEditor::ACLEditor(const MessageEditACL *mea, QWidget *p) : QDialog(p) { perm = perm * 2; } - MessageEditACL::ACLStruct *def = new MessageEditACL::ACLStruct(); + ChanACL *def = new ChanACL(NULL); + def->bApplyHere = true; def->bApplySubs = true; def->bInherited = true; @@ -82,45 +81,56 @@ ACLEditor::ACLEditor(const MessageEditACL *mea, QWidget *p) : QDialog(p) { def->pAllow = ChanACL::Traverse | ChanACL::Enter | ChanACL::Speak | ChanACL::AltSpeak; def->pDeny = 0; - acls << def; + qlACLs << def; - foreach(as, mea->acls) { - asp = new MessageEditACL::ACLStruct(as); - acls << asp; + for(int i=0;i<mea.acls_size();++i) { + const MumbleProto::ACL_ChanACL &as = mea.acls(i); + + ChanACL *acl = new ChanACL(NULL); + acl->bApplyHere = as.apply_here(); + acl->bApplySubs = as.apply_subs(); + acl->bInherited = as.inherited(); + acl->iPlayerId = -1; + if (as.has_user_id()) + acl->iPlayerId = as.user_id(); + else + acl->qsGroup = u8(as.group()); + acl->pAllow = static_cast<ChanACL::Permissions>(as.grant()); + acl->pDeny = static_cast<ChanACL::Permissions>(as.deny()); + + qlACLs << acl; } - foreach(gs, mea->groups) { - gsp = new MessageEditACL::GroupStruct(gs); - groups << gsp; + + for(int i=0;i<mea.groups_size();++i) { + const MumbleProto::ACL_ChanGroup &gs = mea.groups(i); + + Group *gp = new Group(NULL, u8(gs.name())); + for(int j=0;j<gs.add_size();++j) + gp->qsAdd.insert(gs.add(j)); + for(int j=0;j<gs.remove_size();++j) + gp->qsRemove.insert(gs.remove(j)); + for(int j=0;j<gs.inherited_members_size();++j) + gp->qsTemporary.insert(gs.inherited_members(j)); + + qlGroups << gp; } + iUnknown = -2; + numInheritACL = -1; - bInheritACL = mea->bInheritACL; + bInheritACL = mea.inherit_acls(); qcbACLInherit->setChecked(bInheritACL); - foreach(asp, acls) { - if (asp->bInherited) + foreach(ChanACL *acl, qlACLs) { + if (acl->bInherited) numInheritACL++; - if (asp->iPlayerId != -1) - addQuery(ACLList, asp->iPlayerId); - } - foreach(gsp, groups) { - int id; - foreach(id, gsp->qsAdd) - addQuery(GroupAdd, id); - foreach(id, gsp->qsRemove) - addQuery(GroupRemove, id); - foreach(id, gsp->qsInheritedMembers) - addQuery(GroupInherit, id); } refill(GroupAdd); refill(GroupRemove); refill(GroupInherit); refill(ACLList); - - doneQuery(); - refillGroupNames(); ACLEnableCheck(); @@ -130,14 +140,11 @@ ACLEditor::ACLEditor(const MessageEditACL *mea, QWidget *p) : QDialog(p) { } ACLEditor::~ACLEditor() { - MessageEditACL::ACLStruct *asp; - MessageEditACL::GroupStruct *gsp; - - foreach(asp, acls) { - delete asp; + foreach(ChanACL *acl, qlACLs) { + delete acl; } - foreach(gsp, groups) { - delete gsp; + foreach(Group *gp, qlGroups) { + delete gp; } } @@ -162,89 +169,91 @@ void ACLEditor::addToolTipsWhatsThis() { void ACLEditor::accept() { - MessageEditACL::ACLStruct as; - MessageEditACL::GroupStruct gs; - MessageEditACL::ACLStruct *asp; - MessageEditACL::GroupStruct *gsp; - MessageEditACL mea; - - mea.iId = iId; - mea.bQuery = false; - mea.bInheritACL = bInheritACL; - - foreach(asp, acls) { - as = *asp; - if (as.bInherited) + msg.set_inherit_acls(bInheritACL); + msg.clear_acls(); + msg.clear_groups(); + + foreach(ChanACL *acl, qlACLs) { + if (acl->bInherited || (acl->iPlayerId < -1)) continue; - mea.acls << as; + MumbleProto::ACL_ChanACL *mpa = msg.add_acls(); + mpa->set_apply_here(acl->bApplyHere); + mpa->set_apply_subs(acl->bApplySubs); + if (acl->iPlayerId != -1) + mpa->set_user_id(acl->iPlayerId); + else + mpa->set_group(u8(acl->qsGroup)); + mpa->set_grant(acl->pAllow); + mpa->set_deny(acl->pDeny); } - foreach(gsp, groups) { - gs = *gsp; - if (gs.bInherited && gs.bInherit && gs.bInheritable && (gs.qsAdd.count() == 0) && (gs.qsRemove.count() == 0)) + foreach(Group *gp, qlGroups) { + if (gp->bInherited && gp->bInherit && gp->bInheritable && (gp->qsAdd.count() == 0) && (gp->qsRemove.count() == 0)) continue; - gs.qsInheritedMembers.clear(); - mea.groups << gs; + MumbleProto::ACL_ChanGroup *mpg = msg.add_groups(); + mpg->set_name(u8(gp->qsName)); + foreach(int id, gp->qsAdd) + if (id >= 0) + mpg->add_add(id); + foreach(int id, gp->qsRemove) + if (id >= 0) + mpg->add_remove(id); } - g.sh->sendMessage(&mea); + g.sh->sendMessage(msg, MessageHandler::ACL); + QDialog::accept(); } -void ACLEditor::addQuery(WaitID me, int id) { - qhIDWait[id].insert(me); -} -void ACLEditor::addQuery(WaitID me, QString name) { - qhNameWait[name].insert(me); +const QString ACLEditor::userName(int id) { + if (qhNameCache.contains(id)) + return qhNameCache.value(id); + else + return QString::fromLatin1("#%1").arg(id); } -void ACLEditor::doneQuery() { - MessageQueryUsers mqu; +int ACLEditor::id(const QString &uname) { + if (qhIDCache.contains(uname)) + return qhIDCache.value(uname); + else { + if (! qhNameWait.contains(uname)) { + MumbleProto::QueryUsers mpuq; + mpuq.add_names(u8(uname)); + g.sh->sendMessage(mpuq, MessageHandler::QueryUsers); - cleanQuery(); - - foreach(int id, qhIDWait.keys()) { - mqu.qlIds << id; - mqu.qlNames << QString(); - } - foreach(QString name, qhNameWait.keys()) { - mqu.qlIds << -1; - mqu.qlNames << name; + iUnknown--; + qhNameWait.insert(uname, iUnknown); + qhNameCache.insert(iUnknown, uname); + } + return qhNameWait.value(uname); } - if (mqu.qlIds.count() > 0) - g.sh->sendMessage(&mqu); } -void ACLEditor::cleanQuery() { - QSet<WaitID> notify; +void ACLEditor::returnQuery(const MumbleProto::QueryUsers &mqu) { + if (mqu.names_size() != mqu.ids_size()) + return; - foreach(int id, qhIDWait.keys()) { - if (qhNameCache.contains(id)) { - notify = notify.unite(qhIDWait.value(id)); - qhIDWait.remove(id); - } - } - foreach(QString name, qhNameWait.keys()) { - if (qhIDCache.contains(name)) { - notify = notify.unite(qhNameWait.value(name)); - qhNameWait.remove(name); + for(int i=0;i < mqu.names_size(); ++i) { + int id = mqu.ids(i); + QString name = u8(mqu.names(i)); + qhIDCache.insert(name, id); + qhNameCache.insert(id, name); + + if (qhNameWait.contains(name)) { + int tid = qhNameWait.take(name); + + foreach(ChanACL *acl, qlACLs) + if (acl->iPlayerId == tid) + acl->iPlayerId = id; + foreach(Group *gp, qlGroups) { + if (gp->qsAdd.remove(tid)) + gp->qsAdd.insert(id); + if (gp->qsRemove.remove(tid)) + gp->qsRemove.insert(id); + } } } - foreach(WaitID wid, notify) { - refill(wid); - } -} - -void ACLEditor::returnQuery(const MessageQueryUsers *mqu) { - int i; - for (i=0;i<mqu->qlIds.count();i++) { - int id = mqu->qlIds[i]; - QString name = mqu->qlNames[i]; - qhIDCache[name] = id; - qhNameCache[id] = name; - } - cleanQuery(); } void ACLEditor::refill(WaitID wid) { @@ -264,30 +273,7 @@ void ACLEditor::refill(WaitID wid) { } } -QString ACLEditor::userName(int id) { - if (qhNameCache.contains(id)) - return qhNameCache.value(id); - else - return QString::fromLatin1("#%1").arg(id); -} - void ACLEditor::refillACL() { - MessageEditACL::ACLStruct *as; - - foreach(as, qhACLNameWait.keys()) { - if (acls.indexOf(as) >= 0) { - QString name = qhACLNameWait.value(as); - if (qhIDCache.contains(name)) { - int id = qhIDCache.value(name); - if (id != -1) { - as->iPlayerId = id; - as->qsGroup = QString(); - } - qhACLNameWait.remove(as); - } - } - } - int idx = qlwACLs->currentRow(); bool previnh = bInheritACL; bInheritACL = qcbACLInherit->isChecked(); @@ -296,18 +282,18 @@ void ACLEditor::refillACL() { bool first = true; - foreach(as, acls) { + foreach(ChanACL *acl, qlACLs) { if (first) first = false; - else if (! bInheritACL && as->bInherited) + else if (! bInheritACL && acl->bInherited) continue; QString text; - if (as->iPlayerId == -1) - text=QString::fromLatin1("@%1").arg(as->qsGroup); + if (acl->iPlayerId == -1) + text=QString::fromLatin1("@%1").arg(acl->qsGroup); else - text=userName(as->iPlayerId); + text=userName(acl->iPlayerId); QListWidgetItem *item=new QListWidgetItem(text, qlwACLs); - if (as->bInherited) { + if (acl->bInherited) { QFont f = item->font(); f.setItalic(true); item->setFont(f); @@ -322,13 +308,11 @@ void ACLEditor::refillACL() { } void ACLEditor::refillGroupNames() { - MessageEditACL::GroupStruct *gsp; - QString text = qcbGroupList->currentText().toLower(); QStringList qsl; - foreach(gsp, groups) { - qsl << gsp->qsName; + foreach(Group *gp, qlGroups) { + qsl << gp->qsName; } qsl.sort(); @@ -342,53 +326,37 @@ void ACLEditor::refillGroupNames() { qcbGroupList->setCurrentIndex(wantindex); } -MessageEditACL::GroupStruct *ACLEditor::currentGroup() { +Group *ACLEditor::currentGroup() { QString group = qcbGroupList->currentText().toLower(); - MessageEditACL::GroupStruct *gs; - foreach(gs, groups) { - if (gs->qsName == group) { - return gs; + foreach(Group *gp, qlGroups) { + if (gp->qsName == group) { + return gp; } } return NULL; } -MessageEditACL::ACLStruct *ACLEditor::currentACL() { +ChanACL *ACLEditor::currentACL() { int idx = qlwACLs->currentRow(); if (idx < 0) return NULL; if (! bInheritACL) idx += numInheritACL; - return acls[idx]; + return qlACLs[idx]; } void ACLEditor::refillGroupAdd() { - MessageEditACL::GroupStruct *gs; - - foreach(gs, qhAddNameWait.keys()) { - if (groups.indexOf(gs) >= 0) { - QString name = qhAddNameWait.value(gs); - if (qhIDCache.contains(name)) { - int id = qhIDCache.value(name); - if (id != -1) { - gs->qsAdd.insert(id); - } - qhAddNameWait.remove(gs); - } - } - } + Group *gp = currentGroup(); - gs = currentGroup(); - - if (! gs) + if (! gp) return; QStringList qsl; - foreach(int id, gs->qsAdd) { + foreach(int id, gp->qsAdd) { qsl << userName(id); } qsl.sort(); @@ -399,27 +367,12 @@ void ACLEditor::refillGroupAdd() { } void ACLEditor::refillGroupRemove() { - MessageEditACL::GroupStruct *gs; - - foreach(gs, qhRemoveNameWait.keys()) { - if (groups.indexOf(gs) >= 0) { - QString name = qhRemoveNameWait.value(gs); - if (qhIDCache.contains(name)) { - int id = qhIDCache.value(name); - if (id != -1) { - gs->qsRemove.insert(id); - } - qhRemoveNameWait.remove(gs); - } - } - } - - gs = currentGroup(); - if (! gs) + Group *gp = currentGroup(); + if (! gp) return; QStringList qsl; - foreach(int id, gs->qsRemove) { + foreach(int id, gp->qsRemove) { qsl << userName(id); } qsl.sort(); @@ -430,13 +383,13 @@ void ACLEditor::refillGroupRemove() { } void ACLEditor::refillGroupInherit() { - MessageEditACL::GroupStruct *gs = currentGroup(); + Group *gp = currentGroup(); - if (! gs) + if (! gp) return; QStringList qsl; - foreach(int id, gs->qsInheritedMembers) { + foreach(int id, gp->qsTemporary) { qsl << userName(id); } qsl.sort(); @@ -447,14 +400,14 @@ void ACLEditor::refillGroupInherit() { } void ACLEditor::groupEnableCheck() { - MessageEditACL::GroupStruct *gs = currentGroup(); + Group *gp = currentGroup(); bool ena = true; - if (! gs) + if (! gp) ena = false; else - ena = gs->bInherit; + ena = gp->bInherit; qlwGroupRemove->setEnabled(ena); qlwGroupInherit->setEnabled(ena); @@ -463,23 +416,22 @@ void ACLEditor::groupEnableCheck() { qpbGroupRemoveRemove->setEnabled(ena); qpbGroupInheritRemove->setEnabled(ena); - ena = (gs != NULL); + ena = (gp != NULL); qlwGroupAdd->setEnabled(ena); qpbGroupAddAdd->setEnabled(ena); qpbGroupAddRemove->setEnabled(ena); qcbGroupInherit->setEnabled(ena); qcbGroupInheritable->setEnabled(ena); - if (gs) { - qcbGroupInherit->setChecked(gs->bInherit); - qcbGroupInheritable->setChecked(gs->bInheritable); - qcbGroupInherited->setChecked(gs->bInherited); + if (gp) { + qcbGroupInherit->setChecked(gp->bInherit); + qcbGroupInheritable->setChecked(gp->bInheritable); + qcbGroupInherited->setChecked(gp->bInherited); } } void ACLEditor::ACLEnableCheck() { - MessageEditACL::ACLStruct *as = currentACL(); - MessageEditACL::GroupStruct *gs;; + ChanACL *as = currentACL(); bool ena = true; if (! as) @@ -520,7 +472,7 @@ void ACLEditor::ACLEnableCheck() { qcbACLGroup->addItem(QLatin1String("~in")); qcbACLGroup->addItem(QLatin1String("~sub")); qcbACLGroup->addItem(QLatin1String("~out")); - foreach(gs, groups) + foreach(Group *gs, qlGroups) qcbACLGroup->addItem(gs->qsName); if (as->iPlayerId == -1) { qleACLUser->setText(QString()); @@ -544,7 +496,7 @@ void ACLEditor::on_qlwACLs_currentRowChanged() { } void ACLEditor::on_qpbACLAdd_clicked() { - MessageEditACL::ACLStruct *as = new MessageEditACL::ACLStruct; + ChanACL *as = new ChanACL(NULL); as->bApplyHere = true; as->bApplySubs = true; as->bInherited = false; @@ -552,42 +504,42 @@ void ACLEditor::on_qpbACLAdd_clicked() { as->iPlayerId = -1; as->pAllow = ChanACL::None; as->pDeny = ChanACL::None; - acls << as; + qlACLs << as; refillACL(); qlwACLs->setCurrentRow(qlwACLs->count() - 1); } void ACLEditor::on_qpbACLRemove_clicked() { - MessageEditACL::ACLStruct *as = currentACL(); + ChanACL *as = currentACL(); if (! as || as->bInherited) return; - acls.removeAll(as); + qlACLs.removeAll(as); delete as; refillACL(); } void ACLEditor::on_qpbACLUp_clicked() { - MessageEditACL::ACLStruct *as = currentACL(); + ChanACL *as = currentACL(); if (! as || as->bInherited) return; - int idx = acls.indexOf(as); + int idx = qlACLs.indexOf(as); if (idx <= numInheritACL) return; - acls.swap(idx - 1, idx); + qlACLs.swap(idx - 1, idx); qlwACLs->setCurrentRow(qlwACLs->currentRow() - 1); refillACL(); } void ACLEditor::on_qpbACLDown_clicked() { - MessageEditACL::ACLStruct *as = currentACL(); + ChanACL *as = currentACL(); if (! as || as->bInherited) return; - int idx = acls.indexOf(as) + 1; - if (idx >= acls.count()) + int idx = qlACLs.indexOf(as) + 1; + if (idx >= qlACLs.count()) return; - acls.swap(idx - 1, idx); + qlACLs.swap(idx - 1, idx); qlwACLs->setCurrentRow(qlwACLs->currentRow() + 1); refillACL(); } @@ -597,7 +549,7 @@ void ACLEditor::on_qcbACLInherit_clicked(bool) { } void ACLEditor::on_qcbACLApplyHere_clicked(bool checked) { - MessageEditACL::ACLStruct *as = currentACL(); + ChanACL *as = currentACL(); if (! as || as->bInherited) return; @@ -605,7 +557,7 @@ void ACLEditor::on_qcbACLApplyHere_clicked(bool checked) { } void ACLEditor::on_qcbACLApplySubs_clicked(bool checked) { - MessageEditACL::ACLStruct *as = currentACL(); + ChanACL *as = currentACL(); if (! as || as->bInherited) return; @@ -613,7 +565,7 @@ void ACLEditor::on_qcbACLApplySubs_clicked(bool checked) { } void ACLEditor::on_qcbACLGroup_activated(const QString &text) { - MessageEditACL::ACLStruct *as = currentACL(); + ChanACL *as = currentACL(); if (! as || as->bInherited) return; @@ -632,7 +584,7 @@ void ACLEditor::on_qcbACLGroup_activated(const QString &text) { void ACLEditor::on_qleACLUser_editingFinished() { QString text = qleACLUser->text(); - MessageEditACL::ACLStruct *as = currentACL(); + ChanACL *as = currentACL(); if (! as || as->bInherited) return; @@ -645,16 +597,14 @@ void ACLEditor::on_qleACLUser_editingFinished() { refillACL(); } else { qcbACLGroup->setCurrentIndex(0); - qhACLNameWait[as] = text; - addQuery(ACLList, text); - doneQuery(); + as->iPlayerId = id(text); } } void ACLEditor::ACLPermissions_clicked() { QCheckBox *source = qobject_cast<QCheckBox *>(sender()); - MessageEditACL::ACLStruct *as = currentACL(); + ChanACL *as = currentACL(); if (! as || as->bInherited) return; @@ -682,17 +632,17 @@ void ACLEditor::ACLPermissions_clicked() { } void ACLEditor::on_qcbGroupList_activated(const QString &text) { - MessageEditACL::GroupStruct *gs = currentGroup(); + Group *gs = currentGroup(); if (text.isEmpty()) return; if (! gs) { QString name = text.toLower(); - gs = new MessageEditACL::GroupStruct; + gs = new Group(NULL, name); gs->bInherited = false; gs->bInherit = true; gs->bInheritable = true; gs->qsName = name; - groups << gs; + qlGroups << gs; } refillGroupNames(); @@ -703,7 +653,7 @@ void ACLEditor::on_qcbGroupList_activated(const QString &text) { } void ACLEditor::on_qpbGroupRemove_clicked() { - MessageEditACL::GroupStruct *gs = currentGroup(); + Group *gs = currentGroup(); if (! gs) return; if (gs->bInherited) { @@ -712,7 +662,7 @@ void ACLEditor::on_qpbGroupRemove_clicked() { gs->qsAdd.clear(); gs->qsRemove.clear(); } else { - groups.removeAll(gs); + qlGroups.removeAll(gs); delete gs; } refillGroupNames(); @@ -723,7 +673,7 @@ void ACLEditor::on_qpbGroupRemove_clicked() { } void ACLEditor::on_qcbGroupInherit_clicked(bool checked) { - MessageEditACL::GroupStruct *gs = currentGroup(); + Group *gs = currentGroup(); if (! gs) return; gs->bInherit = checked; @@ -731,29 +681,27 @@ void ACLEditor::on_qcbGroupInherit_clicked(bool checked) { } void ACLEditor::on_qcbGroupInheritable_clicked(bool checked) { - MessageEditACL::GroupStruct *gs = currentGroup(); + Group *gs = currentGroup(); if (! gs) return; gs->bInheritable = checked; } void ACLEditor::on_qpbGroupAddAdd_clicked() { + Group *gs = currentGroup(); QString text = qleGroupAdd->text(); - MessageEditACL::GroupStruct *gs = currentGroup(); if (! gs) return; if (text.isEmpty()) return; - qhAddNameWait[gs] = text; - addQuery(GroupAdd, text); - doneQuery(); + gs->qsAdd << id(text); } void ACLEditor::on_qpbGroupAddRemove_clicked() { - MessageEditACL::GroupStruct *gs = currentGroup(); + Group *gs = currentGroup(); if (! gs) return; @@ -761,28 +709,25 @@ void ACLEditor::on_qpbGroupAddRemove_clicked() { if (! item) return; - int id = qhIDCache.value(item->text()); - gs->qsAdd.remove(id); + gs->qsAdd.remove(id(item->text())); refillGroupAdd(); } void ACLEditor::on_qpbGroupRemoveAdd_clicked() { QString text = qleGroupRemove->text(); - MessageEditACL::GroupStruct *gs = currentGroup(); + Group *gs = currentGroup(); if (! gs) return; if (text.isEmpty()) return; - qhRemoveNameWait[gs] = text; - addQuery(GroupRemove, text); - doneQuery(); + gs->qsRemove << id(text); } void ACLEditor::on_qpbGroupRemoveRemove_clicked() { - MessageEditACL::GroupStruct *gs = currentGroup(); + Group *gs = currentGroup(); if (! gs) return; @@ -790,13 +735,12 @@ void ACLEditor::on_qpbGroupRemoveRemove_clicked() { if (! item) return; - int id = qhIDCache.value(item->text()); - gs->qsRemove.remove(id); + gs->qsRemove.remove(id(item->text())); refillGroupRemove(); } void ACLEditor::on_qpbGroupInheritRemove_clicked() { - MessageEditACL::GroupStruct *gs = currentGroup(); + Group *gs = currentGroup(); if (! gs) return; @@ -804,7 +748,6 @@ void ACLEditor::on_qpbGroupInheritRemove_clicked() { if (! item) return; - int id = qhIDCache.value(item->text()); - gs->qsRemove.insert(id); + gs->qsRemove.insert(id(item->text())); refillGroupRemove(); } diff --git a/src/mumble/ACLEditor.h b/src/mumble/ACLEditor.h index 1447e4687..191df849a 100644 --- a/src/mumble/ACLEditor.h +++ b/src/mumble/ACLEditor.h @@ -33,6 +33,8 @@ #include "mumble_pch.hpp" #include "Message.h" +#include "ACL.h" +#include "Group.h" #include "ui_ACLEditor.h" @@ -41,35 +43,29 @@ class ACLEditor : public QDialog, public Ui::ACLEditor { Q_OBJECT Q_DISABLE_COPY(ACLEditor) protected: + MumbleProto::ACL msg; enum WaitID { GroupAdd, GroupRemove, GroupInherit, ACLList }; - int iId; QHash<int, QString> qhNameCache; QHash<QString, int> qhIDCache; + QHash<QString, int> qhNameWait; - QHash<int, QSet<WaitID> > qhIDWait; - QHash<QString, QSet<WaitID> > qhNameWait; + int iUnknown; - void addQuery(WaitID me, int id); - void addQuery(WaitID me, QString name); - void doneQuery(); - void cleanQuery(); void refill(WaitID what); - QHash<MessageEditACL::ACLStruct *, QString> qhACLNameWait; - QHash<MessageEditACL::GroupStruct *, QString> qhAddNameWait; - QHash<MessageEditACL::GroupStruct *, QString> qhRemoveNameWait; - - MessageEditACL::GroupStruct *currentGroup(); - MessageEditACL::ACLStruct *currentACL(); + Group *currentGroup(); + ChanACL *currentACL(); + int iId; bool bInheritACL; - QList<MessageEditACL::ACLStruct *> acls; - QList<MessageEditACL::GroupStruct *> groups; + QList<ChanACL *> qlACLs; + QList<Group *> qlGroups; int numInheritACL; - QString userName(int id); + const QString userName(int id); + int id(const QString &uname); QList<QCheckBox *> qlACLAllow; QList<QCheckBox *> qlACLDeny; @@ -78,9 +74,9 @@ class ACLEditor : public QDialog, public Ui::ACLEditor { void showEvent(QShowEvent *); public: - ACLEditor(const MessageEditACL *mea, QWidget *p = NULL); + ACLEditor(const MumbleProto::ACL &mea, QWidget *p = NULL); ~ACLEditor(); - void returnQuery(const MessageQueryUsers *mqu); + void returnQuery(const MumbleProto::QueryUsers &mqu); public slots: void accept(); public slots: diff --git a/src/mumble/AudioInput.cpp b/src/mumble/AudioInput.cpp index e98a114c3..5c19b49f2 100644 --- a/src/mumble/AudioInput.cpp +++ b/src/mumble/AudioInput.cpp @@ -719,31 +719,23 @@ void AudioInput::flushCheck() { return; int flags = 0; - if (g.iAltSpeak > 0) - flags += MessageSpeex::AltSpeak; if (g.s.lmLoopMode == Settings::Server) - flags += MessageSpeex::LoopBack; - - if (! bPreviousVoice) - flags += MessageSpeex::EndSpeech; - - flags += (iFrames - 1) << 4; + flags = 0x1f; + else if (g.iAltSpeak > 0) + flags = 1; int len = speex_bits_nbytes(&sbBits); - QByteArray qba(len + 1, 0); - qba[0] = static_cast<unsigned char>(flags); + STACKVAR(char, data, len+1); + data[0] = static_cast<unsigned char>(flags); - speex_bits_write(&sbBits, qba.data() + 1, len); + speex_bits_write(&sbBits, data + 1, len); - MessageSpeex msPacket; - msPacket.qbaSpeexPacket = qba; - msPacket.iSeq = iFrameCounter; + // TODO: Loopback + //if (g.s.lmLoopMode == Settings::Local) { + // LoopPlayer::lpLoopy.addFrame(qba, msPacket.iSeq); - if (g.s.lmLoopMode == Settings::Local) { - LoopPlayer::lpLoopy.addFrame(qba, msPacket.iSeq); - } else if (g.sh) { - g.sh->sendMessage(&msPacket); - } + if (g.sh) + g.sh->sendMessage(data, len + 1); iFrames = 0; speex_bits_reset(&sbBits); diff --git a/src/mumble/AudioOutput.cpp b/src/mumble/AudioOutput.cpp index 4db692750..907575b8b 100644 --- a/src/mumble/AudioOutput.cpp +++ b/src/mumble/AudioOutput.cpp @@ -395,16 +395,19 @@ bool AudioOutputSpeech::needSamples(unsigned int snum) { spx_int32_t startofs = 0; if (jitter_buffer_get(jbJitter, &jbp, iFrameSize, &startofs) == JITTER_BUFFER_OK) { - ucFlags = jbp.data[0]; + ucFlags = jbp.data[0] & 0x1f; fPos[0] = fPos[1] = fPos[2] = 0.0; speex_bits_read_from(&sbBits, jbp.data + 1, jbp.len - 1); speex_decode(dsDecState, &sbBits, pOut); bLastAlive = true; } else { + // FIXME: End-of-speech flags + /* if (ucFlags & MessageSpeex::EndSpeech) { memset(pOut, 0, sizeof(float) * iFrameSize); bLastAlive = false; } else { + */ iMissCount++; if (iMissCount < 5) { speex_decode(dsDecState, NULL, pOut); @@ -412,7 +415,6 @@ bool AudioOutputSpeech::needSamples(unsigned int snum) { memset(pOut, 0, sizeof(float) * iFrameSize); bLastAlive = false; } - } } int activity; @@ -430,7 +432,7 @@ bool AudioOutputSpeech::needSamples(unsigned int snum) { } if (p) - p->setTalking(bLastAlive, ((ucFlags & MessageSpeex::AltSpeak) ? true : false)); + p->setTalking(bLastAlive, ((ucFlags == 1) ? true : false)); return bLastAlive; } diff --git a/src/mumble/AudioOutput.h b/src/mumble/AudioOutput.h index c2c872f8a..47ba9f2c7 100644 --- a/src/mumble/AudioOutput.h +++ b/src/mumble/AudioOutput.h @@ -38,24 +38,24 @@ // having them use resources while unused. #ifndef SPEAKER_FRONT_LEFT -#define SPEAKER_FRONT_LEFT 0x00000001 -#define SPEAKER_FRONT_RIGHT 0x00000002 -#define SPEAKER_FRONT_CENTER 0x00000004 -#define SPEAKER_LOW_FREQUENCY 0x00000008 -#define SPEAKER_BACK_LEFT 0x00000010 -#define SPEAKER_BACK_RIGHT 0x00000020 -#define SPEAKER_FRONT_LEFT_OF_CENTER 0x00000040 -#define SPEAKER_FRONT_RIGHT_OF_CENTER 0x00000080 -#define SPEAKER_BACK_CENTER 0x00000100 -#define SPEAKER_SIDE_LEFT 0x00000200 -#define SPEAKER_SIDE_RIGHT 0x00000400 -#define SPEAKER_TOP_CENTER 0x00000800 -#define SPEAKER_TOP_FRONT_LEFT 0x00001000 -#define SPEAKER_TOP_FRONT_CENTER 0x00002000 -#define SPEAKER_TOP_FRONT_RIGHT 0x00004000 -#define SPEAKER_TOP_BACK_LEFT 0x00008000 -#define SPEAKER_TOP_BACK_CENTER 0x00010000 -#define SPEAKER_TOP_BACK_RIGHT 0x00020000 +#define SPEAKER_FRONT_LEFT 0x1 +#define SPEAKER_FRONT_RIGHT 0x2 +#define SPEAKER_FRONT_CENTER 0x4 +#define SPEAKER_LOW_FREQUENCY 0x8 +#define SPEAKER_BACK_LEFT 0x10 +#define SPEAKER_BACK_RIGHT 0x20 +#define SPEAKER_FRONT_LEFT_OF_CENTER 0x40 +#define SPEAKER_FRONT_RIGHT_OF_CENTER 0x80 +#define SPEAKER_BACK_CENTER 0x100 +#define SPEAKER_SIDE_LEFT 0x200 +#define SPEAKER_SIDE_RIGHT 0x400 +#define SPEAKER_TOP_CENTER 0x800 +#define SPEAKER_TOP_FRONT_LEFT 0x1000 +#define SPEAKER_TOP_FRONT_CENTER 0x2000 +#define SPEAKER_TOP_FRONT_RIGHT 0x4000 +#define SPEAKER_TOP_BACK_LEFT 0x8000 +#define SPEAKER_TOP_BACK_CENTER 0x10000 +#define SPEAKER_TOP_BACK_RIGHT 0x20000 #endif #include "Audio.h" diff --git a/src/mumble/BanEditor.cpp b/src/mumble/BanEditor.cpp index f8d3e1f55..ca1ac7c3a 100644 --- a/src/mumble/BanEditor.cpp +++ b/src/mumble/BanEditor.cpp @@ -33,25 +33,49 @@ #include "Channel.h" #include "Global.h" -BanEditor::BanEditor(const MessageServerBanList *msbl, QWidget *p) : QDialog(p) { +typedef QPair<quint32, int> ban; + +BanEditor::BanEditor(const MumbleProto::BanList &msg, QWidget *p) : QDialog(p) { setupUi(this); QRegExp rx(QLatin1String("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}")); QValidator *validator = new QRegExpValidator(rx, this); qleIP->setValidator(validator); - qlBans = msbl->qlBans; + qlBans.clear(); + for(int i=0;i < msg.bans_size(); ++i) { + const MumbleProto::BanList_BanEntry &be = msg.bans(i); + quint32 v = 0; + std::string s = be.address(); + if (s.length() == 4) { + const char *data = s.data(); + v += (data[0] << 24); + v += (data[1] << 16); + v += (data[2] << 8); + v += (data[3] << 0); + qlBans << ban(v, be.mask()); + } + } + refreshBanList(); } void BanEditor::accept() { - MessageServerBanList msbl; - - msbl.bQuery = false; - msbl.qlBans = qlBans; + MumbleProto::BanList msg; + + foreach(const ban &b, qlBans) { + MumbleProto::BanList_BanEntry *be = msg.add_bans(); + char buff[4]; + buff[0] = (b.first >> 24) & 0xFF; + buff[1] = (b.first >> 16) & 0xFF; + buff[2] = (b.first >> 8) & 0xFF; + buff[3] = (b.first >> 0) & 0xFF; + be->set_address(std::string(buff, 4)); + be->set_mask(b.second); + } - g.sh->sendMessage(&msbl); + g.sh->sendMessage(msg, MessageHandler::BanList); QDialog::accept(); } diff --git a/src/mumble/BanEditor.h b/src/mumble/BanEditor.h index d359a1dd5..36ebeb468 100644 --- a/src/mumble/BanEditor.h +++ b/src/mumble/BanEditor.h @@ -42,7 +42,7 @@ class BanEditor : public QDialog, public Ui::BanEditor { protected: QList<QPair<quint32, int> > qlBans; public: - BanEditor(const MessageServerBanList *msbl, QWidget *p = NULL); + BanEditor(const MumbleProto::BanList &msbl, QWidget *p = NULL); public slots: void accept(); public slots: diff --git a/src/mumble/MainWindow.cpp b/src/mumble/MainWindow.cpp index edab3b916..95ae62220 100644 --- a/src/mumble/MainWindow.cpp +++ b/src/mumble/MainWindow.cpp @@ -383,10 +383,10 @@ void MainWindow::on_qtvPlayers_doubleClicked(const QModelIndex &idx) { Channel *c = pmModel->getChannel(idx); if (!c) return; - MessagePlayerMove mpm; - mpm.uiVictim = g.uiSession; - mpm.iChannelId = c->iId; - g.sh->sendMessage(&mpm); + MumbleProto::UserState mpus; + mpus.set_session(g.uiSession); + mpus.set_channel_id(c->iId); + g.sh->sendMessage(mpus, MessageHandler::UserState); } void MainWindow::on_qteLog_customContextMenuRequested(const QPoint &mpos) { @@ -440,7 +440,7 @@ void MainWindow::openUrl(const QUrl &url) { g.sh->wait(); } - rtLast = MessageServerReject::None; + rtLast = MumbleProto::Reject_RejectType_None; qaServerDisconnect->setEnabled(true); g.sh->setConnectionInfo(host, port, user, pw); g.sh->start(QThread::TimeCriticalPriority); @@ -469,10 +469,10 @@ void MainWindow::findDesiredChannel() { } } if (found && (chan != ClientPlayer::get(g.uiSession)->cChannel)) { - MessagePlayerMove mpm; - mpm.uiVictim = g.uiSession; - mpm.iChannelId = chan->iId; - g.sh->sendMessage(&mpm); + MumbleProto::UserState mpus; + mpus.set_session(g.uiSession); + mpus.set_channel_id(chan->iId); + g.sh->sendMessage(mpus, MessageHandler::UserState); } } @@ -554,7 +554,7 @@ void MainWindow::on_qaServerConnect_triggered() { if (res == QDialog::Accepted) { qsDesiredChannel = QString(); - rtLast = MessageServerReject::None; + rtLast = MumbleProto::Reject_RejectType_None; qaServerDisconnect->setEnabled(true); g.sh->setConnectionInfo(cd->qsServer, cd->usPort, cd->qsUsername, cd->qsPassword); g.sh->start(QThread::TimeCriticalPriority); @@ -594,9 +594,9 @@ void MainWindow::on_qaServerDisconnect_triggered() { } void MainWindow::on_qaServerBanList_triggered() { - MessageServerBanList msbl; - msbl.bQuery = true; - g.sh->sendMessage(&msbl); + MumbleProto::BanList mpbl; + mpbl.set_query(true); + g.sh->sendMessage(mpbl, MessageHandler::BanList); if (banEdit) { banEdit->reject(); @@ -705,10 +705,10 @@ void MainWindow::on_qaPlayerMute_triggered() { if (!p) return; - MessagePlayerMute mpmMsg; - mpmMsg.uiVictim = p->uiSession; - mpmMsg.bMute = ! p->bMute; - g.sh->sendMessage(&mpmMsg); + MumbleProto::UserState mpus; + mpus.set_session(p->uiSession); + mpus.set_mute(! p->bMute); + g.sh->sendMessage(mpus, MessageHandler::UserState); } void MainWindow::on_qaPlayerLocalMute_triggered() { @@ -724,10 +724,10 @@ void MainWindow::on_qaPlayerDeaf_triggered() { if (!p) return; - MessagePlayerDeaf mpdMsg; - mpdMsg.uiVictim = p->uiSession; - mpdMsg.bDeaf = ! p->bDeaf; - g.sh->sendMessage(&mpdMsg); + MumbleProto::UserState mpus; + mpus.set_session(p->uiSession); + mpus.set_deaf(! p->bDeaf); + g.sh->sendMessage(mpus, MessageHandler::UserState); } void MainWindow::on_qaPlayerKick_triggered() { @@ -745,10 +745,10 @@ void MainWindow::on_qaPlayerKick_triggered() { return; if (ok) { - MessagePlayerKick mpkMsg; - mpkMsg.uiVictim=p->uiSession; - mpkMsg.qsReason = reason; - g.sh->sendMessage(&mpkMsg); + MumbleProto::UserRemove mpur; + mpur.set_session(p->uiSession); + mpur.set_reason(u8(reason)); + g.sh->sendMessage(mpur, MessageHandler::UserRemove); } } @@ -766,10 +766,11 @@ void MainWindow::on_qaPlayerBan_triggered() { return; if (ok) { - MessagePlayerBan mpbMsg; - mpbMsg.uiVictim=p->uiSession; - mpbMsg.qsReason = reason; - g.sh->sendMessage(&mpbMsg); + MumbleProto::UserRemove mpur; + mpur.set_session(p->uiSession); + mpur.set_reason(u8(reason)); + mpur.set_ban(true); + g.sh->sendMessage(mpur, MessageHandler::UserRemove); } } @@ -781,22 +782,20 @@ void MainWindow::on_qaPlayerTextMessage_triggered() { unsigned int session = p->uiSession; - TextMessage *tm = new TextMessage(this); - tm->setWindowTitle(tr("Sending message to %1").arg(p->qsName)); - int res = tm->exec(); + ::TextMessage *texm = new ::TextMessage(this); + texm->setWindowTitle(tr("Sending message to %1").arg(p->qsName)); + int res = texm->exec(); p = ClientPlayer::get(session); if (p && (res==QDialog::Accepted)) { - MessageTextMessage mtxt; - mtxt.iChannel = -1; - mtxt.bTree = false; - mtxt.uiVictim = p->uiSession; - mtxt.qsMessage = tm->message(); - g.l->log(Log::TextMessage, tr("To %1: %2").arg(p->qsName).arg(mtxt.qsMessage), tr("Message to %1").arg(p->qsName)); - g.sh->sendMessage(&mtxt); + MumbleProto::TextMessage mptm; + mptm.add_session(p->uiSession); + mptm.set_message(u8(texm->message())); + g.sh->sendMessage(mptm, MessageHandler::TextMessage); + g.l->log(Log::TextMessage, tr("To %1: %2").arg(p->qsName).arg(texm->message()), tr("Message to %1").arg(p->qsName)); } - delete tm; + delete texm; } void MainWindow::on_qaQuit_triggered() { @@ -896,10 +895,10 @@ void MainWindow::on_qaChannelAdd_triggered() { return; if (ok) { - MessageChannelAdd mca; - mca.qsName = name; - mca.iParent = iParent; - g.sh->sendMessage(&mca); + MumbleProto::ChannelState mpcs; + mpcs.set_name(u8(name)); + mpcs.set_parent(iParent); + g.sh->sendMessage(mpcs, MessageHandler::ChannelState); } } @@ -918,9 +917,9 @@ void MainWindow::on_qaChannelRemove_triggered() { return; if (ret == QMessageBox::Yes) { - MessageChannelRemove mcr; - mcr.iId = c->iId; - g.sh->sendMessage(&mcr); + MumbleProto::ChannelRemove mpcr; + mpcr.set_channel_id(c->iId); + g.sh->sendMessage(mpcr, MessageHandler::ChannelRemove); } } @@ -939,10 +938,10 @@ void MainWindow::on_qaChannelRename_triggered() { return; if (ok) { - MessageChannelRename mcr; - mcr.iId = id; - mcr.qsName = name; - g.sh->sendMessage(&mcr); + MumbleProto::ChannelState mpcs; + mpcs.set_channel_id(id); + mpcs.set_name(u8(name)); + g.sh->sendMessage(mpcs, MessageHandler::ChannelState); } } @@ -953,34 +952,34 @@ void MainWindow::on_qaChannelDescUpdate_triggered() { int id = c->iId; - TextMessage tm; - tm.setWindowTitle(tr("Change description of channel %1").arg(c->qsName)); + ::TextMessage *texm = new ::TextMessage(this); + texm->setWindowTitle(tr("Change description of channel %1").arg(c->qsName)); const QString html = QTextDocumentFragment::fromPlainText(c->qsDesc).toHtml(); - tm.qteEdit->setText(html); - int res = tm.exec(); + texm->qteEdit->setText(html); + int res = texm->exec(); c = Channel::get(id); - if (!c) - return; - if (res==QDialog::Accepted) { - MessageChannelDescUpdate mcdu; - mcdu.iId = id; - mcdu.qsDesc = tm.message(); - g.sh->sendMessage(&mcdu); + if (c && (res==QDialog::Accepted)) { + MumbleProto::ChannelState mpcs; + mpcs.set_channel_id(id); + mpcs.set_description(u8(texm->message())); + g.sh->sendMessage(mpcs); } + delete texm; } void MainWindow::on_qaChannelACL_triggered() { Channel *c = pmModel->getChannel(qtvPlayers->currentIndex()); int id = c ? c->iId : 0; - MessageEditACL mea; - mea.iId = id; - mea.bQuery = true; - g.sh->sendMessage(&mea); + MumbleProto::ACL mpacl; + mpacl.set_channel_id(id); + mpacl.set_query(true); + + g.sh->sendMessage(mpacl); if (aclEdit) { aclEdit->reject(); @@ -995,11 +994,10 @@ void MainWindow::on_qaChannelLink_triggered() { if (! l) l = Channel::get(0); - MessageChannelLink mcl; - mcl.iId = c->iId; - mcl.qlTargets << l->iId; - mcl.ltType = MessageChannelLink::Link; - g.sh->sendMessage(&mcl); + MumbleProto::ChannelState mpcs; + mpcs.set_channel_id(c->iId); + mpcs.add_links_add(l->iId); + g.sh->sendMessage(mpcs, MessageHandler::ChannelState); } void MainWindow::on_qaChannelUnlink_triggered() { @@ -1008,20 +1006,20 @@ void MainWindow::on_qaChannelUnlink_triggered() { if (! l) l = Channel::get(0); - MessageChannelLink mcl; - mcl.iId = c->iId; - mcl.qlTargets << l->iId; - mcl.ltType = MessageChannelLink::Unlink; - g.sh->sendMessage(&mcl); + MumbleProto::ChannelState mpcs; + mpcs.set_channel_id(c->iId); + mpcs.add_links_remove(l->iId); + g.sh->sendMessage(mpcs, MessageHandler::ChannelState); } void MainWindow::on_qaChannelUnlinkAll_triggered() { Channel *c = ClientPlayer::get(g.uiSession)->cChannel; - MessageChannelLink mcl; - mcl.iId = c->iId; - mcl.ltType = MessageChannelLink::UnlinkAll; - g.sh->sendMessage(&mcl); + MumbleProto::ChannelState mpcs; + mpcs.set_channel_id(c->iId); + foreach(Channel *l, c->qsPermLinks) + mpcs.add_links_remove(l->iId); + g.sh->sendMessage(mpcs, MessageHandler::ChannelState); } void MainWindow::on_qaChannelSendMessage_triggered() { @@ -1032,23 +1030,20 @@ void MainWindow::on_qaChannelSendMessage_triggered() { int id = c->iId; - TextMessage tm; - tm.setWindowTitle(tr("Sending message to channel %1").arg(c->qsName)); - int res = tm.exec(); + ::TextMessage *texm = new ::TextMessage(this); + texm->setWindowTitle(tr("Sending message to channel %1").arg(c->qsName)); + int res = texm->exec(); c = Channel::get(id); - if (!c) - return; - if (res==QDialog::Accepted) { - MessageTextMessage mtxt; - mtxt.iChannel = id; - mtxt.bTree = false; - mtxt.uiVictim = 0; - mtxt.qsMessage = tm.message(); - g.l->log(Log::TextMessage, tr("To %1: %2").arg(c->qsName).arg(mtxt.qsMessage), tr("Message to %1").arg(c->qsName)); - g.sh->sendMessage(&mtxt); + if (c && (res==QDialog::Accepted)) { + MumbleProto::TextMessage mptm; + mptm.add_channel_id(id); + mptm.set_message(u8(texm->message())); + g.sh->sendMessage(mptm, MessageHandler::TextMessage); + g.l->log(Log::TextMessage, tr("To tree %1: %2").arg(c->qsName).arg(texm->message()), tr("Message to tree %1").arg(c->qsName)); } + delete texm; } void MainWindow::on_qaChannelSendTreeMessage_triggered() { @@ -1059,23 +1054,20 @@ void MainWindow::on_qaChannelSendTreeMessage_triggered() { int id = c->iId; - TextMessage tm; - tm.setWindowTitle(tr("Sending message to channel tree %1").arg(c->qsName)); - int res = tm.exec(); + ::TextMessage *texm = new ::TextMessage(this); + texm->setWindowTitle(tr("Sending message to channel tree %1").arg(c->qsName)); + int res = texm->exec(); c = Channel::get(id); - if (!c) - return; - if (res==QDialog::Accepted) { - MessageTextMessage mtxt; - mtxt.iChannel = id; - mtxt.bTree = true; - mtxt.uiVictim = 0; - mtxt.qsMessage = tm.message(); - g.l->log(Log::TextMessage, tr("To tree %1: %2").arg(c->qsName).arg(mtxt.qsMessage), tr("Message to tree %1").arg(c->qsName)); - g.sh->sendMessage(&mtxt); + if (c && (res==QDialog::Accepted)) { + MumbleProto::TextMessage mptm; + mptm.add_tree_id(id); + mptm.set_message(u8(texm->message())); + g.sh->sendMessage(mptm, MessageHandler::TextMessage); + g.l->log(Log::TextMessage, tr("To tree %1: %2").arg(c->qsName).arg(texm->message()), tr("Message to tree %1").arg(c->qsName)); } + delete texm; } void MainWindow::on_qaAudioReset_triggered() { @@ -1101,10 +1093,10 @@ void MainWindow::on_qaAudioMute_triggered() { g.l->log(Log::SelfMute, tr("Muted.")); } - MessagePlayerSelfMuteDeaf mpsmd; - mpsmd.bMute = g.s.bMute; - mpsmd.bDeaf = g.s.bDeaf; - g.sh->sendMessage(&mpsmd); + MumbleProto::UserState mpus; + mpus.set_self_mute(g.s.bMute); + mpus.set_self_deaf(g.s.bDeaf); + g.sh->sendMessage(mpus); updateTrayIcon(); } @@ -1125,10 +1117,10 @@ void MainWindow::on_qaAudioDeaf_triggered() { g.l->log(Log::SelfMute, tr("Undeafened.")); } - MessagePlayerSelfMuteDeaf mpsmd; - mpsmd.bMute = g.s.bMute; - mpsmd.bDeaf = g.s.bDeaf; - g.sh->sendMessage(&mpsmd); + MumbleProto::UserState mpus; + mpus.set_self_mute(g.s.bMute); + mpus.set_self_deaf(g.s.bDeaf); + g.sh->sendMessage(mpus); updateTrayIcon(); } @@ -1277,27 +1269,13 @@ void MainWindow::pushLink(bool down) { if (! target || ! down) return; - MessagePlayerMove mpm; - mpm.uiVictim = g.uiSession; - mpm.iChannelId = target->iId; - g.sh->sendMessage(&mpm); + // FIXME: This was shortcut to move to a channel. + g.l->log(Log::Information, tr("Joining %1.").arg(target->qsName)); } else { - MessageChannelLink mcl; - mcl.iId = home->iId; - if (down) - mcl.ltType = MessageChannelLink::PushLink; - else - mcl.ltType = MessageChannelLink::PushUnlink; - if (idx == 10) { - foreach(Channel *l, home->qlChannels) - mcl.qlTargets << l->iId; - } else if (target) { - mcl.qlTargets << target->iId; - } - if (mcl.qlTargets.count() == 0) - return; - g.sh->sendMessage(&mcl); + + // FIXME: This was shortcut to temp-link a channel. Replace with target. + } } @@ -1323,10 +1301,10 @@ void MainWindow::serverConnected() { qtvPlayers->setRowHidden(0, QModelIndex(), false); if (g.s.bMute || g.s.bDeaf) { - MessagePlayerSelfMuteDeaf mpsmd; - mpsmd.bMute = g.s.bMute; - mpsmd.bDeaf = g.s.bDeaf; - g.sh->sendMessage(&mpsmd); + MumbleProto::UserState mpus; + mpus.set_self_mute(g.s.bMute); + mpus.set_self_deaf(g.s.bDeaf); + g.sh->sendMessage(mpus); } } @@ -1424,15 +1402,15 @@ void MainWindow::serverDisconnected(QString reason) { #endif switch (rtLast) { - case MessageServerReject::InvalidUsername: - case MessageServerReject::UsernameInUse: + case MumbleProto::Reject_RejectType_InvalidUsername: + case MumbleProto::Reject_RejectType_UsernameInUse: matched = true; - uname = QInputDialog::getText(this, tr("Invalid username"), (rtLast == MessageServerReject::InvalidUsername) ? tr("You connected with an invalid username, please try another one.") : tr("That username is already in use, please try another username."), QLineEdit::Normal, uname, &ok, wf); + uname = QInputDialog::getText(this, tr("Invalid username"), (rtLast == MumbleProto::Reject_RejectType_InvalidUsername) ? tr("You connected with an invalid username, please try another one.") : tr("That username is already in use, please try another username."), QLineEdit::Normal, uname, &ok, wf); break; - case MessageServerReject::WrongUserPW: - case MessageServerReject::WrongServerPW: + case MumbleProto::Reject_RejectType_WrongUserPW: + case MumbleProto::Reject_RejectType_WrongServerPW: matched = true; - pw = QInputDialog::getText(this, tr("Wrong password"), (rtLast == MessageServerReject::WrongUserPW) ? tr("Wrong password for registered users, please try again.") : tr("Wrong server password for unregistered user account, please try again."), QLineEdit::Password, pw, &ok, wf); + pw = QInputDialog::getText(this, tr("Wrong password"), (rtLast == MumbleProto::Reject_RejectType_WrongUserPW) ? tr("Wrong password for registered users, please try again.") : tr("Wrong server password for unregistered user account, please try again."), QLineEdit::Password, pw, &ok, wf); break; default: break; @@ -1475,11 +1453,7 @@ void MainWindow::customEvent(QEvent *evt) { ServerHandlerMessageEvent *shme=static_cast<ServerHandlerMessageEvent *>(evt); - Message *mMsg = Message::networkToMessage(shme->qbaMsg); - if (mMsg) { - dispatch(NULL, mMsg); - delete mMsg; - } + dispatch(NULL, shme->qbaMsg); } void MainWindow::on_qteLog_anchorClicked(const QUrl &url) { @@ -1499,11 +1473,11 @@ void MainWindow::context_triggered() { Channel *c = pmModel->getChannel(qtvPlayers->currentIndex()); ClientPlayer *p = pmModel->getPlayer(qtvPlayers->currentIndex()); - MessageContextAction mca; - mca.uiSession = g.uiSession; - mca.qsAction = a->data().toString(); - mca.uiVictim = p ? p->uiSession : 0; - mca.iChannel = c ? c->iId : -1; - - g.sh->sendMessage(&mca); + MumbleProto::ContextAction mpca; + mpca.set_action(u8(a->data().toString())); + if (p->uiSession) + mpca.set_session(p->uiSession); + if (c) + mpca.set_channel_id(c->iId); + g.sh->sendMessage(mpca); } diff --git a/src/mumble/MainWindow.h b/src/mumble/MainWindow.h index 87973cc4b..b6ee361d9 100644 --- a/src/mumble/MainWindow.h +++ b/src/mumble/MainWindow.h @@ -90,7 +90,7 @@ class MainWindow : public QMainWindow, public MessageHandler, public Ui::MainWin ACLEditor *aclEdit; BanEditor *banEdit; - MessageServerReject::RejectType rtLast; + MumbleProto::Reject_RejectType rtLast; QString qsDesiredChannel; void recheckTTS(); @@ -178,37 +178,24 @@ class MainWindow : public QMainWindow, public MessageHandler, public Ui::MainWin ~MainWindow(); // From msgHandler. Implementation in Messages.cpp - virtual void msgSpeex(Connection *, MessageSpeex *); - virtual void msgServerAuthenticate(Connection *, MessageServerAuthenticate *); - virtual void msgPing(Connection *, MessagePing *); - virtual void msgPingStats(Connection *, MessagePingStats *); - virtual void msgServerReject(Connection *, MessageServerReject *); - virtual void msgServerSync(Connection *, MessageServerSync *); - virtual void msgServerJoin(Connection *, MessageServerJoin *); - virtual void msgServerLeave(Connection *, MessageServerLeave *); - virtual void msgPlayerMute(Connection *, MessagePlayerMute *); - virtual void msgPlayerDeaf(Connection *, MessagePlayerDeaf *); - virtual void msgPlayerSelfMuteDeaf(Connection *, MessagePlayerSelfMuteDeaf *); - virtual void msgPlayerKick(Connection *, MessagePlayerKick *); - virtual void msgPlayerBan(Connection *, MessagePlayerBan *); - virtual void msgPlayerMove(Connection *, MessagePlayerMove *); - virtual void msgPlayerRename(Connection *, MessagePlayerRename *); - virtual void msgChannelAdd(Connection *, MessageChannelAdd *); - virtual void msgChannelRemove(Connection *, MessageChannelRemove *); - virtual void msgChannelMove(Connection *, MessageChannelMove *); - virtual void msgChannelLink(Connection *, MessageChannelLink *); - virtual void msgChannelRename(Connection *, MessageChannelRename *); - virtual void msgChannelDescUpdate(Connection *, MessageChannelDescUpdate *); - virtual void msgServerBanList(Connection *, MessageServerBanList *); - virtual void msgTextMessage(Connection *, MessageTextMessage *); - virtual void msgPermissionDenied(Connection *, MessagePermissionDenied *); - virtual void msgEditACL(Connection *, MessageEditACL *); - virtual void msgQueryUsers(Connection *, MessageQueryUsers *); - virtual void msgTexture(Connection *, MessageTexture *); - virtual void msgCryptSetup(Connection *, MessageCryptSetup *); - virtual void msgCryptSync(Connection *, MessageCryptSync *); - virtual void msgContextAddAction(Connection *, MessageContextAddAction *); - virtual void msgContextAction(Connection *, MessageContextAction *); + virtual void msgVersion(Connection *, MumbleProto::Version *); + virtual void msgUDPTunnel(Connection *, MumbleProto::UDPTunnel *); + virtual void msgAuthenticate(Connection *, MumbleProto::Authenticate *); + virtual void msgPing(Connection *, MumbleProto::Ping *); + virtual void msgReject(Connection *, MumbleProto::Reject *); + virtual void msgServerSync(Connection *, MumbleProto::ServerSync *); + virtual void msgChannelRemove(Connection *, MumbleProto::ChannelRemove *); + virtual void msgChannelState(Connection *, MumbleProto::ChannelState *); + virtual void msgUserRemove(Connection *, MumbleProto::UserRemove *); + virtual void msgUserState(Connection *, MumbleProto::UserState *); + virtual void msgBanList(Connection *, MumbleProto::BanList *); + virtual void msgTextMessage(Connection *, MumbleProto::TextMessage *); + virtual void msgPermissionDenied(Connection *, MumbleProto::PermissionDenied *); + virtual void msgACL(Connection *, MumbleProto::ACL *); + virtual void msgQueryUsers(Connection *, MumbleProto::QueryUsers *); + virtual void msgCryptSetup(Connection *, MumbleProto::CryptSetup *); + virtual void msgContextActionAdd(Connection *, MumbleProto::ContextActionAdd *); + virtual void msgContextAction(Connection *, MumbleProto::ContextAction *); }; #else diff --git a/src/mumble/Messages.cpp b/src/mumble/Messages.cpp index c2fe3563e..d094f828c 100644 --- a/src/mumble/Messages.cpp +++ b/src/mumble/Messages.cpp @@ -50,366 +50,335 @@ #include "Database.h" #include "ViewCert.h" - -void MainWindow::msgServerJoin(Connection *, MessageServerJoin *msg) { - ClientPlayer *p = pmModel->addPlayer(msg->uiSession, msg->qsPlayerName); - p->iId = msg->iId; - g.l->log(Log::PlayerJoin, MainWindow::tr("Joined server: %1.").arg(p->qsName)); -} - -#define MSG_INIT \ - ClientPlayer *pSrc=ClientPlayer::get(msg->uiSession); \ +#define ACTOR_INIT \ + ClientPlayer *pSrc=NULL; \ + if (msg->has_actor()) \ + pSrc = ClientPlayer::get(msg->actor()); \ Q_UNUSED(pSrc); #define VICTIM_INIT \ - ClientPlayer *pDst=ClientPlayer::get(msg->uiVictim); \ + ClientPlayer *pDst=ClientPlayer::get(msg->session()); \ if (! pDst) { \ - qWarning("MainWindow: Message for nonexistant victim %d.", msg->uiVictim); \ + qWarning("MainWindow: Message for nonexistant victim %d.", msg->session()); \ return; \ } -void MainWindow::msgServerLeave(Connection *, MessageServerLeave *msg) { - MSG_INIT; +#define SELF_INIT \ + ClientPlayer *pSelf = ClientPlayer::get(g.uiSession); - if (! pSrc) - return; - g.l->log(Log::PlayerLeave, MainWindow::tr("Left server: %1.").arg(pSrc->qsName)); - pmModel->removePlayer(pSrc); +void MainWindow::msgAuthenticate(Connection *, MumbleProto::Authenticate *) { } -void MainWindow::msgServerBanList(Connection *, MessageServerBanList *msg) { +void MainWindow::msgBanList(Connection *, MumbleProto::BanList *msg) { if (banEdit) { banEdit->reject(); delete banEdit; banEdit = NULL; } - banEdit = new BanEditor(msg, this); + banEdit = new BanEditor(*msg, this); banEdit->show(); - } -void MainWindow::msgSpeex(Connection *, MessageSpeex *) { +void MainWindow::msgReject(Connection *, MumbleProto::Reject *msg) { + rtLast = msg->type(); + g.l->log(Log::ServerDisconnected, tr("Server connection rejected: %1.").arg(u8(msg->reason()))); + g.l->setIgnore(Log::ServerDisconnected, 1); } -void MainWindow::msgPlayerSelfMuteDeaf(Connection *, MessagePlayerSelfMuteDeaf *msg) { - MSG_INIT; - - if (! pSrc) - return; - - pSrc->setSelfMuteDeaf(msg->bMute, msg->bDeaf); +void MainWindow::msgServerSync(Connection *, MumbleProto::ServerSync *msg) { + g.iMaxBandwidth = msg->max_bandwidth(); + g.uiSession = msg->session(); + g.l->clearIgnore(); + g.l->log(Log::Information, u8(msg->welcome_text())); + pmModel->ensureSelfVisible(); + pmModel->recheckLinks(); - if (msg->uiSession == g.uiSession || ! g.uiSession) - return; - if (pSrc->cChannel != ClientPlayer::get(g.uiSession)->cChannel) - return; + AudioInputPtr ai = g.ai; + if (ai) { + int bw = ai->getMaxBandwidth(); + if (bw > g.iMaxBandwidth) { + g.l->log(Log::Information, tr("Server maximum bandwidth is only %1 kbit/s. Quality auto-adjusted.").arg(g.iMaxBandwidth / 125)); + } + ai->setMaxBandwidth(g.iMaxBandwidth); + } - QString name = pSrc->qsName; - if (msg->bMute && msg->bDeaf) - g.l->log(Log::OtherSelfMute, MainWindow::tr("%1 is now muted and deafened.").arg(name)); - else if (msg->bMute) - g.l->log(Log::OtherSelfMute, MainWindow::tr("%1 is now muted.").arg(name)); - else - g.l->log(Log::OtherSelfMute, MainWindow::tr("%1 is now unmuted.").arg(name)); + findDesiredChannel(); } -void MainWindow::msgPlayerMute(Connection *, MessagePlayerMute *msg) { - MSG_INIT; - VICTIM_INIT; - - pDst->setMute(msg->bMute); - - if (!g.uiSession || pDst->cChannel != ClientPlayer::get(g.uiSession)->cChannel) - return; - - QString vic = pDst->qsName; - QString admin = pSrc ? pSrc->qsName : MainWindow::tr("server"); - - if (msg->uiVictim == g.uiSession) { - g.l->log(Log::YouMuted, msg->bMute ? MainWindow::tr("You were muted by %1.").arg(admin) : MainWindow::tr("You were unmuted by %1.").arg(admin)); - updateTrayIcon(); - } else { - g.l->log((msg->uiSession == g.uiSession) ? Log::YouMutedOther : Log::OtherMutedOther, msg->bMute ? MainWindow::tr("%1 muted by %2.").arg(vic).arg(admin) : MainWindow::tr("%1 unmuted by %2.").arg(vic).arg(admin)); - } +void MainWindow::msgPermissionDenied(Connection *, MumbleProto::PermissionDenied *msg) { + g.l->log(Log::PermissionDenied, tr("Denied: %1.").arg(u8(msg->reason()))); } -void MainWindow::msgPlayerDeaf(Connection *, MessagePlayerDeaf *msg) { - MSG_INIT; - VICTIM_INIT; - - pDst->setDeaf(msg->bDeaf); - - if (!g.uiSession || pDst->cChannel != ClientPlayer::get(g.uiSession)->cChannel) - return; - - QString vic = pDst->qsName; - QString admin = pSrc ? pSrc->qsName : MainWindow::tr("server"); - - if (msg->uiVictim == g.uiSession) { - g.l->log(Log::YouMuted, msg->bDeaf ? MainWindow::tr("You were deafened by %1.").arg(admin) : MainWindow::tr("You were undeafened by %1.").arg(admin)); - updateTrayIcon(); - } else { - g.l->log((msg->uiSession == g.uiSession) ? Log::YouMutedOther : Log::OtherMutedOther, msg->bDeaf ? MainWindow::tr("%1 deafened by %2.").arg(vic).arg(admin) : MainWindow::tr("%1 undeafened by %2.").arg(vic).arg(admin)); - } +void MainWindow::msgUDPTunnel(Connection *, MumbleProto::UDPTunnel *) { + qWarning("Fudge!"); } -void MainWindow::msgPlayerKick(Connection *, MessagePlayerKick *msg) { - MSG_INIT; - VICTIM_INIT; - QString admin = pSrc ? pSrc->qsName : QLatin1String("server"); - - if (msg->uiVictim == g.uiSession) { - g.l->log(Log::YouKicked, MainWindow::tr("You were kicked from the server by %1: %2.").arg(admin).arg(msg->qsReason)); - g.l->setIgnore(Log::ServerDisconnected, 1); - } else { - g.l->setIgnore(Log::PlayerLeave, 1); - g.l->log((msg->uiSession == g.uiSession) ? Log::YouKicked : Log::PlayerKicked, MainWindow::tr("%3 was kicked from the server by %1: %2.").arg(admin).arg(msg->qsReason).arg(pDst->qsName)); +void MainWindow::msgUserState(Connection *, MumbleProto::UserState *msg) { + ACTOR_INIT; + SELF_INIT; + ClientPlayer *pDst=ClientPlayer::get(msg->session()); + + if (! pDst) { + if (msg->has_name()) { + pDst = pmModel->addPlayer(msg->session(), u8(msg->name())); + g.l->log(Log::PlayerJoin, tr("Joined server: %1.").arg(pDst->qsName)); + msg->clear_name(); + } else { + return; + } } -} -void MainWindow::msgPlayerBan(Connection *, MessagePlayerBan *msg) { - MSG_INIT; - VICTIM_INIT; - QString admin = pSrc ? pSrc->qsName : QLatin1String("server"); - if (msg->uiVictim == g.uiSession) { - g.l->log(Log::YouKicked, MainWindow::tr("You were kicked and banned from the server by %1: %2.").arg(admin).arg(msg->qsReason)); - g.l->setIgnore(Log::ServerDisconnected, 1); - } else { - g.l->setIgnore(Log::PlayerLeave, 1); - g.l->log((msg->uiSession == g.uiSession) ? Log::YouKicked : Log::PlayerKicked, MainWindow::tr("%3 was kicked and banned from the server by %1: %2.").arg(admin).arg(msg->qsReason).arg(pDst->qsName)); + if (msg->has_self_deaf() || msg->has_self_mute()) { + if (msg->has_self_mute()) + pDst->setSelfMute(msg->self_mute()); + if (msg->has_self_deaf()) + pDst->setSelfDeaf(msg->self_deaf()); + + if (pSelf && pDst != pSelf && (pDst->cChannel == pSelf->cChannel)) { + QString name = pDst->qsName; + if (pDst->bSelfMute && pDst->bSelfDeaf) + g.l->log(Log::OtherSelfMute, tr("%1 is now muted and deafened.").arg(name)); + else if (pDst->bSelfMute) + g.l->log(Log::OtherSelfMute, tr("%1 is now muted.").arg(name)); + else + g.l->log(Log::OtherSelfMute, tr("%1 is now unmuted.").arg(name)); + } } -} - -void MainWindow::msgPlayerMove(Connection *, MessagePlayerMove *msg) { - MSG_INIT; - VICTIM_INIT; - Channel *c = Channel::get(msg->iChannelId); - if (!c) { - qWarning("MessagePlayerMove for unknown channel."); - c = Channel::get(0); + if (msg->has_deaf() || msg->has_mute()) { + if (msg->has_mute()) + pDst->setMute(msg->mute()); + if (msg->has_deaf()) + pDst->setDeaf(msg->deaf()); + + if (pSelf && (pDst->cChannel == pSelf->cChannel)) { + QString vic = pDst->qsName; + QString admin = pSrc ? pSrc->qsName : tr("the server"); + + if (pDst == pSelf) { + if (pDst->bMute && pDst->bDeaf) + g.l->log(Log::YouMuted, tr("You were deafened by %1.").arg(admin)); + else if (pDst->bMute) + g.l->log(Log::YouMuted, tr("You were muted by %1.").arg(admin)); + else + g.l->log(Log::YouMuted, tr("You were unmuted by %1.").arg(admin)); + + updateTrayIcon(); + } else { + if (pDst->bMute && pDst->bDeaf) + g.l->log(Log::YouMuted, tr("%1 deafened by %2.").arg(vic).arg(admin)); + else if (pDst->bMute) + g.l->log(Log::YouMuted, tr("%1 muted by %2.").arg(vic).arg(admin)); + else + g.l->log(Log::YouMuted, tr("%1 unmuted by %2.").arg(vic).arg(admin)); + } + } } - bool log = true; - if ((msg->uiVictim == g.uiSession) && (msg->uiSession == msg->uiVictim)) - log = false; - if (g.uiSession == 0) - log = false; - - QString pname = pDst->qsName; - QString admin = pSrc ? pSrc->qsName : QLatin1String("server"); - - Channel *old = pDst->cChannel; + if (msg->has_channel_id()) { + Channel *c = Channel::get(msg->channel_id()); + if (!c) { + qWarning("MessagePlayerMove for unknown channel."); + c = Channel::get(0); + } - if (log) { - if (g.uiSession == msg->uiVictim) { - g.l->log(Log::ChannelJoin, MainWindow::tr("You were moved to %1 by %2.").arg(c->qsName).arg(admin)); - } else if (pDst->cChannel == ClientPlayer::get(g.uiSession)->cChannel) { - if (pDst == pSrc || (!pSrc)) - g.l->log(Log::ChannelLeave, MainWindow::tr("%1 left channel.").arg(pname)); - else - g.l->log(Log::ChannelLeave, MainWindow::tr("%1 moved out by %2 to %3.").arg(pname).arg(admin).arg(c->qsName)); + Channel *old = pDst->cChannel; + if (c != old) { + bool log = pSelf && !((pDst == pSelf) && (pSrc == pSelf)); + + QString pname = pDst->qsName; + QString admin = pSrc ? pSrc->qsName : tr("the server"); + + if (log) { + if (pDst == pSelf) { + g.l->log(Log::ChannelJoin, tr("You were moved to %1 by %2.").arg(c->qsName).arg(admin)); + } else if (pDst->cChannel == ClientPlayer::get(g.uiSession)->cChannel) { + if (pDst == pSrc) + g.l->log(Log::ChannelLeave, tr("%1 moved to %2.").arg(pname).arg(c->qsName)); + else + g.l->log(Log::ChannelLeave, tr("%1 moved to %2 by %3.").arg(pname).arg(c->qsName).arg(admin)); + } + } + + pmModel->movePlayer(pDst, c); + + + if (log && (pDst != pSelf) && (pDst->cChannel == pSelf->cChannel)) { + if (pDst == pSrc) + g.l->log(Log::ChannelJoin, tr("%1 entered channel.").arg(pname)); + else + g.l->log(Log::ChannelJoin, tr("%1 moved in from %2 by %3.").arg(pname).arg(old->qsName).arg(admin)); + } } } - - pmModel->movePlayer(pDst, c); - - if (log && (g.uiSession != msg->uiVictim) && (pDst->cChannel == ClientPlayer::get(g.uiSession)->cChannel)) { - if (pDst == pSrc || (!pSrc)) - g.l->log(Log::ChannelJoin, MainWindow::tr("%1 entered channel.").arg(pname)); - else - g.l->log(Log::ChannelJoin, MainWindow::tr("%1 moved in by %2 from %3.").arg(pname).arg(admin).arg(old->qsName)); + if (msg->has_name()) { + pmModel->renamePlayer(pDst, u8(msg->name())); } } -void MainWindow::msgPlayerRename(Connection *, MessagePlayerRename *msg) { - MSG_INIT; - if (pSrc) - pmModel->renamePlayer(pSrc, msg->qsName); -} +void MainWindow::msgUserRemove(Connection *, MumbleProto::UserRemove *msg) { + VICTIM_INIT; + ACTOR_INIT; + SELF_INIT; -void MainWindow::msgChannelAdd(Connection *, MessageChannelAdd *msg) { - if (msg->qsName.isEmpty()) - return; + QString admin = pSrc ? pSrc->qsName : tr("the server"); + QString reason = u8(msg->reason()); - if (msg->iId == 0) { - pmModel->renameChannel(Channel::get(0), msg->qsName); - return; + if (pDst == pSelf) { + if (msg->ban()) + g.l->log(Log::YouKicked, tr("You were kicked and banned from the server by %1: %2.").arg(admin).arg(reason)); + else + g.l->log(Log::YouKicked, tr("You were kicked from the server by %1: %2.").arg(admin).arg(reason)); + } else if (pSrc) { + if (msg->ban()) + g.l->log((pSrc == pSelf) ? Log::YouKicked : Log::PlayerKicked, tr("%3 was kicked and banned from the server by %1: %2.").arg(admin).arg(reason).arg(pDst->qsName)); + else + g.l->log((pSrc == pSelf) ? Log::YouKicked : Log::PlayerKicked, tr("%3 was kicked from the server by %1: %2.").arg(admin).arg(reason).arg(pDst->qsName)); + } else { + g.l->log(Log::PlayerLeave, tr("Left server: %1.").arg(pSrc->qsName)); } - - Channel *p = Channel::get(msg->iParent); - if (p) - pmModel->addChannel(msg->iId, p, msg->qsName); -} - -void MainWindow::msgChannelRemove(Connection *, MessageChannelRemove *msg) { - if (msg->iId == 0) - return; - - Channel *c = Channel::get(msg->iId); - if (c) - pmModel->removeChannel(c); + pmModel->removePlayer(pSrc); } -void MainWindow::msgChannelMove(Connection *, MessageChannelMove *msg) { - if (msg->iId == 0) +void MainWindow::msgChannelState(Connection *, MumbleProto::ChannelState *msg) { + if (! msg->has_channel_id()) return; - Channel *c = Channel::get(msg->iId); - Channel *p = Channel::get(msg->iParent); - if (!c || !p) - return; + Channel *c = Channel::get(msg->channel_id()); + Channel *p = Channel::get(msg->parent()); - Channel *pp = p; - while (pp) { - if (pp == c) + if (!c) { + if (msg->has_parent() && p && msg->has_name()) { + pmModel->addChannel(msg->channel_id(), p, u8(msg->name())); + msg->clear_name(); + msg->clear_parent(); + p = NULL; + } else { return; - pp = pp->cParent; + } } - if (c && p) - pmModel->moveChannel(c, p); -} -void MainWindow::msgChannelRename(Connection *, MessageChannelRename *msg) { - if (msg->iId == 0) - return; + if (p) { + Channel *pp = p; + while(pp) { + if (pp == c) + return; + pp = pp->cParent; + } + pmModel->moveChannel(c, p); + } - Channel *c = Channel::get(msg->iId); - if (c && c->cParent) - pmModel->renameChannel(c, msg->qsName); -} + if (msg->has_name()) + pmModel->renameChannel(c, u8(msg->name())); -void MainWindow::msgChannelDescUpdate(Connection *, MessageChannelDescUpdate *msg) { - Channel *c = Channel::get(msg->iId); - if (c) c->qsDesc=msg->qsDesc; -} + if (msg->has_description()) + c->qsDesc = u8(msg->description()); -void MainWindow::msgChannelLink(Connection *, MessageChannelLink *msg) { - Channel *c = Channel::get(msg->iId); - if (!c) - return; - - QList<Channel *> qlChans; - foreach(int id, msg->qlTargets) { - Channel *l = Channel::get(id); - if (l) - qlChans << l; + if (msg->links_size()) { + QList<Channel *> ql; + pmModel->unlinkAll(c); + for(int i=0;i<msg->links_size();++i) { + Channel *l = Channel::get(msg->links(i)); + if (l) + ql << l; + } + if (! ql.isEmpty()) + pmModel->linkChannels(c, ql); } - - switch (msg->ltType) { - case MessageChannelLink::Link: - pmModel->linkChannels(c, qlChans); - break; - case MessageChannelLink::Unlink: - pmModel->unlinkChannels(c, qlChans); - break; - case MessageChannelLink::UnlinkAll: - pmModel->unlinkAll(c); - break; - default: - qFatal("Unknown link message"); + if (msg->links_remove_size()) { + QList<Channel *> ql; + for(int i=0;i<msg->links_remove_size();++i) { + Channel *l = Channel::get(msg->links_remove(i)); + if (l) + ql << l; + } + if (! ql.isEmpty()) + pmModel->unlinkChannels(c, ql); } -} - -void MainWindow::msgServerAuthenticate(Connection *, MessageServerAuthenticate *) { -} - -void MainWindow::msgServerReject(Connection *, MessageServerReject *msg) { - rtLast = msg->rtType; - g.l->log(Log::ServerDisconnected, MainWindow::tr("Server connection rejected: %1.").arg(msg->qsReason)); - g.l->setIgnore(Log::ServerDisconnected, 1); -} - -void MainWindow::msgPermissionDenied(Connection *, MessagePermissionDenied *msg) { - g.l->log(Log::PermissionDenied, MainWindow::tr("Denied: %1.").arg(msg->qsReason)); -} - -void MainWindow::msgServerSync(Connection *, MessageServerSync *msg) { - MSG_INIT; - g.iMaxBandwidth = msg->iMaxBandwidth; - g.uiSession = msg->uiSession; - g.l->clearIgnore(); - g.l->log(Log::Information, msg->qsWelcomeText); - pmModel->ensureSelfVisible(); - pmModel->recheckLinks(); - - AudioInputPtr ai = g.ai; - if (ai) { - int bw = ai->getMaxBandwidth(); - if (bw > msg->iMaxBandwidth) { - g.l->log(Log::Information, MainWindow::tr("Server maximum bandwidth is only %1 kbit/s. Quality auto-adjusted.").arg(msg->iMaxBandwidth / 125)); + if (msg->links_add_size()) { + QList<Channel *> ql; + for(int i=0;i<msg->links_add_size();++i) { + Channel *l = Channel::get(msg->links_add(i)); + if (l) + ql << l; } - ai->setMaxBandwidth(g.iMaxBandwidth); + if (! ql.isEmpty()) + pmModel->linkChannels(c, ql); } +} - findDesiredChannel(); +void MainWindow::msgChannelRemove(Connection *, MumbleProto::ChannelRemove *msg) { + Channel *c = Channel::get(msg->channel_id()); + if (c && (c->iId != 0)) + pmModel->removeChannel(c); } -void MainWindow::msgTextMessage(Connection *, MessageTextMessage *msg) { - MSG_INIT; - const QString &name = pSrc ? pSrc->qsName : tr("Server", "message from"); - g.l->log(Log::TextMessage, MainWindow::tr("From %1: %2").arg(name).arg(msg->qsMessage), - MainWindow::tr("Message from %1").arg(name)); +void MainWindow::msgTextMessage(Connection *, MumbleProto::TextMessage *msg) { + ACTOR_INIT; + const QString &name = pSrc ? pSrc->qsName : tr("the server", "message from"); + g.l->log(Log::TextMessage, tr("From %1: %2").arg(name).arg(u8(msg->message())), + tr("Message from %1").arg(name)); } -void MainWindow::msgEditACL(Connection *, MessageEditACL *msg) { +void MainWindow::msgACL(Connection *, MumbleProto::ACL *msg) { + // FIXME: Check if channel exists first. + if (aclEdit) { aclEdit->reject(); delete aclEdit; aclEdit = NULL; } - aclEdit = new ACLEditor(msg, this); + aclEdit = new ACLEditor(*msg, this); aclEdit->show(); } -void MainWindow::msgQueryUsers(Connection *, MessageQueryUsers *msg) { +void MainWindow::msgQueryUsers(Connection *, MumbleProto::QueryUsers *msg) { if (aclEdit) - aclEdit->returnQuery(msg); -} - -void MainWindow::msgPing(Connection *, MessagePing *) { + aclEdit->returnQuery(*msg); } -void MainWindow::msgPingStats(Connection *, MessagePingStats *) { +void MainWindow::msgPing(Connection *, MumbleProto::Ping *) { + // FIXME: Do the logic *here*, since this ping is what matters. } -void MainWindow::msgTexture(Connection *, MessageTexture *msg) { - if (! msg->qbaTexture.isEmpty()) - g.o->textureResponse(msg->iPlayerId,msg->qbaTexture); -} - -void MainWindow::msgCryptSetup(Connection *, MessageCryptSetup *msg) { +void MainWindow::msgCryptSetup(Connection *, MumbleProto::CryptSetup *msg) { ConnectionPtr c= g.sh->cConnection; if (! c) return; - c->csCrypt.setKey(reinterpret_cast<const unsigned char *>(msg->qbaKey.constData()), reinterpret_cast<const unsigned char *>(msg->qbaClientNonce.constData()), reinterpret_cast<const unsigned char *>(msg->qbaServerNonce.constData())); -} - -void MainWindow::msgCryptSync(Connection *, MessageCryptSync *msg) { - ConnectionPtr c= g.sh->cConnection; - if (! c) - return; - if (msg->qbaNonce.isEmpty()) { - msg->qbaNonce = QByteArray(reinterpret_cast<const char *>(c->csCrypt.encrypt_iv), AES_BLOCK_SIZE); - g.sh->sendMessage(msg); - } else if (msg->qbaNonce.size() == AES_BLOCK_SIZE) { - c->csCrypt.uiResync++; - memcpy(c->csCrypt.decrypt_iv, msg->qbaNonce.constData(), AES_BLOCK_SIZE); + if (msg->has_key() && msg->has_client_nonce() && msg->has_server_nonce()) { + const std::string &key = msg->key(); + const std::string &client_nonce = msg->client_nonce(); + const std::string &server_nonce = msg->server_nonce(); + if (key.size() == AES_BLOCK_SIZE && client_nonce.size() == AES_BLOCK_SIZE && server_nonce.size() == AES_BLOCK_SIZE) + c->csCrypt.setKey(reinterpret_cast<const unsigned char *>(key.data()), reinterpret_cast<const unsigned char *>(client_nonce.data()), reinterpret_cast<const unsigned char *>(server_nonce.data())); + } else if (msg->has_server_nonce()) { + const std::string &server_nonce = msg->server_nonce(); + if (server_nonce.size() == AES_BLOCK_SIZE) { + c->csCrypt.uiResync++; + memcpy(c->csCrypt.decrypt_iv, server_nonce.data(), AES_BLOCK_SIZE); + } + } else { + msg->set_client_nonce(std::string(reinterpret_cast<const char *>(c->csCrypt.encrypt_iv), AES_BLOCK_SIZE)); + g.sh->sendMessage(*msg); } } -void MainWindow::msgContextAction(Connection *, MessageContextAction *) { +void MainWindow::msgContextAction(Connection *, MumbleProto::ContextAction *) { } -void MainWindow::msgContextAddAction(Connection *, MessageContextAddAction *msg) { - QAction *a = new QAction(msg->qsText, g.mw); - a->setData(msg->qsAction); +void MainWindow::msgContextActionAdd(Connection *, MumbleProto::ContextActionAdd *msg) { + QAction *a = new QAction(u8(msg->text()), g.mw); + a->setData(u8(msg->action())); connect(a, SIGNAL(triggered()), this, SLOT(context_triggered())); - if (msg->ctx & MessageContextAddAction::CtxServer) + unsigned int ctx = msg->context(); + if (ctx & MumbleProto::ContextActionAdd_Context_Server) qlServerActions.append(a); - if (msg->ctx & MessageContextAddAction::CtxPlayer) + if (ctx & MumbleProto::ContextActionAdd_Context_User) qlPlayerActions.append(a); - if (msg->ctx & MessageContextAddAction::CtxChannel) + if (ctx & MumbleProto::ContextActionAdd_Context_Channel) qlChannelActions.append(a); } + +void MainWindow::msgVersion(Connection *, MumbleProto::Version *) { +} diff --git a/src/mumble/Overlay.cpp b/src/mumble/Overlay.cpp index 26954caf9..490b0512d 100644 --- a/src/mumble/Overlay.cpp +++ b/src/mumble/Overlay.cpp @@ -293,6 +293,8 @@ void Overlay::forceSettings() { updateOverlay(); } +/* +FIXME: Move into update check. void Overlay::textureResponse(int id, const QByteArray &texture) { QString s = qhQueried.value(id); if (s.isEmpty()) @@ -316,6 +318,7 @@ void Overlay::textureResponse(int id, const QByteArray &texture) { qsForce.insert(id); setTexts(qlCurrentTexts); } +*/ typedef QPair<QString, quint32> qpChanCol; @@ -366,12 +369,6 @@ void Overlay::updateOverlay() { foreach(Player *p, ClientPlayer::get(g.uiSession)->cChannel->qlPlayers) { if ((g.s.osOverlay == Settings::All) || p->bTalking || ((p == ClientPlayer::get(g.uiSession)) && g.s.bOverlayAlwaysSelf)) { - if (g.s.bOverlayUserTextures && (p->iId >= 0) && (! qhQueried.contains(p->iId))) { - qhQueried.insert(p->iId, p->qsName); - MessageTexture mt; - mt.iPlayerId = p->iId; - g.sh->sendMessage(&mt); - } QString name = p->qsName; Decoration dec = None; if (p->bDeaf || p->bSelfDeaf) diff --git a/src/mumble/Overlay.h b/src/mumble/Overlay.h index 95e364d18..afe028222 100644 --- a/src/mumble/Overlay.h +++ b/src/mumble/Overlay.h @@ -120,7 +120,6 @@ class Overlay : public QObject { Overlay(); ~Overlay(); bool isActive() const; - void textureResponse(int id, const QByteArray &texture); public slots: void on_Timer_timeout(); void updateOverlay(); diff --git a/src/mumble/PlayerModel.cpp b/src/mumble/PlayerModel.cpp index 063d5b3b9..f0c6a276f 100644 --- a/src/mumble/PlayerModel.cpp +++ b/src/mumble/PlayerModel.cpp @@ -979,10 +979,10 @@ bool PlayerModel::dropMimeData(const QMimeData *md, Qt::DropAction, int, int, co expandAll(c); if (! isChannel) { - MessagePlayerMove mpm; - mpm.uiVictim = uiSession; - mpm.iChannelId = c->iId; - g.sh->sendMessage(&mpm); + MumbleProto::UserState mpus; + mpus.set_session(uiSession); + mpus.set_channel_id(c->iId); + g.sh->sendMessage(mpus, MessageHandler::UserState); } else { int ret; switch (g.s.ceChannelDrag) { @@ -1002,10 +1002,10 @@ bool PlayerModel::dropMimeData(const QMimeData *md, Qt::DropAction, int, int, co g.l->log(Log::CriticalError, MainWindow::tr("Unknown Channel Drag mode in PlayerModel::dropMimeData.")); break; } - MessageChannelMove mcm; - mcm.iId = iId; - mcm.iParent = c->iId; - g.sh->sendMessage(&mcm); + MumbleProto::ChannelState mpcs; + mpcs.set_channel_id(iId); + mpcs.set_parent(c->iId); + g.sh->sendMessage(mpcs, MessageHandler::ChannelState); } return true; diff --git a/src/mumble/ServerHandler.cpp b/src/mumble/ServerHandler.cpp index 77186bc92..975da2e95 100644 --- a/src/mumble/ServerHandler.cpp +++ b/src/mumble/ServerHandler.cpp @@ -128,27 +128,32 @@ void ServerHandler::udpReady() { if (! cConnection->csCrypt.isValid()) continue; + if (buflen < 5) + continue; + if (! cConnection->csCrypt.decrypt(reinterpret_cast<const unsigned char *>(encrypted), reinterpret_cast<unsigned char *>(buffer), buflen)) { if (cConnection->csCrypt.tLastGood.elapsed() > 5000000ULL) { if (cConnection->csCrypt.tLastRequest.elapsed() > 5000000ULL) { cConnection->csCrypt.tLastRequest.restart(); - MessageCryptSync mcs; - sendMessage(&mcs); + MumbleProto::CryptSetup mpcs; + sendMessage(mpcs); } } continue; } - PacketDataStream pds(buffer, buflen-4); + PacketDataStream pds(buffer + 1, buflen-5); - quint32 msgType, uiSession; - pds >> msgType >> uiSession; + quint32 msgType; + pds >> msgType; - if (msgType == Message::Ping) { + if (msgType == MessageHandler::UDPPing) { quint64 t; pds >> t; Connection::updatePing(cConnection->dUDPPingAvg, cConnection->dUDPPingVar, cConnection->uiUDPPackets, tTimestamp.elapsed() - t); - } else if (msgType == Message::Speex) { + } else if (msgType == MessageHandler::UDPVoice) { + unsigned int uiSession; + pds >> uiSession; ClientPlayer *p = ClientPlayer::get(uiSession); AudioOutputPtr ao = g.ao; if (ao) { @@ -167,28 +172,33 @@ void ServerHandler::udpReady() { } } -void ServerHandler::sendMessage(Message *mMsg) { - bool mayUdp = (mMsg->messageType() == Message::Speex) || (mMsg->messageType() == Message::Ping); - mMsg->uiSession = g.uiSession; +void ServerHandler::sendMessage(const char *data, int len) { + STACKVAR(unsigned char, crypto, len+4); - if (mayUdp && !NetworkConfig::TcpModeEnabled()) { - QMutexLocker qml(&qmUdp); - if (! qusUdp) - return; - if (! cConnection->csCrypt.isValid()) - return; - unsigned char buffer[65536]; - unsigned char crypto[65540]; - PacketDataStream pds(buffer, 65536); - mMsg->messageToNetwork(pds); - cConnection->csCrypt.encrypt(buffer, crypto, pds.size()); - qusUdp->writeDatagram(reinterpret_cast<const char *>(crypto), pds.size() + 4, qhaRemote, usPort); + QMutexLocker qml(&qmUdp); + + if (! qusUdp) + return; + if (! cConnection->csCrypt.isValid()) + return; + + if (NetworkConfig::TcpModeEnabled()) { + // FIXME: Tunnel } else { - QByteArray qbaBuffer; - mMsg->messageToNetwork(qbaBuffer); + cConnection->csCrypt.encrypt(reinterpret_cast<const unsigned char *>(data), crypto, len); + qusUdp->writeDatagram(reinterpret_cast<const char *>(crypto), len + 4, qhaRemote, usPort); + } +} - ServerHandlerMessageEvent *shme=new ServerHandlerMessageEvent(qbaBuffer, mayUdp); +void ServerHandler::sendMessage(const ::google::protobuf::Message &msg, unsigned int msgType) { + QByteArray qba; + + if (QThread::currentThread() != thread()) { + MessageHandler::messageToNetwork(msg, msgType, qba); + ServerHandlerMessageEvent *shme=new ServerHandlerMessageEvent(qba, false); QApplication::postEvent(this, shme); + } else { + cConnection->sendMessage(msg, msgType, qba); } } @@ -209,7 +219,7 @@ void ServerHandler::run() { connect(ticker, SIGNAL(timeout()), this, SLOT(sendPing())); ticker->start(5000); - g.mw->rtLast = MessageServerReject::None; + g.mw->rtLast = MumbleProto::Reject_RejectType_None; exec(); @@ -242,65 +252,39 @@ void ServerHandler::setSslErrors(const QList<QSslError> &errors) { void ServerHandler::sendPing() { CryptState &cs = cConnection->csCrypt; - MessagePingStats mps; - mps.uiTimestamp = tTimestamp.elapsed(); - mps.uiGood = cs.uiGood; - mps.uiLate = cs.uiLate; - mps.uiLost = cs.uiLost; - mps.uiResync = cs.uiResync; - mps.dUDPPingAvg = cConnection->dUDPPingAvg; - mps.dUDPPingVar = cConnection->dUDPPingVar; - mps.dTCPPingAvg = cConnection->dTCPPingAvg; - mps.dTCPPingVar = cConnection->dTCPPingVar; - sendMessage(&mps); - - if (!NetworkConfig::TcpModeEnabled()) { - MessagePing mp; - mp.uiTimestamp = mps.uiTimestamp; - sendMessage(&mp); + + quint64 t = tTimestamp.elapsed(); + + if (qusUdp) { + unsigned char buffer[256]; + PacketDataStream pds(buffer + 1, 255); + buffer[0] = MessageHandler::UDPPing << 5; + pds << t; + sendMessage(reinterpret_cast<const char *>(buffer), pds.size() + 1); } -} -void ServerHandler::message(QByteArray &qbaMsg) { - Message *mMsg = Message::networkToMessage(qbaMsg); - if (! mMsg) - return; + MumbleProto::Ping mpp; - ClientPlayer *p = ClientPlayer::get(mMsg->uiSession); - AudioOutputPtr ao = g.ao; + mpp.set_timestamp(t); + mpp.set_good(cs.uiGood); + mpp.set_late(cs.uiLate); + mpp.set_lost(cs.uiLost); + mpp.set_resync(cs.uiResync); - if (mMsg->messageType() == Message::Speex) { - if (ao) { - if (p) { - MessageSpeex *msMsg=static_cast<MessageSpeex *>(mMsg); - if (! p->bLocalMute) - ao->addFrameToBuffer(p, msMsg->qbaSpeexPacket, msMsg->iSeq); - } else { - // Eek, we just got a late packet for a player already removed. Remove - // the buffer and pretend this never happened. - // If ~AudioOutputPlayer or decendants uses the Player object now, - // Bad Things happen. - ao->removeBuffer(p); - } - } - } else if (mMsg->messageType() == Message::PingStats) { - MessagePingStats *mpsMsg = static_cast<MessagePingStats *>(mMsg); - CryptState &cs = cConnection->csCrypt; - cs.uiRemoteGood = mpsMsg->uiGood; - cs.uiRemoteLate = mpsMsg->uiLate; - cs.uiRemoteLost = mpsMsg->uiLost; - cs.uiRemoteResync = mpsMsg->uiResync; - Connection::updatePing(cConnection->dTCPPingAvg, cConnection->dTCPPingVar, cConnection->uiTCPPackets, tTimestamp.elapsed() - mpsMsg->uiTimestamp); - } else { - if (mMsg->messageType() == Message::ServerLeave) { - if (ao) - ao->removeBuffer(p); - } - ServerHandlerMessageEvent *shme=new ServerHandlerMessageEvent(qbaMsg, false); - QApplication::postEvent(g.mw, shme); - } + mpp.set_udp_ping_avg(cConnection->dUDPPingAvg); + mpp.set_udp_ping_var(cConnection->dUDPPingVar); + mpp.set_tcp_ping_avg(cConnection->dTCPPingAvg); + mpp.set_tcp_ping_var(cConnection->dTCPPingVar); + sendMessage(mpp); +} + +void ServerHandler::message(unsigned int msgType, QByteArray &qbaMsg) { + // FIXME: Special-case UDP tunnel, don't throw it to GUI thread! + // FIXME: UserRemove needs to clear out stale AudioOutput + // FIXME: Do something about the msgType, please :) - delete mMsg; + ServerHandlerMessageEvent *shme=new ServerHandlerMessageEvent(qbaMsg, false); + QApplication::postEvent(g.mw, shme); } void ServerHandler::disconnect() { @@ -324,11 +308,13 @@ void ServerHandler::serverConnectionConnected() { cConnection->setToS(); - MessageServerAuthenticate msaMsg; - msaMsg.qsUsername = qsUserName; - msaMsg.qsPassword = qsPassword; + MumbleProto::Authenticate mpa; + mpa.set_username(u8(qsUserName)); + mpa.set_password(u8(qsPassword)); + // FIXME: Check config -- make some way to reset this "on the fly" + mpa.set_want_textures(true); - cConnection->sendMessage(&msaMsg); + sendMessage(mpa); { QMutexLocker qml(&qmUdp); diff --git a/src/mumble/ServerHandler.h b/src/mumble/ServerHandler.h index a2d173e0a..34fa4e23d 100644 --- a/src/mumble/ServerHandler.h +++ b/src/mumble/ServerHandler.h @@ -35,7 +35,8 @@ #include "mumble_pch.hpp" #include "Timer.h" - +#include "Message.h" +#include "PacketDataStream.h" class Connection; class Message; @@ -80,14 +81,21 @@ class ServerHandler : public QThread { void setConnectionInfo(const QString &host, unsigned short port, const QString &username, const QString &pw); void getConnectionInfo(QString &host, unsigned short &port, QString &username, QString &pw); void customEvent(QEvent *evt); - void sendMessage(Message *m); + + void sendMessage(const ::google::protobuf::Message &msg, unsigned int msgType); + void sendMessage(const char *data, int len); + +#define MUMBLE_MH_MSG(x) void sendMessage(const MumbleProto::##x &msg) { sendMessage(msg, MessageHandler::##x); } + MUMBLE_MH_ALL +#undef MUMBLE_MH_MSG + void disconnect(); void run(); signals: void disconnected(QString reason); void connected(); protected slots: - void message(QByteArray &); + void message(unsigned int, QByteArray &); void serverConnectionConnected(); void serverConnectionClosed(QString); void setSslErrors(const QList<QSslError> &); diff --git a/src/murmur/Messages.cpp b/src/murmur/Messages.cpp index c57249e07..439e85da3 100644 --- a/src/murmur/Messages.cpp +++ b/src/murmur/Messages.cpp @@ -763,6 +763,7 @@ void Server::msgACL(Connection *cCon, MumbleProto::ACL *msg) { foreach(int id, pg->members()) group->add_inherited_members(id); } + // TODO: Send QueryUsers with it. sendMessage(uSource, *msg, MessageHandler::ACL); } else { Group *g; diff --git a/src/murmur/Server.cpp b/src/murmur/Server.cpp index 27f7551a4..f1c333199 100644 --- a/src/murmur/Server.cpp +++ b/src/murmur/Server.cpp @@ -650,7 +650,7 @@ void Server::message(const QByteArray &qbaMsg, unsigned int msgType, Connection if (cCon == NULL) { cCon = static_cast<Connection *>(sender()); } - dispatch(cCon, msgType, qbaMsg); + dispatch(cCon, qbaMsg); } void Server::checkTimeout() { |