00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "inspircd.h"
00015
00016
00017
00020 class CommandTitle : public Command
00021 {
00022 public:
00023 CommandTitle (InspIRCd* Instance) : Command(Instance,"TITLE",0,2)
00024 {
00025 this->source = "m_customtitle.so";
00026 syntax = "<user> <password>";
00027 TRANSLATE3(TR_NICK, TR_TEXT, TR_END);
00028 }
00029
00030 bool OneOfMatches(const char* host, const char* ip, const char* hostlist)
00031 {
00032 std::stringstream hl(hostlist);
00033 std::string xhost;
00034 while (hl >> xhost)
00035 {
00036 if (InspIRCd::Match(host, xhost) || InspIRCd::MatchCIDR(ip,xhost))
00037 {
00038 return true;
00039 }
00040 }
00041 return false;
00042 }
00043
00044 CmdResult Handle(const std::vector<std::string> ¶meters, User* user)
00045 {
00046 if (!IS_LOCAL(user))
00047 return CMD_LOCALONLY;
00048
00049 char TheHost[MAXBUF];
00050 char TheIP[MAXBUF];
00051
00052 snprintf(TheHost,MAXBUF,"%s@%s",user->ident.c_str(), user->host.c_str());
00053 snprintf(TheIP, MAXBUF,"%s@%s",user->ident.c_str(), user->GetIPString());
00054
00055 ConfigReader Conf(ServerInstance);
00056 for (int i=0; i<Conf.Enumerate("title"); i++)
00057 {
00058 std::string name = Conf.ReadValue("title", "name", "", i);
00059 std::string pass = Conf.ReadValue("title", "password", "", i);
00060 std::string hash = Conf.ReadValue("title", "hash", "", i);
00061 std::string host = Conf.ReadValue("title", "host", "*@*", i);
00062 std::string title = Conf.ReadValue("title", "title", "", i);
00063 std::string vhost = Conf.ReadValue("title", "vhost", "", i);
00064
00065 if (!strcmp(name.c_str(),parameters[0].c_str()) && !ServerInstance->PassCompare(user, pass.c_str(), parameters[1].c_str(), hash.c_str()) && OneOfMatches(TheHost,TheIP,host.c_str()) && !title.empty())
00066 {
00067 std::string* text;
00068 if (user->GetExt("ctitle", text))
00069 {
00070 user->Shrink("ctitle");
00071 delete text;
00072 }
00073
00074 text = new std::string(title);
00075 user->Extend("ctitle", text);
00076
00077 ServerInstance->PI->SendMetaData(user, TYPE_USER, "ctitle", *text);
00078
00079 if (!vhost.empty())
00080 user->ChangeDisplayedHost(vhost.c_str());
00081
00082 if (!ServerInstance->ULine(user->server))
00083
00084 ServerInstance->SNO->WriteToSnoMask('A', "%s used TITLE to set custom title '%s'",user->nick.c_str(),title.c_str());
00085
00086 user->WriteServ("NOTICE %s :Custom title set to '%s'",user->nick.c_str(), title.c_str());
00087
00088 return CMD_SUCCESS;
00089 }
00090 }
00091
00092 if (!ServerInstance->ULine(user->server))
00093
00094 ServerInstance->SNO->WriteToSnoMask('A', "Failed TITLE attempt by %s!%s@%s using login '%s'", user->nick.c_str(), user->ident.c_str(), user->host.c_str(), parameters[0].c_str());
00095
00096 user->WriteServ("NOTICE %s :Invalid title credentials",user->nick.c_str());
00097 return CMD_SUCCESS;
00098 }
00099
00100 };
00101
00102 class ModuleCustomTitle : public Module
00103 {
00104 CommandTitle* mycommand;
00105
00106 public:
00107 ModuleCustomTitle(InspIRCd* Me) : Module(Me)
00108 {
00109
00110 mycommand = new CommandTitle(ServerInstance);
00111 ServerInstance->AddCommand(mycommand);
00112 Implementation eventlist[] = { I_OnDecodeMetaData, I_OnWhoisLine, I_OnSyncUserMetaData, I_OnUserQuit, I_OnCleanup };
00113 ServerInstance->Modules->Attach(eventlist, this, 5);
00114 }
00115
00116
00117
00118 int OnWhoisLine(User* user, User* dest, int &numeric, std::string &text)
00119 {
00120
00121 if (numeric == 312)
00122 {
00123
00124 std::string* ctitle;
00125 if (dest->GetExt("ctitle", ctitle))
00126 {
00127 ServerInstance->SendWhoisLine(user, dest, 320, "%s %s :%s",user->nick.c_str(), dest->nick.c_str(), ctitle->c_str());
00128 }
00129 }
00130
00131 return 0;
00132 }
00133
00134
00135
00136
00137
00138
00139 virtual void OnSyncUserMetaData(User* user, Module* proto, void* opaque, const std::string &extname, bool displayable)
00140 {
00141
00142 if (extname == "ctitle")
00143 {
00144
00145 std::string* ctitle;
00146 if (user->GetExt("ctitle", ctitle))
00147 {
00148
00149
00150 proto->ProtoSendMetaData(opaque,TYPE_USER,user,extname,*ctitle);
00151 }
00152 }
00153 }
00154
00155
00156 virtual void OnUserQuit(User* user, const std::string &message, const std::string &oper_message)
00157 {
00158 std::string* ctitle;
00159 if (user->GetExt("ctitle", ctitle))
00160 {
00161 user->Shrink("ctitle");
00162 delete ctitle;
00163 }
00164 }
00165
00166
00167 virtual void OnCleanup(int target_type, void* item)
00168 {
00169 if (target_type == TYPE_USER)
00170 {
00171 User* user = (User*)item;
00172 std::string* ctitle;
00173 if (user->GetExt("ctitle", ctitle))
00174 {
00175 user->Shrink("ctitle");
00176 delete ctitle;
00177 }
00178 }
00179 }
00180
00181
00182
00183
00184
00185
00186
00187
00188 virtual void OnDecodeMetaData(int target_type, void* target, const std::string &extname, const std::string &extdata)
00189 {
00190
00191 if ((target_type == TYPE_USER) && (extname == "ctitle"))
00192 {
00193 User* dest = (User*)target;
00194
00195 std::string* text;
00196 if (!dest->GetExt("ctitle", text))
00197 {
00198 std::string* ntext = new std::string(extdata);
00199 dest->Extend("ctitle",ntext);
00200 }
00201 }
00202 }
00203
00204 virtual ~ModuleCustomTitle()
00205 {
00206 }
00207
00208 virtual Version GetVersion()
00209 {
00210 return Version("$Id: m_customtitle.cpp 10292 2008-08-25 20:38:22Z w00t $", VF_COMMON | VF_VENDOR, API_VERSION);
00211 }
00212 };
00213
00214 MODULE_INIT(ModuleCustomTitle)