Anope IRC Services  Version 2.0
ms_set.cpp
Go to the documentation of this file.
1 /* MemoServ core functions
2  *
3  * (C) 2003-2014 Anope Team
4  * Contact us at team@anope.org
5  *
6  * Please read COPYING and README for further details.
7  *
8  * Based on the original code of Epona by Lara.
9  * Based on the original code of Services by Andy Church.
10  */
11 
12 #include "module.h"
13 
14 class CommandMSSet : public Command
15 {
16  private:
17  void DoNotify(CommandSource &source, const std::vector<Anope::string> &params, MemoInfo *mi)
18  {
19  const Anope::string &param = params[1];
20  NickCore *nc = source.nc;
21  BotInfo *MemoServ = Config->GetClient("MemoServ");
22 
23  if (!MemoServ)
24  return;
25 
26  if (param.equals_ci("ON"))
27  {
28  nc->Extend<bool>("MEMO_SIGNON");
29  nc->Extend<bool>("MEMO_RECEIVE");
30  source.Reply(_("%s will now notify you of memos when you log on and when they are sent to you."), MemoServ->nick.c_str());
31  }
32  else if (param.equals_ci("LOGON"))
33  {
34  nc->Extend<bool>("MEMO_SIGNON");
35  nc->Shrink<bool>("MEMO_RECEIVE");
36  source.Reply(_("%s will now notify you of memos when you log on or unset /AWAY."), MemoServ->nick.c_str());
37  }
38  else if (param.equals_ci("NEW"))
39  {
40  nc->Shrink<bool>("MEMO_SIGNON");
41  nc->Extend<bool>("MEMO_RECEIVE");
42  source.Reply(_("%s will now notify you of memos when they are sent to you."), MemoServ->nick.c_str());
43  }
44  else if (param.equals_ci("MAIL"))
45  {
46  if (!nc->email.empty())
47  {
48  nc->Extend<bool>("MEMO_MAIL");
49  source.Reply(_("You will now be informed about new memos via email."));
50  }
51  else
52  source.Reply(_("There's no email address set for your nick."));
53  }
54  else if (param.equals_ci("NOMAIL"))
55  {
56  nc->Shrink<bool>("MEMO_MAIL");
57  source.Reply(_("You will no longer be informed via email."));
58  }
59  else if (param.equals_ci("OFF"))
60  {
61  nc->Shrink<bool>("MEMO_SIGNON");
62  nc->Shrink<bool>("MEMO_RECEIVE");
63  nc->Shrink<bool>("MEMO_MAIL");
64  source.Reply(_("%s will not send you any notification of memos."), MemoServ->nick.c_str());
65  }
66  else
67  this->OnSyntaxError(source, "");
68  }
69 
70  void DoLimit(CommandSource &source, const std::vector<Anope::string> &params, MemoInfo *mi)
71  {
72 
73  Anope::string p1 = params[1];
74  Anope::string p2 = params.size() > 2 ? params[2] : "";
75  Anope::string p3 = params.size() > 3 ? params[3] : "";
76  Anope::string user, chan;
77  int16_t limit;
78  NickCore *nc = source.nc;
79  ChannelInfo *ci = NULL;
80  bool is_servadmin = source.HasPriv("memoserv/set-limit");
81 
82  if (p1[0] == '#')
83  {
84  chan = p1;
85  p1 = p2;
86  p2 = p3;
87  p3 = params.size() > 4 ? params[4] : "";
88 
89  ci = ChannelInfo::Find(chan);
90  if (!ci)
91  {
92  source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
93  return;
94  }
95  else if (!is_servadmin && !source.AccessFor(ci).HasPriv("MEMO"))
96  {
97  source.Reply(ACCESS_DENIED);
98  return;
99  }
100  mi = &ci->memos;
101  }
102  if (is_servadmin)
103  {
104  if (!p2.empty() && !p2.equals_ci("HARD") && chan.empty())
105  {
106  const NickAlias *na;
107  if (!(na = NickAlias::Find(p1)))
108  {
109  source.Reply(NICK_X_NOT_REGISTERED, p1.c_str());
110  return;
111  }
112  user = p1;
113  mi = &na->nc->memos;
114  nc = na->nc;
115  p1 = p2;
116  p2 = p3;
117  }
118  else if (p1.empty() || (!p1.is_pos_number_only() && !p1.equals_ci("NONE")) || (!p2.empty() && !p2.equals_ci("HARD")))
119  {
120  this->OnSyntaxError(source, "");
121  return;
122  }
123  if (!chan.empty())
124  {
125  if (!p2.empty())
126  ci->Extend<bool>("MEMO_HARDMAX");
127  else
128  ci->Shrink<bool>("MEMO_HARDMAX");
129  }
130  else
131  {
132  if (!p2.empty())
133  nc->Extend<bool>("MEMO_HARDMAX");
134  else
135  nc->Shrink<bool>("MEMO_HARDMAX");
136  }
137  limit = -1;
138  try
139  {
140  limit = convertTo<int16_t>(p1);
141  }
142  catch (const ConvertException &) { }
143  }
144  else
145  {
146  if (p1.empty() || !p2.empty() || !isdigit(p1[0]))
147  {
148  this->OnSyntaxError(source, "");
149  return;
150  }
151  if (!chan.empty() && ci->HasExt("MEMO_HARDMAX"))
152  {
153  source.Reply(_("The memo limit for %s may not be changed."), chan.c_str());
154  return;
155  }
156  else if (chan.empty() && nc->HasExt("MEMO_HARDMAX"))
157  {
158  source.Reply(_("You are not permitted to change your memo limit."));
159  return;
160  }
161  int max_memos = Config->GetModule("memoserv")->Get<int>("maxmemos");
162  limit = -1;
163  try
164  {
165  limit = convertTo<int16_t>(p1);
166  }
167  catch (const ConvertException &) { }
168  /* The first character is a digit, but we could still go negative
169  * from overflow... watch out! */
170  if (limit < 0 || (max_memos > 0 && limit > max_memos))
171  {
172  if (!chan.empty())
173  source.Reply(_("You cannot set the memo limit for %s higher than %d."), chan.c_str(), max_memos);
174  else
175  source.Reply(_("You cannot set your memo limit higher than %d."), max_memos);
176  return;
177  }
178  }
179  mi->memomax = limit;
180  if (limit > 0)
181  {
182  if (chan.empty() && nc == source.nc)
183  source.Reply(_("Your memo limit has been set to \002%d\002."), limit);
184  else
185  source.Reply(_("Memo limit for %s set to \002%d\002."), !chan.empty() ? chan.c_str() : user.c_str(), limit);
186  }
187  else if (!limit)
188  {
189  if (chan.empty() && nc == source.nc)
190  source.Reply(_("You will no longer be able to receive memos."));
191  else
192  source.Reply(_("Memo limit for %s set to \0020\002."), !chan.empty() ? chan.c_str() : user.c_str());
193  }
194  else
195  {
196  if (chan.empty() && nc == source.nc)
197  source.Reply(_("Your memo limit has been disabled."));
198  else
199  source.Reply(_("Memo limit \002disabled\002 for %s."), !chan.empty() ? chan.c_str() : user.c_str());
200  }
201  return;
202  }
203  public:
204  CommandMSSet(Module *creator) : Command(creator, "memoserv/set", 2, 5)
205  {
206  this->SetDesc(_("Set options related to memos"));
207  this->SetSyntax(_("\037option\037 \037parameters\037"));
208  }
209 
210  void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
211  {
212  const Anope::string &cmd = params[0];
213  MemoInfo *mi = &source.nc->memos;
214 
215  if (Anope::ReadOnly)
216  source.Reply(_("Sorry, memo option setting is temporarily disabled."));
217  else if (cmd.equals_ci("NOTIFY"))
218  return this->DoNotify(source, params, mi);
219  else if (cmd.equals_ci("LIMIT"))
220  return this->DoLimit(source, params, mi);
221  else
222  {
223  this->OnSyntaxError(source, "");
224  }
225 
226  return;
227  }
228 
229  bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
230  {
231  if (subcommand.empty())
232  {
233  this->SendSyntax(source);
234  source.Reply(" ");
235  source.Reply(_("Sets various memo options. \037option\037 can be one of:\n"
236  " \n"
237  " NOTIFY Changes when you will be notified about\n"
238  " new memos (only for nicknames)\n"
239  " LIMIT Sets the maximum number of memos you can\n"
240  " receive\n"
241  " \n"
242  "Type \002%s%s HELP %s \037option\037\002 for more information\n"
243  "on a specific option."), Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), source.command.c_str());
244  }
245  else if (subcommand.equals_ci("NOTIFY"))
246  source.Reply(_("Syntax: \002NOTIFY {ON | LOGON | NEW | MAIL | NOMAIL | OFF}\002\n"
247  " \n"
248  "Changes when you will be notified about new memos:\n"
249  " \n"
250  " ON You will be notified of memos when you log on,\n"
251  " when you unset /AWAY, and when they are sent\n"
252  " to you.\n"
253  " LOGON You will only be notified of memos when you log\n"
254  " on or when you unset /AWAY.\n"
255  " NEW You will only be notified of memos when they\n"
256  " are sent to you.\n"
257  " MAIL You will be notified of memos by email aswell as\n"
258  " any other settings you have.\n"
259  " NOMAIL You will not be notified of memos by email.\n"
260  " OFF You will not receive any notification of memos.\n"
261  " \n"
262  "\002ON\002 is essentially \002LOGON\002 and \002NEW\002 combined."));
263  else if (subcommand.equals_ci("LIMIT"))
264  {
265  int max_memos = Config->GetModule("memoserv")->Get<int>("maxmemos");
266  if (source.IsServicesOper())
267  source.Reply(_("Syntax: \002LIMIT [\037user\037 | \037channel\037] {\037limit\037 | NONE} [HARD]\002\n"
268  " \n"
269  "Sets the maximum number of memos a user or channel is\n"
270  "allowed to have. Setting the limit to 0 prevents the user\n"
271  "from receiving any memos; setting it to \002NONE\002 allows the\n"
272  "user to receive and keep as many memos as they want. If\n"
273  "you do not give a nickname or channel, your own limit is\n"
274  "set.\n"
275  " \n"
276  "Adding \002HARD\002 prevents the user from changing the limit. Not\n"
277  "adding \002HARD\002 has the opposite effect, allowing the user to\n"
278  "change the limit (even if a previous limit was set with\n"
279  "\002HARD\002).\n"
280  " \n"
281  "This use of the \002SET LIMIT\002 command is limited to \002Services\002\n"
282  "\002Operators\002. Other users may only enter a limit for themselves\n"
283  "or a channel on which they have such privileges, may not\n"
284  "remove their limit, may not set a limit above %d, and may\n"
285  "not set a hard limit."), max_memos);
286  else
287  source.Reply(_("Syntax: \002LIMIT [\037channel\037] \037limit\037\002\n"
288  " \n"
289  "Sets the maximum number of memos you (or the given channel)\n"
290  "are allowed to have. If you set this to 0, no one will be\n"
291  "able to send any memos to you. However, you cannot set\n"
292  "this any higher than %d."), max_memos);
293  }
294  else
295  return false;
296 
297  return true;
298  }
299 };
300 
301 class MSSet : public Module
302 {
305 
306  public:
307  MSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
308  commandmsset(this), memo_signon(this, "MEMO_SIGNON"), memo_receive(this, "MEMO_RECEIVE"), memo_mail(this, "MEMO_MAIL"),
309  memo_hardmax(this, "MEMO_HARDMAX")
310  {
311 
312  }
313 };
314 
Serialize::Reference< NickCore > nc
Definition: account.h:47
Definition: bots.h:24
void DoLimit(CommandSource &source, const std::vector< Anope::string > &params, MemoInfo *mi)
Definition: ms_set.cpp:70
CoreExport bool ReadOnly
Definition: main.cpp:28
static NickAlias * Find(const Anope::string &nick)
Definition: nickalias.cpp:121
CommandMSSet commandmsset
Definition: ms_set.cpp:303
Definition: hashcomp.h:84
bool is_pos_number_only() const
Definition: anope.h:218
#define ACCESS_DENIED
Definition: language.h:73
CommandMSSet(Module *creator)
Definition: ms_set.cpp:204
T * Extend(const Anope::string &name, const T &what)
Definition: extensible.h:224
#define NICK_X_NOT_REGISTERED
Definition: language.h:79
SerializableExtensibleItem< bool > memo_signon
Definition: ms_set.cpp:304
void SetDesc(const Anope::string &d)
Definition: command.cpp:130
bool equals_ci(const char *_str) const
Definition: anope.h:78
SerializableExtensibleItem< bool > memo_receive
Definition: ms_set.cpp:304
bool HasPriv(const Anope::string &priv) const
Definition: access.cpp:384
SerializableExtensibleItem< bool > memo_mail
Definition: ms_set.cpp:304
void Execute(CommandSource &source, const std::vector< Anope::string > &params) anope_override
Definition: ms_set.cpp:210
static ChannelInfo * Find(const Anope::string &name)
Definition: regchannel.cpp:630
SerializableExtensibleItem< bool > memo_hardmax
Definition: ms_set.cpp:304
Definition: Config.cs:26
void Shrink(const Anope::string &name)
Definition: extensible.h:253
virtual void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
Definition: command.cpp:191
Definition: memo.h:40
void Reply(const char *message,...)
Definition: command.cpp:96
bool HasPriv(const Anope::string &cmd)
Definition: command.cpp:69
#define anope_override
Definition: services.h:56
bool empty() const
Definition: anope.h:126
MemoInfo memos
Definition: regchannel.h:77
#define MODULE_INIT(x)
Definition: modules.h:45
MSSet(const Anope::string &modname, const Anope::string &creator)
Definition: ms_set.cpp:307
void SetSyntax(const Anope::string &s)
Definition: command.cpp:140
void DoNotify(CommandSource &source, const std::vector< Anope::string > &params, MemoInfo *mi)
Definition: ms_set.cpp:17
int16_t memomax
Definition: memo.h:42
#define CHAN_X_NOT_REGISTERED
Definition: language.h:84
Anope::string nick
Definition: users.h:62
AccessGroup AccessFor(ChannelInfo *ci)
Definition: command.cpp:41
Serialize::Checker< std::vector< Memo * > > memos
Definition: memo.h:43
Reference< NickCore > nc
Definition: commands.h:61
void SendSyntax(CommandSource &)
Definition: command.cpp:145
const char * c_str() const
Definition: anope.h:117
Anope::string email
Definition: account.h:116
#define _(x)
Definition: services.h:50
bool HasExt(const Anope::string &name) const
Definition: extensible.cpp:31
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
Definition: ms_set.cpp:229