summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2010-11-07 20:51:41 -0500
committerAdam <Adam@anope.org>2010-12-12 19:31:00 -0500
commitac41137ce2741df8faf539e0655a10cd4a8f7e32 (patch)
treeee4fc88bba9eeb24bd6802533d42df05e9ee9e75
parent28aba58e250fd6d58b0dff3bbc9ee8bbe172df24 (diff)
Added /ms ignore
-rw-r--r--data/example.conf2
-rw-r--r--docs/Changes.conf1
-rw-r--r--docs/TODO2
-rw-r--r--include/language.h9
-rw-r--r--include/services.h2
-rw-r--r--modules/core/db_plain.cpp55
-rw-r--r--modules/core/ms_ignore.cpp117
-rw-r--r--modules/extra/db_mysql.cpp50
-rw-r--r--src/language.cpp21
-rw-r--r--src/memoserv.cpp15
10 files changed, 243 insertions, 31 deletions
diff --git a/data/example.conf b/data/example.conf
index e573cbaac..106dba189 100644
--- a/data/example.conf
+++ b/data/example.conf
@@ -1160,7 +1160,7 @@ memoserv
* The core modules to load for MemoServ. This is a space separated list that corresponds
* to the base names of the modules for MemoServ. This directive is optional, but highly recommended.
*/
- modules = "ms_send ms_cancel ms_list ms_read ms_del ms_set ms_info ms_rsend ms_check ms_staff ms_sendall ms_help"
+ modules = "ms_send ms_cancel ms_list ms_read ms_del ms_set ms_info ms_rsend ms_check ms_staff ms_sendall ms_ignore ms_help"
/*
* The maximum number of memos a user is allowed to keep by default. Normal users may set the
diff --git a/docs/Changes.conf b/docs/Changes.conf
index a57a96455..b453fec76 100644
--- a/docs/Changes.conf
+++ b/docs/Changes.conf
@@ -1,5 +1,6 @@
Anope Version 1.9.4
-------------------
+memoserv:modules added ms_ignore
Anope Version 1.9.3
------------------
diff --git a/docs/TODO b/docs/TODO
index 99aca91e9..2b66a1fa8 100644
--- a/docs/TODO
+++ b/docs/TODO
@@ -5,6 +5,7 @@ Legend:
1.9.4
-----
+[x] MS IGNORE. Make it take nick (accounts) or n!u@h masks. Fake success of memo send still, but send to opers?
Future
------
@@ -16,7 +17,6 @@ Future
[?] Last successful login time/ip? perhaps both of these should be a new nick setting
[ ] NS INFO: seperate field for last seen realhost, shown to SRA only
[ ] NS SUSPEND: show suspender and reason, probably to sopers only (see CS SUSPEND)
-[ ] MS IGNORE. Make it take nick (accounts) or n!u@h masks. Fake success of memo send still, but send to opers?
[ ] Allow channel founders to change the fantasy trigger for their channel.
[ ] CIDR Akills, session exceptions, etc
[ ] Language charset stuff, including collation (1.9.1? phoenix?)
diff --git a/include/language.h b/include/language.h
index 4366d93c9..51f3e1cfc 100644
--- a/include/language.h
+++ b/include/language.h
@@ -705,6 +705,13 @@ enum LanguageString
MEMO_CHECK_READ,
MEMO_CHECK_NO_MEMO,
MEMO_NO_RSEND_SELF,
+ MEMO_IGNORE_SYNTAX,
+ MEMO_IGNORE_ADD,
+ MEMO_IGNORE_ALREADY_IGNORED,
+ MEMO_IGNORE_DEL,
+ MEMO_IGNORE_NOT_IGNORED,
+ MEMO_IGNORE_LIST_EMPTY,
+ MEMO_IGNORE_LIST_HEADER,
BOT_DOES_NOT_EXIST,
BOT_NOT_ASSIGNED,
BOT_NOT_ON_CHANNEL,
@@ -1373,6 +1380,7 @@ enum LanguageString
MEMO_HELP_CMD_CHECK,
MEMO_HELP_CMD_SENDALL,
MEMO_HELP_CMD_STAFF,
+ MEMO_HELP_CMD_IGNORE,
MEMO_HELP_HEADER,
MEMO_HELP_FOOTER,
MEMO_HELP_SEND,
@@ -1390,6 +1398,7 @@ enum LanguageString
MEMO_HELP_SENDALL,
MEMO_HELP_RSEND,
MEMO_HELP_CHECK,
+ MEMO_HELP_IGNORE,
OPER_HELP_CMD_GLOBAL,
OPER_HELP_CMD_STATS,
OPER_HELP_CMD_STAFF,
diff --git a/include/services.h b/include/services.h
index d1dca8724..1b14f5e88 100644
--- a/include/services.h
+++ b/include/services.h
@@ -487,10 +487,12 @@ struct CoreExport MemoInfo
{
unsigned memomax;
std::vector<Memo *> memos;
+ std::vector<ci::string> ignores;
unsigned GetIndex(Memo *m) const;
void Del(unsigned index);
void Del(Memo *m);
+ bool HasIgnore(User *u);
};
/*************************************************************************/
diff --git a/modules/core/db_plain.cpp b/modules/core/db_plain.cpp
index 041ea752e..1c8de7fee 100644
--- a/modules/core/db_plain.cpp
+++ b/modules/core/db_plain.cpp
@@ -609,6 +609,8 @@ class DBPlain : public Module
m->text = params[params.size() - 1];
nc->memos.memos.push_back(m);
}
+ else if (key.equals_ci("MIG"))
+ nc->memos.ignores.push_back(params[0].ci_str());
return EVENT_CONTINUE;
}
@@ -766,6 +768,8 @@ class DBPlain : public Module
m->text = params[params.size() - 1];
ci->memos.memos.push_back(m);
}
+ else if (key.equals_ci("MIG"))
+ ci->memos.ignores.push_back(params[0].ci_str());
else if (key.equals_ci("ENTRYMSG"))
ci->entry_message = params[0];
else if (key.equals_ci("BI"))
@@ -884,21 +888,20 @@ class DBPlain : public Module
db << " " << NickCoreFlags[j].Name;
db << endl;
}
- if (!nc->memos.memos.empty())
+ MemoInfo *mi = &nc->memos;
+ for (unsigned k = 0, end = mi->memos.size(); k < end; ++k)
{
- MemoInfo *mi = &nc->memos;
- for (unsigned k = 0, end = mi->memos.size(); k < end; ++k)
- {
- db << "MD MI " << mi->memos[k]->time << " " << mi->memos[k]->sender;
- if (mi->memos[k]->HasFlag(MF_UNREAD))
- db << " UNREAD";
- if (mi->memos[k]->HasFlag(MF_RECEIPT))
- db << " RECEIPT";
- if (mi->memos[k]->HasFlag(MF_NOTIFYS))
- db << " NOTIFYS";
- db << " :" << mi->memos[k]->text << endl;
- }
+ db << "MD MI " << mi->memos[k]->time << " " << mi->memos[k]->sender;
+ if (mi->memos[k]->HasFlag(MF_UNREAD))
+ db << " UNREAD";
+ if (mi->memos[k]->HasFlag(MF_RECEIPT))
+ db << " RECEIPT";
+ if (mi->memos[k]->HasFlag(MF_NOTIFYS))
+ db << " NOTIFYS";
+ db << " :" << mi->memos[k]->text << endl;
}
+ for (unsigned k = 0, end = mi->ignores.size(); k < end; ++k)
+ db << "MD MIG " << Anope::string(mi->ignores[k]) << endl;
FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteMetadata, nc));
}
@@ -1030,22 +1033,20 @@ class DBPlain : public Module
db << "MD MLP " << cm->NameAsString << " " << Param << endl;
}
}
- if (!ci->memos.memos.empty())
+ MemoInfo *memos = &ci->memos;
+ for (unsigned k = 0, end = memos->memos.size(); k < end; ++k)
{
- MemoInfo *memos = &ci->memos;
-
- for (unsigned k = 0, end = memos->memos.size(); k < end; ++k)
- {
- db << "MD MI " << memos->memos[k]->time << " " << memos->memos[k]->sender;
- if (memos->memos[k]->HasFlag(MF_UNREAD))
- db << " UNREAD";
- if (memos->memos[k]->HasFlag(MF_RECEIPT))
- db << " RECEIPT";
- if (memos->memos[k]->HasFlag(MF_NOTIFYS))
- db << " NOTIFYS";
- db << " :" << memos->memos[k]->text << endl;
- }
+ db << "MD MI " << memos->memos[k]->time << " " << memos->memos[k]->sender;
+ if (memos->memos[k]->HasFlag(MF_UNREAD))
+ db << " UNREAD";
+ if (memos->memos[k]->HasFlag(MF_RECEIPT))
+ db << " RECEIPT";
+ if (memos->memos[k]->HasFlag(MF_NOTIFYS))
+ db << " NOTIFYS";
+ db << " :" << memos->memos[k]->text << endl;
}
+ for (unsigned k = 0, end = memos->ignores.size(); k < end; ++k)
+ db << "MD MIG " << Anope::string(memos->ignores[k]) << endl;
if (!ci->entry_message.empty())
db << "MD ENTRYMSG :" << ci->entry_message << endl;
if (ci->bi)
diff --git a/modules/core/ms_ignore.cpp b/modules/core/ms_ignore.cpp
new file mode 100644
index 000000000..347657437
--- /dev/null
+++ b/modules/core/ms_ignore.cpp
@@ -0,0 +1,117 @@
+/* MemoServ core functions
+ *
+ * (C) 2003-2010 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"
+
+class CommandMSIgnore : public Command
+{
+ public:
+ CommandMSIgnore() : Command("IGNORE", 1, 3)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<Anope::string> &params)
+ {
+ Anope::string channel = params[0];
+ Anope::string command = (params.size() > 1 ? params[1] : "");
+ Anope::string param = (params.size() > 2 ? params[2] : "");
+
+ if (channel[0] != '#')
+ {
+ param = command;
+ command = channel;
+ channel = u->nick;
+ }
+
+ bool ischan, isforbid;
+ MemoInfo *mi = getmemoinfo(channel, ischan, isforbid);
+ if (!mi)
+ {
+ if (isforbid)
+ u->SendMessage(MemoServ, ischan ? CHAN_X_FORBIDDEN : NICK_X_FORBIDDEN, channel.c_str());
+ else
+ u->SendMessage(MemoServ, ischan ? CHAN_X_NOT_REGISTERED : NICK_X_NOT_REGISTERED, channel.c_str());
+ }
+ else if (ischan && !check_access(u, cs_findchan(channel), CA_MEMO))
+ u->SendMessage(MemoServ, ACCESS_DENIED);
+ else if (command.equals_ci("ADD") && !param.empty())
+ {
+ if (std::find(mi->ignores.begin(), mi->ignores.end(), param.ci_str()) == mi->ignores.end())
+ {
+ mi->ignores.push_back(param.ci_str());
+ u->SendMessage(MemoServ, MEMO_IGNORE_ADD, param.c_str());
+ }
+ else
+ u->SendMessage(MemoServ, MEMO_IGNORE_ALREADY_IGNORED, param.c_str());
+ }
+ else if (command.equals_ci("DEL") && !param.empty())
+ {
+ std::vector<ci::string>::iterator it = std::find(mi->ignores.begin(), mi->ignores.end(), param.ci_str());
+
+ if (it != mi->ignores.end())
+ {
+ mi->ignores.erase(it);
+ u->SendMessage(MemoServ, MEMO_IGNORE_DEL, param.c_str());
+ }
+ else
+ u->SendMessage(MemoServ, MEMO_IGNORE_NOT_IGNORED, param.c_str());
+ }
+ else if (command.equals_ci("LIST"))
+ {
+ if (mi->ignores.empty())
+ u->SendMessage(MemoServ, MEMO_IGNORE_LIST_EMPTY);
+ else
+ {
+ u->SendMessage(MemoServ, MEMO_IGNORE_LIST_HEADER);
+ for (unsigned i = 0; i < mi->ignores.size(); ++i)
+ u->SendMessage(Config->s_MemoServ, " %s", mi->ignores[i].c_str());
+ }
+ }
+ else
+ this->OnSyntaxError(u, "");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const Anope::string &subcommand)
+ {
+ u->SendMessage(MemoServ, MEMO_HELP_IGNORE);
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const Anope::string &subcommand)
+ {
+ SyntaxError(MemoServ, u, "IGNORE", MEMO_IGNORE_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ u->SendMessage(MemoServ, MEMO_HELP_CMD_IGNORE);
+ }
+};
+
+class MSIgnore : public Module
+{
+ CommandMSIgnore commandmsignore;
+
+ public:
+ MSIgnore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetType(CORE);
+
+ this->AddCommand(MemoServ, &commandmsignore);
+ }
+};
+
+MODULE_INIT(MSIgnore)
diff --git a/modules/extra/db_mysql.cpp b/modules/extra/db_mysql.cpp
index f6e0f8f12..fc9f47df9 100644
--- a/modules/extra/db_mysql.cpp
+++ b/modules/extra/db_mysql.cpp
@@ -905,6 +905,26 @@ class DBMySQL : public Module
FOREACH_RESULT(I_OnDatabaseRead, OnDatabaseRead(params));
}
+ r = SQL->RunQuery("SELECT * FROM `anope_ns_core_metadata`");
+ for (int i = 0; i < r.Rows(); ++i)
+ {
+ NickCore *nc = findcore(r.Get(i, "nick"));
+ if (!nc)
+ continue;
+ if (r.Get(i, "name") == "MEMO_IGNORE")
+ nc->memos.ignores.push_back(r.Get(i, "value").ci_str());
+ }
+
+ r = SQL->RunQuery("SELECT * FROM `anope_cs_info_metadata`");
+ for (int i = 0; i < r.Rows(); ++i)
+ {
+ ChannelInfo *ci = cs_findchan(r.Get(i, "channel"));
+ if (!ci)
+ continue;
+ if (r.Get(i, "name") == "MEMO_IGNORE")
+ ci->memos.ignores.push_back(r.Get(i, "value").ci_str());
+ }
+
return EVENT_STOP;
}
@@ -1073,6 +1093,36 @@ class DBMySQL : public Module
}
}
}
+ else if (service == MemoServ)
+ {
+ if (command.equals_ci("IGNORE") && params.size() > 0)
+ {
+ Anope::string target = params[0];
+ NickCore *nc = NULL;
+ ChannelInfo *ci = NULL;
+ if (target[0] != '#')
+ {
+ target = u->nick;
+ nc = u->Account();
+ if (!nc)
+ return;
+ }
+ else
+ {
+ ci = cs_findchan(target);
+ if (!ci || !check_access(u, ci, CA_MEMO))
+ return;
+ }
+
+ MemoInfo *mi = ci ? &ci->memos : &nc->memos;
+ Anope::string table = ci ? "anope_cs_info_metadata" : "anope_ns_core_metadata";
+ Anope::string ename = ci ? "channel" : "nick";
+
+ this->RunQuery("DELETE FROM `" + table + "` WHERE `" + ename + "` = '" + this->Escape(target) + "' AND `name` = 'MEMO_IGNORE'");
+ for (unsigned j = 0; j < mi->ignores.size(); ++j)
+ this->RunQuery("INSERT INTO `" + table + "` VALUES(" + ename + ", name, value) ('" + this->Escape(target) + "', 'MEMO_IGNORE', '" + this->Escape(mi->ignores[j]) + "')");
+ }
+ }
}
void OnNickAddAccess(NickCore *nc, const Anope::string &entry)
diff --git a/src/language.cpp b/src/language.cpp
index 3fb2beffd..7cae1e4bb 100644
--- a/src/language.cpp
+++ b/src/language.cpp
@@ -1605,6 +1605,20 @@ const char *const language_strings[LANG_STRING_COUNT] = {
_("Nick %s doesn't have a memo from you."),
/* MEMO_NO_RSEND_SELF */
_("You can not request a receipt when sending a memo to yourself."),
+ /* MEMO_IGNORE_SYNTAX */
+ _("IGNORE [\037channel\037] {\002ADD|DEL|LIST\002} [\037entry\037]"),
+ /* MEMO_IGNORE_ADD */
+ _("\002%s\002 added to your ignore list."),
+ /* MEMO_IGNORE_ALREADY_IGNORED */
+ _("\002%s\002 is already on your ignore list."),
+ /* MEMO_IGNORE_DEL */
+ _("\002%s\002 removed from your ignore list."),
+ /* MEMO_IGNORE_NOT_IGNORED */
+ _("\002%s\002 is not on your ignore list."),
+ /* MEMO_IGNORE_LIST_EMPTY */
+ _("Your memo ignore list is empty."),
+ /* MEMO_IGNORE_LIST_HEADER */
+ _("Ignore list:"),
/* BOT_DOES_NOT_EXIST */
_("Bot %s does not exist."),
/* BOT_NOT_ASSIGNED */
@@ -4185,6 +4199,8 @@ const char *const language_strings[LANG_STRING_COUNT] = {
_(" SENDALL Send a memo to all registered users"),
/* MEMO_HELP_CMD_STAFF */
_(" STAFF Send a memo to all opers/admins"),
+ /* MEMO_HELP_CMD_IGNORE */
+ _(" IGNORE Manage your memo ignore list"),
/* MEMO_HELP_HEADER */
_("%S is a utility allowing IRC users to send short\n"
"messages to other IRC users, whether they are online at\n"
@@ -4341,6 +4357,11 @@ const char *const language_strings[LANG_STRING_COUNT] = {
" \n"
"Checks whether the _last_ memo you sent to nick has been read\n"
"or not. Note that this does only work with nicks, not with chans."),
+ /* MEMO_HELP_IGNORE */
+ _("Syntax: \002IGNORE [\037channek\037] {\002ADD|DEL|LIST\002} [\037entry\037]\n"
+ " \n"
+ "Allows you to ignore users by nick or host from memoing you. If someone on your\n"
+ "memo ignore list tries to memo you, they will not be told that you have them ignored."),
/* OPER_HELP_CMD_GLOBAL */
_(" GLOBAL Send a message to all users"),
/* OPER_HELP_CMD_STATS */
diff --git a/src/memoserv.cpp b/src/memoserv.cpp
index ac455257f..eac54cc6d 100644
--- a/src/memoserv.cpp
+++ b/src/memoserv.cpp
@@ -211,6 +211,11 @@ void memo_send(User *u, const Anope::string &name, const Anope::string &text, in
}
else
{
+ if (!z || z == 3)
+ u->SendMessage(MemoServ, MEMO_SENT, name.c_str());
+ if ((!u->Account() || !u->Account()->IsServicesOper()) && mi->HasIgnore(u))
+ return;
+
u->lastmemosend = Anope::CurTime;
Memo *m = new Memo();
mi->memos.push_back(m);
@@ -224,8 +229,6 @@ void memo_send(User *u, const Anope::string &name, const Anope::string &text, in
/* Set receipt request flag */
if (z == 3)
m->SetFlag(MF_RECEIPT);
- if (!z || z == 3)
- u->SendMessage(MemoServ, MEMO_SENT, name.c_str());
if (!ischan)
{
NickCore *nc = findnick(name)->nc;
@@ -307,6 +310,14 @@ void MemoInfo::Del(Memo *memo)
}
}
+bool MemoInfo::HasIgnore(User *u)
+{
+ for (unsigned i = 0; i < this->ignores.size(); ++i)
+ if (u->nick.equals_ci(this->ignores[i]) || (u->Account() && u->Account()->display.equals_ci(this->ignores[i])) || Anope::Match(u->GetMask(), Anope::string(this->ignores[i])))
+ return true;
+ return false;
+}
+
/*************************************************************************/
static bool SendMemoMail(NickCore *nc, MemoInfo *mi, Memo *m)