if (argTypes.size() >= 1 && argTypes[0] == qMetaTypeId<PeerPtr>() && proxy()->proxyMode() == SignalProxy::Server) {
Peer *peer = params[0].value<PeerPtr>();
proxy()->dispatch(peer, RpcCall(signal.signature, params));
+ } else if (proxy()->_restrictMessageTarget) {
+ for (auto peer : proxy()->_restrictedTargets) {
+ if (peer != nullptr)
+ proxy()->dispatch(peer, RpcCall(signal.signature, params));
+ }
} else
proxy()->dispatch(RpcCall(signal.signature, params));
}
return _peerMap[peerId];
}
+/**
+ * This method allows to send a signal only to a limited set of peers
+ * @param peerIds A list of peers that should receive it
+ * @param closure Code you want to execute within of that restricted environment
+ */
+void SignalProxy::restrictTargetPeers(std::initializer_list<Peer *> peers, std::function<void()> closure)
+{
+ auto previousRestrictMessageTarget = _restrictMessageTarget;
+ auto previousRestrictedTargets = _restrictedTargets;
+ _restrictMessageTarget = true;
+ _restrictedTargets = QSet<Peer*>(peers);
+
+ closure();
+
+ _restrictMessageTarget = previousRestrictMessageTarget;
+ _restrictedTargets = previousRestrictedTargets;
+}
// ==================================================
// ExtendedMetaObject
bool isSecure() const { return _secure; }
void dumpProxyStats();
void dumpSyncMap(SyncableObject *object);
+
+ void restrictTargetPeers(std::initializer_list<Peer *> peerIds, std::function<void()> closure);
+
inline int peerCount() const { return _peers.size(); }
QVariantList peerData();
int _lastPeerId = 0;
+ QSet<Peer *> _restrictedTargets;
+ bool _restrictMessageTarget = false;
+
friend class SignalRelay;
friend class SyncableObject;
friend class Peer;
p->attachSignal(this, SIGNAL(passwordChanged(PeerPtr,bool)));
p->attachSlot(SIGNAL(kickClient(int)), this, SLOT(kickClient(int)));
+ p->attachSignal(this, SIGNAL(disconnectFromCore()));
loadSettings();
initScriptEngine();
}
void CoreSession::kickClient(int peerId) {
+ qWarning() << "kickClient(" << peerId << ")";
+
auto peer = signalProxy()->peerById(peerId);
- if (!peer) {
+ if (peer == nullptr) {
qWarning() << "Invalid peer Id: " << peerId;
+ return;
}
- peer->close("Terminated by user action");
+ signalProxy()->restrictTargetPeers({peer}, [&]{
+ qWarning() << "executing closure";
+ emit disconnectFromCore();
+ });
}
void passwordChanged(PeerPtr peer, bool success);
+ void disconnectFromCore();
+
protected:
virtual void customEvent(QEvent *event);