Anope IRC Services  Version 2.0
cs_entrymsg.cpp
Go to the documentation of this file.
1 /* ChanServ 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 #include "modules/cs_entrymsg.h"
14 
16 {
17  EntryMsgImpl() : Serializable("EntryMsg")
18  {
19  }
20 
21  EntryMsgImpl(ChannelInfo *c, const Anope::string &cname, const Anope::string &cmessage, time_t ct = Anope::CurTime) : Serializable("EntryMsg")
22  {
23  this->chan = c->name;
24  this->creator = cname;
25  this->message = cmessage;
26  this->when = ct;
27  }
28 
29  ~EntryMsgImpl();
30 
32  {
33  data["ci"] << this->chan;
34  data["creator"] << this->creator;
35  data["message"] << this->message;
36  data.SetType("when", Serialize::Data::DT_INT); data["when"] << this->when;
37  }
38 
40 };
41 
43 {
45 
47  {
48  return new EntryMsgImpl();
49  }
50 };
51 
53 {
55  if (!ci)
56  return;
57 
58  EntryMessageList *messages = ci->GetExt<EntryMessageList>("entrymsg");
59  if (!messages)
60  return;
61 
62  std::vector<EntryMsg *>::iterator it = std::find((*messages)->begin(), (*messages)->end(), this);
63  if (it != (*messages)->end())
64  (*messages)->erase(it);
65 }
66 
67 
69 {
70  Anope::string sci, screator, smessage;
71  time_t swhen;
72 
73  data["ci"] >> sci;
74  data["creator"] >> screator;
75  data["message"] >> smessage;
76 
78  if (!ci)
79  return NULL;
80 
81  if (obj)
82  {
84  msg->chan = ci->name;
85  data["creator"] >> msg->creator;
86  data["message"] >> msg->message;
87  data["when"] >> msg->when;
88  return msg;
89  }
90 
91  EntryMessageList *messages = ci->Require<EntryMessageList>("entrymsg");
92 
93  data["when"] >> swhen;
94 
95  EntryMsgImpl *m = new EntryMsgImpl(ci, screator, smessage, swhen);
96  (*messages)->push_back(m);
97  return m;
98 }
99 
101 {
102  private:
104  {
105  EntryMessageList *messages = ci->Require<EntryMessageList>("entrymsg");
106 
107  if ((*messages)->empty())
108  {
109  source.Reply(_("Entry message list for \002%s\002 is empty."), ci->name.c_str());
110  return;
111  }
112 
113  source.Reply(_("Entry message list for \002%s\002:"), ci->name.c_str());
114 
115  ListFormatter list(source.GetAccount());
116  list.AddColumn(_("Number")).AddColumn(_("Creator")).AddColumn(_("Created")).AddColumn(_("Message"));
117  for (unsigned i = 0; i < (*messages)->size(); ++i)
118  {
119  EntryMsg *msg = (*messages)->at(i);
120 
122  entry["Number"] = stringify(i + 1);
123  entry["Creator"] = msg->creator;
124  entry["Created"] = Anope::strftime(msg->when, NULL, true);
125  entry["Message"] = msg->message;
126  list.AddEntry(entry);
127  }
128 
129  std::vector<Anope::string> replies;
130  list.Process(replies);
131  for (unsigned i = 0; i < replies.size(); ++i)
132  source.Reply(replies[i]);
133 
134  source.Reply(_("End of entry message list."));
135  }
136 
137  void DoAdd(CommandSource &source, ChannelInfo *ci, const Anope::string &message)
138  {
139  EntryMessageList *messages = ci->Require<EntryMessageList>("entrymsg");
140 
141  if ((*messages)->size() >= Config->GetModule(this->owner)->Get<unsigned>("maxentries"))
142  source.Reply(_("The entry message list for \002%s\002 is full."), ci->name.c_str());
143  else
144  {
145  (*messages)->push_back(new EntryMsgImpl(ci, source.GetNick(), message));
146  Log(source.IsFounder(ci) ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to add a message";
147  source.Reply(_("Entry message added to \002%s\002"), ci->name.c_str());
148  }
149  }
150 
151  void DoDel(CommandSource &source, ChannelInfo *ci, const Anope::string &message)
152  {
153  EntryMessageList *messages = ci->Require<EntryMessageList>("entrymsg");
154 
155  if (!message.is_pos_number_only())
156  source.Reply(("Entry message \002%s\002 not found on channel \002%s\002."), message.c_str(), ci->name.c_str());
157  else if ((*messages)->empty())
158  source.Reply(_("Entry message list for \002%s\002 is empty."), ci->name.c_str());
159  else
160  {
161  try
162  {
163  unsigned i = convertTo<unsigned>(message);
164  if (i > 0 && i <= (*messages)->size())
165  {
166  delete (*messages)->at(i - 1);
167  if ((*messages)->empty())
168  ci->Shrink<EntryMessageList>("entrymsg");
169  Log(source.IsFounder(ci) ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to remove a message";
170  source.Reply(_("Entry message \002%i\002 for \002%s\002 deleted."), i, ci->name.c_str());
171  }
172  else
173  throw ConvertException();
174  }
175  catch (const ConvertException &)
176  {
177  source.Reply(_("Entry message \002%s\002 not found on channel \002%s\002."), message.c_str(), ci->name.c_str());
178  }
179  }
180  }
181 
183  {
184  ci->Shrink<EntryMessageList>("entrymsg");
185 
186  Log(source.IsFounder(ci) ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to remove all messages";
187  source.Reply(_("Entry messages for \002%s\002 have been cleared."), ci->name.c_str());
188  }
189 
190  public:
191  CommandEntryMessage(Module *creator) : Command(creator, "chanserv/entrymsg", 2, 3)
192  {
193  this->SetDesc(_("Manage the channel's entry messages"));
194  this->SetSyntax(_("\037channel\037 ADD \037message\037"));
195  this->SetSyntax(_("\037channel\037 DEL \037num\037"));
196  this->SetSyntax(_("\037channel\037 LIST"));
197  this->SetSyntax(_("\037channel\037 CLEAR"));
198  }
199 
200  void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
201  {
202  ChannelInfo *ci = ChannelInfo::Find(params[0]);
203  if (ci == NULL)
204  {
205  source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
206  return;
207  }
208 
209  if (Anope::ReadOnly && !params[1].equals_ci("LIST"))
210  {
211  source.Reply(READ_ONLY_MODE);
212  return;
213  }
214 
215  if (!source.IsFounder(ci) && !source.HasPriv("chanserv/administration"))
216  {
217  source.Reply(ACCESS_DENIED);
218  return;
219  }
220 
221  if (params[1].equals_ci("LIST"))
222  this->DoList(source, ci);
223  else if (params[1].equals_ci("CLEAR"))
224  this->DoClear(source, ci);
225  else if (params.size() < 3)
226  this->OnSyntaxError(source, "");
227  else if (params[1].equals_ci("ADD"))
228  this->DoAdd(source, ci, params[2]);
229  else if (params[1].equals_ci("DEL"))
230  this->DoDel(source, ci, params[2]);
231  else
232  this->OnSyntaxError(source, "");
233  }
234 
235  bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
236  {
237  this->SendSyntax(source);
238  source.Reply(" ");
239  source.Reply(_("Controls what messages will be sent to users when they join the channel."));
240  source.Reply(" ");
241  source.Reply(_("The \002ENTRYMSG ADD\002 command adds the given message to\n"
242  "the list of messages to be shown to users when they join\n"
243  "the channel."));
244  source.Reply(" ");
245  source.Reply(_("The \002ENTRYMSG DEL\002 command removes the given message from\n"
246  "the list of messages to be shown to users when they join\n"
247  "the channel. You can remove the message by specifying its number\n"
248  "which you can get by listing the messages as explained below."));
249  source.Reply(" ");
250  source.Reply(_("The \002ENTRYMSG LIST\002 command displays a listing of messages\n"
251  "to be shown to users when they join the channel."));
252  source.Reply(" ");
253  source.Reply(_("The \002ENTRYMSG CLEAR\002 command clears all entries from\n"
254  "the list of messages to be shown to users when they join\n"
255  "the channel, effectively disabling entry messages."));
256  return true;
257  }
258 };
259 
260 class CSEntryMessage : public Module
261 {
265 
266  public:
267  CSEntryMessage(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
268  commandentrymsg(this),
269  eml(this, "entrymsg"), entrymsg_type("EntryMsg", EntryMsgImpl::Unserialize)
270  {
271  }
272 
274  {
275  if (u && c && c->ci && u->server->IsSynced())
276  {
277  EntryMessageList *messages = c->ci->GetExt<EntryMessageList>("entrymsg");
278 
279  if (messages != NULL)
280  for (unsigned i = 0; i < (*messages)->size(); ++i)
281  u->SendMessage(c->ci->WhoSends(), "[%s] %s", c->ci->name.c_str(), (*messages)->at(i)->message.c_str());
282  }
283  }
284 };
285 
CoreExport bool ReadOnly
Definition: main.cpp:28
void DoDel(CommandSource &source, ChannelInfo *ci, const Anope::string &message)
Anope::string message
Definition: cs_entrymsg.h:13
EntryMsg * Create() anope_override
Definition: cs_entrymsg.cpp:46
void Serialize(Serialize::Data &data) const anope_override
Definition: cs_entrymsg.cpp:31
Definition: hashcomp.h:84
void DoList(CommandSource &source, ChannelInfo *ci)
Anope::string name
Definition: regchannel.h:63
bool is_pos_number_only() const
Definition: anope.h:218
#define ACCESS_DENIED
Definition: language.h:73
Definition: users.h:34
void Execute(CommandSource &source, const std::vector< Anope::string > &params) anope_override
bool IsFounder(ChannelInfo *ci)
Definition: command.cpp:51
Definition: cs_entrymsg.cpp:42
#define READ_ONLY_MODE
Definition: language.h:71
void SetDesc(const Anope::string &d)
Definition: command.cpp:130
Definition: cs_entrymsg.cpp:15
T * Require(const Anope::string &name)
Definition: extensible.h:244
CoreExport time_t CurTime
Definition: main.cpp:41
const Anope::string & GetNick() const
Definition: command.cpp:26
CommandEntryMessage commandentrymsg
Definition: cs_entrymsg.h:21
static ChannelInfo * Find(const Anope::string &name)
Definition: regchannel.cpp:630
std::map< Anope::string, Anope::string > ListEntry
Definition: lists.h:68
EntryMsgImpl(ChannelInfo *c, const Anope::string &cname, const Anope::string &cmessage, time_t ct=Anope::CurTime)
Definition: cs_entrymsg.cpp:21
static Serializable * Unserialize(Serializable *obj, Serialize::Data &data)
Definition: cs_entrymsg.cpp:68
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
void Reply(const char *message,...)
Definition: command.cpp:96
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
CommandEntryMessage(Module *creator)
EntryMessageListImpl(Extensible *)
Definition: cs_entrymsg.cpp:44
EntryMsgImpl()
Definition: cs_entrymsg.cpp:17
CSEntryMessage(const Anope::string &modname, const Anope::string &creator)
#define anope_override
Definition: services.h:56
Definition: cs_entrymsg.h:9
void DoAdd(CommandSource &source, ChannelInfo *ci, const Anope::string &message)
#define MODULE_INIT(x)
Definition: modules.h:45
void SetSyntax(const Anope::string &s)
Definition: command.cpp:140
Anope::string stringify(const T &x)
Definition: anope.h:710
#define CHAN_X_NOT_REGISTERED
Definition: language.h:84
void DoClear(CommandSource &source, ChannelInfo *ci)
Serialize::Type entrymsg_type
void OnJoinChannel(User *u, Channel *c) anope_override
Anope::string creator
Definition: cs_entrymsg.h:12
T anope_dynamic_static_cast(O ptr)
Definition: anope.h:774
void SendSyntax(CommandSource &)
Definition: command.cpp:145
NickCore * GetAccount()
Definition: command.cpp:36
const char * c_str() const
Definition: anope.h:117
Definition: logger.h:53
~EntryMsgImpl()
Definition: cs_entrymsg.cpp:52
T * GetExt(const Anope::string &name) const
Definition: extensible.h:213
CoreExport Anope::string strftime(time_t t, const NickCore *nc=NULL, bool short_output=false)
Definition: misc.cpp:356
#define _(x)
Definition: services.h:50
ListFormatter & AddColumn(const Anope::string &name)
Definition: misc.cpp:128
Type(const Anope::string &n, unserialize_func f, Module *owner=NULL)
Anope::string chan
Definition: cs_entrymsg.h:11
ExtensibleItem< EntryMessageListImpl > eml
time_t when
Definition: cs_entrymsg.h:14
Module * owner
Definition: service.h:84