summaryrefslogtreecommitdiff
path: root/modules/pseudoclients/ms_main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/pseudoclients/ms_main.cpp')
-rw-r--r--modules/pseudoclients/ms_main.cpp228
1 files changed, 228 insertions, 0 deletions
diff --git a/modules/pseudoclients/ms_main.cpp b/modules/pseudoclients/ms_main.cpp
new file mode 100644
index 000000000..bb6d7847e
--- /dev/null
+++ b/modules/pseudoclients/ms_main.cpp
@@ -0,0 +1,228 @@
+/* MemoServ core functions
+ *
+ * (C) 2003-2011 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ */
+
+/*************************************************************************/
+
+#include "module.h"
+#include "memoserv.h"
+
+static BotInfo *MemoServ;
+
+static bool SendMemoMail(NickCore *nc, MemoInfo *mi, Memo *m)
+{
+ Anope::string message = Anope::printf(translate(nc, _(
+ "Hi %s\n"
+ " \n"
+ "You've just received a new memo from %s. This is memo number %d.\n"
+ " \n"
+ "Memo text:\n"
+ " \n"
+ "%s")), nc->display.c_str(), m->sender.c_str(), mi->GetIndex(m), m->text.c_str());
+
+ return Mail(nc, translate(nc, _("New memo")), message);
+}
+
+class MyMemoServService : public MemoServService
+{
+ public:
+ MyMemoServService(Module *m) : MemoServService(m) { }
+
+ MemoInfo *GetMemoInfo(const Anope::string &target, bool &ischan)
+ {
+ if (!target.empty() && target[0] == '#')
+ {
+ ischan = true;
+ ChannelInfo *ci = cs_findchan(target);
+ if (ci != NULL)
+ return &ci->memos;
+ }
+ else
+ {
+ ischan = false;
+ NickAlias *na = findnick(target);
+ if (na != NULL)
+ return &na->nc->memos;
+ }
+
+ return NULL;
+ }
+
+ MemoResult Send(const Anope::string &source, const Anope::string &target, const Anope::string &message, bool force)
+ {
+ bool ischan;
+ MemoInfo *mi = this->GetMemoInfo(target, ischan);
+
+ if (mi == NULL)
+ return MEMO_INVALID_TARGET;
+
+ User *sender = finduser(source);
+ if (sender != NULL && !sender->HasPriv("memoserv/no-limit") && !force)
+ {
+ if (Config->MSSendDelay > 0 && sender->lastmemosend + Config->MSSendDelay > Anope::CurTime)
+ return MEMO_TOO_FAST;
+ else if (!mi->memomax)
+ return MEMO_TARGET_FULL;
+ else if (mi->memomax > 0 && mi->memos.size() >= mi->memomax)
+ return MEMO_TARGET_FULL;
+ else if (mi->HasIgnore(sender))
+ return MEMO_SUCCESS;
+ }
+
+ if (sender != NULL)
+ sender->lastmemosend = Anope::CurTime;
+
+ Memo *m = new Memo();
+ mi->memos.push_back(m);
+ m->sender = source;
+ m->time = Anope::CurTime;
+ m->text = message;
+ m->SetFlag(MF_UNREAD);
+
+ FOREACH_MOD(I_OnMemoSend, OnMemoSend(source, target, mi, m));
+
+ if (ischan)
+ {
+ ChannelInfo *ci = cs_findchan(target);
+
+ if (ci->c)
+ {
+ for (CUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
+ {
+ UserContainer *cu = *it;
+
+ if (ci->HasPriv(cu->user, CA_MEMO))
+ {
+ if (cu->user->Account() && cu->user->Account()->HasFlag(NI_MEMO_RECEIVE))
+ cu->user->SendMessage(MemoServ, MEMO_NEW_X_MEMO_ARRIVED, ci->name.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->MemoServ.c_str(), ci->name.c_str(), mi->memos.size());
+ }
+ }
+ }
+ }
+ else
+ {
+ NickCore *nc = findnick(target)->nc;
+
+ if (nc->HasFlag(NI_MEMO_RECEIVE))
+ {
+ for (std::list<NickAlias *>::iterator it = nc->aliases.begin(), it_end = nc->aliases.end(); it != it_end; ++it)
+ {
+ NickAlias *na = *it;
+ User *user = finduser(na->nick);
+ if (user && user->IsIdentified())
+ user->SendMessage(MemoServ, MEMO_NEW_MEMO_ARRIVED, source.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->MemoServ.c_str(), mi->memos.size());
+ }
+ }
+
+ /* let's get out the mail if set in the nickcore - certus */
+ if (nc->HasFlag(NI_MEMO_MAIL))
+ SendMemoMail(nc, mi, m);
+ }
+
+ return MEMO_SUCCESS;
+ }
+
+ void Check(User *u)
+ {
+ NickCore *nc = u->Account();
+ if (!nc)
+ return;
+
+ unsigned i = 0, end = nc->memos.memos.size(), newcnt = 0;
+ for (; i < end; ++i)
+ {
+ if (nc->memos.memos[i]->HasFlag(MF_UNREAD))
+ ++newcnt;
+ }
+ if (newcnt > 0)
+ u->SendMessage(MemoServ, newcnt == 1 ? _("You have 1 new memo.") : _("You have %d new memos."), newcnt);
+ if (nc->memos.memomax > 0 && nc->memos.memos.size() >= nc->memos.memomax)
+ {
+ if (nc->memos.memos.size() > nc->memos.memomax)
+ 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);
+ else
+ 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);
+ }
+ }
+};
+
+class MemoServCore : public Module
+{
+ MyMemoServService mymemoserv;
+ public:
+ MemoServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
+ mymemoserv(this)
+ {
+ this->SetAuthor("Anope");
+
+ MemoServ = findbot(Config->MemoServ);
+ if (MemoServ == NULL)
+ throw ModuleException("No bot named " + Config->MemoServ);
+
+ Implementation i[] = { I_OnNickIdentify, I_OnJoinChannel, I_OnUserAway, I_OnNickUpdate, I_OnPreHelp, I_OnPostHelp };
+ ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
+
+ ModuleManager::RegisterService(&this->mymemoserv);
+ }
+
+ void OnNickIdentify(User *u)
+ {
+ this->mymemoserv.Check(u);
+ }
+
+ void OnJoinChannel(User *u, Channel *c)
+ {
+ if (c->ci && c->ci->HasPriv(u, CA_MEMO) && c->ci->memos.memos.size() > 0)
+ {
+ if (c->ci->memos.memos.size() == 1)
+ u->SendMessage(MemoServ, _("There is \002%d\002 memo on channel %s."), c->ci->memos.memos.size(), c->ci->name.c_str());
+ else
+ u->SendMessage(MemoServ, _("There are \002%d\002 memos on channel %s."), c->ci->memos.memos.size(), c->ci->name.c_str());
+ }
+ }
+
+ void OnUserAway(User *u, const Anope::string &message)
+ {
+ if (message.empty())
+ this->mymemoserv.Check(u);
+ }
+
+ void OnNickUpdate(User *u)
+ {
+ this->mymemoserv.Check(u);
+ }
+
+ void OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params)
+ {
+ if (!params.empty() || source.owner->nick != Config->MemoServ)
+ return;
+ source.Reply(_("\002%s\002 is a utility allowing IRC users to send short\n"
+ "messages to other IRC users, whether they are online at\n"
+ "the time or not, or to channels(*). Both the sender's\n"
+ "nickname and the target nickname or channel must be\n"
+ "registered in order to send a memo.\n"
+ "%s's commands include:"), Config->MemoServ.c_str(), Config->MemoServ.c_str());
+ }
+
+ void OnPostHelp(CommandSource &source, const std::vector<Anope::string> &params)
+ {
+ if (!params.empty() || source.owner->nick != Config->MemoServ)
+ return;
+ source.Reply(_(" \n"
+ "Type \002%s%s HELP \037command\037\002 for help on any of the\n"
+ "above commands.\n"
+ "(*) By default, any user with at least level 10 access on a\n"
+ " channel can read that channel's memos. This can be\n"
+ " changed with the %s \002LEVELS\002 command."), Config->UseStrictPrivMsgString.c_str(), Config->MemoServ.c_str(), Config->ChanServ.c_str());
+ }
+};
+
+MODULE_INIT(MemoServCore)
+