]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_helpop.cpp
Merge pull request #92 from Robby-/insp20-headers
[user/henk/code/inspircd.git] / src / modules / m_helpop.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
5  *   Copyright (C) 2005-2009 Robin Burchell <robin+git@viroteck.net>
6  *   Copyright (C) 2004-2006, 2008 Craig Edwards <craigedwards@brainbox.cc>
7  *   Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
8  *   Copyright (C) 2004-2005 Craig McLure <craig@chatspike.net>
9  *
10  * This file is part of InspIRCd.  InspIRCd is free software: you can
11  * redistribute it and/or modify it under the terms of the GNU General Public
12  * License as published by the Free Software Foundation, version 2.
13  *
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
17  * details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  */
22
23
24 #include "inspircd.h"
25
26 static std::map<irc::string, std::string> helpop_map;
27
28 /** Handles user mode +h
29  */
30 class Helpop : public ModeHandler
31 {
32  public:
33         Helpop(Module* Creator) : ModeHandler(Creator, "helpop", 'h', PARAM_NONE, MODETYPE_USER)
34         {
35                 oper = true;
36         }
37
38         ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding)
39         {
40                 if (adding)
41                 {
42                         if (!dest->IsModeSet('h'))
43                         {
44                                 dest->SetMode('h',true);
45                                 return MODEACTION_ALLOW;
46                         }
47                 }
48                 else
49                 {
50                         if (dest->IsModeSet('h'))
51                         {
52                                 dest->SetMode('h',false);
53                                 return MODEACTION_ALLOW;
54                         }
55                 }
56
57                 return MODEACTION_DENY;
58         }
59 };
60
61 /** Handles /HELPOP
62  */
63 class CommandHelpop : public Command
64 {
65  public:
66         CommandHelpop(Module* Creator) : Command(Creator, "HELPOP", 0)
67         {
68                 syntax = "<any-text>";
69         }
70
71         CmdResult Handle (const std::vector<std::string> &parameters, User *user)
72         {
73                 irc::string parameter("start");
74                 if (parameters.size() > 0)
75                         parameter = parameters[0].c_str();
76
77                 if (parameter == "index")
78                 {
79                         /* iterate over all helpop items */
80                         user->WriteServ("290 %s :HELPOP topic index", user->nick.c_str());
81                         for (std::map<irc::string, std::string>::iterator iter = helpop_map.begin(); iter != helpop_map.end(); iter++)
82                         {
83                                 user->WriteServ("292 %s :  %s", user->nick.c_str(), iter->first.c_str());
84                         }
85                         user->WriteServ("292 %s :*** End of HELPOP topic index", user->nick.c_str());
86                 }
87                 else
88                 {
89                         user->WriteServ("290 %s :*** HELPOP for %s", user->nick.c_str(), parameter.c_str());
90                         user->WriteServ("292 %s : -", user->nick.c_str());
91
92                         std::map<irc::string, std::string>::iterator iter = helpop_map.find(parameter);
93
94                         if (iter == helpop_map.end())
95                         {
96                                 iter = helpop_map.find("nohelp");
97                         }
98
99                         std::string value = iter->second;
100                         irc::sepstream stream(value, '\n');
101                         std::string token = "*";
102
103                         while (stream.GetToken(token))
104                         {
105                                 // Writing a blank line will not work with some clients
106                                 if (token.empty())
107                                         user->WriteServ("292 %s : ", user->nick.c_str());
108                                 else
109                                         user->WriteServ("292 %s :%s", user->nick.c_str(), token.c_str());
110                         }
111
112                         user->WriteServ("292 %s : -", user->nick.c_str());
113                         user->WriteServ("292 %s :*** End of HELPOP", user->nick.c_str());
114                 }
115                 return CMD_SUCCESS;
116         }
117 };
118
119 class ModuleHelpop : public Module
120 {
121         private:
122                 std::string  h_file;
123                 CommandHelpop cmd;
124                 Helpop ho;
125
126         public:
127                 ModuleHelpop()
128                         : cmd(this), ho(this)
129                 {
130                 }
131
132                 void init()
133                 {
134                         ReadConfig();
135                         ServerInstance->Modules->AddService(ho);
136                         ServerInstance->Modules->AddService(cmd);
137                         Implementation eventlist[] = { I_OnRehash, I_OnWhois };
138                         ServerInstance->Modules->Attach(eventlist, this, 2);
139                 }
140
141                 void ReadConfig()
142                 {
143                         helpop_map.clear();
144
145                         ConfigTagList tags = ServerInstance->Config->ConfTags("helpop");
146                         for(ConfigIter i = tags.first; i != tags.second; ++i)
147                         {
148                                 ConfigTag* tag = i->second;
149                                 irc::string key = assign(tag->getString("key"));
150                                 std::string value;
151                                 tag->readString("value", value, true); /* Linefeeds allowed */
152
153                                 if (key == "index")
154                                 {
155                                         throw ModuleException("m_helpop: The key 'index' is reserved for internal purposes. Please remove it.");
156                                 }
157
158                                 helpop_map[key] = value;
159                         }
160
161                         if (helpop_map.find("start") == helpop_map.end())
162                         {
163                                 // error!
164                                 throw ModuleException("m_helpop: Helpop file is missing important entry 'start'. Please check the example conf.");
165                         }
166                         else if (helpop_map.find("nohelp") == helpop_map.end())
167                         {
168                                 // error!
169                                 throw ModuleException("m_helpop: Helpop file is missing important entry 'nohelp'. Please check the example conf.");
170                         }
171
172                 }
173
174                 void OnRehash(User* user)
175                 {
176                         ReadConfig();
177                 }
178
179                 void OnWhois(User* src, User* dst)
180                 {
181                         if (dst->IsModeSet('h'))
182                         {
183                                 ServerInstance->SendWhoisLine(src, dst, 310, std::string(src->nick)+" "+std::string(dst->nick)+" :is available for help.");
184                         }
185                 }
186
187                 Version GetVersion()
188                 {
189                         return Version("Provides the /HELPOP command, works like UnrealIRCd's helpop", VF_VENDOR);
190                 }
191 };
192
193 MODULE_INIT(ModuleHelpop)