X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fcommon%2Faliasmanager.cpp;h=a4a9d648b6e3f5f376df615440ba857da14e87d2;hp=002309ded98d838241ddaa9f48242fafd4fb6f10;hb=528e63d2bb9988f2f4cb47b94bd627300bf240ca;hpb=4a5065255e652dd0c301bac0db41b7afb777ef49 diff --git a/src/common/aliasmanager.cpp b/src/common/aliasmanager.cpp index 002309de..a4a9d648 100644 --- a/src/common/aliasmanager.cpp +++ b/src/common/aliasmanager.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005-2013 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 * @@ -18,25 +18,14 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ +#include "aliasmanager.h" + #include #include -#include "aliasmanager.h" #include "network.h" -INIT_SYNCABLE_OBJECT(AliasManager) -AliasManager &AliasManager::operator=(const AliasManager &other) -{ - if (this == &other) - return *this; - - SyncableObject::operator=(other); - _aliases = other._aliases; - return *this; -} - - -int AliasManager::indexOf(const QString &name) const +int AliasManager::indexOf(const QString& name) const { for (int i = 0; i < _aliases.count(); i++) { if (_aliases[i].name == name) @@ -45,7 +34,6 @@ int AliasManager::indexOf(const QString &name) const return -1; } - QVariantMap AliasManager::initAliases() const { QVariantMap aliases; @@ -62,14 +50,14 @@ QVariantMap AliasManager::initAliases() const return aliases; } - -void AliasManager::initSetAliases(const QVariantMap &aliases) +void AliasManager::initSetAliases(const QVariantMap& aliases) { QStringList names = aliases["names"].toStringList(); QStringList expansions = aliases["expansions"].toStringList(); if (names.count() != expansions.count()) { - qWarning() << "AliasesManager::initSetAliases: received" << names.count() << "alias names but only" << expansions.count() << "expansions!"; + qWarning() << "AliasesManager::initSetAliases: received" << names.count() << "alias names but only" << expansions.count() + << "expansions!"; return; } @@ -79,8 +67,7 @@ void AliasManager::initSetAliases(const QVariantMap &aliases) } } - -void AliasManager::addAlias(const QString &name, const QString &expansion) +void AliasManager::addAlias(const QString& name, const QString& expansion) { if (contains(name)) { return; @@ -91,48 +78,43 @@ void AliasManager::addAlias(const QString &name, const QString &expansion) SYNC(ARG(name), ARG(expansion)) } - AliasManager::AliasList AliasManager::defaults() { AliasList aliases; - aliases << Alias("j", "/join $0") - << Alias("ns", "/msg nickserv $0") - << Alias("nickserv", "/msg nickserv $0") - << Alias("cs", "/msg chanserv $0") - << Alias("chanserv", "/msg chanserv $0") - << Alias("hs", "/msg hostserv $0") - << Alias("hostserv", "/msg hostserv $0") - << Alias("back", "/quote away"); + aliases << Alias("j", "/join $0") << Alias("ns", "/quote nickserv $0") << Alias("nickserv", "/quote nickserv $0") + << Alias("cs", "/quote chanserv $0") << Alias("chanserv", "/quote chanserv $0") << Alias("hs", "/quote hostserv $0") + << Alias("hostserv", "/quote hostserv $0") << Alias("wii", "/whois $0 $0") << Alias("back", "/quote away") + << Alias("raw", "/quote $0"); #ifdef Q_OS_LINUX // let's add aliases for scripts that only run on linux - aliases << Alias("inxi", "/exec inxi $0") - << Alias("sysinfo", "/exec inxi -d"); + aliases << Alias("inxi", "/exec inxi $0") << Alias("sysinfo", "/exec inxi -d"); #endif return aliases; } - -AliasManager::CommandList AliasManager::processInput(const BufferInfo &info, const QString &msg) +AliasManager::CommandList AliasManager::processInput(const BufferInfo& info, const QString& msg) { CommandList result; processInput(info, msg, result); return result; } - -void AliasManager::processInput(const BufferInfo &info, const QString &msg_, CommandList &list) +void AliasManager::processInput(const BufferInfo& info, const QString& msg_, CommandList& list) { QString msg = msg_; // leading slashes indicate there's a command to call unless there is another one in the first section (like a path /proc/cpuinfo) + // For those habitally tied to irssi, "/ " also makes the rest of the line a literal message int secondSlashPos = msg.indexOf('/', 1); int firstSpacePos = msg.indexOf(' '); - if (!msg.startsWith('/') || (secondSlashPos != -1 && (secondSlashPos < firstSpacePos || firstSpacePos == -1))) { + if (!msg.startsWith('/') || firstSpacePos == 1 || (secondSlashPos != -1 && (secondSlashPos < firstSpacePos || firstSpacePos == -1))) { if (msg.startsWith("//")) - msg.remove(0, 1); // //asdf is transformed to /asdf - msg.prepend("/SAY "); // make sure we only send proper commands to the core + msg.remove(0, 1); // "//asdf" is transformed to "/asdf" + else if (msg.startsWith("/ ")) + msg.remove(0, 2); // "/ /asdf" is transformed to "/asdf" + msg.prepend("/SAY "); // make sure we only send proper commands to the core } else { // check for aliases @@ -148,16 +130,15 @@ void AliasManager::processInput(const BufferInfo &info, const QString &msg_, Com list.append(qMakePair(info, msg)); } - -void AliasManager::expand(const QString &alias, const BufferInfo &bufferInfo, const QString &msg, CommandList &list) +void AliasManager::expand(const QString& alias, const BufferInfo& bufferInfo, const QString& msg, CommandList& list) { - const Network *net = network(bufferInfo.networkId()); + const Network* net = network(bufferInfo.networkId()); if (!net) { // FIXME send error as soon as we have a method for that! return; } - QRegExp paramRangeR("\\$(\\d+)\\.\\.(\\d*)"); + QRegExp paramRangeR(R"(\$(\d+)\.\.(\d*))"); QStringList commands = alias.split(QRegExp("; ?")); QStringList params = msg.split(' '); QStringList expandedCommands; @@ -183,21 +164,49 @@ void AliasManager::expand(const QString &alias, const BufferInfo &bufferInfo, co } for (int j = params.count(); j > 0; j--) { - IrcUser *ircUser = net->ircUser(params[j - 1]); - command = command.replace(QString("$%1:hostname").arg(j), ircUser ? ircUser->host() : QString("*")); + // Find the referenced IRC user... + IrcUser* ircUser = net->ircUser(params[j - 1]); + // ...and replace components, using short-circuit evaluation as ircUser might be null + + // Account, or "*" if blank/nonexistent/logged out + command = command.replace(QString("$%1:account").arg(j), + (ircUser && !ircUser->account().isEmpty()) ? ircUser->account() : QString("*")); + + // Hostname, or "*" if blank/nonexistent + command = command.replace(QString("$%1:hostname").arg(j), + (ircUser && !ircUser->host().isEmpty()) ? ircUser->host() : QString("*")); + + // Identd + // Ident if verified, or "*" if blank/unknown/unverified (prefixed with "~") + // + // Most IRC daemons have the option to prefix an ident with "~" if it could not be + // verified via an identity daemon such as oidentd. In these cases, it can be handy to + // have a way to ban via ident if verified, or all idents if not verified. If the + // server does not verify idents, it usually won't add "~". + // + // Identd must be replaced before ident to avoid being treated as "$i:ident" + "d" + command = command.replace(QString("$%1:identd").arg(j), + (ircUser && !ircUser->user().isEmpty() && !ircUser->user().startsWith("~")) ? ircUser->user() + : QString("*")); + + // Ident, or "*" if blank/nonexistent + command = command.replace(QString("$%1:ident").arg(j), (ircUser && !ircUser->user().isEmpty()) ? ircUser->user() : QString("*")); + + // Nickname + // Must be replaced last to avoid interferring with more specific aliases command = command.replace(QString("$%1").arg(j), params[j - 1]); } command = command.replace("$0", msg); - command = command.replace("$channelname", bufferInfo.bufferName()); // legacy + command = command.replace("$channelname", bufferInfo.bufferName()); // legacy command = command.replace("$channel", bufferInfo.bufferName()); - command = command.replace("$currentnick", net->myNick()); // legacy + command = command.replace("$currentnick", net->myNick()); // legacy command = command.replace("$nick", net->myNick()); expandedCommands << command; } while (!expandedCommands.isEmpty()) { QString command; - if (expandedCommands[0].trimmed().toLower().startsWith("/wait")) { + if (expandedCommands[0].trimmed().toLower().startsWith("/wait ")) { command = expandedCommands.join("; "); expandedCommands.clear(); }