]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_helpop.cpp
Decide that it wasn't quite appropriate :(
[user/henk/code/inspircd.git] / src / modules / m_helpop.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 using namespace std;
18
19 #include "users.h"
20 #include "channels.h"
21 #include "modules.h"
22 #include "helperfuncs.h"
23
24 // Global Vars
25 /* XXX - should all this be marked static? clear the global namespace, etc. */
26 ConfigReader *helpop;
27 Server *Srv;
28
29 void handle_helpop(char**, int, userrec*);
30 bool do_helpop(char**, int, userrec*);
31 void sendtohelpop(userrec*, int, char**);
32
33 /* $ModDesc: /helpop Command, Works like Unreal helpop */
34
35 class cmd_helpop : public command_t
36 {
37  public:
38          cmd_helpop () : command_t("HELPOP",0,0)
39          {
40                  this->source = "m_helpop.so";
41          }
42
43         void Handle (char **parameters, int pcnt, userrec *user)
44         {
45                 char a[MAXBUF];
46                 std::string output = " ";
47
48                 if (!helpop)
49                         return;
50
51                 if (pcnt < 1)
52                 {
53                         do_helpop(NULL,pcnt,user);
54                         return;
55                 }
56
57                 if (parameters[0][0] == '!')
58                 {
59                         // Force send to all +h users
60                         sendtohelpop(user, pcnt, parameters);
61                 }
62                 else if (parameters[0][0] == '?')
63                 {
64                         // Force to the helpop system with no forward if not found.
65                         if (do_helpop(parameters, pcnt, user) == false)
66                         {
67                                 // Not handled by the Database, Tell the user, and bail.
68                                 for (int i = 1; output != ""; i++)
69                                 {
70                                         snprintf(a,MAXBUF,"line%d",i);
71                                         output = helpop->ReadValue("nohelp", std::string(a), 0);
72         
73                                         if(output != "")
74                                         {
75                                                 Srv->SendTo(NULL,user,"290 "+std::string(user->nick)+" :"+output);
76                                         }
77                                 }
78                         }
79                 }
80                 else
81                 {
82                         // Check with the helpop database, if not found send to +h
83                         if (do_helpop(parameters, pcnt, user) == false)
84                         {
85                                 // Not handled by the Database, Tell the user, and forward.
86                                 for (int i = 1; output != ""; i++)
87                                 {
88                                         snprintf(a,MAXBUF,"line%d",i);
89                                         /* "nohelpo" for opers "nohelp" for users */
90                                         output = helpop->ReadValue("nohelpo", std::string(a), 0);
91                                         if (output != "")
92                                         {
93                                                 Srv->SendTo(NULL,user,"290 "+std::string(user->nick)+" :"+output);
94                                         }
95                                 }
96                                 // Forward.
97                                 sendtohelpop(user, pcnt, parameters);
98                         }
99                 }
100         }
101 };
102
103
104 bool do_helpop(char **parameters, int pcnt, userrec *src)
105 {
106         char *search;
107         std::string output = " "; // a fix bought to you by brain :p
108         char a[MAXBUF];
109         char lower[MAXBUF];
110         int nlines = 0;
111
112         if (!parameters)
113         {
114                 search = "start";
115         }
116         else
117         {
118                 search = parameters[0];
119         }
120
121         if (search[0] == '?')
122         {
123                 search++;
124         }
125
126         /* XXX - don't we have an strtolower()? if not, might pay to add one.. that works on char *, preferably.. */
127         strlcpy(lower, search, MAXBUF);
128         for (unsigned int t = 0; t < strlen(lower); t++)
129                 lower[t] = tolower(lower[t]);
130
131
132         for (int i = 1; output != ""; i++)
133         {
134                 snprintf(a,MAXBUF,"line%d",i);
135                 output = helpop->ReadValue(lower, a, 0);
136                 if (output != "")
137                 {
138                         Srv->SendTo(NULL,src,"290 "+std::string(src->nick)+" :"+output);
139                         nlines++;
140                 }
141         }
142         return (nlines>0);
143 }
144
145
146
147 void sendtohelpop(userrec *src, int pcnt, char **params)
148 {
149         char* first = params[0];
150         if (*first == '!')
151         {
152                 first++;
153         }
154
155         std::string line = "*** HELPOPS - From "+std::string(src->nick)+": "+std::string(first)+" ";
156         for (int i = 1; i < pcnt; i++)
157         {
158                 line = line + std::string(params[i]) + " ";
159         }
160         Srv->SendToModeMask("oh",WM_AND,line);
161 }
162
163 class HelpopException : public ModuleException
164 {
165  private:
166         std::string err;
167  public:
168         HelpopException(std::string message) : err(message) { }
169         virtual char* GetReason() { return (char*)err.c_str(); }
170 };
171
172 class ModuleHelpop : public Module
173 {
174         private:
175                 ConfigReader *conf;
176                 std::string  h_file;
177                 cmd_helpop* mycommand;
178
179         public:
180                 ModuleHelpop(Server* Me)
181                         : Module::Module(Me)
182                 {
183                         Srv  = Me;
184
185                         ReadConfig();
186                         if (!Srv->AddExtendedMode('h',MT_CLIENT,true,0,0))
187                         {
188                                 Srv->Log(DEFAULT,"Unable to claim the +h usermode.");
189                                 return;
190                         }
191
192                         mycommand = new cmd_helpop();
193                         Srv->AddCommand(mycommand);
194                 }
195
196                 virtual void ReadConfig()
197                 {
198                         conf = new ConfigReader;
199                         h_file = conf->ReadValue("helpop", "file", 0);
200
201                         if (h_file == "")
202                         {
203                                 helpop = NULL;
204                                 HelpopException e("Missing helpop file");
205                                 throw(e);
206                         }
207
208                         helpop = new ConfigReader(h_file);
209                         if ((helpop->ReadValue("nohelp",  "line1", 0) == "") ||
210                                 (helpop->ReadValue("nohelpo", "line1", 0) == "") ||
211                                 (helpop->ReadValue("start",   "line1", 0) == ""))
212                         {
213                                 HelpopException e("m_helpop: Helpop file is missing important entries. Please check the example conf.");
214                                 throw(e);
215                         }
216                 }
217
218                 void Implements(char* List)
219                 {
220                         List[I_OnRehash] = List[I_OnExtendedMode] = List[I_OnWhois] = 1;
221                 }
222
223                 virtual void OnRehash(std::string parameter)
224                 {
225                         delete conf;
226                         if (helpop)
227                                 delete helpop;
228
229                         ReadConfig();
230                 }
231
232                 virtual int OnExtendedMode(userrec* user, void* target, char modechar, int type, bool mode_on, string_list &params)
233                 {
234                         if ((modechar == 'h') && (type == MT_CLIENT))
235                         {
236                                 return 1;
237                         }
238                         return 0;
239                 }
240
241                 virtual void OnWhois(userrec* src, userrec* dst)
242                 {
243                         if (strchr(dst->modes,'h'))
244                         {
245                                 Srv->SendTo(NULL,src,"310 "+std::string(src->nick)+" "+std::string(dst->nick)+" :is available for help.");
246                         }
247                 }
248
249                 virtual ~ModuleHelpop()
250                 {
251                         delete conf;
252                         delete helpop;
253                 }
254         
255                 virtual Version GetVersion()
256                 {
257                         return Version(1,0,0,1,VF_STATIC|VF_VENDOR);
258                 }
259 };
260
261 class ModuleHelpopFactory : public ModuleFactory
262 {
263  public:
264         ModuleHelpopFactory()
265         {
266         }
267         
268         ~ModuleHelpopFactory()
269         {
270         }
271         
272         virtual Module * CreateModule(Server* Me)
273         {
274                 return new ModuleHelpop(Me);
275         }
276         
277 };
278
279 extern "C" void * init_module( void )
280 {
281         return new ModuleHelpopFactory;
282 }