1
0
mirror of https://github.com/anope/anope.git synced 2026-06-25 08:56:39 +02:00
Files
anope/modules/pseudoclients/memoserv.cpp
T
2012-04-23 05:08:26 -04:00

231 lines
7.1 KiB
C++

/* MemoServ core functions
*
* (C) 2003-2012 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 bool SendMemoMail(NickCore *nc, MemoInfo *mi, Memo *m)
{
Anope::string subject = translate(nc, Config->MailMemoSubject.c_str());
Anope::string message = translate(nc, Config->MailMemoMessage.c_str());
subject = subject.replace_all_cs("%n", nc->display);
subject = subject.replace_all_cs("%s", m->sender);
subject = subject.replace_all_cs("%d", mi->GetIndex(m));
subject = subject.replace_all_cs("%t", m->text);
message = message.replace_all_cs("%n", nc->display);
message = message.replace_all_cs("%s", m->sender);
message = message.replace_all_cs("%d", mi->GetIndex(m));
message = message.replace_all_cs("%t", m->text);
return Mail(nc, subject, message);
}
class MyMemoServService : public MemoServService
{
public:
MyMemoServService(Module *m) : MemoServService(m) { }
MemoInfo *GetMemoInfo(const Anope::string &target, bool &ischan) anope_override
{
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) anope_override
{
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->owner = target;
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->AccessFor(cu->user).HasPriv("MEMO"))
{
if (cu->user->Account() && cu->user->Account()->HasFlag(NI_MEMO_RECEIVE))
cu->user->SendMessage(findbot(Config->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<serialize_obj<NickAlias> >::const_iterator it = nc->aliases.begin(), it_end = nc->aliases.end(); it != it_end;)
{
const NickAlias *na = *it++;
if (!na)
continue;
User *user = finduser(na->nick);
if (user && user->IsIdentified())
user->SendMessage(findbot(Config->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)
{
const NickCore *nc = u->Account();
if (!nc)
return;
const BotInfo *ms = findbot(Config->MemoServ);
unsigned i = 0, end = nc->memos.memos->size(), newcnt = 0;
for (; i < end; ++i)
if (nc->memos.GetMemo(i)->HasFlag(MF_UNREAD))
++newcnt;
if (newcnt > 0)
u->SendMessage(ms, 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(ms, _("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(ms, _("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");
if (!findbot(Config->MemoServ))
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));
}
void OnNickIdentify(User *u) anope_override
{
this->mymemoserv.Check(u);
}
void OnJoinChannel(User *u, Channel *c) anope_override
{
if (c->ci && c->ci->AccessFor(u).HasPriv("MEMO") && c->ci->memos.memos->size() > 0)
{
if (c->ci->memos.memos->size() == 1)
u->SendMessage(findbot(Config->MemoServ), _("There is \002%d\002 memo on channel %s."), c->ci->memos.memos->size(), c->ci->name.c_str());
else
u->SendMessage(findbot(Config->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) anope_override
{
if (message.empty())
this->mymemoserv.Check(u);
}
void OnNickUpdate(User *u) anope_override
{
this->mymemoserv.Check(u);
}
EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
if (!params.empty() || source.owner->nick != Config->MemoServ)
return EVENT_CONTINUE;
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());
return EVENT_CONTINUE;
}
void OnPostHelp(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
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)