/***************************************************************************
- * Copyright (C) 2005-2018 by the Quassel Project *
+ * Copyright (C) 2005-2020 by the Quassel Project *
* devel@quassel-irc.org *
* *
* This program is free software; you can redistribute it and/or modify *
#include "coresession.h"
-#include <QtScript>
+#include <utility>
#include "core.h"
#include "corebacklogmanager.h"
#include "ircchannel.h"
#include "ircparser.h"
#include "ircuser.h"
-#include "logmessage.h"
#include "messageevent.h"
#include "remotepeer.h"
#include "storage.h"
, _sessionEventProcessor(new CoreSessionEventProcessor(this))
, _ctcpParser(new CtcpParser(this))
, _ircParser(new IrcParser(this))
- , scriptEngine(new QScriptEngine(this))
, _processMessages(false)
, _ignoreListManager(this)
, _highlightRuleManager(this)
+ , _metricsServer(Core::instance()->metricsServer())
{
SignalProxy* p = signalProxy();
p->setHeartBeatInterval(30);
connect(p, &SignalProxy::connected, this, &CoreSession::clientsConnected);
connect(p, &SignalProxy::disconnected, this, &CoreSession::clientsDisconnected);
- p->attachSlot(SIGNAL(sendInput(BufferInfo, QString)), this, SLOT(msgFromClient(BufferInfo, QString)));
- p->attachSignal(this, SIGNAL(displayMsg(Message)));
- p->attachSignal(this, SIGNAL(displayStatusMsg(QString, QString)));
+ p->attachSlot(SIGNAL(sendInput(BufferInfo,QString)), this, &CoreSession::msgFromClient);
+ p->attachSignal(this, &CoreSession::displayMsg);
+ p->attachSignal(this, &CoreSession::displayStatusMsg);
- p->attachSignal(this, SIGNAL(identityCreated(const Identity&)));
- p->attachSignal(this, SIGNAL(identityRemoved(IdentityId)));
- p->attachSlot(SIGNAL(createIdentity(const Identity&, const QVariantMap&)),
- this,
- SLOT(createIdentity(const Identity&, const QVariantMap&)));
- p->attachSlot(SIGNAL(removeIdentity(IdentityId)), this, SLOT(removeIdentity(IdentityId)));
+ p->attachSignal(this, &CoreSession::identityCreated);
+ p->attachSignal(this, &CoreSession::identityRemoved);
+ p->attachSlot(SIGNAL(createIdentity(Identity,QVariantMap)), this, selectOverload<const Identity&, const QVariantMap&>(&CoreSession::createIdentity));
+ p->attachSlot(SIGNAL(removeIdentity(IdentityId)), this, &CoreSession::removeIdentity);
- p->attachSignal(this, SIGNAL(networkCreated(NetworkId)));
- p->attachSignal(this, SIGNAL(networkRemoved(NetworkId)));
- p->attachSlot(SIGNAL(createNetwork(const NetworkInfo&, const QStringList&)),
- this,
- SLOT(createNetwork(const NetworkInfo&, const QStringList&)));
- p->attachSlot(SIGNAL(removeNetwork(NetworkId)), this, SLOT(removeNetwork(NetworkId)));
+ p->attachSignal(this, &CoreSession::networkCreated);
+ p->attachSignal(this, &CoreSession::networkRemoved);
+ p->attachSlot(SIGNAL(createNetwork(NetworkInfo,QStringList)), this,&CoreSession::createNetwork);
+ p->attachSlot(SIGNAL(removeNetwork(NetworkId)), this, &CoreSession::removeNetwork);
- p->attachSlot(SIGNAL(changePassword(PeerPtr, QString, QString, QString)), this, SLOT(changePassword(PeerPtr, QString, QString, QString)));
- p->attachSignal(this, SIGNAL(passwordChanged(PeerPtr, bool)));
+ p->attachSlot(SIGNAL(changePassword(PeerPtr,QString,QString,QString)), this, &CoreSession::changePassword);
+ p->attachSignal(this, &CoreSession::passwordChanged);
- p->attachSlot(SIGNAL(kickClient(int)), this, SLOT(kickClient(int)));
- p->attachSignal(this, SIGNAL(disconnectFromCore()));
+ p->attachSlot(SIGNAL(kickClient(int)), this, &CoreSession::kickClient);
+ p->attachSignal(this, &CoreSession::disconnectFromCore);
QVariantMap data;
data["quasselVersion"] = Quassel::buildInfo().fancyVersionString;
data["quasselBuildDate"] = Quassel::buildInfo().commitDate; // "BuildDate" for compatibility
- data["startTime"] = Core::instance()->startTime();
+ data["startTime"] = Core::startTime();
data["sessionConnectedClients"] = 0;
_coreInfo->setCoreData(data);
loadSettings();
- initScriptEngine();
eventManager()->registerObject(ircParser(), EventManager::NormalPriority);
eventManager()->registerObject(sessionEventProcessor(), EventManager::HighPriority); // needs to process events *before* the stringifier!
eventManager()->registerObject(ctcpParser(), EventManager::LowPriority, "send");
// periodically save our session state
- connect(Core::instance()->syncTimer(), &QTimer::timeout, this, &CoreSession::saveSessionState);
+ connect(Core::syncTimer(), &QTimer::timeout, this, &CoreSession::saveSessionState);
p->synchronize(_bufferSyncer);
p->synchronize(&aliasManager());
restoreSessionState();
emit initialized();
+
+ if (_metricsServer) {
+ _metricsServer->addSession(user(), Core::instance()->strictSysIdent(_user));
+ }
}
void CoreSession::shutdown()
// Nothing to do, suicide so the core can shut down
deleteLater();
}
+
+ if (_metricsServer) {
+ _metricsServer->removeSession(user());
+ }
}
void CoreSession::onNetworkDisconnected(NetworkId networkId)
// migrate to db
QList<IdentityId> ids = s.identityIds();
- QList<NetworkInfo> networkInfos = Core::networks(user());
- foreach (IdentityId id, ids) {
+ std::vector<NetworkInfo> networkInfos = Core::networks(user());
+ for (IdentityId id : ids) {
CoreIdentity identity(s.identity(id));
IdentityId newId = Core::createIdentity(user(), identity);
- QList<NetworkInfo>::iterator networkIter = networkInfos.begin();
+ auto networkIter = networkInfos.begin();
while (networkIter != networkInfos.end()) {
if (networkIter->identity == id) {
networkIter->identity = newId;
}
// end of migration
- foreach (CoreIdentity identity, Core::identities(user())) {
+ for (const CoreIdentity& identity : Core::identities(user())) {
createIdentity(identity);
}
- foreach (NetworkInfo info, Core::networks(user())) {
+ for (const NetworkInfo& info : Core::networks(user())) {
createNetwork(info);
}
}
void CoreSession::restoreSessionState()
{
- QList<NetworkId> nets = Core::connectedNetworks(user());
- CoreNetwork* net = nullptr;
- foreach (NetworkId id, nets) {
- net = network(id);
+ for (NetworkId id : Core::connectedNetworks(user())) {
+ auto net = network(id);
Q_ASSERT(net);
net->connectToIrc();
}
_coreInfo->setConnectedClientData(signalProxy()->peerCount(), signalProxy()->peerData());
signalProxy()->setTargetPeer(nullptr);
+
+ if (_metricsServer) {
+ _metricsServer->addClient(user());
+ }
}
void CoreSession::addClient(InternalPeer* peer)
{
auto* p = qobject_cast<RemotePeer*>(peer);
if (p)
- quInfo() << qPrintable(tr("Client")) << p->description() << qPrintable(tr("disconnected (UserId: %1).").arg(user().toInt()));
+ qInfo() << qPrintable(tr("Client")) << p->description() << qPrintable(tr("disconnected (UserId: %1).").arg(user().toInt()));
_coreInfo->setConnectedClientData(signalProxy()->peerCount(), signalProxy()->peerData());
+
+ if (_metricsServer) {
+ _metricsServer->removeClient(user());
+ }
}
QHash<QString, QString> CoreSession::persistentChannels(NetworkId id) const
// ALL messages coming pass through these functions before going to the GUI.
// So this is the perfect place for storing the backlog and log stuff.
-void CoreSession::recvMessageFromServer(NetworkId networkId,
- Message::Type type,
- BufferInfo::Type bufferType,
- const QString& target,
- const QString& text_,
- const QString& sender,
- Message::Flags flags)
+void CoreSession::recvMessageFromServer(RawMessage msg)
{
// U+FDD0 and U+FDD1 are special characters for Qt's text engine, specifically they mark the boundaries of
// text frames in a QTextDocument. This might lead to problems in widgets displaying QTextDocuments (such as
// KDE's notifications), hence we remove those just to be safe.
- QString text = text_;
- text.remove(QChar(0xfdd0)).remove(QChar(0xfdd1));
- RawMessage rawMsg(networkId, type, bufferType, target, text, sender, flags);
+ msg.text.remove(QChar(0xfdd0)).remove(QChar(0xfdd1));
// check for HardStrictness ignore
- CoreNetwork* currentNetwork = network(networkId);
+ CoreNetwork* currentNetwork = network(msg.networkId);
QString networkName = currentNetwork ? currentNetwork->networkName() : QString("");
- if (_ignoreListManager.match(rawMsg, networkName) == IgnoreListManager::HardStrictness)
+ switch (_ignoreListManager.match(msg, networkName)) {
+ case IgnoreListManager::StrictnessType::HardStrictness:
+ // Drop the message permanently
return;
+ case IgnoreListManager::StrictnessType::SoftStrictness:
+ // Mark the message as (dynamically) ignored
+ msg.flags |= Message::Flag::Ignored;
+ break;
+ case IgnoreListManager::StrictnessType::UnmatchedStrictness:
+ // Keep the message unmodified
+ break;
+ }
- if (currentNetwork && _highlightRuleManager.match(rawMsg, currentNetwork->myNick(), currentNetwork->identityPtr()->nicks()))
- rawMsg.flags |= Message::Flag::Highlight;
+ if (currentNetwork && _highlightRuleManager.match(msg, currentNetwork->myNick(), currentNetwork->identityPtr()->nicks()))
+ msg.flags |= Message::Flag::Highlight;
- _messageQueue << rawMsg;
+ _messageQueue << std::move(msg);
if (!_processMessages) {
_processMessages = true;
QCoreApplication::postEvent(this, new ProcessMessagesEvent());
{
auto* net = qobject_cast<CoreNetwork*>(sender());
Q_ASSERT(net);
- emit displayStatusMsg(net->networkName(), msg);
+ emit displayStatusMsg(net->networkName(), std::move(msg));
}
void CoreSession::processMessageEvent(MessageEvent* event)
{
- recvMessageFromServer(event->networkId(),
- event->msgType(),
- event->bufferType(),
- event->target().isNull() ? "" : event->target(),
- event->text().isNull() ? "" : event->text(),
- event->sender().isNull() ? "" : event->sender(),
- event->msgFlags());
+ recvMessageFromServer(RawMessage{
+ event->timestamp(),
+ event->networkId(),
+ event->msgType(),
+ event->bufferType(),
+ event->target().isNull() ? "" : event->target(),
+ event->text().isNull() ? "" : event->text(),
+ event->sender().isNull() ? "" : event->sender(),
+ event->msgFlags()
+ });
}
-QList<BufferInfo> CoreSession::buffers() const
+std::vector<BufferInfo> CoreSession::buffers() const
{
return Core::requestBuffers(user());
}
Q_ASSERT(!createBuffer);
bufferInfo = Core::bufferInfo(user(), rawMsg.networkId, BufferInfo::StatusBuffer, "");
}
- Message msg(bufferInfo,
+ Message msg(rawMsg.timestamp,
+ bufferInfo,
rawMsg.type,
rawMsg.text,
rawMsg.sender,
}
bufferInfoCache[rawMsg.networkId][rawMsg.target] = bufferInfo;
}
- Message msg(bufferInfo,
+ Message msg(rawMsg.timestamp,
+ bufferInfo,
rawMsg.type,
rawMsg.text,
rawMsg.sender,
// add the StatusBuffer to the Cache in case there are more Messages for the original target
bufferInfoCache[rawMsg.networkId][rawMsg.target] = bufferInfo;
}
- Message msg(bufferInfo,
+ Message msg(rawMsg.timestamp,
+ bufferInfo,
rawMsg.type,
rawMsg.text,
rawMsg.sender,
QVariantList networkIds;
QVariantList identities;
- foreach (const BufferInfo& id, buffers())
+ for (const BufferInfo& id : buffers()) {
bufferInfos << QVariant::fromValue(id);
- foreach (const NetworkId& id, _networks.keys())
+ }
+ for (const NetworkId& id : _networks.keys()) {
networkIds << QVariant::fromValue(id);
- foreach (const Identity* i, _identities.values())
+ }
+ for (const Identity* i : _identities.values()) {
identities << QVariant::fromValue(*i);
+ }
return Protocol::SessionState(identities, bufferInfos, networkIds);
}
-void CoreSession::initScriptEngine()
-{
- signalProxy()->attachSlot(SIGNAL(scriptRequest(QString)), this, SLOT(scriptRequest(QString)));
- signalProxy()->attachSignal(this, SIGNAL(scriptResult(QString)));
-
- // FIXME
- // QScriptValue storage_ = scriptEngine->newQObject(storage);
- // scriptEngine->globalObject().setProperty("storage", storage_);
-}
-
-void CoreSession::scriptRequest(QString script)
-{
- emit scriptResult(scriptEngine->evaluate(script).toString());
-}
-
/*** Identity Handling ***/
void CoreSession::createIdentity(const Identity& identity, const QVariantMap& additional)
{
-#ifndef HAVE_SSL
- Q_UNUSED(additional)
-#endif
-
CoreIdentity coreIdentity(identity);
-#ifdef HAVE_SSL
if (additional.contains("KeyPem"))
coreIdentity.setSslKey(additional["KeyPem"].toByteArray());
if (additional.contains("CertPem"))
coreIdentity.setSslCert(additional["CertPem"].toByteArray());
-#endif
qDebug() << Q_FUNC_INFO;
IdentityId id = Core::createIdentity(user(), coreIdentity);
if (!id.isValid())
if (!_networks.contains(id)) {
// create persistent chans
QRegExp rx(R"(\s*(\S+)(?:\s*(\S+))?\s*)");
- foreach (QString channel, persistentChans) {
+ for (const QString& channel : persistentChans) {
if (!rx.exactMatch(channel)) {
qWarning() << QString("Invalid persistent channel declaration: %1").arg(channel);
continue;
void CoreSession::destroyNetwork(NetworkId id)
{
- QList<BufferId> removedBuffers = Core::requestBufferIdsForNetwork(user(), id);
Network* net = _networks.take(id);
if (net && Core::removeNetwork(user(), id)) {
// make sure that all unprocessed RawMessages from this network are removed
}
}
// remove buffers from syncer
- foreach (BufferId bufferId, removedBuffers) {
+ for (BufferId bufferId : Core::requestBufferIdsForNetwork(user(), id)) {
_bufferSyncer->removeBuffer(bufferId);
}
emit networkRemoved(id);