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