Anope IRC Services  Version 2.0
memoserv.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 MemoServCore : public Module, public MemoServService
15 {
17 
18  bool SendMemoMail(NickCore *nc, MemoInfo *mi, Memo *m)
19  {
20  Anope::string subject = Language::Translate(nc, Config->GetBlock("mail")->Get<const Anope::string>("memo_subject").c_str()),
21  message = Language::Translate(Config->GetBlock("mail")->Get<const Anope::string>("memo_message").c_str());
22 
23  subject = subject.replace_all_cs("%n", nc->display);
24  subject = subject.replace_all_cs("%s", m->sender);
25  subject = subject.replace_all_cs("%d", stringify(mi->GetIndex(m) + 1));
26  subject = subject.replace_all_cs("%t", m->text);
27  subject = subject.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname"));
28 
29  message = message.replace_all_cs("%n", nc->display);
30  message = message.replace_all_cs("%s", m->sender);
31  message = message.replace_all_cs("%d", stringify(mi->GetIndex(m) + 1));
32  message = message.replace_all_cs("%t", m->text);
33  message = message.replace_all_cs("%N", Config->GetBlock("networkinfo")->Get<const Anope::string>("networkname"));
34 
35  return Mail::Send(nc, subject, message);
36  }
37 
38  public:
39  MemoServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PSEUDOCLIENT | VENDOR),
40  MemoServService(this)
41  {
42  }
43 
44  MemoResult Send(const Anope::string &source, const Anope::string &target, const Anope::string &message, bool force) anope_override
45  {
46  bool ischan;
47  MemoInfo *mi = MemoInfo::GetMemoInfo(target, ischan);
48 
49  if (mi == NULL)
50  return MEMO_INVALID_TARGET;
51 
52  User *sender = User::Find(source);
53  if (sender != NULL && !sender->HasPriv("memoserv/no-limit") && !force)
54  {
55  time_t send_delay = Config->GetModule("memoserv")->Get<time_t>("senddelay");
56  if (send_delay > 0 && sender->lastmemosend + send_delay > Anope::CurTime)
57  return MEMO_TOO_FAST;
58  else if (!mi->memomax)
59  return MEMO_TARGET_FULL;
60  else if (mi->memomax > 0 && mi->memos->size() >= static_cast<unsigned>(mi->memomax))
61  return MEMO_TARGET_FULL;
62  else if (mi->HasIgnore(sender))
63  return MEMO_SUCCESS;
64  }
65 
66  if (sender != NULL)
67  sender->lastmemosend = Anope::CurTime;
68 
69  Memo *m = new Memo();
70  mi->memos->push_back(m);
71  m->owner = target;
72  m->sender = source;
73  m->time = Anope::CurTime;
74  m->text = message;
75  m->unread = true;
76 
77  FOREACH_MOD(OnMemoSend, (source, target, mi, m));
78 
79  if (ischan)
80  {
81  ChannelInfo *ci = ChannelInfo::Find(target);
82 
83  if (ci->c)
84  {
85  for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
86  {
87  ChanUserContainer *cu = it->second;
88 
89  if (ci->AccessFor(cu->user).HasPriv("MEMO"))
90  {
91  if (cu->user->Account() && cu->user->Account()->HasExt("MEMO_RECEIVE"))
92  cu->user->SendMessage(MemoServ, MEMO_NEW_X_MEMO_ARRIVED, ci->name.c_str(), Config->StrictPrivmsg.c_str(), MemoServ->nick.c_str(), ci->name.c_str(), mi->memos->size());
93  }
94  }
95  }
96  }
97  else
98  {
99  NickCore *nc = NickAlias::Find(target)->nc;
100 
101  if (nc->HasExt("MEMO_RECEIVE"))
102  {
103  for (unsigned i = 0; i < nc->aliases->size(); ++i)
104  {
105  const NickAlias *na = nc->aliases->at(i);
106  User *user = User::Find(na->nick);
107  if (user && user->IsIdentified())
108  user->SendMessage(MemoServ, MEMO_NEW_MEMO_ARRIVED, source.c_str(), Config->StrictPrivmsg.c_str(), MemoServ->nick.c_str(), mi->memos->size());
109  }
110  }
111 
112  /* let's get out the mail if set in the nickcore - certus */
113  if (nc->HasExt("MEMO_MAIL"))
114  SendMemoMail(nc, mi, m);
115  }
116 
117  return MEMO_SUCCESS;
118  }
119 
120  void Check(User *u)
121  {
122  const NickCore *nc = u->Account();
123  if (!nc)
124  return;
125 
126  unsigned i = 0, end = nc->memos.memos->size(), newcnt = 0;
127  for (; i < end; ++i)
128  if (nc->memos.GetMemo(i)->unread)
129  ++newcnt;
130  if (newcnt > 0)
131  u->SendMessage(MemoServ, newcnt == 1 ? _("You have 1 new memo.") : _("You have %d new memos."), newcnt);
132  if (nc->memos.memomax > 0 && nc->memos.memos->size() >= static_cast<unsigned>(nc->memos.memomax))
133  {
134  if (nc->memos.memos->size() > static_cast<unsigned>(nc->memos.memomax))
135  u->SendMessage(MemoServ, _("You are over your maximum number of memos (%d). You will be unable to receive any new memos until you delete some of your current ones."), nc->memos.memomax);
136  else
137  u->SendMessage(MemoServ, _("You have reached your maximum number of memos (%d). You will be unable to receive any new memos until you delete some of your current ones."), nc->memos.memomax);
138  }
139  }
140 
142  {
143  const Anope::string &msnick = conf->GetModule(this)->Get<const Anope::string>("client");
144 
145  if (msnick.empty())
146  throw ConfigException(Module::name + ": <client> must be defined");
147 
148  BotInfo *bi = BotInfo::Find(msnick, true);
149  if (!bi)
150  throw ConfigException(Module::name + ": no bot named " + msnick);
151 
152  MemoServ = bi;
153  }
154 
156  {
157  nc->memos.memomax = Config->GetModule(this)->Get<int>("maxmemos");
158  }
159 
161  {
162  ci->memos.memomax = Config->GetModule(this)->Get<int>("maxmemos");
163  }
164 
166  {
167  if (bi == MemoServ)
168  MemoServ = NULL;
169  }
170 
172  {
173  this->Check(u);
174  }
175 
177  {
178  if (c->ci && !c->ci->memos.memos->empty() && c->ci->AccessFor(u).HasPriv("MEMO"))
179  {
180  if (c->ci->memos.memos->size() == 1)
181  u->SendMessage(MemoServ, _("There is \002%d\002 memo on channel %s."), c->ci->memos.memos->size(), c->ci->name.c_str());
182  else
183  u->SendMessage(MemoServ, _("There are \002%d\002 memos on channel %s."), c->ci->memos.memos->size(), c->ci->name.c_str());
184  }
185  }
186 
187  void OnUserAway(User *u, const Anope::string &message) anope_override
188  {
189  if (message.empty())
190  this->Check(u);
191  }
192 
194  {
195  this->Check(u);
196  }
197 
198  EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
199  {
200  if (!params.empty() || source.c || source.service != *MemoServ)
201  return EVENT_CONTINUE;
202  source.Reply(_("\002%s\002 is a utility allowing IRC users to send short\n"
203  "messages to other IRC users, whether they are online at\n"
204  "the time or not, or to channels(*). Both the sender's\n"
205  "nickname and the target nickname or channel must be\n"
206  "registered in order to send a memo.\n"
207  "%s's commands include:"), MemoServ->nick.c_str(), MemoServ->nick.c_str());
208  return EVENT_CONTINUE;
209  }
210 
211  void OnPostHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
212  {
213  if (!params.empty() || source.c || source.service != *MemoServ)
214  return;
215  source.Reply(_(" \n"
216  "Type \002%s%s HELP \037command\037\002 for help on any of the\n"
217  "above commands."), Config->StrictPrivmsg.c_str(), MemoServ->nick.c_str());
218  }
219 };
220 
222 
Serialize::Reference< NickCore > nc
Definition: account.h:47
Definition: bots.h:24
static NickAlias * Find(const Anope::string &nick)
Definition: nickalias.cpp:121
Anope::string name
Definition: modules.h:221
Definition: hashcomp.h:84
Serialize::Checker< std::vector< NickAlias * > > aliases
Definition: account.h:128
Anope::string name
Definition: regchannel.h:63
#define MEMO_NEW_X_MEMO_ARRIVED
Definition: language.h:111
Anope::string text
Definition: memo.h:34
void OnNickUpdate(User *u) anope_override
Definition: memoserv.cpp:193
Anope::string nick
Definition: account.h:37
void OnJoinChannel(User *u, Channel *c) anope_override
Definition: memoserv.cpp:176
bool HasIgnore(User *u)
Definition: memos.cpp:106
unsigned GetIndex(Memo *m) const
Definition: memos.cpp:91
void Check(User *u)
Definition: memoserv.cpp:120
Anope::string sender
Definition: memo.h:33
Definition: users.h:34
static MemoInfo * GetMemoInfo(const Anope::string &targ, bool &is_chan)
Definition: memos.cpp:114
void OnUserAway(User *u, const Anope::string &message) anope_override
Definition: memoserv.cpp:187
CoreExport time_t CurTime
Definition: main.cpp:41
time_t lastmemosend
Definition: users.h:90
bool HasPriv(const Anope::string &priv) const
Definition: access.cpp:384
#define FOREACH_MOD(ename, args)
Definition: modules.h:62
MemoInfo memos
Definition: account.h:122
#define MEMO_NEW_MEMO_ARRIVED
Definition: language.h:113
static ChannelInfo * Find(const Anope::string &name)
Definition: regchannel.cpp:630
void OnCreateChan(ChannelInfo *ci) anope_override
Definition: memoserv.cpp:160
virtual void OnMemoSend(const Anope::string &source, const Anope::string &target, MemoInfo *mi, Memo *m)
Definition: modules.h:877
Definition: Config.cs:26
bool SendMemoMail(NickCore *nc, MemoInfo *mi, Memo *m)
Definition: memoserv.cpp:18
Channel * c
Definition: regchannel.h:79
Definition: memo.h:40
string replace_all_cs(const string &_orig, const string &_repl) const
Definition: anope.h:229
void OnReload(Configuration::Conf *conf) anope_override
Definition: memoserv.cpp:141
Definition: memo.h:19
bool IsIdentified(bool check_nick=false) const
Definition: users.cpp:427
bool HasPriv(const Anope::string &privstr)
Definition: users.cpp:487
Anope::string display
Definition: account.h:113
CoreExport bool Send(User *from, NickCore *to, BotInfo *service, const Anope::string &subject, const Anope::string &message)
Definition: mail.cpp:54
Memo * GetMemo(unsigned index) const
Definition: memos.cpp:82
#define anope_override
Definition: services.h:56
bool empty() const
Definition: anope.h:126
EventReturn
Definition: modules.h:129
#define MODULE_INIT(x)
Definition: modules.h:45
CoreExport const char * Translate(const char *string)
Definition: language.cpp:59
ChanUserList users
Definition: channels.h:56
AccessGroup AccessFor(const User *u)
Definition: regchannel.cpp:413
EventReturn OnPreHelp(CommandSource &source, const std::vector< Anope::string > &params) anope_override
Definition: memoserv.cpp:198
int16_t memomax
Definition: memo.h:42
Anope::string stringify(const T &x)
Definition: anope.h:710
void OnBotDelete(BotInfo *bi) anope_override
Definition: memoserv.cpp:165
MemoResult Send(const Anope::string &source, const Anope::string &target, const Anope::string &message, bool force) anope_override
Definition: memoserv.cpp:44
Anope::string nick
Definition: users.h:62
static User * Find(const Anope::string &name, bool nick_only=false)
Definition: users.cpp:815
Serialize::Checker< std::vector< Memo * > > memos
Definition: memo.h:43
MemoServCore(const Anope::string &modname, const Anope::string &creator)
Definition: memoserv.cpp:39
NickCore * Account() const
Definition: users.cpp:422
void OnPostHelp(CommandSource &source, const std::vector< Anope::string > &params) anope_override
Definition: memoserv.cpp:211
const char * c_str() const
Definition: anope.h:117
time_t time
Definition: memo.h:32
void OnNickIdentify(User *u) anope_override
Definition: memoserv.cpp:171
void SendMessage(BotInfo *source, const char *fmt,...)
Definition: users.cpp:320
bool unread
Definition: memo.h:22
Anope::string owner
Definition: memo.h:30
#define _(x)
Definition: services.h:50
static BotInfo * Find(const Anope::string &nick, bool nick_only=false)
Definition: bots.cpp:249
bool HasExt(const Anope::string &name) const
Definition: extensible.cpp:31
Reference< BotInfo > MemoServ
Definition: memoserv.cpp:16
void OnNickCoreCreate(NickCore *nc) anope_override
Definition: memoserv.cpp:155