]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_alias.cpp
Don't send an override notice if no modes were actually applied, thanks Ankit.
[user/henk/code/inspircd.git] / src / modules / m_alias.cpp
index 06191a993538cb8049b48aad41edc00309c614d8..ad5f84034c7cf1e1b727d5a0e40fb8c7d453015f 100644 (file)
@@ -71,8 +71,8 @@ class ModuleAlias : public Module
                        a.ReplaceFormat = MyConf.ReadValue("alias", "replace", i, true);
                        a.RequiredNick = MyConf.ReadValue("alias", "requires", i);
                        a.ULineOnly = MyConf.ReadFlag("alias", "uline", i);
-                       a.ChannelCommand = MyConf.ReadFlag("alias", "channelcommand", i);
-                       a.UserCommand = MyConf.ReadFlag("alias", "usercommand", i);
+                       a.ChannelCommand = MyConf.ReadFlag("alias", "channelcommand", "no", i);
+                       a.UserCommand = MyConf.ReadFlag("alias", "usercommand", "yes", i);
                        a.OperOnly = MyConf.ReadFlag("alias", "operonly", i);
                        a.format = MyConf.ReadValue("alias", "format", i);
                        a.CaseSensitive = MyConf.ReadFlag("alias", "matchcase", i);
@@ -88,6 +88,7 @@ class ModuleAlias : public Module
                ReadAliases();
                Me->Modules->Attach(I_OnPreCommand, this);
                Me->Modules->Attach(I_OnRehash, this);
+               Me->Modules->Attach(I_OnUserPreMessage, this);
 
        }
 
@@ -166,7 +167,12 @@ class ModuleAlias : public Module
                while (i != Aliases.end())
                {
                        if (i->second.UserCommand)
-                               DoAlias(user, &(i->second), compare, safe);
+                       {
+                               if (DoAlias(user, NULL, &(i->second), compare, safe))
+                               {
+                                       return 1;
+                               }
+                       }
 
                        i++;
                }
@@ -175,26 +181,103 @@ class ModuleAlias : public Module
                return 1;
        }
 
