inline void debugInfo(QDebug& dbg) const override
{
NetworkEvent::debugInfo(dbg);
- dbg.nospace() << ", sender = " << qPrintable(sender()) << ", target = " << qPrintable(target()) << ", text = " << text()
+ dbg.nospace() << ", sender = " << qPrintable(sender())
+ << ", target = " << qPrintable(target())
+ << ", text = " << text()
<< ", msgtype = " << qPrintable(QString::number(msgType(), 16))
<< ", buffertype = " << qPrintable(QString::number(bufferType(), 16))
<< ", msgflags = " << qPrintable(QString::number(msgFlags(), 16));
eventstringifier.cpp
identserver.cpp
ircparser.cpp
+ irctags.h
netsplit.cpp
oidentdconfiggenerator.cpp
postgresqlstorage.cpp
QList<QByteArray> userEncode(const QString& userNick, const QStringList& stringlist);
signals:
- void displayMsg(Message::Type,
- BufferInfo::Type,
- const QString& target,
- const QString& text,
- const QString& sender = "",
- Message::Flags flags = Message::None);
+ void displayMsg(const NetworkInternalMessage& msg);
/**
* Sends the raw (encoded) line, adding to the queue if needed, optionally with higher priority.
, _autoReconnectCount(0)
, _quitRequested(false)
, _disconnectExpected(false)
- ,
-
- _previousConnectionAttemptFailed(false)
+ , _previousConnectionAttemptFailed(false)
, _lastUsedServerIndex(0)
- ,
-
- _requestedUserModes('-')
+ , _requestedUserModes('-')
{
// Check if raw IRC logging is enabled
_debugLogRawIrc = (Quassel::isOptionSet("debug-irc") || Quassel::isOptionSet("debug-irc-id"));
setAutoWhoInterval(networkConfig()->autoWhoInterval());
QHash<QString, QString> channels = coreSession()->persistentChannels(networkId());
- foreach (QString chan, channels.keys()) {
+ for (const QString& chan : channels.keys()) {
_channelKeys[chan.toLower()] = channels[chan];
}
QHash<QString, QByteArray> bufferCiphers = coreSession()->bufferCiphers(networkId());
- foreach (QString buffer, bufferCiphers.keys()) {
+ for (const QString& buffer : bufferCiphers.keys()) {
storeChannelCipherKey(buffer.toLower(), bufferCiphers[buffer]);
}
disconnect(&socket, nullptr, this, nullptr);
if (!forceDisconnect()) {
qWarning() << QString{"Could not disconnect from network %1 (network ID: %2, user ID: %3)"}
- .arg(networkName())
- .arg(networkId().toInt())
- .arg(userId().toInt());
+ .arg(networkName())
+ .arg(networkId().toInt())
+ .arg(userId().toInt());
}
}
else if (_previousConnectionAttemptFailed) {
// cycle to next server if previous connection attempt failed
_previousConnectionAttemptFailed = false;
- showMessage(Message::Server, BufferInfo::StatusBuffer, "", tr("Connection failed. Cycling to next Server"));
+ showMessage(NetworkInternalMessage(
+ Message::Server,
+ BufferInfo::StatusBuffer,
+ "",
+ tr("Connection failed. Cycling to next server...")
+ ));
if (++_lastUsedServerIndex >= serverList().size()) {
_lastUsedServerIndex = 0;
}
Server server = usedServer();
displayStatusMsg(tr("Connecting to %1:%2...").arg(server.host).arg(server.port));
- showMessage(Message::Server, BufferInfo::StatusBuffer, "", tr("Connecting to %1:%2...").arg(server.host).arg(server.port));
+ showMessage(NetworkInternalMessage(
+ Message::Server,
+ BufferInfo::StatusBuffer,
+ "",
+ tr("Connecting to %1:%2...").arg(server.host).arg(server.port)
+ ));
if (server.useProxy) {
- QNetworkProxy proxy((QNetworkProxy::ProxyType)server.proxyType, server.proxyHost, server.proxyPort, server.proxyUser, server.proxyPass);
+ QNetworkProxy proxy((QNetworkProxy::ProxyType) server.proxyType, server.proxyHost, server.proxyPort, server.proxyUser, server.proxyPass);
socket.setProxy(proxy);
}
else {
else
_quitReason = reason;
- showMessage(Message::Server,
- BufferInfo::StatusBuffer,
- "",
- tr("Disconnecting. (%1)").arg((!requested && !withReconnect) ? tr("Core Shutdown") : _quitReason));
+ showMessage(NetworkInternalMessage(
+ Message::Server,
+ BufferInfo::StatusBuffer,
+ "",
+ tr("Disconnecting. (%1)").arg((!requested && !withReconnect) ? tr("Core Shutdown") : _quitReason)
+ ));
if (socket.state() == QAbstractSocket::UnconnectedState) {
onSocketDisconnected();
}
void CoreNetwork::onSocketCloseTimeout()
{
qWarning() << QString{"Timed out quitting network %1 (network ID: %2, user ID: %3)"}
- .arg(networkName())
- .arg(networkId().toInt())
- .arg(userId().toInt());
+ .arg(networkName())
+ .arg(networkId().toInt())
+ .arg(userId().toInt());
socket.abort();
}
}
}
-void CoreNetwork::putCmd(const QString& cmd, const QList<QByteArray>& params, const QByteArray& prefix, const QHash<IrcTagKey, QString> &tags, const bool prepend)
+void CoreNetwork::putCmd(const QString& cmd, const QList<QByteArray>& params, const QByteArray& prefix, const QHash<IrcTagKey, QString>& tags, bool prepend)
{
putRawLine(IrcEncoder::writeMessage(tags, prefix, cmd, params), prepend);
}
-void CoreNetwork::putCmd(const QString& cmd, const QList<QList<QByteArray>>& params, const QByteArray& prefix, const QHash<IrcTagKey, QString> &tags, const bool prependAll)
+void CoreNetwork::putCmd(const QString& cmd, const QList<QList<QByteArray>>& params, const QByteArray& prefix, const QHash<IrcTagKey, QString>& tags, bool prependAll)
{
QListIterator<QList<QByteArray>> i(params);
while (i.hasNext()) {
_previousConnectionAttemptFailed = true;
qWarning() << qPrintable(tr("Could not connect to %1 (%2)").arg(networkName(), socket.errorString()));
emit connectionError(socket.errorString());
- showMessage(Message::Error, BufferInfo::StatusBuffer, "", tr("Connection failure: %1").arg(socket.errorString()));
+ showMessage(NetworkInternalMessage(
+ Message::Error,
+ BufferInfo::StatusBuffer,
+ "",
+ tr("Connection failure: %1").arg(socket.errorString())
+ ));
emitConnectionError(socket.errorString());
if (socket.state() < QAbstractSocket::ConnectedState) {
onSocketDisconnected();
// Request capabilities as per IRCv3.2 specifications
// Older servers should ignore this; newer servers won't downgrade to RFC1459
- showMessage(Message::Server, BufferInfo::StatusBuffer, "", tr("Requesting capability list..."));
+ showMessage(NetworkInternalMessage(
+ Message::Server,
+ BufferInfo::StatusBuffer,
+ "",
+ tr("Requesting capability list...")
+ ));
putRawLine(serverEncode(QString("CAP LS 302")));
if (!server.password.isEmpty()) {
IrcUser* me_ = me();
if (me_) {
- foreach (QString channel, me_->channels())
- showMessage(Message::Quit, BufferInfo::ChannelBuffer, channel, _quitReason, me_->hostmask());
+ for (const QString& channel : me_->channels()) {
+ showMessage(NetworkInternalMessage(
+ Message::Quit,
+ BufferInfo::ChannelBuffer,
+ channel,
+ _quitReason, me_->hostmask()
+ ));
+ }
}
setConnected(false);
}
// send perform list
- foreach (QString line, perform()) {
+ for (const QString& line : perform()) {
if (!line.isEmpty())
userInput(statusBuf, line);
}
// rejoin channels we've been in
if (rejoinChannels()) {
QStringList channels, keys;
- foreach (QString chan, coreSession()->persistentChannels(networkId()).keys()) {
+ for (const QString& chan : coreSession()->persistentChannels(networkId()).keys()) {
QString key = channelKey(chan);
if (!key.isEmpty()) {
channels.prepend(chan);
qDebug() << "UserId:" << userId() << "Network:" << networkName() << "missed" << _pingCount << "pings."
<< "BA:" << socket.bytesAvailable() << "BTW:" << socket.bytesToWrite();
}
- if ((int)_pingCount >= networkConfig()->maxPingCount() && (now - _lastPingTime) <= (_pingTimer.interval() + (1 * 1000))) {
+ if ((int) _pingCount >= networkConfig()->maxPingCount() && (now - _lastPingTime) <= (_pingTimer.interval() + (1 * 1000))) {
// In transitioning to 64-bit time, the interval no longer needs converted down to seconds.
// However, to reduce the risk of breaking things by changing past behavior, we still allow
// up to 1 second missed instead of enforcing a stricter 1 millisecond allowance.
/******** Custom Rate Limiting ********/
-void CoreNetwork::updateRateLimiting(const bool forceUnlimited)
+void CoreNetwork::updateRateLimiting(bool forceUnlimited)
{
// Verify and apply custom rate limiting options, always resetting the delay and burst size
// (safe-guarding against accidentally starting the timer), but don't reset the token bucket as
putRawLine(serverEncode("AUTHENTICATE EXTERNAL"));
}
else {
- showMessage(Message::Error, BufferInfo::StatusBuffer, "", tr("SASL EXTERNAL authentication not supported"));
+ showMessage(NetworkInternalMessage(
+ Message::Error,
+ BufferInfo::StatusBuffer,
+ "",
+ tr("SASL EXTERNAL authentication not supported")
+ ));
sendNextCap();
}
}
putRawLine(serverEncode("AUTHENTICATE PLAIN"));
}
else {
- showMessage(Message::Error, BufferInfo::StatusBuffer, "", tr("SASL PLAIN authentication not supported"));
+ showMessage(NetworkInternalMessage(
+ Message::Error,
+ BufferInfo::StatusBuffer,
+ "",
+ tr("SASL PLAIN authentication not supported")
+ ));
sendNextCap();
}
#ifdef HAVE_SSL
// Add most recently tried capability set to individual list, re-requesting them one at a time
_capsQueuedIndividual.append(_capsQueuedLastBundle);
// Warn of this issue to explain the slower login. Servers usually shouldn't trigger this.
- showMessage(Message::Server,
- BufferInfo::StatusBuffer,
- "",
- tr("Could not negotiate some capabilities, retrying individually (%1)...").arg(_capsQueuedLastBundle.join(", ")));
+ showMessage(NetworkInternalMessage(
+ Message::Server,
+ BufferInfo::StatusBuffer,
+ "",
+ tr("Could not negotiate some capabilities, retrying individually (%1)...").arg(_capsQueuedLastBundle.join(", "))
+ ));
// Capabilities are already removed from the capability bundle queue via takeQueuedCaps(), no
// need to remove them here.
// Clear the most recently tried set to reduce risk that mistakes elsewhere causes retrying
if (!capNegotiationInProgress()) {
// If the server doesn't have any capabilities, but supports CAP LS, continue on with the
// normal connection.
- showMessage(Message::Server, BufferInfo::StatusBuffer, "", tr("No capabilities available"));
+ showMessage(NetworkInternalMessage(
+ Message::Server,
+ BufferInfo::StatusBuffer,
+ "",
+ tr("No capabilities available")
+ ));
endCapNegotiation();
return;
}
_capNegotiationActive = true;
- showMessage(Message::Server, BufferInfo::StatusBuffer, "", tr("Ready to negotiate (found: %1)").arg(caps().join(", ")));
+ showMessage(NetworkInternalMessage(
+ Message::Server,
+ BufferInfo::StatusBuffer,
+ "",
+ tr("Ready to negotiate (found: %1)").arg(caps().join(", "))
+ ));
// Build a list of queued capabilities, starting with individual, then bundled, only adding the
// comma separator between the two if needed (both individual and bundled caps exist).
QString queuedCapsDisplay = _capsQueuedIndividual.join(", ")
+ ((!_capsQueuedIndividual.empty() && !_capsQueuedBundled.empty()) ? ", " : "")
+ _capsQueuedBundled.join(", ");
- showMessage(Message::Server, BufferInfo::StatusBuffer, "", tr("Negotiating capabilities (requesting: %1)...").arg(queuedCapsDisplay));
+ showMessage(NetworkInternalMessage(
+ Message::Server,
+ BufferInfo::StatusBuffer,
+ "",
+ tr("Negotiating capabilities (requesting: %1)...").arg(queuedCapsDisplay)
+ ));
sendNextCap();
}
// No pending desired capabilities, capability negotiation finished
// If SASL requested but not available, print a warning
if (networkInfo().useSasl && !capEnabled(IrcCap::SASL))
- showMessage(Message::Error, BufferInfo::StatusBuffer, "", tr("SASL authentication currently not supported by server"));
+ showMessage(NetworkInternalMessage(
+ Message::Error,
+ BufferInfo::StatusBuffer,
+ "",
+ tr("SASL authentication currently not supported by server")
+ ));
if (_capNegotiationActive) {
- showMessage(Message::Server,
- BufferInfo::StatusBuffer,
- "",
- tr("Capability negotiation finished (enabled: %1)").arg(capsEnabled().join(", ")));
+ showMessage(NetworkInternalMessage(
+ Message::Server,
+ BufferInfo::StatusBuffer,
+ "",
+ tr("Capability negotiation finished (enabled: %1)").arg(capsEnabled().join(", "))
+ ));
_capNegotiationActive = false;
}
// Add the error reason if known
sslErrorMessage.append(tr(" (Reason: %1)").arg(sslErrors.first().errorString()));
}
- showMessage(Message::Error, BufferInfo::StatusBuffer, "", sslErrorMessage);
+ showMessage(NetworkInternalMessage(
+ Message::Error,
+ BufferInfo::StatusBuffer,
+ "",
+ sslErrorMessage
+ ));
// Disconnect, triggering a reconnect in case it's a temporary issue with certificate
// validity, network trouble, etc.
// Add the error reason if known
sslErrorMessage.append(tr(" (Reason: %1)").arg(sslErrors.first().errorString()));
}
- showMessage(Message::Info, BufferInfo::StatusBuffer, "", sslErrorMessage);
+ showMessage(NetworkInternalMessage(
+ Message::Info,
+ BufferInfo::StatusBuffer,
+ "",
+ sslErrorMessage
+ ));
// Proceed with the connection
socket.ignoreSslErrors();
void CoreNetwork::checkTokenBucket()
{
if (_skipMessageRates) {
- if (_msgQueue.size() == 0) {
+ if (_msgQueue.empty()) {
// Message queue emptied; stop the timer and bail out
_tokenBucketTimer.stop();
return;
}
// As long as there's tokens available and messages remaining, sending messages from the queue
- while (_msgQueue.size() > 0 && _tokenBucket > 0) {
+ while (!_msgQueue.empty() && _tokenBucket > 0) {
writeToSocket(_msgQueue.takeFirst());
}
}
* set by the user. Use with caution and remember to re-enable configured limits when done.
* @endparmblock
*/
- void updateRateLimiting(const bool forceUnlimited = false);
+ void updateRateLimiting(bool forceUnlimited = false);
/**
* Resets the token bucket up to the maximum
*/
inline void resetPongReplyPending() { _pongReplyPending = false; }
- void onDisplayMsg(Message::Type msgType,
- BufferInfo::Type bufferType,
- const QString& target,
- const QString& text,
- const QString& sender,
- Message::Flags flags)
+ void onDisplayMsg(const NetworkInternalMessage& msg)
{
- emit displayMsg(networkId(), msgType, bufferType, target, text, sender, flags);
+ emit displayMsg(RawMessage(networkId(), msg));
}
signals:
- void recvRawServerMsg(QString);
- void displayStatusMsg(QString);
- void displayMsg(
- NetworkId, Message::Type, BufferInfo::Type, const QString& target, const QString& text, const QString& sender, Message::Flags flags);
+ void recvRawServerMsg(const QString&);
+ void displayStatusMsg(const QString&);
+ void displayMsg(const RawMessage& msg);
void disconnected(NetworkId networkId);
void connectionError(const QString& errorMsg);
void writeToSocket(const QByteArray& data);
private:
- void showMessage(Message::Type msgType,
- BufferInfo::Type bufferType,
- const QString& target,
- const QString& text,
- const QString& sender = "",
- Message::Flags flags = Message::None)
+ void showMessage(const NetworkInternalMessage& msg)
{
- emit displayMsg(networkId(), msgType, bufferType, target, text, sender, flags);
+ emit displayMsg(RawMessage(networkId(), msg));
}
private:
#include "coresession.h"
+#include <utility>
+
#include <QtScript>
#include "core.h"
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);
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());
// migrate to db
QList<IdentityId> ids = s.identityIds();
QList<NetworkInfo> networkInfos = Core::networks(user());
- foreach (IdentityId id, ids) {
+ for (IdentityId id : ids) {
CoreIdentity identity(s.identity(id));
IdentityId newId = Core::createIdentity(user(), identity);
QList<NetworkInfo>::iterator networkIter = networkInfos.begin();
}
// 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);
}
}
{
QList<NetworkId> nets = Core::connectedNetworks(user());
CoreNetwork* net = nullptr;
- foreach (NetworkId id, nets) {
+ for (NetworkId id : nets) {
net = network(id);
Q_ASSERT(net);
net->connectToIrc();
// 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)
+ if (_ignoreListManager.match(msg, networkName) == IgnoreListManager::HardStrictness)
return;
- 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->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
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);
}
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;
}
}
// remove buffers from syncer
- foreach (BufferId bufferId, removedBuffers) {
+ for (BufferId bufferId : removedBuffers) {
_bufferSyncer->removeBuffer(bufferId);
}
emit networkRemoved(id);
class InternalPeer;
class IrcParser;
class MessageEvent;
-class NetworkConnection;
class RemotePeer;
class SignalProxy;
const QString strictCompliantIdent(const CoreIdentity* identity);
inline CoreNetworkConfig* networkConfig() const { return _networkConfig; }
- NetworkConnection* networkConnection(NetworkId) const;
Protocol::SessionState sessionState() const;
* @param[in] msg Away message, or blank to set unaway
* @param[in] skipFormatting If true, skip timestamp formatting codes (e.g. if already done)
*/
- void globalAway(const QString& msg = QString(), const bool skipFormatting = false);
+ void globalAway(const QString& msg = QString(), bool skipFormatting = false);
signals:
void initialized();
void removeClient(Peer* peer);
void recvStatusMsgFromServer(QString msg);
- void recvMessageFromServer(NetworkId networkId,
- Message::Type,
- BufferInfo::Type,
- const QString& target,
- const QString& text,
- const QString& sender = "",
- Message::Flags flags = Message::None);
+ void recvMessageFromServer(RawMessage msg);
void destroyNetwork(NetworkId);
CoreHighlightRuleManager _highlightRuleManager;
};
+struct NetworkInternalMessage
+{
+ Message::Type type;
+ BufferInfo::Type bufferType;
+ QString target;
+ QString text;
+ QString sender;
+ Message::Flags flags;
+ NetworkInternalMessage(Message::Type type, BufferInfo::Type bufferType, QString target, QString text, QString sender = "", Message::Flags flags = Message::None)
+ : type(type)
+ , bufferType(bufferType)
+ , target(std::move(target))
+ , text(std::move(text))
+ , sender(std::move(sender))
+ , flags(flags)
+ {}
+};
+
struct RawMessage
{
NetworkId networkId;
, sender(std::move(sender))
, flags(flags)
{}
+
+ RawMessage(NetworkId networkId, const NetworkInternalMessage& msg)
+ : networkId(networkId)
+ , type(msg.type)
+ , bufferType(msg.bufferType)
+ , target(msg.target)
+ , text(msg.text)
+ , sender(msg.sender)
+ , flags(msg.flags)
+ {}
};
// Else :nick!user@host JOIN #channelname
bool handledByNetsplit = false;
- foreach (Netsplit* n, _netsplits.value(e->network())) {
+ for (Netsplit* n : _netsplits.value(e->network())) {
handledByNetsplit = n->userJoined(e->prefix(), channel);
if (handledByNetsplit)
break;
if (add) {
bool handledByNetsplit = false;
QHash<QString, Netsplit*> splits = _netsplits.value(e->network());
- foreach (Netsplit* n, _netsplits.value(e->network())) {
+ for (Netsplit* n : _netsplits.value(e->network())) {
handledByNetsplit = n->userAlreadyJoined(ircUser->hostmask(), channel->name());
if (handledByNetsplit) {
n->addMode(ircUser->hostmask(), channel->name(), QString(mode));
// Cache result of multi-prefix to avoid unneeded casts and lookups with each iteration.
bool _useCapMultiPrefix = coreNetwork(e)->capEnabled(IrcCap::MULTI_PREFIX);
- foreach (QString nick, e->params()[2].split(' ', QString::SkipEmptyParts)) {
+ for (QString nick : e->params()[2].split(' ', QString::SkipEmptyParts)) {
QString mode;
if (_useCapMultiPrefix) {
QStringList newModes = modes;
QStringList newUsers = users;
- foreach (const QString& user, users) {
+ for (const QString& user : users) {
IrcUser* iu = net->ircUser(nickFromMask(user));
if (iu)
ircUsers.append(iu);
{
NetworkSplitEvent* event = new NetworkSplitEvent(EventManager::NetworkSplitQuit, net, channel, users, quitMessage);
emit newEvent(event);
- foreach (QString user, users) {
- IrcUser* iu = net->ircUser(nickFromMask(user));
- if (iu)
- iu->quit();
+ for (const QString& user : users) {
+ IrcUser* ircUser = net->ircUser(nickFromMask(user));
+ if (ircUser) ircUser->quit();
}
}
QList<IrcUser*> ircUsers;
QStringList newModes = modes;
- foreach (QString user, users) {
- IrcUser* iu = net->updateNickFromMask(user);
- if (iu) {
- ircUsers.append(iu);
+ for (const QString& user : users) {
+ IrcUser* ircUser = net->updateNickFromMask(user);
+ if (ircUser) {
+ ircUsers.append(ircUser);
// fake event for scripts that consume join events
- events << new IrcEvent(EventManager::IrcEventJoin, net, iu->hostmask(), QStringList() << channel);
+ events << new IrcEvent(EventManager::IrcEventJoin, net, ircUser->hostmask(), QStringList() << channel);
}
else {
newModes.removeAt(users.indexOf(user));
}
}
ircChannel->joinIrcUsers(ircUsers, newModes);
- foreach (NetworkEvent* event, events) {
+ for (NetworkEvent* event : events) {
event->setFlag(EventManager::Fake); // ignore this in here!
emit newEvent(event);
}
void CoreSessionEventProcessor::handleCtcpClientinfo(CtcpEvent* e)
{
QStringList supportedHandlers;
- foreach (QString handler, providesHandlers())
+ for (const QString& handler : providesHandlers())
supportedHandlers << handler.toUpper();
qSort(supportedHandlers);
e->setReply(supportedHandlers.join(" "));
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
-#ifndef CORESESSIONEVENTPROCESSOR_H
-#define CORESESSIONEVENTPROCESSOR_H
+#pragma once
#include "basichandler.h"
#include "corenetwork.h"
Q_OBJECT
public:
- CoreSessionEventProcessor(CoreSession* session);
+ explicit CoreSessionEventProcessor(CoreSession* session);
inline CoreSession* coreSession() const { return _coreSession; }
const QString& awayStateAndModes,
const QString& realname);
};
-
-#endif
banChannel = bufferInfo.bufferName();
}
else {
- emit displayMsg(Message::Error, BufferInfo::StatusBuffer, "", QString("Error: channel unknown in command: /BAN %1").arg(msg));
+ emit displayMsg(NetworkInternalMessage(
+ Message::Error,
+ BufferInfo::StatusBuffer,
+ "",
+ QString("Error: channel unknown in command: /BAN %1").arg(msg)
+ ));
return;
}
// generalizedHost changes <nick> to *!ident@*.sld.tld.
QString generalizedHost = ircuser->host();
if (generalizedHost.isEmpty()) {
- emit displayMsg(Message::Error, BufferInfo::StatusBuffer, "", QString("Error: host unknown in command: /BAN %1").arg(msg));
+ emit displayMsg(NetworkInternalMessage(
+ Message::Error,
+ BufferInfo::StatusBuffer,
+ "",
+ QString("Error: host unknown in command: /BAN %1").arg(msg)
+ ));
return;
}
// FIXME make this a proper event
coreNetwork()->coreSession()->ctcpParser()->query(coreNetwork(), nick, ctcpTag, message);
- emit displayMsg(Message::Action, BufferInfo::StatusBuffer, "", verboseMessage, network()->myNick(), Message::Flag::Self);
+ emit displayMsg(NetworkInternalMessage(
+ Message::Action,
+ BufferInfo::StatusBuffer,
+ "",
+ verboseMessage,
+ network()->myNick(),
+ Message::Flag::Self
+ ));
}
void CoreUserInputHandler::handleDelkey(const BufferInfo& bufferInfo, const QString& msg)
return;
if (!Cipher::neededFeaturesAvailable()) {
- emit displayMsg(Message::Error,
- typeByTarget(bufname),
- bufname,
- tr("Error: QCA provider plugin not found. It is usually provided by the qca-ossl plugin."));
+ emit displayMsg(NetworkInternalMessage(
+ Message::Error,
+ typeByTarget(bufname),
+ bufname,
+ tr("Error: QCA provider plugin not found. It is usually provided by the qca-ossl plugin.")
+ ));
return;
}
parms.prepend(bufferInfo.bufferName());
if (parms.isEmpty()) {
- emit displayMsg(Message::Info,
- typeByTarget(bufname),
- bufname,
- tr("[usage] /delkey <nick|channel> deletes the encryption key for nick or channel or just /delkey when in a "
- "channel or query."));
+ emit displayMsg(NetworkInternalMessage(
+ Message::Info,
+ typeByTarget(bufname),
+ bufname,
+ tr("[usage] /delkey <nick|channel> deletes the encryption key for nick or channel or just /delkey when in a "
+ "channel or query.")
+ ));
return;
}
QString target = parms.at(0);
if (network()->cipherKey(target).isEmpty()) {
- emit displayMsg(Message::Info, typeByTarget(bufname), bufname, tr("No key has been set for %1.").arg(target));
+ emit displayMsg(NetworkInternalMessage(
+ Message::Info,
+ typeByTarget(bufname),
+ bufname,
+ tr("No key has been set for %1.").arg(target)
+ ));
return;
}
network()->setCipherKey(target, QByteArray());
- emit displayMsg(Message::Info, typeByTarget(bufname), bufname, tr("The key for %1 has been deleted.").arg(target));
+ emit displayMsg(NetworkInternalMessage(
+ Message::Info,
+ typeByTarget(bufname),
+ bufname,
+ tr("The key for %1 has been deleted.").arg(target)
+ ));
#else
Q_UNUSED(msg)
- emit displayMsg(Message::Error,
- typeByTarget(bufname),
- bufname,
- tr("Error: Setting an encryption key requires Quassel to have been built "
- "with support for the Qt Cryptographic Architecture (QCA2) library. "
- "Contact your distributor about a Quassel package with QCA2 "
- "support, or rebuild Quassel with QCA2 present."));
+ emit displayMsg(NetworkInternalMessage(
+ Message::Error,
+ typeByTarget(bufname),
+ bufname,
+ tr("Error: Setting an encryption key requires Quassel to have been built "
+ "with support for the Qt Cryptographic Architecture (QCA2) library. "
+ "Contact your distributor about a Quassel package with QCA2 "
+ "support, or rebuild Quassel with QCA2 present.")
+ ));
#endif
}
void CoreUserInputHandler::doMode(const BufferInfo& bufferInfo, const QChar& addOrRemove, const QChar& mode, const QString& nicks)
{
- QString m;
bool isNumber;
int maxModes = network()->support("MODES").toInt(&isNumber);
if (!isNumber || maxModes == 0)
QStringList nickList;
if (nicks == "*" && bufferInfo.type() == BufferInfo::ChannelBuffer) { // All users in channel
const QList<IrcUser*> users = network()->ircChannel(bufferInfo.bufferName())->ircUsers();
- foreach (IrcUser* user, users) {
+ for (IrcUser* user : users) {
if ((addOrRemove == '+' && !network()->ircChannel(bufferInfo.bufferName())->userModes(user).contains(mode))
|| (addOrRemove == '-' && network()->ircChannel(bufferInfo.bufferName())->userModes(user).contains(mode)))
nickList.append(user->nick());
return;
if (!Cipher::neededFeaturesAvailable()) {
- emit displayMsg(Message::Error,
- typeByTarget(bufname),
- bufname,
- tr("Error: QCA provider plugin not found. It is usually provided by the qca-ossl plugin."));
+ emit displayMsg(NetworkInternalMessage(
+ Message::Error,
+ typeByTarget(bufname),
+ bufname,
+ tr("Error: QCA provider plugin not found. It is usually provided by the qca-ossl plugin.")
+ ));
return;
}
if (parms.count() == 0 && !bufferInfo.bufferName().isEmpty() && bufferInfo.acceptsRegularMessages())
parms.prepend(bufferInfo.bufferName());
else if (parms.count() != 1) {
- emit displayMsg(Message::Info,
- typeByTarget(bufname),
- bufname,
- tr("[usage] /keyx [<nick>] Initiates a DH1080 key exchange with the target."));
+ emit displayMsg(NetworkInternalMessage(
+ Message::Info,
+ typeByTarget(bufname),
+ bufname,
+ tr("[usage] /keyx [<nick>] Initiates a DH1080 key exchange with the target.")
+ ));
return;
}
QString target = parms.at(0);
if (network()->isChannelName(target)) {
- emit displayMsg(Message::Info, typeByTarget(bufname), bufname, tr("It is only possible to exchange keys in a query buffer."));
+ emit displayMsg(NetworkInternalMessage(
+ Message::Info,
+ typeByTarget(bufname),
+ bufname,
+ tr("It is only possible to exchange keys in a query buffer.")
+ ));
return;
}
QByteArray pubKey = cipher->initKeyExchange();
if (pubKey.isEmpty())
- emit displayMsg(Message::Error, typeByTarget(bufname), bufname, tr("Failed to initiate key exchange with %1.").arg(target));
+ emit displayMsg(NetworkInternalMessage(
+ Message::Error,
+ typeByTarget(bufname),
+ bufname,
+ tr("Failed to initiate key exchange with %1.").arg(target)
+ ));
else {
QList<QByteArray> params;
params << serverEncode(target) << serverEncode("DH1080_INIT ") + pubKey;
emit putCmd("NOTICE", params);
- emit displayMsg(Message::Info, typeByTarget(bufname), bufname, tr("Initiated key exchange with %1.").arg(target));
+ emit displayMsg(NetworkInternalMessage(
+ Message::Info,
+ typeByTarget(bufname),
+ bufname,
+ tr("Initiated key exchange with %1.").arg(target)
+ ));
}
#else
Q_UNUSED(msg)
- emit displayMsg(Message::Error,
- typeByTarget(bufname),
- bufname,
- tr("Error: Setting an encryption key requires Quassel to have been built "
- "with support for the Qt Cryptographic Architecture (QCA) library. "
- "Contact your distributor about a Quassel package with QCA "
- "support, or rebuild Quassel with QCA present."));
+ emit displayMsg(NetworkInternalMessage(
+ Message::Error,
+ typeByTarget(bufname),
+ bufname,
+ tr("Error: Setting an encryption key requires Quassel to have been built "
+ "with support for the Qt Cryptographic Architecture (QCA) library. "
+ "Contact your distributor about a Quassel package with QCA "
+ "support, or rebuild Quassel with QCA present.")
+ ));
#endif
}
// they need to be split into multiple messages.
QStringList messages = msg.split(QChar::LineFeed);
- foreach (auto message, messages) {
+ for (const auto& message : messages) {
// Handle each separated message independently
coreNetwork()->coreSession()->ctcpParser()->query(coreNetwork(), bufferInfo.bufferName(), "ACTION", message);
- emit displayMsg(Message::Action, bufferInfo.type(), bufferInfo.bufferName(), message, network()->myNick(), Message::Self);
+ emit displayMsg(NetworkInternalMessage(
+ Message::Action,
+ bufferInfo.type(),
+ bufferInfo.bufferName(),
+ message,
+ network()->myNick(),
+ Message::Self
+ ));
}
}
if (!params.isEmpty()) {
if (params[0] == "-reset" && params.count() == 1) {
network()->resetPersistentModes();
- emit displayMsg(Message::Info, BufferInfo::StatusBuffer, "", tr("Your persistent modes have been reset."));
+ emit displayMsg(NetworkInternalMessage(
+ Message::Info,
+ BufferInfo::StatusBuffer,
+ "",
+ tr("Your persistent modes have been reset.")
+ ));
return;
}
if (!network()->isChannelName(params[0]) && !network()->isMyNick(params[0]))
// they need to be split into multiple messages.
QStringList messages = msg.section(' ', 1).split(QChar::LineFeed);
- foreach (auto message, messages) {
+ for (const auto& message : messages) {
// Handle each separated message independently
params.clear();
params << serverEncode(bufferName) << channelEncode(bufferInfo.bufferName(), message);
emit putCmd("NOTICE", params);
- emit displayMsg(Message::Notice, typeByTarget(bufferName), bufferName, message, network()->myNick(), Message::Self);
+ emit displayMsg(NetworkInternalMessage(
+ Message::Notice,
+ typeByTarget(bufferName),
+ bufferName,
+ message,
+ network()->myNick(),
+ Message::Self
+ ));
}
}
return; // server buffer
QByteArray encMsg = channelEncode(bufferInfo.bufferName(), msg);
- emit displayMsg(Message::Info, bufferInfo.type(), bufferInfo.bufferName(), msg, network()->myNick(), Message::Self);
+ emit displayMsg(NetworkInternalMessage(
+ Message::Info,
+ bufferInfo.type(),
+ bufferInfo.bufferName(),
+ msg,
+ network()->myNick(),
+ Message::Self
+ ));
}
// TODO: implement queries
// they need to be split into multiple messages.
QStringList messages = msg.section(' ', 1).split(QChar::LineFeed);
- foreach (auto message, messages) {
+ for (const auto& message : messages) {
// Handle each separated message independently
if (message.isEmpty()) {
- emit displayMsg(Message::Server,
- BufferInfo::QueryBuffer,
- target,
- tr("Starting query with %1").arg(target),
- network()->myNick(),
- Message::Self);
+ emit displayMsg(NetworkInternalMessage(
+ Message::Server,
+ BufferInfo::QueryBuffer,
+ target,
+ tr("Starting query with %1").arg(target),
+ network()->myNick(),
+ Message::Self
+ ));
// handleMsg is a no-op if message is empty
}
else {
- emit displayMsg(Message::Plain, BufferInfo::QueryBuffer, target, message, network()->myNick(), Message::Self);
+ emit displayMsg(NetworkInternalMessage(
+ Message::Plain,
+ BufferInfo::QueryBuffer,
+ target,
+ message,
+ network()->myNick(),
+ Message::Self
+ ));
// handleMsg needs the target specified at the beginning of the message
handleMsg(bufferInfo, target + " " + message);
}
// they need to be split into multiple messages.
QStringList messages = msg.split(QChar::LineFeed, QString::SkipEmptyParts);
- foreach (auto message, messages) {
+ for (const auto& message : messages) {
// Handle each separated message independently
#ifdef HAVE_QCA2
putPrivmsg(bufferInfo.bufferName(), message, encodeFunc, network()->cipher(bufferInfo.bufferName()));
#else
putPrivmsg(bufferInfo.bufferName(), message, encodeFunc);
#endif
- emit displayMsg(Message::Plain, bufferInfo.type(), bufferInfo.bufferName(), message, network()->myNick(), Message::Self);
+ emit displayMsg(NetworkInternalMessage(
+ Message::Plain,
+ bufferInfo.type(),
+ bufferInfo.bufferName(),
+ message,
+ network()->myNick(),
+ Message::Self
+ ));
}
}
return;
if (!Cipher::neededFeaturesAvailable()) {
- emit displayMsg(Message::Error,
- typeByTarget(bufname),
- bufname,
- tr("Error: QCA provider plugin not found. It is usually provided by the qca-ossl plugin."));
+ emit displayMsg(NetworkInternalMessage(
+ Message::Error,
+ typeByTarget(bufname),
+ bufname,
+ tr("Error: QCA provider plugin not found. It is usually provided by the qca-ossl plugin.")
+ ));
return;
}
if (parms.count() == 1 && !bufferInfo.bufferName().isEmpty() && bufferInfo.acceptsRegularMessages())
parms.prepend(bufferInfo.bufferName());
else if (parms.count() != 2) {
- emit displayMsg(Message::Info,
- typeByTarget(bufname),
- bufname,
- tr("[usage] /setkey <nick|channel> <key> sets the encryption key for nick or channel. "
- "/setkey <key> when in a channel or query buffer sets the key for it."));
+ emit displayMsg(NetworkInternalMessage(
+ Message::Info,
+ typeByTarget(bufname),
+ bufname,
+ tr("[usage] /setkey <nick|channel> <key> sets the encryption key for nick or channel. "
+ "/setkey <key> when in a channel or query buffer sets the key for it.")
+ ));
return;
}
QByteArray key = parms.at(1).toLocal8Bit();
network()->setCipherKey(target, key);
- emit displayMsg(Message::Info, typeByTarget(bufname), bufname, tr("The key for %1 has been set.").arg(target));
+ emit displayMsg(NetworkInternalMessage(
+ Message::Info,
+ typeByTarget(bufname),
+ bufname,
+ tr("The key for %1 has been set.").arg(target)
+ ));
#else
Q_UNUSED(msg)
- emit displayMsg(Message::Error,
- typeByTarget(bufname),
- bufname,
- tr("Error: Setting an encryption key requires Quassel to have been built "
- "with support for the Qt Cryptographic Architecture (QCA) library. "
- "Contact your distributor about a Quassel package with QCA "
- "support, or rebuild Quassel with QCA present."));
+ emit displayMsg(NetworkInternalMessage(
+ Message::Error,
+ typeByTarget(bufname),
+ bufname,
+ tr("Error: Setting an encryption key requires Quassel to have been built "
+ "with support for the Qt Cryptographic Architecture (QCA) library. "
+ "Contact your distributor about a Quassel package with QCA "
+ "support, or rebuild Quassel with QCA present.")
+ ));
#endif
}
return;
if (!Cipher::neededFeaturesAvailable()) {
- emit displayMsg(Message::Error,
- typeByTarget(bufname),
- bufname,
- tr("Error: QCA provider plugin not found. It is usually provided by the qca-ossl plugin."));
+ emit displayMsg(NetworkInternalMessage(
+ Message::Error,
+ typeByTarget(bufname),
+ bufname,
+ tr("Error: QCA provider plugin not found. It is usually provided by the qca-ossl plugin.")
+ ));
return;
}
parms.prepend(bufferInfo.bufferName());
if (parms.isEmpty()) {
- emit displayMsg(Message::Info,
- typeByTarget(bufname),
- bufname,
- tr("[usage] /showkey <nick|channel> shows the encryption key for nick or channel or just /showkey when in a "
- "channel or query."));
+ emit displayMsg(NetworkInternalMessage(
+ Message::Info,
+ typeByTarget(bufname),
+ bufname,
+ tr("[usage] /showkey <nick|channel> shows the encryption key for nick or channel or just /showkey when in a "
+ "channel or query.")
+ ));
return;
}
QByteArray key = network()->cipherKey(target);
if (key.isEmpty()) {
- emit displayMsg(Message::Info, typeByTarget(bufname), bufname, tr("No key has been set for %1.").arg(target));
+ emit displayMsg(NetworkInternalMessage(
+ Message::Info,
+ typeByTarget(bufname),
+ bufname,
+ tr("No key has been set for %1.").arg(target)
+ ));
return;
}
- emit displayMsg(Message::Info,
- typeByTarget(bufname),
- bufname,
- tr("The key for %1 is %2:%3").arg(target, network()->cipherUsesCBC(target) ? "CBC" : "ECB", QString(key)));
+ emit displayMsg(NetworkInternalMessage(
+ Message::Info,
+ typeByTarget(bufname),
+ bufname,
+ tr("The key for %1 is %2:%3").arg(target, network()->cipherUsesCBC(target) ? "CBC" : "ECB", QString(key))
+ ));
#else
Q_UNUSED(msg)
- emit displayMsg(Message::Error,
- typeByTarget(bufname),
- bufname,
- tr("Error: Setting an encryption key requires Quassel to have been built "
- "with support for the Qt Cryptographic Architecture (QCA2) library. "
- "Contact your distributor about a Quassel package with QCA2 "
- "support, or rebuild Quassel with QCA2 present."));
+ emit displayMsg(NetworkInternalMessage(
+ Message::Error,
+ typeByTarget(bufname),
+ bufname,
+ tr("Error: Setting an encryption key requires Quassel to have been built "
+ "with support for the Qt Cryptographic Architecture (QCA2) library. "
+ "Contact your distributor about a Quassel package with QCA2 "
+ "support, or rebuild Quassel with QCA2 present.")
+ ));
#endif
}
// the stored command might be the result of an alias expansion, so we need to split it up again
QStringList commands = rawCommand.split(QRegExp("; ?"));
- foreach (QString command, commands) {
+ for (const QString& command : commands) {
handleUserInput(bufferInfo, command);
}
}
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
-#ifndef COREUSERINPUTHANDLER_H
-#define COREUSERINPUTHANDLER_H
+#pragma once
#include <utility>
QHash<int, Command> _delayedCommands;
};
-
-#endif
#include "eventmanager.h"
#include "ircdecoder.h"
#include "ircevent.h"
+#include "irctags.h"
#include "messageevent.h"
#include "networkevent.h"
Q_OBJECT
public:
- IrcParser(CoreSession* session);
+ explicit IrcParser(CoreSession* session);
inline CoreSession* coreSession() const { return _coreSession; }
inline EventManager* eventManager() const { return coreSession()->eventManager(); }
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2005-2019 by the Quassel Project *
+ * devel@quassel-irc.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) version 3. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#pragma once
+
+#include "irctag.h"
+
+/**
+ * This namespace contains commonly used message tags, similar to the IrcCaps
+ * namespace used for IRCv3 capabilities.
+ */
+namespace IrcTags
+{
+ /**
+ * Server time for messages.
+ *
+ * https://ircv3.net/specs/extensions/server-time-3.2.html
+ */
+ const IrcTagKey SERVER_TIME = IrcTagKey{"", "time", false};
+}