The InspIRCd Project
Home | Developers | Wiki | Forums | Bug Tracker | SVN | Download
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

m_abbreviation.cpp

Go to the documentation of this file.
00001 /*       +------------------------------------+
00002  *       | Inspire Internet Relay Chat Daemon |
00003  *       +------------------------------------+
00004  *
00005  *  InspIRCd: (C) 2002-2008 InspIRCd Development Team
00006  * See: http://www.inspircd.org/wiki/index.php/Credits
00007  *
00008  * This program is free but copyrighted software; see
00009  *            the file COPYING for details.
00010  *
00011  * ---------------------------------------------------
00012  */
00013 
00014 #include "inspircd.h"
00015 
00016 /* $ModDesc: Provides the ability to abbreviate commands a-la BBC BASIC keywords. */
00017 
00018 class ModuleAbbreviation : public Module
00019 {
00020 
00021  public:
00022 
00023         ModuleAbbreviation(InspIRCd* Me)
00024                 : Module(Me)
00025         {
00026                 Me->Modules->Attach(I_OnPreCommand, this);
00027                 /* Must do this first */
00028                 Me->Modules->SetPriority(this, I_OnPreCommand, PRIO_FIRST);
00029         }
00030 
00031         virtual Version GetVersion()
00032         {
00033                 return Version("$Id: m_abbreviation.cpp 10291 2008-08-25 20:35:51Z w00t $",VF_VENDOR,API_VERSION);
00034         }
00035 
00036         virtual int OnPreCommand(std::string &command, std::vector<std::string> &parameters, User *user, bool validated, const std::string &original_line)
00037         {
00038                 /* Command is already validated, has a length of 0, or last character is not a . */
00039                 if (validated || command.empty() || *command.rbegin() != '.')
00040                         return 0;
00041 
00042                 /* Whack the . off the end */
00043                 command.erase(command.end() - 1);
00044 
00045                 /* Look for any command that starts with the same characters, if it does, replace the command string with it */
00046                 size_t clen = command.length();
00047                 std::string foundcommand, matchlist;
00048                 bool foundmatch = false;
00049                 for (Commandtable::iterator n = ServerInstance->Parser->cmdlist.begin(); n != ServerInstance->Parser->cmdlist.end(); ++n)
00050                 {
00051                         if (n->first.length() < clen)
00052                                 continue;
00053 
00054                         if (command == n->first.substr(0, clen))
00055                         {
00056                                 if (matchlist.length() > 450)
00057                                 {
00058                                         user->WriteNumeric(420, "%s :Ambiguous abbreviation and too many possible matches.", user->nick.c_str());
00059                                         return true;
00060                                 }
00061 
00062                                 if (!foundmatch)
00063                                 {
00064                                         /* Found the command */
00065                                         foundcommand = n->first;
00066                                         foundmatch = true;
00067                                 }
00068                                 else
00069                                         matchlist.append(" ").append(n->first);
00070                         }
00071                 }
00072 
00073                 /* Ambiguous command, list the matches */
00074                 if (!matchlist.empty())
00075                 {
00076                         user->WriteNumeric(420, "%s :Ambiguous abbreviation, posssible matches: %s%s", user->nick.c_str(), foundcommand.c_str(), matchlist.c_str());
00077                         return true;
00078                 }
00079 
00080                 if (foundcommand.empty())
00081                 {
00082                         /* No match, we have to put the . back again so that the invalid command numeric looks correct. */
00083                         command += '.';
00084                 }
00085                 else
00086                 {
00087                         command = foundcommand;
00088                 }
00089 
00090                 return false;
00091         }
00092 };
00093 
00094 MODULE_INIT(ModuleAbbreviation)