-       void DoAlias(User *user, Alias *a, const std::string compare, const std::string safe)
+       virtual int OnUserPreMessage(User *user, void *dest, int target_type, std::string &text, char status, CUList &exempt_list)
+       {
+               if (target_type != TYPE_CHANNEL)
+               {
+                       ServerInstance->Logs->Log("FANTASY", DEBUG, "fantasy: not a channel msg");
+                       return 0;
+               }
+
+               // fcommands are only for local users. Spanningtree will send them back out as their original cmd.
+               if (!IS_LOCAL(user))
+               {
+                       ServerInstance->Logs->Log("FANTASY", DEBUG, "fantasy: not local");
+                       return 0;
+               }
+
+               Channel *c = (Channel *)dest;
+               std::string fcommand;
+
+               // text is like "!moo cows bite me", we want "!moo" first
+               irc::spacesepstream ss(text);
+               ss.GetToken(fcommand);
+
+               if (fcommand.empty())
+               {
+                       ServerInstance->Logs->Log("FANTASY", DEBUG, "fantasy: empty (?)");
+                       return 0; // wtfbbq
+               }
+
+               ServerInstance->Logs->Log("FANTASY", DEBUG, "fantasy: looking at fcommand %s", fcommand.c_str());
+
+               // we don't want to touch non-fantasy stuff
+               if (*fcommand.c_str() != '!')
+               {
+                       ServerInstance->Logs->Log("FANTASY", DEBUG, "fantasy: not a fcommand");
+                       return 0;
+               }
+
+               // nor do we give a shit about the !
+               fcommand.erase(fcommand.begin());
+               std::transform(fcommand.begin(), fcommand.end(), fcommand.begin(), ::toupper);
+               ServerInstance->Logs->Log("FANTASY", DEBUG, "fantasy: now got %s", fcommand.c_str());
+
+
+               std::multimap<std::string, Alias>::iterator i = Aliases.find(fcommand);
+
+               if (i == Aliases.end())
+                       return 0;
+
+
+               /* The parameters for the command in their original form, with the command stripped off */
+               std::string compare = text.substr(fcommand.length() + 1);
+               while (*(compare.c_str()) == ' ')
+                       compare.erase(compare.begin());
+
+               std::string safe(compare);
+
+               /* Escape out any $ symbols in the user provided text (ugly, but better than crashy) */
+               SearchAndReplace(safe, "$", "\r");
+
+               ServerInstance->Logs->Log("FANTASY", DEBUG, "fantasy: compare is %s and safe is %s", compare.c_str(), safe.c_str());
+
+               while (i != Aliases.end())
+               {
+                       if (i->second.ChannelCommand)
+                       {
+                               if (DoAlias(user, c, &(i->second), compare, safe))
+                                       return 0;
+                       }
+
+                       i++;
+               }
+               
+               return 0;
+       }
+
+
+       int DoAlias(User *user, Channel *c, Alias *a, const std::string compare, const std::string safe)
        {
                User *u = NULL;
+
                /* Does it match the pattern? */
                if (!a->format.empty())
                {
                        if (a->CaseSensitive)
                        {
                                if (InspIRCd::Match(compare, a->format, case_sensitive_map))
-                                       return;
+                                       return 0;
                        }
                        else
                        {
                                if (InspIRCd::Match(compare, a->format))
-                                       return;
+                                       return 0;
                        }
                }
 
                if ((a->OperOnly) && (!IS_OPER(user)))
-                       return;
+                       return 0;
 
                if (!a->RequiredNick.empty())
                {
@@ -202,7 +285,7 @@ class ModuleAlias : public Module
                        if (!u)
                        {
                                user->WriteNumeric(401, ""+std::string(user->nick)+" "+a->RequiredNick+" :is currently unavailable. Please try again later.");
-                               return;
+                               return 1;
                        }
                }
                if ((u != NULL) && (!a->RequiredNick.empty()) && (a->ULineOnly))
@@ -211,7 +294,7 @@ class ModuleAlias : public Module
                        {
                                ServerInstance->SNO->WriteToSnoMask('A', "NOTICE -- Service "+a->RequiredNick+" required by alias "+std::string(a->AliasedCommand.c_str())+" is not on a u-lined server, possibly underhanded antics detected!");
                                user->WriteNumeric(401, ""+std::string(user->nick)+" "+a->RequiredNick+" :is an imposter! Please inform an IRC operator as soon as possible.");
-                               return;
+                               return 1;
                        }
                }
 
@@ -221,8 +304,8 @@ class ModuleAlias : public Module
 
                if (crlf == std::string::npos)
                {
-                       DoCommand(a->ReplaceFormat, user, safe);
-                       return;
+                       DoCommand(a->ReplaceFormat, user, c, safe);
+                       return 1;
                }
                else
                {
@@ -230,13 +313,13 @@ class ModuleAlias : public Module
                        std::string scommand;
                        while (commands.GetToken(scommand))
                        {
-                               DoCommand(scommand, user, safe);
+                               DoCommand(scommand, user, c, safe);
                        }
-                       return;
+                       return 1;
                }
        }
 
-       void DoCommand(std::string newline, User* user, const std::string &original_line)
+       void DoCommand(std::string newline, User* user, Channel *c, const std::string &original_line)
        {
                std::vector<std::string> pars;
 
@@ -272,6 +355,12 @@ class ModuleAlias : public Module
                SearchAndReplace(newline, "$host", user->host);
                SearchAndReplace(newline, "$vhost", user->dhost);
 
+               if (c)
+               {
+                       /* Channel specific variables */
+                       SearchAndReplace(newline, "$chan", c->name);                    
+               }
+
                /* Unescape any variable names in the user text before sending */
                SearchAndReplace(newline, "\r", "$");