+ if (user->registered != REG_ALL)
+ return MOD_RES_PASSTHRU;
+
+ /* We dont have any commands looking like this? Stop processing. */
+ std::pair<AliasMap::iterator, AliasMap::iterator> iters = Aliases.equal_range(command);
+ if (iters.first == iters.second)
+ return MOD_RES_PASSTHRU;
+
+ /* The parameters for the command in their original form, with the command stripped off */
+ std::string original_line = CreateRFCMessage(command, parameters);
+ std::string compare(original_line, command.length());
+ while (*(compare.c_str()) == ' ')
+ compare.erase(compare.begin());
+
+ for (AliasMap::iterator i = iters.first; i != iters.second; ++i)
+ {
+ if (i->second.UserCommand)
+ {
+ if (DoAlias(user, NULL, &(i->second), compare, original_line))
+ {
+ return MOD_RES_DENY;
+ }
+ }
+ }
+
+ // If we made it here, no aliases actually matched.
+ return MOD_RES_PASSTHRU;
+ }
+
+ ModResult OnUserPreMessage(User* user, const MessageTarget& target, MessageDetails& details) CXX11_OVERRIDE
+ {
+ // Don't echo anything which is caused by an alias.
+ if (active)
+ details.echo = false;
+
+ return MOD_RES_PASSTHRU;
+ }
+
+ void OnUserPostMessage(User* user, const MessageTarget& target, const MessageDetails& details) CXX11_OVERRIDE
+ {
+ if ((target.type != MessageTarget::TYPE_CHANNEL) || (details.type != MSG_PRIVMSG))
+ {
+ return;
+ }
+
+ // fcommands are only for local users. Spanningtree will send them back out as their original cmd.
+ if (!IS_LOCAL(user))
+ {
+ return;
+ }
+
+ /* Stop here if the user is +B and allowbot is set to no. */
+ if (!AllowBots && user->IsModeSet(botmode))
+ {
+ return;
+ }
+
+ Channel *c = target.Get<Channel>();
+ std::string scommand;
+
+ // text is like "!moo cows bite me", we want "!moo" first
+ irc::spacesepstream ss(details.text);
+ ss.GetToken(scommand);
+
+ if (scommand.size() <= fprefix.size())
+ {
+ return; // wtfbbq
+ }
+
+ // we don't want to touch non-fantasy stuff
+ if (scommand.compare(0, fprefix.size(), fprefix) != 0)
+ {
+ return;
+ }
+
+ // nor do we give a shit about the prefix
+ scommand.erase(0, fprefix.size());
+
+ std::pair<AliasMap::iterator, AliasMap::iterator> iters = Aliases.equal_range(scommand);
+ if (iters.first == iters.second)
+ return;
+
+ /* The parameters for the command in their original form, with the command stripped off */
+ std::string compare(details.text, scommand.length() + fprefix.size());
+ while (*(compare.c_str()) == ' ')
+ compare.erase(compare.begin());
+
+ for (AliasMap::iterator i = iters.first; i != iters.second; ++i)
+ {
+ if (i->second.ChannelCommand)
+ {
+ // We use substr here to remove the fantasy prefix
+ if (DoAlias(user, c, &(i->second), compare, details.text.substr(fprefix.size())))
+ return;
+ }
+ }
+ }
+
+
+ int DoAlias(User *user, Channel *c, Alias *a, const std::string& compare, const std::string& safe)
+ {
+ std::string stripped(compare);
+ if (a->StripColor)
+ InspIRCd::StripColor(stripped);
+
+ /* Does it match the pattern? */
+ if (!a->format.empty())
+ {
+ if (!InspIRCd::Match(stripped, a->format))
+ return 0;
+ }
+
+ if ((a->OperOnly) && (!user->IsOper()))