Anope IRC Services  Version 2.0
ms_info.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 CommandMSInfo : public Command
15 {
16  public:
17  CommandMSInfo(Module *creator) : Command(creator, "memoserv/info", 0, 1)
18  {
19  this->SetDesc(_("Displays information about your memos"));
20  this->SetSyntax(_("[\037nick\037 | \037channel\037]"));
21  }
22 
23  void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
24  {
25  NickCore *nc = source.nc;
26  const MemoInfo *mi;
27  const NickAlias *na = NULL;
28  ChannelInfo *ci = NULL;
29  const Anope::string &nname = !params.empty() ? params[0] : "";
30  bool hardmax;
31 
32  if (!nname.empty() && nname[0] != '#' && source.HasPriv("memoserv/info"))
33  {
34  na = NickAlias::Find(nname);
35  if (!na)
36  {
37  source.Reply(NICK_X_NOT_REGISTERED, nname.c_str());
38  return;
39  }
40  mi = &na->nc->memos;
41  hardmax = na->nc->HasExt("MEMO_HARDMAX");
42  }
43  else if (!nname.empty() && nname[0] == '#')
44  {
45  ci = ChannelInfo::Find(nname);
46  if (!ci)
47  {
48  source.Reply(CHAN_X_NOT_REGISTERED, nname.c_str());
49  return;
50  }
51  else if (!source.AccessFor(ci).HasPriv("MEMO"))
52  {
53  source.Reply(ACCESS_DENIED);
54  return;
55  }
56  mi = &ci->memos;
57  hardmax = ci->HasExt("MEMO_HARDMAX");
58  }
59  else if (!nname.empty()) /* It's not a chan and we aren't services admin */
60  {
61  source.Reply(ACCESS_DENIED);
62  return;
63  }
64  else
65  {
66  mi = &nc->memos;
67  hardmax = nc->HasExt("MEMO_HARDMAX");
68  }
69 
70  if (!nname.empty() && (ci || na->nc != nc))
71  {
72  if (mi->memos->empty())
73  source.Reply(_("%s currently has no memos."), nname.c_str());
74  else if (mi->memos->size() == 1)
75  {
76  if (mi->GetMemo(0)->unread)
77  source.Reply(_("%s currently has \0021\002 memo, and it has not yet been read."), nname.c_str());
78  else
79  source.Reply(_("%s currently has \0021\002 memo."), nname.c_str());
80  }
81  else
82  {
83  unsigned count = 0, i, end;
84  for (i = 0, end = mi->memos->size(); i < end; ++i)
85  if (mi->GetMemo(i)->unread)
86  ++count;
87  if (count == mi->memos->size())
88  source.Reply(_("%s currently has \002%d\002 memos; all of them are unread."), nname.c_str(), count);
89  else if (!count)
90  source.Reply(_("%s currently has \002%d\002 memos."), nname.c_str(), mi->memos->size());
91  else if (count == 1)
92  source.Reply(_("%s currently has \002%d\002 memos, of which \0021\002 is unread."), nname.c_str(), mi->memos->size());
93  else
94  source.Reply(_("%s currently has \002%d\002 memos, of which \002%d\002 are unread."), nname.c_str(), mi->memos->size(), count);
95  }
96  if (!mi->memomax)
97  {
98  if (hardmax)
99  source.Reply(_("%s's memo limit is \002%d\002, and may not be changed."), nname.c_str(), mi->memomax);
100  else
101  source.Reply(_("%s's memo limit is \002%d\002."), nname.c_str(), mi->memomax);
102  }
103  else if (mi->memomax > 0)
104  {
105  if (hardmax)
106  source.Reply(_("%s's memo limit is \002%d\002, and may not be changed."), nname.c_str(), mi->memomax);
107  else
108  source.Reply(_("%s's memo limit is \002%d\002."), nname.c_str(), mi->memomax);
109  }
110  else
111  source.Reply(_("%s has no memo limit."), nname.c_str());
112 
113  /* I ripped this code out of ircservices 4.4.5, since I didn't want
114  to rewrite the whole thing (it pisses me off). */
115  if (na)
116  {
117  if (na->nc->HasExt("MEMO_RECEIVE") && na->nc->HasExt("MEMO_SIGNON"))
118  source.Reply(_("%s is notified of new memos at logon and when they arrive."), nname.c_str());
119  else if (na->nc->HasExt("MEMO_RECEIVE"))
120  source.Reply(_("%s is notified when new memos arrive."), nname.c_str());
121  else if (na->nc->HasExt("MEMO_SIGNON"))
122  source.Reply(_("%s is notified of news memos at logon."), nname.c_str());
123  else
124  source.Reply(_("%s is not notified of new memos."), nname.c_str());
125  }
126  }
127  else /* !nname || (!ci || na->nc == nc) */
128  {
129  if (mi->memos->empty())
130  source.Reply(_("You currently have no memos."));
131  else if (mi->memos->size() == 1)
132  {
133  if (mi->GetMemo(0)->unread)
134  source.Reply(_("You currently have \0021\002 memo, and it has not yet been read."));
135  else
136  source.Reply(_("You currently have \0021\002 memo."));
137  }
138  else
139  {
140  unsigned count = 0, i, end;
141  for (i = 0, end = mi->memos->size(); i < end; ++i)
142  if (mi->GetMemo(i)->unread)
143  ++count;
144  if (count == mi->memos->size())
145  source.Reply(_("You currently have \002%d\002 memos; all of them are unread."), count);
146  else if (!count)
147  source.Reply(_("You currently have \002%d\002 memos."), mi->memos->size());
148  else if (count == 1)
149  source.Reply(_("You currently have \002%d\002 memos, of which \0021\002 is unread."), mi->memos->size());
150  else
151  source.Reply(_("You currently have \002%d\002 memos, of which \002%d\002 are unread."), mi->memos->size(), count);
152  }
153 
154  if (!mi->memomax)
155  {
156  if (!source.IsServicesOper() && hardmax)
157  source.Reply(_("Your memo limit is \0020\002; you will not receive any new memos. You cannot change this limit."));
158  else
159  source.Reply(_("Your memo limit is \0020\002; you will not receive any new memos."));
160  }
161  else if (mi->memomax > 0)
162  {
163  if (!source.IsServicesOper() && hardmax)
164  source.Reply(_("Your memo limit is \002%d\002, and may not be changed."), mi->memomax);
165  else
166  source.Reply(_("Your memo limit is \002%d\002."), mi->memomax);
167  }
168  else
169  source.Reply(_("You have no limit on the number of memos you may keep."));
170 
171  /* Ripped too. But differently because of a seg fault (loughs) */
172  if (nc->HasExt("MEMO_RECEIVE") && nc->HasExt("MEMO_SIGNON"))
173  source.Reply(_("You will be notified of new memos at logon and when they arrive."));
174  else if (nc->HasExt("MEMO_RECEIVE"))
175  source.Reply(_("You will be notified when new memos arrive."));
176  else if (nc->HasExt("MEMO_SIGNON"))
177  source.Reply(_("You will be notified of new memos at logon."));
178  else
179  source.Reply(_("You will not be notified of new memos."));
180  }
181  }
182 
183  bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
184  {
185  this->SendSyntax(source);
186  source.Reply(" ");
187  source.Reply(_("Without a parameter, displays information on the number of\n"
188  "memos you have, how many of them are unread, and how many\n"
189  "total memos you can receive.\n"
190  " \n"
191  "With a channel parameter, displays the same information for\n"
192  "the given channel.\n"
193  " \n"
194  "With a nickname parameter, displays the same information\n"
195  "for the given nickname. This is limited to \002Services\002\n"
196  "\002Operators\002."));
197 
198  return true;
199  }
200 };
201 
202 class MSInfo : public Module
203 {
205 
206  public:
207  MSInfo(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
208  commandmsinfo(this)
209  {
210 
211  }
212 };
213 
Serialize::Reference< NickCore > nc
Definition: account.h:47
static NickAlias * Find(const Anope::string &nick)
Definition: nickalias.cpp:121
Definition: hashcomp.h:84
#define ACCESS_DENIED
Definition: language.h:73
CommandMSInfo(Module *creator)
Definition: ms_info.cpp:17
#define NICK_X_NOT_REGISTERED
Definition: language.h:79
void SetDesc(const Anope::string &d)
Definition: command.cpp:130
MemoInfo memos
Definition: account.h:122
static ChannelInfo * Find(const Anope::string &name)
Definition: regchannel.cpp:630
CommandMSInfo commandmsinfo
Definition: ms_info.cpp:204
Definition: memo.h:40
MSInfo(const Anope::string &modname, const Anope::string &creator)
Definition: ms_info.cpp:207
Memo * GetMemo(unsigned index) const
Definition: memos.cpp:82
#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
void SetSyntax(const Anope::string &s)
Definition: command.cpp:140
int16_t memomax
Definition: memo.h:42
#define CHAN_X_NOT_REGISTERED
Definition: language.h:84
Serialize::Checker< std::vector< Memo * > > memos
Definition: memo.h:43
void Execute(CommandSource &source, const std::vector< Anope::string > &params) anope_override
Definition: ms_info.cpp:23
void SendSyntax(CommandSource &)
Definition: command.cpp:145
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
Definition: ms_info.cpp:183
const char * c_str() const
Definition: anope.h:117
bool unread
Definition: memo.h:22
#define _(x)
Definition: services.h:50
bool HasExt(const Anope::string &name) const
Definition: extensible.cpp:31