X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fcommon%2Faliasmanager.cpp;h=d8dd082f9119f8ae703031002c65e6ee1bc74a3f;hp=51f4af731242fb0bdc3a2bd148131b261a867d77;hb=cc6e7c08709c4e761e2fd9c2e322751015497003;hpb=694f9bfbf7f1af19108461c7e00d133e55082bce diff --git a/src/common/aliasmanager.cpp b/src/common/aliasmanager.cpp index 51f4af73..d8dd082f 100644 --- a/src/common/aliasmanager.cpp +++ b/src/common/aliasmanager.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005-09 by the Quassel Project * + * Copyright (C) 2005-2019 by the Quassel Project * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * @@ -15,17 +15,17 @@ * 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., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * 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) +AliasManager& AliasManager::operator=(const AliasManager& other) { if (this == &other) return *this; @@ -35,8 +35,7 @@ AliasManager &AliasManager::operator=(const AliasManager &other) 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 +44,6 @@ int AliasManager::indexOf(const QString &name) const return -1; } - QVariantMap AliasManager::initAliases() const { QVariantMap aliases; @@ -62,14 +60,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 +77,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 +88,42 @@ 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", "/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("wii", "/whois $0 $0") << Alias("back", "/quote away"); #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 +139,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 +173,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(); }