]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_swhois.cpp
Add support for OnWhoisLine, which allows modules to change or drop any line of whois...
[user/henk/code/inspircd.git] / src / modules / m_swhois.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev.
6  *                       E-mail:
7  *                <brain@chatspike.net>
8  *                <Craig@chatspike.net>
9  *     
10  * Written by Craig Edwards, Craig McLure, and others.
11  * This program is free but copyrighted software; see
12  *            the file COPYING for details.
13  *
14  * ---------------------------------------------------
15  */
16
17 #include "users.h"
18 #include "channels.h"
19 #include "modules.h"
20 #include "inspircd.h"
21
22 /* $ModDesc: Provides the SWHOIS command which allows setting of arbitary WHOIS lines */
23
24 /** Handle /SWHOIS
25  */
26 class cmd_swhois : public command_t
27 {
28         
29  public:
30         cmd_swhois (InspIRCd* Instance) : command_t(Instance,"SWHOIS",'o',2)
31         {
32                 this->source = "m_swhois.so";
33                 syntax = "<nick> <swhois>";
34         }
35
36         CmdResult Handle(const char** parameters, int pcnt, userrec* user)
37         {
38                 userrec* dest = ServerInstance->FindNick(parameters[0]);
39                 if(dest)
40                 {
41                         std::string line;
42                         for(int i = 1; i < pcnt; i++)
43                         {
44                                 if (i != 1)
45                                         line.append(" ");
46                                         
47                                 line.append(parameters[i]);
48                         }
49                         
50                         std::string* text;
51                         dest->GetExt("swhois", text);
52         
53                         if(text)
54                         {
55                                 // We already had it set...
56                                 
57                                 if (!ServerInstance->ULine(user->server))
58                                         // Ulines set SWHOISes silently
59                                         ServerInstance->WriteOpers("*** %s used SWHOIS to set %s's extra whois from '%s' to '%s'", user->nick, dest->nick, text->c_str(), line.c_str());
60                                 
61                                 dest->Shrink("swhois");
62                                 DELETE(text);
63                         }
64                         else if(!ServerInstance->ULine(user->server))
65                         {
66                                 // Ulines set SWHOISes silently
67                                 ServerInstance->WriteOpers("*** %s used SWHOIS to set %s's extra whois to '%s'", user->nick, dest->nick, line.c_str());
68                         }
69                         
70                         text = new std::string(line);
71                         dest->Extend("swhois", text);
72
73                         return CMD_SUCCESS;
74                 }
75
76                 return CMD_FAILURE;
77         }
78 };
79
80 class ModuleSWhois : public Module
81 {
82         cmd_swhois* mycommand;
83         
84         ConfigReader* Conf;
85         
86  public:
87         ModuleSWhois(InspIRCd* Me) : Module::Module(Me)
88         {
89                 
90                 Conf = new ConfigReader(ServerInstance);
91                 mycommand = new cmd_swhois(ServerInstance);
92                 ServerInstance->AddCommand(mycommand);
93         }
94
95         void OnRehash(const std::string &parameter)
96         {
97                 DELETE(Conf);
98                 Conf = new ConfigReader(ServerInstance);
99         }
100
101         void Implements(char* List)
102         {
103                 List[I_OnWhois] = List[I_OnSyncUserMetaData] = List[I_OnUserQuit] = List[I_OnCleanup] = List[I_OnRehash] = List[I_OnOper] = 1;
104         }
105
106         // :kenny.chatspike.net 320 Brain Azhrarn :is getting paid to play games.
107         virtual void OnWhois(userrec* source, userrec* dest)
108         {
109                 std::string* swhois;
110                 dest->GetExt("swhois", swhois);
111                 if (swhois)
112                 {
113                         ServerInstance->SendWhoisLine(source, 320, "%s %s :%s",source->nick,dest->nick,swhois->c_str());
114                 }
115         }
116
117         // Whenever the linking module wants to send out data, but doesnt know what the data
118         // represents (e.g. it is metadata, added to a userrec or chanrec by a module) then
119         // this method is called. We should use the ProtoSendMetaData function after we've
120         // corrected decided how the data should look, to send the metadata on its way if
121         // it is ours.
122         virtual void OnSyncUserMetaData(userrec* user, Module* proto, void* opaque, const std::string &extname)
123         {
124                 // check if the linking module wants to know about OUR metadata
125                 if (extname == "swhois")
126                 {
127                         // check if this user has an swhois field to send
128                         std::string* swhois;
129                         user->GetExt("swhois", swhois);
130                         if (swhois)
131                         {
132                                 // call this function in the linking module, let it format the data how it
133                                 // sees fit, and send it on its way. We dont need or want to know how.
134                                 proto->ProtoSendMetaData(opaque,TYPE_USER,user,extname,*swhois);
135                         }
136                 }
137         }
138
139         // when a user quits, tidy up their metadata
140         virtual void OnUserQuit(userrec* user, const std::string &message)
141         {
142                 std::string* swhois;
143                 user->GetExt("swhois", swhois);
144                 if (swhois)
145                 {
146                         user->Shrink("swhois");
147                         DELETE(swhois);
148                 }
149         }
150
151         // if the module is unloaded, tidy up all our dangling metadata
152         virtual void OnCleanup(int target_type, void* item)
153         {
154                 if (target_type == TYPE_USER)
155                 {
156                         userrec* user = (userrec*)item;
157                         std::string* swhois;
158                         user->GetExt("swhois", swhois);
159                         if (swhois)
160                         {
161                                 user->Shrink("swhois");
162                                 DELETE(swhois);
163                         }
164                 }
165         }
166
167         // Whenever the linking module receives metadata from another server and doesnt know what
168         // to do with it (of course, hence the 'meta') it calls this method, and it is up to each
169         // module in turn to figure out if this metadata key belongs to them, and what they want
170         // to do with it.
171         // In our case we're only sending a single string around, so we just construct a std::string.
172         // Some modules will probably get much more complex and format more detailed structs and classes
173         // in a textual way for sending over the link.
174         virtual void OnDecodeMetaData(int target_type, void* target, const std::string &extname, const std::string &extdata)
175         {
176                 // check if its our metadata key, and its associated with a user
177                 if ((target_type == TYPE_USER) && (extname == "swhois"))
178                 {
179                         userrec* dest = (userrec*)target;
180                         // if they dont already have an swhois field, accept the remote server's
181                         std::string* text;
182                         if (!dest->GetExt("swhois", text))
183                         {
184                                 std::string* text = new std::string(extdata);
185                                 dest->Extend("swhois",text);
186                         }
187                 }
188         }
189         
190         virtual void OnOper(userrec* user, const std::string &opertype)
191         {
192                 for(int i =0; i < Conf->Enumerate("type"); i++)
193                 {
194                         std::string type = Conf->ReadValue("type", "name", i);
195                         
196                         if(strcmp(type.c_str(), user->oper) == 0)
197                         {
198                                 std::string swhois = Conf->ReadValue("type", "swhois", i);
199                                 
200                                 if(swhois.length())
201                                 {
202                                         std::string* old;
203                                         if(user->GetExt("swhois", old))
204                                         {
205                                                 user->Shrink("swhois");
206                                                 DELETE(old);
207                                         }
208                         
209                                         std::string* text = new std::string(swhois);
210                                         user->Extend("swhois", text);
211                                         
212                                         break;
213                                 }
214                         }
215                 }               
216         }
217         
218         virtual ~ModuleSWhois()
219         {
220                 DELETE(Conf);
221         }
222         
223         virtual Version GetVersion()
224         {
225                 return Version(1,1,0,0,VF_VENDOR,API_VERSION);
226         }
227 };
228
229
230 class ModuleSWhoisFactory : public ModuleFactory
231 {
232  public:
233         ModuleSWhoisFactory()
234         {
235         }
236         
237         ~ModuleSWhoisFactory()
238         {
239         }
240         
241         virtual Module * CreateModule(InspIRCd* Me)
242         {
243                 return new ModuleSWhois(Me);
244         }
245         
246 };
247
248
249 extern "C" void * init_module( void )
250 {
251         return new ModuleSWhoisFactory;
252 }
253