mirror of
https://github.com/mumble-voip/mumble.git
synced 2025-10-26 11:19:16 +00:00
1599 lines
46 KiB
C++
1599 lines
46 KiB
C++
/* Copyright (C) 2005-2011, 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.
|
|
*/
|
|
|
|
|
|
#include <Ice/Ice.h>
|
|
#include <Ice/SliceChecksums.h>
|
|
#include <IceUtil/IceUtil.h>
|
|
#include "Meta.h"
|
|
#include "Server.h"
|
|
#include "ServerUser.h"
|
|
#include "ServerDB.h"
|
|
#include "User.h"
|
|
#include "Channel.h"
|
|
#include "Group.h"
|
|
#include "MurmurIce.h"
|
|
#include "MurmurI.h"
|
|
|
|
using namespace std;
|
|
using namespace Murmur;
|
|
|
|
static MurmurIce *mi = NULL;
|
|
static Ice::ObjectPtr iopServer;
|
|
static Ice::PropertiesPtr ippProperties;
|
|
|
|
void IceParse(int &argc, char *argv[]) {
|
|
ippProperties = Ice::createProperties(argc, argv);
|
|
}
|
|
|
|
void IceStart() {
|
|
mi = new MurmurIce();
|
|
}
|
|
|
|
void IceStop() {
|
|
delete mi;
|
|
mi = NULL;
|
|
}
|
|
|
|
static void logToLog(const ServerDB::LogRecord &r, Murmur::LogEntry &le) {
|
|
le.timestamp = r.first;
|
|
le.txt = u8(r.second);
|
|
}
|
|
|
|
static void userToUser(const ::User *p, Murmur::User &mp) {
|
|
mp.session = p->uiSession;
|
|
mp.userid = p->iId;
|
|
mp.name = u8(p->qsName);
|
|
mp.mute = p->bMute;
|
|
mp.deaf = p->bDeaf;
|
|
mp.suppress = p->bSuppress;
|
|
mp.recording = p->bRecording;
|
|
mp.prioritySpeaker = p->bPrioritySpeaker;
|
|
mp.selfMute = p->bSelfMute;
|
|
mp.selfDeaf = p->bSelfDeaf;
|
|
mp.channel = p->cChannel->iId;
|
|
mp.comment = u8(p->qsComment);
|
|
|
|
const ServerUser *u=static_cast<const ServerUser *>(p);
|
|
mp.onlinesecs = u->bwr.onlineSeconds();
|
|
mp.bytespersec = u->bwr.bandwidth();
|
|
mp.version = u->uiVersion;
|
|
mp.release = u8(u->qsRelease);
|
|
mp.os = u8(u->qsOS);
|
|
mp.osversion = u8(u->qsOSVersion);
|
|
mp.identity = u8(u->qsIdentity);
|
|
mp.context = u->ssContext;
|
|
mp.idlesecs = u->bwr.idleSeconds();
|
|
mp.udpPing = u->dUDPPingAvg;
|
|
mp.tcpPing = u->dTCPPingAvg;
|
|
|
|
mp.tcponly = ! u->bUdp;
|
|
|
|
::Murmur::NetAddress addr(16, 0);
|
|
const Q_IPV6ADDR &a = u->haAddress.qip6;
|
|
for (int i=0;i<16;++i)
|
|
addr[i] = a[i];
|
|
|
|
mp.address = addr;
|
|
}
|
|
|
|
static void channelToChannel(const ::Channel *c, Murmur::Channel &mc) {
|
|
mc.id = c->iId;
|
|
mc.name = u8(c->qsName);
|
|
mc.parent = c->cParent ? c->cParent->iId : -1;
|
|
mc.description = u8(c->qsDesc);
|
|
mc.position = c->iPosition;
|
|
mc.links.clear();
|
|
foreach(::Channel *chn, c->qsPermLinks)
|
|
mc.links.push_back(chn->iId);
|
|
mc.temporary = c->bTemporary;
|
|
}
|
|
|
|
static void ACLtoACL(const ::ChanACL *acl, Murmur::ACL &ma) {
|
|
ma.applyHere = acl->bApplyHere;
|
|
ma.applySubs = acl->bApplySubs;
|
|
ma.inherited = false;
|
|
ma.userid = acl->iUserId;
|
|
ma.group = u8(acl->qsGroup);
|
|
ma.allow = acl->pAllow;
|
|
ma.deny = acl->pDeny;
|
|
}
|
|
|
|
static void groupToGroup(const ::Group *g, Murmur::Group &mg) {
|
|
mg.name = u8(g->qsName);
|
|
mg.inherit = g->bInherit;
|
|
mg.inheritable = g->bInheritable;
|
|
mg.add.clear();
|
|
mg.remove.clear();
|
|
mg.members.clear();
|
|
}
|
|
|
|
static void banToBan(const ::Ban &b, Murmur::Ban &mb) {
|
|
::Murmur::NetAddress addr(16, 0);
|
|
const Q_IPV6ADDR &a = b.haAddress.qip6;
|
|
for (int i=0;i<16;++i)
|
|
addr[i] = a[i];
|
|
|
|
mb.address = addr;
|
|
mb.bits = b.iMask;
|
|
mb.name = u8(b.qsUsername);
|
|
mb.hash = u8(b.qsHash);
|
|
mb.reason = u8(b.qsReason);
|
|
mb.start = b.qdtStart.toLocalTime().toTime_t();
|
|
mb.duration = b.iDuration;
|
|
}
|
|
|
|
static void banToBan(const ::Murmur::Ban &mb, ::Ban &b) {
|
|
if (mb.address.size() != 16)
|
|
for (int i=0;i<16;++i)
|
|
b.haAddress.qip6[i] = 0;
|
|
else
|
|
for (int i=0;i<16;++i)
|
|
b.haAddress.qip6[i] = mb.address[i];
|
|
b.iMask = mb.bits;
|
|
b.qsUsername = u8(mb.name);
|
|
b.qsHash = u8(mb.hash);
|
|
b.qsReason = u8(mb.reason);
|
|
b.qdtStart = QDateTime::fromTime_t(static_cast<quint32>(mb.start)).toUTC();
|
|
b.iDuration = mb.duration;
|
|
}
|
|
|
|
static void infoToInfo(const QMap<int, QString> &info, Murmur::UserInfoMap &im) {
|
|
QMap<int, QString>::const_iterator i;
|
|
for (i = info.constBegin(); i != info.constEnd(); ++i)
|
|
im[static_cast<Murmur::UserInfo>(i.key())] = u8(i.value());
|
|
}
|
|
|
|
static void infoToInfo(const Murmur::UserInfoMap &im, QMap<int, QString> &info) {
|
|
Murmur::UserInfoMap::const_iterator i;
|
|
for (i = im.begin(); i != im.end(); ++i)
|
|
info.insert((*i).first, u8((*i).second));
|
|
}
|
|
|
|
static void textmessageToTextmessage(const ::TextMessage &tm, Murmur::TextMessage &tmdst) {
|
|
tmdst.text = u8(tm.qsText);
|
|
|
|
foreach(unsigned int i, tm.qlSessions)
|
|
tmdst.sessions.push_back(i);
|
|
|
|
foreach(unsigned int i, tm.qlChannels)
|
|
tmdst.channels.push_back(i);
|
|
|
|
foreach(unsigned int i, tm.qlTrees)
|
|
tmdst.trees.push_back(i);
|
|
}
|
|
|
|
class ServerLocator : public virtual Ice::ServantLocator {
|
|
public:
|
|
virtual Ice::ObjectPtr locate(const Ice::Current &, Ice::LocalObjectPtr &);
|
|
virtual void finished(const Ice::Current &, const Ice::ObjectPtr &, const Ice::LocalObjectPtr &) {};
|
|
virtual void deactivate(const std::string &) {};
|
|
};
|
|
|
|
MurmurIce::MurmurIce() {
|
|
count = 0;
|
|
|
|
if (meta->mp.qsIceEndpoint.isEmpty())
|
|
return;
|
|
|
|
Ice::PropertiesPtr ipp = Ice::createProperties();
|
|
|
|
::Meta::mp.qsSettings->beginGroup("Ice");
|
|
foreach(const QString &v, ::Meta::mp.qsSettings->childKeys()) {
|
|
ipp->setProperty(u8(v), u8(::Meta::mp.qsSettings->value(v).toString()));
|
|
}
|
|
::Meta::mp.qsSettings->endGroup();
|
|
|
|
Ice::PropertyDict props = ippProperties->getPropertiesForPrefix("");
|
|
Ice::PropertyDict::iterator i;
|
|
for (i=props.begin(); i != props.end(); ++i) {
|
|
ipp->setProperty((*i).first, (*i).second);
|
|
}
|
|
ipp->setProperty("Ice.ImplicitContext", "Shared");
|
|
|
|
Ice::InitializationData idd;
|
|
idd.properties = ipp;
|
|
|
|
try {
|
|
communicator = Ice::initialize(idd);
|
|
if (! meta->mp.qsIceSecretWrite.isEmpty()) {
|
|
::Ice::ImplicitContextPtr impl = communicator->getImplicitContext();
|
|
if (impl)
|
|
impl->put("secret", u8(meta->mp.qsIceSecretWrite));
|
|
}
|
|
adapter = communicator->createObjectAdapterWithEndpoints("Murmur", qPrintable(meta->mp.qsIceEndpoint));
|
|
MetaPtr m = new MetaI;
|
|
MetaPrx mprx = MetaPrx::uncheckedCast(adapter->add(m, communicator->stringToIdentity("Meta")));
|
|
adapter->addServantLocator(new ServerLocator(), "s");
|
|
|
|
iopServer = new ServerI;
|
|
|
|
adapter->activate();
|
|
foreach(const Ice::EndpointPtr ep, mprx->ice_getEndpoints()) {
|
|
qWarning("MurmurIce: Endpoint \"%s\" running", qPrintable(u8(ep->toString())));
|
|
}
|
|
|
|
meta->connectListener(this);
|
|
} catch (Ice::Exception &e) {
|
|
qCritical("MurmurIce: Initialization failed: %s", qPrintable(u8(e.ice_name())));
|
|
}
|
|
}
|
|
|
|
MurmurIce::~MurmurIce() {
|
|
if (communicator) {
|
|
communicator->shutdown();
|
|
communicator->waitForShutdown();
|
|
communicator->destroy();
|
|
communicator=NULL;
|
|
qWarning("MurmurIce: Shutdown complete");
|
|
}
|
|
iopServer = NULL;
|
|
}
|
|
|
|
void MurmurIce::customEvent(QEvent *evt) {
|
|
if (evt->type() == EXEC_QEVENT)
|
|
static_cast<ExecEvent *>(evt)->execute();
|
|
}
|
|
|
|
void MurmurIce::badMetaProxy(const ::Murmur::MetaCallbackPrx &prx) {
|
|
qCritical("Registered Ice MetaCallback %s failed", qPrintable(QString::fromStdString(communicator->proxyToString(prx))));
|
|
qmMetaCallbacks.removeAll(prx);
|
|
}
|
|
|
|
void MurmurIce::badServerProxy(const ::Murmur::ServerCallbackPrx &prx, int id) {
|
|
qCritical("Registered Ice ServerCallback %s on server %d failed", qPrintable(QString::fromStdString(communicator->proxyToString(prx))), id);
|
|
qmServerCallbacks[id].removeAll(prx);
|
|
}
|
|
|
|
void MurmurIce::badAuthenticator(::Server *server) {
|
|
server->disconnectAuthenticator(this);
|
|
const ::Murmur::ServerAuthenticatorPrx &prx = qmServerAuthenticator.value(server->iServerNum);
|
|
qCritical("Registered Ice Authenticator %s on server %d failed", qPrintable(QString::fromStdString(communicator->proxyToString(prx))), server->iServerNum);
|
|
qmServerAuthenticator.remove(server->iServerNum);
|
|
qmServerUpdatingAuthenticator.remove(server->iServerNum);
|
|
}
|
|
|
|
static ServerPrx idToProxy(int id, const Ice::ObjectAdapterPtr &adapter) {
|
|
Ice::Identity ident;
|
|
ident.category = "s";
|
|
ident.name = u8(QString::number(id));
|
|
|
|
return ServerPrx::uncheckedCast(adapter->createProxy(ident));
|
|
}
|
|
|
|
void MurmurIce::started(::Server *s) {
|
|
s->connectListener(mi);
|
|
connect(s, SIGNAL(contextAction(const User *, const QString &, unsigned int, int)), this, SLOT(contextAction(const User *, const QString &, unsigned int, int)));
|
|
|
|
const QList< ::Murmur::MetaCallbackPrx> &qmList = qmMetaCallbacks;
|
|
|
|
if (qmList.isEmpty())
|
|
return;
|
|
|
|
foreach(const ::Murmur::MetaCallbackPrx &prx, qmList) {
|
|
try {
|
|
prx->started(idToProxy(s->iServerNum, adapter));
|
|
} catch (...) {
|
|
badMetaProxy(prx);
|
|
}
|
|
}
|
|
}
|
|
|
|
void MurmurIce::stopped(::Server *s) {
|
|
qmServerCallbacks.remove(s->iServerNum);
|
|
qmServerAuthenticator.remove(s->iServerNum);
|
|
qmServerUpdatingAuthenticator.remove(s->iServerNum);
|
|
|
|
const QList< ::Murmur::MetaCallbackPrx> &qmList = qmMetaCallbacks;
|
|
|
|
if (qmList.isEmpty())
|
|
return;
|
|
|
|
foreach(const ::Murmur::MetaCallbackPrx &prx, qmList) {
|
|
try {
|
|
prx->stopped(idToProxy(s->iServerNum, adapter));
|
|
} catch (...) {
|
|
badMetaProxy(prx);
|
|
}
|
|
}
|
|
}
|
|
|
|
void MurmurIce::userConnected(const ::User *p) {
|
|
::Server *s = qobject_cast< ::Server *> (sender());
|
|
|
|
const QList< ::Murmur::ServerCallbackPrx> &qmList = qmServerCallbacks[s->iServerNum];
|
|
|
|
if (qmList.isEmpty())
|
|
return;
|
|
|
|
::Murmur::User mp;
|
|
userToUser(p, mp);
|
|
|
|
foreach(const ::Murmur::ServerCallbackPrx &prx, qmList) {
|
|
try {
|
|
prx->userConnected(mp);
|
|
} catch (...) {
|
|
badServerProxy(prx, s->iServerNum);
|
|
}
|
|
}
|
|
}
|
|
|
|
void MurmurIce::userDisconnected(const ::User *p) {
|
|
::Server *s = qobject_cast< ::Server *> (sender());
|
|
|
|
mi->qmServerContextCallbacks[s->iServerNum].remove(p->uiSession);
|
|
|
|
const QList< ::Murmur::ServerCallbackPrx> &qmList = qmServerCallbacks[s->iServerNum];
|
|
|
|
if (qmList.isEmpty())
|
|
return;
|
|
|
|
::Murmur::User mp;
|
|
userToUser(p, mp);
|
|
|
|
foreach(const ::Murmur::ServerCallbackPrx &prx, qmList) {
|
|
try {
|
|
prx->userDisconnected(mp);
|
|
} catch (...) {
|
|
badServerProxy(prx, s->iServerNum);
|
|
}
|
|
}
|
|
}
|
|
|
|
void MurmurIce::userStateChanged(const ::User *p) {
|
|
::Server *s = qobject_cast< ::Server *> (sender());
|
|
|
|
const QList< ::Murmur::ServerCallbackPrx> &qmList = qmServerCallbacks[s->iServerNum];
|
|
|
|
if (qmList.isEmpty())
|
|
return;
|
|
|
|
::Murmur::User mp;
|
|
userToUser(p, mp);
|
|
|
|
foreach(const ::Murmur::ServerCallbackPrx &prx, qmList) {
|
|
try {
|
|
prx->userStateChanged(mp);
|
|
} catch (...) {
|
|
badServerProxy(prx, s->iServerNum);
|
|
}
|
|
}
|
|
}
|
|
|
|
void MurmurIce::userTextMessage(const ::User *p, const ::TextMessage &message) {
|
|
::Server *s = qobject_cast< ::Server *> (sender());
|
|
|
|
const QList< ::Murmur::ServerCallbackPrx> &qmList = qmServerCallbacks[s->iServerNum];
|
|
|
|
if (qmList.isEmpty())
|
|
return;
|
|
|
|
::Murmur::User mp;
|
|
userToUser(p, mp);
|
|
|
|
::Murmur::TextMessage textMessage;
|
|
textmessageToTextmessage(message, textMessage);
|
|
|
|
foreach(const ::Murmur::ServerCallbackPrx &prx, qmList) {
|
|
try {
|
|
prx->userTextMessage(mp, textMessage);
|
|
} catch (...) {
|
|
badServerProxy(prx, s->iServerNum);
|
|
}
|
|
}
|
|
}
|
|
|
|
void MurmurIce::channelCreated(const ::Channel *c) {
|
|
::Server *s = qobject_cast< ::Server *> (sender());
|
|
|
|
const QList< ::Murmur::ServerCallbackPrx> &qmList = qmServerCallbacks[s->iServerNum];
|
|
|
|
if (qmList.isEmpty())
|
|
return;
|
|
|
|
::Murmur::Channel mc;
|
|
channelToChannel(c, mc);
|
|
|
|
foreach(const ::Murmur::ServerCallbackPrx &prx, qmList) {
|
|
try {
|
|
prx->channelCreated(mc);
|
|
} catch (...) {
|
|
badServerProxy(prx, s->iServerNum);
|
|
}
|
|
}
|
|
}
|
|
|
|
void MurmurIce::channelRemoved(const ::Channel *c) {
|
|
::Server *s = qobject_cast< ::Server *> (sender());
|
|
|
|
const QList< ::Murmur::ServerCallbackPrx> &qmList = qmServerCallbacks[s->iServerNum];
|
|
|
|
if (qmList.isEmpty())
|
|
return;
|
|
|
|
::Murmur::Channel mc;
|
|
channelToChannel(c, mc);
|
|
|
|
foreach(const ::Murmur::ServerCallbackPrx &prx, qmList) {
|
|
try {
|
|
prx->channelRemoved(mc);
|
|
} catch (...) {
|
|
badServerProxy(prx, s->iServerNum);
|
|
}
|
|
}
|
|
}
|
|
|
|
void MurmurIce::channelStateChanged(const ::Channel *c) {
|
|
::Server *s = qobject_cast< ::Server *> (sender());
|
|
|
|
const QList< ::Murmur::ServerCallbackPrx> &qmList = qmServerCallbacks[s->iServerNum];
|
|
|
|
if (qmList.isEmpty())
|
|
return;
|
|
|
|
::Murmur::Channel mc;
|
|
channelToChannel(c, mc);
|
|
|
|
foreach(const ::Murmur::ServerCallbackPrx &prx, qmList) {
|
|
try {
|
|
prx->channelStateChanged(mc);
|
|
} catch (...) {
|
|
badServerProxy(prx, s->iServerNum);
|
|
}
|
|
}
|
|
}
|
|
|
|
void MurmurIce::contextAction(const ::User *pSrc, const QString &action, unsigned int session, int iChannel) {
|
|
::Server *s = qobject_cast< ::Server *> (sender());
|
|
|
|
QMap<int, QMap<int, QMap<QString, ::Murmur::ServerContextCallbackPrx> > > &qmAll = mi->qmServerContextCallbacks;
|
|
if (! qmAll.contains(s->iServerNum))
|
|
return;
|
|
|
|
QMap<int, QMap<QString, ::Murmur::ServerContextCallbackPrx> > &qmServer = qmAll[s->iServerNum];
|
|
if (! qmServer.contains(pSrc->uiSession))
|
|
return;
|
|
|
|
QMap<QString, ::Murmur::ServerContextCallbackPrx> &qmUser = qmServer[pSrc->uiSession];
|
|
if (! qmUser.contains(action))
|
|
return;
|
|
|
|
const ::Murmur::ServerContextCallbackPrx &prx = qmUser[action];
|
|
|
|
::Murmur::User mp;
|
|
userToUser(pSrc, mp);
|
|
|
|
try {
|
|
prx->contextAction(u8(action), mp, session, iChannel);
|
|
} catch (...) {
|
|
qCritical("Registered Ice ServerContextCallback %s on server %d, session %d, action %s failed", qPrintable(QString::fromStdString(communicator->proxyToString(prx))), s->iServerNum, pSrc->uiSession, qPrintable(action));
|
|
qmUser.remove(action);
|
|
|
|
// Remove clientside entry
|
|
MumbleProto::ContextActionModify mpcam;
|
|
mpcam.set_action(u8(action));
|
|
mpcam.set_operation(MumbleProto::ContextActionModify_Operation_Remove);
|
|
ServerUser *su = s->qhUsers.value(session);
|
|
if (su)
|
|
s->sendMessage(su, mpcam);
|
|
}
|
|
}
|
|
|
|
void MurmurIce::idToNameSlot(QString &name, int id) {
|
|
::Server *server = qobject_cast< ::Server *> (sender());
|
|
|
|
ServerAuthenticatorPrx prx = mi->qmServerAuthenticator.value(server->iServerNum);
|
|
try {
|
|
name = u8(prx->idToName(id));
|
|
} catch (...) {
|
|
badAuthenticator(server);
|
|
}
|
|
}
|
|
void MurmurIce::idToTextureSlot(QByteArray &qba, int id) {
|
|
::Server *server = qobject_cast< ::Server *> (sender());
|
|
|
|
ServerAuthenticatorPrx prx = mi->qmServerAuthenticator.value(server->iServerNum);
|
|
try {
|
|
const ::Murmur::Texture &tex = prx->idToTexture(id);
|
|
|
|
qba.resize(static_cast<int>(tex.size()));
|
|
char *ptr = qba.data();
|
|
for (unsigned int i=0;i<tex.size();++i)
|
|
ptr[i] = tex[i];
|
|
} catch (...) {
|
|
badAuthenticator(server);
|
|
}
|
|
}
|
|
|
|
void MurmurIce::nameToIdSlot(int &id, const QString &name) {
|
|
::Server *server = qobject_cast< ::Server *> (sender());
|
|
|
|
ServerAuthenticatorPrx prx = mi->qmServerAuthenticator.value(server->iServerNum);
|
|
try {
|
|
id = prx->nameToId(u8(name));
|
|
} catch (...) {
|
|
badAuthenticator(server);
|
|
}
|
|
}
|
|
|
|
void MurmurIce::authenticateSlot(int &res, QString &uname, const QList<QSslCertificate> &certlist, const QString &certhash, bool certstrong, const QString &pw) {
|
|
::Server *server = qobject_cast< ::Server *> (sender());
|
|
|
|
ServerAuthenticatorPrx prx = mi->qmServerAuthenticator.value(server->iServerNum);
|
|
::std::string newname;
|
|
::Murmur::GroupNameList groups;
|
|
::Murmur::CertificateList certs;
|
|
|
|
certs.resize(certlist.size());
|
|
for (int i=0;i<certlist.size();++i) {
|
|
::Murmur::CertificateDer der;
|
|
QByteArray qba = certlist.at(i).toDer();
|
|
der.resize(qba.size());
|
|
const char *ptr = qba.constData();
|
|
for (int j=0;j<qba.size();++j)
|
|
der[j] = ptr[j];
|
|
certs[i] = der;
|
|
}
|
|
|
|
try {
|
|
res = prx->authenticate(u8(uname), u8(pw), certs, u8(certhash), certstrong, newname, groups);
|
|
} catch (...) {
|
|
badAuthenticator(server);
|
|
}
|
|
if (res >= 0) {
|
|
if (newname.length() > 0)
|
|
uname = u8(newname);
|
|
QStringList qsl;
|
|
foreach(const ::std::string &str, groups) {
|
|
qsl << u8(str);
|
|
}
|
|
if (! qsl.isEmpty())
|
|
server->setTempGroups(res, NULL, qsl);
|
|
}
|
|
}
|
|
|
|
void MurmurIce::registerUserSlot(int &res, const QMap<int, QString> &info) {
|
|
::Server *server = qobject_cast< ::Server *> (sender());
|
|
|
|
ServerUpdatingAuthenticatorPrx prx = mi->qmServerUpdatingAuthenticator.value(server->iServerNum);
|
|
if (! prx)
|
|
return;
|
|
|
|
::Murmur::UserInfoMap im;
|
|
|
|
infoToInfo(info, im);
|
|
try {
|
|
res = prx->registerUser(im);
|
|
} catch (...) {
|
|
badAuthenticator(server);
|
|
}
|
|
}
|
|
|
|
void MurmurIce::unregisterUserSlot(int &res, int id) {
|
|
::Server *server = qobject_cast< ::Server *> (sender());
|
|
|
|
ServerUpdatingAuthenticatorPrx prx = mi->qmServerUpdatingAuthenticator.value(server->iServerNum);
|
|
if (! prx)
|
|
return;
|
|
try {
|
|
res = prx->unregisterUser(id);
|
|
} catch (...) {
|
|
badAuthenticator(server);
|
|
}
|
|
}
|
|
|
|
void MurmurIce::getRegistrationSlot(int &res, int id, QMap<int, QString> &info) {
|
|
::Server *server = qobject_cast< ::Server *> (sender());
|
|
|
|
ServerUpdatingAuthenticatorPrx prx = mi->qmServerUpdatingAuthenticator.value(server->iServerNum);
|
|
if (! prx)
|
|
return;
|
|
|
|
Murmur::UserInfoMap im;
|
|
try {
|
|
if (prx->getInfo(id, im)) {
|
|
res = 1;
|
|
infoToInfo(im, info);
|
|
}
|
|
} catch (...) {
|
|
badAuthenticator(server);
|
|
return;
|
|
}
|
|
}
|
|
|
|
void MurmurIce::getRegisteredUsersSlot(const QString &filter, QMap<int, QString> &m) {
|
|
::Server *server = qobject_cast< ::Server *> (sender());
|
|
|
|
ServerUpdatingAuthenticatorPrx prx = mi->qmServerUpdatingAuthenticator.value(server->iServerNum);
|
|
if (! prx)
|
|
return;
|
|
|
|
::Murmur::NameMap lst;
|
|
|
|
try {
|
|
lst = prx->getRegisteredUsers(u8(filter));
|
|
} catch (...) {
|
|
badAuthenticator(server);
|
|
return;
|
|
}
|
|
::Murmur::NameMap::const_iterator i;
|
|
for (i=lst.begin(); i != lst.end(); ++i)
|
|
m.insert((*i).first, u8((*i).second));
|
|
}
|
|
|
|
void MurmurIce::setInfoSlot(int &res, int id, const QMap<int, QString> &info) {
|
|
::Server *server = qobject_cast< ::Server *> (sender());
|
|
|
|
ServerUpdatingAuthenticatorPrx prx = mi->qmServerUpdatingAuthenticator.value(server->iServerNum);
|
|
if (! prx)
|
|
return;
|
|
|
|
Murmur::UserInfoMap im;
|
|
infoToInfo(info, im);
|
|
|
|
try {
|
|
res = prx->setInfo(id, im);
|
|
} catch (...) {
|
|
badAuthenticator(server);
|
|
}
|
|
}
|
|
|
|
void MurmurIce::setTextureSlot(int &res, int id, const QByteArray &texture) {
|
|
::Server *server = qobject_cast< ::Server *> (sender());
|
|
|
|
ServerUpdatingAuthenticatorPrx prx = mi->qmServerUpdatingAuthenticator.value(server->iServerNum);
|
|
if (! prx)
|
|
return;
|
|
|
|
::Murmur::Texture tex;
|
|
tex.resize(texture.size());
|
|
const char *ptr = texture.constData();
|
|
for (int i=0;i<texture.size();++i)
|
|
tex[i] = ptr[i];
|
|
|
|
try {
|
|
res = prx->setTexture(id, tex);
|
|
} catch (...) {
|
|
badAuthenticator(server);
|
|
}
|
|
}
|
|
|
|
Ice::ObjectPtr ServerLocator::locate(const Ice::Current &, Ice::LocalObjectPtr &) {
|
|
return iopServer;
|
|
}
|
|
|
|
#define FIND_SERVER \
|
|
::Server *server = meta->qhServers.value(server_id);
|
|
|
|
#define NEED_SERVER_EXISTS \
|
|
FIND_SERVER \
|
|
if (!server && ! ServerDB::serverExists(server_id)) { \
|
|
cb->ice_exception(::Ice::ObjectNotExistException(__FILE__,__LINE__)); \
|
|
return; \
|
|
}
|
|
|
|
#define NEED_SERVER \
|
|
NEED_SERVER_EXISTS \
|
|
if (! server) { \
|
|
cb->ice_exception(ServerBootedException()); \
|
|
return; \
|
|
}
|
|
|
|
#define NEED_PLAYER \
|
|
ServerUser *user = server->qhUsers.value(session); \
|
|
if (!user) { \
|
|
cb->ice_exception(::Murmur::InvalidSessionException()); \
|
|
return; \
|
|
}
|
|
|
|
#define NEED_CHANNEL_VAR(x,y) \
|
|
x = server->qhChannels.value(y); \
|
|
if (!x) { \
|
|
cb->ice_exception(::Murmur::InvalidChannelException()); \
|
|
return; \
|
|
}
|
|
|
|
#define NEED_CHANNEL \
|
|
::Channel *channel; \
|
|
NEED_CHANNEL_VAR(channel, channelid);
|
|
|
|
void ServerI::ice_ping(const Ice::Current ¤t) const {
|
|
// This is executed in the ice thread.
|
|
int server_id = u8(current.id.name).toInt();
|
|
if (! ServerDB::serverExists(server_id))
|
|
throw ::Ice::ObjectNotExistException(__FILE__, __LINE__);
|
|
}
|
|
|
|
#define ACCESS_Server_isRunning_READ
|
|
static void impl_Server_isRunning(const ::Murmur::AMD_Server_isRunningPtr cb, int server_id) {
|
|
NEED_SERVER_EXISTS;
|
|
cb->ice_response(server != NULL);
|
|
}
|
|
|
|
static void impl_Server_start(const ::Murmur::AMD_Server_startPtr cb, int server_id) {
|
|
NEED_SERVER_EXISTS;
|
|
if (server)
|
|
cb->ice_exception(ServerBootedException());
|
|
else if (! meta->boot(server_id))
|
|
cb->ice_exception(ServerFailureException());
|
|
else
|
|
cb->ice_response();
|
|
}
|
|
|
|
static void impl_Server_stop(const ::Murmur::AMD_Server_stopPtr cb, int server_id) {
|
|
NEED_SERVER;
|
|
meta->kill(server_id);
|
|
cb->ice_response();
|
|
}
|
|
|
|
static void impl_Server_delete(const ::Murmur::AMD_Server_deletePtr cb, int server_id) {
|
|
NEED_SERVER_EXISTS;
|
|
if (server) {
|
|
cb->ice_exception(ServerBootedException());
|
|
return;
|
|
}
|
|
ServerDB::deleteServer(server_id);
|
|
cb->ice_response();
|
|
}
|
|
|
|
static void impl_Server_addCallback(const Murmur::AMD_Server_addCallbackPtr cb, int server_id, const Murmur::ServerCallbackPrx& cbptr) {
|
|
NEED_SERVER;
|
|
QList< ::Murmur::ServerCallbackPrx> &qmList = mi->qmServerCallbacks[server_id];
|
|
|
|
try {
|
|
const Murmur::ServerCallbackPrx &oneway = Murmur::ServerCallbackPrx::checkedCast(cbptr->ice_oneway()->ice_connectionCached(false));
|
|
if (! qmList.contains(oneway))
|
|
qmList.append(oneway);
|
|
cb->ice_response();
|
|
} catch (...) {
|
|
cb->ice_exception(InvalidCallbackException());
|
|
}
|
|
}
|
|
|
|
static void impl_Server_removeCallback(const Murmur::AMD_Server_removeCallbackPtr cb, int server_id, const Murmur::ServerCallbackPrx& cbptr) {
|
|
NEED_SERVER;
|
|
QList< ::Murmur::ServerCallbackPrx> &qmList = mi->qmServerCallbacks[server_id];
|
|
|
|
try {
|
|
const Murmur::ServerCallbackPrx &oneway = Murmur::ServerCallbackPrx::uncheckedCast(cbptr->ice_oneway()->ice_connectionCached(false));
|
|
qmList.removeAll(oneway);
|
|
cb->ice_response();
|
|
} catch (...) {
|
|
cb->ice_exception(InvalidCallbackException());
|
|
}
|
|
}
|
|
|
|
static void impl_Server_setAuthenticator(const ::Murmur::AMD_Server_setAuthenticatorPtr& cb, int server_id, const ::Murmur::ServerAuthenticatorPrx &aptr) {
|
|
NEED_SERVER;
|
|
|
|
if (mi->qmServerAuthenticator[server_id])
|
|
server->disconnectAuthenticator(mi);
|
|
|
|
::Murmur::ServerAuthenticatorPrx prx;
|
|
|
|
try {
|
|
prx = ::Murmur::ServerAuthenticatorPrx::checkedCast(aptr->ice_connectionCached(false)->ice_timeout(5000));
|
|
const ::Murmur::ServerUpdatingAuthenticatorPrx uprx = ::Murmur::ServerUpdatingAuthenticatorPrx::checkedCast(prx);
|
|
|
|
mi->qmServerAuthenticator[server_id] = prx;
|
|
if (uprx)
|
|
mi->qmServerUpdatingAuthenticator[server_id] = uprx;
|
|
} catch (...) {
|
|
cb->ice_exception(InvalidCallbackException());
|
|
return;
|
|
}
|
|
|
|
if (prx)
|
|
server->connectAuthenticator(mi);
|
|
|
|
cb->ice_response();
|
|
|
|
server->log(QString("Registered Ice Authenticator %1").arg(QString::fromStdString(mi->communicator->proxyToString(aptr))));
|
|
}
|
|
|
|
#define ACCESS_Server_id_READ
|
|
static void impl_Server_id(const ::Murmur::AMD_Server_idPtr cb, int server_id) {
|
|
NEED_SERVER_EXISTS;
|
|
cb->ice_response(server_id);
|
|
}
|
|
|
|
#define ACCESS_Server_getConf_READ
|
|
static void impl_Server_getConf(const ::Murmur::AMD_Server_getConfPtr cb, int server_id, const ::std::string& key) {
|
|
NEED_SERVER_EXISTS;
|
|
cb->ice_response(u8(ServerDB::getConf(server_id, u8(key)).toString()));
|
|
}
|
|
|
|
#define ACCESS_Server_getAllConf_READ
|
|
static void impl_Server_getAllConf(const ::Murmur::AMD_Server_getAllConfPtr cb, int server_id) {
|
|
NEED_SERVER_EXISTS;
|
|
|
|
::Murmur::ConfigMap cm;
|
|
|
|
QMap<QString, QString> values = ServerDB::getAllConf(server_id);
|
|
QMap<QString, QString>::const_iterator i;
|
|
for (i=values.constBegin();i != values.constEnd(); ++i) {
|
|
cm[u8(i.key())] = u8(i.value());
|
|
}
|
|
cb->ice_response(cm);
|
|
}
|
|
|
|
static void impl_Server_setConf(const ::Murmur::AMD_Server_setConfPtr cb, int server_id, const ::std::string& key, const ::std::string& value) {
|
|
NEED_SERVER_EXISTS;
|
|
QString k=u8(key);
|
|
QString v=u8(value);
|
|
ServerDB::setConf(server_id, k, v);
|
|
if (server)
|
|
server->setLiveConf(k, v);
|
|
cb->ice_response();
|
|
}
|
|
|
|
static void impl_Server_setSuperuserPassword(const ::Murmur::AMD_Server_setSuperuserPasswordPtr cb, int server_id, const ::std::string& pw) {
|
|
NEED_SERVER_EXISTS;
|
|
ServerDB::setSUPW(server_id, u8(pw));
|
|
cb->ice_response();
|
|
}
|
|
|
|
#define ACCESS_Server_getLog_READ
|
|
static void impl_Server_getLog(const ::Murmur::AMD_Server_getLogPtr cb, int server_id, ::Ice::Int min, ::Ice::Int max) {
|
|
NEED_SERVER_EXISTS;
|
|
|
|
::Murmur::LogList ll;
|
|
|
|
QList<ServerDB::LogRecord> dblog = ServerDB::getLog(server_id, min, max);
|
|
foreach(const ServerDB::LogRecord &e, dblog) {
|
|
::Murmur::LogEntry le;
|
|
logToLog(e, le);
|
|
ll.push_back(le);
|
|
}
|
|
cb->ice_response(ll);
|
|
}
|
|
|
|
#define ACCESS_Server_getLogLen_READ
|
|
static void impl_Server_getLogLen(const ::Murmur::AMD_Server_getLogLenPtr cb, int server_id) {
|
|
NEED_SERVER_EXISTS;
|
|
|
|
int len = ServerDB::getLogLen(server_id);
|
|
cb->ice_response(len);
|
|
}
|
|
|
|
#define ACCESS_Server_getUsers_READ
|
|
static void impl_Server_getUsers(const ::Murmur::AMD_Server_getUsersPtr cb, int server_id) {
|
|
NEED_SERVER;
|
|
::Murmur::UserMap pm;
|
|
foreach(const ::User *p, server->qhUsers) {
|
|
::Murmur::User mp;
|
|
if (static_cast<const ServerUser *>(p)->sState == ::ServerUser::Authenticated) {
|
|
userToUser(p, mp);
|
|
pm[p->uiSession] = mp;
|
|
}
|
|
}
|
|
cb->ice_response(pm);
|
|
}
|
|
|
|
#define ACCESS_Server_getChannels_READ
|
|
static void impl_Server_getChannels(const ::Murmur::AMD_Server_getChannelsPtr cb, int server_id) {
|
|
NEED_SERVER;
|
|
::Murmur::ChannelMap cm;
|
|
foreach(const ::Channel *c, server->qhChannels) {
|
|
::Murmur::Channel mc;
|
|
channelToChannel(c, mc);
|
|
cm[c->iId] = mc;
|
|
}
|
|
cb->ice_response(cm);
|
|
}
|
|
|
|
static bool userSort(const ::User *a, const ::User *b) {
|
|
return ::User::lessThan(a, b);
|
|
}
|
|
|
|
static bool channelSort(const ::Channel *a, const ::Channel *b) {
|
|
return ::Channel::lessThan(a, b);
|
|
}
|
|
|
|
TreePtr recurseTree(const ::Channel *c) {
|
|
TreePtr t = new Tree();
|
|
channelToChannel(c, t->c);
|
|
QList< ::User *> users = c->qlUsers;
|
|
qSort(users.begin(), users.end(), userSort);
|
|
|
|
foreach(const ::User *p, users) {
|
|
::Murmur::User mp;
|
|
userToUser(p, mp);
|
|
t->users.push_back(mp);
|
|
}
|
|
|
|
QList< ::Channel *> channels = c->qlChannels;
|
|
qSort(channels.begin(), channels.end(), channelSort);
|
|
|
|
foreach(const ::Channel *chn, channels) {
|
|
t->children.push_back(recurseTree(chn));
|
|
}
|
|
|
|
return t;
|
|
}
|
|
|
|
#define ACCESS_Server_getTree_READ
|
|
static void impl_Server_getTree(const ::Murmur::AMD_Server_getTreePtr cb, int server_id) {
|
|
NEED_SERVER;
|
|
cb->ice_response(recurseTree(server->qhChannels.value(0)));
|
|
}
|
|
|
|
#define ACCESS_Server_getCertificateList_READ
|
|
static void impl_Server_getCertificateList(const ::Murmur::AMD_Server_getCertificateListPtr cb, int server_id, ::Ice::Int session) {
|
|
NEED_SERVER;
|
|
NEED_PLAYER;
|
|
|
|
::Murmur::CertificateList certs;
|
|
|
|
const QList<QSslCertificate> &certlist = user->peerCertificateChain();
|
|
|
|
certs.resize(certlist.size());
|
|
for (int i=0;i<certlist.size();++i) {
|
|
::Murmur::CertificateDer der;
|
|
QByteArray qba = certlist.at(i).toDer();
|
|
der.resize(qba.size());
|
|
const char *ptr = qba.constData();
|
|
for (int j=0;j<qba.size();++j)
|
|
der[j] = ptr[j];
|
|
certs[i] = der;
|
|
}
|
|
cb->ice_response(certs);
|
|
}
|
|
|
|
#define ACCESS_Server_getBans_READ
|
|
static void impl_Server_getBans(const ::Murmur::AMD_Server_getBansPtr cb, int server_id) {
|
|
NEED_SERVER;
|
|
::Murmur::BanList bl;
|
|
foreach(const ::Ban &ban, server->qlBans) {
|
|
::Murmur::Ban mb;
|
|
banToBan(ban, mb);
|
|
bl.push_back(mb);
|
|
}
|
|
cb->ice_response(bl);
|
|
}
|
|
|
|
static void impl_Server_setBans(const ::Murmur::AMD_Server_setBansPtr cb, int server_id, const ::Murmur::BanList& bans) {
|
|
NEED_SERVER;
|
|
server->qlBans.clear();
|
|
foreach(const ::Murmur::Ban &mb, bans) {
|
|
::Ban ban;
|
|
banToBan(mb, ban);
|
|
server->qlBans << ban;
|
|
}
|
|
server->saveBans();
|
|
cb->ice_response();
|
|
}
|
|
|
|
static void impl_Server_kickUser(const ::Murmur::AMD_Server_kickUserPtr cb, int server_id, ::Ice::Int session, const ::std::string& reason) {
|
|
NEED_SERVER;
|
|
NEED_PLAYER;
|
|
|
|
MumbleProto::UserRemove mpur;
|
|
mpur.set_session(session);
|
|
mpur.set_reason(reason);
|
|
server->sendAll(mpur);
|
|
user->disconnectSocket();
|
|
cb->ice_response();
|
|
}
|
|
|
|
static void impl_Server_sendMessage(const ::Murmur::AMD_Server_sendMessagePtr cb, int server_id, ::Ice::Int session, const ::std::string &text) {
|
|
NEED_SERVER;
|
|
NEED_PLAYER;
|
|
|
|
server->sendTextMessage(NULL, user, false, u8(text));
|
|
cb->ice_response();
|
|
}
|
|
|
|
#define ACCESS_Server_hasPermission_READ
|
|
static void impl_Server_hasPermission(const ::Murmur::AMD_Server_hasPermissionPtr cb, int server_id, ::Ice::Int session, ::Ice::Int channelid, ::Ice::Int perm) {
|
|
NEED_SERVER;
|
|
NEED_PLAYER;
|
|
NEED_CHANNEL;
|
|
cb->ice_response(server->hasPermission(user, channel, static_cast<ChanACL::Perm>(perm)));
|
|
}
|
|
|
|
#define ACCESS_Server_effectivePermissions_READ
|
|
static void impl_Server_effectivePermissions(const ::Murmur::AMD_Server_effectivePermissionsPtr cb, int server_id, ::Ice::Int session, ::Ice::Int channelid) {
|
|
NEED_SERVER;
|
|
NEED_PLAYER;
|
|
NEED_CHANNEL;
|
|
cb->ice_response(server->effectivePermissions(user, channel));
|
|
}
|
|
|
|
static void impl_Server_addContextCallback(const Murmur::AMD_Server_addContextCallbackPtr cb, int server_id, ::Ice::Int session, const ::std::string& action, const ::std::string& text, const ::Murmur::ServerContextCallbackPrx& cbptr, int ctx) {
|
|
NEED_SERVER;
|
|
NEED_PLAYER;
|
|
|
|
QMap<QString, ::Murmur::ServerContextCallbackPrx> & qmPrx = mi->qmServerContextCallbacks[server_id][session];
|
|
|
|
if (!(ctx & (MumbleProto::ContextActionModify_Context_Server | MumbleProto::ContextActionModify_Context_Channel | MumbleProto::ContextActionModify_Context_User))) {
|
|
cb->ice_exception(InvalidCallbackException());
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const Murmur::ServerContextCallbackPrx &oneway = Murmur::ServerContextCallbackPrx::checkedCast(cbptr->ice_oneway()->ice_connectionCached(false)->ice_timeout(5000));
|
|
if (qmPrx.contains(u8(action))) {
|
|
// Since the server has no notion of the ctx part of the context action
|
|
// make sure we remove them all clientside when overriding an old callback
|
|
MumbleProto::ContextActionModify mpcam;
|
|
mpcam.set_action(action);
|
|
mpcam.set_operation(MumbleProto::ContextActionModify_Operation_Remove);
|
|
server->sendMessage(user, mpcam);
|
|
}
|
|
qmPrx.insert(u8(action), oneway);
|
|
cb->ice_response();
|
|
} catch (...) {
|
|
cb->ice_exception(InvalidCallbackException());
|
|
return;
|
|
}
|
|
|
|
MumbleProto::ContextActionModify mpcam;
|
|
mpcam.set_action(action);
|
|
mpcam.set_text(text);
|
|
mpcam.set_context(ctx);
|
|
mpcam.set_operation(MumbleProto::ContextActionModify_Operation_Add);
|
|
server->sendMessage(user, mpcam);
|
|
}
|
|
|
|
static void impl_Server_removeContextCallback(const Murmur::AMD_Server_removeContextCallbackPtr cb, int server_id, const Murmur::ServerContextCallbackPrx& cbptr) {
|
|
NEED_SERVER;
|
|
|
|
QMap<int, QMap<QString, ::Murmur::ServerContextCallbackPrx> > & qmPrx = mi->qmServerContextCallbacks[server_id];
|
|
|
|
try {
|
|
const Murmur::ServerContextCallbackPrx &oneway = Murmur::ServerContextCallbackPrx::uncheckedCast(cbptr->ice_oneway()->ice_connectionCached(false)->ice_timeout(5000));
|
|
|
|
foreach(int session, qmPrx.keys()) {
|
|
ServerUser *user = server->qhUsers.value(session);
|
|
QMap<QString, ::Murmur::ServerContextCallbackPrx> &qm = qmPrx[session];
|
|
foreach(const QString &act, qm.keys(oneway)) {
|
|
qm.remove(act);
|
|
|
|
// Ask clients to remove the clientside callbacks
|
|
if (user) {
|
|
MumbleProto::ContextActionModify mpcam;
|
|
mpcam.set_action(u8(act));
|
|
mpcam.set_operation(MumbleProto::ContextActionModify_Operation_Remove);
|
|
server->sendMessage(user, mpcam);
|
|
}
|
|
}
|
|
}
|
|
|
|
cb->ice_response();
|
|
} catch (...) {
|
|
cb->ice_exception(InvalidCallbackException());
|
|
}
|
|
}
|
|
|
|
#define ACCESS_Server_getState_READ
|
|
static void impl_Server_getState(const ::Murmur::AMD_Server_getStatePtr cb, int server_id, ::Ice::Int session) {
|
|
NEED_SERVER;
|
|
NEED_PLAYER;
|
|
|
|
::Murmur::User mp;
|
|
userToUser(user, mp);
|
|
cb->ice_response(mp);
|
|
}
|
|
|
|
static void impl_Server_setState(const ::Murmur::AMD_Server_setStatePtr cb, int server_id, const ::Murmur::User& state) {
|
|
int session = state.session;
|
|
::Channel *channel;
|
|
NEED_SERVER;
|
|
NEED_PLAYER;
|
|
NEED_CHANNEL_VAR(channel, state.channel);
|
|
|
|
server->setUserState(user, channel, state.mute, state.deaf, state.suppress, state.prioritySpeaker, u8(state.comment));
|
|
cb->ice_response();
|
|
}
|
|
|
|
static void impl_Server_sendMessageChannel(const ::Murmur::AMD_Server_sendMessageChannelPtr cb, int server_id, ::Ice::Int channelid, bool tree, const ::std::string &text) {
|
|
NEED_SERVER;
|
|
NEED_CHANNEL;
|
|
|
|
server->sendTextMessage(channel, NULL, tree, u8(text));
|
|
cb->ice_response();
|
|
}
|
|
|
|
#define ACCESS_Server_getChannelState_READ
|
|
static void impl_Server_getChannelState(const ::Murmur::AMD_Server_getChannelStatePtr cb, int server_id, ::Ice::Int channelid) {
|
|
NEED_SERVER;
|
|
NEED_CHANNEL;
|
|
|
|
::Murmur::Channel mc;
|
|
channelToChannel(channel, mc);
|
|
cb->ice_response(mc);
|
|
}
|
|
|
|
static void impl_Server_setChannelState(const ::Murmur::AMD_Server_setChannelStatePtr cb, int server_id, const ::Murmur::Channel& state) {
|
|
int channelid = state.id;
|
|
NEED_SERVER;
|
|
NEED_CHANNEL;
|
|
::Channel *np = NULL;
|
|
if (channel->iId != 0) {
|
|
NEED_CHANNEL_VAR(np, state.parent);
|
|
}
|
|
|
|
QString qsName = u8(state.name);
|
|
|
|
QSet< ::Channel *> newset;
|
|
foreach(int linkid, state.links) {
|
|
::Channel *cLink;
|
|
NEED_CHANNEL_VAR(cLink, linkid);
|
|
newset << cLink;
|
|
}
|
|
|
|
if (! server->setChannelState(channel, np, qsName, newset, u8(state.description), state.position))
|
|
cb->ice_exception(::Murmur::InvalidChannelException());
|
|
else
|
|
cb->ice_response();
|
|
}
|
|
|
|
static void impl_Server_removeChannel(const ::Murmur::AMD_Server_removeChannelPtr cb, int server_id, ::Ice::Int channelid) {
|
|
NEED_SERVER;
|
|
NEED_CHANNEL;
|
|
|
|
if (!channel->cParent) {
|
|
cb->ice_exception(::Murmur::InvalidChannelException());
|
|
} else {
|
|
server->removeChannel(channel);
|
|
cb->ice_response();
|
|
}
|
|
}
|
|
|
|
static void impl_Server_addChannel(const ::Murmur::AMD_Server_addChannelPtr cb, int server_id, const ::std::string& name, ::Ice::Int parent) {
|
|
NEED_SERVER;
|
|
::Channel *p, *nc;
|
|
NEED_CHANNEL_VAR(p, parent);
|
|
|
|
QString qsName = u8(name);
|
|
|
|
nc = server->addChannel(p, qsName);
|
|
server->updateChannel(nc);
|
|
int newid = nc->iId;
|
|
|
|
MumbleProto::ChannelState mpcs;
|
|
mpcs.set_channel_id(newid);
|
|
mpcs.set_parent(parent);
|
|
mpcs.set_name(name);
|
|
server->sendAll(mpcs);
|
|
|
|
cb->ice_response(newid);
|
|
}
|
|
|
|
#define ACCESS_Server_getACL_READ
|
|
static void impl_Server_getACL(const ::Murmur::AMD_Server_getACLPtr cb, int server_id, ::Ice::Int channelid) {
|
|
NEED_SERVER;
|
|
NEED_CHANNEL;
|
|
|
|
::Murmur::ACLList acls;
|
|
::Murmur::GroupList groups;
|
|
|
|
QStack< ::Channel *> chans;
|
|
::Channel *p;
|
|
ChanACL *acl;
|
|
p = channel;
|
|
while (p) {
|
|
chans.push(p);
|
|
if ((p == channel) || (p->bInheritACL))
|
|
p = p->cParent;
|
|
else
|
|
p = NULL;
|
|
}
|
|
|
|
bool inherit = channel->bInheritACL;
|
|
|
|
while (! chans.isEmpty()) {
|
|
p = chans.pop();
|
|
foreach(acl, p->qlACL) {
|
|
if ((p==channel) || (acl->bApplySubs)) {
|
|
::Murmur::ACL ma;
|
|
ACLtoACL(acl, ma);
|
|
if (p != channel)
|
|
ma.inherited = true;
|
|
acls.push_back(ma);
|
|
}
|
|
}
|
|
}
|
|
|
|
p = channel->cParent;
|
|
const QSet<QString> allnames = ::Group::groupNames(channel);
|
|
foreach(const QString &name, allnames) {
|
|
::Group *g = channel->qhGroups.value(name);
|
|
::Group *pg = p ? ::Group::getGroup(p, name) : NULL;
|
|
if (!g && ! pg)
|
|
continue;
|
|
::Murmur::Group mg;
|
|
groupToGroup(g ? g : pg, mg);
|
|
QSet<int> members;
|
|
if (pg)
|
|
members = pg->members();
|
|
if (g) {
|
|
mg.add = g->qsAdd.toList().toVector().toStdVector();
|
|
mg.remove = g->qsRemove.toList().toVector().toStdVector();
|
|
mg.inherited = false;
|
|
members += g->qsAdd;
|
|
members -= g->qsRemove;
|
|
} else {
|
|
mg.inherited = true;
|
|
}
|
|
mg.members = members.toList().toVector().toStdVector();
|
|
groups.push_back(mg);
|
|
}
|
|
cb->ice_response(acls, groups, inherit);
|
|
}
|
|
|
|
static void impl_Server_setACL(const ::Murmur::AMD_Server_setACLPtr cb, int server_id, ::Ice::Int channelid, const ::Murmur::ACLList& acls, const ::Murmur::GroupList& groups, bool inherit) {
|
|
NEED_SERVER;
|
|
NEED_CHANNEL;
|
|
|
|
::Group *g;
|
|
ChanACL *acl;
|
|
|
|
QHash<QString, QSet<int> > hOldTemp;
|
|
foreach(g, channel->qhGroups) {
|
|
hOldTemp.insert(g->qsName, g->qsTemporary);
|
|
delete g;
|
|
}
|
|
foreach(acl, channel->qlACL)
|
|
delete acl;
|
|
|
|
channel->qhGroups.clear();
|
|
channel->qlACL.clear();
|
|
|
|
channel->bInheritACL = inherit;
|
|
foreach(const ::Murmur::Group &gi, groups) {
|
|
QString name = u8(gi.name);
|
|
g = new ::Group(channel, name);
|
|
g->bInherit = gi.inherit;
|
|
g->bInheritable = gi.inheritable;
|
|
g->qsAdd = QVector<int>::fromStdVector(gi.add).toList().toSet();
|
|
g->qsRemove = QVector<int>::fromStdVector(gi.remove).toList().toSet();
|
|
g->qsTemporary = hOldTemp.value(name);
|
|
}
|
|
foreach(const ::Murmur::ACL &ai, acls) {
|
|
acl = new ChanACL(channel);
|
|
acl->bApplyHere = ai.applyHere;
|
|
acl->bApplySubs = ai.applySubs;
|
|
acl->iUserId = ai.userid;
|
|
acl->qsGroup = u8(ai.group);
|
|
acl->pDeny = static_cast<ChanACL::Permissions>(ai.deny) & ChanACL::All;
|
|
acl->pAllow = static_cast<ChanACL::Permissions>(ai.allow) & ChanACL::All;
|
|
}
|
|
|
|
server->clearACLCache();
|
|
server->updateChannel(channel);
|
|
cb->ice_response();
|
|
}
|
|
|
|
#define ACCESS_Server_getUserNames_READ
|
|
static void impl_Server_getUserNames(const ::Murmur::AMD_Server_getUserNamesPtr cb, int server_id, const ::Murmur::IdList& ids) {
|
|
NEED_SERVER;
|
|
::Murmur::NameMap nm;
|
|
foreach(int userid, ids) {
|
|
nm[userid] = u8(server->getUserName(userid));
|
|
}
|
|
cb->ice_response(nm);
|
|
}
|
|
|
|
#define ACCESS_Server_getUserIds_READ
|
|
static void impl_Server_getUserIds(const ::Murmur::AMD_Server_getUserIdsPtr cb, int server_id, const ::Murmur::NameList& names) {
|
|
NEED_SERVER;
|
|
::Murmur::IdMap im;
|
|
foreach(const string &n, names) {
|
|
QString name = u8(n);
|
|
im[n] = server->getUserID(name);
|
|
}
|
|
cb->ice_response(im);
|
|
}
|
|
|
|
static void impl_Server_registerUser(const ::Murmur::AMD_Server_registerUserPtr cb, int server_id, const ::Murmur::UserInfoMap &im) {
|
|
NEED_SERVER;
|
|
|
|
QMap<int, QString> info;
|
|
infoToInfo(im, info);
|
|
|
|
int userid = server->registerUser(info);
|
|
if (userid < 0)
|
|
cb->ice_exception(InvalidUserException());
|
|
else
|
|
cb->ice_response(userid);
|
|
}
|
|
|
|
static void impl_Server_unregisterUser(const ::Murmur::AMD_Server_unregisterUserPtr cb, int server_id, ::Ice::Int userid) {
|
|
NEED_SERVER;
|
|
if (! server->unregisterUser(userid))
|
|
cb->ice_exception(InvalidUserException());
|
|
else
|
|
cb->ice_response();
|
|
}
|
|
|
|
static void impl_Server_updateRegistration(const ::Murmur::AMD_Server_updateRegistrationPtr cb, int server_id, int id, const ::Murmur::UserInfoMap &im) {
|
|
NEED_SERVER;
|
|
|
|
if (! server->isUserId(id)) {
|
|
cb->ice_exception(InvalidUserException());
|
|
return;
|
|
}
|
|
|
|
QMap<int, QString> info;
|
|
infoToInfo(im, info);
|
|
|
|
if (! server->setInfo(id, info)) {
|
|
cb->ice_exception(InvalidUserException());
|
|
return;
|
|
}
|
|
|
|
if (info.contains(ServerDB::User_Comment)) {
|
|
foreach(ServerUser *u, server->qhUsers) {
|
|
if (u->iId == id)
|
|
server->setUserState(u, u->cChannel, u->bMute, u->bDeaf, u->bSuppress, u->bPrioritySpeaker, info.value(ServerDB::User_Comment));
|
|
}
|
|
}
|
|
|
|
cb->ice_response();
|
|
}
|
|
|
|
#define ACCESS_Server_getRegistration_READ
|
|
static void impl_Server_getRegistration(const ::Murmur::AMD_Server_getRegistrationPtr cb, int server_id, ::Ice::Int userid) {
|
|
NEED_SERVER;
|
|
|
|
QMap<int, QString> info = server->getRegistration(userid);
|
|
|
|
if (info.isEmpty()) {
|
|
cb->ice_exception(InvalidUserException());
|
|
return;
|
|
}
|
|
|
|
Murmur::UserInfoMap im;
|
|
infoToInfo(info, im);
|
|
cb->ice_response(im);
|
|
}
|
|
|
|
#define ACCESS_Server_getRegisteredUsers_READ
|
|
static void impl_Server_getRegisteredUsers(const ::Murmur::AMD_Server_getRegisteredUsersPtr cb, int server_id, const ::std::string& filter) {
|
|
NEED_SERVER;
|
|
Murmur::NameMap rpl;
|
|
|
|
const QMap<int, QString> l = server->getRegisteredUsers(u8(filter));
|
|
QMap<int, QString>::const_iterator i;
|
|
for (i = l.constBegin(); i != l.constEnd(); ++i) {
|
|
rpl[i.key()] = u8(i.value());
|
|
}
|
|
|
|
cb->ice_response(rpl);
|
|
}
|
|
|
|
#define ACCESS_Server_verifyPassword_READ
|
|
static void impl_Server_verifyPassword(const ::Murmur::AMD_Server_verifyPasswordPtr cb, int server_id, const ::std::string& name, const ::std::string& pw) {
|
|
NEED_SERVER;
|
|
QString uname = u8(name);
|
|
cb->ice_response(server->authenticate(uname, u8(pw)));
|
|
}
|
|
|
|
#define ACCESS_Server_getTexture_READ
|
|
static void impl_Server_getTexture(const ::Murmur::AMD_Server_getTexturePtr cb, int server_id, ::Ice::Int userid) {
|
|
NEED_SERVER;
|
|
|
|
if (! server->isUserId(userid)) {
|
|
cb->ice_exception(InvalidUserException());
|
|
return;
|
|
}
|
|
|
|
const QByteArray &qba = server->getUserTexture(userid);
|
|
|
|
::Murmur::Texture tex;
|
|
tex.resize(qba.size());
|
|
const char *ptr = qba.constData();
|
|
for (int i=0;i<qba.size();++i)
|
|
tex[i] = ptr[i];
|
|
|
|
cb->ice_response(tex);
|
|
}
|
|
|
|
static void impl_Server_setTexture(const ::Murmur::AMD_Server_setTexturePtr cb, int server_id, ::Ice::Int userid, const ::Murmur::Texture& tex) {
|
|
NEED_SERVER;
|
|
|
|
if (! server->isUserId(userid)) {
|
|
cb->ice_exception(InvalidUserException());
|
|
return;
|
|
}
|
|
|
|
QByteArray qba(static_cast<int>(tex.size()), 0);
|
|
char *ptr = qba.data();
|
|
for (unsigned int i=0;i<tex.size();++i)
|
|
ptr[i] = tex[i];
|
|
if (! server->setTexture(userid, qba)) {
|
|
cb->ice_exception(InvalidTextureException());
|
|
} else {
|
|
ServerUser *user = server->qhUsers.value(userid);
|
|
if (user) {
|
|
MumbleProto::UserState mpus;
|
|
mpus.set_session(user->uiSession);
|
|
mpus.set_texture(blob(user->qbaTexture));
|
|
|
|
server->sendAll(mpus, ~0x010202);
|
|
if (! user->qbaTextureHash.isEmpty()) {
|
|
mpus.clear_texture();
|
|
mpus.set_texture_hash(blob(user->qbaTextureHash));
|
|
}
|
|
server->sendAll(mpus, 0x010202);
|
|
}
|
|
|
|
cb->ice_response();
|
|
}
|
|
}
|
|
|
|
#define ACCESS_Server_getUptime_READ
|
|
static void impl_Server_getUptime(const ::Murmur::AMD_Server_getUptimePtr cb, int server_id) {
|
|
NEED_SERVER;
|
|
cb->ice_response(static_cast<int>(server->tUptime.elapsed()/1000000LL));
|
|
}
|
|
|
|
static void impl_Server_addUserToGroup(const ::Murmur::AMD_Server_addUserToGroupPtr cb, int server_id, ::Ice::Int channelid, ::Ice::Int session, const ::std::string& group) {
|
|
NEED_SERVER;
|
|
NEED_PLAYER;
|
|
NEED_CHANNEL;
|
|
|
|
QString qsgroup = u8(group);
|
|
if (qsgroup.isEmpty()) {
|
|
cb->ice_exception(InvalidChannelException());
|
|
return;
|
|
}
|
|
|
|
::Group *g = channel->qhGroups.value(qsgroup);
|
|
if (! g)
|
|
g = new ::Group(channel, qsgroup);
|
|
|
|
g->qsTemporary.insert(- session);
|
|
server->clearACLCache(user);
|
|
|
|
cb->ice_response();
|
|
}
|
|
|
|
static void impl_Server_removeUserFromGroup(const ::Murmur::AMD_Server_removeUserFromGroupPtr cb, int server_id, ::Ice::Int channelid, ::Ice::Int session, const ::std::string& group) {
|
|
NEED_SERVER;
|
|
NEED_PLAYER;
|
|
NEED_CHANNEL;
|
|
|
|
QString qsgroup = u8(group);
|
|
if (qsgroup.isEmpty()) {
|
|
cb->ice_exception(InvalidChannelException());
|
|
return;
|
|
}
|
|
|
|
::Group *g = channel->qhGroups.value(qsgroup);
|
|
if (! g)
|
|
g = new ::Group(channel, qsgroup);
|
|
|
|
g->qsTemporary.remove(- session);
|
|
server->clearACLCache(user);
|
|
|
|
cb->ice_response();
|
|
}
|
|
|
|
static void impl_Server_redirectWhisperGroup(const ::Murmur::AMD_Server_redirectWhisperGroupPtr cb, int server_id, ::Ice::Int session, const ::std::string& source, const ::std::string& target) {
|
|
NEED_SERVER;
|
|
NEED_PLAYER;
|
|
|
|
QString qssource = u8(source);
|
|
QString qstarget = u8(target);
|
|
if (qstarget.isEmpty())
|
|
user->qmWhisperRedirect.remove(qssource);
|
|
else
|
|
user->qmWhisperRedirect.insert(qssource, qstarget);
|
|
|
|
server->clearACLCache(user);
|
|
|
|
cb->ice_response();
|
|
}
|
|
|
|
#define ACCESS_Meta_getSliceChecksums_ALL
|
|
static void impl_Meta_getSliceChecksums(const ::Murmur::AMD_Meta_getSliceChecksumsPtr cb, const Ice::ObjectAdapterPtr) {
|
|
cb->ice_response(::Ice::sliceChecksums());
|
|
}
|
|
|
|
#define ACCESS_Meta_getServer_READ
|
|
static void impl_Meta_getServer(const ::Murmur::AMD_Meta_getServerPtr cb, const Ice::ObjectAdapterPtr adapter, ::Ice::Int id) {
|
|
QList<int> server_list = ServerDB::getAllServers();
|
|
if (! server_list.contains(id))
|
|
cb->ice_response(NULL);
|
|
else
|
|
cb->ice_response(idToProxy(id, adapter));
|
|
}
|
|
|
|
static void impl_Meta_newServer(const ::Murmur::AMD_Meta_newServerPtr cb, const Ice::ObjectAdapterPtr adapter) {
|
|
cb->ice_response(idToProxy(ServerDB::addServer(), adapter));
|
|
}
|
|
|
|
#define ACCESS_Meta_getAllServers_READ
|
|
static void impl_Meta_getAllServers(const ::Murmur::AMD_Meta_getAllServersPtr cb, const Ice::ObjectAdapterPtr adapter) {
|
|
::Murmur::ServerList sl;
|
|
|
|
foreach(int id, ServerDB::getAllServers())
|
|
sl.push_back(idToProxy(id, adapter));
|
|
cb->ice_response(sl);
|
|
}
|
|
|
|
#define ACCESS_Meta_getDefaultConf_READ
|
|
static void impl_Meta_getDefaultConf(const ::Murmur::AMD_Meta_getDefaultConfPtr cb, const Ice::ObjectAdapterPtr) {
|
|
::Murmur::ConfigMap cm;
|
|
QMap<QString, QString>::const_iterator i;
|
|
for (i=meta->mp.qmConfig.constBegin();i != meta->mp.qmConfig.constEnd(); ++i) {
|
|
cm[u8(i.key())] = u8(i.value());
|
|
}
|
|
cb->ice_response(cm);
|
|
}
|
|
|
|
#define ACCESS_Meta_getBootedServers_READ
|
|
static void impl_Meta_getBootedServers(const ::Murmur::AMD_Meta_getBootedServersPtr cb, const Ice::ObjectAdapterPtr adapter) {
|
|
::Murmur::ServerList sl;
|
|
|
|
foreach(int id, meta->qhServers.keys())
|
|
sl.push_back(idToProxy(id, adapter));
|
|
cb->ice_response(sl);
|
|
}
|
|
|
|
#define ACCESS_Meta_getVersion_ALL
|
|
static void impl_Meta_getVersion(const ::Murmur::AMD_Meta_getVersionPtr cb, const Ice::ObjectAdapterPtr) {
|
|
int major, minor, patch;
|
|
QString txt;
|
|
::Meta::getVersion(major, minor, patch, txt);
|
|
cb->ice_response(major, minor, patch, u8(txt));
|
|
}
|
|
|
|
static void impl_Meta_addCallback(const Murmur::AMD_Meta_addCallbackPtr cb, const Ice::ObjectAdapterPtr, const Murmur::MetaCallbackPrx& cbptr) {
|
|
try {
|
|
const Murmur::MetaCallbackPrx &oneway = Murmur::MetaCallbackPrx::checkedCast(cbptr->ice_oneway()->ice_connectionCached(false)->ice_timeout(5000));
|
|
if (! mi->qmMetaCallbacks.contains(oneway))
|
|
mi->qmMetaCallbacks.append(oneway);
|
|
cb->ice_response();
|
|
} catch (...) {
|
|
cb->ice_exception(InvalidCallbackException());
|
|
}
|
|
}
|
|
|
|
static void impl_Meta_removeCallback(const Murmur::AMD_Meta_removeCallbackPtr cb, const Ice::ObjectAdapterPtr, const Murmur::MetaCallbackPrx& cbptr) {
|
|
try {
|
|
const Murmur::MetaCallbackPrx &oneway = Murmur::MetaCallbackPrx::uncheckedCast(cbptr->ice_oneway()->ice_connectionCached(false)->ice_timeout(5000));
|
|
mi->qmMetaCallbacks.removeAll(oneway);
|
|
cb->ice_response();
|
|
} catch (...) {
|
|
cb->ice_exception(InvalidCallbackException());
|
|
}
|
|
}
|
|
|
|
#define ACCESS_Meta_getUptime_ALL
|
|
static void impl_Meta_getUptime(const ::Murmur::AMD_Meta_getUptimePtr cb, const Ice::ObjectAdapterPtr) {
|
|
cb->ice_response(static_cast<int>(meta->tUptime.elapsed()/1000000LL));
|
|
}
|
|
|
|
#include "MurmurIceWrapper.cpp"
|