+ private:
+
+ char fprefix;
+
+ /* We cant use a map, there may be multiple aliases with the same name.
+ * We can, however, use a fancy invention: the multimap. Maps a key to one or more values.
+ * -- w00t
+ */
+ std::multimap<std::string, Alias> Aliases;
+
+ /* whether or not +B users are allowed to use fantasy commands */
+ bool AllowBots;
+
+ virtual void ReadAliases()
+ {
+ ConfigReader MyConf(ServerInstance);
+
+ AllowBots = MyConf.ReadFlag("fantasy", "allowbots", "no", 0);
+
+ std::string fpre = MyConf.ReadValue("fantasy","prefix",0);
+ fprefix = fpre.empty() ? '!' : fpre[0];
+
+ Aliases.clear();
+ for (int i = 0; i < MyConf.Enumerate("alias"); i++)
+ {
+ Alias a;
+ std::string txt;
+ txt = MyConf.ReadValue("alias", "text", i);
+ a.AliasedCommand = txt.c_str();
+ 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", "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);
+ Aliases.insert(std::make_pair(txt, a));
+ }
+ }
+
+ public:
+
+ ModuleAlias(InspIRCd* Me)
+ : Module(Me)
+ {
+ ReadAliases();
+ Me->Modules->Attach(I_OnPreCommand, this);
+ Me->Modules->Attach(I_OnRehash, this);
+ Me->Modules->Attach(I_OnUserPreMessage, this);
+
+ }
+
+ virtual ~ModuleAlias()
+ {
+ }
+
+ virtual Version GetVersion()
+ {
+ return Version("$Id$", VF_VENDOR,API_VERSION);
+ }
+
+ std::string GetVar(std::string varname, const std::string &original_line)
+ {
+ irc::spacesepstream ss(original_line);
+ varname.erase(varname.begin());
+ int index = *(varname.begin()) - 48;
+ varname.erase(varname.begin());
+ bool everything_after = (varname == "-");
+ std::string word;
+
+ for (int j = 0; j < index; j++)
+ ss.GetToken(word);
+
+ if (everything_after)
+ {
+ std::string more;
+ while (ss.GetToken(more))
+ {
+ word.append(" ");
+ word.append(more);
+ }
+ }
+
+ return word;
+ }
+
+ virtual int OnPreCommand(std::string &command, std::vector<std::string> ¶meters, User *user, bool validated, const std::string &original_line)
+ {
+ std::multimap<std::string, Alias>::iterator i, upperbound;
+
+ /* If theyre not registered yet, we dont want
+ * to know.
+ */
+ if (user->registered != REG_ALL)
+ return 0;
+
+ /* We dont have any commands looking like this? Stop processing. */
+ i = Aliases.find(command);
+ if (i == Aliases.end())
+ return 0;
+ /* Avoid iterating on to different aliases if no patterns match. */
+ upperbound = Aliases.upper_bound(command);
+
+ irc::string c = command.c_str();
+ /* The parameters for the command in their original form, with the command stripped off */
+ std::string compare = original_line.substr(command.length());
+ while (*(compare.c_str()) == ' ')
+ compare.erase(compare.begin());
+
+ while (i != upperbound)
+ {
+ if (i->second.UserCommand)