diff --git a/src/murmur/DBus.cpp b/src/murmur/DBus.cpp index d7580086a..8d1aaebee 100644 --- a/src/murmur/DBus.cpp +++ b/src/murmur/DBus.cpp @@ -523,7 +523,7 @@ void MurmurDBus::removeChannel(int id, const QDBusMessage &msg) { qdbc.send(msg.createErrorReply("net.sourceforge.mumble.Error.channel", "Invalid channel id")); return; } - server->removeChannel(cChannel, NULL); + server->removeChannel(cChannel); } void MurmurDBus::setChannelState(const ChannelInfo &nci, const QDBusMessage &msg) { @@ -540,7 +540,7 @@ void MurmurDBus::setChannelState(const ChannelInfo &nci, const QDBusMessage &msg newset << cLink; } - if (cParent != cChannel->cParent) { + if ((cParent != cChannel) && (cParent != cChannel->cParent)) { Channel *p = cParent; while (p) { diff --git a/src/murmur/Murmur.ice b/src/murmur/Murmur.ice index 48a4d5155..60a0982f4 100644 --- a/src/murmur/Murmur.ice +++ b/src/murmur/Murmur.ice @@ -92,6 +92,7 @@ module Murmur exception InvalidServerException extends MurmurException {}; exception ServerBootedException extends MurmurException {}; exception ServerFailureException extends MurmurException {}; + exception InvalidPlayerException extends MurmurException {}; interface Server { bool isRunning(); @@ -134,7 +135,7 @@ module Murmur void updateregistration(RegisteredPlayer registration); RegisteredPlayer getRegistration(int playerid); RegisteredPlayerList getRegisteredPlayers(string filter); - bool verifyPassword(int playerid, string pw); + int verifyPassword(string playerid, string pw); Texture getTexture(int playerid); void setTexture(int playerid, Texture tex); }; diff --git a/src/murmur/MurmurI.h b/src/murmur/MurmurI.h index 91e780e0e..c7f8cd954 100644 --- a/src/murmur/MurmurI.h +++ b/src/murmur/MurmurI.h @@ -103,7 +103,7 @@ public: virtual ::Murmur::RegisteredPlayerList getRegisteredPlayers(const ::std::string&, const Ice::Current&); - virtual bool verifyPassword(::Ice::Int, + virtual int verifyPassword(const ::std::string&, const ::std::string&, const Ice::Current&); diff --git a/src/murmur/MurmurIce.cpp b/src/murmur/MurmurIce.cpp index 6faf8b9ed..c5ec2b24f 100644 --- a/src/murmur/MurmurIce.cpp +++ b/src/murmur/MurmurIce.cpp @@ -1,3 +1,34 @@ +/* Copyright (C) 2005-2008, Thorvald Natvig + + 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 #include #include "Meta.h" @@ -43,7 +74,7 @@ class ServerLocator : public virtual Ice::ServantLocator { MurmurIce::MurmurIce() { communicator = Ice::initialize(); - Ice::ObjectAdapterPtr adapter = communicator->createObjectAdapterWithEndpoints("Murmur", "tcp -p 10000"); + Ice::ObjectAdapterPtr adapter = communicator->createObjectAdapterWithEndpoints("Murmur", "tcp -h 127.0.0.1 -p 10000"); MetaPtr m = new MetaI; adapter->add(m, communicator->stringToIdentity("Meta")); adapter->addServantLocator(new ServerLocator(), "s"); @@ -213,7 +244,7 @@ string ServerI::getConf(const string& key, const Ice::Current& current) { QMap values = ServerDB::getAllConf(server_id); QMap::const_iterator i; - for (i=meta->mp.qmConfig.constBegin();i != meta->mp.qmConfig.constEnd(); ++i) { + for (i=values.constBegin();i != values.constEnd(); ++i) { cm[i.key().toStdString()] = i.value().toStdString(); } return cm; @@ -354,50 +385,8 @@ void ServerI::setState(const ::Murmur::Player& state, const Ice::Current& curren NEED_SERVER; NEED_PLAYER; NEED_CHANNEL_VAR(channel, state.channel); - - ::Murmur::Player ps; - playerToPlayer(user, ps); - - bool changed = false; - bool deaf = state.deaf; - bool mute = state.mute; - if (deaf) - mute = true; - if (! mute) - deaf = false; - - if ((ps.deaf != deaf) && (deaf || (!deaf && mute))) { - user->bDeaf = deaf; - user->bMute = mute; - MessagePlayerDeaf mpd; - mpd.uiSession = 0; - mpd.uiVictim=user->uiSession; - mpd.bDeaf = deaf; - server->sendAll(&mpd); - changed = true; - } else if ((ps.deaf != deaf) || (ps.mute != mute)) { - user->bDeaf = deaf; - user->bMute = mute; - MessagePlayerMute mpm; - mpm.uiSession = 0; - mpm.uiVictim=user->uiSession; - mpm.bMute=mute; - server->sendAll(&mpm); - changed = true; - } - - if (channel->iId != ps.channel) { - server->playerEnterChannel(user, channel); - MessagePlayerMove mpm; - mpm.uiSession = 0; - mpm.uiVictim = user->uiSession; - mpm.iChannelId = channel->iId; - server->sendAll(&mpm); - changed = true; - } - - if (changed) - server->dbus->playerStateChanged(user); + + server->setPlayerState(user, channel, state.mute, state.deaf, state.suppressed); } ::Murmur::Channel ServerI::getChannelState(int channelid, const Ice::Current& current) { @@ -416,59 +405,268 @@ void ServerI::setChannelState(const ::Murmur::Channel& state, const Ice::Current ::Channel *np; NEED_CHANNEL_VAR(np, state.parent); - bool changed = false; - - // TODO + QSet< ::Channel *> newset; + foreach(int linkid, state.links) { + ::Channel *cLink; + NEED_CHANNEL_VAR(cLink, linkid); + newset << cLink; + } + + if (! server->setChannelState(channel, np, newset)) + throw ::Murmur::InvalidChannelException(); } void ServerI::removeChannel(int channelid, const Ice::Current& current) { + NEED_SERVER; + NEED_CHANNEL; + server->removeChannel(channel); } int ServerI::addChannel(const string& name, int parent, const Ice::Current& current) { - return 0; + NEED_SERVER; + ::Channel *p, *nc; + NEED_CHANNEL_VAR(p, parent); + + QString qsName = QString::fromStdString(name); + + nc = server->addChannel(p, qsName); + server->updateChannel(nc); + int newid = nc->iId; + + MessageChannelAdd mca; + mca.uiSession = 0; + mca.qsName = qsName; + mca.iParent = parent; + mca.iId = newid; + server->sendAll(&mca); + + return newid; } void ServerI::getACL(int channelid, ::Murmur::ACLList& acls, ::Murmur::GroupList& groups, bool& inherit, const Ice::Current& current) { + NEED_SERVER; + NEED_CHANNEL; + + acls.clear(); + groups.clear(); + + 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; + } + + 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 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 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); + } } void ServerI::setACL(int channelid, const ::Murmur::ACLList& acls, const ::Murmur::GroupList& groups, bool inherit, const Ice::Current& current) { + NEED_SERVER; + NEED_CHANNEL; + + ::Group *g; + ChanACL *acl; + + QHash > 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 = QString::fromStdString(gi.name); + g = new ::Group(channel, name); + g->bInherit = gi.inherit; + g->bInheritable = gi.inheritable; + g->qsAdd = QVector::fromStdVector(gi.add).toList().toSet(); + g->qsRemove = QVector::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->iPlayerId = ai.playerid; + acl->qsGroup = QString::fromStdString(ai.group); + acl->pDeny = static_cast(ai.deny); + acl->pAllow = static_cast(ai.allow); + } + server->clearACLCache(); + server->updateChannel(channel); } ::Murmur::NameMap ServerI::getPlayerNames(const ::Murmur::IdList& ids, const Ice::Current& current) { - return ::Murmur::NameMap(); + NEED_SERVER; + ::Murmur::NameMap nm; + foreach(int playerid, ids) { + if (! server->qhUserNameCache.contains(playerid)) { + QString name=server->getUserName(playerid); + if (! name.isEmpty()) + server->qhUserNameCache.insert(playerid, name); + } + nm[playerid] = server->qhUserNameCache.value(playerid).toStdString(); + } + return nm; } ::Murmur::IdMap ServerI::getPlayerIds(const ::Murmur::NameList& names, const Ice::Current& current) { - return ::Murmur::IdMap(); + NEED_SERVER; + ::Murmur::IdMap im; + foreach(const string &n, names) { + QString name = QString::fromStdString(n); + if (! server->qhUserIDCache.contains(name)) { + int playerid = server->getUserID(name); + if (playerid != -1) + server->qhUserIDCache.insert(name, playerid); + } + im[n] = server->qhUserIDCache.value(name); + } + return im; } int ServerI::registerPlayer(const string& name, const Ice::Current& current) { - return 0; + NEED_SERVER; + int playerid = server->registerPlayer(QString::fromStdString(name)); + if (playerid < 0) + throw InvalidPlayerException(); + return playerid; } void ServerI::unregisterPlayer(int playerid, const Ice::Current& current) { + NEED_SERVER; + if (! server->unregisterPlayer(playerid)) + throw InvalidPlayerException(); } void ServerI::updateregistration(const ::Murmur::RegisteredPlayer& registration, const Ice::Current& current) { + NEED_SERVER; + + QString name, email; + if (! server->getRegistration(registration.playerid, name, email)) + throw InvalidPlayerException(); + + QString newname = QString::fromStdString(registration.name); + QString newemail = QString::fromStdString(registration.email); + QString newpw = QString::fromStdString(registration.pw); + + if ((! newname.isEmpty()) && (newname != name)) + if (! server->setName(registration.playerid, newname)) + throw InvalidPlayerException(); + + if ((! newemail.isEmpty()) && (newemail != email)) + server->setEmail(registration.playerid, newemail); + + if ((! newpw.isEmpty())) + server->setPW(registration.playerid, newpw); } ::Murmur::RegisteredPlayer ServerI::getRegistration(int playerid, const Ice::Current& current) { - return ::Murmur::RegisteredPlayer(); + NEED_SERVER; + + QString name, email; + if (! server->getRegistration(playerid, name, email)) + throw InvalidPlayerException(); + + ::Murmur::RegisteredPlayer reg; + reg.playerid = playerid; + reg.name = name.toStdString(); + reg.email = email.toStdString(); + return reg; } ::Murmur::RegisteredPlayerList ServerI::getRegisteredPlayers(const string& filter, const Ice::Current& current) { - return ::Murmur::RegisteredPlayerList(); + NEED_SERVER; + Murmur::RegisteredPlayerList rpl; + Murmur::RegisteredPlayer reg; + + const QMap > l = server->getRegisteredPlayers(QString::fromStdString(filter)); + QMap >::const_iterator i; + for(i = l.constBegin(); i != l.constEnd(); ++i) { + reg.playerid = i.key(); + reg.name = i.value().first.toStdString(); + reg.email = i.value().second.toStdString(); + rpl.push_back(reg); + } + + return rpl; } -bool ServerI::verifyPassword(int playerid, const string& pw, const Ice::Current& current) { - return false; +int ServerI::verifyPassword(const string &name, const string& pw, const Ice::Current& current) { + NEED_SERVER; + QString uname = QString::fromStdString(name); + return server->authenticate(uname, QString::fromStdString(pw)); } ::Murmur::Texture ServerI::getTexture(int playerid, const Ice::Current& current) { - return ::Murmur::Texture(); + NEED_SERVER; + const QByteArray &qba = server->getUserTexture(playerid); + + ::Murmur::Texture tex; + tex.resize(qba.size()); + const char *ptr = qba.constData(); + for(int i=0;isetTexture(playerid, qba)) + throw InvalidPlayerException(); } ServerPrx MetaI::getServer(int id, const Ice::Current¤t) { @@ -504,7 +702,7 @@ ServerPrx MetaI::newServer(const Ice::Current& current) { return sl; } -::Murmur::ConfigMap MetaI::getDefaultConf(const Ice::Current& current) { +::Murmur::ConfigMap MetaI::getDefaultConf(const Ice::Current&) { ::Murmur::ConfigMap cm; QMap::const_iterator i; for (i=meta->mp.qmConfig.constBegin();i != meta->mp.qmConfig.constEnd(); ++i) { diff --git a/src/murmur/MurmurIce.h b/src/murmur/MurmurIce.h index 33ee93482..e1fddd954 100644 --- a/src/murmur/MurmurIce.h +++ b/src/murmur/MurmurIce.h @@ -1,3 +1,36 @@ +/* Copyright (C) 2005-2008, Thorvald Natvig + + 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 _MURMURICE_H +#define _MURMURICE_H + #include "murmur_pch.h" #include @@ -18,4 +51,4 @@ class MurmurIce : public QObject { MurmurIce(); ~MurmurIce(); }; - +#endif diff --git a/src/murmur/RPC.cpp b/src/murmur/RPC.cpp new file mode 100644 index 000000000..be53e20a1 --- /dev/null +++ b/src/murmur/RPC.cpp @@ -0,0 +1,135 @@ +/* Copyright (C) 2005-2008, Thorvald Natvig + + 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 "Server.h" + +void Server::setPlayerState(Player *pPlayer, Channel *cChannel, bool deaf, bool mute, bool suppressed) { + bool changed = false; + + 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; + } + + if (cChannel != pPlayer->cChannel) { + playerEnterChannel(pPlayer, cChannel); + MessagePlayerMove mpm; + mpm.uiSession = 0; + mpm.uiVictim = pPlayer->uiSession; + mpm.iChannelId = cChannel->iId; + sendAll(&mpm); + changed = true; + } + + emit playerStateChanged(pPlayer); +} + +bool Server::setChannelState(Channel *cChannel, Channel *cParent, const QSet &links) { + bool changed = false; + + if ((cParent != cChannel) && (cParent != cChannel->cParent)) { + Channel *p = cParent; + while (p) { + if (p == cChannel) + return false; + p = p->cParent; + } + + cChannel->cParent->removeChannel(cChannel); + cParent->addChannel(cChannel); + updateChannel(cChannel); + + MessageChannelMove mcm; + mcm.uiSession = 0; + mcm.iId = cChannel->iId; + mcm.iParent = cParent->iId; + sendAll(&mcm); + + changed = true; + } + + const QSet &oldset = cChannel->qsPermLinks; + + if (links != oldset) { + // Remove + 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); + } + } + + // Add + 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); + } + } + + changed = true; + } + + if (changed) + emit channelStateChanged(cChannel); +} diff --git a/src/murmur/Server.h b/src/murmur/Server.h index 8f5097e5f..0ac1e09a5 100644 --- a/src/murmur/Server.h +++ b/src/murmur/Server.h @@ -94,8 +94,14 @@ class User : public Connection, public Player { User(Server *parent, QSslSocket *socket); }; +class DBus; +namespace Murmur { + class ServerI; +}; class Server : public QThread, public MessageHandler { + friend class DBus; + friend class Murmur::ServerI; Q_OBJECT; // Former ServerParams @@ -198,12 +204,24 @@ class Server : public QThread, public MessageHandler { #endif void log(User *u, const char *format, ...); - void removeChannel(Channel *c, Player *src, Channel *dest = NULL); + void removeChannel(Channel *c, Player *src = NULL, Channel *dest = NULL); void playerEnterChannel(Player *u, Channel *c, bool quiet = false); Server(int snum, QObject *parent = NULL); ~Server(); + // RPC functions. Implementation in RPC.cpp + signals: + void playerStateChanged(const Player *); + void playerConnected(const Player *); + void playerDisconnected(const Player *); + void channelStateChanged(const Channel *); + void channelCreated(const Channel *); + void channelRemoved(const Channel *); + public: + void setPlayerState(Player *p, Channel *parent, bool deaf, bool mute, bool suppressed); + bool setChannelState(Channel *c, Channel *parent, const QSet &links); + // Database / DBus functions. Implementation in ServerDB.cpp void initialize(); typedef QPair qpBan; diff --git a/src/murmur/murmur.pro b/src/murmur/murmur.pro index 2864bb2bf..9e98f3f53 100644 --- a/src/murmur/murmur.pro +++ b/src/murmur/murmur.pro @@ -13,7 +13,7 @@ DBFILE = murmur.db LANGUAGE = C++ FORMS = HEADERS = Server.h Meta.h DBus.h -SOURCES = murmur.cpp Server.cpp ServerDB.cpp Register.cpp Cert.cpp Messages.cpp Meta.cpp DBus.cpp +SOURCES = murmur.cpp Server.cpp ServerDB.cpp Register.cpp Cert.cpp Messages.cpp Meta.cpp DBus.cpp RPC.cpp HEADERS += ../ACL.h ../Group.h ../Channel.h ../Connection.h ../Player.h SOURCES += ../ACL.cpp ../Group.cpp ../Channel.cpp ../Message.cpp ../Connection.cpp ../Player.cpp ../Timer.cpp ../CryptState.cpp