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

github.com/mumble-voip/mumble.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Connection.cpp22
-rw-r--r--src/Connection.h5
-rw-r--r--src/Message.cpp683
-rw-r--r--src/Message.h510
-rw-r--r--src/Mumble.proto53
-rw-r--r--src/PacketDataStream.h406
-rw-r--r--src/murmur/Messages.cpp1123
-rw-r--r--src/murmur/RPC.cpp108
-rw-r--r--src/murmur/Server.cpp168
-rw-r--r--src/murmur/Server.h62
-rw-r--r--src/murmur/ServerDB.cpp3
11 files changed, 747 insertions, 2396 deletions
diff --git a/src/Connection.cpp b/src/Connection.cpp
index 96219321c..5a62996f4 100644
--- a/src/Connection.cpp
+++ b/src/Connection.cpp
@@ -30,7 +30,6 @@
#include "Message.h"
#include "Connection.h"
-#include "PacketDataStream.h"
#ifdef Q_OS_UNIX
#include <sys/socket.h>
@@ -87,7 +86,7 @@ void Connection::setToS() {
#elif defined(Q_OS_UNIX)
int val = 0xa0;
if (setsockopt(qtsSocket->socketDescriptor(), IPPROTO_IP, IP_TOS, &val, sizeof(val))) {
- int val = 0x60;
+ val = 0x60;
if (setsockopt(qtsSocket->socketDescriptor(), IPPROTO_IP, IP_TOS, &val, sizeof(val)))
qWarning("Connection: Failed to set TOS for TCP Socket");
}
@@ -204,11 +203,22 @@ void Connection::socketDisconnected() {
}
}
-void Connection::sendMessage(const Message *mMsg) {
- QByteArray qbaBuffer;
- mMsg->messageToNetwork(qbaBuffer);
+void Connection::sendMessage(const ::google::protobuf::Message &msg, unsigned int msgType, QByteArray &cache) {
+ if (cache.isEmpty()) {
+ 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);
+ }
- sendMessage(qbaBuffer);
+ sendMessage(cache);
}
void Connection::sendMessage(const QByteArray &qbaMsg) {
diff --git a/src/Connection.h b/src/Connection.h
index 8955b406a..18b0cfc89 100644
--- a/src/Connection.h
+++ b/src/Connection.h
@@ -33,8 +33,7 @@
#include "murmur_pch.h"
#include "CryptState.h"
-
-class Message;
+#include "Mumble.pb.h"
class Connection : public QObject {
private:
@@ -68,7 +67,7 @@ class Connection : public QObject {
public:
Connection(QObject *parent, QSslSocket *qtsSocket);
~Connection();
- void sendMessage(const Message *mMsg);
+ void sendMessage(const ::google::protobuf::Message &msg, unsigned int msgType, QByteArray &cache);
void sendMessage(const QByteArray &qbaMsg);
void disconnectSocket(bool force=false);
void forceFlush();
diff --git a/src/Message.cpp b/src/Message.cpp
index bd31b68a8..48e0d081a 100644
--- a/src/Message.cpp
+++ b/src/Message.cpp
@@ -29,681 +29,18 @@
*/
#include "Message.h"
-#include "PacketDataStream.h"
#include "murmur_pch.h"
-Message::Message() {
- uiSession = 0;
-}
-
-Message::~Message() {
-}
-
-void Message::messageToNetwork(QByteArray &qbaOut) const {
- char buffer[8192];
- PacketDataStream qdsOut(buffer, 8192);
- qdsOut << messageType();
- qdsOut << uiSession;
- saveStream(qdsOut);
-
- if (qdsOut.undersize() == 0) {
- qbaOut = QByteArray(buffer, qdsOut.size());
- return;
- }
-
- unsigned int size = 8192 + qdsOut.undersize();
- STACKVAR(char, b, size);
- PacketDataStream pdsResized(b, size);
- pdsResized << messageType();
- pdsResized << uiSession;
- saveStream(pdsResized);
- qbaOut = QByteArray(b, pdsResized.size());
-}
-
-void Message::messageToNetwork(PacketDataStream &pds) const {
- pds << messageType();
- pds << uiSession;
- saveStream(pds);
- pds.truncate();
-}
-
-Message *Message::networkToMessage(QByteArray &qbaIn) {
- PacketDataStream qdsIn(qbaIn.constData(), qbaIn.size());
- return networkToMessage(qdsIn);
-}
-
-Message *Message::networkToMessage(PacketDataStream &qdsIn) {
- Message *mMsg = NULL;
- unsigned char iMessageType;
- short uiSession;
- qdsIn >> iMessageType;
- qdsIn >> uiSession;
- switch (iMessageType) {
- case Speex:
- mMsg = new MessageSpeex();
- break;
- case ServerAuthenticate:
- mMsg = new MessageServerAuthenticate();
- break;
- case ServerReject:
- mMsg = new MessageServerReject();
- break;
- case ServerSync:
- mMsg = new MessageServerSync();
- break;
- case ServerJoin:
- mMsg = new MessageServerJoin();
- break;
- case ServerLeave:
- mMsg = new MessageServerLeave();
- break;
- case ServerBanList:
- mMsg = new MessageServerBanList();
- break;
- case PlayerMute:
- mMsg = new MessagePlayerMute();
- break;
- case PlayerDeaf:
- mMsg = new MessagePlayerDeaf();
- break;
- case PlayerSelfMuteDeaf:
- mMsg = new MessagePlayerSelfMuteDeaf();
- break;
- case PlayerKick:
- mMsg = new MessagePlayerKick();
- break;
- case PlayerBan:
- mMsg = new MessagePlayerBan();
- break;
- case PlayerMove:
- mMsg = new MessagePlayerMove();
- break;
- case PlayerRename:
- mMsg = new MessagePlayerRename();
- break;
- case ChannelAdd:
- mMsg = new MessageChannelAdd();
- break;
- case ChannelRemove:
- mMsg = new MessageChannelRemove();
- break;
- case ChannelMove:
- mMsg = new MessageChannelMove();
- break;
- case ChannelLink:
- mMsg = new MessageChannelLink();
- break;
- case ChannelRename:
- mMsg = new MessageChannelRename();
- break;
- case ChannelDescUpdate:
- mMsg = new MessageChannelDescUpdate();
- break;
- case TextMessage:
- mMsg = new MessageTextMessage();
- break;
- case PermissionDenied:
- mMsg = new MessagePermissionDenied();
- break;
- case EditACL:
- mMsg = new MessageEditACL();
- break;
- case QueryUsers:
- mMsg = new MessageQueryUsers();
- break;
- case Ping:
- mMsg = new MessagePing();
- break;
- case PingStats:
- mMsg = new MessagePingStats();
- break;
- case PlayerTexture:
- mMsg = new MessageTexture();
- break;
- case CryptSetup:
- mMsg = new MessageCryptSetup();
- break;
- case CryptSync:
- mMsg = new MessageCryptSync();
- break;
- case ContextAction:
- mMsg = new MessageContextAction();
- break;
- case ContextAddAction:
- mMsg = new MessageContextAddAction();
- break;
- default:
- qWarning("Message: Type %d (session %d, size %d) is unknown type", iMessageType, uiSession, qdsIn.capacity());
- }
- if (mMsg) {
- mMsg->uiSession=uiSession;
- mMsg->restoreStream(qdsIn);
- if (! qdsIn.isValid()) {
- delete mMsg;
- mMsg = NULL;
- qWarning("Message: Type %d (session %d, size %d) corrupt or short packet", iMessageType, uiSession, qdsIn.capacity());
- } else if (qdsIn.left() != 0) {
- delete mMsg;
- mMsg = NULL;
- qWarning("Message: Type %d (session %d) Long packet: %d/%d leftover bytes", iMessageType, uiSession, qdsIn.left(), qdsIn.size());
- } else if (! mMsg->isValid()) {
- delete mMsg;
- mMsg = NULL;
- qWarning("Message: Type %d (session %d, size %d) failed to validate", iMessageType, uiSession, qdsIn.capacity());
- }
- }
-
- return mMsg;
-}
-
-void MessageHandler::dispatch(Connection *cCon, Message *msg) {
- switch (msg->messageType()) {
- case Message::Speex:
- msgSpeex(cCon, static_cast<MessageSpeex *>(msg));
- break;
- case Message::ServerAuthenticate:
- msgServerAuthenticate(cCon, static_cast<MessageServerAuthenticate *>(msg));
- break;
- case Message::ServerReject:
- msgServerReject(cCon, static_cast<MessageServerReject *>(msg));
- break;
- case Message::ServerSync:
- msgServerSync(cCon, static_cast<MessageServerSync *>(msg));
- break;
- case Message::ServerJoin:
- msgServerJoin(cCon, static_cast<MessageServerJoin *>(msg));
- break;
- case Message::ServerLeave:
- msgServerLeave(cCon, static_cast<MessageServerLeave *>(msg));
- break;
- case Message::ServerBanList:
- msgServerBanList(cCon, static_cast<MessageServerBanList *>(msg));
- break;
- case Message::PlayerMute:
- msgPlayerMute(cCon, static_cast<MessagePlayerMute *>(msg));
- break;
- case Message::PlayerDeaf:
- msgPlayerDeaf(cCon, static_cast<MessagePlayerDeaf *>(msg));
- break;
- case Message::PlayerSelfMuteDeaf:
- msgPlayerSelfMuteDeaf(cCon, static_cast<MessagePlayerSelfMuteDeaf *>(msg));
- break;
- case Message::PlayerKick:
- msgPlayerKick(cCon, static_cast<MessagePlayerKick *>(msg));
- break;
- case Message::PlayerBan:
- msgPlayerBan(cCon, static_cast<MessagePlayerBan *>(msg));
- break;
- case Message::PlayerMove:
- msgPlayerMove(cCon, static_cast<MessagePlayerMove *>(msg));
- break;
- case Message::PlayerRename:
- msgPlayerRename(cCon, static_cast<MessagePlayerRename *>(msg));
- break;
- case Message::ChannelAdd:
- msgChannelAdd(cCon, static_cast<MessageChannelAdd *>(msg));
- break;
- case Message::ChannelRemove:
- msgChannelRemove(cCon, static_cast<MessageChannelRemove *>(msg));
- break;
- case Message::ChannelMove:
- msgChannelMove(cCon, static_cast<MessageChannelMove *>(msg));
- break;
- case Message::ChannelLink:
- msgChannelLink(cCon, static_cast<MessageChannelLink *>(msg));
- break;
- case Message::ChannelRename:
- msgChannelRename(cCon, static_cast<MessageChannelRename *>(msg));
- break;
- case Message::ChannelDescUpdate:
- msgChannelDescUpdate(cCon, static_cast<MessageChannelDescUpdate *>(msg));
- break;
- case Message::TextMessage:
- msgTextMessage(cCon, static_cast<MessageTextMessage *>(msg));
- break;
- case Message::PermissionDenied:
- msgPermissionDenied(cCon, static_cast<MessagePermissionDenied *>(msg));
- break;
- case Message::EditACL:
- msgEditACL(cCon, static_cast<MessageEditACL *>(msg));
- break;
- case Message::QueryUsers:
- msgQueryUsers(cCon, static_cast<MessageQueryUsers *>(msg));
- break;
- case Message::Ping:
- msgPing(cCon, static_cast<MessagePing *>(msg));
- break;
- case Message::PingStats:
- msgPingStats(cCon, static_cast<MessagePingStats *>(msg));
- break;
- case Message::PlayerTexture:
- msgTexture(cCon, static_cast<MessageTexture *>(msg));
- break;
- case Message::CryptSetup:
- msgCryptSetup(cCon, static_cast<MessageCryptSetup *>(msg));
- break;
- case Message::CryptSync:
- msgCryptSync(cCon, static_cast<MessageCryptSync *>(msg));
- break;
- case Message::ContextAction:
- msgContextAction(cCon, static_cast<MessageContextAction *>(msg));
- break;
- case Message::ContextAddAction:
- msgContextAddAction(cCon, static_cast<MessageContextAddAction *>(msg));
+void MessageHandler::dispatch(Connection *cCon, int type, const QByteArray &msg) {
+ switch (type) {
+ case MessageHandler::Version:
+ {
+ MumbleProto::Version mpv;
+ mpv.ParseFromArray(msg.constData(), msg.size());
+ msgVersion(cCon, &mpv);
+ }
break;
default:
- qFatal("MessageHandler called with unknown message type %d", msg->messageType());
- }
-}
-
-bool Message::isValid() const {
- return true;
-}
-
-void Message::saveStream(PacketDataStream &) const {
-}
-
-void Message::restoreStream(PacketDataStream &) {
-}
-
-void MessagePing::saveStream(PacketDataStream &qdsOut) const {
- qdsOut << uiTimestamp;
-}
-
-void MessagePing::restoreStream(PacketDataStream &qdsIn) {
- qdsIn >> uiTimestamp;
-}
-
-void MessagePingStats::saveStream(PacketDataStream &qdsOut) const {
- qdsOut << uiTimestamp << uiGood << uiLate << uiLost << uiResync << dUDPPingAvg << dUDPPingVar << uiUDPPackets << dTCPPingAvg << dTCPPingVar << uiTCPPackets;
-}
-
-void MessagePingStats::restoreStream(PacketDataStream &qdsIn) {
- qdsIn >> uiTimestamp >> uiGood >> uiLate >> uiLost >> uiResync >> dUDPPingAvg >> dUDPPingVar >> uiUDPPackets >> dTCPPingAvg >> dTCPPingVar >> uiTCPPackets;
-}
-
-MessageServerAuthenticate::MessageServerAuthenticate() {
- iVersion = MESSAGE_STREAM_VERSION;
-}
-
-void MessageServerAuthenticate::saveStream(PacketDataStream &qdsOut) const {
- qdsOut << iVersion;
- qdsOut << qsUsername;
- qdsOut << qsPassword;
-}
-
-void MessageServerAuthenticate::restoreStream(PacketDataStream &qdsIn) {
- qdsIn >> iVersion;
- qdsIn >> qsUsername;
- qdsIn >> qsPassword;
-}
-
-
-void MessageServerReject::saveStream(PacketDataStream &qdsOut) const {
- qdsOut << qsReason;
- qdsOut << static_cast<int>(rtType);
-}
-
-void MessageServerReject::restoreStream(PacketDataStream &qdsIn) {
- qdsIn >> qsReason;
- int v;
- qdsIn >> v;
- rtType = static_cast<RejectType>(v);
-}
-
-void MessageServerSync::saveStream(PacketDataStream &qdsOut) const {
- qdsOut << iMaxBandwidth;
- qdsOut << qsWelcomeText;
-}
-
-void MessageServerSync::restoreStream(PacketDataStream &qdsIn) {
- qdsIn >> iMaxBandwidth;
- qdsIn >> qsWelcomeText;
-}
-
-void MessageServerJoin::saveStream(PacketDataStream &qdsOut) const {
- qdsOut << qsPlayerName;
- qdsOut << iId;
-}
-
-void MessageServerJoin::restoreStream(PacketDataStream &qdsIn) {
- qdsIn >> qsPlayerName;
- qdsIn >> iId;
-}
-
-void MessageServerBanList::saveStream(PacketDataStream &qdsOut) const {
- qdsOut << bQuery;
- qdsOut << qlBans;
-}
-
-void MessageServerBanList::restoreStream(PacketDataStream &qdsIn) {
- qdsIn >> bQuery;
- qdsIn >> qlBans;
-}
-
-void MessagePermissionDenied::saveStream(PacketDataStream &qdsOut) const {
- qdsOut << qsReason;
-}
-
-void MessagePermissionDenied::restoreStream(PacketDataStream &qdsIn) {
- qdsIn >> qsReason;
-}
-
-void MessageSpeex::saveStream(PacketDataStream &qdsOut) const {
- qdsOut << static_cast<unsigned short>(iSeq);
- qdsOut.append(qbaSpeexPacket.constData(), qbaSpeexPacket.size());
-}
-
-void MessageSpeex::restoreStream(PacketDataStream &qdsIn) {
- qdsIn >> iSeq;
- qbaSpeexPacket = qdsIn.dataBlock(qdsIn.left());
-}
-
-bool MessageSpeex::isValid() const {
- return ! qbaSpeexPacket.isEmpty();
-}
-
-void MessagePlayerMute::saveStream(PacketDataStream &qdsOut) const {
- qdsOut << uiVictim;
- qdsOut << bMute;
-}
-
-void MessagePlayerMute::restoreStream(PacketDataStream &qdsIn) {
- qdsIn >> uiVictim;
- qdsIn >> bMute;
-}
-
-void MessagePlayerDeaf::saveStream(PacketDataStream &qdsOut) const {
- qdsOut << uiVictim;
- qdsOut << bDeaf;
-}
-
-void MessagePlayerDeaf::restoreStream(PacketDataStream &qdsIn) {
- qdsIn >> uiVictim;
- qdsIn >> bDeaf;
-}
-
-void MessagePlayerKick::saveStream(PacketDataStream &qdsOut) const {
- qdsOut << uiVictim;
- qdsOut << qsReason;
-}
-
-void MessagePlayerKick::restoreStream(PacketDataStream &qdsIn) {
- qdsIn >> uiVictim;
- qdsIn >> qsReason;
-}
-
-void MessagePlayerBan::saveStream(PacketDataStream &qdsOut) const {
- qdsOut << uiVictim;
- qdsOut << qsReason;
-}
-
-void MessagePlayerBan::restoreStream(PacketDataStream &qdsIn) {
- qdsIn >> uiVictim;
- qdsIn >> qsReason;
-}
-
-void MessagePlayerMove::saveStream(PacketDataStream &qdsOut) const {
- qdsOut << uiVictim;
- qdsOut << iChannelId;
-}
-
-void MessagePlayerMove::restoreStream(PacketDataStream &qdsIn) {
- qdsIn >> uiVictim;
- qdsIn >> iChannelId;
-}
-
-void MessagePlayerRename::saveStream(PacketDataStream &qdsOut) const {
- qdsOut << qsName;
-}
-
-void MessagePlayerRename::restoreStream(PacketDataStream &qdsIn) {
- qdsIn >> qsName;
-}
-
-void MessagePlayerSelfMuteDeaf::saveStream(PacketDataStream &qdsOut) const {
- qdsOut << bMute;
- qdsOut << bDeaf;
-}
-
-void MessagePlayerSelfMuteDeaf::restoreStream(PacketDataStream &qdsIn) {
- qdsIn >> bMute;
- qdsIn >> bDeaf;
-}
-
-void MessageChannelAdd::saveStream(PacketDataStream &qdsOut) const {
- qdsOut << iId;
- qdsOut << iParent;
- qdsOut << qsName;
-}
-
-void MessageChannelAdd::restoreStream(PacketDataStream &qdsIn) {
- qdsIn >> iId;
- qdsIn >> iParent;
- qdsIn >> qsName;
-}
-
-void MessageChannelRemove::saveStream(PacketDataStream &qdsOut) const {
- qdsOut << iId;
-}
-
-void MessageChannelRemove::restoreStream(PacketDataStream &qdsIn) {
- qdsIn >> iId;
-}
-
-void MessageChannelLink::saveStream(PacketDataStream &qdsOut) const {
- qdsOut << iId;
- qdsOut << static_cast<int>(ltType);
- qdsOut << qlTargets;
-}
-
-void MessageChannelLink::restoreStream(PacketDataStream &qdsIn) {
- qdsIn >> iId;
- int v;
- qdsIn >> v;
- ltType = static_cast<LinkType>(v);
- qdsIn >> qlTargets;
-}
-
-void MessageChannelMove::saveStream(PacketDataStream &qdsOut) const {
- qdsOut << iId;
- qdsOut << iParent;
-}
-
-void MessageChannelMove::restoreStream(PacketDataStream &qdsIn) {
- qdsIn >> iId;
- qdsIn >> iParent;
-}
-
-void MessageChannelRename::saveStream(PacketDataStream &qdsOut) const {
- qdsOut << iId << qsName;
-}
-
-void MessageChannelRename::restoreStream(PacketDataStream &qdsIn) {
- qdsIn >> iId >> qsName;
-}
-
-void MessageChannelDescUpdate::saveStream(PacketDataStream &qdsOut) const {
- qdsOut << iId << qsDesc;
-}
-
-void MessageChannelDescUpdate::restoreStream(PacketDataStream &qdsIn) {
- qdsIn >> iId >> qsDesc;
-}
-
-void MessageTextMessage::saveStream(PacketDataStream &qdsOut) const {
- qdsOut << uiVictim;
- qdsOut << iChannel;
- qdsOut << bTree;
- qdsOut << qsMessage;
-}
-
-void MessageTextMessage::restoreStream(PacketDataStream &qdsIn) {
- qdsIn >> uiVictim;
- qdsIn >> iChannel;
- qdsIn >> bTree;
- qdsIn >> qsMessage;
-}
-
-void MessageEditACL::saveStream(PacketDataStream &qdsOut) const {
- qdsOut << iId;
- qdsOut << bQuery;
- if (bQuery)
- return;
-
- qdsOut << bInheritACL;
- qdsOut << groups;
- qdsOut << acls;
-}
-
-void MessageEditACL::restoreStream(PacketDataStream &qdsIn) {
- qdsIn >> iId;
- qdsIn >> bQuery;
- if (bQuery)
- return;
-
- qdsIn >> bInheritACL;
- qdsIn >> groups;
- qdsIn >> acls;
-}
-
-void MessageQueryUsers::saveStream(PacketDataStream &qdsOut) const {
- qdsOut << qlIds;
- qdsOut << qlNames;
-}
-
-void MessageQueryUsers::restoreStream(PacketDataStream &qdsIn) {
- qdsIn >> qlIds;
- qdsIn >> qlNames;
-}
-
-bool MessageQueryUsers::isValid() const {
- if (qlIds.count() != qlNames.count())
- return false;
-
- int i;
- for (i=0;i<qlIds.count();i++) {
- if ((qlIds[i] == -1) && (qlNames[i].isEmpty()))
- return false;
- }
- return true;
-}
-
-void MessageTexture::saveStream(PacketDataStream &qdsOut) const {
- qdsOut << iPlayerId;
- qdsOut << qbaTexture;
-}
-
-void MessageTexture::restoreStream(PacketDataStream &qdsIn) {
- qdsIn >> iPlayerId;
- qdsIn >> qbaTexture;
-}
-
-void MessageCryptSetup::saveStream(PacketDataStream &qdsOut) const {
- qdsOut << qbaKey << qbaServerNonce << qbaClientNonce;
-}
-
-void MessageCryptSetup::restoreStream(PacketDataStream &qdsIn) {
- qdsIn >> qbaKey >> qbaServerNonce >> qbaClientNonce;
-}
-
-bool MessageCryptSetup::isValid() const {
- return ((qbaKey.size() == AES_BLOCK_SIZE) &&
- (qbaClientNonce.size() == AES_BLOCK_SIZE) &&
- (qbaServerNonce.size() == AES_BLOCK_SIZE));
-}
-
-
-void MessageCryptSync::saveStream(PacketDataStream &qdsOut) const {
- qdsOut << qbaNonce;
-}
-
-void MessageCryptSync::restoreStream(PacketDataStream &qdsIn) {
- qdsIn >> qbaNonce;
-}
-
-bool MessageCryptSync::isValid() const {
- return (qbaNonce.isEmpty() || (qbaNonce.size() == AES_BLOCK_SIZE));
-}
-
-void MessageContextAddAction::saveStream(PacketDataStream &qdsOut) const {
- qdsOut << qsAction;
- qdsOut << qsText;
- qdsOut << static_cast<int>(ctx);
-}
-
-void MessageContextAddAction::restoreStream(PacketDataStream &qdsIn) {
- qdsIn >> qsAction;
- qdsIn >> qsText;
- int c;
- qdsIn >> c;
- ctx = static_cast<Context>(c);
-}
-
-bool MessageContextAddAction::isValid() const {
- return (! qsAction.isEmpty() && (ctx & (CtxServer | CtxPlayer | CtxChannel)));
-}
-
-void MessageContextAction::saveStream(PacketDataStream &qdsOut) const {
- qdsOut << qsAction;
- qdsOut << uiVictim;
- qdsOut << iChannel;
-}
-
-void MessageContextAction::restoreStream(PacketDataStream &qdsIn) {
- qdsIn >> qsAction;
- qdsIn >> uiVictim;
- qdsIn >> iChannel;
-}
-
-bool MessageContextAction::isValid() const {
- return (! qsAction.isEmpty());
-}
-
-PacketDataStream & operator<< (PacketDataStream & out, const MessageEditACL::GroupStruct &gs) {
- out << gs.qsName;
- out << gs.bInherited;
- out << gs.bInherit;
- out << gs.bInheritable;
- out << gs.qsAdd;
- out << gs.qsRemove;
- out << gs.qsInheritedMembers;
- return out;
-}
-
-PacketDataStream & operator>> (PacketDataStream & in, MessageEditACL::GroupStruct &gs) {
- in >> gs.qsName;
- in >> gs.bInherited;
- in >> gs.bInherit;
- in >> gs.bInheritable;
- in >> gs.qsAdd;
- in >> gs.qsRemove;
- in >> gs.qsInheritedMembers;
- return in;
-}
-
-PacketDataStream & operator<< (PacketDataStream & out, const MessageEditACL::ACLStruct &as) {
- out << as.bApplyHere;
- out << as.bApplySubs;
- out << as.bInherited;
- out << as.iPlayerId;
- out << as.qsGroup;
- out << static_cast<int>(as.pAllow);
- out << static_cast<int>(as.pDeny);
- return out;
-}
-
-PacketDataStream & operator>> (PacketDataStream & in, MessageEditACL::ACLStruct &as) {
- int v;
-
- in >> as.bApplyHere;
- in >> as.bApplySubs;
- in >> as.bInherited;
- in >> as.iPlayerId;
- in >> as.qsGroup;
- in >> v;
- as.pAllow = static_cast<ChanACL::Permissions>(v);
- in >> v;
- as.pDeny = static_cast<ChanACL::Permissions>(v);
- return in;
+ break;
+ }
}
diff --git a/src/Message.h b/src/Message.h
index 303cf59f8..7e02c366f 100644
--- a/src/Message.h
+++ b/src/Message.h
@@ -31,489 +31,45 @@
#ifndef _MESSAGE_H
#define _MESSAGE_H
-#define MESSAGE_STREAM_VERSION 4
-
-#include "ACL.h"
-
-class Connection;
-class PacketDataStream;
-
-class Message {
- protected:
- virtual void saveStream(PacketDataStream &) const;
- virtual void restoreStream(PacketDataStream &);
- public:
- enum MessageType { ServerReject, ServerAuthenticate, Speex, ServerSync, ServerJoin, ServerLeave, ServerBanList, PlayerMute, PlayerDeaf, PlayerKick, PlayerRename, PlayerBan, PlayerMove, PlayerSelfMuteDeaf, ChannelAdd, ChannelRemove, ChannelMove, ChannelLink, ChannelRename, PermissionDenied, EditACL, QueryUsers, Ping, TextMessage, PlayerTexture, CryptSetup, CryptSync, PingStats, ContextAction, ContextAddAction, ChannelDescUpdate };
- unsigned int uiSession;
-
- Message();
- virtual ~Message();
- virtual Message::MessageType messageType() const = 0;
- virtual bool isValid() const;
-
- void messageToNetwork(QByteArray &) const;
- void messageToNetwork(PacketDataStream &) const;
- static Message *networkToMessage(QByteArray &);
- static Message *networkToMessage(PacketDataStream &);
-};
-
-class MessageSpeex : public Message {
- protected:
- void saveStream(PacketDataStream &) const;
- void restoreStream(PacketDataStream &);
- public:
- enum { AltSpeak = 0x01, LoopBack = 0x02, EndSpeech = 0x04, FrameCountMask = 0x30 };
- unsigned int iSeq;
- // Flags is in first byte of packet.
- QByteArray qbaSpeexPacket;
- Message::MessageType messageType() const {
- return Speex;
- };
- bool isValid() const;
-};
-
-class MessageServerAuthenticate : public Message {
- protected:
- void saveStream(PacketDataStream &) const;
- void restoreStream(PacketDataStream &);
- public:
- int iVersion;
- QString qsUsername;
- QString qsPassword;
- MessageServerAuthenticate();
- Message::MessageType messageType() const {
- return ServerAuthenticate;
- };
-};
-
-class MessagePing : public Message {
- protected:
- void saveStream(PacketDataStream &) const;
- void restoreStream(PacketDataStream &);
- public:
- quint64 uiTimestamp;
- Message::MessageType messageType() const {
- return Ping;
- };
-};
-
-class MessagePingStats : public Message {
- protected:
- void saveStream(PacketDataStream &) const;
- void restoreStream(PacketDataStream &);
- public:
- quint64 uiTimestamp;
- quint32 uiGood;
- quint32 uiLate;
- quint32 uiLost;
- quint32 uiResync;
- double dUDPPingAvg;
- double dUDPPingVar;
- quint32 uiUDPPackets;
- double dTCPPingAvg;
- double dTCPPingVar;
- quint32 uiTCPPackets;
- Message::MessageType messageType() const {
- return PingStats;
- };
-};
-
-class MessageServerReject : public Message {
- protected:
- void saveStream(PacketDataStream &) const;
- void restoreStream(PacketDataStream &);
- public:
- enum RejectType { None, WrongVersion, InvalidUsername, WrongUserPW, WrongServerPW, UsernameInUse, ServerFull };
- QString qsReason;
- RejectType rtType;
- Message::MessageType messageType() const {
- return ServerReject;
- };
-};
-
-class MessageServerSync : public Message {
- protected:
- void saveStream(PacketDataStream &) const;
- void restoreStream(PacketDataStream &);
- public:
- int iMaxBandwidth;
- QString qsWelcomeText;
- Message::MessageType messageType() const {
- return ServerSync;
- };
-};
-
-class MessageServerJoin : public Message {
- protected:
- void saveStream(PacketDataStream &) const;
- void restoreStream(PacketDataStream &);
- public:
- QString qsPlayerName;
- int iId;
- Message::MessageType messageType() const {
- return ServerJoin;
- };
-};
-
-class MessageServerLeave : public Message {
- public:
- Message::MessageType messageType() const {
- return ServerLeave;
- };
-};
-
-class MessagePlayerMute : public Message {
- protected:
- void saveStream(PacketDataStream &) const;
- void restoreStream(PacketDataStream &);
- public:
- unsigned int uiVictim;
- bool bMute;
- Message::MessageType messageType() const {
- return PlayerMute;
- };
-};
-
-class MessagePlayerDeaf : public Message {
- protected:
- void saveStream(PacketDataStream &) const;
- void restoreStream(PacketDataStream &);
- public:
- unsigned int uiVictim;
- bool bDeaf;
- Message::MessageType messageType() const {
- return PlayerDeaf;
- };
-};
-
-class MessagePlayerSelfMuteDeaf : public Message {
- protected:
- void saveStream(PacketDataStream &) const;
- void restoreStream(PacketDataStream &);
- public:
- bool bMute;
- bool bDeaf;
- Message::MessageType messageType() const {
- return PlayerSelfMuteDeaf;
- };
-};
-
-class MessagePlayerKick : public Message {
- protected:
- void saveStream(PacketDataStream &) const;
- void restoreStream(PacketDataStream &);
- public:
- unsigned int uiVictim;
- QString qsReason;
- Message::MessageType messageType() const {
- return PlayerKick;
- };
-};
-
-class MessagePlayerBan : public Message {
- protected:
- void saveStream(PacketDataStream &) const;
- void restoreStream(PacketDataStream &);
- public:
- unsigned int uiVictim;
- QString qsReason;
- Message::MessageType messageType() const {
- return PlayerBan;
- };
-};
-
-class MessagePlayerMove : public Message {
- protected:
- void saveStream(PacketDataStream &) const;
- void restoreStream(PacketDataStream &);
- public:
- unsigned int uiVictim;
- int iChannelId;
- Message::MessageType messageType() const {
- return PlayerMove;
- };
-};
-
-class MessagePlayerRename : public Message {
- protected:
- void saveStream(PacketDataStream &) const;
- void restoreStream(PacketDataStream &);
- public:
- QString qsName;
- Message::MessageType messageType() const {
- return PlayerRename;
- };
-};
-
-class MessageChannelAdd : public Message {
- protected:
- void saveStream(PacketDataStream &) const;
- void restoreStream(PacketDataStream &);
- public:
- int iId;
- int iParent;
- QString qsName;
- Message::MessageType messageType() const {
- return ChannelAdd;
- };
-};
-
-class MessageChannelRemove : public Message {
- protected:
- void saveStream(PacketDataStream &) const;
- void restoreStream(PacketDataStream &);
- public:
- int iId;
- Message::MessageType messageType() const {
- return ChannelRemove;
- };
-};
-
-class MessageChannelMove : public Message {
- protected:
- void saveStream(PacketDataStream &) const;
- void restoreStream(PacketDataStream &);
- public:
- int iId;
- int iParent;
- Message::MessageType messageType() const {
- return ChannelMove;
- };
-};
-
-class MessageChannelLink : public Message {
- protected:
- void saveStream(PacketDataStream &) const;
- void restoreStream(PacketDataStream &);
- public:
- enum LinkType {
- Link, Unlink, UnlinkAll, PushLink, PushUnlink
- };
- int iId;
- LinkType ltType;
- QList<int> qlTargets;
- Message::MessageType messageType() const {
- return ChannelLink;
- };
-};
-
-class MessageChannelRename : public Message {
- protected:
- void saveStream(PacketDataStream &) const;
- void restoreStream(PacketDataStream &);
- public:
- int iId;
- QString qsName;
- Message::MessageType messageType() const {
- return ChannelRename;
- };
-};
-
-class MessageChannelDescUpdate : public Message {
- protected:
- void saveStream(PacketDataStream &) const;
- void restoreStream(PacketDataStream &);
- public:
- int iId;
- QString qsDesc;
- Message::MessageType messageType() const {
- return ChannelDescUpdate;
- };
-};
-
-class MessageServerBanList : public Message {
- protected:
- void saveStream(PacketDataStream &) const;
- void restoreStream(PacketDataStream &);
- public:
- bool bQuery;
- QList<QPair<quint32, int> > qlBans;
- Message::MessageType messageType() const {
- return ServerBanList;
- };
-};
-
-class MessageTextMessage : public Message {
- protected:
- void saveStream(PacketDataStream &) const;
- void restoreStream(PacketDataStream &);
- public:
- unsigned int uiVictim;
- int iChannel;
- bool bTree;
- QString qsMessage;
- Message::MessageType messageType() const {
- return TextMessage;
- };
-};
-
-class MessagePermissionDenied : public Message {
- protected:
- void saveStream(PacketDataStream &) const;
- void restoreStream(PacketDataStream &);
- public:
- QString qsReason;
- Message::MessageType messageType() const {
- return PermissionDenied;
- };
-};
-
-class MessageEditACL : public Message {
- protected:
- void saveStream(PacketDataStream &) const;
- void restoreStream(PacketDataStream &);
- public:
- struct GroupStruct {
- QString qsName;
- bool bInherited;
- bool bInherit;
- bool bInheritable;
- QSet<int> qsAdd;
- QSet<int> qsRemove;
- QSet<int> qsInheritedMembers;
- };
-
- struct ACLStruct {
- bool bApplyHere;
- bool bApplySubs;
- bool bInherited;
- int iPlayerId;
- QString qsGroup;
- ChanACL::Permissions pAllow;
- ChanACL::Permissions pDeny;
- };
-
- int iId;
- bool bQuery;
- bool bInheritACL;
- QList<GroupStruct> groups;
- QList<ACLStruct> acls;
- Message::MessageType messageType() const {
- return EditACL;
- };
-};
-
-PacketDataStream & operator<< (PacketDataStream & out, const MessageEditACL::GroupStruct &gs);
-PacketDataStream & operator>> (PacketDataStream & in, MessageEditACL::GroupStruct &gs);
-PacketDataStream & operator<< (PacketDataStream & out, const MessageEditACL::ACLStruct &gs);
-PacketDataStream & operator>> (PacketDataStream & in, MessageEditACL::ACLStruct &gs);
-
-class MessageQueryUsers : public Message {
- protected:
- void saveStream(PacketDataStream &) const;
- void restoreStream(PacketDataStream &);
- public:
- QList<int> qlIds;
- QList<QString> qlNames;
- Message::MessageType messageType() const {
- return QueryUsers;
- };
- bool isValid() const;
-};
-
-class MessageTexture : public Message {
- protected:
- void saveStream(PacketDataStream &) const;
- void restoreStream(PacketDataStream &);
- public:
- int iPlayerId;
- QByteArray qbaTexture;
- Message::MessageType messageType() const {
- return PlayerTexture;
- }
-};
-
-class MessageCryptSetup : public Message {
- protected:
- void saveStream(PacketDataStream &) const;
- void restoreStream(PacketDataStream &);
- public:
- QByteArray qbaKey, qbaClientNonce, qbaServerNonce;
- Message::MessageType messageType() const {
- return CryptSetup;
- }
- bool isValid() const;
-};
-
-class MessageCryptSync : public Message {
- protected:
- void saveStream(PacketDataStream &) const;
- void restoreStream(PacketDataStream &);
- public:
- QByteArray qbaNonce;
- Message::MessageType messageType() const {
- return CryptSync;
- }
- bool isValid() const;
-};
-
-class MessageContextAddAction : public Message {
- protected:
- void saveStream(PacketDataStream &) const;
- void restoreStream(PacketDataStream &);
- public:
- enum Context { CtxServer = 0x01, CtxChannel = 0x02, CtxPlayer = 0x04 };
- QString qsAction;
- QString qsText;
- Context ctx;
- Message::MessageType messageType() const {
- return ContextAddAction;
- }
- bool isValid() const;
-};
-
-class MessageContextAction : public Message {
- protected:
- void saveStream(PacketDataStream &) const;
- void restoreStream(PacketDataStream &);
- public:
- QString qsAction;
- unsigned int uiVictim;
- int iChannel;
- Message::MessageType messageType() const {
- return ContextAction;
- }
- bool isValid() const;
-};
+#include "Connection.h"
+#include "Mumble.pb.h"
class MessageHandler {
- protected:
- virtual void msgSpeex(Connection *, MessageSpeex *) = 0;
- virtual void msgServerAuthenticate(Connection *, MessageServerAuthenticate *) = 0;
- virtual void msgPing(Connection *, MessagePing *) = 0;
- virtual void msgPingStats(Connection *, MessagePingStats *) = 0;
- virtual void msgServerReject(Connection *, MessageServerReject *) = 0;
- virtual void msgServerSync(Connection *, MessageServerSync *) = 0;
- virtual void msgServerJoin(Connection *, MessageServerJoin *) = 0;
- virtual void msgServerLeave(Connection *, MessageServerLeave *) = 0;
- virtual void msgPlayerMute(Connection *, MessagePlayerMute *) = 0;
- virtual void msgPlayerDeaf(Connection *, MessagePlayerDeaf *) = 0;
- virtual void msgPlayerSelfMuteDeaf(Connection *, MessagePlayerSelfMuteDeaf *) = 0;
- virtual void msgPlayerKick(Connection *, MessagePlayerKick *) = 0;
- virtual void msgPlayerBan(Connection *, MessagePlayerBan *) = 0;
- virtual void msgPlayerMove(Connection *, MessagePlayerMove *) = 0;
- virtual void msgPlayerRename(Connection *, MessagePlayerRename *) = 0;
- virtual void msgChannelAdd(Connection *, MessageChannelAdd *) = 0;
- virtual void msgChannelRemove(Connection *, MessageChannelRemove *) = 0;
- virtual void msgChannelMove(Connection *, MessageChannelMove *) = 0;
- virtual void msgChannelLink(Connection *, MessageChannelLink *) = 0;
- virtual void msgChannelRename(Connection *, MessageChannelRename *) = 0;
- virtual void msgChannelDescUpdate(Connection *, MessageChannelDescUpdate *) = 0;
- virtual void msgServerBanList(Connection *, MessageServerBanList *) = 0;
- virtual void msgTextMessage(Connection *, MessageTextMessage *) = 0;
- virtual void msgPermissionDenied(Connection *, MessagePermissionDenied *) = 0;
- virtual void msgEditACL(Connection *, MessageEditACL *) = 0;
- virtual void msgQueryUsers(Connection *, MessageQueryUsers *) = 0;
- virtual void msgTexture(Connection *, MessageTexture *) = 0;
- virtual void msgCryptSetup(Connection *, MessageCryptSetup *) = 0;
- virtual void msgCryptSync(Connection *, MessageCryptSync *) = 0;
- virtual void msgContextAddAction(Connection *, MessageContextAddAction *) = 0;
- virtual void msgContextAction(Connection *, MessageContextAction *) = 0;
- void dispatch(Connection *, Message *);
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 };
+ 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 &);
virtual ~MessageHandler() { };
};
+inline QString u8(const ::std::string &str) {
+ return QString::fromUtf8(str.data(), str.length());
+}
+
+inline ::std::string u8(const QString &str) {
+ const QByteArray &qba = str.toUtf8();
+ return ::std::string(qba.constData(), qba.length());
+}
+
#else
class Message;
#endif
diff --git a/src/Mumble.proto b/src/Mumble.proto
index 62b6abf53..85f56ca80 100644
--- a/src/Mumble.proto
+++ b/src/Mumble.proto
@@ -12,23 +12,19 @@ message UDPTunnel {
}
message Authenticate {
- required string username = 1;
+ optional string username = 1;
optional string password = 2;
optional bool want_textures = 3 [default = true];
}
message Ping {
optional uint64 timestamp = 1;
-}
-
-message PingStats {
- optional uint64 timestamp = 1;
- required uint32 good = 2;
- required uint32 late = 3;
- required uint32 lost = 4;
- required uint32 resync = 5;
- required uint32 udp_packets = 6;
- required uint32 tcp_packets = 7;
+ optional uint32 good = 2;
+ optional uint32 late = 3;
+ optional uint32 lost = 4;
+ optional uint32 resync = 5;
+ optional uint32 udp_packets = 6;
+ optional uint32 tcp_packets = 7;
optional float udp_ping_avg = 8;
optional float udp_ping_var = 9;
optional float tcp_ping_avg = 10;
@@ -50,8 +46,9 @@ message Reject {
}
message ServerSync {
- optional uint32 maxbandwidth = 1;
- optional string welcometext = 2;
+ optional uint32 session = 1;
+ optional uint32 max_bandwidth = 2;
+ optional string welcome_text = 3;
}
message ChannelRemove {
@@ -64,10 +61,15 @@ message ChannelState {
optional string name = 3;
repeated uint32 links = 4;
optional string description = 5;
+ repeated uint32 links_add = 6;
+ repeated uint32 links_remove = 7;
}
message UserRemove {
required uint32 session = 1;
+ optional uint32 actor = 2;
+ optional string reason = 3;
+ optional bool ban = 4;
}
message UserState {
@@ -75,22 +77,15 @@ message UserState {
optional uint32 actor = 2;
optional string name = 3;
optional uint32 user_id = 4;
- optional uint32 channel = 5;
+ optional uint32 channel_id = 5;
optional bool mute = 6;
optional bool deaf = 7;
optional bool suppressed = 8;
- optional bool selfmute = 9;
- optional bool selfdeaf = 10;
+ optional bool self_mute = 9;
+ optional bool self_deaf = 10;
optional bytes texture = 11;
}
-message Kick {
- required uint32 session = 1;
- optional uint32 actor = 2;
- optional string reason = 3;
- optional bool ban = 4;
-}
-
message BanList {
message BanEntry {
required bytes address = 1;
@@ -101,10 +96,11 @@ message BanList {
}
message TextMessage {
- required uint32 actor = 1;
+ optional uint32 actor = 1;
repeated uint32 session = 2;
repeated uint32 channel_id = 3;
- required string message = 4;
+ repeated uint32 tree_id = 4;
+ required string message = 5;
}
message PermissionDenied {
@@ -128,8 +124,8 @@ message ACL {
optional bool inherited = 3 [default = true];
optional uint32 user_id = 4;
optional string group = 5;
- required uint32 grant = 6;
- required uint32 deny = 7;
+ optional uint32 grant = 6;
+ optional uint32 deny = 7;
}
required uint32 channel_id = 1;
optional bool inherit_acls = 2 [default = true];
@@ -145,7 +141,8 @@ message QueryUsers {
message CryptSetup {
optional bytes key = 1;
- optional bytes nonce = 2;
+ optional bytes client_nonce = 2;
+ optional bytes server_nonce = 3;
}
message ContextActionAdd {
diff --git a/src/PacketDataStream.h b/src/PacketDataStream.h
deleted file mode 100644
index 948cb03dd..000000000
--- a/src/PacketDataStream.h
+++ /dev/null
@@ -1,406 +0,0 @@
-/* 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/murmur/Messages.cpp b/src/murmur/Messages.cpp
index 44aafe0ab..41c81be8c 100644
--- a/src/murmur/Messages.cpp
+++ b/src/murmur/Messages.cpp
@@ -37,66 +37,66 @@
#include "Connection.h"
#include "Server.h"
#include "DBus.h"
-#include "PacketDataStream.h"
#define MSG_SETUP(st) \
User *uSource = static_cast<User *>(cCon); \
- MessagePermissionDenied mpd; \
- msg->uiSession = uSource->uiSession; \
if (uSource->sState != st) \
return
#define VICTIM_SETUP \
- User *pDstUser = qhUsers.value(msg->uiVictim); \
+ User *pDstUser = uSource; \
+ if (msg->has_session()) \
+ pDstUser = qhUsers.value(msg->session()); \
if (! pDstUser) \
return; \
Q_UNUSED(pDstUser)
#define PERM_DENIED(who, where, what) \
- mpd.qsReason = QString("%1 not allowed to %2 in %3").arg(who->qsName).arg(ChanACL::permName(what)).arg(where->qsName); \
- sendMessage(cCon, &mpd); \
- log(uSource, mpd.qsReason)
+ { \
+ MumbleProto::PermissionDenied mppd; \
+ QString reason = QString("%1 not allowed to %2 in %3").arg(who->qsName).arg(ChanACL::permName(what)).arg(where->qsName); \
+ mppd.set_reason(u8(reason)); \
+ sendMessage(uSource, mppd, MessageHandler::PermissionDenied); \
+ log(uSource, reason); \
+ }
#define PERM_DENIED_TEXT(text) \
- mpd.qsReason = text; \
- sendMessage(cCon, &mpd)
+ { \
+ MumbleProto::PermissionDenied mppd; \
+ mppd.set_reason(std::string(text)); \
+ sendMessage(uSource, mppd, MessageHandler::PermissionDenied); \
+ }
-void Server::msgServerAuthenticate(Connection *cCon, MessageServerAuthenticate *msg) {
+void Server::msgAuthenticate(Connection *cCon, MumbleProto::Authenticate *msg) {
MSG_SETUP(Player::Connected);
Channel *c;
- uSource->qsName = msg->qsUsername;
+ uSource->qsName = u8(msg->username());
- MessageServerReject msr;
bool ok = false;
- bool nameok = validatePlayerName(msg->qsUsername);
+ bool nameok = validatePlayerName(uSource->qsName);
+ QString pw = u8(msg->password());
// Fetch ID and stored username.
// Since this may call DBus, which may recall our dbus messages, this function needs
// to support re-entrancy, and also to support the fact that sessions may go away.
- int id = authenticate(msg->qsUsername, msg->qsPassword);
-
- // Did the session go away?
- Player *p = qhUsers.value(msg->uiSession);
- if (p != uSource)
- return;
+ int id = authenticate(uSource->qsName, pw);
uSource->iId = id >= 0 ? id : -1;
- uSource->qsName = msg->qsUsername;
-
- if (msg->iVersion != MESSAGE_STREAM_VERSION) {
- msr.qsReason = QString("Wrong version of mumble protocol (client: %1, server: %2)").arg(msg->iVersion).arg(MESSAGE_STREAM_VERSION);
- msr.rtType = MessageServerReject::WrongVersion;
- } else if (! nameok && (uSource->iId == -1)) {
- msr.qsReason = "Invalid Username";
- msr.rtType = MessageServerReject::InvalidUsername;
+
+ QString reason;
+ MumbleProto::Reject_RejectType rtType = MumbleProto::Reject_RejectType_None;
+
+ if (! nameok && (uSource->iId == -1)) {
+ reason = "Invalid Username";
+ rtType = MumbleProto::Reject_RejectType_InvalidUsername;
} else if (id==-1) {
- msr.qsReason = "Wrong password for user";
- msr.rtType = MessageServerReject::WrongUserPW;
- } else if (id==-2 && ! qsPassword.isEmpty() && qsPassword != msg->qsPassword) {
- msr.qsReason = "Invalid server password";
- msr.rtType = MessageServerReject::WrongServerPW;
+ reason = "Wrong password for user";
+ rtType = MumbleProto::Reject_RejectType_WrongUserPW;
+ } else if (id==-2 && ! qsPassword.isEmpty() && qsPassword != pw) {
+ reason = "Invalid server password";
+ rtType = MumbleProto::Reject_RejectType_WrongServerPW;
} else {
ok = true;
}
@@ -115,39 +115,42 @@ void Server::msgServerAuthenticate(Connection *cCon, MessageServerAuthenticate *
// Allow reuse of name from same IP
if (ok && uOld && (uSource->iId == -1)) {
if (uOld->peerAddress() != cCon->peerAddress()) {
- msr.qsReason = "Playername already in use";
- msr.rtType = MessageServerReject::UsernameInUse;
+ reason = "Playername already in use";
+ rtType = MumbleProto::Reject_RejectType_UsernameInUse;
ok = false;
}
}
if ((id != 0) && (qhUsers.count() > iMaxUsers)) {
- msr.qsReason = QString::fromLatin1("Server is full (max %1 users)").arg(iMaxUsers);
- msr.rtType = MessageServerReject::ServerFull;
+ reason = QString::fromLatin1("Server is full (max %1 users)").arg(iMaxUsers);
+ rtType = MumbleProto::Reject_RejectType_ServerFull;
ok = false;
}
if (! ok) {
- log(uSource, QString("Rejected connection: %1").arg(msr.qsReason));
- sendMessage(cCon, &msr);
- cCon->disconnectSocket();
+ log(uSource, QString("Rejected connection: %1").arg(reason));
+ MumbleProto::Reject mpr;
+ mpr.set_reason(u8(reason));
+ mpr.set_type(rtType);
+ sendMessage(uSource, mpr, MessageHandler::Reject);
+ cCon->disconnectSocket(true);
return;
}
// Kick ghost
if (uOld) {
log(uSource, "Disconnecting ghost");
- uOld->disconnectSocket();
+ uOld->disconnectSocket(true);
}
// Setup UDP encryption
uSource->csCrypt.genKey();
- MessageCryptSetup mcs;
- mcs.uiSession = uSource->uiSession;
- mcs.qbaKey = QByteArray(reinterpret_cast<const char *>(uSource->csCrypt.raw_key), AES_BLOCK_SIZE);
- mcs.qbaServerNonce = QByteArray(reinterpret_cast<const char *>(uSource->csCrypt.encrypt_iv), AES_BLOCK_SIZE);
- mcs.qbaClientNonce = QByteArray(reinterpret_cast<const char *>(uSource->csCrypt.decrypt_iv), AES_BLOCK_SIZE);
- sendMessage(cCon, &mcs);
+
+ MumbleProto::CryptSetup mpcrypt;
+ mpcrypt.set_key(std::string(reinterpret_cast<const char *>(uSource->csCrypt.raw_key), AES_BLOCK_SIZE));
+ mpcrypt.set_server_nonce(std::string(reinterpret_cast<const char *>(uSource->csCrypt.encrypt_iv), AES_BLOCK_SIZE));
+ mpcrypt.set_client_nonce(std::string(reinterpret_cast<const char *>(uSource->csCrypt.decrypt_iv), AES_BLOCK_SIZE));
+ sendMessage(uSource, mpcrypt, MessageHandler::CryptSetup);
int lchan = readLastChannel(uSource->iId);
if (lchan == 0)
@@ -163,27 +166,24 @@ void Server::msgServerAuthenticate(Connection *cCon, MessageServerAuthenticate *
QQueue<Channel *> q;
QSet<Channel *> chans;
q << qhChannels.value(0);
+ MumbleProto::ChannelState mpcs;
while (! q.isEmpty()) {
c = q.dequeue();
-
chans.insert(c);
- MessageChannelAdd mca;
- mca.uiSession = 0;
- mca.iId = c->iId;
- mca.iParent = (c->cParent) ? c->cParent->iId : -1;
- mca.qsName = c->qsName;
- if (c->iId == 0)
- mca.qsName = qsRegName.isEmpty() ? QLatin1String("Root") : qsRegName;
+ mpcs.Clear();
- sendMessage(cCon, &mca);
-
- MessageChannelDescUpdate mcdu;
-
- mcdu.iId = c->iId;
- mcdu.qsDesc = c->qsDesc;
+ mpcs.set_channel_id(c->iId);
+ if (c->cParent)
+ mpcs.set_parent(c->cParent->iId);
+ if (c->iId == 0)
+ mpcs.set_name(u8(qsRegName.isEmpty() ? QLatin1String("Root") : qsRegName));
+ else
+ mpcs.set_name(u8(c->qsName));
+ if (! c->qsDesc.isEmpty())
+ mpcs.set_description(u8(c->qsDesc));
- sendMessage(static_cast<User *>(p), &mcdu);
+ sendMessage(uSource, mpcs, MessageHandler::ChannelState);
foreach(c, c->qlChannels)
q.enqueue(c);
@@ -191,513 +191,472 @@ void Server::msgServerAuthenticate(Connection *cCon, MessageServerAuthenticate *
foreach(c, chans) {
if (c->qhLinks.count() > 0) {
- MessageChannelLink mcl;
- mcl.iId = c->iId;
- mcl.ltType = MessageChannelLink::Link;
+ mpcs.Clear();
+ mpcs.set_channel_id(c->iId);
+
foreach(Channel *l, c->qhLinks.keys())
- mcl.qlTargets << l->iId;
- sendMessage(cCon, &mcl);
+ mpcs.add_links(l->iId);
+ sendMessage(uSource, mpcs, MessageHandler::ChannelState);
}
}
- MessageServerJoin msjMsg;
- MessagePlayerMove mpm;
+ MumbleProto::UserState mpus;
uSource->sState = Player::Authenticated;
- msjMsg.uiSession = uSource->uiSession;
- msjMsg.iId = uSource->iId;
- msjMsg.qsPlayerName = uSource->qsName;
- sendExcept(&msjMsg, cCon);
+ mpus.set_session(uSource->uiSession);
+ mpus.set_name(u8(uSource->qsName));
+ if (uSource->iId >= 0)
+ mpus.set_user_id(uSource->iId);
+ if (uSource->cChannel->iId != 0)
+ mpus.set_channel_id(uSource->cChannel->iId);
- mpm.uiSession = 0;
- mpm.uiVictim = uSource->uiSession;
- mpm.iChannelId = uSource->cChannel->iId;
- if (mpm.iChannelId != 0)
- sendExcept(&mpm, cCon);
+ sendExcept(uSource, mpus, MessageHandler::UserState);
foreach(User *u, qhUsers) {
if (u->sState != Player::Authenticated)
continue;
- msjMsg.uiSession = u->uiSession;
- msjMsg.iId = u->iId;
- msjMsg.qsPlayerName = u->qsName;
- sendMessage(cCon, &msjMsg);
-
- if (u->bDeaf) {
- MessagePlayerDeaf mpdMsg;
- mpdMsg.uiSession = 0;
- mpdMsg.uiVictim = u->uiSession;
- mpdMsg.bDeaf = true;
- sendMessage(cCon, &mpdMsg);
- } else if (u->bMute || u->bSuppressed) {
- MessagePlayerMute mpmMsg;
- mpmMsg.uiSession = 0;
- mpmMsg.uiVictim = u->uiSession;
- mpmMsg.bMute = true;
- sendMessage(cCon, &mpmMsg);
- }
- if (u->bSelfDeaf || u->bSelfMute) {
- MessagePlayerSelfMuteDeaf mpsmdMsg;
- mpsmdMsg.uiSession = u->uiSession;
- mpsmdMsg.bDeaf = u->bSelfDeaf;
- mpsmdMsg.bMute = u->bSelfMute;
- sendMessage(cCon, &mpsmdMsg);
- }
-
- mpm.uiSession = 0;
- mpm.uiVictim = u->uiSession;
- mpm.iChannelId = u->cChannel->iId;
- sendMessage(cCon, &mpm);
- }
-
- MessageServerSync mssMsg;
- mssMsg.uiSession = uSource->uiSession;
- mssMsg.qsWelcomeText = qsWelcomeText;
- mssMsg.iMaxBandwidth = iMaxBandwidth;
- sendMessage(cCon, &mssMsg);
+
+ mpus.Clear();
+ mpus.set_session(u->uiSession);
+ mpus.set_name(u8(u->qsName));
+ if (u->iId >= 0)
+ mpus.set_user_id(u->iId);
+ if (u->cChannel->iId != 0)
+ mpus.set_channel_id(u->cChannel->iId);
+ if (u->bDeaf)
+ mpus.set_deaf(true);
+ else if (u->bMute)
+ mpus.set_mute(true);
+ if (u->bSuppressed)
+ mpus.set_suppressed(true);
+ if (u->bSelfDeaf)
+ mpus.set_self_deaf(true);
+ else if (u->bSelfMute)
+ mpus.set_self_mute(true);
+
+ if (! qhUserTextureCache.contains(u->iId)) {
+ QByteArray qba = getUserTexture(u->iId);
+ qhUserTextureCache.insert(u->iId, qba);
+ }
+ QByteArray texture = qhUserTextureCache.value(u->iId);
+ if (! texture.isEmpty())
+ mpus.set_texture(std::string(texture.constData(), texture.size()));
+
+ sendMessage(uSource, mpus, MessageHandler::UserState);
+ }
+
+ MumbleProto::ServerSync mpss;
+ mpss.set_session(uSource->uiSession);
+ if (! qsWelcomeText.isEmpty())
+ mpss.set_welcome_text(u8(qsWelcomeText));
+ mpss.set_max_bandwidth(iMaxBandwidth);
+
+ sendMessage(uSource, mpss, MessageHandler::ServerSync);
log(uSource, "Authenticated");
emit playerConnected(uSource);
playerEnterChannel(uSource, lc, false);
-
- while (lc && lc->qsDesc.isEmpty())
- lc = lc->cParent;
- if (lc)
- sendChannelDescription(uSource, lc);
}
-void Server::msgServerBanList(Connection *cCon, MessageServerBanList *msg) {
+void Server::msgBanList(Connection *cCon, MumbleProto::BanList *msg) {
MSG_SETUP(Player::Authenticated);
+ typedef QPair<quint32, int> ban;
if (! hasPermission(uSource, qhChannels.value(0), ChanACL::Write)) {
PERM_DENIED(uSource, qhChannels.value(0), ChanACL::Write);
return;
}
- if (msg->bQuery) {
- MessageServerBanList msbl;
- msbl.uiSession = 0;
- msbl.bQuery = false;
- msbl.qlBans = qlBans;
- sendMessage(cCon, &msbl);
+ if (msg->query()) {
+ msg->clear_query();
+ msg->clear_bans();
+ 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);
+ }
+ sendMessage(uSource, *msg, MessageHandler::BanList);
} else {
- qlBans = msg->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());
+ }
+ }
saveBans();
log(uSource, "Updated banlist");
}
}
-void Server::msgServerLeave(Connection *cCon, MessageServerLeave *) {
- cCon->disconnectSocket();
-}
-
-void Server::msgServerJoin(Connection *cCon, MessageServerJoin *) {
- cCon->disconnectSocket();
+void Server::msgReject(Connection *, MumbleProto::Reject *) {
}
-void Server::msgServerReject(Connection *cCon, MessageServerReject *) {
- cCon->disconnectSocket();
+void Server::msgServerSync(Connection *, MumbleProto::ServerSync *) {
}
-void Server::msgServerSync(Connection *cCon, MessageServerSync *) {
- cCon->disconnectSocket();
+void Server::msgPermissionDenied(Connection *, MumbleProto::PermissionDenied *) {
}
-void Server::msgPermissionDenied(Connection *cCon, MessagePermissionDenied *) {
- cCon->disconnectSocket();
-}
-
-void Server::msgPlayerRename(Connection *cCon, MessagePlayerRename *) {
- cCon->disconnectSocket();
-}
-
-void Server::msgCryptSetup(Connection *cCon, MessageCryptSetup *) {
- cCon->disconnectSocket();
-}
-
-void Server::msgSpeex(Connection *cCon, MessageSpeex *msg) {
+void Server::msgUDPTunnel(Connection *cCon, MumbleProto::UDPTunnel *msg) {
MSG_SETUP(Player::Authenticated);
- fakeUdpPacket(msg, cCon);
+
+ const std::string &str = msg->packet();
+ int len = str.length();
+ if (len < 1)
+ return;
+ QReadLocker rl(&qrwlUsers);
+ processMsg(uSource, str.data(), len);
}
-void Server::msgPlayerMute(Connection *cCon, MessagePlayerMute *msg) {
+void Server::msgUserState(Connection *cCon, MumbleProto::UserState *msg) {
MSG_SETUP(Player::Authenticated);
VICTIM_SETUP;
- if ((pDstUser->iId ==0) || ! hasPermission(uSource, pDstUser->cChannel, ChanACL::MuteDeafen)) {
- PERM_DENIED(uSource, pDstUser->cChannel, ChanACL::MuteDeafen);
+ if (pDstUser->iId == 0) {
+ PERM_DENIED_TEXT("Can't modify SuperUser");
return;
}
- if (! msg->bMute && pDstUser->bSuppressed) {
- pDstUser->bSuppressed = false;
- } else if (pDstUser->bMute == msg->bMute) {
- return;
- }
+ msg->set_session(pDstUser->uiSession);
+ msg->set_actor(uSource->uiSession);
- pDstUser->bMute = msg->bMute;
- sendAll(msg);
-
- if (! msg->bMute && pDstUser->bDeaf) {
- pDstUser->bDeaf = false;
- }
+ if (msg->has_channel_id()) {
+ Channel *c = qhChannels.value(msg->channel_id());
+ if (!c || (c == pDstUser->cChannel))
+ return;
- log(uSource, QString("Muted %1 (%2)").arg(*pDstUser).arg(msg->bMute));
- emit playerStateChanged(pDstUser);
-}
+ if ((uSource != pDstUser) && (! hasPermission(uSource, pDstUser->cChannel, ChanACL::MoveKick))) {
+ PERM_DENIED(uSource, pDstUser->cChannel, ChanACL::MoveKick);
+ return;
+ }
-void Server::msgPlayerDeaf(Connection *cCon, MessagePlayerDeaf *msg) {
- MSG_SETUP(Player::Authenticated);
- VICTIM_SETUP;
+ if (! hasPermission(uSource, c, ChanACL::MoveKick) && ! hasPermission(pDstUser, c, ChanACL::Enter)) {
+ PERM_DENIED(pDstUser, c, ChanACL::Enter);
+ return;
+ }
+ }
- if ((pDstUser->iId ==0) || ! hasPermission(uSource, pDstUser->cChannel, ChanACL::MuteDeafen)) {
- PERM_DENIED(uSource, pDstUser->cChannel, ChanACL::MuteDeafen);
- return;
+ if (msg->has_mute() || msg->has_deaf() || msg->has_suppressed()) {
+ if (! hasPermission(uSource, pDstUser->cChannel, ChanACL::MuteDeafen) || msg->suppressed()) {
+ PERM_DENIED(uSource, pDstUser->cChannel, ChanACL::MuteDeafen);
+ return;
+ }
}
- if (pDstUser->bDeaf == msg->bDeaf)
+ if ((pDstUser != uSource) && (msg->has_self_deaf() || msg->has_self_mute() || msg->has_texture()))
return;
- pDstUser->bDeaf = msg->bDeaf;
- sendAll(msg);
+ // Permission checks done. Now enact this.
- if (msg->bDeaf && ! pDstUser->bMute) {
- pDstUser->bMute = true;
+ if (msg->has_self_deaf()) {
+ uSource->bSelfDeaf = msg->self_deaf();
+ if (uSource->bSelfDeaf)
+ msg->set_self_mute(true);
}
- log(uSource, QString("Deafened %1 (%2)").arg(*pDstUser).arg(msg->bDeaf));
-
- emit playerStateChanged(pDstUser);
-}
-
-void Server::msgPlayerKick(Connection *cCon, MessagePlayerKick *msg) {
- MSG_SETUP(Player::Authenticated);
- VICTIM_SETUP;
-
- if ((pDstUser->iId ==0) || ! hasPermission(uSource, pDstUser->cChannel, ChanACL::MoveKick)) {
- PERM_DENIED(uSource, pDstUser->cChannel, ChanACL::MoveKick);
- return;
+ if (msg->has_self_mute()) {
+ uSource->bSelfMute = msg->self_mute();
+ if (! uSource->bSelfMute) {
+ msg->set_self_deaf(false);
+ uSource->bSelfDeaf = false;
+ }
}
- sendAll(msg);
- log(uSource, QString("Kicked %1 (%2)").arg(*pDstUser).arg(msg->qsReason));
- pDstUser->disconnectSocket();
-}
-void Server::msgPlayerBan(Connection *cCon, MessagePlayerBan *msg) {
- MSG_SETUP(Player::Authenticated);
- VICTIM_SETUP;
+ if (msg->has_channel_id()) {
+ Channel *c = qhChannels.value(msg->channel_id());
- if ((pDstUser->iId ==0) || ! hasPermission(uSource, qhChannels.value(0), ChanACL::MoveKick)) {
- PERM_DENIED(uSource, qhChannels.value(0), ChanACL::MoveKick);
- return;
+ playerEnterChannel(pDstUser, c);
+ log(uSource, QString("Moved %1 to %2").arg(*pDstUser).arg(*c));
}
- sendAll(msg);
- log(uSource, QString("Kickbanned %1 (%2)").arg(*pDstUser).arg(msg->qsReason));
-
- QHostAddress adr = pDstUser->peerAddress();
- quint32 base = adr.toIPv4Address();
- qlBans << QPair<quint32,int>(base, 32);
- saveBans();
- pDstUser->disconnectSocket();
-}
+ if (msg->has_mute() || msg->has_deaf() || msg->has_suppressed()) {
+ if (msg->has_deaf()) {
+ pDstUser->bDeaf = msg->deaf();
+ if (pDstUser->bDeaf)
+ msg->set_mute(true);
+ }
+ if (msg->has_mute()) {
+ pDstUser->bMute = msg->mute();
+ if (! pDstUser->bMute) {
+ msg->set_deaf(false);
+ pDstUser->bDeaf = false;
+ }
+ }
+ if (msg->has_suppressed())
+ pDstUser->bSuppressed = msg->suppressed();
-void Server::msgPlayerSelfMuteDeaf(Connection *cCon, MessagePlayerSelfMuteDeaf *msg) {
- MSG_SETUP(Player::Authenticated);
+ log(uSource, QString("Changed speak-state of %1 (%2 %3 %4)").arg(*pDstUser).arg(pDstUser->bMute).arg(pDstUser->bDeaf).arg(pDstUser->bSuppressed));
+ }
- uSource->bSelfMute = msg->bMute;
- uSource->bSelfDeaf = msg->bDeaf;
- sendAll(msg);
+ sendAll(*msg, MessageHandler::UserState);
- emit playerStateChanged(uSource);
+ emit playerStateChanged(pDstUser);
}
-void Server::msgPlayerMove(Connection *cCon, MessagePlayerMove *msg) {
+void Server::msgUserRemove(Connection *cCon, MumbleProto::UserRemove *msg) {
MSG_SETUP(Player::Authenticated);
VICTIM_SETUP;
+
+ msg->set_actor(uSource->uiSession);
- Channel *c = qhChannels.value(msg->iChannelId);
- if (!c || (c == pDstUser->cChannel))
- return;
+ bool ban = msg->has_ban() && msg->ban();
+
+ Channel *c = ban ? qhChannels.value(0) : pDstUser->cChannel;
- if ((uSource != pDstUser) && ((pDstUser->iId ==0) || ! hasPermission(uSource, pDstUser->cChannel, ChanACL::MoveKick))) {
- PERM_DENIED(uSource, pDstUser->cChannel, ChanACL::MoveKick);
+ if ((pDstUser->iId ==0) || ! hasPermission(uSource, c, ChanACL::MoveKick)) {
+ PERM_DENIED(uSource, c, ChanACL::MoveKick);
return;
}
- if (! hasPermission(uSource, c, ChanACL::MoveKick) && ! hasPermission(pDstUser, c, ChanACL::Enter)) {
- PERM_DENIED(pDstUser, c, ChanACL::Enter);
- return;
+ if (ban) {
+ QHostAddress adr = pDstUser->peerAddress();
+ quint32 base = adr.toIPv4Address();
+ qlBans << QPair<quint32,int>(base, 32);
+ saveBans();
}
- sendAll(msg);
- playerEnterChannel(pDstUser, c);
- log(uSource, QString("Moved %1 to %2").arg(*pDstUser).arg(*c));
+ sendAll(*msg, MessageHandler::UserRemove);
+ if (ban)
+ log(uSource, QString("Kickbanned %1 (%2)").arg(*pDstUser).arg(u8(msg->reason())));
+ else
+ log(uSource, QString("Kicked %1 (%2)").arg(*pDstUser).arg(u8(msg->reason())));
+ pDstUser->disconnectSocket();
}
-void Server::msgChannelAdd(Connection *cCon, MessageChannelAdd *msg) {
+void Server::msgChannelState(Connection *cCon, MumbleProto::ChannelState *msg) {
MSG_SETUP(Player::Authenticated);
- Channel *p = qhChannels.value(msg->iParent);
- if (!p)
- return;
+ Channel *c = NULL;
+ Channel *p = NULL;
- if (! hasPermission(uSource, p, ChanACL::MakeChannel)) {
- PERM_DENIED(uSource, p, ChanACL::MakeChannel);
- return;
+ if (msg->has_channel_id()) {
+ c = qhChannels.value(msg->channel_id());
+ if (! c)
+ return;
}
- if (! validateChannelName(msg->qsName)) {
- PERM_DENIED_TEXT("Illegal channel name");
+ if (msg->has_parent()) {
+ p = qhChannels.value(msg->parent());
+ if (! p);
return;
}
- QRegExp re2("\\w");
- if (re2.indexIn(msg->qsName) == -1) {
- PERM_DENIED_TEXT("Must have alphanumeric in name");
- return;
- }
+ msg->clear_links();
- foreach(Channel *sibling, p->qlChannels) {
- if (sibling->qsName == msg->qsName) {
- PERM_DENIED_TEXT("Duplicate channel name");
+ QString qsName;
+ QString qsDesc;
+ if (msg->has_description())
+ qsDesc = u8(msg->description());
+ if (msg->has_name()) {
+ qsName = u8(msg->name());
+
+ if (! validateChannelName(qsName)) {
+ PERM_DENIED_TEXT("Illegal channel name");
return;
}
- }
-
- Channel *c = addChannel(p, msg->qsName, QString());
- if (uSource->iId >= 0) {
- Group *g = new Group(c, "admin");
- g->qsAdd << uSource->iId;
- }
- updateChannel(c);
-
- msg->iId = c->iId;
- sendAll(msg);
- log(uSource, QString("Added channel %1 under %2").arg(*c).arg(*p));
-
- emit channelCreated(c);
-}
-
-void Server::msgChannelRemove(Connection *cCon, MessageChannelRemove *msg) {
- MSG_SETUP(Player::Authenticated);
- Channel *c = qhChannels.value(msg->iId);
- if (!c)
- return;
+ QRegExp re2("\\w");
+ if (re2.indexIn(qsName) == -1) {
+ PERM_DENIED_TEXT("Must have alphanumeric in name");
+ return;
+ }
- if (! hasPermission(uSource, c, ChanACL::Write) || (c->iId == 0)) {
- PERM_DENIED(uSource, c, ChanACL::Write);
- return;
+ if (p || c) {
+ Channel *cp = p ? p : c->cParent;
+ foreach(Channel *sibling, cp->qlChannels) {
+ if (sibling->qsName == qsName) {
+ PERM_DENIED_TEXT("Duplicate channel name");
+ return;
+ }
+ }
+ }
}
- log(uSource, QString("Removed channel %1").arg(*c));
+ if (! c) {
+ if (! p || qsName.isNull())
+ return;
+ if (! hasPermission(uSource, p, ChanACL::MakeChannel)) {
+ PERM_DENIED(uSource, p, ChanACL::MakeChannel);
+ return;
+ }
- removeChannel(c, uSource);
-}
+ c = addChannel(p, qsName, qsDesc);
+ if (uSource->iId >= 0) {
+ Group *g = new Group(c, "admin");
+ g->qsAdd << uSource->iId;
+ }
+ updateChannel(c);
-void Server::msgChannelRename(Connection *cCon, MessageChannelRename *msg) {
- MSG_SETUP(Player::Authenticated);
- Channel *c = qhChannels.value(msg->iId);
+ msg->set_channel_id(c->iId);
+ log(uSource, QString("Added channel %1 under %2").arg(*c).arg(*p));
+ emit channelCreated(c);
+ } else {
+ if (! qsName.isNull()) {
+ if (! hasPermission(uSource, c, ChanACL::Write) || (c->iId == 0)) {
+ PERM_DENIED(uSource, c, ChanACL::Write);
+ return;
+ }
+ }
+ if (! qsDesc.isNull()) {
+ if (! hasPermission(uSource, c, ChanACL::Write)) {
+ PERM_DENIED(uSource, c, ChanACL::Write);
+ return;
+ }
+ }
+ if (p) {
+ if (p == c->cParent)
+ return;
- if (!c)
- return;
+ Channel *ip = p;
+ while (ip) {
+ if (ip == c)
+ return;
+ ip = ip->cParent;
+ }
- if (! hasPermission(uSource, c, ChanACL::Write) || (c->iId == 0)) {
- PERM_DENIED(uSource, c, ChanACL::Write);
- return;
- }
+ if (! hasPermission(uSource, c, ChanACL::Write)) {
+ PERM_DENIED(uSource, c, ChanACL::Write);
+ return;
+ }
- if (! validateChannelName(msg->qsName)) {
- PERM_DENIED_TEXT("Illegal channel name");
- return;
- }
+ if (! hasPermission(uSource, p, ChanACL::MakeChannel)) {
+ PERM_DENIED(uSource, p, ChanACL::MakeChannel);
+ return;
+ }
- QRegExp re2("\\w");
- if (re2.indexIn(msg->qsName) == -1) {
- PERM_DENIED_TEXT("Must have alphanumeric in name");
- return;
- }
+ QString name = qsName.isNull() ? c->qsName : qsName;
- foreach(Channel *sibling, c->cParent->qlChannels) {
- if (sibling->qsName == msg->qsName) {
- PERM_DENIED_TEXT("Duplicate channel name");
- return;
+ foreach(Channel *sibling, p->qlChannels) {
+ if (sibling->qsName == name) {
+ PERM_DENIED_TEXT("Duplicate channel name");
+ return;
+ }
+ }
+ }
+ QList<Channel *> qlAdd;
+ QList<Channel *> qlRemove;
+
+ if (msg->links_add_size() || msg->links_remove_size()) {
+ if (! hasPermission(uSource, c, ChanACL::LinkChannel)) {
+ PERM_DENIED(uSource, c, ChanACL::LinkChannel);
+ return;
+ }
+ if (msg->links_remove_size()) {
+ for(int i=0;i < msg->links_remove_size(); ++i) {
+ unsigned int link = msg->links_remove(i);
+ Channel *l = qhChannels.value(link);
+ if (! l)
+ return;
+ qlRemove << l;
+ }
+ }
+ if (msg->links_add_size()) {
+ for(int i=0;i < msg->links_add_size(); ++i) {
+ unsigned int link = msg->links_add(i);
+ Channel *l = qhChannels.value(link);
+ if (! l)
+ return;
+ if (! hasPermission(uSource, l, ChanACL::LinkChannel)) {
+ PERM_DENIED(uSource, l, ChanACL::LinkChannel);
+ return;
+ }
+ qlAdd << l;
+ }
+ }
}
- }
- log(uSource, QString("Renamed channel %1 to %2").arg(*c).arg(msg->qsName));
- c->qsName = msg->qsName;
- updateChannel(c);
- sendAll(msg);
+ // All permission checks done -- the update is good.
- emit channelStateChanged(c);
-}
+ if (p) {
+ log(uSource, QString("Moved channel %1 from %2 to %3").arg(*c).arg(* c->cParent).arg(*p));
-void Server::msgChannelDescUpdate(Connection *cCon, MessageChannelDescUpdate *msg) {
- MSG_SETUP(Player::Authenticated);
- Channel *c = qhChannels.value(msg->iId);
+ c->cParent->removeChannel(c);
+ p->addChannel(c);
+ }
+ if (! qsName.isNull()) {
+ log(uSource, QString("Renamed channel %1 to %2").arg(*c).arg(qsName));
+ c->qsName = qsName;
+ }
+ if (! qsDesc.isNull())
+ c->qsDesc = qsDesc;
- if (!c)
- return;
+ foreach(Channel *l, qlAdd) {
+ c->link(l);
+ addLink(c, l);
+ }
+ foreach(Channel *l, qlRemove) {
+ c->unlink(l);
+ removeLink(c, l);
+ }
- if (! hasPermission(uSource, c, ChanACL::Write)) {
- PERM_DENIED(uSource, c, ChanACL::Write);
- return;
+ updateChannel(c);
+ emit channelStateChanged(c);
}
- log(uSource, QString("Changed description for channel %1 to: %2").arg(*c).arg(msg->qsDesc));
- c->qsDesc = msg->qsDesc;
- updateChannel(c);
- sendAll(msg);
- sendChannelDescriptionUpdate(c);
+ sendAll(*msg, MessageHandler::ChannelState);
}
-void Server::msgChannelMove(Connection *cCon, MessageChannelMove *msg) {
+void Server::msgChannelRemove(Connection *cCon, MumbleProto::ChannelRemove *msg) {
MSG_SETUP(Player::Authenticated);
- Channel *c = qhChannels.value(msg->iId);
- Channel *np = qhChannels.value(msg->iParent);
- if (!c || ! np)
- return;
-
- if (np == c->cParent)
+ Channel *c = qhChannels.value(msg->channel_id());
+ if (!c)
return;
- if (! hasPermission(uSource, c, ChanACL::Write)) {
+ if (! hasPermission(uSource, c, ChanACL::Write) || (c->iId == 0)) {
PERM_DENIED(uSource, c, ChanACL::Write);
return;
}
- if (! hasPermission(uSource, np, ChanACL::MakeChannel)) {
- PERM_DENIED(uSource, np, ChanACL::MakeChannel);
- return;
- }
-
- foreach(Channel *sibling, np->qlChannels) {
- if (sibling->qsName == c->qsName) {
- PERM_DENIED_TEXT("Duplicate channel name");
- return;
- }
- }
-
- // Can't move to a subchannel of itself
- Channel *p = np;
- while (p) {
- if (p == c)
- return;
- p = p->cParent;
- }
-
- log(uSource, QString("Moved channel %1 from %2 to %3").arg(*c).arg(* c->cParent).arg(*np));
-
- c->cParent->removeChannel(c);
- np->addChannel(c);
- updateChannel(c);
- sendAll(msg);
+ log(uSource, QString("Removed channel %1").arg(*c));
- emit channelStateChanged(c);
+ removeChannel(c, uSource);
}
-void Server::msgChannelLink(Connection *cCon, MessageChannelLink *msg) {
+void Server::msgTextMessage(Connection *cCon, MumbleProto::TextMessage *msg) {
MSG_SETUP(Player::Authenticated);
+ QMutexLocker qml(&qmCache);
- Channel *c = qhChannels.value(msg->iId);
- if (!c)
- return;
-
- if (! hasPermission(uSource, c, ChanACL::LinkChannel)) {
- PERM_DENIED(uSource, c, ChanACL::LinkChannel);
- return;
- }
+ QSet<User *> users;
+ QQueue<Channel *> q;
- Channel *l = (msg->qlTargets.count() == 1) ? qhChannels.value(msg->qlTargets[0]) : NULL;
+ msg->set_actor(uSource->uiSession);
- QSet<Channel *> oldset = c->qhLinks.keys().toSet();
+ for(int i=0;i<msg->channel_id_size(); ++i) {
+ unsigned int id = msg->channel_id(i);
- switch (msg->ltType) {
- case MessageChannelLink::Link:
- if (!l)
- return;
- if (! hasPermission(uSource, l, ChanACL::LinkChannel)) {
- PERM_DENIED(uSource, l, ChanACL::LinkChannel);
- return;
- }
- c->link(l);
- addLink(c, l);
- log(uSource, QString("Linked channel %1 to %2").arg(*c).arg(*l));
- emit channelStateChanged(c);
- break;
- case MessageChannelLink::Unlink:
- if (!l)
- return;
- c->unlink(l);
- removeLink(c, l);
- log(uSource, QString("Unlinked channel %1 to %2").arg(*c).arg(*l));
- emit channelStateChanged(c);
- break;
- case MessageChannelLink::UnlinkAll:
- if (msg->qlTargets.count() > 0)
- return;
- c->unlink(NULL);
- removeLink(c, NULL);
- log(uSource, QString("Unlinked all from channel %1").arg(*c));
- sendAll(msg);
- emit channelStateChanged(c);
+ Channel *c = qhChannels.value(id);
+ if (! c)
return;
- case MessageChannelLink::PushLink:
- if (msg->qlTargets.count() <= 0)
- return;
- foreach(int tid, msg->qlTargets) {
- l=qhChannels.value(tid);
- if (l && hasPermission(uSource, l, ChanACL::LinkChannel))
- c->playerLink(l, uSource);
- }
- break;
- case MessageChannelLink::PushUnlink:
- if (msg->qlTargets.count() <= 0)
- return;
- foreach(int tid, msg->qlTargets) {
- l=qhChannels.value(tid);
- if (l)
- c->playerUnlink(l, uSource);
- }
- break;
- default:
- if (msg->qlTargets.count() <= 0)
- return;
- }
-
- QSet<Channel *> newset = c->qhLinks.keys().toSet();
- QSet<Channel *> changed;
- if (newset.count() == oldset.count())
- return;
-
- MessageChannelLink mcl;
- mcl.iId = msg->iId;
- mcl.uiSession=msg->uiSession;
+ if (! ChanACL::hasPermission(uSource, c, ChanACL::Speak | ChanACL::AltSpeak, acCache)) {
+ PERM_DENIED(uSource, c, ChanACL::Speak);
+ return;
+ }
- if (newset.count() > oldset.count()) {
- mcl.ltType = MessageChannelLink::Link;
- changed = newset - oldset;
- } else {
- mcl.ltType = MessageChannelLink::Unlink;
- changed = oldset - newset;
+ foreach(Player *p, c->qlPlayers)
+ users.insert(static_cast<User *>(p));
}
- foreach(l, changed)
- mcl.qlTargets << l->iId;
- sendAll(&mcl);
-}
+
+ for(int i=0;i<msg->tree_id_size(); ++i) {
+ unsigned int id = msg->tree_id(i);
-void Server::msgTextMessage(Connection *cCon, MessageTextMessage *msg) {
- MSG_SETUP(Player::Authenticated);
- QMutexLocker qml(&qmCache);
-
- if (msg->iChannel != -1) {
- Channel *c = qhChannels.value(msg->iChannel);
- if (!c)
+ Channel *c = qhChannels.value(id);
+ if (! c)
return;
if (! ChanACL::hasPermission(uSource, c, ChanACL::Speak | ChanACL::AltSpeak, acCache)) {
@@ -705,42 +664,37 @@ void Server::msgTextMessage(Connection *cCon, MessageTextMessage *msg) {
return;
}
- QSet<Channel *> chans;
- QQueue<Channel *> q;
- q << c;
- chans.insert(c);
+ q.enqueue(c);
+ }
- if (msg->bTree) {
- while (! q.isEmpty()) {
- c = q.dequeue();
- chans.insert(c);
- foreach(c, c->qlChannels)
- q.enqueue(c);
- }
- }
- foreach(c, chans) {
- if (ChanACL::hasPermission(uSource, c, ChanACL::Speak | ChanACL::AltSpeak, acCache)) {
- foreach(Player *p, c->qlPlayers) {
- if (p != static_cast<Player *>(uSource))
- sendMessage(static_cast<User *>(p), msg);
- }
- }
+ while (! q.isEmpty()) {
+ Channel *c = q.dequeue();
+ if (ChanACL::hasPermission(uSource, c, ChanACL::Speak | ChanACL::AltSpeak, acCache)) {
+ foreach(c, c->qlChannels)
+ q.enqueue(c);
+ foreach(Player *p, c->qlPlayers)
+ users.insert(static_cast<User *>(p));
}
+ }
- } else {
- VICTIM_SETUP;
- if (! ChanACL::hasPermission(uSource, pDstUser->cChannel, ChanACL::Speak | ChanACL::AltSpeak, acCache)) {
- PERM_DENIED(uSource, pDstUser->cChannel, ChanACL::Speak);
+ for(int i=0;i < msg->session_size(); ++i) {
+ unsigned int session = msg->session(i);
+ User *u = qhUsers.value(session);
+ if (! ChanACL::hasPermission(uSource, u->cChannel, ChanACL::Speak | ChanACL::AltSpeak, acCache)) {
+ PERM_DENIED(uSource, u->cChannel, ChanACL::Speak);
return;
}
- sendMessage(pDstUser, msg);
+ users.insert(u);
}
+
+ foreach(User *u, users)
+ sendMessage(u, *msg, MessageHandler::TextMessage);
}
-void Server::msgEditACL(Connection *cCon, MessageEditACL *msg) {
+void Server::msgACL(Connection *cCon, MumbleProto::ACL *msg) {
MSG_SETUP(Player::Authenticated);
- Channel *c = qhChannels.value(msg->iId);
+ Channel *c = qhChannels.value(msg->channel_id());
if (!c)
return;
@@ -748,15 +702,17 @@ void Server::msgEditACL(Connection *cCon, MessageEditACL *msg) {
PERM_DENIED(uSource, c, ChanACL::Write);
return;
}
-
- MessageEditACL mea;
- mea.iId = msg->iId;
-
- if (msg->bQuery) {
+
+ if (msg->has_query() && msg->query()) {
QStack<Channel *> chans;
Channel *p;
ChanACL *acl;
-
+
+ msg->clear_groups();
+ msg->clear_acls();
+ msg->clear_query();
+ msg->set_inherit_acls(c->bInheritACL);
+
p = c;
while (p) {
chans.push(p);
@@ -766,22 +722,21 @@ void Server::msgEditACL(Connection *cCon, MessageEditACL *msg) {
p = NULL;
}
- mea.bQuery = false;
- mea.bInheritACL = c->bInheritACL;
-
while (! chans.isEmpty()) {
p = chans.pop();
foreach(acl, p->qlACL) {
if ((p == c) || (acl->bApplySubs)) {
- MessageEditACL::ACLStruct as;
- as.bInherited = (p != c);
- as.bApplyHere = acl->bApplyHere;
- as.bApplySubs = acl->bApplySubs;
- as.iPlayerId = acl->iPlayerId;
- as.qsGroup = acl->qsGroup;
- as.pDeny = acl->pDeny;
- as.pAllow = acl->pAllow;
- mea.acls << as;
+ MumbleProto::ACL_ChanACL *mpacl = msg->add_acls();
+
+ mpacl->set_inherited(p != c);
+ mpacl->set_apply_here(acl->bApplyHere);
+ mpacl->set_apply_subs(acl->bApplySubs);
+ if (acl->iPlayerId >= 0)
+ mpacl->set_user_id(acl->iPlayerId);
+ else
+ mpacl->set_group(u8(acl->qsGroup));
+ mpacl->set_grant(acl->pAllow);
+ mpacl->set_deny(acl->pDeny);
}
}
}
@@ -792,25 +747,26 @@ void Server::msgEditACL(Connection *cCon, MessageEditACL *msg) {
foreach(name, allnames) {
Group *g = c->qhGroups.value(name);
Group *pg = p ? Group::getGroup(p, name) : NULL;
- MessageEditACL::GroupStruct gs;
- gs.qsName = name;
- gs.bInherit = g ? g->bInherit : true;
- gs.bInheritable = g ? g->bInheritable : true;
- gs.bInherited = ((pg != NULL) && pg->bInheritable);
+
+ MumbleProto::ACL_ChanGroup *group = msg->add_groups();
+ group->set_name(u8(name));
+ group->set_inherit(g ? g->bInherit : true);
+ group->set_inheritable(g ? g->bInheritable : true);
+ group->set_inherited((pg != NULL) && pg->bInheritable);
if (g) {
- gs.qsAdd = g->qsAdd;
- gs.qsRemove = g->qsRemove;
+ foreach(int id, g->qsAdd)
+ group->add_add(id);
+ foreach(int id, g->qsRemove)
+ group->add_remove(id);
}
if (pg)
- gs.qsInheritedMembers = pg->members();
- mea.groups << gs;
+ foreach(int id, pg->members())
+ group->add_inherited_members(id);
}
- sendMessage(cCon, &mea);
+ sendMessage(uSource, *msg, MessageHandler::ACL);
} else {
Group *g;
ChanACL *a;
- MessageEditACL::GroupStruct gs;
- MessageEditACL::ACLStruct as;
QHash<QString, QSet<int> > hOldTemp;
@@ -825,25 +781,31 @@ void Server::msgEditACL(Connection *cCon, MessageEditACL *msg) {
c->qhGroups.clear();
c->qlACL.clear();
- c->bInheritACL = msg->bInheritACL;
-
- foreach(gs, msg->groups) {
- g = new Group(c, gs.qsName);
- g->bInherit = gs.bInherit;
- g->bInheritable = gs.bInheritable;
- g->qsAdd = gs.qsAdd;
- g->qsRemove = gs.qsRemove;
- g->qsTemporary = hOldTemp.value(gs.qsName);
+ c->bInheritACL = msg->inherit_acls();
+
+ for(int i=0;i<msg->groups_size(); ++i) {
+ const MumbleProto::ACL_ChanGroup &group = msg->groups(i);
+ g = new Group(c, u8(group.name()));
+ g->bInherit = group.inherit();
+ g->bInheritable = group.inheritable();
+ for(int j=0;j<group.add_size();++j)
+ g->qsAdd << group.add(j);
+ for(int j=0;j<group.remove_size();++j)
+ g->qsRemove << group.remove(j);
+ g->qsTemporary = hOldTemp.value(g->qsName);
}
- foreach(as, msg->acls) {
+ for(int i=0;i<msg->acls_size(); ++i) {
+ const MumbleProto::ACL_ChanACL &mpacl = msg->acls(i);
a = new ChanACL(c);
- a->bApplyHere=as.bApplyHere;
- a->bApplySubs=as.bApplySubs;
- a->iPlayerId=as.iPlayerId;
- a->qsGroup=as.qsGroup;
- a->pDeny=as.pDeny;
- a->pAllow=as.pAllow;
+ a->bApplyHere=mpacl.apply_here();
+ a->bApplySubs=mpacl.apply_subs();
+ if (mpacl.has_user_id())
+ a->iPlayerId=mpacl.user_id();
+ else
+ a->qsGroup=u8(mpacl.group());
+ a->pDeny=static_cast<ChanACL::Permissions>(mpacl.deny());
+ a->pAllow=static_cast<ChanACL::Permissions>(mpacl.grant());
}
clearACLCache();
@@ -864,111 +826,96 @@ void Server::msgEditACL(Connection *cCon, MessageEditACL *msg) {
}
}
-void Server::msgQueryUsers(Connection *cCon, MessageQueryUsers *msg) {
+void Server::msgQueryUsers(Connection *cCon, MumbleProto::QueryUsers *msg) {
MSG_SETUP(Player::Authenticated);
- int i;
- for (i=0;i<msg->qlIds.count();i++) {
- QString name = msg->qlNames[i];
- int id = msg->qlIds[i];
- if (id < 0) {
- id = qhUserIDCache.value(name);
+ if (msg->ids_size()) {
+ msg->clear_names();
+ for(int i=0;i<msg->ids_size();++i) {
+ int id = msg->ids(i);
+ if (! qhUserNameCache.contains(id)) {
+ QString name = getUserName(id);
+ if (! name.isEmpty())
+ qhUserNameCache[id] = name;
+ }
+ msg->add_names(u8(qhUserNameCache.value(id)));
+ }
+ } else {
+ msg->clear_ids();
+ for(int i=0;i<msg->names_size();++i) {
+ QString name = u8(msg->names(i));
+ int id = qhUserIDCache.value(name);
if (! qhUserIDCache.contains(name)) {
id = getUserID(name);
if (id >= 0)
qhUserIDCache[name] = id;
}
- msg->qlIds[i] = (id >= 0) ? id : -1;
- } else {
- if (! qhUserNameCache.contains(id)) {
- name = getUserName(id);
- if (! name.isEmpty())
- qhUserNameCache[id] = name;
- }
- msg->qlNames[i] = qhUserNameCache.value(id);
+ msg->add_ids((id >= 0) ? id : -1);
}
}
- // Check if session is alive.
- if (! qhUsers.contains(msg->uiSession))
- return;
-
- sendMessage(cCon, msg);
-}
-void Server::msgPing(Connection *cCon, MessagePing *msg) {
- MSG_SETUP(Player::Authenticated);
- sendMessage(cCon, msg);
+ sendMessage(uSource, *msg, MessageHandler::QueryUsers);
}
-void Server::msgPingStats(Connection *cCon, MessagePingStats *msg) {
+void Server::msgPing(Connection *cCon, MumbleProto::Ping *msg) {
MSG_SETUP(Player::Authenticated);
CryptState &cs=uSource->csCrypt;
- cs.uiRemoteGood = msg->uiGood;
- cs.uiRemoteLate = msg->uiLate;
- cs.uiRemoteLost = msg->uiLost;
- cs.uiRemoteResync = msg->uiResync;
-
- uSource->dUDPPingAvg = msg->dUDPPingAvg;
- uSource->dUDPPingVar = msg->dUDPPingVar;
- uSource->uiUDPPackets = msg->uiUDPPackets;
- uSource->dTCPPingAvg = msg->dTCPPingAvg;
- uSource->dTCPPingVar = msg->dTCPPingVar;
- uSource->uiTCPPackets = msg->uiTCPPackets;
-
- msg->uiGood = cs.uiGood;
- msg->uiLate = cs.uiLate;
- msg->uiLost = cs.uiLost;
- msg->uiResync = cs.uiResync;
-
- msg->dUDPPingAvg = msg->dUDPPingVar = msg->dTCPPingAvg = msg->dTCPPingVar = 0.0L;
- msg->uiUDPPackets = msg->uiTCPPackets = 0;
- sendMessage(cCon, msg);
-}
-
-void Server::msgTexture(Connection *cCon, MessageTexture *msg) {
- MSG_SETUP(Player::Authenticated);
- if (! qhUserTextureCache.contains(msg->iPlayerId)) {
- QByteArray qba = getUserTexture(msg->iPlayerId);
- if (! qba.isEmpty()) {
- // Check for uncompressed image
- if (qba.size() == 600 * 60 * 4)
- qba = qCompress(qba);
- }
- qhUserTextureCache.insert(msg->iPlayerId, qba);
- }
-
- // Check if session is alive.
- if (! qhUsers.contains(msg->uiSession))
- return;
- msg->qbaTexture = qhUserTextureCache.value(msg->iPlayerId);
- if (! msg->qbaTexture.isEmpty())
- sendMessage(cCon, msg);
+ cs.uiRemoteGood = msg->good();
+ cs.uiRemoteLate = msg->late();
+ cs.uiRemoteLost = msg->lost();
+ cs.uiRemoteResync = msg->resync();
+
+ uSource->dUDPPingAvg = msg->udp_ping_avg();
+ uSource->dUDPPingVar = msg->udp_ping_var();
+ uSource->uiUDPPackets = msg->udp_packets();
+ uSource->dTCPPingAvg = msg->tcp_ping_avg();
+ uSource->dTCPPingVar = msg->tcp_ping_var();
+ uSource->uiTCPPackets = msg->tcp_packets();
+
+ quint64 ts = msg->timestamp();
+
+ msg->Clear();
+ msg->set_timestamp(ts);
+ msg->set_good(cs.uiGood);
+ msg->set_late(cs.uiLate);
+ msg->set_lost(cs.uiLost);
+ msg->set_resync(cs.uiResync);
+
+ sendMessage(uSource, *msg, MessageHandler::Ping);
}
-void Server::msgCryptSync(Connection *cCon, MessageCryptSync *msg) {
+void Server::msgCryptSetup(Connection *cCon, MumbleProto::CryptSetup *msg) {
MSG_SETUP(Player::Authenticated);
- if (msg->qbaNonce.isEmpty()) {
+ if (! msg->has_client_nonce()) {
log(uSource, "Requested crypt-nonce resync");
- msg->qbaNonce = QByteArray(reinterpret_cast<const char *>(uSource->csCrypt.encrypt_iv), AES_BLOCK_SIZE);
- sendMessage(cCon, msg);
- } else if (msg->qbaNonce.size() == AES_BLOCK_SIZE) {
- uSource->csCrypt.uiResync++;
- memcpy(uSource->csCrypt.decrypt_iv, msg->qbaNonce.constData(), AES_BLOCK_SIZE);
+ msg->set_server_nonce(std::string(reinterpret_cast<const char *>(uSource->csCrypt.encrypt_iv), AES_BLOCK_SIZE));
+ sendMessage(uSource, *msg, MessageHandler::CryptSetup);
} else {
- cCon->disconnectSocket();
+ const std::string &str = msg->client_nonce();
+ if (str.size() == AES_BLOCK_SIZE) {
+ uSource->csCrypt.uiResync++;
+ memcpy(uSource->csCrypt.decrypt_iv, str.data(), AES_BLOCK_SIZE);
+ }
}
}
-void Server::msgContextAddAction(Connection *cCon, MessageContextAddAction *) {
- cCon->disconnectSocket();
+void Server::msgContextActionAdd(Connection *, MumbleProto::ContextActionAdd *) {
}
-void Server::msgContextAction(Connection *cCon, MessageContextAction *msg) {
+void Server::msgContextAction(Connection *cCon, MumbleProto::ContextAction *msg) {
MSG_SETUP(Player::Authenticated);
- if ((msg->uiVictim > 0) && ! qhUsers.contains(msg->uiVictim))
+
+ unsigned int session = msg->has_session() ? msg->session() : 0;
+ int id = msg->has_channel_id() ? static_cast<int>(msg->channel_id()) : -1;
+
+ if (session && ! qhUsers.contains(session))
return;
- if ((msg->iChannel >= 0) && ! qhChannels.contains(msg->iChannel))
+ if ((id >= 0) && ! qhChannels.contains(id))
return;
- emit contextAction(uSource, msg->qsAction, msg->uiVictim, msg->iChannel);
+ emit contextAction(uSource, u8(msg->action()), session, id);
+}
+
+void Server::msgVersion(Connection *, MumbleProto::Version *) {
}
+
diff --git a/src/murmur/RPC.cpp b/src/murmur/RPC.cpp
index 7c008eaec..0de7cb06d 100644
--- a/src/murmur/RPC.cpp
+++ b/src/murmur/RPC.cpp
@@ -36,58 +36,45 @@
#include "Version.h"
void Server::setPlayerState(Player *pPlayer, Channel *cChannel, bool mute, bool deaf, bool suppressed) {
- bool changed = false;
+ // FIXME: What if nothing changed? Then don't emit and don't sendAll.
if (deaf)
mute = true;
if (! mute)
deaf = false;
-
- if ((pPlayer->bDeaf != deaf) && (deaf || (!deaf && mute))) {
- pPlayer->bDeaf = deaf;
- pPlayer->bMute = mute;
- MessagePlayerDeaf mpd;
- mpd.uiSession = 0;
- mpd.uiVictim=pPlayer->uiSession;
- mpd.bDeaf = deaf;
- sendAll(&mpd);
- changed = true;
- } else if ((pPlayer->bDeaf != deaf) || (pPlayer->bMute != mute)) {
- pPlayer->bDeaf = deaf;
- pPlayer->bMute = mute;
-
- MessagePlayerMute mpm;
- mpm.uiSession = 0;
- mpm.uiVictim=pPlayer->uiSession;
- mpm.bMute=mute;
- sendAll(&mpm);
- changed = true;
- }
-
+
+ MumbleProto::UserState mpus;
+ mpus.set_session(pPlayer->uiSession);
+ if (mute != pPlayer->bMute)
+ mpus.set_mute(mute);
+ if (deaf != pPlayer->bDeaf)
+ mpus.set_deaf(deaf);
+ if (suppressed != pPlayer->bSuppressed)
+ mpus.set_suppressed(suppressed);
+
+ pPlayer->bDeaf = deaf;
+ pPlayer->bMute = mute;
+ pPlayer->bSuppressed = suppressed;
+
if (cChannel != pPlayer->cChannel) {
+ mpus.set_channel_id(cChannel->iId);
playerEnterChannel(pPlayer, cChannel);
- MessagePlayerMove mpm;
- mpm.uiSession = 0;
- mpm.uiVictim = pPlayer->uiSession;
- mpm.iChannelId = cChannel->iId;
- sendAll(&mpm);
- changed = true;
}
-
+
+ sendAll(mpus, MessageHandler::UserState);
emit playerStateChanged(pPlayer);
}
bool Server::setChannelState(Channel *cChannel, Channel *cParent, const QString &qsName, const QSet<Channel *> &links) {
bool changed = false;
bool updated = false;
-
+
+ MumbleProto::ChannelState mpcs;
+ mpcs.set_channel_id(cChannel->iId);
+
if (cChannel->qsName != qsName) {
cChannel->qsName = qsName;
- MessageChannelRename mcr;
- mcr.uiSession = 0;
- mcr.iId = cChannel->iId;
- mcr.qsName = cChannel->qsName;
- sendAll(&mcr);
+ mpcs.set_name(u8(qsName));
updated = true;
changed = true;
}
@@ -102,12 +89,8 @@ bool Server::setChannelState(Channel *cChannel, Channel *cParent, const QString
cChannel->cParent->removeChannel(cChannel);
cParent->addChannel(cChannel);
-
- MessageChannelMove mcm;
- mcm.uiSession = 0;
- mcm.iId = cChannel->iId;
- mcm.iParent = cParent->iId;
- sendAll(&mcm);
+
+ mpcs.set_parent(cParent->iId);
updated = true;
changed = true;
@@ -120,13 +103,7 @@ bool Server::setChannelState(Channel *cChannel, Channel *cParent, const QString
foreach(Channel *l, links) {
if (! links.contains(l)) {
removeLink(cChannel, l);
-
- MessageChannelLink mcl;
- mcl.uiSession = 0;
- mcl.iId = cChannel->iId;
- mcl.qlTargets << l->iId;
- mcl.ltType = MessageChannelLink::Unlink;
- sendAll(&mcl);
+ mpcs.add_links_remove(l->iId);
}
}
@@ -134,13 +111,7 @@ bool Server::setChannelState(Channel *cChannel, Channel *cParent, const QString
foreach(Channel *l, links) {
if (! oldset.contains(l)) {
addLink(cChannel, l);
-
- MessageChannelLink mcl;
- mcl.uiSession = 0;
- mcl.iId = cChannel->iId;
- mcl.qlTargets << l->iId;
- mcl.ltType = MessageChannelLink::Link;
- sendAll(&mcl);
+ mpcs.add_links_add(l->iId);
}
}
@@ -149,25 +120,26 @@ bool Server::setChannelState(Channel *cChannel, Channel *cParent, const QString
if (updated)
updateChannel(cChannel);
- if (changed)
+ if (changed) {
+ sendAll(mpcs, MessageHandler::ChannelState);
emit channelStateChanged(cChannel);
+ }
return true;
}
void Server::sendTextMessage(Channel *cChannel, User *pPlayer, bool tree, const QString &text) {
- MessageTextMessage mtm;
- mtm.uiSession = 0;
- mtm.qsMessage = text;
+ MumbleProto::TextMessage mptm;
+ mptm.set_message(u8(text));
+
if (pPlayer) {
- mtm.uiVictim = pPlayer->uiSession;
- mtm.iChannel = -1;
- mtm.bTree = false;
- sendMessage(pPlayer, &mtm);
+ mptm.add_session(pPlayer->uiSession);
+ sendMessage(pPlayer, mptm, MessageHandler::TextMessage);
} else {
- mtm.uiVictim = 0;
- mtm.iChannel = cChannel->iId;
- mtm.bTree = tree;
+ if (tree)
+ mptm.add_tree_id(cChannel->iId);
+ else
+ mptm.add_channel_id(cChannel->iId);
QSet<Channel *> chans;
QQueue<Channel *> q;
@@ -185,7 +157,7 @@ void Server::sendTextMessage(Channel *cChannel, User *pPlayer, bool tree, const
}
foreach(c, chans) {
foreach(Player *p, c->qlPlayers)
- sendMessage(static_cast<User *>(p), &mtm);
+ sendMessage(static_cast<User *>(p), mptm, MessageHandler::TextMessage);
}
}
}
diff --git a/src/murmur/Server.cpp b/src/murmur/Server.cpp
index e5c5b5cb6..b7a1c357e 100644
--- a/src/murmur/Server.cpp
+++ b/src/murmur/Server.cpp
@@ -39,7 +39,6 @@
#include "Connection.h"
#include "Server.h"
#include "DBus.h"
-#include "PacketDataStream.h"
#include "Meta.h"
uint qHash(const Peer &p) {
@@ -327,9 +326,6 @@ void Server::run() {
#endif
char buffer[512];
- quint32 msgType = 0;
- unsigned int uiSession = 0;
-
sockaddr_in from;
#ifdef Q_OS_UNIX
socklen_t fromlen;
@@ -372,7 +368,7 @@ void Server::run() {
break;
} else if (len == SOCKET_ERROR) {
break;
- } else if (len < 6) {
+ } else if (len < 5) {
// 4 bytes crypt header + type + session
continue;
} else if (len > 512) {
@@ -382,80 +378,51 @@ void Server::run() {
QReadLocker rl(&qrwlUsers);
quint64 key = (static_cast<unsigned long long>(from.sin_addr.s_addr) << 16) ^ from.sin_port;
- PacketDataStream pds(buffer, len - 4);
User *u = qhPeerUsers.value(key);
if (u) {
if (! checkDecrypt(u, encrypted, buffer, len)) {
continue;
}
- pds >> msgType >> uiSession;
- if (u->uiSession != uiSession) {
- continue;
- }
} else {
// Unknown peer
foreach(User *usr, qhHostUsers.value(from.sin_addr.s_addr)) {
- pds.rewind();
if (usr->csCrypt.isValid() && checkDecrypt(usr, encrypted, buffer, len)) {
- pds >> msgType >> uiSession;
- if (usr->uiSession == uiSession) {
- // Every time we relock, reverify users' existance.
- // The main thread might delete the user while the lock isn't held.
- rl.unlock();
- qrwlUsers.lockForWrite();
- if (qhUsers.contains(uiSession)) {
- u = usr;
- qhHostUsers[from.sin_addr.s_addr].remove(u);
- qhPeerUsers.insert(key, u);
- u->saiUdpAddress.sin_port = from.sin_port;
- qrwlUsers.unlock();
- rl.relock();
- if (! qhUsers.contains(uiSession))
- u = NULL;
- }
+ // Every time we relock, reverify users' existance.
+ // The main thread might delete the user while the lock isn't held.
+ unsigned int uiSession = usr->uiSession;
+ rl.unlock();
+ qrwlUsers.lockForWrite();
+ if (qhUsers.contains(uiSession)) {
+ u = usr;
+ qhHostUsers[from.sin_addr.s_addr].remove(u);
+ qhPeerUsers.insert(key, u);
+ u->saiUdpAddress.sin_port = from.sin_port;
+ qrwlUsers.unlock();
+ rl.relock();
+ if (! qhUsers.contains(uiSession))
+ u = NULL;
}
-
+ break;
}
}
if (! u) {
continue;
}
- len -= 4;
}
+ len -= 4;
- if ((msgType != Message::Speex) && (msgType != Message::Ping))
- continue;
- if (! pds.isValid())
- continue;
-
- if (msgType == Message::Ping) {
+ unsigned int msgType = (buffer[0] >> 5) & 0x7;
+
+ if (msgType == MessageHandler::UDPPing) {
QByteArray qba;
sendMessage(u, buffer, len, qba);
- } else {
- processMsg(pds, qhUsers.value(uiSession));
+ } else if (msgType == MessageHandler::UDPVoice) {
+ processMsg(u, buffer, len);
}
}
}
-void Server::fakeUdpPacket(Message *msg, Connection *source) {
- char buffer[512];
- PacketDataStream pds(buffer, 512);
- msg->messageToNetwork(pds);
- if (! pds.isValid())
- return;
-
- pds.rewind();
-
- quint32 msgType;
- int uiSession;
-
- pds >> msgType >> uiSession;
-
- QReadLocker rl(&qrwlUsers);
- processMsg(pds, source);
-}
-
bool Server::checkDecrypt(User *u, const char *encrypted, char *plain, unsigned int len) {
if (u->csCrypt.isValid() && u->csCrypt.decrypt(reinterpret_cast<const unsigned char *>(encrypted), reinterpret_cast<unsigned char *>(plain), len))
return true;
@@ -497,24 +464,16 @@ void Server::sendMessage(User *u, const char *data, int len, QByteArray &cache)
}
}
-void Server::processMsg(PacketDataStream &pds, Connection *cCon) {
- User *u = static_cast<User *>(cCon);
- if (! u || (u->sState != Player::Authenticated))
+void Server::processMsg(User *u, const char *data, int len) {
+ if (u->sState != Player::Authenticated || u->bMute || u->bSuppressed)
return;
Player *p;
- int seq, flags;
-
- if (u->bMute || u->bSuppressed)
- return;
BandwidthRecord *bw = & u->bwr;
- pds >> seq;
- pds >> flags;
-
// IP + UDP + Crypt + Data
- int packetsize = 20 + 8 + 4 + pds.capacity();
+ int packetsize = 20 + 8 + 4 + len;
bw->addFrame(packetsize);
if (bw->bytesPerSec() > iMaxBandwidth) {
@@ -526,11 +485,9 @@ void Server::processMsg(PacketDataStream &pds, Connection *cCon) {
QByteArray qba;
- pds.rewind();
- const char *data = pds.charPtr();
- int len = pds.left();
+ unsigned int target = data[0] & 0x1f;
- if (flags & MessageSpeex::LoopBack) {
+ if (target == 0x1f) {
sendMessage(u, data, len, qba);
return;
}
@@ -547,7 +504,7 @@ void Server::processMsg(PacketDataStream &pds, Connection *cCon) {
QMutexLocker qml(&qmCache);
foreach(Channel *l, chans) {
- if (ChanACL::hasPermission(u, l, (flags & MessageSpeex::AltSpeak) ? ChanACL::AltSpeak : ChanACL::Speak, acCache)) {
+ if (ChanACL::hasPermission(u, l, (target == 1) ? ChanACL::AltSpeak : ChanACL::Speak, acCache)) {
foreach(p, l->qlPlayers) {
if (! p->bDeaf && ! p->bSelfDeaf)
sendMessage(static_cast<User *>(p), data, len, qba);
@@ -658,9 +615,9 @@ void Server::connectionClosed(QString reason) {
log(u, QString("Connection closed: %1").arg(reason));
if (u->sState == Player::Authenticated) {
- MessageServerLeave mslMsg;
- mslMsg.uiSession=u->uiSession;
- sendExcept(&mslMsg, c);
+ MumbleProto::UserRemove mpur;
+ mpur.set_session(u->uiSession);
+ sendExcept(u, mpur, MessageHandler::UserRemove);
emit playerDisconnected(u);
}
@@ -689,21 +646,13 @@ void Server::connectionClosed(QString reason) {
stopThread();
}
-void Server::message(QByteArray &qbaMsg, Connection *cCon) {
+void Server::message(const QByteArray &qbaMsg, unsigned int msgType, Connection *cCon) {
if (cCon == NULL) {
cCon = static_cast<Connection *>(sender());
}
- Message *mMsg = Message::networkToMessage(qbaMsg);
-
- if (mMsg) {
- dispatch(cCon, mMsg);
- delete mMsg;
- } else {
- cCon->disconnectSocket();
- }
+ dispatch(cCon, msgType, qbaMsg);
}
-
void Server::checkTimeout() {
QList<User *> qlClose;
@@ -731,23 +680,25 @@ void Server::doSync(unsigned int id) {
User *u = qhUsers.value(id);
if (u) {
log(u, "Requesting crypt-nonce resync");
- MessageCryptSync mcs;
- u->sendMessage(&mcs);
+ MumbleProto::CryptSetup mpcs;
+ sendMessage(u, mpcs, MessageHandler::CryptSetup);
}
}
-void Server::sendMessage(Connection *c, Message *mMsg) {
- c->sendMessage(mMsg);
+void Server::sendMessage(User *u, const ::google::protobuf::Message &msg, unsigned int msgType) {
+ QByteArray cache;
+ u->sendMessage(msg, msgType, cache);
}
-void Server::sendAll(Message *mMsg) {
- sendExcept(mMsg, NULL);
+void Server::sendAll(const ::google::protobuf::Message &msg, unsigned int msgType) {
+ sendExcept(NULL, msg, msgType);
}
-void Server::sendExcept(Message *mMsg, Connection *cCon) {
- foreach(User *u, qhUsers)
- if ((static_cast<Connection *>(u) != cCon) && (u->sState == Player::Authenticated))
- u->sendMessage(mMsg);
+void Server::sendExcept(User *u, const ::google::protobuf::Message &msg, unsigned int msgType) {
+ QByteArray cache;
+ foreach(User *usr, qhUsers)
+ if ((usr != u) && (usr->sState == Player::Authenticated))
+ usr->sendMessage(msg, msgType, cache);
}
void Server::sendChannelDescription(Player *p, const Channel *c) {
@@ -783,20 +734,18 @@ void Server::removeChannel(Channel *chan, Player *src, Channel *dest) {
foreach(p, chan->qlPlayers) {
chan->removePlayer(p);
-
- MessagePlayerMove mpm;
- mpm.uiSession = 0;
- mpm.uiVictim = p->uiSession;
- mpm.iChannelId = dest->iId;
- sendAll(&mpm);
+
+ MumbleProto::UserState mpus;
+ mpus.set_session(p->uiSession);
+ mpus.set_channel_id(dest->iId);
+ sendAll(mpus, MessageHandler::UserState);
playerEnterChannel(p, dest);
}
-
- MessageChannelRemove mcr;
- mcr.uiSession = src ? src->uiSession : 0;
- mcr.iId = chan->iId;
- sendAll(&mcr);
+
+ MumbleProto::ChannelRemove mpcr;
+ mpcr.set_channel_id(chan->iId);
+ sendAll(mpcr, MessageHandler::ChannelRemove);
removeChannel(chan);
emit channelRemoved(chan);
@@ -851,11 +800,10 @@ void Server::playerEnterChannel(Player *p, Channel *c, bool quiet) {
// Ok, he can speak and was suppressed, or vice versa
p->bSuppressed = ! mayspeak;
- MessagePlayerMute mpm;
- mpm.uiSession = 0;
- mpm.uiVictim = p->uiSession;
- mpm.bMute = p->bSuppressed;
- sendAll(&mpm);
+ MumbleProto::UserState mpus;
+ mpus.set_session(p->uiSession);
+ mpus.set_suppressed(p->bSuppressed);
+ sendAll(mpus, MessageHandler::UserState);
}
}
emit playerStateChanged(p);
diff --git a/src/murmur/Server.h b/src/murmur/Server.h
index a4f4def95..2a210ea7c 100644
--- a/src/murmur/Server.h
+++ b/src/murmur/Server.h
@@ -36,6 +36,7 @@
#include "Timer.h"
#include "Player.h"
#include "Connection.h"
+#include "ACL.h"
#include "DBus.h"
class Channel;
@@ -157,7 +158,7 @@ class Server : public QThread, public MessageHandler {
void newClient();
void connectionClosed(QString);
void sslError(const QList<QSslError> &);
- void message(QByteArray &, Connection *cCon = NULL);
+ void message(const QByteArray &, unsigned int, Connection *cCon = NULL);
void checkTimeout();
void tcpTransmitData(QByteArray, unsigned int);
void doSync(unsigned int);
@@ -189,9 +190,8 @@ class Server : public QThread, public MessageHandler {
QList<QPair<quint32, int> > qlBans;
- void processMsg(PacketDataStream &pds, Connection *cCon);
+ void processMsg(User *u, const char *data, int len);
void sendMessage(User *u, const char *data, int len, QByteArray &cache);
- void fakeUdpPacket(Message *msg, Connection *source);
void run();
bool validateChannelName(const QString &name);
@@ -202,9 +202,10 @@ class Server : public QThread, public MessageHandler {
bool hasPermission(Player *p, Channel *c, ChanACL::Perm perm);
void clearACLCache(Player *p = NULL);
- void sendAll(Message *);
- void sendExcept(Message *, Connection *);
- void sendMessage(Connection *, Message *);
+ void sendAll(const ::google::protobuf::Message &msg, unsigned int msgType);
+ void sendExcept(User *, const ::google::protobuf::Message &msg, unsigned int msgType);
+ void sendMessage(User *, const ::google::protobuf::Message &msg, unsigned int msgType);
+
void sendChannelDescription(Player *, const Channel *);
void sendChannelDescriptionUpdate(const Channel *changed, const Channel *current=NULL);
@@ -288,37 +289,24 @@ class Server : public QThread, public MessageHandler {
void dblog(const QString &str);
// 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 *);
};
diff --git a/src/murmur/ServerDB.cpp b/src/murmur/ServerDB.cpp
index 3ccf84571..7e9fea792 100644
--- a/src/murmur/ServerDB.cpp
+++ b/src/murmur/ServerDB.cpp
@@ -844,6 +844,9 @@ QByteArray Server::getUserTexture(int id) {
SQLEXEC();
if (query.next()) {
qba = query.value(0).toByteArray();
+ if (! qba.isEmpty())
+ if (qba.size() == 600 * 60 * 4)
+ qba = qCompress(qba);
}
return qba;
}