summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/core/botserv.h65
-rw-r--r--modules/core/bs_act.cpp8
-rw-r--r--modules/core/bs_assign.cpp6
-rw-r--r--modules/core/bs_badwords.cpp8
-rw-r--r--modules/core/bs_bot.cpp6
-rw-r--r--modules/core/bs_botlist.cpp6
-rw-r--r--modules/core/bs_help.cpp14
-rw-r--r--modules/core/bs_info.cpp8
-rw-r--r--modules/core/bs_kick.cpp301
-rw-r--r--modules/core/bs_main.cpp265
-rw-r--r--modules/core/bs_say.cpp8
-rw-r--r--modules/core/bs_set.cpp8
-rw-r--r--modules/core/bs_unassign.cpp8
-rw-r--r--modules/core/chanserv.h15
-rw-r--r--modules/core/cs_access.cpp14
-rw-r--r--modules/core/cs_akick.cpp10
-rw-r--r--modules/core/cs_ban.cpp10
-rw-r--r--modules/core/cs_clearusers.cpp10
-rw-r--r--modules/core/cs_clone.cpp6
-rw-r--r--modules/core/cs_drop.cpp8
-rw-r--r--modules/core/cs_forbid.cpp8
-rw-r--r--modules/core/cs_getkey.cpp6
-rw-r--r--modules/core/cs_help.cpp13
-rw-r--r--modules/core/cs_info.cpp6
-rw-r--r--modules/core/cs_invite.cpp14
-rw-r--r--modules/core/cs_kick.cpp10
-rw-r--r--modules/core/cs_list.cpp7
-rw-r--r--modules/core/cs_main.cpp256
-rw-r--r--modules/core/cs_mode.cpp6
-rw-r--r--modules/core/cs_modes.cpp39
-rw-r--r--modules/core/cs_register.cpp8
-rw-r--r--modules/core/cs_saset.cpp10
-rw-r--r--modules/core/cs_saset_noexpire.cpp8
-rw-r--r--modules/core/cs_set.cpp10
-rw-r--r--modules/core/cs_set_bantype.cpp12
-rw-r--r--modules/core/cs_set_description.cpp12
-rw-r--r--modules/core/cs_set_founder.cpp12
-rw-r--r--modules/core/cs_set_keeptopic.cpp14
-rw-r--r--modules/core/cs_set_opnotice.cpp14
-rw-r--r--modules/core/cs_set_peace.cpp14
-rw-r--r--modules/core/cs_set_persist.cpp20
-rw-r--r--modules/core/cs_set_private.cpp14
-rw-r--r--modules/core/cs_set_restricted.cpp12
-rw-r--r--modules/core/cs_set_secure.cpp16
-rw-r--r--modules/core/cs_set_securefounder.cpp12
-rw-r--r--modules/core/cs_set_secureops.cpp12
-rw-r--r--modules/core/cs_set_signkick.cpp14
-rw-r--r--modules/core/cs_set_successor.cpp12
-rw-r--r--modules/core/cs_set_topiclock.cpp14
-rw-r--r--modules/core/cs_set_xop.cpp12
-rw-r--r--modules/core/cs_status.cpp3
-rw-r--r--modules/core/cs_suspend.cpp5
-rw-r--r--modules/core/cs_topic.cpp5
-rw-r--r--modules/core/cs_unban.cpp5
-rw-r--r--modules/core/cs_xop.cpp35
-rw-r--r--modules/core/db_plain.cpp40
-rw-r--r--modules/core/gl_global.cpp (renamed from modules/core/os_global.cpp)24
-rw-r--r--modules/core/gl_help.cpp58
-rw-r--r--modules/core/gl_main.cpp111
-rw-r--r--modules/core/global.h22
-rw-r--r--modules/core/hostserv.h17
-rw-r--r--modules/core/hs_del.cpp6
-rw-r--r--modules/core/hs_delall.cpp6
-rw-r--r--modules/core/hs_group.cpp8
-rw-r--r--modules/core/hs_help.cpp10
-rw-r--r--modules/core/hs_list.cpp6
-rw-r--r--modules/core/hs_main.cpp123
-rw-r--r--modules/core/hs_off.cpp6
-rw-r--r--modules/core/hs_on.cpp6
-rw-r--r--modules/core/hs_set.cpp6
-rw-r--r--modules/core/hs_setall.cpp8
-rw-r--r--modules/core/memoserv.h44
-rw-r--r--modules/core/ms_cancel.cpp14
-rw-r--r--modules/core/ms_check.cpp6
-rw-r--r--modules/core/ms_del.cpp6
-rw-r--r--modules/core/ms_help.cpp14
-rw-r--r--modules/core/ms_ignore.cpp8
-rw-r--r--modules/core/ms_info.cpp6
-rw-r--r--modules/core/ms_list.cpp6
-rw-r--r--modules/core/ms_main.cpp250
-rw-r--r--modules/core/ms_read.cpp42
-rw-r--r--modules/core/ms_rsend.cpp44
-rw-r--r--modules/core/ms_send.cpp18
-rw-r--r--modules/core/ms_sendall.cpp8
-rw-r--r--modules/core/ms_set.cpp8
-rw-r--r--modules/core/ms_staff.cpp8
-rw-r--r--modules/core/nickserv.h17
-rw-r--r--modules/core/ns_access.cpp8
-rw-r--r--modules/core/ns_ajoin.cpp10
-rw-r--r--modules/core/ns_alist.cpp3
-rw-r--r--modules/core/ns_cert.cpp12
-rw-r--r--modules/core/ns_drop.cpp10
-rw-r--r--modules/core/ns_forbid.cpp8
-rw-r--r--modules/core/ns_getemail.cpp6
-rw-r--r--modules/core/ns_getpass.cpp12
-rw-r--r--modules/core/ns_ghost.cpp8
-rw-r--r--modules/core/ns_group.cpp18
-rw-r--r--modules/core/ns_help.cpp17
-rw-r--r--modules/core/ns_identify.cpp8
-rw-r--r--modules/core/ns_info.cpp6
-rw-r--r--modules/core/ns_list.cpp7
-rw-r--r--modules/core/ns_logout.cpp10
-rw-r--r--modules/core/ns_main.cpp282
-rw-r--r--modules/core/ns_recover.cpp12
-rw-r--r--modules/core/ns_register.cpp23
-rw-r--r--modules/core/ns_release.cpp8
-rw-r--r--modules/core/ns_resetpass.cpp16
-rw-r--r--modules/core/ns_saset.cpp12
-rw-r--r--modules/core/ns_saset_noexpire.cpp8
-rw-r--r--modules/core/ns_sendpass.cpp14
-rw-r--r--modules/core/ns_set.cpp12
-rw-r--r--modules/core/ns_set_autoop.cpp12
-rw-r--r--modules/core/ns_set_email.cpp16
-rw-r--r--modules/core/ns_set_greet.cpp12
-rw-r--r--modules/core/ns_set_hide.cpp16
-rw-r--r--modules/core/ns_set_kill.cpp16
-rw-r--r--modules/core/ns_set_language.cpp12
-rw-r--r--modules/core/ns_set_message.cpp12
-rw-r--r--modules/core/ns_set_private.cpp18
-rw-r--r--modules/core/ns_set_secure.cpp16
-rw-r--r--modules/core/ns_status.cpp6
-rw-r--r--modules/core/ns_suspend.cpp8
-rw-r--r--modules/core/ns_update.cpp17
-rw-r--r--modules/core/operserv.h15
-rw-r--r--modules/core/os_akill.cpp64
-rw-r--r--modules/core/os_chankill.cpp8
-rw-r--r--modules/core/os_chanlist.cpp8
-rw-r--r--modules/core/os_config.cpp6
-rw-r--r--modules/core/os_defcon.cpp496
-rw-r--r--modules/core/os_help.cpp14
-rw-r--r--modules/core/os_ignore.cpp6
-rw-r--r--modules/core/os_jupe.cpp6
-rw-r--r--modules/core/os_kick.cpp10
-rw-r--r--modules/core/os_login.cpp12
-rw-r--r--modules/core/os_main.cpp137
-rw-r--r--modules/core/os_mode.cpp12
-rw-r--r--modules/core/os_modinfo.cpp24
-rw-r--r--modules/core/os_modlist.cpp6
-rw-r--r--modules/core/os_modload.cpp8
-rw-r--r--modules/core/os_modreload.cpp8
-rw-r--r--modules/core/os_modunload.cpp8
-rw-r--r--modules/core/os_news.cpp22
-rw-r--r--modules/core/os_noop.cpp6
-rw-r--r--modules/core/os_oline.cpp14
-rw-r--r--modules/core/os_quit.cpp9
-rw-r--r--modules/core/os_reload.cpp16
-rw-r--r--modules/core/os_restart.cpp9
-rw-r--r--modules/core/os_session.cpp234
-rw-r--r--modules/core/os_session.h80
-rw-r--r--modules/core/os_set.cpp12
-rw-r--r--modules/core/os_shutdown.cpp9
-rw-r--r--modules/core/os_snline.cpp67
-rw-r--r--modules/core/os_sqline.cpp54
-rw-r--r--modules/core/os_staff.cpp6
-rw-r--r--modules/core/os_stats.cpp160
-rw-r--r--modules/core/os_svsnick.cpp10
-rw-r--r--modules/core/os_szline.cpp62
-rw-r--r--modules/core/os_update.cpp6
-rw-r--r--modules/core/os_userlist.cpp6
-rw-r--r--modules/core/ss_main.cpp65
-rw-r--r--modules/extra/cs_appendtopic.cpp14
-rw-r--r--modules/extra/cs_enforce.cpp10
-rw-r--r--modules/extra/cs_entrymsg.cpp12
-rw-r--r--modules/extra/cs_set_misc.cpp16
-rw-r--r--modules/extra/cs_tban.cpp12
-rw-r--r--modules/extra/db_mysql.cpp87
-rw-r--r--modules/extra/hs_request.cpp47
-rw-r--r--modules/extra/m_alias.cpp9
-rw-r--r--modules/extra/m_dnsbl.cpp44
-rw-r--r--modules/extra/m_helpchan.cpp9
-rw-r--r--modules/extra/m_ldap.cpp4
-rw-r--r--modules/extra/m_ldap_authentication.cpp19
-rw-r--r--modules/extra/m_ldap_oper.cpp4
-rw-r--r--modules/extra/m_mysql.cpp4
-rw-r--r--modules/extra/m_xmlrpc.cpp6
-rw-r--r--modules/extra/m_xmlrpc_main.cpp7
-rw-r--r--modules/extra/ns_maxemail.cpp10
-rw-r--r--modules/extra/ns_set_misc.cpp13
-rw-r--r--modules/extra/os_defcon.cpp693
-rw-r--r--modules/protocol/bahamut.cpp27
-rw-r--r--modules/protocol/inspircd-ts6.h20
-rw-r--r--modules/protocol/inspircd11.cpp21
-rw-r--r--modules/protocol/inspircd12.cpp38
-rw-r--r--modules/protocol/inspircd20.cpp36
-rw-r--r--modules/protocol/plexus.cpp15
-rw-r--r--modules/protocol/ratbox.cpp26
-rw-r--r--modules/protocol/unreal32.cpp31
187 files changed, 4425 insertions, 1605 deletions
diff --git a/modules/core/botserv.h b/modules/core/botserv.h
new file mode 100644
index 000000000..5c707278a
--- /dev/null
+++ b/modules/core/botserv.h
@@ -0,0 +1,65 @@
+#ifndef BOTSERV_H
+#define BOTSERV_H
+
+struct UserData
+{
+ UserData()
+ {
+ this->Clear();
+ }
+
+ void Clear()
+ {
+ last_use = last_start = Anope::CurTime;
+ lines = times = 0;
+ lastline.clear();
+ }
+
+ /* Data validity */
+ time_t last_use;
+
+ /* for flood kicker */
+ int16 lines;
+ time_t last_start;
+
+ /* for repeat kicker */
+ Anope::string lastline;
+ Anope::string lasttarget;
+ int16 times;
+};
+
+struct BanData
+{
+ Anope::string mask;
+ time_t last_use;
+ int16 ttb[TTB_SIZE];
+
+ BanData()
+ {
+ this->Clear();
+ }
+
+ void Clear()
+ {
+ last_use = 0;
+ for (int i = 0; i < TTB_SIZE; ++i)
+ this->ttb[i] = 0;
+ }
+};
+
+class BotServService : public Service
+{
+ public:
+ BotServService(Module *m) : Service(m, "BotServ") { }
+
+ virtual BotInfo *Bot() = 0;
+
+ virtual UserData *GetUserData(User *u, Channel *c) = 0;
+
+ virtual BanData *GetBanData(User *u, Channel *c) = 0;
+};
+
+static service_reference<BotServService> botserv("BotServ");
+
+#endif // BOTSERV_H
+
diff --git a/modules/core/bs_act.cpp b/modules/core/bs_act.cpp
index 3e868c25a..2547ce3c1 100644
--- a/modules/core/bs_act.cpp
+++ b/modules/core/bs_act.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "botserv.h"
class CommandBSAct : public Command
{
@@ -35,7 +36,7 @@ class CommandBSAct : public Command
if (!ci->bi)
{
- source.Reply(_(BOT_NOT_ASSIGNED), Config->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str());
+ source.Reply(_(BOT_NOT_ASSIGNED), Config->UseStrictPrivMsgString.c_str(), Config->s_BotServ.c_str());
return MOD_CONT;
}
@@ -83,7 +84,10 @@ class BSAct : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(BotServ, &commandbsact);
+ if (!botserv)
+ throw ModuleException("BotServ is not loaded!");
+
+ this->AddCommand(botserv->Bot(), &commandbsact);
}
};
diff --git a/modules/core/bs_assign.cpp b/modules/core/bs_assign.cpp
index f1000cb11..5be9e6bf3 100644
--- a/modules/core/bs_assign.cpp
+++ b/modules/core/bs_assign.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "botserv.h"
class CommandBSAssign : public Command
{
@@ -93,7 +94,10 @@ class BSAssign : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(BotServ, &commandbsassign);
+ if (!botserv)
+ throw ModuleException("BotServ is not loaded!");
+
+ this->AddCommand(botserv->Bot(), &commandbsassign);
}
};
diff --git a/modules/core/bs_badwords.cpp b/modules/core/bs_badwords.cpp
index 5acbf913f..1b3b2a884 100644
--- a/modules/core/bs_badwords.cpp
+++ b/modules/core/bs_badwords.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "botserv.h"
class BadwordsListCallback : public NumberList
{
@@ -291,7 +292,7 @@ class CommandBSBadwords : public Command
"will be done if a user says a word that ends with\n"
"\037word\037. If you don't specify anything, a kick will\n"
"be issued every time \037word\037 is said by a user.\n"
- " \n"), Config->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str());
+ " \n"), Config->UseStrictPrivMsgString.c_str(), Config->s_BotServ.c_str());
source.Reply(_("The \002BADWORDS DEL\002 command removes the given word from the\n"
"bad words list. If a list of entry numbers is given, those\n"
"entries are deleted. (See the example for LIST below.)\n"
@@ -325,7 +326,10 @@ class BSBadwords : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(BotServ, &commandbsbadwords);
+ if (!botserv)
+ throw ModuleException("BotServ is not loaded!");
+
+ this->AddCommand(botserv->Bot(), &commandbsbadwords);
}
};
diff --git a/modules/core/bs_bot.cpp b/modules/core/bs_bot.cpp
index d35d90ec1..64413b5f0 100644
--- a/modules/core/bs_bot.cpp
+++ b/modules/core/bs_bot.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "botserv.h"
class CommandBSBot : public Command
{
@@ -423,7 +424,10 @@ class BSBot : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(BotServ, &commandbsbot);
+ if (!botserv)
+ throw ModuleException("BotServ is not loaded!");
+
+ this->AddCommand(botserv->Bot(), &commandbsbot);
}
};
diff --git a/modules/core/bs_botlist.cpp b/modules/core/bs_botlist.cpp
index 1310a6358..a6a56f088 100644
--- a/modules/core/bs_botlist.cpp
+++ b/modules/core/bs_botlist.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "botserv.h"
class CommandBSBotList : public Command
{
@@ -83,7 +84,10 @@ class BSBotList : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(BotServ, &commandbsbotlist);
+ if (!botserv)
+ throw ModuleException("BotServ is not loaded!");
+
+ this->AddCommand(botserv->Bot(), &commandbsbotlist);
}
};
diff --git a/modules/core/bs_help.cpp b/modules/core/bs_help.cpp
index c2632b437..eafa5b44e 100644
--- a/modules/core/bs_help.cpp
+++ b/modules/core/bs_help.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "botserv.h"
class CommandBSHelp : public Command
{
@@ -25,7 +26,7 @@ class CommandBSHelp : public Command
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
- mod_help_cmd(BotServ, source.u, NULL, params[0]);
+ mod_help_cmd(botserv->Bot(), source.u, NULL, params[0]);
return MOD_CONT;
}
@@ -40,9 +41,9 @@ class CommandBSHelp : public Command
"below; to use them, type \002%s%s \037command\037\002. For\n"
"more information on a specific command, type\n"
"\002%s%s HELP \037command\037\002."),
- BotServ->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str(),
- Config->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str());
- for (CommandMap::const_iterator it = BotServ->Commands.begin(), it_end = BotServ->Commands.end(); it != it_end; ++it)
+ Config->s_BotServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->s_BotServ.c_str(),
+ Config->UseStrictPrivMsgString.c_str(), Config->s_BotServ.c_str());
+ for (CommandMap::const_iterator it = botserv->Bot()->Commands.begin(), it_end = botserv->Bot()->Commands.end(); it != it_end; ++it)
if (!Config->HidePrivilegedCommands || it->second->permission.empty() || u->HasCommand(it->second->permission))
it->second->OnServHelp(source);
source.Reply(_("Bot will join a channel whenever there is at least\n"
@@ -62,7 +63,10 @@ class BSHelp : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(BotServ, &commandbshelp);
+ if (!botserv)
+ throw ModuleException("BotServ is not loaded!");
+
+ this->AddCommand(botserv->Bot(), &commandbshelp);
}
};
diff --git a/modules/core/bs_info.cpp b/modules/core/bs_info.cpp
index a5853f611..afb13c66d 100644
--- a/modules/core/bs_info.cpp
+++ b/modules/core/bs_info.cpp
@@ -13,6 +13,7 @@
/*************************************************************************/
#include "module.h"
+#include "botserv.h"
class CommandBSInfo : public Command
{
@@ -227,7 +228,7 @@ class CommandBSInfo : public Command
"If the parameter is a channel, then you'll get information\n"
"such as enabled kickers. If the parameter is a nick,\n"
"you'll get information about a bot, such as creation\n"
- "time or number of channels it is on."), NickServ->nick.c_str());
+ "time or number of channels it is on."), Config->s_NickServ.c_str());
return true;
}
@@ -247,7 +248,10 @@ class BSInfo : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(BotServ, &commandbsinfo);
+ if (!botserv)
+ throw ModuleException("BotServ is not loaded!");
+
+ this->AddCommand(botserv->Bot(), &commandbsinfo);
}
};
diff --git a/modules/core/bs_kick.cpp b/modules/core/bs_kick.cpp
index ff68b7099..9b78d6e7b 100644
--- a/modules/core/bs_kick.cpp
+++ b/modules/core/bs_kick.cpp
@@ -13,6 +13,7 @@
/*************************************************************************/
#include "module.h"
+#include "botserv.h"
class CommandBSKick : public Command
{
@@ -41,7 +42,7 @@ class CommandBSKick : public Command
else if (!check_access(u, ci, CA_SET) && !u->HasPriv("botserv/administration"))
source.Reply(_(ACCESS_DENIED));
else if (!ci->bi)
- source.Reply(_(BOT_NOT_ASSIGNED), Config->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str());
+ source.Reply(_(BOT_NOT_ASSIGNED), Config->UseStrictPrivMsgString.c_str(), Config->s_BotServ.c_str());
else
{
bool override = !check_access(u, ci, CA_SET);
@@ -479,7 +480,7 @@ class CommandBSKick : public Command
"on a specific option.\n"
" \n"
"Note: access to this command is controlled by the\n"
- "level SET."), Config->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str());
+ "level SET."), Config->UseStrictPrivMsgString.c_str(), Config->s_BotServ.c_str());
else if (subcommand.equals_ci("BADWORDS"))
source.Reply(_("Syntax: \002KICK \037#channel\037 BADWORDS {\037ON|OFF\037} [\037ttb\037]\002\n"
"Sets the bad words kicker on or off. When enabled, this\n"
@@ -490,7 +491,7 @@ class CommandBSKick : public Command
"more information.\n"
"ttb is the number of times a user can be kicked\n"
"before it get banned. Don't give ttb to disable\n"
- "the ban system once activated."), Config->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str());
+ "the ban system once activated."), Config->UseStrictPrivMsgString.c_str(), Config->s_BotServ.c_str());
else if (subcommand.equals_ci("BOLDS"))
source.Reply(_("Syntax: \002KICK \037channel\037 BOLDS {\037ON|OFF\037} [\037ttb\037]\002\n"
"Sets the bolds kicker on or off. When enabled, this\n"
@@ -581,47 +582,301 @@ class BSKick : public Module
{
CommandBSKick commandbskick;
+ void check_ban(ChannelInfo *ci, User *u, int ttbtype)
+ {
+ /* Don't ban ulines */
+ if (u->server->IsULined())
+ return;
+
+ BanData *bd = botserv->GetBanData(u, ci->c);
+
+ ++bd->ttb[ttbtype];
+ if (ci->ttb[ttbtype] && bd->ttb[ttbtype] >= ci->ttb[ttbtype])
+ {
+ /* Should not use == here because bd->ttb[ttbtype] could possibly be > ci->ttb[ttbtype]
+ * if the TTB was changed after it was not set (0) before and the user had already been
+ * kicked a few times. Bug #1056 - Adam */
+ Anope::string mask;
+
+ bd->ttb[ttbtype] = 0;
+
+ get_idealban(ci, u, mask);
+
+ if (ci->c)
+ ci->c->SetMode(NULL, CMODE_BAN, mask);
+ FOREACH_MOD(I_OnBotBan, OnBotBan(u, ci, mask));
+ }
+ }
+
+ void bot_kick(ChannelInfo *ci, User *u, const char *message, ...)
+ {
+ va_list args;
+ char buf[1024];
+
+ if (!ci || !ci->bi || !ci->c || !u || u->server->IsULined())
+ return;
+
+ Anope::string fmt = GetString(u->Account(), message);
+ va_start(args, message);
+ if (fmt.empty())
+ return;
+ vsnprintf(buf, sizeof(buf), fmt.c_str(), args);
+ va_end(args);
+
+ ci->c->Kick(ci->bi, u, "%s", buf);
+ }
+
public:
BSKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
{
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(BotServ, &commandbskick);
+ if (!botserv)
+ throw ModuleException("BotServ is not loaded!");
+
+ this->AddCommand(botserv->Bot(), &commandbskick);
ModuleManager::Attach(I_OnPrivmsg, this);
}
- EventReturn OnPrivmsg(User *u, ChannelInfo *ci, Anope::string &msg, bool &Allow)
+ void OnPrivmsg(User *u, ChannelInfo *ci, Anope::string &msg)
{
- Anope::string m, ch;
- time_t time;
-
- if (u->GetExtRegular("bs_kick_lastmsg", m) && u->GetExtRegular("bs_kick_lasttime", time) && u->GetExtRegular("bs_kick_lastchan", ch))
+ /* Now we can make kicker stuff. We try to order the checks
+ * from the fastest one to the slowest one, since there's
+ * no need to process other kickers if a user is kicked before
+ * the last kicker check.
+ *
+ * But FIRST we check whether the user is protected in any
+ * way.
+ */
+
+ bool Allow = true;
+ if (check_access(u, ci, CA_NOKICK))
+ Allow = false;
+ else if (ci->botflags.HasFlag(BS_DONTKICKOPS) && (ci->c->HasUserStatus(u, CMODE_HALFOP) || ci->c->HasUserStatus(u, CMODE_OP) || ci->c->HasUserStatus(u, CMODE_PROTECT) || ci->c->HasUserStatus(u, CMODE_OWNER)))
+ Allow = false;
+ else if (ci->botflags.HasFlag(BS_DONTKICKVOICES) && ci->c->HasUserStatus(u, CMODE_VOICE))
+ Allow = false;
+
+ if (Allow)
{
- if (time == Anope::CurTime && m == msg && ch != ci->name)
+ Anope::string realbuf = msg;
+
+ /* Bolds kicker */
+ if (ci->botflags.HasFlag(BS_KICK_BOLDS) && realbuf.find(2) != Anope::string::npos)
+ {
+ check_ban(ci, u, TTB_BOLDS);
+ bot_kick(ci, u, _("Don't use bolds on this channel!"));
+ return;
+ }
+
+ /* Color kicker */
+ if (ci->botflags.HasFlag(BS_KICK_COLORS) && realbuf.find(3) != Anope::string::npos)
+ {
+ check_ban(ci, u, TTB_COLORS);
+ bot_kick(ci, u, _("Don't use colors on this channel!"));
+ return;
+ }
+
+ /* Reverses kicker */
+ if (ci->botflags.HasFlag(BS_KICK_REVERSES) && realbuf.find(22) != Anope::string::npos)
+ {
+ check_ban(ci, u, TTB_REVERSES);
+ bot_kick(ci, u, _("Don't use reverses on this channel!"));
+ return;
+ }
+
+ /* Italics kicker */
+ if (ci->botflags.HasFlag(BS_KICK_ITALICS) && realbuf.find(29) != Anope::string::npos)
+ {
+ check_ban(ci, u, TTB_ITALICS);
+ bot_kick(ci, u, _("Don't use italics on this channel!"));
+ return;
+ }
+
+ /* Underlines kicker */
+ if (ci->botflags.HasFlag(BS_KICK_UNDERLINES) && realbuf.find(31) != Anope::string::npos)
+ {
+ check_ban(ci, u, TTB_UNDERLINES);
+ bot_kick(ci, u, _("Don't use underlines on this channel!"));
+ return;
+ }
+
+ /* Caps kicker */
+ if (ci->botflags.HasFlag(BS_KICK_CAPS) && realbuf.length() >= ci->capsmin)
+ {
+ int i = 0, l = 0;
+
+ for (unsigned j = 0, end = realbuf.length(); j < end; ++j)
+ {
+ if (isupper(realbuf[j]))
+ ++i;
+ else if (islower(realbuf[j]))
+ ++l;
+ }
+
+ /* i counts uppercase chars, l counts lowercase chars. Only
+ * alphabetic chars (so islower || isupper) qualify for the
+ * percentage of caps to kick for; the rest is ignored. -GD
+ */
+
+ if ((i || l) && i >= ci->capsmin && i * 100 / (i + l) >= ci->capspercent)
+ {
+ check_ban(ci, u, TTB_CAPS);
+ bot_kick(ci, u, _("Turn caps lock OFF!"));
+ return;
+ }
+ }
+
+ /* Bad words kicker */
+ if (ci->botflags.HasFlag(BS_KICK_BADWORDS))
{
- for (UChannelList::iterator it = u->chans.begin(); it != u->chans.end();)
+ bool mustkick = false;
+
+ /* Normalize the buffer */
+ Anope::string nbuf = normalizeBuffer(realbuf);
+
+ for (unsigned i = 0, end = ci->GetBadWordCount(); i < end; ++i)
{
- Channel *c = (*it)->chan;
- ++it;
+ BadWord *bw = ci->GetBadWord(i);
- if (c->ci != NULL && c->ci->botflags.HasFlag(BS_KICK_AMSGS))
+ if (bw->type == BW_ANY && ((Config->BSCaseSensitive && nbuf.find(bw->word) != Anope::string::npos) || (!Config->BSCaseSensitive && nbuf.find_ci(bw->word) != Anope::string::npos)))
+ mustkick = true;
+ else if (bw->type == BW_SINGLE)
{
- check_ban(c->ci, u, TTB_AMSGS);
- bot_kick(c->ci, u, _("Don't use AMSGs!"));
+ size_t len = bw->word.length();
+
+ if ((Config->BSCaseSensitive && bw->word.equals_cs(nbuf)) || (!Config->BSCaseSensitive && bw->word.equals_ci(nbuf)))
+ mustkick = true;
+ else if (nbuf.find(' ') == len && ((Config->BSCaseSensitive && bw->word.equals_cs(nbuf)) || (!Config->BSCaseSensitive && bw->word.equals_ci(nbuf))))
+ mustkick = true;
+ else
+ {
+ if (nbuf.rfind(' ') == nbuf.length() - len - 1 && ((Config->BSCaseSensitive && nbuf.find(bw->word) == nbuf.length() - len) || (!Config->BSCaseSensitive && nbuf.find_ci(bw->word) == nbuf.length() - len)))
+ mustkick = true;
+ else
+ {
+ Anope::string wordbuf = " " + bw->word + " ";
+
+ if ((Config->BSCaseSensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!Config->BSCaseSensitive && nbuf.find_ci(wordbuf) != Anope::string::npos))
+ mustkick = true;
+ }
+ }
+ }
+ else if (bw->type == BW_START)
+ {
+ size_t len = bw->word.length();
+
+ if ((Config->BSCaseSensitive && nbuf.substr(0, len).equals_cs(bw->word)) || (!Config->BSCaseSensitive && nbuf.substr(0, len).equals_ci(bw->word)))
+ mustkick = true;
+ else
+ {
+ Anope::string wordbuf = " " + bw->word;
+
+ if ((Config->BSCaseSensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!Config->BSCaseSensitive && nbuf.find_ci(wordbuf) != Anope::string::npos))
+ mustkick = true;
+ }
+ }
+ else if (bw->type == BW_END)
+ {
+ size_t len = bw->word.length();
+
+ if ((Config->BSCaseSensitive && nbuf.substr(nbuf.length() - len).equals_cs(bw->word)) || (!Config->BSCaseSensitive && nbuf.substr(nbuf.length() - len).equals_ci(bw->word)))
+ mustkick = true;
+ else
+ {
+ Anope::string wordbuf = bw->word + " ";
+
+ if ((Config->BSCaseSensitive && nbuf.find(wordbuf) != Anope::string::npos) || (!Config->BSCaseSensitive && nbuf.find_ci(wordbuf) != Anope::string::npos))
+ mustkick = true;
+ }
+ }
+
+ if (mustkick)
+ {
+ check_ban(ci, u, TTB_BADWORDS);
+ if (Config->BSGentleBWReason)
+ bot_kick(ci, u, _("Watch your language!"));
+ else
+ bot_kick(ci, u, _("Don't use the word \"%s\" on this channel!"), bw->word.c_str());
+
+ return;
}
}
- return EVENT_CONTINUE;
+ UserData *ud = NULL;
+
+ /* Flood kicker */
+ if (ci->botflags.HasFlag(BS_KICK_FLOOD))
+ {
+ ud = botserv->GetUserData(u, ci->c);
+ if (ud)
+ {
+ if (Anope::CurTime - ud->last_start > ci->floodsecs)
+ {
+ ud->last_start = Anope::CurTime;
+ ud->lines = 0;
+ }
+
+ ++ud->lines;
+ if (ud->lines >= ci->floodlines)
+ {
+ check_ban(ci, u, TTB_FLOOD);
+ bot_kick(ci, u, _("Stop flooding!"));
+ return;
+ }
+ }
+ }
+
+ /* Repeat kicker */
+ if (ci->botflags.HasFlag(BS_KICK_REPEAT))
+ {
+ if (!ud)
+ ud = botserv->GetUserData(u, ci->c);
+ if (ud)
+ {
+
+ if (!ud->lastline.empty() && !ud->lastline.equals_ci(realbuf))
+ {
+ ud->lastline = realbuf;
+ ud->times = 0;
+ }
+ else
+ {
+ if (ud->lastline.empty())
+ ud->lastline = realbuf;
+ ++ud->times;
+ }
+
+ if (ud->times >= ci->repeattimes)
+ {
+ check_ban(ci, u, TTB_REPEAT);
+ bot_kick(ci, u, _("Stop repeating yourself!"));
+ return;
+ }
+ }
+ }
+
+ if (ud && ud->lastline.equals_ci(realbuf) && !ud->lasttarget.empty() && !ud->lasttarget.equals_ci(ci->name))
+ {
+ for (UChannelList::iterator it = u->chans.begin(); it != u->chans.end();)
+ {
+ Channel *c = (*it)->chan;
+ ++it;
+
+ if (c->ci != NULL && c->ci->botflags.HasFlag(BS_KICK_AMSGS) && !check_access(u, c->ci, CA_NOKICK))
+ {
+ check_ban(c->ci, u, TTB_AMSGS);
+ bot_kick(c->ci, u, _("Don't use AMSGs!"));
+ }
+ }
+ }
+
+ if (ud)
+ ud->lasttarget = ci->name;
}
}
-
- u->Extend("bs_kick_lastmsg", new ExtensibleItemRegular<Anope::string>(msg));
- u->Extend("bs_kick_lasttime", new ExtensibleItemRegular<time_t>(Anope::CurTime));
- u->Extend("bs_kick_lastchan", new ExtensibleItemRegular<Anope::string>(ci->name));
-
- return EVENT_CONTINUE;
}
};
diff --git a/modules/core/bs_main.cpp b/modules/core/bs_main.cpp
new file mode 100644
index 000000000..5bd7e5ce2
--- /dev/null
+++ b/modules/core/bs_main.cpp
@@ -0,0 +1,265 @@
+/* BotServ 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 "botserv.h"
+#include "chanserv.h"
+
+static BotInfo *BotServ = NULL;
+
+class BotServBotInfo : public BotInfo
+{
+ public:
+ BotServBotInfo(const Anope::string &bnick, const Anope::string &user = "", const Anope::string &bhost = "", const Anope::string &real = "") : BotInfo(bnick, user, bhost, real) { }
+
+ void OnMessage(User *u, const Anope::string &message)
+ {
+ PushLanguage("anope", u->Account() ? u->Account()->language : "");
+
+ spacesepstream sep(message);
+ Anope::string command, param;
+ if (sep.GetToken(command) && sep.GetToken(param))
+ {
+ Command *c = FindCommand(this, command);
+ if (c)
+ {
+ if (ircdproto->IsChannelValid(param))
+ {
+ ChannelInfo *ci = cs_findchan(param);
+ if (ci)
+ {
+ if (ci->HasFlag(CI_FORBIDDEN) && !c->HasFlag(CFLAG_ALLOW_FORBIDDEN))
+ {
+ u->SendMessage(this, _(_(CHAN_X_FORBIDDEN)), ci->name.c_str());
+ Log(LOG_COMMAND, "denied", this) << "Access denied for user " << u->GetMask() << " with command " << command << " because of FORBIDDEN channel " << ci->name;
+ PopLanguage();
+ return;
+ }
+ else if (ci->HasFlag(CI_SUSPENDED) && !c->HasFlag(CFLAG_ALLOW_SUSPENDED))
+ {
+ u->SendMessage(this, _(_(CHAN_X_FORBIDDEN)), ci->name.c_str());
+ Log(LOG_COMMAND, "denied", this) << "Access denied for user " << u->GetMask() << " with command " << command << " because of SUSPENDED channel " << ci->name;
+ PopLanguage();
+ return;
+ }
+ }
+ else if (!c->HasFlag(CFLAG_ALLOW_UNREGISTEREDCHANNEL))
+ {
+ u->SendMessage(this, _(_(CHAN_X_NOT_REGISTERED)), param.c_str());
+ PopLanguage();
+ return;
+ }
+ }
+ /* A user not giving a channel name for a param that should be a channel */
+ else
+ {
+ u->SendMessage(this, _(CHAN_X_INVALID), param.c_str());
+ PopLanguage();
+ return;
+ }
+ }
+ }
+
+ PopLanguage();
+ BotInfo::OnMessage(u, message);
+ }
+};
+
+class MyBotServService : public BotServService
+{
+ public:
+ MyBotServService(Module *m) : BotServService(m) { }
+
+ BotInfo *Bot()
+ {
+ return BotServ;
+ }
+
+ UserData *GetUserData(User *u, Channel *c)
+ {
+ UserData *ud = NULL;
+ UserContainer *uc = c->FindUser(u);
+ if (uc != NULL)
+ {
+ if (!uc->GetExtPointer("bs_main_userdata", ud))
+ {
+ ud = new UserData();
+ uc->Extend("bs_main_userdata", new ExtensibleItemPointer<UserData>(ud));
+ }
+ }
+ return ud;
+ }
+
+ BanData *GetBanData(User *u, Channel *c)
+ {
+ std::map<Anope::string, BanData> bandatamap;
+ if (!c->GetExtRegular("bs_main_bandata", bandatamap));
+ c->Extend("bs_main_bandata", new ExtensibleItemRegular<std::map<Anope::string, BanData> >(bandatamap));
+ c->GetExtRegular("bs_main_bandata", bandatamap);
+
+ BanData *bd = &bandatamap[u->GetMask()];
+ if (bd->last_use && Anope::CurTime - bd->last_use > Config->BSKeepData)
+ bd->Clear();
+ bd->last_use = Anope::CurTime;
+ return bd;
+ }
+};
+
+class BanDataPurger : public CallBack
+{
+ public:
+ BanDataPurger(Module *owner) : CallBack(owner, 300, Anope::CurTime, true) { }
+
+ void Tick(time_t)
+ {
+ Log(LOG_DEBUG) << "bs_main: Running bandata purger";
+
+ for (channel_map::iterator it = ChannelList.begin(), it_end = ChannelList.end(); it != it_end; ++it)
+ {
+ Channel *c = it->second;
+
+ std::map<Anope::string, BanData> bandata;
+ if (c->GetExtRegular("bs_main_bandata", bandata))
+ {
+ for (std::map<Anope::string, BanData>::iterator it2 = bandata.begin(), it2_end = bandata.end(); it2 != it2_end; ++it2)
+ {
+ BanData *bd = &it2->second;
+
+ if (Anope::CurTime - bd->last_use > Config->BSKeepData)
+ {
+ bandata.erase(it2);
+ continue;
+ }
+ }
+
+ if (bandata.empty())
+ c->Shrink("bs_main_bandata");
+ }
+ }
+ }
+};
+
+class BotServCore : public Module
+{
+ MyBotServService mybotserv;
+ BanDataPurger bdpurger;
+
+ public:
+ BotServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator), mybotserv(this), bdpurger(this)
+ {
+ this->SetAuthor("Anope");
+ this->SetType(CORE);
+
+ ModuleManager::RegisterService(&this->mybotserv);
+
+ BotServ = new BotServBotInfo(Config->s_BotServ, Config->ServiceUser, Config->ServiceHost, Config->desc_BotServ);
+ BotServ->SetFlag(BI_CORE);
+
+ Implementation i[] = { I_OnPrivmsg };
+ ModuleManager::Attach(i, this, 1);
+
+ spacesepstream coreModules(Config->BotCoreModules);
+ Anope::string module;
+ while (coreModules.GetToken(module))
+ ModuleManager::LoadModule(module, NULL);
+ }
+
+ ~BotServCore()
+ {
+ spacesepstream coreModules(Config->BotCoreModules);
+ Anope::string module;
+ while (coreModules.GetToken(module))
+ {
+ Module *m = FindModule(module);
+ if (m != NULL)
+ ModuleManager::UnloadModule(m, NULL);
+ }
+
+ delete BotServ;
+ }
+
+ void OnPrivmsg(User *u, ChannelInfo *ci, Anope::string &msg)
+ {
+ if (!u || !ci || !ci->c || !ci->bi || msg.empty())
+ return;
+
+ /* Answer to ping if needed */
+ if (msg.substr(0, 6).equals_ci("\1PING ") && msg[msg.length() - 1] == '\1')
+ {
+ Anope::string ctcp = msg;
+ ctcp.erase(ctcp.begin());
+ ctcp.erase(ctcp.length() - 1);
+ ircdproto->SendCTCP(ci->bi, u->nick, "%s", ctcp.c_str());
+ }
+
+ bool was_action = false;
+
+ Anope::string realbuf = msg;
+
+ /* If it's a /me, cut the CTCP part because the ACTION will cause
+ * problems with the caps or badwords kicker
+ */
+ if (realbuf.substr(0, 8).equals_ci("\1ACTION ") && realbuf[realbuf.length() - 1] == '\1')
+ {
+ realbuf.erase(0, 8);
+ realbuf.erase(realbuf.length() - 1);
+ was_action = true;
+ }
+
+ if (realbuf.empty())
+ return;
+
+ /* Fantaisist commands */
+ if (ci->botflags.HasFlag(BS_FANTASY) && realbuf[0] == Config->BSFantasyCharacter[0] && !was_action && chanserv)
+ {
+ /* Strip off the fantasy character */
+ realbuf.erase(realbuf.begin());
+
+ size_t space = realbuf.find(' ');
+ Anope::string command, rest;
+ if (space == Anope::string::npos)
+ command = realbuf;
+ else
+ {
+ command = realbuf.substr(0, space);
+ rest = realbuf.substr(space + 1);
+ }
+
+ if (check_access(u, ci, CA_FANTASIA))
+ {
+ Command *cmd = FindCommand(chanserv->Bot(), command);
+
+ /* Command exists and can be called by fantasy */
+ if (cmd && !cmd->HasFlag(CFLAG_DISABLE_FANTASY))
+ {
+ Anope::string params = rest;
+ /* Some commands don't need the channel name added.. eg !help */
+ if (!cmd->HasFlag(CFLAG_STRIP_CHANNEL))
+ params = ci->name + " " + params;
+ params = command + " " + params;
+
+ mod_run_cmd(chanserv->Bot(), u, ci, params);
+ }
+
+ FOREACH_MOD(I_OnBotFantasy, OnBotFantasy(command, u, ci, rest));
+ }
+ else
+ {
+ FOREACH_MOD(I_OnBotNoFantasyAccess, OnBotNoFantasyAccess(command, u, ci, rest));
+ }
+ }
+ }
+};
+
+MODULE_INIT(BotServCore)
+
diff --git a/modules/core/bs_say.cpp b/modules/core/bs_say.cpp
index d64880964..673244a6c 100644
--- a/modules/core/bs_say.cpp
+++ b/modules/core/bs_say.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "botserv.h"
class CommandBSSay : public Command
{
@@ -36,7 +37,7 @@ class CommandBSSay : public Command
if (!ci->bi)
{
- source.Reply(_(BOT_NOT_ASSIGNED), Config->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str());
+ source.Reply(_(BOT_NOT_ASSIGNED), Config->UseStrictPrivMsgString.c_str(), Config->s_BotServ.c_str());
return MOD_CONT;
}
@@ -85,7 +86,10 @@ class BSSay : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(BotServ, &commandbssay);
+ if (!botserv)
+ throw ModuleException("BotServ is not loaded!");
+
+ this->AddCommand(botserv->Bot(), &commandbssay);
}
};
diff --git a/modules/core/bs_set.cpp b/modules/core/bs_set.cpp
index 24843fff7..daf37c199 100644
--- a/modules/core/bs_set.cpp
+++ b/modules/core/bs_set.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "botserv.h"
class CommandBSSet : public Command
{
@@ -216,7 +217,7 @@ class CommandBSSet : public Command
"Type \002%s%s HELP SET \037option\037\002 for more information\n"
"on a specific option.\n"
"Note: access to this command is controlled by the\n"
- "level SET."), Config->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str());
+ "level SET."), Config->UseStrictPrivMsgString.c_str(), Config->s_BotServ.c_str());
User *u = source.u;
if (u->IsServicesOper())
source.Reply(_("These options are reserved to Services Operators:\n"
@@ -308,7 +309,10 @@ class BSSet : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(BotServ, &commandbsset);
+ if (!botserv)
+ throw ModuleException("BotServ is not loaded!");
+
+ this->AddCommand(botserv->Bot(), &commandbsset);
}
};
diff --git a/modules/core/bs_unassign.cpp b/modules/core/bs_unassign.cpp
index 8e28508ab..104eded56 100644
--- a/modules/core/bs_unassign.cpp
+++ b/modules/core/bs_unassign.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "botserv.h"
class CommandBSUnassign : public Command
{
@@ -33,7 +34,7 @@ class CommandBSUnassign : public Command
else if (!u->HasPriv("botserv/administration") && !check_access(u, ci, CA_ASSIGN))
source.Reply(_(ACCESS_DENIED));
else if (!ci->bi)
- source.Reply(_(BOT_NOT_ASSIGNED), Config->UseStrictPrivMsgString.c_str(), BotServ->nick.c_str());
+ source.Reply(_(BOT_NOT_ASSIGNED), Config->UseStrictPrivMsgString.c_str(), Config->s_BotServ.c_str());
else if (ci->HasFlag(CI_PERSIST) && !cm)
source.Reply(_("You can not unassign bots while persist is set on the channel."));
else
@@ -75,7 +76,10 @@ class BSUnassign : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(BotServ, &commandbsunassign);
+ if (!botserv)
+ throw ModuleException("BotServ is not loaded!");
+
+ this->AddCommand(botserv->Bot(), &commandbsunassign);
}
};
diff --git a/modules/core/chanserv.h b/modules/core/chanserv.h
new file mode 100644
index 000000000..2017aa156
--- /dev/null
+++ b/modules/core/chanserv.h
@@ -0,0 +1,15 @@
+#ifndef CHANSERV_H
+#define CHANSERV_H
+
+class ChanServService : public Service
+{
+ public:
+ ChanServService(Module *m) : Service(m, "ChanServ") { }
+
+ virtual BotInfo *Bot() = 0;
+};
+
+static service_reference<ChanServService> chanserv("ChanServ");
+
+#endif // CHANSERV_H
+
diff --git a/modules/core/cs_access.cpp b/modules/core/cs_access.cpp
index 0cf8263ac..5fc4e7290 100644
--- a/modules/core/cs_access.cpp
+++ b/modules/core/cs_access.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class AccessListCallback : public NumberList
{
@@ -504,7 +505,7 @@ class CommandCSAccess : public Command
" \n"
"The \002ACCESS CLEAR\002 command clears all entries of the\n"
"access list."),
- ChanServ->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str());
+ Config->s_ChanServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
source.Reply(_("\002User access levels\002\n"
" \n"
"By default, the following access levels are defined:\n"
@@ -523,7 +524,7 @@ class CommandCSAccess : public Command
" \n"
"These levels may be changed, or new ones added, using the\n"
"\002LEVELS\002 command; type \002%s%s HELP LEVELS\002 for\n"
- "information."), ChanServ->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str());
+ "information."), Config->s_ChanServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
return true;
}
@@ -746,7 +747,7 @@ class CommandCSLevels : public Command
"\002HELP ACCESS LEVELS\002).\n"
" \n"
"For a list of the features and functions whose levels can be\n"
- "set, see \002HELP LEVELS DESC\002."), ChanServ->nick.c_str());
+ "set, see \002HELP LEVELS DESC\002."), Config->s_ChanServ.c_str());
return true;
}
@@ -767,8 +768,11 @@ class CSAccess : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(ChanServ, &commandcsaccess);
- this->AddCommand(ChanServ, &commandcslevels);
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ this->AddCommand(chanserv->Bot(), &commandcsaccess);
+ this->AddCommand(chanserv->Bot(), &commandcslevels);
}
};
diff --git a/modules/core/cs_akick.cpp b/modules/core/cs_akick.cpp
index 4584ac6b5..e168bdb67 100644
--- a/modules/core/cs_akick.cpp
+++ b/modules/core/cs_akick.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
/* Split a usermask up into its constitutent parts. Returned strings are
* malloc()'d, and should be free()'d when done with. Returns "*" for
@@ -532,7 +533,7 @@ class CommandCSAKick : public Command
"When akicking a \037registered nick\037 the nickserv account\n"
"will be added to the akick list instead of the mask.\n"
"All users within that nickgroup will then be akicked.\n"),
- ChanServ->nick.c_str());
+ Config->s_ChanServ.c_str());
source.Reply(_(
" \n"
"The \002AKICK DEL\002 command removes the given nick or mask\n"
@@ -552,7 +553,7 @@ class CommandCSAKick : public Command
"AKICK mask.\n"
" \n"
"The \002AKICK CLEAR\002 command clears all entries of the\n"
- "akick list."), ChanServ->nick.c_str());
+ "akick list."), Config->s_ChanServ.c_str());
return true;
}
@@ -572,7 +573,10 @@ class CSAKick : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(ChanServ, &commandcsakick);
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ this->AddCommand(chanserv->Bot(), &commandcsakick);
}
};
diff --git a/modules/core/cs_ban.cpp b/modules/core/cs_ban.cpp
index 97d205156..3bccd9897 100644
--- a/modules/core/cs_ban.cpp
+++ b/modules/core/cs_ban.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class CommandCSBan : public Command
{
@@ -67,9 +68,9 @@ class CommandCSBan : public Command
return MOD_CONT;
if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !check_access(u, ci, CA_SIGNKICK)))
- c->Kick(whosends(ci), u2, "%s (%s)", reason.c_str(), u->nick.c_str());
+ c->Kick(ci->WhoSends(), u2, "%s (%s)", reason.c_str(), u->nick.c_str());
else
- c->Kick(whosends(ci), u2, "%s", reason.c_str());
+ c->Kick(ci->WhoSends(), u2, "%s", reason.c_str());
}
return MOD_CONT;
@@ -102,7 +103,10 @@ class CSBan : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(ChanServ, &commandcsban);
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ this->AddCommand(chanserv->Bot(), &commandcsban);
}
};
diff --git a/modules/core/cs_clearusers.cpp b/modules/core/cs_clearusers.cpp
index 572c396af..7cf5055b7 100644
--- a/modules/core/cs_clearusers.cpp
+++ b/modules/core/cs_clearusers.cpp
@@ -12,13 +12,14 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class CommandCSClearUsers : public Command
{
public:
CommandCSClearUsers() : Command("CLEARUSERS", 1, 1)
{
- this->SetDesc(_("Tells ChanServ to clear (kick) all users on a channel"));
+ this->SetDesc(Anope::printf(_("Tells %s to kick all users on a channel"), Config->s_ChanServ.c_str()));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
@@ -57,7 +58,7 @@ class CommandCSClearUsers : public Command
"Tells %s to clear (kick) all users certain settings on a channel."
" \n"
"By default, limited to those with founder access on the\n"
- "channel."), ChanServ->nick.c_str());
+ "channel."), Config->s_ChanServ.c_str());
return true;
}
@@ -77,7 +78,10 @@ class CSClearUsers : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(ChanServ, &commandcsclearusers);
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ this->AddCommand(chanserv->Bot(), &commandcsclearusers);
}
};
diff --git a/modules/core/cs_clone.cpp b/modules/core/cs_clone.cpp
index bbdae4c5f..52161abf1 100644
--- a/modules/core/cs_clone.cpp
+++ b/modules/core/cs_clone.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class CommandCSClone : public Command
{
@@ -177,7 +178,10 @@ class CSClone : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(ChanServ, &commandcsclone);
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ this->AddCommand(chanserv->Bot(), &commandcsclone);
}
};
diff --git a/modules/core/cs_drop.cpp b/modules/core/cs_drop.cpp
index 248cfa37e..66f1b31f6 100644
--- a/modules/core/cs_drop.cpp
+++ b/modules/core/cs_drop.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class CommandCSDrop : public Command
{
@@ -67,8 +68,6 @@ class CommandCSDrop : public Command
bool override = (ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER));
Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "founder: " << (ci->founder ? ci->founder->display : "none");
- if (override)
- ircdproto->SendGlobops(ChanServ, "\2%s\2 used DROP on channel \2%s\2", u->nick.c_str(), ci->name.c_str());
delete ci;
@@ -112,7 +111,10 @@ class CSDrop : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(ChanServ, &commandcsdrop);
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ this->AddCommand(chanserv->Bot(), &commandcsdrop);
}
};
diff --git a/modules/core/cs_forbid.cpp b/modules/core/cs_forbid.cpp
index e17a1777c..9c0573971 100644
--- a/modules/core/cs_forbid.cpp
+++ b/modules/core/cs_forbid.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class CommandCSForbid : public Command
{
@@ -75,7 +76,7 @@ class CommandCSForbid : public Command
if (uc->user->HasMode(UMODE_OPER))
continue;
- c->Kick(ChanServ, uc->user, "%s", !reason.empty() ? reason.c_str() : GetString(uc->user->Account(), "This channel has been forbidden.").c_str());
+ c->Kick(chanserv->Bot(), uc->user, "%s", !reason.empty() ? reason.c_str() : GetString(uc->user->Account(), "This channel has been forbidden.").c_str());
}
}
@@ -121,7 +122,10 @@ class CSForbid : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(ChanServ, &commandcsforbid);
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ this->AddCommand(chanserv->Bot(), &commandcsforbid);
}
};
diff --git a/modules/core/cs_getkey.cpp b/modules/core/cs_getkey.cpp
index da71e690e..b46a7df53 100644
--- a/modules/core/cs_getkey.cpp
+++ b/modules/core/cs_getkey.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class CommandCSGetKey : public Command
{
@@ -72,7 +73,10 @@ class CSGetKey : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(ChanServ, &commandcsgetkey);
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ this->AddCommand(chanserv->Bot(), &commandcsgetkey);
}
};
diff --git a/modules/core/cs_help.cpp b/modules/core/cs_help.cpp
index be2436d29..aff4c5165 100644
--- a/modules/core/cs_help.cpp
+++ b/modules/core/cs_help.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class CommandCSHelp : public Command
{
@@ -25,7 +26,7 @@ class CommandCSHelp : public Command
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
- mod_help_cmd(ChanServ, source.u, NULL, params[0]);
+ mod_help_cmd(chanserv->Bot(), source.u, NULL, params[0]);
return MOD_CONT;
}
@@ -40,9 +41,8 @@ class CommandCSHelp : public Command
"commands are listed below; to use them, type\n"
"\002%s%s \037command\037\002. For more information on a\n"
"specific command, type \002%s%s HELP \037command\037\002."),
- ChanServ->nick.c_str(), ChanServ->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str(),
- ChanServ->nick.c_str());
- for (CommandMap::const_iterator it = ChanServ->Commands.begin(); it != ChanServ->Commands.end(); ++it)
+ Config->s_ChanServ.c_str(), Config->s_ChanServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str(), Config->s_ChanServ.c_str());
+ for (CommandMap::const_iterator it = chanserv->Bot()->Commands.begin(); it != chanserv->Bot()->Commands.end(); ++it)
if (!Config->HidePrivilegedCommands || it->second->permission.empty() || u->HasCommand(it->second->permission))
it->second->OnServHelp(source);
if (Config->CSExpire >= 86400)
@@ -67,7 +67,10 @@ class CSHelp : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(ChanServ, &commandcshelp);
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ this->AddCommand(chanserv->Bot(), &commandcshelp);
}
};
diff --git a/modules/core/cs_info.cpp b/modules/core/cs_info.cpp
index c9c8b674c..19823004d 100644
--- a/modules/core/cs_info.cpp
+++ b/modules/core/cs_info.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class CommandCSInfo : public Command
{
@@ -140,7 +141,10 @@ class CSInfo : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(ChanServ, &commandcsinfo);
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ this->AddCommand(chanserv->Bot(), &commandcsinfo);
}
};
diff --git a/modules/core/cs_invite.cpp b/modules/core/cs_invite.cpp
index efafdeedd..e7bcbbdab 100644
--- a/modules/core/cs_invite.cpp
+++ b/modules/core/cs_invite.cpp
@@ -12,13 +12,14 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class CommandCSInvite : public Command
{
public:
CommandCSInvite() : Command("INVITE", 1, 3)
{
- this->SetDesc(_("Tells ChanServ to invite you into a channel"));
+ this->SetDesc(Anope::printf(_("Tells %s to invite you into a channel"), Config->s_ChanServ.c_str()));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
@@ -62,9 +63,9 @@ class CommandCSInvite : public Command
source.Reply(_("You are already in \002%s\002! "), c->name.c_str());
else
{
- ircdproto->SendInvite(whosends(ci), chan, u2->nick);
+ ircdproto->SendInvite(ci->WhoSends(), chan, u2->nick);
source.Reply(_("\002%s\002 has been invited to \002%s\002."), u2->nick.c_str(), c->name.c_str());
- u2->SendMessage(whosends(ci), _("You have been invited to \002%s\002."), c->name.c_str());
+ u2->SendMessage(ci->WhoSends(), _("You have been invited to \002%s\002."), c->name.c_str());
}
return MOD_CONT;
}
@@ -76,7 +77,7 @@ class CommandCSInvite : public Command
"Tells %s to invite you into the given channel.\n"
" \n"
"By default, limited to AOPs or those with level 5 and above\n"
- "on the channel."), ChanServ->nick.c_str());
+ "on the channel."), Config->s_ChanServ.c_str());
return true;
}
@@ -96,7 +97,10 @@ class CSInvite : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(ChanServ, &commandcsinvite);
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ this->AddCommand(chanserv->Bot(), &commandcsinvite);
}
};
diff --git a/modules/core/cs_kick.cpp b/modules/core/cs_kick.cpp
index 2f165fb72..2cf06e1e4 100644
--- a/modules/core/cs_kick.cpp
+++ b/modules/core/cs_kick.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class CommandCSKick : public Command
{
@@ -54,9 +55,9 @@ class CommandCSKick : public Command
Log(LOG_COMMAND, u, this, ci) << "for " << u2->nick;
if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !check_access(u, ci, CA_SIGNKICK)))
- ci->c->Kick(whosends(ci), u2, "%s (%s)", reason.c_str(), u->nick.c_str());
+ ci->c->Kick(ci->WhoSends(), u2, "%s (%s)", reason.c_str(), u->nick.c_str());
else
- ci->c->Kick(whosends(ci), u2, "%s", reason.c_str());
+ ci->c->Kick(ci->WhoSends(), u2, "%s", reason.c_str());
}
return MOD_CONT;
}
@@ -88,7 +89,10 @@ class CSKick : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(ChanServ, &commandcskick);
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ this->AddCommand(chanserv->Bot(), &commandcskick);
}
};
diff --git a/modules/core/cs_list.cpp b/modules/core/cs_list.cpp
index 8e3d75e5f..318eea59f 100644
--- a/modules/core/cs_list.cpp
+++ b/modules/core/cs_list.cpp
@@ -12,7 +12,7 @@
/*************************************************************************/
#include "module.h"
-#include "hashcomp.h"
+#include "chanserv.h"
class CommandCSList : public Command
{
@@ -147,7 +147,10 @@ class CSList : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(ChanServ, &commandcslist);
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ this->AddCommand(chanserv->Bot(), &commandcslist);
}
};
diff --git a/modules/core/cs_main.cpp b/modules/core/cs_main.cpp
new file mode 100644
index 000000000..04258b646
--- /dev/null
+++ b/modules/core/cs_main.cpp
@@ -0,0 +1,256 @@
+/* ChanServ 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 "chanserv.h"
+
+static BotInfo *ChanServ = NULL;
+
+class ChanServBotInfo : public BotInfo
+{
+ public:
+ ChanServBotInfo(const Anope::string &bnick, const Anope::string &user = "", const Anope::string &bhost = "", const Anope::string &real = "") : BotInfo(bnick, user, bhost, real) { }
+
+ void OnMessage(User *u, const Anope::string &message)
+ {
+ PushLanguage("anope", u->Account() ? u->Account()->language : "");
+
+ if (!u->HasMode(UMODE_OPER) && Config->CSOpersOnly)
+ {
+ u->SendMessage(ChanServ, _(ACCESS_DENIED));
+ PopLanguage();
+ return;
+ }
+
+ spacesepstream sep(message);
+ Anope::string command, param;
+ if (sep.GetToken(command) && sep.GetToken(param))
+ {
+ Command *c = FindCommand(this, command);
+ if (c)
+ {
+ if (ircdproto->IsChannelValid(param))
+ {
+ ChannelInfo *ci = cs_findchan(param);
+ if (ci)
+ {
+ if (ci->HasFlag(CI_FORBIDDEN) && !c->HasFlag(CFLAG_ALLOW_FORBIDDEN))
+ {
+ u->SendMessage(this, _(_(CHAN_X_FORBIDDEN)), ci->name.c_str());
+ Log(LOG_COMMAND, "denied", this) << "Access denied for user " << u->GetMask() << " with command " << command << " because of FORBIDDEN channel " << ci->name;
+ PopLanguage();
+ return;
+ }
+ else if (ci->HasFlag(CI_SUSPENDED) && !c->HasFlag(CFLAG_ALLOW_SUSPENDED))
+ {
+ u->SendMessage(this, _(_(CHAN_X_FORBIDDEN)), ci->name.c_str());
+ Log(LOG_COMMAND, "denied", this) << "Access denied for user " << u->GetMask() << " with command " << command << " because of SUSPENDED channel " << ci->name;
+ PopLanguage();
+ return;
+ }
+ }
+ else if (!c->HasFlag(CFLAG_ALLOW_UNREGISTEREDCHANNEL))
+ {
+ u->SendMessage(this, _(_(CHAN_X_NOT_REGISTERED)), param.c_str());
+ PopLanguage();
+ return;
+ }
+ }
+ /* A user not giving a channel name for a param that should be a channel */
+ else
+ {
+ u->SendMessage(this, _(CHAN_X_INVALID), param.c_str());
+ PopLanguage();
+ return;
+ }
+ }
+ }
+
+ PopLanguage();
+ BotInfo::OnMessage(u, message);
+ }
+};
+
+class MyChanServService : public ChanServService
+{
+ public:
+ MyChanServService(Module *m) : ChanServService(m) { }
+
+ BotInfo *Bot()
+ {
+ return ChanServ;
+ }
+};
+
+class ExpireCallback : public CallBack
+{
+ public:
+ ExpireCallback(Module *owner) : CallBack(owner, Config->ExpireTimeout, Anope::CurTime, true) { }
+
+ void Tick(time_t)
+ {
+ if (!Config->CSExpire || noexpire || readonly)
+ return;
+
+ for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(), it_end = RegisteredChannelList.end(); it != it_end; )
+ {
+ ChannelInfo *ci = it->second;
+ ++it;
+
+ bool expire = false;
+ if (ci->HasFlag(CI_SUSPENDED))
+ {
+ if (Config->CSSuspendExpire && Anope::CurTime - ci->last_used >= Config->CSSuspendExpire)
+ expire = true;
+ }
+ else if (ci->HasFlag(CI_FORBIDDEN))
+ {
+ if (Config->CSForbidExpire && Anope::CurTime - ci->last_used >= Config->CSForbidExpire)
+ expire = true;
+ }
+ else if (!ci->c && Anope::CurTime - ci->last_used >= Config->CSExpire)
+ expire = true;
+
+ if (ci->HasFlag(CI_NO_EXPIRE))
+ expire = false;
+
+ if (expire)
+ {
+ EventReturn MOD_RESULT;
+ FOREACH_RESULT(I_OnPreChanExpire, OnPreChanExpire(ci));
+ if (MOD_RESULT == EVENT_STOP)
+ continue;
+
+ Anope::string extra;
+ if (ci->HasFlag(CI_FORBIDDEN))
+ extra = "forbidden ";
+ else if (ci->HasFlag(CI_SUSPENDED))
+ extra = "suspended ";
+
+ Log(LOG_NORMAL, "chanserv/expire", ChanServ) << "Expiring " << extra << "channel " << ci->name << " (founder: " << (ci->founder ? ci->founder->display : "(none)") << ")";
+ FOREACH_MOD(I_OnChanExpire, OnChanExpire(ci));
+ delete ci;
+ }
+ }
+ }
+};
+
+class ChanServCore : public Module
+{
+ MyChanServService mychanserv;
+ ExpireCallback expires;
+
+ public:
+ ChanServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator), mychanserv(this), expires(this)
+ {
+ this->SetAuthor("Anope");
+ this->SetType(CORE);
+
+ ModuleManager::RegisterService(&this->mychanserv);
+
+ ChanServ = new ChanServBotInfo(Config->s_ChanServ, Config->ServiceUser, Config->ServiceHost, Config->desc_ChanServ);
+ ChanServ->SetFlag(BI_CORE);
+
+ Implementation i[] = { I_OnDelCore, I_OnDelChan };
+ ModuleManager::Attach(i, this, 2);
+
+ spacesepstream coreModules(Config->ChanCoreModules);
+ Anope::string module;
+ while (coreModules.GetToken(module))
+ ModuleManager::LoadModule(module, NULL);
+ }
+
+ ~ChanServCore()
+ {
+ spacesepstream coreModules(Config->ChanCoreModules);
+ Anope::string module;
+ while (coreModules.GetToken(module))
+ {
+ Module *m = FindModule(module);
+ if (m != NULL)
+ ModuleManager::UnloadModule(m, NULL);
+ }
+
+ delete ChanServ;
+ }
+
+ void OnDelCore(NickCore *nc)
+ {
+ // XXX this is slightly inefficient
+ for (registered_channel_map::const_iterator it = RegisteredChannelList.begin(), it_end = RegisteredChannelList.end(); it != it_end;)
+ {
+ ChannelInfo *ci = it->second;
+ ++it;
+
+ if (ci->founder == nc)
+ {
+ NickCore *newowner = NULL;
+ if (ci->successor && (ci->successor->IsServicesOper() || !Config->CSMaxReg || ci->successor->channelcount < Config->CSMaxReg))
+ newowner = ci->successor;
+ else
+ {
+ ChanAccess *highest = NULL;
+ for (unsigned j = 0; j < ci->GetAccessCount(); ++j)
+ {
+ ChanAccess *ca = ci->GetAccess(j);
+
+ if (!ca->nc || (!ca->nc->IsServicesOper() && Config->CSMaxReg && ca->nc->channelcount >= Config->CSMaxReg) || (ca->nc == nc))
+ continue;
+ if (!highest || ca->level > highest->level)
+ highest = ca;
+ }
+ if (highest)
+ newowner = highest->nc;
+ }
+
+ if (newowner)
+ {
+ Log(LOG_NORMAL, "chanserv/expire") << "Transferring foundership of " << ci->name << " from deleted nick " << nc->display << " to " << newowner->display;
+ ci->founder = newowner;
+ ci->successor = NULL;
+ ++newowner->channelcount;
+ }
+ else
+ {
+ Log(LOG_NORMAL, "chanserv/expire") << "Deleting channel " << ci->name << " owned by deleted nick " << nc->display;
+
+ delete ci;
+ continue;
+ }
+ }
+
+ if (ci->successor == nc)
+ ci->successor = NULL;
+
+ ChanAccess *access = ci->GetAccess(nc);
+ if (access)
+ ci->EraseAccess(access);
+
+ for (unsigned j = ci->GetAkickCount(); j > 0; --j)
+ {
+ AutoKick *akick = ci->GetAkick(j - 1);
+ if (akick->HasFlag(AK_ISNICK) && akick->nc == nc)
+ ci->EraseAkick(j - 1);
+ }
+ }
+ }
+
+ void OnDelChan(ChannelInfo *ci)
+ {
+ if (ci->c && ci->c->HasMode(CMODE_REGISTERED))
+ ci->c->RemoveMode(NULL, CMODE_REGISTERED, "", false);
+ }
+};
+
+MODULE_INIT(ChanServCore)
+
diff --git a/modules/core/cs_mode.cpp b/modules/core/cs_mode.cpp
index 55da9762c..fc4538033 100644
--- a/modules/core/cs_mode.cpp
+++ b/modules/core/cs_mode.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class CommandCSMode : public Command
{
@@ -366,7 +367,10 @@ class CSMode : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(ChanServ, &commandcsmode);
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ this->AddCommand(chanserv->Bot(), &commandcsmode);
}
};
diff --git a/modules/core/cs_modes.cpp b/modules/core/cs_modes.cpp
index 96520b215..eeaf9f733 100644
--- a/modules/core/cs_modes.cpp
+++ b/modules/core/cs_modes.cpp
@@ -12,7 +12,7 @@
/*************************************************************************/
#include "module.h"
-
+#include "chanserv.h"
class CommandModeBase : public Command
{
@@ -76,7 +76,7 @@ class CommandModeBase : public Command
Log(LOG_COMMAND, u, com, ci) << "for " << u2->nick;
if (notice && ci->HasFlag(notice))
- ircdproto->SendMessage(whosends(ci), c->name, "%s command used for %s by %s", com->name.c_str(), u2->nick.c_str(), u->nick.c_str());
+ ircdproto->SendMessage(ci->WhoSends(), c->name, "%s command used for %s by %s", com->name.c_str(), u2->nick.c_str(), u->nick.c_str());
}
}
@@ -462,10 +462,13 @@ class CSModes : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(ChanServ, &commandcsop);
- this->AddCommand(ChanServ, &commandcsdeop);
- this->AddCommand(ChanServ, &commandcsvoice);
- this->AddCommand(ChanServ, &commandcsdevoice);
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ this->AddCommand(chanserv->Bot(), &commandcsop);
+ this->AddCommand(chanserv->Bot(), &commandcsdeop);
+ this->AddCommand(chanserv->Bot(), &commandcsvoice);
+ this->AddCommand(chanserv->Bot(), &commandcsdevoice);
if (Me && Me->IsSynced())
OnUplinkSync(NULL);
@@ -478,31 +481,31 @@ class CSModes : public Module
{
if (ModeManager::FindChannelModeByName(CMODE_OWNER))
{
- this->AddCommand(ChanServ, &commandcsowner);
- this->AddCommand(ChanServ, &commandcsdeowner);
+ this->AddCommand(chanserv->Bot(), &commandcsowner);
+ this->AddCommand(chanserv->Bot(), &commandcsdeowner);
}
if (ModeManager::FindChannelModeByName(CMODE_PROTECT))
{
- this->AddCommand(ChanServ, &commandcsprotect);
- this->AddCommand(ChanServ, &commandcsdeprotect);
+ this->AddCommand(chanserv->Bot(), &commandcsprotect);
+ this->AddCommand(chanserv->Bot(), &commandcsdeprotect);
}
if (ModeManager::FindChannelModeByName(CMODE_HALFOP))
{
- this->AddCommand(ChanServ, &commandcshalfop);
- this->AddCommand(ChanServ, &commandcsdehalfop);
+ this->AddCommand(chanserv->Bot(), &commandcshalfop);
+ this->AddCommand(chanserv->Bot(), &commandcsdehalfop);
}
}
void OnServerDisconnect()
{
- this->DelCommand(ChanServ, &commandcsowner);
- this->DelCommand(ChanServ, &commandcsdeowner);
- this->DelCommand(ChanServ, &commandcsprotect);
- this->DelCommand(ChanServ, &commandcsdeprotect);
- this->DelCommand(ChanServ, &commandcshalfop);
- this->DelCommand(ChanServ, &commandcsdehalfop);
+ this->DelCommand(chanserv->Bot(), &commandcsowner);
+ this->DelCommand(chanserv->Bot(), &commandcsdeowner);
+ this->DelCommand(chanserv->Bot(), &commandcsprotect);
+ this->DelCommand(chanserv->Bot(), &commandcsdeprotect);
+ this->DelCommand(chanserv->Bot(), &commandcshalfop);
+ this->DelCommand(chanserv->Bot(), &commandcsdehalfop);
}
};
diff --git a/modules/core/cs_register.cpp b/modules/core/cs_register.cpp
index 09bcd812f..0682f045a 100644
--- a/modules/core/cs_register.cpp
+++ b/modules/core/cs_register.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class CommandCSRegister : public Command
{
@@ -117,7 +118,7 @@ class CommandCSRegister : public Command
"NOTICE: In order to register a channel, you must have\n"
"first registered your nickname. If you haven't,\n"
"\002%s%s HELP\002 for information on how to do so."),
- ChanServ->nick.c_str(), ChanServ->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str());
+ Config->s_ChanServ.c_str(), Config->s_ChanServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
return true;
}
@@ -137,7 +138,10 @@ class CSRegister : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(ChanServ, &commandcsregister);
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ this->AddCommand(chanserv->Bot(), &commandcsregister);
}
};
diff --git a/modules/core/cs_saset.cpp b/modules/core/cs_saset.cpp
index 4a512c26d..b262ce14a 100644
--- a/modules/core/cs_saset.cpp
+++ b/modules/core/cs_saset.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class CommandCSSASet : public Command
{
@@ -55,7 +56,7 @@ class CommandCSSASet : public Command
for (std::vector<Anope::string>::const_iterator it = params.begin() + 2, it_end = params.end(); it != it_end; ++it)
cmdparams += " " + *it;
Log(LOG_ADMIN, u, this, ci) << params[1] << " " << cmdparams;
- mod_run_cmd(ChanServ, u, NULL, c, params[1], cmdparams);
+ mod_run_cmd(chanserv->Bot(), u, NULL, c, params[1], cmdparams);
}
else
{
@@ -79,7 +80,7 @@ class CommandCSSASet : public Command
for (subcommand_map::iterator it = this->subcommands.begin(), it_end = this->subcommands.end(); it != it_end; ++it)
it->second->OnServHelp(source);
source.Reply(_("Type \002%s%s HELP SASET \037option\037\002 for more information on a\n"
- "particular option."), Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str());
+ "particular option."), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
return true;
}
else
@@ -131,7 +132,10 @@ class CSSASet : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(ChanServ, &commandcssaset);
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ this->AddCommand(chanserv->Bot(), &commandcssaset);
}
};
diff --git a/modules/core/cs_saset_noexpire.cpp b/modules/core/cs_saset_noexpire.cpp
index 8ff884d92..1026d8976 100644
--- a/modules/core/cs_saset_noexpire.cpp
+++ b/modules/core/cs_saset_noexpire.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class CommandCSSASetNoexpire : public Command
{
@@ -68,14 +69,17 @@ class CSSetNoexpire : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- Command *c = FindCommand(ChanServ, "SASET");
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ Command *c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetnoexpire);
}
~CSSetNoexpire()
{
- Command *c = FindCommand(ChanServ, "SASET");
+ Command *c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandcssasetnoexpire);
}
diff --git a/modules/core/cs_set.cpp b/modules/core/cs_set.cpp
index 92ae43cfe..d395fad32 100644
--- a/modules/core/cs_set.cpp
+++ b/modules/core/cs_set.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class CommandCSSet : public Command
{
@@ -59,7 +60,7 @@ class CommandCSSet : public Command
Anope::string cmdparams = ci->name;
for (std::vector<Anope::string>::const_iterator it = params.begin() + 2, it_end = params.end(); it != it_end; ++it)
cmdparams += " " + *it;
- mod_run_cmd(ChanServ, u, NULL, c, params[1], cmdparams);
+ mod_run_cmd(chanserv->Bot(), u, NULL, c, params[1], cmdparams);
}
else
{
@@ -83,7 +84,7 @@ class CommandCSSet : public Command
for (subcommand_map::iterator it = this->subcommands.begin(), it_end = this->subcommands.end(); it != it_end; ++it)
it->second->OnServHelp(source);
source.Reply(_("Type \002%s%s HELP SET \037option\037\002 for more information on a\n"
- "particular option."), Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str());
+ "particular option."), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
return true;
}
else
@@ -135,7 +136,10 @@ class CSSet : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(ChanServ, &commandcsset);
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ this->AddCommand(chanserv->Bot(), &commandcsset);
}
};
diff --git a/modules/core/cs_set_bantype.cpp b/modules/core/cs_set_bantype.cpp
index 1b0c2eb7d..35b8c6c14 100644
--- a/modules/core/cs_set_bantype.cpp
+++ b/modules/core/cs_set_bantype.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class CommandCSSetBanType : public Command
{
@@ -88,22 +89,25 @@ class CSSetBanType : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- Command *c = FindCommand(ChanServ, "SET");
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandcssetbantype);
- c = FindCommand(ChanServ, "SASET");
+ c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetbantype);
}
~CSSetBanType()
{
- Command *c = FindCommand(ChanServ, "SET");
+ Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandcssetbantype);
- c = FindCommand(ChanServ, "SASET");
+ c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandcssasetbantype);
}
diff --git a/modules/core/cs_set_description.cpp b/modules/core/cs_set_description.cpp
index dcd7eb24b..a65f4511b 100644
--- a/modules/core/cs_set_description.cpp
+++ b/modules/core/cs_set_description.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class CommandCSSetDescription : public Command
{
@@ -75,22 +76,25 @@ class CSSetDescription : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- Command *c = FindCommand(ChanServ, "SET");
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandcssetdescription);
- c = FindCommand(ChanServ, "SASET");
+ c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetdescription);
}
~CSSetDescription()
{
- Command *c = FindCommand(ChanServ, "SET");
+ Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandcssetdescription);
- c = FindCommand(ChanServ, "SASET");
+ c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandcssasetdescription);
}
diff --git a/modules/core/cs_set_founder.cpp b/modules/core/cs_set_founder.cpp
index 200d32e95..27d6f86fc 100644
--- a/modules/core/cs_set_founder.cpp
+++ b/modules/core/cs_set_founder.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class CommandCSSetFounder : public Command
{
@@ -111,22 +112,25 @@ class CSSetFounder : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- Command *c = FindCommand(ChanServ, "SET");
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandcssetfounder);
- c = FindCommand(ChanServ, "SASET");
+ c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetfounder);
}
~CSSetFounder()
{
- Command *c = FindCommand(ChanServ, "SET");
+ Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandcssetfounder);
- c = FindCommand(ChanServ, "SASET");
+ c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandcssasetfounder);
}
diff --git a/modules/core/cs_set_keeptopic.cpp b/modules/core/cs_set_keeptopic.cpp
index 049ff1b5f..89491d418 100644
--- a/modules/core/cs_set_keeptopic.cpp
+++ b/modules/core/cs_set_keeptopic.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class CommandCSSetKeepTopic : public Command
{
@@ -51,7 +52,7 @@ class CommandCSSetKeepTopic : public Command
"channel. When \002topic retention\002 is set, the topic for the\n"
"channel will be remembered by %s even after the\n"
"last user leaves the channel, and will be restored the\n"
- "next time the channel is created."), this->name.c_str(), ChanServ->nick.c_str());
+ "next time the channel is created."), this->name.c_str(), Config->s_ChanServ.c_str());
return true;
}
@@ -85,22 +86,25 @@ class CSSetKeepTopic : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- Command *c = FindCommand(ChanServ, "SET");
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandcssetkeeptopic);
- c = FindCommand(ChanServ, "SASET");
+ c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetkeeptopic);
}
~CSSetKeepTopic()
{
- Command *c = FindCommand(ChanServ, "SET");
+ Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandcssetkeeptopic);
- c = FindCommand(ChanServ, "SASET");
+ c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandcssasetkeeptopic);
}
diff --git a/modules/core/cs_set_opnotice.cpp b/modules/core/cs_set_opnotice.cpp
index 6e0a5d49b..0d71b42c4 100644
--- a/modules/core/cs_set_opnotice.cpp
+++ b/modules/core/cs_set_opnotice.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class CommandCSSetOpNotice : public Command
{
@@ -50,7 +51,7 @@ class CommandCSSetOpNotice : public Command
"Enables or disables the \002op-notice\002 option for a channel.\n"
"When \002op-notice\002 is set, %s will send a notice to the\n"
"channel whenever the \002OP\002 or \002DEOP\002 commands are used for a user\n"
- "in the channel."), this->name.c_str(), ChanServ->nick.c_str());
+ "in the channel."), this->name.c_str(), Config->s_ChanServ.c_str());
return true;
}
@@ -84,22 +85,25 @@ class CSSetOpNotice : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- Command *c = FindCommand(ChanServ, "SET");
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandcssetopnotice);
- c = FindCommand(ChanServ, "SASET");
+ c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetopnotice);
}
~CSSetOpNotice()
{
- Command *c = FindCommand(ChanServ, "SET");
+ Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandcssetopnotice);
- c = FindCommand(ChanServ, "SASET");
+ c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandcssasetopnotice);
}
diff --git a/modules/core/cs_set_peace.cpp b/modules/core/cs_set_peace.cpp
index 4b89338ee..51c7bc827 100644
--- a/modules/core/cs_set_peace.cpp
+++ b/modules/core/cs_set_peace.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class CommandCSSetPeace : public Command
{
@@ -50,7 +51,7 @@ class CommandCSSetPeace : public Command
"Enables or disables the \002peace\002 option for a channel.\n"
"When \002peace\002 is set, a user won't be able to kick,\n"
"ban or remove a channel status of a user that has\n"
- "a level superior or equal to his via %s commands."), this->name.c_str(), ChanServ->nick.c_str());
+ "a level superior or equal to his via %s commands."), this->name.c_str(), Config->s_ChanServ.c_str());
return true;
}
@@ -84,22 +85,25 @@ class CSSetPeace : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- Command *c = FindCommand(ChanServ, "SET");
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandcssetpeace);
- c = FindCommand(ChanServ, "SASET");
+ c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetpeace);
}
~CSSetPeace()
{
- Command *c = FindCommand(ChanServ, "SET");
+ Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandcssetpeace);
- c = FindCommand(ChanServ, "SASET");
+ c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandcssasetpeace);
}
diff --git a/modules/core/cs_set_persist.cpp b/modules/core/cs_set_persist.cpp
index 291203ea2..683bd4481 100644
--- a/modules/core/cs_set_persist.cpp
+++ b/modules/core/cs_set_persist.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class CommandCSSetPersist : public Command
{
@@ -51,9 +52,9 @@ class CommandCSSetPersist : public Command
*/
if (!ci->bi && !cm)
{
- ChanServ->Assign(NULL, ci);
- if (!ci->c->FindUser(ChanServ))
- ChanServ->Join(ci->c);
+ chanserv->Bot()->Assign(NULL, ci);
+ if (!ci->c->FindUser(chanserv->Bot()))
+ chanserv->Bot()->Join(ci->c);
}
/* Set the perm mode */
@@ -90,7 +91,7 @@ class CommandCSSetPersist : public Command
*/
if (!cm && Config->s_BotServ.empty() && ci->bi)
/* Unassign bot */
- ChanServ->UnAssign(NULL, ci);
+ chanserv->Bot()->UnAssign(NULL, ci);
}
source.Reply(_("Channel \002%s\002 is no longer persistant."), ci->name.c_str());
@@ -156,22 +157,25 @@ class CSSetPersist : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- Command *c = FindCommand(ChanServ, "SET");
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandcssetpeace);
- c = FindCommand(ChanServ, "SASET");
+ c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetpeace);
}
~CSSetPersist()
{
- Command *c = FindCommand(ChanServ, "SET");
+ Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandcssetpeace);
- c = FindCommand(ChanServ, "SASET");
+ c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandcssasetpeace);
}
diff --git a/modules/core/cs_set_private.cpp b/modules/core/cs_set_private.cpp
index 90618bfac..42f7a2261 100644
--- a/modules/core/cs_set_private.cpp
+++ b/modules/core/cs_set_private.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class CommandCSSetPrivate : public Command
{
@@ -49,7 +50,7 @@ class CommandCSSetPrivate : public Command
" \n"
"Enables or disables the \002private\002 option for a channel.\n"
"When \002private\002 is set, a \002%s%s LIST\002 will not\n"
- "include the channel in any lists."), this->name.c_str(), Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str());
+ "include the channel in any lists."), this->name.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
return true;
}
@@ -83,22 +84,25 @@ class CSSetPrivate : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- Command *c = FindCommand(ChanServ, "SET");
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandcssetprivate);
- c = FindCommand(ChanServ, "SASET");
+ c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetprivate);
}
~CSSetPrivate()
{
- Command *c = FindCommand(ChanServ, "SET");
+ Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandcssetprivate);
- c = FindCommand(ChanServ, "SASET");
+ c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandcssasetprivate);
}
diff --git a/modules/core/cs_set_restricted.cpp b/modules/core/cs_set_restricted.cpp
index cc149449c..93fe0d023 100644
--- a/modules/core/cs_set_restricted.cpp
+++ b/modules/core/cs_set_restricted.cpp
@@ -11,6 +11,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class CommandCSSetRestricted : public Command
{
@@ -86,22 +87,25 @@ class CSSetRestricted : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- Command *c = FindCommand(ChanServ, "SET");
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandcssetrestricted);
- c = FindCommand(ChanServ, "SASET");
+ c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetrestricted);
}
~CSSetRestricted()
{
- Command *c = FindCommand(ChanServ, "SET");
+ Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandcssetrestricted);
- c = FindCommand(ChanServ, "SASET");
+ c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandcssasetrestricted);
}
diff --git a/modules/core/cs_set_secure.cpp b/modules/core/cs_set_secure.cpp
index 25977285c..5fb8d9a7c 100644
--- a/modules/core/cs_set_secure.cpp
+++ b/modules/core/cs_set_secure.cpp
@@ -12,13 +12,14 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class CommandCSSetSecure : public Command
{
public:
CommandCSSetSecure(const Anope::string &cpermission = "") : Command("SECURE", 2, 2, cpermission)
{
- this->SetDesc(Anope::printf(_("Activate %s's security features"), ChanServ->nick.c_str()));
+ this->SetDesc(Anope::printf(_("Activate %s's security features"), Config->s_ChanServ.c_str()));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
@@ -51,7 +52,7 @@ class CommandCSSetSecure : public Command
"channel. When \002SECURE\002 is set, only users who have\n"
"registered their nicknames with %s and IDENTIFY'd\n"
"with their password will be given access to the channel\n"
- "as controlled by the access list."), this->name.c_str(), NickServ->nick.c_str(), NickServ->nick.c_str());
+ "as controlled by the access list."), this->name.c_str(), Config->s_NickServ.c_str(), Config->s_NickServ.c_str());
return true;
}
@@ -85,22 +86,25 @@ class CSSetSecure : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- Command *c = FindCommand(ChanServ, "SET");
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandcssetsecure);
- c = FindCommand(ChanServ, "SASET");
+ c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetsecure);
}
~CSSetSecure()
{
- Command *c = FindCommand(ChanServ, "SET");
+ Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandcssetsecure);
- c = FindCommand(ChanServ, "SASET");
+ c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandcssasetsecure);
}
diff --git a/modules/core/cs_set_securefounder.cpp b/modules/core/cs_set_securefounder.cpp
index 44ac0528d..3daa67924 100644
--- a/modules/core/cs_set_securefounder.cpp
+++ b/modules/core/cs_set_securefounder.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class CommandCSSetSecureFounder : public Command
{
@@ -92,22 +93,25 @@ class CSSetSecureFounder : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- Command *c = FindCommand(ChanServ, "SET");
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandcssetsecurefounder);
- c = FindCommand(ChanServ, "SASET");
+ c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetsecurefounder);
}
~CSSetSecureFounder()
{
- Command *c = FindCommand(ChanServ, "SET");
+ Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandcssetsecurefounder);
- c = FindCommand(ChanServ, "SASET");
+ c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandcssasetsecurefounder);
}
diff --git a/modules/core/cs_set_secureops.cpp b/modules/core/cs_set_secureops.cpp
index 21fefdb61..773ae8ffd 100644
--- a/modules/core/cs_set_secureops.cpp
+++ b/modules/core/cs_set_secureops.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class CommandCSSetSecureOps : public Command
{
@@ -83,22 +84,25 @@ class CSSetSecureOps : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- Command *c = FindCommand(ChanServ, "SET");
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandcssetsecureops);
- c = FindCommand(ChanServ, "SASET");
+ c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetsecureops);
}
~CSSetSecureOps()
{
- Command *c = FindCommand(ChanServ, "SET");
+ Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandcssetsecureops);
- c = FindCommand(ChanServ, "SASET");
+ c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandcssasetsecureops);
}
diff --git a/modules/core/cs_set_signkick.cpp b/modules/core/cs_set_signkick.cpp
index 3ca967af9..50c0d74f9 100644
--- a/modules/core/cs_set_signkick.cpp
+++ b/modules/core/cs_set_signkick.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class CommandCSSetSignKick : public Command
{
@@ -64,7 +65,7 @@ class CommandCSSetSignKick : public Command
"If you use \002LEVEL\002, those who have a level that is superior \n"
"or equal to the SIGNKICK level on the channel won't have their \n"
"kicks signed. See \002%s%s HELP LEVELS\002 for more information."), this->name.c_str(),
- ChanServ->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str());
+ Config->s_ChanServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
return true;
}
@@ -98,22 +99,25 @@ class CSSetSignKick : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- Command *c = FindCommand(ChanServ, "SET");
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandcssetsignkick);
- c = FindCommand(ChanServ, "SASET");
+ c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetsignkick);
}
~CSSetSignKick()
{
- Command *c = FindCommand(ChanServ, "SET");
+ Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandcssetsignkick);
- c = FindCommand(ChanServ, "SASET");
+ c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandcssasetsignkick);
}
diff --git a/modules/core/cs_set_successor.cpp b/modules/core/cs_set_successor.cpp
index b80493432..7c3b156e3 100644
--- a/modules/core/cs_set_successor.cpp
+++ b/modules/core/cs_set_successor.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class CommandCSSetSuccessor : public Command
{
@@ -118,22 +119,25 @@ class CSSetSuccessor : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- Command *c = FindCommand(ChanServ, "SET");
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandcssetsuccessor);
- c = FindCommand(ChanServ, "SASET");
+ c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetsuccessor);
}
~CSSetSuccessor()
{
- Command *c = FindCommand(ChanServ, "SET");
+ Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandcssetsuccessor);
- c = FindCommand(ChanServ, "SASET");
+ c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandcssasetsuccessor);
}
diff --git a/modules/core/cs_set_topiclock.cpp b/modules/core/cs_set_topiclock.cpp
index 434d9961d..add079c52 100644
--- a/modules/core/cs_set_topiclock.cpp
+++ b/modules/core/cs_set_topiclock.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class CommandCSSetTopicLock : public Command
{
@@ -50,7 +51,7 @@ class CommandCSSetTopicLock : public Command
"Enables or disables the \002topic lock\002 option for a channel.\n"
"When \002topic lock\002 is set, %s will not allow the\n"
"channel topic to be changed except via the \002TOPIC\002\n"
- "command."), this->name.c_str(), ChanServ->nick.c_str());
+ "command."), this->name.c_str(), Config->s_ChanServ.c_str());
return true;
}
@@ -84,22 +85,25 @@ class CSSetTopicLock : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- Command *c = FindCommand(ChanServ, "SET");
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandcssettopiclock);
- c = FindCommand(ChanServ, "SASET");
+ c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandcssasettopiclock);
}
~CSSetTopicLock()
{
- Command *c = FindCommand(ChanServ, "SET");
+ Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandcssettopiclock);
- c = FindCommand(ChanServ, "SASET");
+ c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandcssasettopiclock);
}
diff --git a/modules/core/cs_set_xop.cpp b/modules/core/cs_set_xop.cpp
index b4c2657d6..2f423e098 100644
--- a/modules/core/cs_set_xop.cpp
+++ b/modules/core/cs_set_xop.cpp
@@ -11,6 +11,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
#define CHECKLEV(lev) (ci->levels[(lev)] != ACCESS_INVALID && access->level >= ci->levels[(lev)])
@@ -138,22 +139,25 @@ class CSSetXOP : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- Command *c = FindCommand(ChanServ, "SET");
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandcssetxop);
- c = FindCommand(ChanServ, "SASET");
+ c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandcssasetxop);
}
~CSSetXOP()
{
- Command *c = FindCommand(ChanServ, "SET");
+ Command *c = FindCommand(chanserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandcssetxop);
- c = FindCommand(ChanServ, "SASET");
+ c = FindCommand(chanserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandcssasetxop);
}
diff --git a/modules/core/cs_status.cpp b/modules/core/cs_status.cpp
index d45c09ab8..0ff2db90a 100644
--- a/modules/core/cs_status.cpp
+++ b/modules/core/cs_status.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class CommandCSStatus : public Command
{
@@ -66,7 +67,7 @@ class CSStatus : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(ChanServ, &commandcsstatus);
+ this->AddCommand(chanserv->Bot(), &commandcsstatus);
}
};
diff --git a/modules/core/cs_suspend.cpp b/modules/core/cs_suspend.cpp
index 7475f2e3a..37fae7723 100644
--- a/modules/core/cs_suspend.cpp
+++ b/modules/core/cs_suspend.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class CommandCSSuspend : public Command
{
@@ -153,8 +154,8 @@ class CSSuspend : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(ChanServ, &commandcssuspend);
- this->AddCommand(ChanServ, &commandcsunsuspend);
+ this->AddCommand(chanserv->Bot(), &commandcssuspend);
+ this->AddCommand(chanserv->Bot(), &commandcsunsuspend);
}
};
diff --git a/modules/core/cs_topic.cpp b/modules/core/cs_topic.cpp
index c832d0ca4..52fecd7a4 100644
--- a/modules/core/cs_topic.cpp
+++ b/modules/core/cs_topic.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class CommandCSTopic : public Command
{
@@ -58,7 +59,7 @@ class CommandCSTopic : public Command
"for more information.\n"
" \n"
"By default, limited to those with founder access on the\n"
- "channel."), ChanServ->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str());
+ "channel."), Config->s_ChanServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
return true;
}
@@ -78,7 +79,7 @@ class CSTopic : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(ChanServ, &commandcstopic);
+ this->AddCommand(chanserv->Bot(), &commandcstopic);
}
};
diff --git a/modules/core/cs_unban.cpp b/modules/core/cs_unban.cpp
index 35b1244e4..be567db9a 100644
--- a/modules/core/cs_unban.cpp
+++ b/modules/core/cs_unban.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class CommandCSUnban : public Command
{
@@ -66,7 +67,7 @@ class CommandCSUnban : public Command
"user from entering the given channel. \n"
" \n"
"By default, limited to AOPs or those with level 5 and above\n"
- "on the channel."), ChanServ->nick.c_str());
+ "on the channel."), Config->s_ChanServ.c_str());
return true;
}
@@ -86,7 +87,7 @@ class CSUnban : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(ChanServ, &commandcsunban);
+ this->AddCommand(chanserv->Bot(), &commandcsunban);
}
};
diff --git a/modules/core/cs_xop.cpp b/modules/core/cs_xop.cpp
index 22ffb4f68..3b65e035f 100644
--- a/modules/core/cs_xop.cpp
+++ b/modules/core/cs_xop.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
enum
{
@@ -449,8 +450,8 @@ class CommandCSQOP : public XOPBase
"\002%s%s HELP ACCESS\002 for information about the access list,\n"
"and \002%s%s HELP SET XOP\002 to know how to toggle between \n"
"the access list and xOP list systems."),
- Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str(),
- Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str());
+ Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str(),
+ Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
return true;
}
@@ -513,8 +514,8 @@ class CommandCSAOP : public XOPBase
"\002%s%s HELP ACCESS\002 for information about the access list,\n"
"and \002%s%s HELP SET XOP\002 to know how to toggle between \n"
"the access list and xOP list systems."),
- Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str(),
- Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str());
+ Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str(),
+ Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
return true;
}
@@ -575,8 +576,8 @@ class CommandCSHOP : public XOPBase
"\002%s%s HELP ACCESS\002 for information about the access list,\n"
"and \002%s%s HELP SET XOP\002 to know how to toggle between \n"
"the access list and xOP list systems."),
- Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str(),
- Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str());
+ Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str(),
+ Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
return true;
}
@@ -639,8 +640,8 @@ class CommandCSSOP : public XOPBase
"\002%s%s HELP ACCESS\002 for information about the access list,\n"
"and \002%s%s HELP SET XOP\002 to know how to toggle between \n"
"the access list and xOP list systems."),
- Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str(),
- Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str());
+ Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str(),
+ Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
return true;
}
@@ -702,8 +703,8 @@ class CommandCSVOP : public XOPBase
"\002%s%s HELP ACCESS\002 for information about the access list,\n"
"and \002%s%s HELP SET XOP\002 to know how to toggle between \n"
"the access list and xOP list systems."),
- Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str(),
- Config->UseStrictPrivMsgString.c_str(), ChanServ->nick.c_str());
+ Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str(),
+ Config->UseStrictPrivMsgString.c_str(), Config->s_ChanServ.c_str());
return true;
}
@@ -727,9 +728,9 @@ class CSXOP : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(ChanServ, &commandcssop);
- this->AddCommand(ChanServ, &commandcsaop);
- this->AddCommand(ChanServ, &commandcsvop);
+ this->AddCommand(chanserv->Bot(), &commandcssop);
+ this->AddCommand(chanserv->Bot(), &commandcsaop);
+ this->AddCommand(chanserv->Bot(), &commandcsvop);
if (Me && Me->IsSynced())
OnUplinkSync(NULL);
@@ -741,15 +742,15 @@ class CSXOP : public Module
void OnUplinkSync(Server *)
{
if (ModeManager::FindChannelModeByName(CMODE_OWNER))
- this->AddCommand(ChanServ, &commandcsqop);
+ this->AddCommand(chanserv->Bot(), &commandcsqop);
if (ModeManager::FindChannelModeByName(CMODE_HALFOP))
- this->AddCommand(ChanServ, &commandcshop);
+ this->AddCommand(chanserv->Bot(), &commandcshop);
}
void OnServerDisconnect()
{
- this->DelCommand(ChanServ, &commandcsqop);
- this->DelCommand(ChanServ, &commandcshop);
+ this->DelCommand(chanserv->Bot(), &commandcsqop);
+ this->DelCommand(chanserv->Bot(), &commandcshop);
}
};
diff --git a/modules/core/db_plain.cpp b/modules/core/db_plain.cpp
index e4678a8d9..4ab248f76 100644
--- a/modules/core/db_plain.cpp
+++ b/modules/core/db_plain.cpp
@@ -11,9 +11,12 @@
/*************************************************************************/
#include "module.h"
+#include "operserv.h"
+#include "os_session.h"
Anope::string DatabaseFile;
std::stringstream db_buffer;
+service_reference<SessionService> SessionInterface("session");
/** Enum used for what METADATA type we are reading
*/
@@ -317,16 +320,13 @@ static void LoadOperInfo(const std::vector<Anope::string> &params)
XLine *x = NULL;
if (params[0].equals_ci("SNLINE") && SNLine)
- x = SNLine->Add(NULL, NULL, mask, expires, reason);
+ x = SNLine->Add(mask, by, expires, reason);
else if (params[0].equals_ci("SQLINE") && SQLine)
- x = SQLine->Add(NULL, NULL, mask, expires, reason);
+ x = SQLine->Add(mask, by, expires, reason);
else if (params[0].equals_ci("SZLINE") && SZLine)
- x = SZLine->Add(NULL, NULL, mask, expires, reason);
+ x = SZLine->Add(mask, by, expires, reason);
if (x)
- {
- x->By = by;
x->Created = seton;
- }
}
else if (params[0].equals_ci("AKILL") && SGLine)
{
@@ -337,12 +337,9 @@ static void LoadOperInfo(const std::vector<Anope::string> &params)
time_t expires = params[5].is_pos_number_only() ? convertTo<time_t>(params[5]) : 0;
Anope::string reason = params[6];
- XLine *x = SGLine->Add(NULL, NULL, user + "@" + host, expires, reason);
+ XLine *x = SGLine->Add(user + "@" + host, by, expires, reason);
if (x)
- {
- x->By = by;
x->Created = seton;
- }
}
else if (params[0].equals_ci("EXCEPTION"))
{
@@ -353,7 +350,7 @@ static void LoadOperInfo(const std::vector<Anope::string> &params)
exception->time = params[4].is_pos_number_only() ? convertTo<time_t>(params[4]) : 0;
exception->expires = params[5].is_pos_number_only() ? convertTo<time_t>(params[5]) : 0;
exception->reason = params[6];
- exceptions.push_back(exception);
+ SessionInterface->AddException(exception);
}
}
@@ -382,7 +379,7 @@ class DBPlain : public Module
Implementation i[] = { I_OnReload, I_OnDatabaseRead, I_OnLoadDatabase, I_OnDatabaseReadMetadata, I_OnSaveDatabase, I_OnModuleLoad };
ModuleManager::Attach(i, this, 6);
- OnReload(true);
+ OnReload();
LastDay = 0;
}
@@ -412,7 +409,8 @@ class DBPlain : public Module
Log(LOG_DEBUG) << "db_plain: Attemping to rename " << DatabaseFile << " to " << newname;
if (rename(DatabaseFile.c_str(), newname.c_str()))
{
- ircdproto->SendGlobops(OperServ, "Unable to backup database!");
+ if (operserv)
+ ircdproto->SendGlobops(operserv->Bot(), "Unable to backup database!");
Log() << "Unable to back up database!";
if (!Config->NoBackupOkay)
@@ -432,7 +430,7 @@ class DBPlain : public Module
}
}
- void OnReload(bool)
+ void OnReload()
{
ConfigReader config;
DatabaseFile = config.ReadValue("db_plain", "database", "anope.db", 0);
@@ -494,14 +492,12 @@ class DBPlain : public Module
Memo *m = new Memo;
m->time = params[0].is_pos_number_only() ? convertTo<time_t>(params[0]) : 0;
m->sender = params[1];
- for (unsigned j = 2; params[j].equals_ci("UNREAD") || params[j].equals_ci("RECEIPT") || params[j].equals_ci("NOTIFYS"); ++j)
+ for (unsigned j = 2; params[j].equals_ci("UNREAD") || params[j].equals_ci("RECEIPT"); ++j)
{
if (params[j].equals_ci("UNREAD"))
m->SetFlag(MF_UNREAD);
else if (params[j].equals_ci("RECEIPT"))
m->SetFlag(MF_RECEIPT);
- else if (params[j].equals_ci("NOTIFYS"))
- m->SetFlag(MF_NOTIFYS);
}
m->text = params[params.size() - 1];
nc->memos.memos.push_back(m);
@@ -633,14 +629,12 @@ class DBPlain : public Module
Memo *m = new Memo;
m->time = params[0].is_pos_number_only() ? convertTo<time_t>(params[0]) : 0;
m->sender = params[1];
- for (unsigned j = 2; params[j].equals_ci("UNREAD") || params[j].equals_ci("RECEIPT") || params[j].equals_ci("NOTIFYS"); ++j)
+ for (unsigned j = 2; params[j].equals_ci("UNREAD") || params[j].equals_ci("RECEIPT"); ++j)
{
if (params[j].equals_ci("UNREAD"))
m->SetFlag(MF_UNREAD);
else if (params[j].equals_ci("RECEIPT"))
m->SetFlag(MF_RECEIPT);
- else if (params[j].equals_ci("NOTIFYS"))
- m->SetFlag(MF_NOTIFYS);
}
m->text = params[params.size() - 1];
ci->memos.memos.push_back(m);
@@ -754,8 +748,6 @@ class DBPlain : public Module
db_buffer << " UNREAD";
if (mi->memos[k]->HasFlag(MF_RECEIPT))
db_buffer << " RECEIPT";
- if (mi->memos[k]->HasFlag(MF_NOTIFYS))
- db_buffer << " NOTIFYS";
db_buffer << " :" << mi->memos[k]->text << endl;
}
for (unsigned k = 0, end = mi->ignores.size(); k < end; ++k)
@@ -848,8 +840,6 @@ class DBPlain : public Module
db_buffer << " UNREAD";
if (memos->memos[k]->HasFlag(MF_RECEIPT))
db_buffer << " RECEIPT";
- if (memos->memos[k]->HasFlag(MF_NOTIFYS))
- db_buffer << " NOTIFYS";
db_buffer << " :" << memos->memos[k]->text << endl;
}
for (unsigned k = 0, end = memos->ignores.size(); k < end; ++k)
@@ -906,7 +896,7 @@ class DBPlain : public Module
db_buffer << "OS SZLINE " << x->Mask << " " << x->By << " " << x->Created << " " << x->Expires << " :" << x->Reason << endl;
}
- for (std::vector<Exception *>::iterator it = exceptions.begin(), it_end = exceptions.end(); it != it_end; ++it)
+ for (SessionService::ExceptionVector::iterator it = SessionInterface->GetExceptions().begin(); it != SessionInterface->GetExceptions().end(); ++it)
{
Exception *e = *it;
db_buffer << "OS EXCEPTION " << e->mask << " " << e->limit << " " << e->who << " " << e->time << " " << e->expires << " " << e->reason << endl;
diff --git a/modules/core/os_global.cpp b/modules/core/gl_global.cpp
index 08fda8fc7..e03c3f788 100644
--- a/modules/core/os_global.cpp
+++ b/modules/core/gl_global.cpp
@@ -1,4 +1,4 @@
-/* OperServ core functions
+/* Global core functions
*
* (C) 2003-2011 Anope Team
* Contact us at team@anope.org
@@ -12,11 +12,12 @@
/*************************************************************************/
#include "module.h"
+#include "global.h"
-class CommandOSGlobal : public Command
+class CommandGLGlobal : public Command
{
public:
- CommandOSGlobal() : Command("GLOBAL", 1, 1, "operserv/global")
+ CommandGLGlobal() : Command("GLOBAL", 1, 1, "global/global")
{
this->SetDesc(_("Send a message to all users"));
}
@@ -27,7 +28,7 @@ class CommandOSGlobal : public Command
const Anope::string &msg = params[0];
Log(LOG_ADMIN, u, this);
- oper_global(u->nick, "%s", msg.c_str());
+ global->SendGlobal(global->Bot(), u->nick, msg);
return MOD_CONT;
}
@@ -36,7 +37,7 @@ class CommandOSGlobal : public Command
source.Reply(_("Syntax: \002GLOBAL \037message\037\002\n"
" \n"
"Allows Administrators to send messages to all users on the \n"
- "network. The message will be sent from the nick \002%s\002."), Config->s_GlobalNoticer.c_str());
+ "network. The message will be sent from the nick \002%s\002."), Config->s_Global.c_str());
return true;
}
@@ -46,22 +47,21 @@ class CommandOSGlobal : public Command
}
};
-class OSGlobal : public Module
+class GLGlobal : public Module
{
- CommandOSGlobal commandosglobal;
+ CommandGLGlobal commandglglobal;
public:
- OSGlobal(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
+ GLGlobal(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
{
this->SetAuthor("Anope");
this->SetType(CORE);
- if (Config->s_GlobalNoticer.empty())
+ if (Config->s_Global.empty())
throw ModuleException("Global is disabled");
- // Maybe we should put this ON Global?
- this->AddCommand(OperServ, &commandosglobal);
+ this->AddCommand(global->Bot(), &commandglglobal);
}
};
-MODULE_INIT(OSGlobal)
+MODULE_INIT(GLGlobal)
diff --git a/modules/core/gl_help.cpp b/modules/core/gl_help.cpp
new file mode 100644
index 000000000..ea67a8efc
--- /dev/null
+++ b/modules/core/gl_help.cpp
@@ -0,0 +1,58 @@
+/* Global 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 "global.h"
+
+class CommandGLHelp : public Command
+{
+ public:
+ CommandGLHelp() : Command("HELP", 1, 1)
+ {
+ this->SetDesc(_("Displays this list and give information about commands"));
+ }
+
+ CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
+ {
+ mod_help_cmd(global->Bot(), source.u, NULL, params[0]);
+ return MOD_CONT;
+ }
+
+ void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
+ {
+ User *u = source.u;
+ source.Reply(_("%s commands:"), Config->s_Global.c_str());
+ for (CommandMap::const_iterator it = global->Bot()->Commands.begin(), it_end = global->Bot()->Commands.end(); it != it_end; ++it)
+ if (!Config->HidePrivilegedCommands || it->second->permission.empty() || u->HasCommand(it->second->permission))
+ it->second->OnServHelp(source);
+ }
+};
+
+class GLHelp : public Module
+{
+ CommandGLHelp commandoshelp;
+
+ public:
+ GLHelp(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetType(CORE);
+
+ if (!global)
+ throw ModuleException("Global is not loaded!");
+
+ this->AddCommand(global->Bot(), &commandoshelp);
+ }
+};
+
+MODULE_INIT(GLHelp)
diff --git a/modules/core/gl_main.cpp b/modules/core/gl_main.cpp
new file mode 100644
index 000000000..84eea0e20
--- /dev/null
+++ b/modules/core/gl_main.cpp
@@ -0,0 +1,111 @@
+/* Global 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 "global.h"
+
+static BotInfo *Global = NULL;
+
+class MyGlobalService : public GlobalService
+{
+ void ServerGlobal(Server *s, const Anope::string &message)
+ {
+ if (s != Me && !s->HasFlag(SERVER_JUPED))
+ notice_server(Config->s_Global, s, "%s", message.c_str());
+ for (unsigned i = 0, j = s->GetLinks().size(); i < j; ++i)
+ this->ServerGlobal(s->GetLinks()[i], message);
+ }
+
+ public:
+ MyGlobalService(Module *m) : GlobalService(m) { }
+
+ BotInfo *Bot()
+ {
+ return Global;
+ }
+
+ void SendGlobal(BotInfo *sender, const Anope::string &source, const Anope::string &message)
+ {
+ if (Me->GetLinks().empty())
+ return;
+
+ Anope::string rmessage;
+
+ if (!source.empty() && !Config->AnonymousGlobal)
+ rmessage = "[" + source + "] " + message;
+ else
+ rmessage = message;
+
+ this->ServerGlobal(Me->GetLinks().front(), rmessage);
+ }
+};
+
+class GlobalCore : public Module
+{
+ MyGlobalService myglobal;
+
+ public:
+ GlobalCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator), myglobal(this)
+ {
+ this->SetAuthor("Anope");
+ this->SetType(CORE);
+
+ Implementation i[] = { I_OnPreRestart, I_OnPreShutdown, I_OnNewServer };
+ ModuleManager::Attach(i, this, 3);
+
+ ModuleManager::RegisterService(&this->myglobal);
+
+ Global = new BotInfo(Config->s_Global, Config->ServiceUser, Config->ServiceHost, Config->desc_Global);
+ Global->SetFlag(BI_CORE);
+
+ spacesepstream coreModules(Config->GlobalCoreModules);
+ Anope::string module;
+ while (coreModules.GetToken(module))
+ ModuleManager::LoadModule(module, NULL);
+ }
+
+ ~GlobalCore()
+ {
+ spacesepstream coreModules(Config->GlobalCoreModules);
+ Anope::string module;
+ while (coreModules.GetToken(module))
+ {
+ Module *m = FindModule(module);
+ if (m != NULL)
+ ModuleManager::UnloadModule(m, NULL);
+ }
+
+ delete Global;
+ }
+
+ void OnPreRestart()
+ {
+ if (Config->GlobalOnCycle)
+ global->SendGlobal(global->Bot(), "", Config->GlobalOnCycleMessage);
+ }
+
+ void OnPreShutdown()
+ {
+ if (Config->GlobalOnCycle)
+ global->SendGlobal(global->Bot(), "", Config->GlobalOnCycleMessage);
+ }
+
+ void OnNewServer(Server *s)
+ {
+ if (Config->GlobalOnCycle && !Config->GlobalOnCycleUP.empty())
+ notice_server(Config->s_Global, s, "%s", Config->GlobalOnCycleUP.c_str());
+ }
+};
+
+MODULE_INIT(GlobalCore)
+
diff --git a/modules/core/global.h b/modules/core/global.h
new file mode 100644
index 000000000..977a327e4
--- /dev/null
+++ b/modules/core/global.h
@@ -0,0 +1,22 @@
+#ifndef GLOBAL_H
+#define GLOBAL_H
+
+class GlobalService : public Service
+{
+ public:
+ GlobalService(Module *m) : Service(m, "Global") { }
+
+ virtual BotInfo *Bot() = 0;
+
+ /** Send out a global message to all users
+ * @param sender Our client which should send the global
+ * @param source The sender of the global
+ * @param message The message
+ */
+ virtual void SendGlobal(BotInfo *sender, const Anope::string &source, const Anope::string &message) = 0;
+};
+
+static service_reference<GlobalService> global("Global");
+
+#endif // GLOBAL_H
+
diff --git a/modules/core/hostserv.h b/modules/core/hostserv.h
new file mode 100644
index 000000000..6f491a30e
--- /dev/null
+++ b/modules/core/hostserv.h
@@ -0,0 +1,17 @@
+#ifndef HOSTSERV_H
+#define HOSTSERV_H
+
+class HostServService : public Service
+{
+ public:
+ HostServService(Module *m) : Service(m, "HostServ") { }
+
+ virtual BotInfo *Bot() = 0;
+
+ virtual void Sync(NickAlias *na) = 0;
+};
+
+static service_reference<HostServService> hostserv("HostServ");
+
+#endif // HOSTSERV_H
+
diff --git a/modules/core/hs_del.cpp b/modules/core/hs_del.cpp
index 6e5458538..bdd1bc525 100644
--- a/modules/core/hs_del.cpp
+++ b/modules/core/hs_del.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "hostserv.h"
class CommandHSDel : public Command
{
@@ -68,7 +69,10 @@ class HSDel : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(HostServ, &commandhsdel);
+ if (!hostserv)
+ throw ModuleException("HostServ is not loaded!");
+
+ this->AddCommand(hostserv->Bot(), &commandhsdel);
}
};
diff --git a/modules/core/hs_delall.cpp b/modules/core/hs_delall.cpp
index 5b32ea191..905fe4ec3 100644
--- a/modules/core/hs_delall.cpp
+++ b/modules/core/hs_delall.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "hostserv.h"
class CommandHSDelAll : public Command
{
@@ -73,7 +74,10 @@ class HSDelAll : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(HostServ, &commandhsdelall);
+ if (!hostserv)
+ throw ModuleException("HostServ is not loaded!");
+
+ this->AddCommand(hostserv->Bot(), &commandhsdelall);
}
};
diff --git a/modules/core/hs_group.cpp b/modules/core/hs_group.cpp
index 3bb42ee94..9525b4646 100644
--- a/modules/core/hs_group.cpp
+++ b/modules/core/hs_group.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "hostserv.h"
class CommandHSGroup : public Command
{
@@ -27,7 +28,7 @@ class CommandHSGroup : public Command
NickAlias *na = findnick(u->nick);
if (na && u->Account() == na->nc && na->hostinfo.HasVhost())
{
- HostServSyncVhosts(na);
+ hostserv->Sync(na);
if (!na->hostinfo.GetIdent().empty())
source.Reply(_("All vhost's in the group \002%s\002 have been set to \002%s\002@\002%s\002"), u->Account()->display.c_str(), na->hostinfo.GetIdent().c_str(), na->hostinfo.GetHost().c_str());
else
@@ -60,7 +61,10 @@ class HSGroup : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(HostServ, &commandhsgroup);
+ if (!hostserv)
+ throw ModuleException("HostServ is not loaded!");
+
+ this->AddCommand(hostserv->Bot(), &commandhsgroup);
}
};
diff --git a/modules/core/hs_help.cpp b/modules/core/hs_help.cpp
index bcf8fd28d..53b40ef89 100644
--- a/modules/core/hs_help.cpp
+++ b/modules/core/hs_help.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "hostserv.h"
class CommandHSHelp : public Command
{
@@ -24,7 +25,7 @@ class CommandHSHelp : public Command
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
- mod_help_cmd(HostServ, source.u, NULL, params[0]);
+ mod_help_cmd(hostserv->Bot(), source.u, NULL, params[0]);
return MOD_CONT;
}
@@ -32,7 +33,7 @@ class CommandHSHelp : public Command
{
User *u = source.u;
source.Reply(_("%s commands:"), Config->s_HostServ.c_str());
- for (CommandMap::const_iterator it = HostServ->Commands.begin(), it_end = HostServ->Commands.end(); it != it_end; ++it)
+ for (CommandMap::const_iterator it = hostserv->Bot()->Commands.begin(), it_end = hostserv->Bot()->Commands.end(); it != it_end; ++it)
if (!Config->HidePrivilegedCommands || it->second->permission.empty() || u->HasCommand(it->second->permission))
it->second->OnServHelp(source);
}
@@ -48,7 +49,10 @@ class HSHelp : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(HostServ, &commandhshelp);
+ if (!hostserv)
+ throw ModuleException("HostServ is not loaded!");
+
+ this->AddCommand(hostserv->Bot(), &commandhshelp);
}
};
diff --git a/modules/core/hs_list.cpp b/modules/core/hs_list.cpp
index 61fee9fcc..a85c2e8b2 100644
--- a/modules/core/hs_list.cpp
+++ b/modules/core/hs_list.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "hostserv.h"
class CommandHSList : public Command
{
@@ -128,7 +129,10 @@ class HSList : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(HostServ, &commandhslist);
+ if (!hostserv)
+ throw ModuleException("HostServ is not loaded!");
+
+ this->AddCommand(hostserv->Bot(), &commandhslist);
}
};
diff --git a/modules/core/hs_main.cpp b/modules/core/hs_main.cpp
new file mode 100644
index 000000000..c4b1433c8
--- /dev/null
+++ b/modules/core/hs_main.cpp
@@ -0,0 +1,123 @@
+/* HostServ 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 "hostserv.h"
+
+static BotInfo *HostServ = NULL;
+
+class MyHostServService : public HostServService
+{
+ public:
+ MyHostServService(Module *m) : HostServService(m) { }
+
+ BotInfo *Bot()
+ {
+ return HostServ;
+ }
+
+ void Sync(NickAlias *na)
+ {
+ if (!na || !na->hostinfo.HasVhost())
+ return;
+
+ for (std::list<NickAlias *>::iterator it = na->nc->aliases.begin(), it_end = na->nc->aliases.end(); it != it_end; ++it)
+ {
+ NickAlias *nick = *it;
+ nick->hostinfo.SetVhost(na->hostinfo.GetIdent(), na->hostinfo.GetHost(), na->hostinfo.GetCreator());
+ }
+ }
+};
+
+class HostServCore : public Module
+{
+ MyHostServService myhostserv;
+
+ public:
+ HostServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator), myhostserv(this)
+ {
+ this->SetAuthor("Anope");
+ this->SetType(CORE);
+
+ if (!ircd->vhost)
+ throw ModuleException("Your IRCd does not suppor vhosts");
+
+ ModuleManager::RegisterService(&this->myhostserv);
+
+ HostServ = new BotInfo(Config->s_HostServ, Config->ServiceUser, Config->ServiceHost, Config->desc_HostServ);
+ HostServ->SetFlag(BI_CORE);
+
+ Implementation i[] = { I_OnNickIdentify, I_OnNickUpdate };
+ ModuleManager::Attach(i, this, 2);
+
+ spacesepstream coreModules(Config->HostCoreModules);
+ Anope::string module;
+ while (coreModules.GetToken(module))
+ ModuleManager::LoadModule(module, NULL);
+ }
+
+ ~HostServCore()
+ {
+ spacesepstream coreModules(Config->HostCoreModules);
+ Anope::string module;
+ while (coreModules.GetToken(module))
+ {
+ Module *m = FindModule(module);
+ if (m != NULL)
+ ModuleManager::UnloadModule(m, NULL);
+ }
+
+ delete HostServ;
+ }
+
+ void OnNickIdentify(User *u)
+ {
+ HostInfo *ho = NULL;
+ NickAlias *na = findnick(u->nick);
+ if (na && na->hostinfo.HasVhost())
+ ho = &na->hostinfo;
+ else
+ {
+ na = findnick(u->Account()->display);
+ if (na && na->hostinfo.HasVhost())
+ ho = &na->hostinfo;
+ }
+ if (ho == NULL)
+ return;
+
+ if (u->vhost.empty() || !u->vhost.equals_cs(na->hostinfo.GetHost()) || (!na->hostinfo.GetIdent().empty() && !u->GetVIdent().equals_cs(na->hostinfo.GetIdent())))
+ {
+ ircdproto->SendVhost(u, na->hostinfo.GetIdent(), na->hostinfo.GetHost());
+ if (ircd->vhost)
+ {
+ u->vhost = na->hostinfo.GetHost();
+ u->UpdateHost();
+ }
+ if (ircd->vident && !na->hostinfo.GetIdent().empty())
+ u->SetVIdent(na->hostinfo.GetIdent());
+
+ if (!na->hostinfo.GetIdent().empty())
+ u->SendMessage(HostServ, _("Your vhost of \002%s\002@\002%s\002 is now activated."), na->hostinfo.GetIdent().c_str(), na->hostinfo.GetHost().c_str());
+ else
+ u->SendMessage(HostServ, _("Your vhost of \002%s\002 is now activated."), na->hostinfo.GetHost().c_str());
+ }
+ }
+
+ void OnNickUpdate(User *u)
+ {
+ this->OnNickIdentify(u);
+ }
+};
+
+MODULE_INIT(HostServCore)
+
diff --git a/modules/core/hs_off.cpp b/modules/core/hs_off.cpp
index dfbeaa2f8..d06d125fa 100644
--- a/modules/core/hs_off.cpp
+++ b/modules/core/hs_off.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "hostserv.h"
class CommandHSOff : public Command
{
@@ -58,7 +59,10 @@ class HSOff : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(HostServ, &commandhsoff);
+ if (!hostserv)
+ throw ModuleException("HostServ is not loaded!");
+
+ this->AddCommand(hostserv->Bot(), &commandhsoff);
}
};
diff --git a/modules/core/hs_on.cpp b/modules/core/hs_on.cpp
index 8838d6b62..43fd06b04 100644
--- a/modules/core/hs_on.cpp
+++ b/modules/core/hs_on.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "hostserv.h"
class CommandHSOn : public Command
{
@@ -68,7 +69,10 @@ class HSOn : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(HostServ, &commandhson);
+ if (!hostserv)
+ throw ModuleException("HostServ is not loaded!");
+
+ this->AddCommand(hostserv->Bot(), &commandhson);
}
};
diff --git a/modules/core/hs_set.cpp b/modules/core/hs_set.cpp
index 9f79fedd7..9521bc57e 100644
--- a/modules/core/hs_set.cpp
+++ b/modules/core/hs_set.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "hostserv.h"
class CommandHSSet : public Command
{
@@ -122,7 +123,10 @@ class HSSet : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(HostServ, &commandhsset);
+ if (!hostserv)
+ throw ModuleException("HostServ is not loaded!");
+
+ this->AddCommand(hostserv->Bot(), &commandhsset);
}
};
diff --git a/modules/core/hs_setall.cpp b/modules/core/hs_setall.cpp
index 18f24d359..52061203f 100644
--- a/modules/core/hs_setall.cpp
+++ b/modules/core/hs_setall.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "hostserv.h"
class CommandHSSetAll : public Command
{
@@ -92,7 +93,7 @@ class CommandHSSetAll : public Command
Log(LOG_ADMIN, u, this) << "to set the vhost for all nicks in group " << na->nc->display << " to " << (!vIdent.empty() ? vIdent + "@" : "") << hostmask;
na->hostinfo.SetVhost(vIdent, hostmask, u->nick);
- HostServSyncVhosts(na);
+ hostserv->Sync(na);
FOREACH_MOD(I_OnSetVhost, OnSetVhost(na));
if (!vIdent.empty())
source.Reply(_("vhost for group \002%s\002 set to \002%s\002@\002%s\002."), nick.c_str(), vIdent.c_str(), hostmask.c_str());
@@ -129,7 +130,10 @@ class HSSetAll : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(HostServ, &commandhssetall);
+ if (!hostserv)
+ throw ModuleException("HostServ is not loaded!");
+
+ this->AddCommand(hostserv->Bot(), &commandhssetall);
}
};
diff --git a/modules/core/memoserv.h b/modules/core/memoserv.h
new file mode 100644
index 000000000..3252a2a2b
--- /dev/null
+++ b/modules/core/memoserv.h
@@ -0,0 +1,44 @@
+#ifndef MEMOSERV_H
+#define MEMOSERV_H
+
+class MemoServService : public Service
+{
+ public:
+ enum MemoResult
+ {
+ MEMO_SUCCESS,
+ MEMO_INVALID_TARGET,
+ MEMO_TOO_FAST,
+ MEMO_TARGET_FULL
+ };
+
+ MemoServService(Module *m) : Service(m, "MemoServ") { }
+
+ virtual BotInfo *Bot() = 0;
+
+ /** Retrieve the memo info for a nick or channel
+ * @param target Target
+ * @param ischan Set to true if target is a channel
+ * @param isforbid Set to true if the target is forbidden
+ * @return A memoinfo structure or NULL
+ */
+ virtual MemoInfo *GetMemoInfo(const Anope::string &target, bool &ischan, bool &isforbid) = 0;
+
+ /** Sends a memo.
+ * @param source The source of the memo, can be anythin.
+ * @param target The target of the memo, nick or channel.
+ * @param message Memo text
+ * @param force true to force the memo, restrictions/delays etc are not checked
+ */
+ virtual MemoResult Send(const Anope::string &source, const Anope::string &target, const Anope::string &message, bool force = false) = 0;
+
+ /** Check for new memos and notify the user if there are any
+ * @param u The user
+ */
+ virtual void Check(User *u) = 0;
+};
+
+static service_reference<MemoServService> memoserv("MemoServ");
+
+#endif // MEMOSERV_H
+
diff --git a/modules/core/ms_cancel.cpp b/modules/core/ms_cancel.cpp
index d5bedc8fb..1cfd20767 100644
--- a/modules/core/ms_cancel.cpp
+++ b/modules/core/ms_cancel.cpp
@@ -12,8 +12,7 @@
/*************************************************************************/
#include "module.h"
-
-void myMemoServHelp(User *u);
+#include "memoserv.h"
class CommandMSCancel : public Command
{
@@ -30,9 +29,9 @@ class CommandMSCancel : public Command
const Anope::string &nname = params[0];
bool ischan, isforbid;
- MemoInfo *mi;
+ MemoInfo *mi = memoserv->GetMemoInfo(nname, ischan, isforbid);
- if (!(mi = getmemoinfo(nname, ischan, isforbid)))
+ if (mi == NULL)
{
if (isforbid)
source.Reply(ischan ? _(CHAN_X_FORBIDDEN) : _(NICK_X_FORBIDDEN), nname.c_str());
@@ -42,7 +41,7 @@ class CommandMSCancel : public Command
else
{
for (int i = mi->memos.size() - 1; i >= 0; --i)
- if (mi->memos[i]->HasFlag(MF_UNREAD) && u->Account()->display.equals_ci(mi->memos[i]->sender) && !mi->memos[i]->HasFlag(MF_NOTIFYS))
+ if (mi->memos[i]->HasFlag(MF_UNREAD) && u->Account()->display.equals_ci(mi->memos[i]->sender))
{
FOREACH_MOD(I_OnMemoDel, OnMemoDel(findnick(nname)->nc, mi, mi->memos[i]));
mi->Del(mi->memos[i]);
@@ -80,7 +79,10 @@ class MSCancel : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(MemoServ, &commandmscancel);
+ if (!memoserv)
+ throw ModuleException("MemoServ is not loaded!");
+
+ this->AddCommand(memoserv->Bot(), &commandmscancel);
}
};
diff --git a/modules/core/ms_check.cpp b/modules/core/ms_check.cpp
index 8134b98a7..34adcf2c4 100644
--- a/modules/core/ms_check.cpp
+++ b/modules/core/ms_check.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "memoserv.h"
class CommandMSCheck : public Command
{
@@ -92,7 +93,10 @@ class MSCheck : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(MemoServ, &commandmscheck);
+ if (!memoserv)
+ throw ModuleException("MemoServ is not loaded!");
+
+ this->AddCommand(memoserv->Bot(), &commandmscheck);
}
};
diff --git a/modules/core/ms_del.cpp b/modules/core/ms_del.cpp
index 1f0a038ee..077b5bdba 100644
--- a/modules/core/ms_del.cpp
+++ b/modules/core/ms_del.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "memoserv.h"
class MemoDelCallback : public NumberList
{
@@ -160,7 +161,10 @@ class MSDel : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(MemoServ, &commandmsdel);
+ if (!memoserv)
+ throw ModuleException("MemoServ is not loaded!");
+
+ this->AddCommand(memoserv->Bot(), &commandmsdel);
}
};
diff --git a/modules/core/ms_help.cpp b/modules/core/ms_help.cpp
index b672e06bf..dcd5f4e03 100644
--- a/modules/core/ms_help.cpp
+++ b/modules/core/ms_help.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "memoserv.h"
class CommandMSHelp : public Command
{
@@ -24,7 +25,7 @@ class CommandMSHelp : public Command
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
- mod_help_cmd(MemoServ, source.u, NULL, params[0]);
+ mod_help_cmd(memoserv->Bot(), source.u, NULL, params[0]);
return MOD_CONT;
}
@@ -36,15 +37,15 @@ class CommandMSHelp : public Command
"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:"), MemoServ->nick.c_str(), MemoServ->nick.c_str());
- for (CommandMap::const_iterator it = MemoServ->Commands.begin(), it_end = MemoServ->Commands.end(); it != it_end; ++it)
+ "%s's commands include:"), Config->s_MemoServ.c_str(), Config->s_MemoServ.c_str());
+ for (CommandMap::const_iterator it = memoserv->Bot()->Commands.begin(), it_end = memoserv->Bot()->Commands.end(); it != it_end; ++it)
if (!Config->HidePrivilegedCommands || it->second->permission.empty() || u->HasCommand(it->second->permission))
it->second->OnServHelp(source);
source.Reply(_("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(), MemoServ->nick.c_str(), Config->s_ChanServ.c_str());
+ " changed with the %s \002LEVELS\002 command."), Config->UseStrictPrivMsgString.c_str(), Config->s_MemoServ.c_str(), Config->s_ChanServ.c_str());
}
};
@@ -58,7 +59,10 @@ class MSHelp : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(MemoServ, &commandmshelp);
+ if (!memoserv)
+ throw ModuleException("MemoServ is not loaded!");
+
+ this->AddCommand(memoserv->Bot(), &commandmshelp);
}
};
diff --git a/modules/core/ms_ignore.cpp b/modules/core/ms_ignore.cpp
index fd1d09ebf..6747798d2 100644
--- a/modules/core/ms_ignore.cpp
+++ b/modules/core/ms_ignore.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "memoserv.h"
class CommandMSIgnore : public Command
{
@@ -37,7 +38,7 @@ class CommandMSIgnore : public Command
}
bool ischan, isforbid;
- MemoInfo *mi = getmemoinfo(channel, ischan, isforbid);
+ MemoInfo *mi = memoserv->GetMemoInfo(channel, ischan, isforbid);
if (!mi)
{
if (isforbid)
@@ -111,7 +112,10 @@ class MSIgnore : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(MemoServ, &commandmsignore);
+ if (!memoserv)
+ throw ModuleException("MemoServ is not loaded!");
+
+ this->AddCommand(memoserv->Bot(), &commandmsignore);
}
};
diff --git a/modules/core/ms_info.cpp b/modules/core/ms_info.cpp
index f87b8af60..1e12f97e9 100644
--- a/modules/core/ms_info.cpp
+++ b/modules/core/ms_info.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "memoserv.h"
class CommandMSInfo : public Command
{
@@ -224,7 +225,10 @@ class MSInfo : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(MemoServ, &commandmsinfo);
+ if (!memoserv)
+ throw ModuleException("MemoServ is not loaded!");
+
+ this->AddCommand(memoserv->Bot(), &commandmsinfo);
}
};
diff --git a/modules/core/ms_list.cpp b/modules/core/ms_list.cpp
index 1b393688b..e09fcecc2 100644
--- a/modules/core/ms_list.cpp
+++ b/modules/core/ms_list.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "memoserv.h"
class MemoListCallback : public NumberList
{
@@ -172,7 +173,10 @@ class MSList : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(MemoServ, &commandmslist);
+ if (!memoserv)
+ throw ModuleException("MemoServ is not loaded!");
+
+ this->AddCommand(memoserv->Bot(), &commandmslist);
}
};
diff --git a/modules/core/ms_main.cpp b/modules/core/ms_main.cpp
new file mode 100644
index 000000000..40cc6d6d5
--- /dev/null
+++ b/modules/core/ms_main.cpp
@@ -0,0 +1,250 @@
+/* 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 = NULL;
+static bool SendMemoMail(NickCore *nc, MemoInfo *mi, Memo *m)
+{
+ Anope::string message = Anope::printf(GetString(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").c_str(), nc->display.c_str(), m->sender.c_str(), mi->GetIndex(m), m->text.c_str());
+
+ return Mail(nc, GetString(nc, _("New memo")), message);
+}
+
+class MyMemoServService : public MemoServService
+{
+ public:
+ MyMemoServService(Module *m) : MemoServService(m) { }
+
+ BotInfo *Bot()
+ {
+ return MemoServ;
+ }
+
+ MemoInfo *GetMemoInfo(const Anope::string &target, bool &ischan, bool &isforbid)
+ {
+ isforbid = false;
+
+ if (!target.empty() && target[0] == '#')
+ {
+ ischan = true;
+ ChannelInfo *ci = cs_findchan(target);
+ if (ci != NULL)
+ {
+ isforbid = ci->HasFlag(CI_FORBIDDEN);
+ return &ci->memos;
+ }
+ }
+ else
+ {
+ ischan = false;
+ NickAlias *na = findnick(target);
+ if (na != NULL)
+ {
+ isforbid = na->HasFlag(NS_FORBIDDEN);
+ return &na->nc->memos;
+ }
+ }
+
+ return NULL;
+ }
+
+ MemoResult Send(const Anope::string &source, const Anope::string &target, const Anope::string &message, bool force)
+ {
+ bool ischan, isforbid;
+ MemoInfo *mi = this->GetMemoInfo(target, ischan, isforbid);
+
+ if (mi == NULL || isforbid == true)
+ 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 (check_access(cu->user, ci, 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->s_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->s_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 (newcnt == 1 && (nc->memos.memos[i - 1]->HasFlag(MF_UNREAD)))
+ u->SendMessage(MemoServ, _("Type \002%s%s READ LAST\002 to read it."), Config->UseStrictPrivMsgString.c_str(), Config->s_MemoServ.c_str());
+ else if (newcnt == 1)
+ {
+ for (i = 0; i < end; ++i)
+ {
+ if (nc->memos.memos[i]->HasFlag(MF_UNREAD))
+ break;
+ }
+ u->SendMessage(MemoServ, _("Type \002%s%s READ %d\002 to read it."), Config->UseStrictPrivMsgString.c_str(), Config->s_MemoServ.c_str(), i);
+ }
+ else
+ u->SendMessage(MemoServ, _("Type \002%s%s LIST NEW\002 to list them."), Config->UseStrictPrivMsgString.c_str(), Config->s_MemoServ.c_str());
+ }
+ 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), mymemoserv(this)
+ {
+ this->SetAuthor("Anope");
+ this->SetType(CORE);
+
+ Implementation i[] = { I_OnNickIdentify, I_OnJoinChannel, I_OnUserAway, I_OnNickUpdate };
+ ModuleManager::Attach(i, this, 4);
+
+ ModuleManager::RegisterService(&this->mymemoserv);
+
+ MemoServ = new BotInfo(Config->s_MemoServ, Config->ServiceUser, Config->ServiceHost, Config->desc_MemoServ);
+ MemoServ->SetFlag(BI_CORE);
+
+ spacesepstream coreModules(Config->MemoCoreModules);
+ Anope::string module;
+ while (coreModules.GetToken(module))
+ ModuleManager::LoadModule(module, NULL);
+ }
+
+ ~MemoServCore()
+ {
+ spacesepstream coreModules(Config->MemoCoreModules);
+ Anope::string module;
+ while (coreModules.GetToken(module))
+ {
+ Module *m = FindModule(module);
+ if (m != NULL)
+ ModuleManager::UnloadModule(m, NULL);
+ }
+
+ delete MemoServ;
+ }
+
+ void OnNickIdentify(User *u)
+ {
+ this->mymemoserv.Check(u);
+ }
+
+ void OnJoinChannel(User *u, Channel *c)
+ {
+ if (c->ci && check_access(u, c->ci, 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);
+ }
+};
+
+MODULE_INIT(MemoServCore)
+
diff --git a/modules/core/ms_read.cpp b/modules/core/ms_read.cpp
index 632bfd056..4b6e03aed 100644
--- a/modules/core/ms_read.cpp
+++ b/modules/core/ms_read.cpp
@@ -12,6 +12,41 @@
/*************************************************************************/
#include "module.h"
+#include "memoserv.h"
+
+void rsend_notify(CommandSource &source, MemoInfo *mi, Memo *m, const Anope::string &targ)
+{
+ /* Only send receipt if memos are allowed */
+ if (memoserv && !readonly)
+ {
+ /* Get nick alias for sender */
+ NickAlias *na = findnick(m->sender);
+
+ if (!na)
+ return;
+
+ /* Get nick core for sender */
+ NickCore *nc = na->nc;
+
+ if (!nc)
+ return;
+
+ /* Text of the memo varies if the recepient was a
+ nick or channel */
+ Anope::string text = Anope::printf(GetString(na->nc, _("\002[auto-memo]\002 The memo you sent to %s has been viewed.")).c_str(), targ.c_str());
+
+ /* Send notification */
+ memoserv->Send(source.u->nick, m->sender, text, true);
+
+ /* Notify recepient of the memo that a notification has
+ been sent to the sender */
+ source.Reply(_("A notification memo has been sent to %s informing him/her you have\n"
+ "read his/her memo."), nc->display.c_str());
+ }
+
+ /* Remove receipt flag from the original memo */
+ m->UnsetFlag(MF_RECEIPT);
+}
class MemoListCallback : public NumberList
{
@@ -42,7 +77,7 @@ class MemoListCallback : public NumberList
/* Check if a receipt notification was requested */
if (m->HasFlag(MF_RECEIPT))
- rsend_notify(source, m, ci ? ci->name : "");
+ rsend_notify(source, mi, m, ci ? ci->name : source.u->nick);
}
};
@@ -157,7 +192,10 @@ class MSRead : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(MemoServ, &commandmsread);
+ if (!memoserv)
+ throw ModuleException("MemoServ is not loaded!");
+
+ this->AddCommand(memoserv->Bot(), &commandmsread);
}
};
diff --git a/modules/core/ms_rsend.cpp b/modules/core/ms_rsend.cpp
index 7e6af4950..46183ec77 100644
--- a/modules/core/ms_rsend.cpp
+++ b/modules/core/ms_rsend.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "memoserv.h"
class CommandMSRSend : public Command
{
@@ -36,22 +37,34 @@ class CommandMSRSend : public Command
return MOD_CONT;
}
- if (Config->MSMemoReceipt == 1)
+ if (Config->MSMemoReceipt == 1 && !u->IsServicesOper())
+ source.Reply(_(ACCESS_DENIED));
+ else if (Config->MSMemoReceipt > 2 || Config->MSMemoReceipt == 0)
{
- /* Services opers and above can use rsend */
- if (u->IsServicesOper())
- memo_send(source, nick, text, 3);
- else
- source.Reply(_(ACCESS_DENIED));
+ Log() << "MSMemoReceipt is set misconfigured to " << Config->MSMemoReceipt;
+ source.Reply(_("Sorry, RSEND has been disabled on this network."));
}
- else if (Config->MSMemoReceipt == 2)
- /* Everybody can use rsend */
- memo_send(source, nick, text, 3);
else
{
- /* rsend has been disabled */
- Log() << "MSMemoReceipt is set misconfigured to " << Config->MSMemoReceipt;
- source.Reply(_("Sorry, RSEND has been disabled on this network."));
+ MemoServService::MemoResult result = memoserv->Send(u->nick, nick, text);
+ if (result == MemoServService::MEMO_INVALID_TARGET)
+ source.Reply(_("\002%s\002 is not a registered unforbidden nick or channel."), nick.c_str());
+ else if (result == MemoServService::MEMO_TOO_FAST)
+ source.Reply(_("Please wait %d seconds before using the SEND command again."), Config->MSSendDelay);
+ else if (result == MemoServService::MEMO_TARGET_FULL)
+ source.Reply(_("%s currently has too many memos and cannot receive more."), nick.c_str());
+ else
+ {
+ source.Reply(_("Memo sent to \002%s\002."), name.c_str());
+
+ bool ischan, isforbid;
+ MemoInfo *mi = memoserv->GetMemoInfo(nick, ischan, isforbid);
+ if (mi == NULL)
+ throw CoreException("NULL mi in ms_rsend");
+ Memo *m = (mi->memos.size() ? mi->memos[mi->memos.size() - 1] : NULL);
+ if (m != NULL)
+ m->SetFlag(MF_RECEIPT);
+ }
}
return MOD_CONT;
@@ -85,12 +98,15 @@ class MSRSend : public Module
MSRSend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
{
if (!Config->MSMemoReceipt)
- throw ModuleException("Don't like memo reciepts, or something.");
+ throw ModuleException("Invalid value for memoreceipt");
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(MemoServ, &commandmsrsend);
+ if (!memoserv)
+ throw ModuleException("MemoServ is not loaded!");
+
+ this->AddCommand(memoserv->Bot(), &commandmsrsend);
}
};
diff --git a/modules/core/ms_send.cpp b/modules/core/ms_send.cpp
index babeb291c..c7bc0bb4c 100644
--- a/modules/core/ms_send.cpp
+++ b/modules/core/ms_send.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "memoserv.h"
class CommandMSSend : public Command
{
@@ -25,7 +26,17 @@ class CommandMSSend : public Command
{
const Anope::string &nick = params[0];
const Anope::string &text = params[1];
- memo_send(source, nick, text, 0);
+
+ MemoServService::MemoResult result = memoserv->Send(source.u->nick, nick, text);
+ if (result == MemoServService::MEMO_SUCCESS)
+ source.Reply(_("Memo sent to \002%s\002."), nick.c_str());
+ else if (result == MemoServService::MEMO_INVALID_TARGET)
+ source.Reply(_("\002%s\002 is not a registered unforbidden nick or channel."), nick.c_str());
+ else if (result == MemoServService::MEMO_TOO_FAST)
+ source.Reply(_("Please wait %d seconds before using the SEND command again."), Config->MSSendDelay);
+ else if (result == MemoServService::MEMO_TARGET_FULL)
+ source.Reply(_("%s currently has too many memos and cannot receive more."), nick.c_str());
+
return MOD_CONT;
}
@@ -56,7 +67,10 @@ class MSSend : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(MemoServ, &commandmssend);
+ if (!memoserv)
+ throw ModuleException("MemoServ is not loaded!");
+
+ this->AddCommand(memoserv->Bot(), &commandmssend);
}
};
diff --git a/modules/core/ms_sendall.cpp b/modules/core/ms_sendall.cpp
index df084a85d..6fea77ae1 100644
--- a/modules/core/ms_sendall.cpp
+++ b/modules/core/ms_sendall.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "memoserv.h"
class CommandMSSendAll : public Command
{
@@ -39,7 +40,7 @@ class CommandMSSendAll : public Command
NickCore *nc = it->second;
if ((na && na->nc == nc) || !nc->display.equals_ci(u->nick))
- memo_send(source, nc->display, text, 1);
+ memoserv->Send(u->nick, nc->display, text);
}
source.Reply(_("A massmemo has been sent to all registered users."));
@@ -69,7 +70,10 @@ class MSSendAll : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(MemoServ, &commandmssendall);
+ if (!memoserv)
+ throw ModuleException("MemoServ is not loaded!");
+
+ this->AddCommand(memoserv->Bot(), &commandmssendall);
}
};
diff --git a/modules/core/ms_set.cpp b/modules/core/ms_set.cpp
index 35e5c6db5..0b5dd3831 100644
--- a/modules/core/ms_set.cpp
+++ b/modules/core/ms_set.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "memoserv.h"
class CommandMSSet : public Command
{
@@ -237,7 +238,7 @@ class CommandMSSet : public Command
" receive\n"
" \n"
"Type \002%s%s HELP SET \037option\037\002 for more information\n"
- "on a specific option."), Config->UseStrictPrivMsgString.c_str(), MemoServ->nick.c_str());
+ "on a specific option."), Config->UseStrictPrivMsgString.c_str(), Config->s_MemoServ.c_str());
else if (subcommand.equals_ci("NOTIFY"))
source.Reply(_("Syntax: \002SET NOTIFY {ON | LOGON | NEW | MAIL | NOMAIL | OFF}\002\n"
"Changes when you will be notified about new memos:\n"
@@ -307,7 +308,10 @@ class MSSet : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(MemoServ, &commandmsset);
+ if (!memoserv)
+ throw ModuleException("MemoServ is not loaded!");
+
+ this->AddCommand(memoserv->Bot(), &commandmsset);
}
};
diff --git a/modules/core/ms_staff.cpp b/modules/core/ms_staff.cpp
index 1de1b11bf..1d7fbc288 100644
--- a/modules/core/ms_staff.cpp
+++ b/modules/core/ms_staff.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "memoserv.h"
class CommandMSStaff : public Command
{
@@ -36,7 +37,7 @@ class CommandMSStaff : public Command
NickCore *nc = it->second;
if (nc->IsServicesOper())
- memo_send(source, nc->display, text, 0);
+ memoserv->Send(source.u->nick, nc->display, text, true);
}
return MOD_CONT;
@@ -67,7 +68,10 @@ class MSStaff : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(MemoServ, &commandmsstaff);
+ if (!memoserv)
+ throw ModuleException("MemoServ is not loaded!");
+
+ this->AddCommand(memoserv->Bot(), &commandmsstaff);
}
};
diff --git a/modules/core/nickserv.h b/modules/core/nickserv.h
new file mode 100644
index 000000000..71039c7ba
--- /dev/null
+++ b/modules/core/nickserv.h
@@ -0,0 +1,17 @@
+#ifndef NICKSERV_H
+#define NICKSERV_H
+
+class NickServService : public Service
+{
+ public:
+ NickServService(Module *m) : Service(m, "NickServ") { }
+
+ virtual BotInfo *Bot() = 0;
+
+ virtual void Validate(User *u) = 0;
+};
+
+static service_reference<NickServService> nickserv("NickServ");
+
+#endif // NICKSERV_H
+
diff --git a/modules/core/ns_access.cpp b/modules/core/ns_access.cpp
index 96aa0e137..7e69dbf4e 100644
--- a/modules/core/ns_access.cpp
+++ b/modules/core/ns_access.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "nickserv.h"
class CommandNSAccess : public Command
{
@@ -172,7 +173,7 @@ class CommandNSAccess : public Command
" Reverses the previous command.\n"
" \n"
" \002ACCESS LIST\002\n"
- " Displays the current access list."), NickServ->nick.c_str(), NickServ->nick.c_str());
+ " Displays the current access list."), Config->s_NickServ.c_str(), Config->s_NickServ.c_str());
return true;
}
@@ -192,7 +193,10 @@ class NSAccess : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(NickServ, &commandnsaccess);
+ if (!nickserv)
+ throw ModuleException("NickServ is not loaded!");
+
+ this->AddCommand(nickserv->Bot(), &commandnsaccess);
}
};
diff --git a/modules/core/ns_ajoin.cpp b/modules/core/ns_ajoin.cpp
index 2f5c4e753..2d5ac146e 100644
--- a/modules/core/ns_ajoin.cpp
+++ b/modules/core/ns_ajoin.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "nickserv.h"
class CommandNSAJoin : public Command
{
@@ -117,7 +118,10 @@ class NSAJoin : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(NickServ, &commandnsajoin);
+ if (!nickserv)
+ throw ModuleException("NickServ is not loaded!");
+
+ this->AddCommand(nickserv->Bot(), &commandnsajoin);
Implementation i[] = { I_OnNickIdentify, I_OnDatabaseWriteMetadata, I_OnDatabaseReadMetadata };
ModuleManager::Attach(i, this, 3);
@@ -189,10 +193,10 @@ class NSAJoin : public Module
{
if (!check_access(u, ci, CA_INVITE))
continue;
- ircdproto->SendInvite(NickServ, channels[i].first, u->nick);
+ ircdproto->SendInvite(nickserv->Bot(), channels[i].first, u->nick);
}
- ircdproto->SendSVSJoin(NickServ->nick, u->nick, channels[i].first, key);
+ ircdproto->SendSVSJoin(Config->s_NickServ, u->nick, channels[i].first, key);
}
}
diff --git a/modules/core/ns_alist.cpp b/modules/core/ns_alist.cpp
index f0fd3f7aa..78b4cf096 100644
--- a/modules/core/ns_alist.cpp
+++ b/modules/core/ns_alist.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "nickserv.h"
class CommandNSAList : public Command
{
@@ -175,7 +176,7 @@ class NSAList : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(NickServ, &commandnsalist);
+ this->AddCommand(nickserv->Bot(), &commandnsalist);
}
};
diff --git a/modules/core/ns_cert.cpp b/modules/core/ns_cert.cpp
index 583502ba9..87acf7ac2 100644
--- a/modules/core/ns_cert.cpp
+++ b/modules/core/ns_cert.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "nickserv.h"
class CommandNSCert : public Command
{
@@ -161,7 +162,7 @@ class CommandNSCert : public Command
"If you connect to IRC and provide a client certificate with a\n"
"matching fingerprint in the cert list, your nick will be\n"
"automatically identified to %s.\n"
- " \n"), NickServ->nick.c_str(), NickServ->nick.c_str());
+ " \n"), Config->s_NickServ.c_str(), Config->s_NickServ.c_str());
source.Reply(_("Examples:\n"
" \n"
" \002CERT ADD <fingerprint>\002\n"
@@ -173,7 +174,7 @@ class CommandNSCert : public Command
" Reverses the previous command.\n"
" \n"
" \002CERT LIST\002\n"
- " Displays the current certificate list."), NickServ->nick.c_str());
+ " Displays the current certificate list."), Config->s_NickServ.c_str());
return true;
}
@@ -200,7 +201,7 @@ class NSCert : public Module
return;
u->Identify(na);
- u->SendMessage(NickServ, _("SSL Fingerprint accepted. You are now identified."));
+ u->SendMessage(nickserv->Bot(), _("SSL Fingerprint accepted. You are now identified."));
return;
}
@@ -213,10 +214,13 @@ class NSCert : public Module
if (!ircd->certfp)
throw ModuleException("Your IRCd does not support ssl client certificates");
+ if (!nickserv)
+ throw ModuleException("NickServ is not loaded!");
+
Implementation i[] = { I_OnUserNickChange, I_OnFingerprint };
ModuleManager::Attach(i, this, 2);
- this->AddCommand(NickServ, &commandnscert);
+ this->AddCommand(nickserv->Bot(), &commandnscert);
}
void OnFingerprint(User *u)
diff --git a/modules/core/ns_drop.cpp b/modules/core/ns_drop.cpp
index 75a0b7899..475359002 100644
--- a/modules/core/ns_drop.cpp
+++ b/modules/core/ns_drop.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "nickserv.h"
class CommandNSDrop : public Command
{
@@ -99,7 +100,7 @@ class CommandNSDrop : public Command
"With a parameter, drops the named nick from the database.\n"
"You may drop any nick within your group without any \n"
"special privileges. Dropping any nick is limited to \n"
- "\002Services Operators\002."), NickServ->nick.c_str());
+ "\002Services Operators\002."), Config->s_NickServ.c_str());
else
source.Reply(_("Syntax: \002DROP [\037nickname\037 | \037password\037]\002\n"
" \n"
@@ -115,7 +116,7 @@ class CommandNSDrop : public Command
" \n"
"In order to use this command, you must first identify\n"
"with your password (\002%s%s HELP IDENTIFY\002 for more\n"
- "information)."), NickServ->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), NickServ->nick.c_str());
+ "information)."), Config->s_NickServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->s_NickServ.c_str());
return true;
}
@@ -131,7 +132,10 @@ class NSDrop : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(NickServ, &commandnsdrop);
+ if (!nickserv)
+ throw ModuleException("NickServ is not loaded!");
+
+ this->AddCommand(nickserv->Bot(), &commandnsdrop);
}
};
diff --git a/modules/core/ns_forbid.cpp b/modules/core/ns_forbid.cpp
index a5f4324a3..d9c13ca67 100644
--- a/modules/core/ns_forbid.cpp
+++ b/modules/core/ns_forbid.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "nickserv.h"
class CommandNSForbid : public Command
{
@@ -64,7 +65,7 @@ class CommandNSForbid : public Command
if (curr)
{
- curr->SendMessage(NickServ, _(FORCENICKCHANGE_NOW));
+ curr->SendMessage(nickserv->Bot(), _(FORCENICKCHANGE_NOW));
curr->Collide(na);
}
@@ -109,7 +110,10 @@ class NSForbid : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(NickServ, &commandnsforbid);
+ if (!nickserv)
+ throw ModuleException("NickServ is not loaded!");
+
+ this->AddCommand(nickserv->Bot(), &commandnsforbid);
}
};
diff --git a/modules/core/ns_getemail.cpp b/modules/core/ns_getemail.cpp
index e31bfb0f5..8f80a5cdf 100644
--- a/modules/core/ns_getemail.cpp
+++ b/modules/core/ns_getemail.cpp
@@ -16,6 +16,7 @@
/*************************************************************************/
#include "module.h"
+#include "nickserv.h"
class CommandNSGetEMail : public Command
{
@@ -78,7 +79,10 @@ class NSGetEMail : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(NickServ, &commandnsgetemail);
+ if (!nickserv)
+ throw ModuleException("NickServ is not loaded!");
+
+ this->AddCommand(nickserv->Bot(), &commandnsgetemail);
}
};
diff --git a/modules/core/ns_getpass.cpp b/modules/core/ns_getpass.cpp
index e106b7a8b..eba380dfb 100644
--- a/modules/core/ns_getpass.cpp
+++ b/modules/core/ns_getpass.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "nickserv.h"
class CommandNSGetPass : public Command
{
@@ -71,14 +72,17 @@ class NSGetPass : public Module
public:
NSGetPass(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
{
+ this->SetAuthor("Anope");
+ this->SetType(CORE);
+
+ if (!nickserv)
+ throw ModuleException("NickServ is not loaded!");
+
Anope::string tmp_pass = "plain:tmp";
if (enc_decrypt(tmp_pass, tmp_pass) == -1)
throw ModuleException("Incompatible with the encryption module being used");
- this->SetAuthor("Anope");
- this->SetType(CORE);
-
- this->AddCommand(NickServ, &commandnsgetpass);
+ this->AddCommand(nickserv->Bot(), &commandnsgetpass);
}
};
diff --git a/modules/core/ns_ghost.cpp b/modules/core/ns_ghost.cpp
index 60bd9aea2..d22b82472 100644
--- a/modules/core/ns_ghost.cpp
+++ b/modules/core/ns_ghost.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "nickserv.h"
class CommandNSGhost : public Command
{
@@ -62,7 +63,7 @@ class CommandNSGhost : public Command
if (ok)
{
- if (!user->IsIdentified() && FindCommand(NickServ, "RECOVER"))
+ if (!user->IsIdentified() && FindCommand(nickserv->Bot(), "RECOVER"))
source.Reply(_("You may not ghost an unidentified user, use RECOVER instead."));
else
{
@@ -121,7 +122,10 @@ class NSGhost : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(NickServ, &commandnsghost);
+ if (!nickserv)
+ throw ModuleException("NickServ is not loaded!");
+
+ this->AddCommand(nickserv->Bot(), &commandnsghost);
}
};
diff --git a/modules/core/ns_group.cpp b/modules/core/ns_group.cpp
index c7a56cb8f..cd3b4946d 100644
--- a/modules/core/ns_group.cpp
+++ b/modules/core/ns_group.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "nickserv.h"
class CommandNSGroup : public Command
{
@@ -60,7 +61,7 @@ class CommandNSGroup : public Command
source.Reply(_("Please wait %d seconds before using the GROUP command again."), (Config->NSRegDelay + u->lastnickreg) - Anope::CurTime);
else if (u->Account() && u->Account()->HasFlag(NI_SUSPENDED))
{
- Log(NickServ) << NickServ << u->GetMask() << " tried to use GROUP from SUSPENDED nick " << target->nick;
+ Log(nickserv->Bot()) << u->GetMask() << " tried to use GROUP from SUSPENDED nick " << target->nick;
source.Reply(_(NICK_X_SUSPENDED), u->nick.c_str());
}
else if (target && target->nc->HasFlag(NI_SUSPENDED))
@@ -124,16 +125,13 @@ class CommandNSGroup : public Command
u->Login(na->nc);
FOREACH_MOD(I_OnNickGroup, OnNickGroup(u, target));
+ ircdproto->SendAccountLogin(u, u->Account());
ircdproto->SetAutoIdentificationToken(u);
- if (target->nc->HasFlag(NI_UNCONFIRMED) == false)
- u->SetMode(NickServ, UMODE_REGISTERED);
Log(LOG_COMMAND, u, this) << "makes " << u->nick << " join group of " << target->nick << " (" << target->nc->display << ") (email: " << (!target->nc->email.empty() ? target->nc->email : "none") << ")";
source.Reply(_("You are now in the group of \002%s\002."), target->nick.c_str());
u->lastnickreg = Anope::CurTime;
-
- check_memos(u);
}
else
{
@@ -177,7 +175,7 @@ class CommandNSGroup : public Command
"not possible.\n"
" \n"
"\037Note\037: all the nicknames of a group have the same password."),
- Config->UseStrictPrivMsgString.c_str(), NickServ->nick.c_str());
+ Config->UseStrictPrivMsgString.c_str(), Config->s_NickServ.c_str());
return true;
}
@@ -233,7 +231,7 @@ class CommandNSUngroup : public Command
User *user = finduser(na->nick);
if (user)
/* The user on the nick who was ungrouped may be identified to the old group, set -r */
- user->RemoveMode(NickServ, UMODE_REGISTERED);
+ user->RemoveMode(nickserv->Bot(), UMODE_REGISTERED);
}
return MOD_CONT;
@@ -318,9 +316,9 @@ class NSGroup : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(NickServ, &commandnsgroup);
- this->AddCommand(NickServ, &commandnsungroup);
- this->AddCommand(NickServ, &commandnsglist);
+ this->AddCommand(nickserv->Bot(), &commandnsgroup);
+ this->AddCommand(nickserv->Bot(), &commandnsungroup);
+ this->AddCommand(nickserv->Bot(), &commandnsglist);
}
};
diff --git a/modules/core/ns_help.cpp b/modules/core/ns_help.cpp
index d586901f8..61088d979 100644
--- a/modules/core/ns_help.cpp
+++ b/modules/core/ns_help.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "nickserv.h"
class CommandNSHelp : public Command
{
@@ -24,7 +25,7 @@ class CommandNSHelp : public Command
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
- mod_help_cmd(NickServ, source.u, NULL, params[0]);
+ mod_help_cmd(nickserv->Bot(), source.u, NULL, params[0]);
return MOD_CONT;
}
@@ -36,9 +37,8 @@ class CommandNSHelp : public Command
"commands allow for registration and maintenance of\n"
"nicknames; to use them, type \002%s%s \037command\037\002.\n"
"For more information on a specific command, type\n"
- "\002%s%s HELP \037command\037\002."), Config->UseStrictPrivMsgString.c_str(), NickServ->nick.c_str(), Config->UseStrictPrivMsgString.c_str(), NickServ->nick.c_str(),
- NickServ->nick.c_str());
- for (CommandMap::const_iterator it = NickServ->Commands.begin(), it_end = NickServ->Commands.end(); it != it_end; ++it)
+ "\002%s%s HELP \037command\037\002."), Config->UseStrictPrivMsgString.c_str(), Config->s_NickServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->s_NickServ.c_str(), Config->s_NickServ.c_str());
+ for (CommandMap::const_iterator it = nickserv->Bot()->Commands.begin(), it_end = nickserv->Bot()->Commands.end(); it != it_end; ++it)
if (!Config->HidePrivilegedCommands || it->second->permission.empty() || u->HasCommand(it->second->permission))
it->second->OnServHelp(source);
if (u->IsServicesOper())
@@ -46,7 +46,7 @@ class CommandNSHelp : public Command
"Services Operators can also drop any nickname without needing\n"
"to identify for the nick, and may view the access list for\n"
"any nickname (\002%s%s ACCESS LIST \037nick\037\002)."),
- Config->UseStrictPrivMsgString.c_str(), NickServ->nick.c_str());
+ Config->UseStrictPrivMsgString.c_str(), Config->s_NickServ.c_str());
if (Config->NSExpire >= 86400)
source.Reply(_("Nicknames that are not used anymore are subject to \n"
"the automatic expiration, i.e. they will be deleted\n"
@@ -57,7 +57,7 @@ class CommandNSHelp : public Command
"It is \002NOT\002 intended to facilitate \"stealing\" of\n"
"nicknames or other malicious actions. Abuse of %s\n"
"will result in, at minimum, loss of the abused\n"
- "nickname(s)."), NickServ->nick.c_str());
+ "nickname(s)."), Config->s_NickServ.c_str());
}
};
@@ -71,7 +71,10 @@ class NSHelp : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(NickServ, &commandnshelp);
+ if (!nickserv)
+ throw ModuleException("NickServ is not loaded!");
+
+ this->AddCommand(nickserv->Bot(), &commandnshelp);
}
};
diff --git a/modules/core/ns_identify.cpp b/modules/core/ns_identify.cpp
index f5f196f62..3ef47b7d7 100644
--- a/modules/core/ns_identify.cpp
+++ b/modules/core/ns_identify.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "nickserv.h"
class CommandNSIdentify : public Command
{
@@ -72,7 +73,7 @@ class CommandNSIdentify : public Command
"nick. Many commands require you to authenticate yourself\n"
"with this command before you use them. The password\n"
"should be the same one you sent with the \002REGISTER\002\n"
- "command."), NickServ->nick.c_str());
+ "command."), Config->s_NickServ.c_str());
return true;
}
@@ -92,7 +93,10 @@ class NSIdentify : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(NickServ, &commandnsidentify);
+ if (!nickserv)
+ throw ModuleException("NickServ is not loaded!");
+
+ this->AddCommand(nickserv->Bot(), &commandnsidentify);
}
};
diff --git a/modules/core/ns_info.cpp b/modules/core/ns_info.cpp
index 6328341cb..59cd60e6d 100644
--- a/modules/core/ns_info.cpp
+++ b/modules/core/ns_info.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "nickserv.h"
class CommandNSInfo : public Command
{
@@ -175,7 +176,10 @@ class NSInfo : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(NickServ, &commandnsinfo);
+ if (!nickserv)
+ throw ModuleException("NickServ is not loaded!");
+
+ this->AddCommand(nickserv->Bot(), &commandnsinfo);
}
};
diff --git a/modules/core/ns_list.cpp b/modules/core/ns_list.cpp
index b032543de..60dfa9732 100644
--- a/modules/core/ns_list.cpp
+++ b/modules/core/ns_list.cpp
@@ -12,7 +12,7 @@
/*************************************************************************/
#include "module.h"
-#include "hashcomp.h"
+#include "nickserv.h"
class CommandNSList : public Command
{
@@ -219,7 +219,10 @@ class NSList : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(NickServ, &commandnslist);
+ if (!nickserv)
+ throw ModuleException("NickServ is not loaded!");
+
+ this->AddCommand(nickserv->Bot(), &commandnslist);
}
};
diff --git a/modules/core/ns_logout.cpp b/modules/core/ns_logout.cpp
index c074fecf8..6675e85b4 100644
--- a/modules/core/ns_logout.cpp
+++ b/modules/core/ns_logout.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "nickserv.h"
class CommandNSLogout : public Command
{
@@ -38,7 +39,7 @@ class CommandNSLogout : public Command
else
{
if (!nick.empty() && !param.empty() && param.equals_ci("REVALIDATE"))
- validate_user(u2);
+ nickserv->Validate(u2);
u2->isSuperAdmin = 0; /* Dont let people logout and remain a SuperAdmin */
Log(LOG_COMMAND, u, this) << "to logout " << u2->nick;
@@ -50,7 +51,7 @@ class CommandNSLogout : public Command
source.Reply(_("Your nick has been logged out."));
ircdproto->SendAccountLogout(u2, u2->Account());
- u2->RemoveMode(NickServ, UMODE_REGISTERED);
+ u2->RemoveMode(nickserv->Bot(), UMODE_REGISTERED);
ircdproto->SendUnregisteredNick(u2);
u2->Logout();
@@ -102,7 +103,10 @@ class NSLogout : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(NickServ, &commandnslogout);
+ if (!nickserv)
+ throw ModuleException("NickServ is not loaded!");
+
+ this->AddCommand(nickserv->Bot(), &commandnslogout);
}
};
diff --git a/modules/core/ns_main.cpp b/modules/core/ns_main.cpp
new file mode 100644
index 000000000..dbf72ca09
--- /dev/null
+++ b/modules/core/ns_main.cpp
@@ -0,0 +1,282 @@
+/* NickServ 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 "nickserv.h"
+
+static BotInfo *NickServ = NULL;
+
+class MyNickServService : public NickServService
+{
+ public:
+ MyNickServService(Module *m) : NickServService(m) { }
+
+ BotInfo *Bot()
+ {
+ return NickServ;
+ }
+
+ void Validate(User *u)
+ {
+ NickAlias *na = findnick(u->nick);
+ if (!na)
+ return;
+
+ if (na->HasFlag(NS_FORBIDDEN))
+ {
+ u->SendMessage(NickServ, _("This nickname may not be used. Please choose another one."));
+ u->Collide(na);
+ return;
+ }
+
+ if (na->nc->HasFlag(NI_SUSPENDED))
+ {
+ u->SendMessage(NickServ, _(NICK_X_SUSPENDED), u->nick.c_str());
+ u->Collide(na);
+ return;
+ }
+
+ if (!u->IsIdentified() && !u->fingerprint.empty() && na->nc->FindCert(u->fingerprint))
+ {
+ u->SendMessage(NickServ, _("SSL Fingerprint accepted, you are now identified"));
+ u->Identify(na);
+ return;
+ }
+
+ if (!na->nc->HasFlag(NI_SECURE) && u->IsRecognized())
+ {
+ na->last_seen = Anope::CurTime;
+ Anope::string last_usermask = u->GetIdent() + "@" + u->GetDisplayedHost();
+ na->last_usermask = last_usermask;
+ na->last_realname = u->realname;
+ return;
+ }
+
+ if (u->IsRecognized() || !na->nc->HasFlag(NI_KILL_IMMED))
+ {
+ if (na->nc->HasFlag(NI_SECURE))
+ u->SendMessage(NickServ, _(NICK_IS_SECURE), Config->UseStrictPrivMsgString.c_str(), Config->s_NickServ.c_str());
+ else
+ u->SendMessage(NickServ, _(NICK_IS_REGISTERED), Config->UseStrictPrivMsgString.c_str(), Config->s_NickServ.c_str());
+ }
+
+ if (na->nc->HasFlag(NI_KILLPROTECT) && !u->IsRecognized())
+ {
+ if (na->nc->HasFlag(NI_KILL_IMMED))
+ {
+ u->SendMessage(NickServ, _(FORCENICKCHANGE_NOW));
+ u->Collide(na);
+ }
+ else if (na->nc->HasFlag(NI_KILL_QUICK))
+ {
+ u->SendMessage(NickServ, _("If you do not change within 20 seconds, I will change your nick."));
+ new NickServCollide(u, 20);
+ }
+ else
+ {
+ u->SendMessage(NickServ, _("If you do not change within one minute, I will change your nick."));
+ new NickServCollide(u, 60);
+ }
+ }
+
+ }
+};
+
+class ExpireCallback : public CallBack
+{
+ public:
+ ExpireCallback(Module *owner) : CallBack(owner, Config->ExpireTimeout, Anope::CurTime, true) { }
+
+ void Tick(time_t)
+ {
+ if (noexpire || readonly)
+ return;
+
+ for (nickalias_map::const_iterator it = NickAliasList.begin(), it_end = NickAliasList.end(); it != it_end; )
+ {
+ NickAlias *na = it->second;
+ ++it;
+
+ User *u = finduser(na->nick);
+ if (u && (na->nc->HasFlag(NI_SECURE) ? u->IsIdentified(true) : u->IsRecognized(true)))
+ na->last_seen = Anope::CurTime;
+
+ bool expire = false;
+
+ if (na->nc->HasFlag(NI_UNCONFIRMED))
+ if (Config->NSUnconfirmedExpire && Anope::CurTime - na->time_registered >= Config->NSUnconfirmedExpire)
+ expire = true;
+ if (na->nc->HasFlag(NI_SUSPENDED))
+ {
+ if (Config->NSSuspendExpire && Anope::CurTime - na->last_seen >= Config->NSSuspendExpire)
+ expire = true;
+ }
+ else if (na->HasFlag(NS_FORBIDDEN))
+ {
+ if (Config->NSForbidExpire && Anope::CurTime - na->last_seen >= Config->NSForbidExpire)
+ expire = true;
+ }
+ else if (Config->NSExpire && Anope::CurTime - na->last_seen >= Config->NSExpire)
+ expire = true;
+ if (na->HasFlag(NS_NO_EXPIRE))
+ expire = false;
+
+ if (expire)
+ {
+ EventReturn MOD_RESULT;
+ FOREACH_RESULT(I_OnPreNickExpire, OnPreNickExpire(na));
+ if (MOD_RESULT == EVENT_STOP)
+ continue;
+ Anope::string extra;
+ if (na->HasFlag(NS_FORBIDDEN))
+ extra = "forbidden ";
+ else if (na->nc->HasFlag(NI_SUSPENDED))
+ extra = "suspended ";
+ Log(LOG_NORMAL, "expire") << "Expiring " << extra << "nickname " << na->nick << " (group: " << na->nc->display << ") (e-mail: " << (na->nc->email.empty() ? "none" : na->nc->email) << ")";
+ FOREACH_MOD(I_OnNickExpire, OnNickExpire(na));
+ delete na;
+ }
+ }
+ }
+};
+
+class NickServCore : public Module
+{
+ MyNickServService mynickserv;
+ ExpireCallback expires;
+
+ public:
+ NickServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator), mynickserv(this), expires(this)
+ {
+ this->SetAuthor("Anope");
+ this->SetType(CORE);
+
+ Implementation i[] = { I_OnDelNick, I_OnDelCore, I_OnChangeCoreDisplay, I_OnNickIdentify, I_OnNickGroup, I_OnNickUpdate };
+ ModuleManager::Attach(i, this, 5);
+
+ ModuleManager::RegisterService(&this->mynickserv);
+
+ NickServ = new BotInfo(Config->s_NickServ, Config->ServiceUser, Config->ServiceHost, Config->desc_NickServ);
+ NickServ->SetFlag(BI_CORE);
+
+ spacesepstream coreModules(Config->NickCoreModules);
+ Anope::string module;
+ while (coreModules.GetToken(module))
+ ModuleManager::LoadModule(module, NULL);
+ }
+
+ ~NickServCore()
+ {
+ spacesepstream coreModules(Config->NickCoreModules);
+ Anope::string module;
+ while (coreModules.GetToken(module))
+ {
+ Module *m = FindModule(module);
+ if (m != NULL)
+ ModuleManager::UnloadModule(m, NULL);
+ }
+
+ delete NickServ;
+ }
+
+ void OnDelNick(NickAlias *na)
+ {
+ User *u = finduser(na->nick);
+ if (u && u->Account() == na->nc)
+ {
+ u->RemoveMode(NickServ, UMODE_REGISTERED);
+ ircdproto->SendAccountLogout(u, u->Account());
+ ircdproto->SendUnregisteredNick(u);
+ u->Logout();
+ }
+ }
+
+ void OnDelCore(NickCore *nc)
+ {
+ Log(NickServ, "nick") << "deleting nickname group " << nc->display;
+
+ /* Clean up this nick core from any users online using it
+ * (ones that /nick but remain unidentified)
+ */
+ for (std::list<User *>::iterator it = nc->Users.begin(); it != nc->Users.end();)
+ {
+ User *user = *it++;
+ ircdproto->SendAccountLogout(user, user->Account());
+ user->RemoveMode(NickServ, UMODE_REGISTERED);
+ ircdproto->SendUnregisteredNick(user);
+ user->Logout();
+ FOREACH_MOD(I_OnNickLogout, OnNickLogout(user));
+ }
+ nc->Users.clear();
+ }
+
+ void OnChangeCoreDisplay(NickCore *nc, const Anope::string &newdisplay)
+ {
+ Log(LOG_NORMAL, "nick", NickServ) << "Changing " << nc->display << " nickname group display to " << newdisplay;
+ }
+
+ void OnNickIdentify(User *u)
+ {
+ NickAlias *this_na = findnick(u->nick);
+ if (this_na && this_na->nc == u->Account() && u->Account()->HasFlag(NI_UNCONFIRMED) == false)
+ u->SetMode(NickServ, UMODE_REGISTERED);
+
+ if (Config->NSModeOnID)
+ for (UChannelList::iterator it = u->chans.begin(), it_end = u->chans.end(); it != it_end; ++it)
+ {
+ ChannelContainer *cc = *it;
+ Channel *c = cc->chan;
+ if (c)
+ chan_set_correct_modes(u, c, 1);
+ }
+
+ if (Config->NSForceEmail && u->Account()->email.empty())
+ {
+ u->SendMessage(NickServ, _("You must now supply an e-mail for your nick.\n"
+ "This e-mail will allow you to retrieve your password in\n"
+ "case you forget it."));
+ u->SendMessage(NickServ, _("Type \002%s%s SET EMAIL \037e-mail\037\002 in order to set your e-mail.\n"
+ "Your privacy is respected; this e-mail won't be given to\n"
+ "any third-party person."), Config->UseStrictPrivMsgString.c_str(), Config->s_NickServ.c_str());
+ }
+
+ if (u->Account()->HasFlag(NI_UNCONFIRMED))
+ {
+ u->SendMessage(NickServ, _("Your email address is not confirmed. To confirm it, follow the instructions that were emailed to you when you registered."));
+ this_na = findnick(u->Account()->display);
+ time_t time_registered = Anope::CurTime - this_na->time_registered;
+ if (Config->NSUnconfirmedExpire > time_registered)
+ u->SendMessage(NickServ, _("Your account will expire, if not confirmed, in %s"), duration(Config->NSUnconfirmedExpire - time_registered).c_str());
+ }
+ }
+
+ void OnNickGroup(User *u, NickAlias *target)
+ {
+ if (target->nc->HasFlag(NI_UNCONFIRMED) == false)
+ u->SetMode(NickServ, UMODE_REGISTERED);
+ }
+
+ void OnNickUpdate(User *u)
+ {
+ for (UChannelList::iterator it = u->chans.begin(), it_end = u->chans.end(); it != it_end; ++it)
+ {
+ ChannelContainer *cc = *it;
+ Channel *c = cc->chan;
+ if (c)
+ chan_set_correct_modes(u, c, 1);
+ }
+ }
+};
+
+MODULE_INIT(NickServCore)
+
diff --git a/modules/core/ns_recover.cpp b/modules/core/ns_recover.cpp
index f9e088586..30e1476c3 100644
--- a/modules/core/ns_recover.cpp
+++ b/modules/core/ns_recover.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "nickserv.h"
class CommandNSRecover : public Command
{
@@ -50,7 +51,7 @@ class CommandNSRecover : public Command
if (MOD_RESULT == EVENT_ALLOW)
{
- u2->SendMessage(NickServ, _(FORCENICKCHANGE_NOW));
+ u2->SendMessage(nickserv->Bot(), _(FORCENICKCHANGE_NOW));
u2->Collide(na);
/* Convert Config->NSReleaseTimeout seconds to string format */
@@ -70,7 +71,7 @@ class CommandNSRecover : public Command
if (u->Account() == na->nc || (!na->nc->HasFlag(NI_SECURE) && is_on_access(u, na->nc)) ||
(!u->fingerprint.empty() && na->nc->FindCert(u->fingerprint)))
{
- u2->SendMessage(NickServ, _(FORCENICKCHANGE_NOW));
+ u2->SendMessage(nickserv->Bot(), _(FORCENICKCHANGE_NOW));
u2->Collide(na);
/* Convert Config->NSReleaseTimeout seconds to string format */
@@ -110,7 +111,7 @@ class CommandNSRecover : public Command
"current address as shown in /WHOIS must be on that nick's\n"
"access list, you must be identified and in the group of\n"
"that nick, or you must supply the correct password for\n"
- "the nickname."), NickServ->nick.c_str(), NickServ->nick.c_str(), relstr.c_str(), Config->UseStrictPrivMsgString.c_str(), NickServ->nick.c_str());
+ "the nickname."), Config->s_NickServ.c_str(), Config->s_NickServ.c_str(), relstr.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->s_NickServ.c_str());
return true;
}
@@ -131,7 +132,10 @@ class NSRecover : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(NickServ, &commandnsrecover);
+ if (!nickserv)
+ throw ModuleException("NickServ is not loaded!");
+
+ this->AddCommand(nickserv->Bot(), &commandnsrecover);
}
};
diff --git a/modules/core/ns_register.cpp b/modules/core/ns_register.cpp
index b1d70c9a5..56c8072ca 100644
--- a/modules/core/ns_register.cpp
+++ b/modules/core/ns_register.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "nickserv.h"
static bool SendRegmail(User *u, NickAlias *na);
@@ -155,7 +156,7 @@ class CommandNSRegister : public Command
/* i.e. there's already such a nick regged */
if (na->HasFlag(NS_FORBIDDEN))
{
- Log(NickServ) << u->GetMask() << " tried to register FORBIDden nick " << u->nick;
+ Log(nickserv->Bot()) << u->GetMask() << " tried to register FORBIDden nick " << u->nick;
source.Reply(_(NICK_CANNOT_BE_REGISTERED), u->nick.c_str());
}
else
@@ -200,7 +201,7 @@ class CommandNSRegister : public Command
na->nc->SetFlag(NI_UNCONFIRMED);
if (SendRegmail(u, na))
{
- source.Reply(_("A passcode has been sent to %s, please type %s%s confirm <passcode> to confirm your email address."), email.c_str(), Config->UseStrictPrivMsgString.c_str(), NickServ->nick.c_str());
+ source.Reply(_("A passcode has been sent to %s, please type %s%s confirm <passcode> to confirm your email address."), email.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->s_NickServ.c_str());
source.Reply(_("If you do not confirm your email address within %s your account will expire."), duration(Config->NSUnconfirmedExpire).c_str());
}
}
@@ -235,10 +236,9 @@ class CommandNSRegister : public Command
"passwords are vulnerable to trial-and-error searches, so\n"
"you should choose a password at least 5 characters long.\n"
"Finally, the space character cannot be used in passwords.\n"),
- NickServ->nick.c_str(), NickServ->nick.c_str());
+ Config->s_NickServ.c_str(), Config->s_NickServ.c_str());
- source.Reply(_(
- " \n"
+ source.Reply(_(" \n"
"The parameter \037email\037 is optional and will set the email\n"
"for your nick immediately. However, it may be required\n"
"on certain networks.\n"
@@ -250,7 +250,7 @@ class CommandNSRegister : public Command
"the same configuration, the same set of memos and the\n"
"same channel privileges. For more information on this\n"
"feature, type \002%s%s HELP GROUP\002."),
- Config->UseStrictPrivMsgString.c_str(), NickServ->nick.c_str());
+ Config->UseStrictPrivMsgString.c_str(), Config->s_NickServ.c_str());
return true;
}
@@ -330,9 +330,12 @@ class NSRegister : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(NickServ, &commandnsregister);
- this->AddCommand(NickServ, &commandnsconfirm);
- this->AddCommand(NickServ, &commandnsrsend);
+ if (!nickserv)
+ throw ModuleException("NickServ is not loaded!");
+
+ this->AddCommand(nickserv->Bot(), &commandnsregister);
+ this->AddCommand(nickserv->Bot(), &commandnsconfirm);
+ this->AddCommand(nickserv->Bot(), &commandnsrsend);
}
};
@@ -364,7 +367,7 @@ static bool SendRegmail(User *u, NickAlias *na)
" \n"
"%s administrators."), na->nick.c_str(), Config->NetworkName.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->s_NickServ.c_str(), code.c_str(), Config->NetworkName.c_str());
- return Mail(u, na->nc, NickServ, subject, message);
+ return Mail(u, na->nc, nickserv->Bot(), subject, message);
}
MODULE_INIT(NSRegister)
diff --git a/modules/core/ns_release.cpp b/modules/core/ns_release.cpp
index a6f5f862f..251355b0d 100644
--- a/modules/core/ns_release.cpp
+++ b/modules/core/ns_release.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "nickserv.h"
class CommandNSRelease : public Command
{
@@ -87,7 +88,7 @@ class CommandNSRelease : public Command
"current address as shown in /WHOIS must be on that nick's\n"
"access list, you must be identified and in the group of\n"
"that nick, or you must supply the correct password for\n"
- "the nickname."), NickServ->nick.c_str(), relstr.c_str());
+ "the nickname."), Config->s_NickServ.c_str(), relstr.c_str());
return true;
@@ -109,7 +110,10 @@ class NSRelease : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(NickServ, &commandnsrelease);
+ if (!nickserv)
+ throw ModuleException("NickServ is not loaded!");
+
+ this->AddCommand(nickserv->Bot(), &commandnsrelease);
}
};
diff --git a/modules/core/ns_resetpass.cpp b/modules/core/ns_resetpass.cpp
index 626af80c8..3cbbe5903 100644
--- a/modules/core/ns_resetpass.cpp
+++ b/modules/core/ns_resetpass.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "nickserv.h"
static bool SendResetEmail(User *u, NickAlias *na);
@@ -68,13 +69,16 @@ class NSResetPass : public Module
public:
NSResetPass(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
{
- if (!Config->UseMail)
- throw ModuleException("Not using mail.");
-
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(NickServ, &commandnsresetpass);
+ if (!nickserv)
+ throw ModuleException("NickServ is not loaded!");
+
+ if (!Config->UseMail)
+ throw ModuleException("Not using mail.");
+
+ this->AddCommand(nickserv->Bot(), &commandnsresetpass);
ModuleManager::Attach(I_OnPreCommand, this);
}
@@ -82,7 +86,7 @@ class NSResetPass : public Module
EventReturn OnPreCommand(CommandSource &source, Command *command, const std::vector<Anope::string> &params)
{
User *u = source.u;
- if (command->service == NickServ && command->name.equals_ci("CONFIRM") && params.size() > 1)
+ if (command->service->nick == Config->s_NickServ && command->name.equals_ci("CONFIRM") && params.size() > 1)
{
NickAlias *na = findnick(params[0]);
@@ -151,7 +155,7 @@ static bool SendResetEmail(User *u, NickAlias *na)
na->nc->Extend("ns_resetpass_code", new ExtensibleItemRegular<Anope::string>(passcode));
na->nc->Extend("ns_resetpass_time", new ExtensibleItemRegular<time_t>(Anope::CurTime));
- return Mail(u, na->nc, NickServ, subject, message);
+ return Mail(u, na->nc, nickserv->Bot(), subject, message);
}
MODULE_INIT(NSResetPass)
diff --git a/modules/core/ns_saset.cpp b/modules/core/ns_saset.cpp
index 94da56ec6..69fb747d6 100644
--- a/modules/core/ns_saset.cpp
+++ b/modules/core/ns_saset.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "nickserv.h"
class CommandNSSASet : public Command
{
@@ -62,7 +63,7 @@ class CommandNSSASet : public Command
Log(LOG_ADMIN, u, this) << params[1] << " " << cmdparams;
else
Log(LOG_ADMIN, u, this) << params[1] << " for " << params[0];
- mod_run_cmd(NickServ, u, NULL, c, params[1], cmdparams);
+ mod_run_cmd(nickserv->Bot(), u, NULL, c, params[1], cmdparams);
}
else
source.Reply(_("Unknown SASET option \002%s\002."), cmd.c_str());
@@ -82,7 +83,7 @@ class CommandNSSASet : public Command
it->second->OnServHelp(source);
source.Reply(_("Type \002%s%s HELP SASET \037option\037\002 for more information\n"
"on a specific option. The options will be set on the given\n"
- "\037nickname\037."), Config->UseStrictPrivMsgString.c_str(), NickServ->nick.c_str());
+ "\037nickname\037."), Config->UseStrictPrivMsgString.c_str(), Config->s_NickServ.c_str());
return true;
}
else
@@ -203,7 +204,7 @@ class CommandNSSASetPassword : public Command
if (enc_encrypt(params[1], nc->pass))
{
- Log(NickServ) << "Failed to encrypt password for " << nc->display << " (saset)";
+ Log() << "Failed to encrypt password for " << nc->display << " (saset)";
source.Reply(_(NICK_SASET_PASSWORD_FAILED), nc->display.c_str());
return MOD_CONT;
}
@@ -243,7 +244,10 @@ class NSSASet : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(NickServ, &commandnssaset);
+ if (!nickserv)
+ throw ModuleException("NickServ is not loaded!");
+
+ this->AddCommand(nickserv->Bot(), &commandnssaset);
commandnssaset.AddSubcommand(this, &commandnssasetdisplay);
commandnssaset.AddSubcommand(this, &commandnssasetpassword);
diff --git a/modules/core/ns_saset_noexpire.cpp b/modules/core/ns_saset_noexpire.cpp
index 532d6c8fe..e1bbaf87f 100644
--- a/modules/core/ns_saset_noexpire.cpp
+++ b/modules/core/ns_saset_noexpire.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "nickserv.h"
class CommandNSSASetNoexpire : public Command
{
@@ -70,14 +71,17 @@ class NSSASetNoexpire : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- Command *c = FindCommand(NickServ, "SASET");
+ if (!nickserv)
+ throw ModuleException("NickServ is not loaded!");
+
+ Command *c = FindCommand(nickserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandnssasetnoexpire);
}
~NSSASetNoexpire()
{
- Command *c = FindCommand(NickServ, "SASET");
+ Command *c = FindCommand(nickserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandnssasetnoexpire);
}
diff --git a/modules/core/ns_sendpass.cpp b/modules/core/ns_sendpass.cpp
index 9614211c1..98530c236 100644
--- a/modules/core/ns_sendpass.cpp
+++ b/modules/core/ns_sendpass.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "nickserv.h"
static bool SendPassMail(User *u, NickAlias *na, const Anope::string &pass);
@@ -79,6 +80,12 @@ class NSSendPass : public Module
public:
NSSendPass(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
{
+ this->SetAuthor("Anope");
+ this->SetType(CORE);
+
+ if (!nickserv)
+ throw ModuleException("NickServ is not loaded!");
+
if (!Config->UseMail)
throw ModuleException("Not using mail, whut.");
@@ -86,10 +93,7 @@ class NSSendPass : public Module
if (enc_decrypt(tmp_pass, tmp_pass) == -1)
throw ModuleException("Incompatible with the encryption module being used");
- this->SetAuthor("Anope");
- this->SetType(CORE);
-
- this->AddCommand(NickServ, &commandnssendpass);
+ this->AddCommand(nickserv->Bot(), &commandnssendpass);
}
};
@@ -108,7 +112,7 @@ static bool SendPassMail(User *u, NickAlias *na, const Anope::string &pass)
" \n"
"%s administrators.").c_str(), na->nick.c_str(), pass.c_str(), Config->NetworkName.c_str());
- return Mail(u, na->nc, NickServ, subject, message);
+ return Mail(u, na->nc, nickserv->Bot(), subject, message);
}
MODULE_INIT(NSSendPass)
diff --git a/modules/core/ns_set.cpp b/modules/core/ns_set.cpp
index bfae7f508..895542cc7 100644
--- a/modules/core/ns_set.cpp
+++ b/modules/core/ns_set.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "nickserv.h"
class CommandNSSet : public Command
{
@@ -57,7 +58,7 @@ class CommandNSSet : public Command
Log(LOG_COMMAND, u, this) << params[0] << " " << cmdparams;
else
Log(LOG_COMMAND, u, this) << params[0];
- mod_run_cmd(NickServ, u, NULL, c, params[0], cmdparams);
+ mod_run_cmd(nickserv->Bot(), u, NULL, c, params[0], cmdparams);
}
else
source.Reply(_(NICK_SET_UNKNOWN_OPTION), Config->UseStrictPrivMsgString.c_str(), params[0].c_str());
@@ -79,7 +80,7 @@ class CommandNSSet : public Command
"information).\n"
" \n"
"Type \002%s%s HELP SET \037option\037\002 for more information\n"
- "on a specific option."), Config->UseStrictPrivMsgString.c_str(), NickServ->nick.c_str(), (Config->UseStrictPrivMsg ? "/msg " : "/"), NickServ->nick.c_str());
+ "on a specific option."), Config->UseStrictPrivMsgString.c_str(), Config->s_NickServ.c_str(), (Config->UseStrictPrivMsg ? "/msg " : "/"), Config->s_NickServ.c_str());
return true;
}
else
@@ -189,7 +190,7 @@ class CommandNSSetPassword : public Command
if (enc_encrypt(param, u->Account()->pass) < 0)
{
- Log(NickServ) << "Failed to encrypt password for " << u->Account()->display << " (set)";
+ Log() << "Failed to encrypt password for " << u->Account()->display << " (set)";
source.Reply(_(NICK_SASET_PASSWORD_FAILED));
return MOD_CONT;
}
@@ -231,7 +232,10 @@ class NSSet : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(NickServ, &commandnsset);
+ if (!nickserv)
+ throw ModuleException("NickServ is not loaded!");
+
+ this->AddCommand(nickserv->Bot(), &commandnsset);
commandnsset.AddSubcommand(this, &commandnssetdisplay);
commandnsset.AddSubcommand(this, &commandnssetpassword);
diff --git a/modules/core/ns_set_autoop.cpp b/modules/core/ns_set_autoop.cpp
index f25e3a749..051ce22e6 100644
--- a/modules/core/ns_set_autoop.cpp
+++ b/modules/core/ns_set_autoop.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "nickserv.h"
class CommandNSSetAutoOp : public Command
{
@@ -95,22 +96,25 @@ class NSSetAutoOp : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- Command *c = FindCommand(NickServ, "SET");
+ if (!nickserv)
+ throw ModuleException("NickServ is not loaded!");
+
+ Command *c = FindCommand(nickserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandnssetautoop);
- c = FindCommand(NickServ, "SASET");
+ c = FindCommand(nickserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandnssasetautoop);
}
~NSSetAutoOp()
{
- Command *c = FindCommand(NickServ, "SET");
+ Command *c = FindCommand(nickserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandnssetautoop);
- c = FindCommand(NickServ, "SASET");
+ c = FindCommand(nickserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandnssasetautoop);
}
diff --git a/modules/core/ns_set_email.cpp b/modules/core/ns_set_email.cpp
index d63329f50..ed49cfd89 100644
--- a/modules/core/ns_set_email.cpp
+++ b/modules/core/ns_set_email.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "nickserv.h"
static bool SendConfirmMail(User *u)
{
@@ -38,7 +39,7 @@ static bool SendConfirmMail(User *u)
" \n"
"%s administrators."), u->Account()->email.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->s_NickServ.c_str(), code.c_str(), Config->NetworkName.c_str());
- return Mail(u, u->Account(), NickServ, subject, message);
+ return Mail(u, u->Account(), nickserv->Bot(), subject, message);
}
class CommandNSSetEmail : public Command
@@ -139,24 +140,27 @@ class NSSetEmail : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
+ if (!nickserv)
+ throw ModuleException("NickServ is not loaded!");
+
ModuleManager::Attach(I_OnPreCommand, this);
- Command *c = FindCommand(NickServ, "SET");
+ Command *c = FindCommand(nickserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandnssetemail);
- c = FindCommand(NickServ, "SASET");
+ c = FindCommand(nickserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandnssasetemail);
}
~NSSetEmail()
{
- Command *c = FindCommand(NickServ, "SET");
+ Command *c = FindCommand(nickserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandnssetemail);
- c = FindCommand(NickServ, "SASET");
+ c = FindCommand(nickserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandnssasetemail);
}
@@ -164,7 +168,7 @@ class NSSetEmail : public Module
EventReturn OnPreCommand(CommandSource &source, Command *command, const std::vector<Anope::string> &params)
{
User *u = source.u;
- if (command->service == NickServ && command->name.equals_ci("CONFIRM") && !params.empty() && u->IsIdentified())
+ if (command->service->nick == Config->s_NickServ && command->name.equals_ci("CONFIRM") && !params.empty() && u->IsIdentified())
{
Anope::string new_email, passcode;
if (u->Account()->GetExtRegular("ns_set_email", new_email) && u->Account()->GetExtRegular("ns_set_email_passcode", passcode))
diff --git a/modules/core/ns_set_greet.cpp b/modules/core/ns_set_greet.cpp
index f5c2a26ab..d36694791 100644
--- a/modules/core/ns_set_greet.cpp
+++ b/modules/core/ns_set_greet.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "nickserv.h"
class CommandNSSetGreet : public Command
{
@@ -86,22 +87,25 @@ class NSSetGreet : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- Command *c = FindCommand(NickServ, "SET");
+ if (!nickserv)
+ throw ModuleException("NickServ is not loaded!");
+
+ Command *c = FindCommand(nickserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandnssetgreet);
- c = FindCommand(NickServ, "SASET");
+ c = FindCommand(nickserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandnssasetgreet);
}
~NSSetGreet()
{
- Command *c = FindCommand(NickServ, "SET");
+ Command *c = FindCommand(nickserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandnssetgreet);
- c = FindCommand(NickServ, "SASET");
+ c = FindCommand(nickserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandnssasetgreet);
}
diff --git a/modules/core/ns_set_hide.cpp b/modules/core/ns_set_hide.cpp
index b827b67fe..5d315d6fa 100644
--- a/modules/core/ns_set_hide.cpp
+++ b/modules/core/ns_set_hide.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "nickserv.h"
class CommandNSSetHide : public Command
{
@@ -90,7 +91,7 @@ class CommandNSSetHide : public Command
"user@host mask (\002USERMASK\002), your services access status\n"
"(\002STATUS\002) and last quit message (\002QUIT\002).\n"
"The second parameter specifies whether the information should\n"
- "be displayed (\002OFF\002) or hidden (\002ON\002)."), NickServ->nick.c_str());
+ "be displayed (\002OFF\002) or hidden (\002ON\002)."), Config->s_NickServ.c_str());
return true;
}
@@ -117,7 +118,7 @@ class CommandNSSASetHide : public CommandNSSetHide
"user@host mask (\002USERMASK\002), the services access status\n"
"(\002STATUS\002) and last quit message (\002QUIT\002).\n"
"The second parameter specifies whether the information should\n"
- "be displayed (\002OFF\002) or hidden (\002ON\002)."), NickServ->nick.c_str());
+ "be displayed (\002OFF\002) or hidden (\002ON\002)."), Config->s_NickServ.c_str());
return true;
}
@@ -138,22 +139,25 @@ class NSSetHide : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- Command *c = FindCommand(NickServ, "SET");
+ if (!nickserv)
+ throw ModuleException("NickServ is not loaded!");
+
+ Command *c = FindCommand(nickserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandnssethide);
- c = FindCommand(NickServ, "SASET");
+ c = FindCommand(nickserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandnssasethide);
}
~NSSetHide()
{
- Command *c = FindCommand(NickServ, "SET");
+ Command *c = FindCommand(nickserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandnssethide);
- c = FindCommand(NickServ, "SASET");
+ c = FindCommand(nickserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandnssasethide);
}
diff --git a/modules/core/ns_set_kill.cpp b/modules/core/ns_set_kill.cpp
index c09228992..6b3952f37 100644
--- a/modules/core/ns_set_kill.cpp
+++ b/modules/core/ns_set_kill.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "nickserv.h"
class CommandNSSetKill : public Command
{
@@ -85,7 +86,7 @@ class CommandNSSetKill : public Command
"\002IMMED\002, user's nick will be changed immediately \037without\037 being\n"
"warned first or given a chance to change their nick; please\n"
"do not use this option unless necessary. Also, your\n"
- "network's administrators may have disabled this option."), NickServ->nick.c_str());
+ "network's administrators may have disabled this option."), Config->s_NickServ.c_str());
return true;
}
@@ -117,7 +118,7 @@ class CommandNSSASetKill : public CommandNSSetKill
"\002IMMED\002, the user's nick will be changed immediately \037without\037 being\n"
"warned first or given a chance to change their nick; please\n"
"do not use this option unless necessary. Also, your\n"
- "network's administrators may have disabled this option."), NickServ->nick.c_str());
+ "network's administrators may have disabled this option."), Config->s_NickServ.c_str());
return true;
}
@@ -138,22 +139,25 @@ class NSSetKill : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- Command *c = FindCommand(NickServ, "SET");
+ if (!nickserv)
+ throw ModuleException("NickServ is not loaded!");
+
+ Command *c = FindCommand(nickserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandnssetkill);
- c = FindCommand(NickServ, "SASET");
+ c = FindCommand(nickserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandnssasetkill);
}
~NSSetKill()
{
- Command *c = FindCommand(NickServ, "SET");
+ Command *c = FindCommand(nickserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandnssetkill);
- c = FindCommand(NickServ, "SASET");
+ c = FindCommand(nickserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandnssasetkill);
}
diff --git a/modules/core/ns_set_language.cpp b/modules/core/ns_set_language.cpp
index 1497ad498..e73bc6f97 100644
--- a/modules/core/ns_set_language.cpp
+++ b/modules/core/ns_set_language.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "nickserv.h"
class CommandNSSetLanguage : public Command
{
@@ -113,22 +114,25 @@ class NSSetLanguage : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- Command *c = FindCommand(NickServ, "SET");
+ if (!nickserv)
+ throw ModuleException("NickServ is not loaded!");
+
+ Command *c = FindCommand(nickserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandnssetlanguage);
- c = FindCommand(NickServ, "SASET");
+ c = FindCommand(nickserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandnssasetlanguage);
}
~NSSetLanguage()
{
- Command *c = FindCommand(NickServ, "SET");
+ Command *c = FindCommand(nickserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandnssetlanguage);
- c = FindCommand(NickServ, "SASET");
+ c = FindCommand(nickserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandnssasetlanguage);
}
diff --git a/modules/core/ns_set_message.cpp b/modules/core/ns_set_message.cpp
index 671398b11..e842e49bd 100644
--- a/modules/core/ns_set_message.cpp
+++ b/modules/core/ns_set_message.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "nickserv.h"
class CommandNSSetMessage : public Command
{
@@ -102,22 +103,25 @@ class NSSetMessage : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- Command *c = FindCommand(NickServ, "SET");
+ if (!nickserv)
+ throw ModuleException("NickServ is not loaded!");
+
+ Command *c = FindCommand(nickserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandnssetmessage);
- c = FindCommand(NickServ, "SASET");
+ c = FindCommand(nickserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandnssasetmessage);
}
~NSSetMessage()
{
- Command *c = FindCommand(NickServ, "SET");
+ Command *c = FindCommand(nickserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandnssetmessage);
- c = FindCommand(NickServ, "SASET");
+ c = FindCommand(nickserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandnssasetmessage);
}
diff --git a/modules/core/ns_set_private.cpp b/modules/core/ns_set_private.cpp
index efcd4da09..40fe2e7c0 100644
--- a/modules/core/ns_set_private.cpp
+++ b/modules/core/ns_set_private.cpp
@@ -12,13 +12,14 @@
/*************************************************************************/
#include "module.h"
+#include "nickserv.h"
class CommandNSSetPrivate : public Command
{
public:
CommandNSSetPrivate(const Anope::string &spermission = "") : Command("PRIVATE", 2, 2, spermission)
{
- this->SetDesc(Anope::printf(_("Prevent the nickname from appearing in a \002%s%s LIST\002"), Config->UseStrictPrivMsgString.c_str(), NickServ->nick.c_str()));
+ this->SetDesc(Anope::printf(_("Prevent the nickname from appearing in a \002%s%s LIST\002"), Config->UseStrictPrivMsgString.c_str(), Config->s_NickServ.c_str()));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
@@ -55,7 +56,7 @@ class CommandNSSetPrivate : public Command
"nickname lists generated with %s's \002LIST\002 command.\n"
"(However, anyone who knows your nickname can still get\n"
"information on it using the \002INFO\002 command.)"),
- NickServ->nick.c_str(), NickServ->nick.c_str());
+ Config->s_NickServ.c_str(), Config->s_NickServ.c_str());
return true;
}
@@ -81,7 +82,7 @@ class CommandNSSASetPrivate : public CommandNSSetPrivate
"nickname lists generated with %s's \002LIST\002 command.\n"
"(However, anyone who knows the nickname can still get\n"
"information on it using the \002INFO\002 command.)"),
- NickServ->nick.c_str(), NickServ->nick.c_str());
+ Config->s_NickServ.c_str(), Config->s_NickServ.c_str());
return true;
}
@@ -102,22 +103,25 @@ class NSSetPrivate : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- Command *c = FindCommand(NickServ, "SET");
+ if (!nickserv)
+ throw ModuleException("NickServ is not loaded!");
+
+ Command *c = FindCommand(nickserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandnssetprivate);
- c = FindCommand(NickServ, "SASET");
+ c = FindCommand(nickserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandnssasetprivate);
}
~NSSetPrivate()
{
- Command *c = FindCommand(NickServ, "SET");
+ Command *c = FindCommand(nickserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandnssetprivate);
- c = FindCommand(NickServ, "SASET");
+ c = FindCommand(nickserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandnssasetprivate);
}
diff --git a/modules/core/ns_set_secure.cpp b/modules/core/ns_set_secure.cpp
index 62e7f88a9..f3e3128ac 100644
--- a/modules/core/ns_set_secure.cpp
+++ b/modules/core/ns_set_secure.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "nickserv.h"
class CommandNSSetSecure : public Command
{
@@ -56,7 +57,7 @@ class CommandNSSetSecure : public Command
"regardless of whether your address is on the access\n"
"list. However, if you are on the access list, %s\n"
"will not auto-kill you regardless of the setting of the\n"
- "\002KILL\002 option."), NickServ->nick.c_str(), NickServ->nick.c_str());
+ "\002KILL\002 option."), Config->s_NickServ.c_str(), Config->s_NickServ.c_str());
return true;
}
@@ -83,7 +84,7 @@ class CommandNSSASetSecure : public CommandNSSetSecure
"regardless of whether your address is on the access\n"
"list. However, if you are on the access list, %s\n"
"will not auto-kill you regardless of the setting of the\n"
- "\002KILL\002 option."), NickServ->nick.c_str(), NickServ->nick.c_str());
+ "\002KILL\002 option."), Config->s_NickServ.c_str(), Config->s_NickServ.c_str());
return true;
}
@@ -104,22 +105,25 @@ class NSSetSecure : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- Command *c = FindCommand(NickServ, "SET");
+ if (!nickserv)
+ throw ModuleException("NickServ is not loaded!");
+
+ Command *c = FindCommand(nickserv->Bot(), "SET");
if (c)
c->AddSubcommand(this, &commandnssetsecure);
- c = FindCommand(NickServ, "SASET");
+ c = FindCommand(nickserv->Bot(), "SASET");
if (c)
c->AddSubcommand(this, &commandnssasetsecure);
}
~NSSetSecure()
{
- Command *c = FindCommand(NickServ, "SET");
+ Command *c = FindCommand(nickserv->Bot(), "SET");
if (c)
c->DelSubcommand(&commandnssetsecure);
- c = FindCommand(NickServ, "SASET");
+ c = FindCommand(nickserv->Bot(), "SASET");
if (c)
c->DelSubcommand(&commandnssasetsecure);
}
diff --git a/modules/core/ns_status.cpp b/modules/core/ns_status.cpp
index fa04d92e2..a7710d326 100644
--- a/modules/core/ns_status.cpp
+++ b/modules/core/ns_status.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "nickserv.h"
class CommandNSStatus : public Command
{
@@ -86,7 +87,10 @@ class NSStatus : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(NickServ, &commandnsstatus);
+ if (!nickserv)
+ throw ModuleException("NickServ is not loaded!");
+
+ this->AddCommand(nickserv->Bot(), &commandnsstatus);
}
};
diff --git a/modules/core/ns_suspend.cpp b/modules/core/ns_suspend.cpp
index 41eddb6f4..1692e88fc 100644
--- a/modules/core/ns_suspend.cpp
+++ b/modules/core/ns_suspend.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "nickserv.h"
class CommandNSSuspend : public Command
{
@@ -169,8 +170,11 @@ class NSSuspend : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(NickServ, &commandnssuspend);
- this->AddCommand(NickServ, &commandnsunsuspend);
+ if (!nickserv)
+ throw ModuleException("NickServ is not loaded!");
+
+ this->AddCommand(nickserv->Bot(), &commandnssuspend);
+ this->AddCommand(nickserv->Bot(), &commandnsunsuspend);
}
};
diff --git a/modules/core/ns_update.cpp b/modules/core/ns_update.cpp
index ac7ba9a09..0146ec954 100644
--- a/modules/core/ns_update.cpp
+++ b/modules/core/ns_update.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "nickserv.h"
class CommandNSUpdate : public Command
{
@@ -26,16 +27,11 @@ class CommandNSUpdate : public Command
User *u = source.u;
NickAlias *na = findnick(u->nick);
- if (!na)
- return MOD_CONT;
-
- do_setmodes(u);
- check_memos(u);
-
na->last_realname = u->realname;
na->last_seen = Anope::CurTime;
- if (ircd->vhost)
- do_on_id(u);
+
+ FOREACH_MOD(I_OnNickUpdate, OnNickUpdate(u));
+
source.Reply(_("Status updated (memos, vhost, chmodes, flags)."), Config->s_NickServ.c_str());
return MOD_CONT;
}
@@ -60,7 +56,10 @@ class NSUpdate : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(NickServ, &commandnsupdate);
+ if (!nickserv)
+ throw ModuleException("NickServ is not loaded!");
+
+ this->AddCommand(nickserv->Bot(), &commandnsupdate);
}
};
diff --git a/modules/core/operserv.h b/modules/core/operserv.h
new file mode 100644
index 000000000..97436b789
--- /dev/null
+++ b/modules/core/operserv.h
@@ -0,0 +1,15 @@
+#ifndef OPERSERV_H
+#define OPERSERV_H
+
+class OperServService : public Service
+{
+ public:
+ OperServService(Module *m) : Service(m, "OperServ") { }
+
+ virtual BotInfo *Bot() = 0;
+};
+
+static service_reference<OperServService> operserv("OperServ");
+
+#endif // OPERSERV_H
+
diff --git a/modules/core/os_akill.cpp b/modules/core/os_akill.cpp
index a616695ce..076335840 100644
--- a/modules/core/os_akill.cpp
+++ b/modules/core/os_akill.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "operserv.h"
class AkillDelCallback : public NumberList
{
@@ -172,33 +173,49 @@ class CommandOSAKill : public Command
reason += " " + params[3];
if (!mask.empty() && !reason.empty())
{
- User *user = finduser(mask);
- if (user)
- mask = "*@" + user->host;
- unsigned int affected = 0;
- for (Anope::insensitive_map<User *>::iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
- if (Anope::Match(it->second->GetIdent() + "@" + it->second->host, mask))
- ++affected;
- float percent = static_cast<float>(affected) / static_cast<float>(UserListByNick.size()) * 100.0;
-
- if (percent > 95)
- {
+ std::pair<int, XLine *> canAdd = SGLine->CanAdd(mask, expires);
+ if (mask.find('!') != Anope::string::npos)
+ source.Reply(_("\002Reminder\002: AKILL masks cannot contain nicknames; make sure you have \002not\002 included a nick portion in your mask."));
+ else if (mask.find('@') == Anope::string::npos)
+ source.Reply(_(BAD_USERHOST_MASK));
+ else if (mask.find_first_not_of("~@.*?") == Anope::string::npos)
source.Reply(_(USERHOST_MASK_TOO_WIDE), mask.c_str());
- Log(LOG_ADMIN, u, this) << "tried to akill " << percent << "% of the network (" << affected << " users)";
- return MOD_CONT;
- }
+ else if (canAdd.first == 1)
+ source.Reply(_("\002%s\002 already exists on the AKILL list."), canAdd.second->Mask.c_str());
+ else if (canAdd.first == 2)
+ source.Reply(_("Expiry time of \002%s\002 changed."), canAdd.second->Mask.c_str());
+ else if (canAdd.first == 3)
+ source.Reply(_("\002%s\002 is already covered by %s."), mask.c_str(), canAdd.second->Mask.c_str());
+ else
+ {
+ User *user = finduser(mask);
+ if (user)
+ mask = "*@" + user->host;
+ unsigned int affected = 0;
+ for (Anope::insensitive_map<User *>::iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
+ if (Anope::Match(it->second->GetIdent() + "@" + it->second->host, mask))
+ ++affected;
+ float percent = static_cast<float>(affected) / static_cast<float>(UserListByNick.size()) * 100.0;
+
+ if (percent > 95)
+ {
+ source.Reply(_(USERHOST_MASK_TOO_WIDE), mask.c_str());
+ Log(LOG_ADMIN, u, this) << "tried to akill " << percent << "% of the network (" << affected << " users)";
+ return MOD_CONT;
+ }
- XLine *x = SGLine->Add(OperServ, u, mask, expires, reason);
+ XLine *x = SGLine->Add(mask, u->nick, expires, reason);
- if (!x)
- return MOD_CONT;
+ if (!x)
+ return MOD_CONT;
- source.Reply(_("\002%s\002 added to the AKILL list."), mask.c_str());
+ source.Reply(_("\002%s\002 added to the AKILL list."), mask.c_str());
- Log(LOG_ADMIN, u, this) << "on " << mask << " (" << reason << ") expires in " << (expires ? duration(expires - Anope::CurTime) : "never") << " [affects " << affected << " user(s) (" << percent << "%)]";
+ Log(LOG_ADMIN, u, this) << "on " << mask << " (" << reason << ") expires in " << (expires ? duration(expires - Anope::CurTime) : "never") << " [affects " << affected << " user(s) (" << percent << "%)]";
- if (readonly)
- source.Reply(_(READ_ONLY_MODE));
+ if (readonly)
+ source.Reply(_(READ_ONLY_MODE));
+ }
}
else
this->OnSyntaxError(source, "ADD");
@@ -435,7 +452,10 @@ class OSAKill : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(OperServ, &commandosakill);
+ if (!operserv)
+ throw ModuleException("OperServ is not loaded!");
+
+ this->AddCommand(operserv->Bot(), &commandosakill);
}
};
diff --git a/modules/core/os_chankill.cpp b/modules/core/os_chankill.cpp
index 9c69973a4..5e3fab915 100644
--- a/modules/core/os_chankill.cpp
+++ b/modules/core/os_chankill.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "operserv.h"
class CommandOSChanKill : public Command
{
@@ -74,7 +75,7 @@ class CommandOSChanKill : public Command
if (uc->user->HasMode(UMODE_OPER))
continue;
- SGLine->Add(OperServ, u, "*@" + uc->user->host, expires, realreason);
+ SGLine->Add("*@" + uc->user->host, u->nick, expires, realreason);
SGLine->Check(uc->user);
}
@@ -111,7 +112,10 @@ class OSChanKill : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(OperServ, &commandoschankill);
+ if (!operserv)
+ throw ModuleException("OperServ is not loaded!");
+
+ this->AddCommand(operserv->Bot(), &commandoschankill);
}
};
diff --git a/modules/core/os_chanlist.cpp b/modules/core/os_chanlist.cpp
index 8ab6d509a..b70edf35a 100644
--- a/modules/core/os_chanlist.cpp
+++ b/modules/core/os_chanlist.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "operserv.h"
class CommandOSChanList : public Command
{
@@ -97,9 +98,12 @@ class OSChanList : public Module
OSChanList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
{
this->SetAuthor("Anope");
- this->SetType(CORE);
+ this->SetType(CORE);
- this->AddCommand(OperServ, &commandoschanlist);
+ if (!operserv)
+ throw ModuleException("OperServ is not loaded!");
+
+ this->AddCommand(operserv->Bot(), &commandoschanlist);
}
};
diff --git a/modules/core/os_config.cpp b/modules/core/os_config.cpp
index f0bfb69bd..a4e129ed5 100644
--- a/modules/core/os_config.cpp
+++ b/modules/core/os_config.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "operserv.h"
class CommandOSConfig : public Command
{
@@ -224,7 +225,10 @@ class OSConfig : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(OperServ, &commandosconfig);
+ if (!operserv)
+ throw ModuleException("OperServ is not loaded!");
+
+ this->AddCommand(operserv->Bot(), &commandosconfig);
}
};
diff --git a/modules/core/os_defcon.cpp b/modules/core/os_defcon.cpp
deleted file mode 100644
index 03a8f0de4..000000000
--- a/modules/core/os_defcon.cpp
+++ /dev/null
@@ -1,496 +0,0 @@
-/* OperServ 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"
-
-void defcon_sendlvls(CommandSource &source);
-void runDefCon();
-void defconParseModeString(const Anope::string &str);
-void resetDefCon(int level);
-static Anope::string defconReverseModes(const Anope::string &modes);
-
-class DefConTimeout : public Timer
-{
- int level;
-
- public:
- DefConTimeout(int newlevel) : Timer(Config->DefConTimeOut), level(newlevel) { }
-
- void Tick(time_t)
- {
- if (Config->DefConLevel != level)
- {
- Config->DefConLevel = level;
- FOREACH_MOD(I_OnDefconLevel, OnDefconLevel(level));
- Log(OperServ, "operserv/defcon") << "Defcon level timeout, returning to level " << level;
- ircdproto->SendGlobops(OperServ, GetString(NULL, _("\002%s\002 Changed the DEFCON level to \002%d\002")).c_str(), Config->s_OperServ.c_str(), level);
-
- if (Config->GlobalOnDefcon)
- {
- if (!Config->DefConOffMessage.empty())
- oper_global("", "%s", Config->DefConOffMessage.c_str());
- else
- oper_global("", GetString(NULL, _("The Defcon Level is now at Level: \002%d\002")).c_str(), Config->DefConLevel);
-
- if (Config->GlobalOnDefconMore && Config->DefConOffMessage.empty())
- oper_global("", "%s", Config->DefconMessage.c_str());
- }
-
- runDefCon();
- }
- }
-};
-static DefConTimeout *timeout;
-
-class CommandOSDefcon : public Command
-{
- public:
- CommandOSDefcon() : Command("DEFCON", 1, 1, "operserv/defcon")
- {
- this->SetDesc(_("Manipulate the DefCon system"));
- }
-
- CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
- {
- User *u = source.u;
- const Anope::string &lvl = params[0];
-
- if (lvl.empty())
- {
- source.Reply(_("Services are now at DEFCON \002%d\002"), Config->DefConLevel);
- defcon_sendlvls(source);
- return MOD_CONT;
- }
-
- int newLevel = 0;
- try
- {
- newLevel = convertTo<int>(lvl);
- }
- catch (const ConvertException &) { }
-
- if (newLevel < 1 || newLevel > 5)
- {
- this->OnSyntaxError(source, "");
- return MOD_CONT;
- }
-
- Config->DefConLevel = newLevel;
-
- FOREACH_MOD(I_OnDefconLevel, OnDefconLevel(newLevel));
-
- if (timeout)
- {
- delete timeout;
- timeout = NULL;
- }
-
- if (Config->DefConTimeOut)
- timeout = new DefConTimeout(5);
-
- source.Reply(_("Services are now at DEFCON \002%d\002"), Config->DefConLevel);
- defcon_sendlvls(source);
- Log(LOG_ADMIN, u, this) << "to change defcon level to " << newLevel;
- ircdproto->SendGlobops(OperServ, GetString(NULL, _("\002%s\002 Changed the DEFCON level to \002%d\002")).c_str(), u->nick.c_str(), newLevel);
- /* Global notice the user what is happening. Also any Message that
- the Admin would like to add. Set in config file. */
- if (Config->GlobalOnDefcon)
- {
- if (Config->DefConLevel == 5 && !Config->DefConOffMessage.empty())
- oper_global("", "%s", Config->DefConOffMessage.c_str());
- else
- oper_global("", GetString(NULL, _("The Defcon Level is now at Level: \002%d\002")).c_str(), Config->DefConLevel);
- }
- if (Config->GlobalOnDefconMore)
- {
- if (Config->DefConOffMessage.empty() || Config->DefConLevel != 5)
- oper_global("", "%s", Config->DefconMessage.c_str());
- }
- /* Run any defcon functions, e.g. FORCE CHAN MODE */
- runDefCon();
- return MOD_CONT;
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand)
- {
- source.Reply(_("Syntax: \002DEFCON\002 [\0021\002|\0022\002|\0023\002|\0024\002|\0025\002]\n"
- "The defcon system can be used to implement a pre-defined\n"
- "set of restrictions to services useful during an attempted\n"
- "attack on the network."));
- return true;
- }
-
- void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
- {
- SyntaxError(source, "DEFCON", _("DEFCON [\0021\002|\0022\002|\0023\002|\0024\002|\0025\002]"));
- }
-};
-
-class OSDefcon : public Module
-{
- CommandOSDefcon commandosdefcon;
-
- public:
- OSDefcon(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
- {
- if (!Config->DefConLevel)
- throw ModuleException("Invalid configuration settings");
-
- this->SetAuthor("Anope");
- this->SetType(CORE);
-
- Implementation i[] = { I_OnPreUserConnect, I_OnChannelModeSet, I_OnChannelModeUnset, I_OnPreCommandRun, I_OnPreCommand, I_OnUserConnect, I_OnChannelModeAdd, I_OnChannelCreate };
- ModuleManager::Attach(i, this, 8);
-
- this->AddCommand(OperServ, &commandosdefcon);
-
- defconParseModeString(Config->DefConChanModes);
- }
-
- EventReturn OnPreUserConnect(User *u)
- {
- if (u->server->IsSynced() && CheckDefCon(DEFCON_AKILL_NEW_CLIENTS) && !u->server->IsULined())
- {
- if (CheckDefCon(DEFCON_AKILL_NEW_CLIENTS))
- {
- Log(OperServ, "operserv/defcon") << "DEFCON: adding akill for *@" << u->host;
- XLine *x = SGLine->Add(NULL, NULL, "*@" + u->host, Anope::CurTime + Config->DefConAKILL, !Config->DefConAkillReason.empty() ? Config->DefConAkillReason : "DEFCON AKILL");
- if (x)
- x->By = Config->s_OperServ;
- }
-
- if (CheckDefCon(DEFCON_NO_NEW_CLIENTS) || CheckDefCon(DEFCON_AKILL_NEW_CLIENTS))
- kill_user(Config->s_OperServ, u, Config->DefConAkillReason);
-
- return EVENT_STOP;
- }
-
- return EVENT_CONTINUE;
- }
-
- EventReturn OnChannelModeSet(Channel *c, ChannelModeName Name, const Anope::string &param)
- {
- ChannelMode *cm = ModeManager::FindChannelModeByName(Name);
-
- if (CheckDefCon(DEFCON_FORCE_CHAN_MODES) && cm && DefConModesOff.HasFlag(Name))
- {
- c->RemoveMode(OperServ, Name, param);
-
- return EVENT_STOP;
- }
-
- return EVENT_CONTINUE;
- }
-
- EventReturn OnChannelModeUnset(Channel *c, ChannelModeName Name, const Anope::string &)
- {
- ChannelMode *cm = ModeManager::FindChannelModeByName(Name);
-
- if (CheckDefCon(DEFCON_FORCE_CHAN_MODES) && cm && DefConModesOn.HasFlag(Name))
- {
- Anope::string param;
-
- if (GetDefConParam(Name, param))
- c->SetMode(OperServ, Name, param);
- else
- c->SetMode(OperServ, Name);
-
- return EVENT_STOP;
-
- }
-
- return EVENT_CONTINUE;
- }
-
- EventReturn OnPreCommandRun(User *&u, BotInfo *&bi, Anope::string &command, Anope::string &message, ChannelInfo *&ci)
- {
- if (!u->HasMode(UMODE_OPER) && (CheckDefCon(DEFCON_OPER_ONLY) || CheckDefCon(DEFCON_SILENT_OPER_ONLY)))
- {
- if (!CheckDefCon(DEFCON_SILENT_OPER_ONLY))
- u->SendMessage(bi, _("Services are in Defcon mode, Please try again later."));
-
- return EVENT_STOP;
- }
-
- return EVENT_CONTINUE;
- }
-
- EventReturn OnPreCommand(CommandSource &source, Command *command, const std::vector<Anope::string> &params)
- {
- BotInfo *service = source.owner;
- if (service == NickServ)
- {
- if (command->name.equals_ci("REGISTER") || command->name.equals_ci("GROUP"))
- {
- if (CheckDefCon(DEFCON_NO_NEW_NICKS))
- {
- source.Reply(_("Services are in Defcon mode, Please try again later."));
- return EVENT_STOP;
- }
- }
- }
- else if (ChanServ && service == ChanServ)
- {
- if (command->name.equals_ci("SET"))
- {
- if (!params.empty() && params[0].equals_ci("MLOCK") && CheckDefCon(DEFCON_NO_MLOCK_CHANGE))
- {
- source.Reply(_("Services are in Defcon mode, Please try again later."));
- return EVENT_STOP;
- }
- }
- else if (command->name.equals_ci("REGISTER"))
- {
- if (CheckDefCon(DEFCON_NO_NEW_CHANNELS))
- {
- source.Reply(_("Services are in Defcon mode, Please try again later."));
- return EVENT_STOP;
- }
- }
- }
- else if (MemoServ && service == MemoServ)
- {
- if (command->name.equals_ci("SEND") || command->name.equals_ci("SENDALL"))
- {
- if (CheckDefCon(DEFCON_NO_NEW_MEMOS))
- {
- source.Reply(_("Services are in Defcon mode, Please try again later."));
- return EVENT_STOP;
- }
- }
- }
-
- return EVENT_CONTINUE;
- }
-
- void OnUserConnect(User *u)
- {
- Session *session = findsession(u->host);
- Exception *exception = find_hostip_exception(u->host, u->ip.addr());
-
- if (CheckDefCon(DEFCON_REDUCE_SESSION) && !exception)
- {
- if (session && session->count > Config->DefConSessionLimit)
- {
- if (!Config->SessionLimitExceeded.empty())
- ircdproto->SendMessage(OperServ, u->nick, Config->SessionLimitExceeded.c_str(), u->host.c_str());
- if (!Config->SessionLimitDetailsLoc.empty())
- ircdproto->SendMessage(OperServ, u->nick, "%s", Config->SessionLimitDetailsLoc.c_str());
-
- kill_user(Config->s_OperServ, u, "Session limit exceeded");
- ++session->hits;
- if (Config->MaxSessionKill && session->hits >= Config->MaxSessionKill)
- {
- SGLine->Add(NULL, NULL, "*@" + u->host, Anope::CurTime + Config->SessionAutoKillExpiry, "Session limit exceeded");
- ircdproto->SendGlobops(OperServ, "Added a temporary AKILL for \2*@%s\2 due to excessive connections", u->host.c_str());
- }
- }
- }
- }
-
- void OnChannelModeAdd(ChannelMode *cm)
- {
- if (!Config->DefConChanModes.empty())
- {
- Anope::string modes = Config->DefConChanModes;
-
- if (modes.find(cm->ModeChar) != Anope::string::npos)
- /* New mode has been added to Anope, check to see if defcon
- * requires it
- */
- defconParseModeString(Config->DefConChanModes);
- }
- }
-
- void OnChannelCreate(Channel *c)
- {
- if (CheckDefCon(DEFCON_FORCE_CHAN_MODES))
- c->SetModes(OperServ, false, "%s", Config->DefConChanModes.c_str());
- }
-};
-
-/**
- * Send a message to the oper about which precautions are "active" for this level
- **/
-void defcon_sendlvls(CommandSource &source)
-{
- if (CheckDefCon(DEFCON_NO_NEW_CHANNELS))
- source.Reply(_("* No new channel registrations"));
- if (CheckDefCon(DEFCON_NO_NEW_NICKS))
- source.Reply(_("* No new nick registrations"));
- if (CheckDefCon(DEFCON_NO_MLOCK_CHANGE))
- source.Reply(_("* No MLOCK changes"));
- if (CheckDefCon(DEFCON_FORCE_CHAN_MODES) && !Config->DefConChanModes.empty())
- source.Reply(_("* Force Chan Modes (%s) to be set on all channels"), Config->DefConChanModes.c_str());
- if (CheckDefCon(DEFCON_REDUCE_SESSION))
- source.Reply(_("* Use the reduced session limit of %d"), Config->DefConSessionLimit);
- if (CheckDefCon(DEFCON_NO_NEW_CLIENTS))
- source.Reply(_("* Kill any NEW clients connecting"));
- if (CheckDefCon(DEFCON_OPER_ONLY))
- source.Reply(_("* Ignore any non-opers with message"));
- if (CheckDefCon(DEFCON_SILENT_OPER_ONLY))
- source.Reply(_("* Silently ignore non-opers"));
- if (CheckDefCon(DEFCON_AKILL_NEW_CLIENTS))
- source.Reply(_("* AKILL any new clients connecting"));
- if (CheckDefCon(DEFCON_NO_NEW_MEMOS))
- source.Reply(_("* No new memos sent"));
-}
-
-void runDefCon()
-{
- if (CheckDefCon(DEFCON_FORCE_CHAN_MODES))
- {
- if (!Config->DefConChanModes.empty() && !DefConModesSet)
- {
- if (Config->DefConChanModes[0] == '+' || Config->DefConChanModes[0] == '-')
- {
- Log(OperServ, "operserv/defcon") << "DEFCON: setting " << Config->DefConChanModes << " on all channels";
- DefConModesSet = true;
- MassChannelModes(OperServ, Config->DefConChanModes);
- }
- }
- }
- else
- {
- if (!Config->DefConChanModes.empty() && DefConModesSet)
- {
- if (Config->DefConChanModes[0] == '+' || Config->DefConChanModes[0] == '-')
- {
- DefConModesSet = false;
- Anope::string newmodes = defconReverseModes(Config->DefConChanModes);
- if (!newmodes.empty())
- {
- Log(OperServ, "operserv/defcon") << "DEFCON: setting " << newmodes << " on all channels";
- MassChannelModes(OperServ, newmodes);
- }
- }
- }
- }
-}
-
-/* Parse the defcon mlock mode string and set the correct global vars.
- *
- * @param str mode string to parse
- * @return 1 if accepted, 0 if failed
- */
-void defconParseModeString(const Anope::string &str)
-{
- int add = -1; /* 1 if adding, 0 if deleting, -1 if neither */
- unsigned char mode;
- ChannelMode *cm;
- ChannelModeParam *cmp;
- Anope::string modes, param;
-
- if (str.empty())
- return;
-
- spacesepstream ss(str);
-
- DefConModesOn.ClearFlags();
- DefConModesOff.ClearFlags();
- ss.GetToken(modes);
-
- /* Loop while there are modes to set */
- for (unsigned i = 0, end = modes.length(); i < end; ++i)
- {
- mode = modes[i];
-
- switch (mode)
- {
- case '+':
- add = 1;
- continue;
- case '-':
- add = 0;
- continue;
- default:
- if (add < 0)
- continue;
- }
-
- if ((cm = ModeManager::FindChannelModeByChar(mode)))
- {
- if (cm->Type == MODE_STATUS || cm->Type == MODE_LIST || !cm->CanSet(NULL))
- {
- Log() << "DefConChanModes mode character '" << mode << "' cannot be locked";
- continue;
- }
- else if (add)
- {
- DefConModesOn.SetFlag(cm->Name);
- DefConModesOff.UnsetFlag(cm->Name);
-
- if (cm->Type == MODE_PARAM)
- {
- cmp = debug_cast<ChannelModeParam *>(cm);
-
- if (!ss.GetToken(param))
- {
- Log() << "DefConChanModes mode character '" << mode << "' has no parameter while one is expected";
- continue;
- }
-
- if (!cmp->IsValid(param))
- continue;
-
- SetDefConParam(cmp->Name, param);
- }
- }
- else
- {
- if (DefConModesOn.HasFlag(cm->Name))
- {
- DefConModesOn.UnsetFlag(cm->Name);
-
- if (cm->Type == MODE_PARAM)
- UnsetDefConParam(cm->Name);
- }
- }
- }
- }
-
- /* We can't mlock +L if +l is not mlocked as well. */
- if ((cm = ModeManager::FindChannelModeByName(CMODE_REDIRECT)) && DefConModesOn.HasFlag(cm->Name) && !DefConModesOn.HasFlag(CMODE_LIMIT))
- {
- DefConModesOn.UnsetFlag(CMODE_REDIRECT);
-
- Log() << "DefConChanModes must lock mode +l as well to lock mode +L";
- }
-
- /* Some ircd we can't set NOKNOCK without INVITE */
- /* So check if we need there is a NOKNOCK MODE and that we need INVITEONLY */
- if (ircd->knock_needs_i && (cm = ModeManager::FindChannelModeByName(CMODE_NOKNOCK)) && DefConModesOn.HasFlag(cm->Name) && !DefConModesOn.HasFlag(CMODE_INVITE))
- {
- DefConModesOn.UnsetFlag(CMODE_NOKNOCK);
- Log() << "DefConChanModes must lock mode +i as well to lock mode +K";
- }
-}
-
-static Anope::string defconReverseModes(const Anope::string &modes)
-{
- if (modes.empty())
- return "";
- Anope::string newmodes;
- for (unsigned i = 0, end = modes.length(); i < end; ++i)
- {
- if (modes[i] == '+')
- newmodes += '-';
- else if (modes[i] == '-')
- newmodes += '+';
- else
- newmodes += modes[i];
- }
- return newmodes;
-}
-
-MODULE_INIT(OSDefcon)
diff --git a/modules/core/os_help.cpp b/modules/core/os_help.cpp
index b64a614b9..3694ad3ff 100644
--- a/modules/core/os_help.cpp
+++ b/modules/core/os_help.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "operserv.h"
class CommandOSHelp : public Command
{
@@ -23,18 +24,18 @@ class CommandOSHelp : public Command
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
- mod_help_cmd(OperServ, source.u, NULL, params[0]);
+ mod_help_cmd(operserv->Bot(), source.u, NULL, params[0]);
return MOD_CONT;
}
void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
{
User *u = source.u;
- source.Reply(_("%s commands:"), OperServ->nick.c_str());
- for (CommandMap::const_iterator it = OperServ->Commands.begin(), it_end = OperServ->Commands.end(); it != it_end; ++it)
+ source.Reply(_("%s commands:"), Config->s_OperServ.c_str());
+ for (CommandMap::const_iterator it = operserv->Bot()->Commands.begin(), it_end = operserv->Bot()->Commands.end(); it != it_end; ++it)
if (!Config->HidePrivilegedCommands || it->second->permission.empty() || u->HasCommand(it->second->permission))
it->second->OnServHelp(source);
- source.Reply(_("\002Notice:\002 All commands sent to %s are logged!"), OperServ->nick.c_str());
+ source.Reply(_("\002Notice:\002 All commands sent to %s are logged!"), Config->s_OperServ.c_str());
}
};
@@ -48,7 +49,10 @@ class OSHelp : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(OperServ, &commandoshelp);
+ if (!operserv)
+ throw ModuleException("OperServ is not loaded!");
+
+ this->AddCommand(operserv->Bot(), &commandoshelp);
}
};
diff --git a/modules/core/os_ignore.cpp b/modules/core/os_ignore.cpp
index ae5ea008a..cd55677cc 100644
--- a/modules/core/os_ignore.cpp
+++ b/modules/core/os_ignore.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "operserv.h"
#include "os_ignore.h"
class OSIgnoreService : public IgnoreService
@@ -292,7 +293,10 @@ class OSIgnore : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(OperServ, &commandosignore);
+ if (!operserv)
+ throw ModuleException("OperServ is not loaded!");
+
+ this->AddCommand(operserv->Bot(), &commandosignore);
Implementation i[] = { I_OnDatabaseRead, I_OnDatabaseWrite, I_OnPreCommandRun, I_OnBotPrivmsg };
ModuleManager::Attach(i, this, 4);
diff --git a/modules/core/os_jupe.cpp b/modules/core/os_jupe.cpp
index 31e301ee0..7eab7d009 100644
--- a/modules/core/os_jupe.cpp
+++ b/modules/core/os_jupe.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "operserv.h"
class CommandOSJupe : public Command
{
@@ -76,7 +77,10 @@ class OSJupe : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(OperServ, &commandosjupe);
+ if (!operserv)
+ throw ModuleException("OperServ is not loaded!");
+
+ this->AddCommand(operserv->Bot(), &commandosjupe);
}
};
diff --git a/modules/core/os_kick.cpp b/modules/core/os_kick.cpp
index d29573285..38eda21b8 100644
--- a/modules/core/os_kick.cpp
+++ b/modules/core/os_kick.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "operserv.h"
class CommandOSKick : public Command
{
@@ -46,7 +47,7 @@ class CommandOSKick : public Command
return MOD_CONT;
}
- c->Kick(OperServ, u2, "%s (%s)", u->nick.c_str(), s.c_str());
+ c->Kick(operserv->Bot(), u2, "%s (%s)", u->nick.c_str(), s.c_str());
Log(LOG_ADMIN, u, this) << "on " << u2->nick << " in " << c->name;
return MOD_CONT;
}
@@ -60,7 +61,7 @@ class CommandOSKick : public Command
"command. The kick message will have the nickname of the\n"
"IRCop sending the KICK command prepended; for example:\n"
" \n"
- "*** SpamMan has been kicked off channel #my_channel by %s (Alcan (Flood))"), OperServ->nick.c_str());
+ "*** SpamMan has been kicked off channel #my_channel by %s (Alcan (Flood))"), Config->s_OperServ.c_str());
return true;
}
@@ -80,7 +81,10 @@ class OSKick : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(OperServ, &commandoskick);
+ if (!operserv)
+ throw ModuleException("OperServ is not loaded!");
+
+ this->AddCommand(operserv->Bot(), &commandoskick);
}
};
diff --git a/modules/core/os_login.cpp b/modules/core/os_login.cpp
index fcbae9cfe..fd96165c2 100644
--- a/modules/core/os_login.cpp
+++ b/modules/core/os_login.cpp
@@ -13,13 +13,14 @@
/*************************************************************************/
#include "module.h"
+#include "operserv.h"
class CommandOSLogin : public Command
{
public:
CommandOSLogin() : Command("LOGIN", 1, 1)
{
- this->SetDesc(Anope::printf(_("Login to %s"), OperServ->nick.c_str()));
+ this->SetDesc(Anope::printf(_("Login to %s"), Config->s_OperServ.c_str()));
}
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
@@ -40,7 +41,7 @@ class CommandOSLogin : public Command
}
else
{
- Log(LOG_ADMIN, source.u, this) << "and succesfully identified to " << OperServ->nick;
+ Log(LOG_ADMIN, source.u, this) << "and succesfully identified to " << Config->s_OperServ;
source.u->Extend("os_login_password_correct");
source.Reply(_("Password accepted."));
}
@@ -54,7 +55,7 @@ class CommandOSLogin : public Command
" \n"
"Logs you in to %s so you gain Services Operator privileges.\n"
"This command may be unnecessary if your oper block is\n"
- "configured without a password."), OperServ->nick.c_str());
+ "configured without a password."), Config->s_OperServ.c_str());
return true;
}
@@ -74,7 +75,10 @@ class OSLogin : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(OperServ, &commandoslogin);
+ if (!operserv)
+ throw ModuleException("OperServ is not loaded!");
+
+ this->AddCommand(operserv->Bot(), &commandoslogin);
}
};
diff --git a/modules/core/os_main.cpp b/modules/core/os_main.cpp
new file mode 100644
index 000000000..4659fdf57
--- /dev/null
+++ b/modules/core/os_main.cpp
@@ -0,0 +1,137 @@
+/* OperServ 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 "operserv.h"
+
+static BotInfo *OperServ = NULL;
+
+class OperServBotInfo : public BotInfo
+{
+ public:
+ OperServBotInfo(const Anope::string &bnick, const Anope::string &user = "", const Anope::string &bhost = "", const Anope::string &real = "") : BotInfo(bnick, user, bhost, real) { }
+
+ void OnMessage(User *u, const Anope::string &message)
+ {
+ if (!u->HasMode(UMODE_OPER) && Config->OSOpersOnly)
+ {
+ PushLanguage("anope", u->Account() ? u->Account()->language : "");
+ u->SendMessage(OperServ, _(ACCESS_DENIED));
+ PopLanguage();
+ if (Config->WallBadOS)
+ ircdproto->SendGlobops(this, "Denied access to %s from %s!%s@%s (non-oper)", Config->s_OperServ.c_str(), u->nick.c_str(), u->GetIdent().c_str(), u->host.c_str());
+ }
+ else
+ {
+ Log(OperServ) << u->nick << ": " << message;
+ BotInfo::OnMessage(u, message);
+ }
+ }
+};
+
+class MyOperServService : public OperServService
+{
+ public:
+ MyOperServService(Module *m) : OperServService(m) { }
+
+ BotInfo *Bot()
+ {
+ return OperServ;
+ }
+};
+
+class OperServCore : public Module
+{
+ MyOperServService myoperserv;
+
+ public:
+ OperServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator), myoperserv(this)
+ {
+ this->SetAuthor("Anope");
+ this->SetType(CORE);
+ this->SetPermanent(true); // Currently, /os modunload os_main explodes for obvious reasons
+
+ Implementation i[] = { I_OnServerQuit, I_OnUserModeSet, I_OnUserModeUnset, I_OnUserConnect };
+ ModuleManager::Attach(i, this, 4);
+
+ ModuleManager::RegisterService(&this->myoperserv);
+
+ OperServ = new OperServBotInfo(Config->s_OperServ, Config->ServiceUser, Config->ServiceHost, Config->desc_OperServ);
+ OperServ->SetFlag(BI_CORE);
+
+ /* Yes, these are in this order for a reason. Most violent->least violent. */
+ XLineManager::RegisterXLineManager(SGLine = new SGLineManager());
+ XLineManager::RegisterXLineManager(SZLine = new SZLineManager());
+ XLineManager::RegisterXLineManager(SQLine = new SQLineManager());
+ XLineManager::RegisterXLineManager(SNLine = new SNLineManager());
+
+ spacesepstream coreModules(Config->OperCoreModules);
+ Anope::string module;
+ while (coreModules.GetToken(module))
+ ModuleManager::LoadModule(module, NULL);
+ }
+
+ ~OperServCore()
+ {
+ spacesepstream coreModules(Config->OperCoreModules);
+ Anope::string module;
+ while (coreModules.GetToken(module))
+ {
+ Module *m = FindModule(module);
+ if (m != NULL)
+ ModuleManager::UnloadModule(m, NULL);
+ }
+
+ delete SGLine;
+ SGLine = NULL;
+ delete SZLine;
+ SZLine = NULL;
+ delete SQLine;
+ SQLine = NULL;
+ delete SNLine;
+ SNLine = NULL;
+
+ delete OperServ;
+ }
+
+ void OnServerQuit(Server *server)
+ {
+ if (server->HasFlag(SERVER_JUPED))
+ ircdproto->SendGlobops(operserv->Bot(), "Received SQUIT for juped server %s", server->GetName().c_str());
+ }
+
+ void OnUserModeSet(User *u, UserModeName Name)
+ {
+ if (Name == UMODE_OPER)
+ {
+ if (Config->WallOper)
+ ircdproto->SendGlobops(OperServ, "\2%s\2 is now an IRC operator.", u->nick.c_str());
+ Log(OperServ) << u->nick << " is now an IRC operator";
+ }
+ }
+
+ void OnUserModeUnset(User *u, UserModeName Name)
+ {
+ if (Name == UMODE_OPER)
+ Log(OperServ) << u->nick << " is no longer an IRC operator";
+ }
+
+ void OnUserConnect(dynamic_reference<User> &u, bool &exempt)
+ {
+ if (u && !exempt)
+ XLineManager::CheckAll(u);
+ }
+};
+
+MODULE_INIT(OperServCore)
+
diff --git a/modules/core/os_mode.cpp b/modules/core/os_mode.cpp
index 476eef032..5efed5383 100644
--- a/modules/core/os_mode.cpp
+++ b/modules/core/os_mode.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "operserv.h"
class CommandOSMode : public Command
{
@@ -36,7 +37,7 @@ class CommandOSMode : public Command
source.Reply(_("Services is unable to change modes. Are your servers' U:lines configured correctly?"));
else
{
- c->SetModes(OperServ, false, modes.c_str());
+ c->SetModes(operserv->Bot(), false, modes.c_str());
Log(LOG_ADMIN, u, this) << modes << " on " << target;
}
@@ -48,10 +49,10 @@ class CommandOSMode : public Command
source.Reply(_(NICK_X_NOT_IN_USE), target.c_str());
else
{
- u2->SetModes(OperServ, "%s", modes.c_str());
+ u2->SetModes(operserv->Bot(), "%s", modes.c_str());
source.Reply(_("Changed usermodes of \002%s\002 to %s."), u2->nick.c_str(), modes.c_str());
- u2->SendMessage(OperServ, _("\002%s\002 changed your usermodes to %s."), u->nick.c_str(), modes.c_str());
+ u2->SendMessage(operserv->Bot(), _("\002%s\002 changed your usermodes to %s."), u->nick.c_str(), modes.c_str());
Log(LOG_ADMIN, u, this) << modes << " on " << target;
}
@@ -86,7 +87,10 @@ class OSMode : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(OperServ, &commandosmode);
+ if (!operserv)
+ throw ModuleException("OperServ is not loaded!");
+
+ this->AddCommand(operserv->Bot(), &commandosmode);
}
};
diff --git a/modules/core/os_modinfo.cpp b/modules/core/os_modinfo.cpp
index 2817b8f72..6634d2939 100644
--- a/modules/core/os_modinfo.cpp
+++ b/modules/core/os_modinfo.cpp
@@ -12,16 +12,14 @@
/*************************************************************************/
#include "module.h"
-
+#include "operserv.h"
class CommandOSModInfo : public Command
{
- int showModuleCmdLoaded(BotInfo *bi, const Anope::string &mod_name, CommandSource &source)
+ void showModuleCmdLoaded(BotInfo *bi, const Anope::string &mod_name, CommandSource &source)
{
if (!bi)
- return 0;
-
- int display = 0;
+ return;
for (CommandMap::iterator it = bi->Commands.begin(), it_end = bi->Commands.end(); it != it_end; ++it)
{
@@ -30,11 +28,8 @@ class CommandOSModInfo : public Command
if (c->module && c->module->name.equals_ci(mod_name) && c->service)
{
source.Reply(_("Providing command: %\002%s %s\002"), c->service->nick.c_str(), c->name.c_str());
- ++display;
}
}
-
- return display;
}
public:
@@ -52,12 +47,8 @@ class CommandOSModInfo : public Command
{
source.Reply(_("Module: \002%s\002 Version: \002%s\002 Author: \002%s\002 loaded: \002%s\002"), m->name.c_str(), !m->version.empty() ? m->version.c_str() : "?", !m->author.empty() ? m->author.c_str() : "?", do_strftime(m->created).c_str());
- showModuleCmdLoaded(HostServ, m->name, source);
- showModuleCmdLoaded(OperServ, m->name, source);
- showModuleCmdLoaded(NickServ, m->name, source);
- showModuleCmdLoaded(ChanServ, m->name, source);
- showModuleCmdLoaded(BotServ, m->name, source);
- showModuleCmdLoaded(MemoServ, m->name, source);
+ for (Anope::insensitive_map<BotInfo *>::const_iterator it = BotListByNick.begin(), it_end = BotListByNick.end(); it != it_end; ++it)
+ this->showModuleCmdLoaded(it->second, m->name, source);
}
else
source.Reply(_("No information about module \002%s\002 is available"), file.c_str());
@@ -89,7 +80,10 @@ class OSModInfo : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(OperServ, &commandosmodinfo);
+ if (!operserv)
+ throw ModuleException("OperServ is not loaded!");
+
+ this->AddCommand(operserv->Bot(), &commandosmodinfo);
}
};
diff --git a/modules/core/os_modlist.cpp b/modules/core/os_modlist.cpp
index 5d8ab6450..cb3afbd65 100644
--- a/modules/core/os_modlist.cpp
+++ b/modules/core/os_modlist.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "operserv.h"
class CommandOSModList : public Command
{
@@ -225,7 +226,10 @@ class OSModList : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(OperServ, &commandosmodlist);
+ if (!operserv)
+ throw ModuleException("OperServ is not loaded!");
+
+ this->AddCommand(operserv->Bot(), &commandosmodlist);
}
};
diff --git a/modules/core/os_modload.cpp b/modules/core/os_modload.cpp
index ed1041564..ff41b5235 100644
--- a/modules/core/os_modload.cpp
+++ b/modules/core/os_modload.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "operserv.h"
class CommandOSModLoad : public Command
{
@@ -36,7 +37,7 @@ class CommandOSModLoad : public Command
ModuleReturn status = ModuleManager::LoadModule(mname, u);
if (status == MOD_ERR_OK)
{
- ircdproto->SendGlobops(OperServ, "%s loaded module %s", u->nick.c_str(), mname.c_str());
+ ircdproto->SendGlobops(operserv->Bot(), "%s loaded module %s", u->nick.c_str(), mname.c_str());
source.Reply(_("Module \002%s\002 loaded"), mname.c_str());
/* If a user is loading this module, then the core databases have already been loaded
@@ -78,7 +79,10 @@ class OSModLoad : public Module
this->SetType(CORE);
this->SetPermanent(true);
- this->AddCommand(OperServ, &commandosmodload);
+ if (!operserv)
+ throw ModuleException("OperServ is not loaded!");
+
+ this->AddCommand(operserv->Bot(), &commandosmodload);
}
};
diff --git a/modules/core/os_modreload.cpp b/modules/core/os_modreload.cpp
index 43625d980..e721f76a9 100644
--- a/modules/core/os_modreload.cpp
+++ b/modules/core/os_modreload.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "operserv.h"
class CommandOSModReLoad : public Command
{
@@ -58,7 +59,7 @@ class CommandOSModReLoad : public Command
status = ModuleManager::LoadModule(mname, u);
if (status == MOD_ERR_OK)
{
- ircdproto->SendGlobops(OperServ, "%s reloaded module %s", u->nick.c_str(), mname.c_str());
+ ircdproto->SendGlobops(operserv->Bot(), "%s reloaded module %s", u->nick.c_str(), mname.c_str());
source.Reply(_("Module \002%s\002 reloaded"), mname.c_str());
/* If a user is loading this module, then the core databases have already been loaded
@@ -104,7 +105,10 @@ class OSModReLoad : public Module
this->SetType(CORE);
this->SetPermanent(true);
- this->AddCommand(OperServ, &commandosmodreload);
+ if (!operserv)
+ throw ModuleException("OperServ is not loaded!");
+
+ this->AddCommand(operserv->Bot(), &commandosmodreload);
}
};
diff --git a/modules/core/os_modunload.cpp b/modules/core/os_modunload.cpp
index 6a9bc9cb9..a2045c555 100644
--- a/modules/core/os_modunload.cpp
+++ b/modules/core/os_modunload.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "operserv.h"
class CommandOSModUnLoad : public Command
{
@@ -52,7 +53,7 @@ class CommandOSModUnLoad : public Command
if (status == MOD_ERR_OK)
{
source.Reply(_("Module \002%s\002 unloaded"), mname.c_str());
- ircdproto->SendGlobops(OperServ, "%s unloaded module %s", u->nick.c_str(), mname.c_str());
+ ircdproto->SendGlobops(operserv->Bot(), "%s unloaded module %s", u->nick.c_str(), mname.c_str());
}
else
source.Reply(_("Unable to remove module \002%s\002"), mname.c_str());
@@ -86,7 +87,10 @@ class OSModUnLoad : public Module
this->SetType(CORE);
this->SetPermanent(true);
- this->AddCommand(OperServ, &commandosmodunload);
+ if (!operserv)
+ throw ModuleException("OperServ is not loaded!");
+
+ this->AddCommand(operserv->Bot(), &commandosmodunload);
}
};
diff --git a/modules/core/os_news.cpp b/modules/core/os_news.cpp
index f67a2a9ca..1cf3e0edf 100644
--- a/modules/core/os_news.cpp
+++ b/modules/core/os_news.cpp
@@ -12,6 +12,8 @@
/*************************************************************************/
#include "module.h"
+#include "operserv.h"
+#include "global.h"
#define lenof(a) (sizeof(a) / sizeof(*(a)))
@@ -95,7 +97,7 @@ static void DisplayNews(User *u, NewsType Type)
if (Type == NEWS_RANDOM && i == current_news)
continue;
- u->SendMessage(Type != NEWS_OPER && Global ? Global : OperServ, msg.c_str(), do_strftime(News[i]->time).c_str(), News[i]->Text.c_str());
+ u->SendMessage(Type != NEWS_OPER && global ? global->Bot() : operserv->Bot(), msg.c_str(), do_strftime(News[i]->time).c_str(), News[i]->Text.c_str());
++displayed;
@@ -406,9 +408,12 @@ class OSNews : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(OperServ, &commandoslogonnews);
- this->AddCommand(OperServ, &commandosopernews);
- this->AddCommand(OperServ, &commandosrandomnews);
+ if (!operserv)
+ throw ModuleException("OperServ is not loaded!");
+
+ this->AddCommand(operserv->Bot(), &commandoslogonnews);
+ this->AddCommand(operserv->Bot(), &commandosopernews);
+ this->AddCommand(operserv->Bot(), &commandosrandomnews);
Implementation i[] = { I_OnUserModeSet, I_OnUserConnect, I_OnDatabaseRead, I_OnDatabaseWrite };
ModuleManager::Attach(i, this, 4);
@@ -427,10 +432,13 @@ class OSNews : public Module
DisplayNews(u, NEWS_OPER);
}
- void OnUserConnect(User *u)
+ void OnUserConnect(dynamic_reference<User> &user, bool &)
{
- DisplayNews(u, NEWS_LOGON);
- DisplayNews(u, NEWS_RANDOM);
+ if (!user)
+ return;
+
+ DisplayNews(user, NEWS_LOGON);
+ DisplayNews(user, NEWS_RANDOM);
}
EventReturn OnDatabaseRead(const std::vector<Anope::string> &params)
diff --git a/modules/core/os_noop.cpp b/modules/core/os_noop.cpp
index a3269d121..e86508d49 100644
--- a/modules/core/os_noop.cpp
+++ b/modules/core/os_noop.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "operserv.h"
class CommandOSNOOP : public Command
{
@@ -90,7 +91,10 @@ class OSNOOP : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(OperServ, &commandosnoop);
+ if (!operserv)
+ throw ModuleException("OperServ is not loaded!");
+
+ this->AddCommand(operserv->Bot(), &commandosnoop);
}
};
diff --git a/modules/core/os_oline.cpp b/modules/core/os_oline.cpp
index 8ed74ffb3..0e4835cff 100644
--- a/modules/core/os_oline.cpp
+++ b/modules/core/os_oline.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "operserv.h"
class CommandOSOLine : public Command
{
@@ -34,16 +35,16 @@ class CommandOSOLine : public Command
else if (u2 && flag[0] == '+')
{
ircdproto->SendSVSO(Config->s_OperServ, nick, flag);
- u2->SetMode(OperServ, UMODE_OPER);
- u2->SendMessage(OperServ, _("You are now an IRC Operator."));
+ u2->SetMode(operserv->Bot(), UMODE_OPER);
+ u2->SendMessage(operserv->Bot(), _("You are now an IRC Operator."));
source.Reply(_("Operflags \002%s\002 have been added for \002%s\002."), flag.c_str(), nick.c_str());
- ircdproto->SendGlobops(OperServ, "\2%s\2 used OLINE for %s", u->nick.c_str(), nick.c_str());
+ ircdproto->SendGlobops(operserv->Bot(), "\2%s\2 used OLINE for %s", u->nick.c_str(), nick.c_str());
}
else if (u2 && flag[0] == '-')
{
ircdproto->SendSVSO(Config->s_OperServ, nick, flag);
source.Reply(_("Operflags \002%s\002 have been added for \002%s\002."), flag.c_str(), nick.c_str());
- ircdproto->SendGlobops(OperServ, "\2%s\2 used OLINE for %s", u->nick.c_str(), nick.c_str());
+ ircdproto->SendGlobops(operserv->Bot(), "\2%s\2 used OLINE for %s", u->nick.c_str(), nick.c_str());
}
else
this->OnSyntaxError(source, "");
@@ -77,10 +78,13 @@ class OSOLine : public Module
if (!ircd->omode)
throw ModuleException("Your IRCd does not support OMODE.");
+ if (!operserv)
+ throw ModuleException("OperServ is not loaded!");
+
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(OperServ, &commandosoline);
+ this->AddCommand(operserv->Bot(), &commandosoline);
}
};
diff --git a/modules/core/os_quit.cpp b/modules/core/os_quit.cpp
index ed85467c4..d21ac78be 100644
--- a/modules/core/os_quit.cpp
+++ b/modules/core/os_quit.cpp
@@ -13,6 +13,7 @@
/*************************************************************************/
#include "module.h"
+#include "operserv.h"
class CommandOSQuit : public Command
{
@@ -26,9 +27,6 @@ class CommandOSQuit : public Command
{
User *u = source.u;
quitmsg = "QUIT command received from " + u->nick;
-
- if (Config->GlobalOnCycle)
- oper_global("", "%s", Config->GlobalOnCycleMessage.c_str());
quitting = true;
return MOD_CONT;
}
@@ -56,7 +54,10 @@ class OSQuit : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(OperServ, &commandosquit);
+ if (!operserv)
+ throw ModuleException("OperServ is not loaded!");
+
+ this->AddCommand(operserv->Bot(), &commandosquit);
}
};
diff --git a/modules/core/os_reload.cpp b/modules/core/os_reload.cpp
index 9b00ea8d8..08bb78444 100644
--- a/modules/core/os_reload.cpp
+++ b/modules/core/os_reload.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "operserv.h"
class CommandOSReload : public Command
{
@@ -23,16 +24,18 @@ class CommandOSReload : public Command
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
+ ServerConfig *old_config = Config;
+
try
{
- ServerConfig *newconfig = new ServerConfig();
- delete Config;
- Config = newconfig;
- FOREACH_MOD(I_OnReload, OnReload(false));
+ Config = new ServerConfig();
+ FOREACH_MOD(I_OnReload, OnReload());
+ delete old_config;
source.Reply(_("Services' configuration file has been reloaded."));
}
catch (const ConfigException &ex)
{
+ Config = old_config;
Log() << "Error reloading configuration file: " << ex.GetReason();
source.Reply(_("Error reloading confguration file: ") + ex.GetReason());
}
@@ -61,7 +64,10 @@ class OSReload : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(OperServ, &commandosreload);
+ if (!operserv)
+ throw ModuleException("OperServ is not loaded!");
+
+ this->AddCommand(operserv->Bot(), &commandosreload);
}
};
diff --git a/modules/core/os_restart.cpp b/modules/core/os_restart.cpp
index 02663e862..73c36d21e 100644
--- a/modules/core/os_restart.cpp
+++ b/modules/core/os_restart.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "operserv.h"
class CommandOSRestart : public Command
{
@@ -25,9 +26,6 @@ class CommandOSRestart : public Command
{
User *u = source.u;
quitmsg = "RESTART command received from " + u->nick;
-
- if (Config->GlobalOnCycle)
- oper_global("", "%s", Config->GlobalOnCycleMessage.c_str());
do_restart_services();
return MOD_CONT;
}
@@ -52,7 +50,10 @@ class OSRestart : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(OperServ, &commandosrestart);
+ if (!operserv)
+ throw ModuleException("OperServ is not loaded!");
+
+ this->AddCommand(operserv->Bot(), &commandosrestart);
}
};
diff --git a/modules/core/os_session.cpp b/modules/core/os_session.cpp
index 8090efe10..4a3695796 100644
--- a/modules/core/os_session.cpp
+++ b/modules/core/os_session.cpp
@@ -12,6 +12,33 @@
/*************************************************************************/
#include "module.h"
+#include "operserv.h"
+#include "os_session.h"
+
+static service_reference<SessionService> sessionservice("session");
+
+class ExpireTimer : public Timer
+{
+ public:
+ ExpireTimer() : Timer(Config->ExpireTimeout, Anope::CurTime, true) { }
+
+ void Tick(time_t)
+ {
+ if (!sessionservice)
+ return;
+ for (unsigned i = sessionservice->GetExceptions().size(); i > 0; --i)
+ {
+ Exception *e = sessionservice->GetExceptions()[i - 1];
+
+ if (!e->expires || e->expires > Anope::CurTime)
+ continue;
+ if (Config->WallExceptionExpire)
+ ircdproto->SendGlobops(operserv->Bot(), "Session exception for %s has expired.", e->mask.c_str());
+ sessionservice->DelException(e);
+ delete e;
+ }
+ }
+};
class ExceptionDelCallback : public NumberList
{
@@ -35,7 +62,7 @@ class ExceptionDelCallback : public NumberList
virtual void HandleNumber(unsigned Number)
{
- if (!Number || Number > exceptions.size())
+ if (!Number || Number > sessionservice->GetExceptions().size())
return;
++Deleted;
@@ -45,10 +72,10 @@ class ExceptionDelCallback : public NumberList
static void DoDel(CommandSource &source, unsigned index)
{
- FOREACH_MOD(I_OnExceptionDel, OnExceptionDel(source.u, exceptions[index]));
+ FOREACH_MOD(I_OnExceptionDel, OnExceptionDel(source.u, sessionservice->GetExceptions()[index]));
- delete exceptions[index];
- exceptions.erase(exceptions.begin() + index);
+ sessionservice->DelException(sessionservice->GetExceptions()[index]);
+ delete sessionservice->GetExceptions()[index];
}
};
@@ -64,7 +91,7 @@ class ExceptionListCallback : public NumberList
virtual void HandleNumber(unsigned Number)
{
- if (!Number || Number > exceptions.size())
+ if (!Number || Number > sessionservice->GetExceptions().size())
return;
if (!SentHeader)
@@ -79,10 +106,10 @@ class ExceptionListCallback : public NumberList
static void DoList(CommandSource &source, unsigned index)
{
- if (index >= exceptions.size())
+ if (index >= sessionservice->GetExceptions().size())
return;
- source.Reply(_("%3d %4d %s"), index + 1, exceptions[index]->limit, exceptions[index]->mask.c_str());
+ source.Reply(_("%3d %4d %s"), index + 1, sessionservice->GetExceptions()[index]->limit, sessionservice->GetExceptions()[index]->mask.c_str());
}
};
@@ -95,7 +122,7 @@ class ExceptionViewCallback : public ExceptionListCallback
void HandleNumber(unsigned Number)
{
- if (!Number || Number > exceptions.size())
+ if (!Number || Number > sessionservice->GetExceptions().size())
return;
if (!SentHeader)
@@ -109,12 +136,12 @@ class ExceptionViewCallback : public ExceptionListCallback
static void DoList(CommandSource &source, unsigned index)
{
- if (index >= exceptions.size())
+ if (index >= sessionservice->GetExceptions().size())
return;
- Anope::string expirebuf = expire_left(source.u->Account(), exceptions[index]->expires);
+ Anope::string expirebuf = expire_left(source.u->Account(), sessionservice->GetExceptions()[index]->expires);
- source.Reply(_("%3d. %s (by %s on %s; %s)\n " " Limit: %-4d - %s"), index + 1, exceptions[index]->mask.c_str(), !exceptions[index]->who.empty() ? exceptions[index]->who.c_str() : "<unknown>", do_strftime((exceptions[index]->time ? exceptions[index]->time : Anope::CurTime)).c_str(), expirebuf.c_str(), exceptions[index]->limit, exceptions[index]->reason.c_str());
+ source.Reply(_("%3d. %s (by %s on %s; %s)\n " " Limit: %-4d - %s"), index + 1, sessionservice->GetExceptions()[index]->mask.c_str(), !sessionservice->GetExceptions()[index]->who.empty() ? sessionservice->GetExceptions()[index]->who.c_str() : "<unknown>", do_strftime((sessionservice->GetExceptions()[index]->time ? sessionservice->GetExceptions()[index]->time : Anope::CurTime)).c_str(), expirebuf.c_str(), sessionservice->GetExceptions()[index]->limit, sessionservice->GetExceptions()[index]->reason.c_str());
}
};
@@ -139,7 +166,7 @@ class CommandOSSession : public Command
source.Reply(_("Hosts with at least \002%d\002 sessions:"), mincount);
source.Reply(_("Sessions Host"));
- for (Anope::map<Session *>::iterator it = SessionList.begin(), it_end = SessionList.end(); it != it_end; ++it)
+ for (SessionService::SessionMap::iterator it = sessionservice->GetSessions().begin(), it_end = sessionservice->GetSessions().end(); it != it_end; ++it)
{
Session *session = it->second;
@@ -154,13 +181,13 @@ class CommandOSSession : public Command
CommandReturn DoView(CommandSource &source, const std::vector<Anope::string> &params)
{
Anope::string param = params[1];
- Session *session = findsession(param);
+ Session *session = sessionservice->FindSession(param);
if (!session)
source.Reply(_("\002%s\002 not found on session list."), param.c_str());
else
{
- Exception *exception = find_host_exception(param);
+ Exception *exception = sessionservice->FindException(param);
source.Reply(_("The host \002%s\002 currently has \002%d\002 sessions with a limit of \002%d\002."), param.c_str(), session->count, exception ? exception-> limit : Config->DefSessionLimit);
}
@@ -225,7 +252,6 @@ class CommandOSException : public Command
User *u = source.u;
Anope::string mask, expiry, limitstr;
unsigned last_param = 3;
- int x;
mask = params.size() > 1 ? params[1] : "";
if (!mask.empty() && mask[0] == '+')
@@ -277,17 +303,44 @@ class CommandOSException : public Command
{
if (mask.find('!') != Anope::string::npos || mask.find('@') != Anope::string::npos)
{
- source.Reply(_("Invalid hostmask. Only real hostmasks are valid as exceptions are not matched against nicks or usernames."));
+ source.Reply(_("Invalid hostmask. Only real hostmasks are valid as sessionservice->GetExceptions() are not matched against nicks or usernames."));
return MOD_CONT;
}
- x = exception_add(u, mask, limit, reason, u->nick, expires);
+ for (std::vector<Exception *>::iterator it = sessionservice->GetExceptions().begin(), it_end = sessionservice->GetExceptions().end(); it != it_end; ++it)
+ {
+ Exception *e = *it;
+ if (e->mask.equals_ci(mask))
+ {
+ if (e->limit != limit)
+ {
+ e->limit = limit;
+ source.Reply(_("Exception for \002%s\002 has been updated to %d."), mask.c_str(), e->limit);
+ }
+ else
+ source.Reply(_("\002%s\002 already exists on the EXCEPTION list."), mask.c_str());
+ }
+ }
- if (x == 1)
+ Exception *exception = new Exception();
+ exception->mask = mask;
+ exception->limit = limit;
+ exception->reason = reason;
+ exception->time = Anope::CurTime;
+ exception->who = u->nick;
+ exception->expires = expires;
+
+ EventReturn MOD_RESULT;
+ FOREACH_RESULT(I_OnExceptionAdd, OnExceptionAdd(exception));
+ if (MOD_RESULT == EVENT_STOP)
+ delete exception;
+ else
+ {
+ sessionservice->AddException(exception);
source.Reply(_("Session limit for \002%s\002 set to \002%d\002."), mask.c_str(), limit);
-
- if (readonly)
- source.Reply(_(READ_ONLY_MODE));
+ if (readonly)
+ source.Reply(_(READ_ONLY_MODE));
+ }
}
return MOD_CONT;
@@ -310,9 +363,9 @@ class CommandOSException : public Command
}
else
{
- unsigned i = 0, end = exceptions.size();
+ unsigned i = 0, end = sessionservice->GetExceptions().size();
for (; i < end; ++i)
- if (mask.equals_ci(exceptions[i]->mask))
+ if (mask.equals_ci(sessionservice->GetExceptions()[i]->mask))
{
ExceptionDelCallback::DoDel(source, i);
source.Reply(_("\002%s\002 deleted from session-limit exception list."), mask.c_str());
@@ -348,13 +401,13 @@ class CommandOSException : public Command
}
catch (const ConvertException &) { }
- if (n1 >= 0 && n1 < exceptions.size() && n2 >= 0 && n2 < exceptions.size() && n1 != n2)
+ if (n1 >= 0 && n1 < sessionservice->GetExceptions().size() && n2 >= 0 && n2 < sessionservice->GetExceptions().size() && n1 != n2)
{
- Exception *temp = exceptions[n1];
- exceptions[n1] = exceptions[n2];
- exceptions[n2] = temp;
+ Exception *temp = sessionservice->GetExceptions()[n1];
+ sessionservice->GetExceptions()[n1] = sessionservice->GetExceptions()[n2];
+ sessionservice->GetExceptions()[n2] = temp;
- source.Reply(_("Exception for \002%s\002 (#%d) moved to position \002%d\002."), exceptions[n1]->mask.c_str(), n1 + 1, n2 + 1);
+ source.Reply(_("Exception for \002%s\002 (#%d) moved to position \002%d\002."), sessionservice->GetExceptions()[n1]->mask.c_str(), n1 + 1, n2 + 1);
if (readonly)
source.Reply(_(READ_ONLY_MODE));
@@ -367,7 +420,6 @@ class CommandOSException : public Command
CommandReturn DoList(CommandSource &source, const std::vector<Anope::string> &params)
{
- expire_exceptions();
Anope::string mask = params.size() > 1 ? params[1] : "";
if (!mask.empty() && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
@@ -379,8 +431,8 @@ class CommandOSException : public Command
{
bool SentHeader = false;
- for (unsigned i = 0, end = exceptions.size(); i < end; ++i)
- if (mask.empty() || Anope::Match(exceptions[i]->mask, mask))
+ for (unsigned i = 0, end = sessionservice->GetExceptions().size(); i < end; ++i)
+ if (mask.empty() || Anope::Match(sessionservice->GetExceptions()[i]->mask, mask))
{
if (!SentHeader)
{
@@ -401,7 +453,6 @@ class CommandOSException : public Command
CommandReturn DoView(CommandSource &source, const std::vector<Anope::string> &params)
{
- expire_exceptions();
Anope::string mask = params.size() > 1 ? params[1] : "";
if (!mask.empty() && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
@@ -413,8 +464,8 @@ class CommandOSException : public Command
{
bool SentHeader = false;
- for (unsigned i = 0, end = exceptions.size(); i < end; ++i)
- if (mask.empty() || Anope::Match(exceptions[i]->mask, mask))
+ for (unsigned i = 0, end = sessionservice->GetExceptions().size(); i < end; ++i)
+ if (mask.empty() || Anope::Match(sessionservice->GetExceptions()[i]->mask, mask))
{
if (!SentHeader)
{
@@ -431,6 +482,7 @@ class CommandOSException : public Command
return MOD_CONT;
}
+
public:
CommandOSException() : Command("EXCEPTION", 1, 5)
{
@@ -491,10 +543,10 @@ class CommandOSException : public Command
"the format of the optional \037expiry\037 parameter.\n"
"\002EXCEPTION DEL\002 removes the given mask from the exception list.\n"
"\002EXCEPTION MOVE\002 moves exception \037num\037 to \037position\037. The\n"
- "exceptions inbetween will be shifted up or down to fill the gap.\n"
+ "sessionservice->GetExceptions() inbetween will be shifted up or down to fill the gap.\n"
"\002EXCEPTION LIST\002 and \002EXCEPTION VIEW\002 show all current\n"
- "exceptions; if the optional mask is given, the list is limited\n"
- "to those exceptions matching the mask. The difference is that\n"
+ "sessionservice->GetExceptions(); if the optional mask is given, the list is limited\n"
+ "to those sessionservice->GetExceptions() matching the mask. The difference is that\n"
"\002EXCEPTION VIEW\002 is more verbose, displaying the name of the\n"
"person who added the exception, its session limit, reason, \n"
"host mask and the expiry date and time.\n"
@@ -502,7 +554,7 @@ class CommandOSException : public Command
"Note that a connecting client will \"use\" the first exception\n"
"their host matches. Large exception lists and widely matching\n"
"exception masks are likely to degrade services' performance."),
- OperServ->nick.c_str());
+ Config->s_OperServ.c_str());
return true;
}
@@ -514,17 +566,117 @@ class CommandOSException : public Command
class OSSession : public Module
{
+ SessionService ss;
+ ExpireTimer expiretimer;
CommandOSSession commandossession;
CommandOSException commandosexception;
+ void AddSession(User *u, bool exempt)
+ {
+ Session *session = sessionservice->FindSession(u->host);
+
+ if (session)
+ {
+ bool kill = false;
+ if (Config->DefSessionLimit && session->count >= Config->DefSessionLimit)
+ {
+ kill = true;
+ Exception *exception = sessionservice->FindException(u);
+ if (exception)
+ {
+ kill = false;
+ if (exception->limit && session->count >= exception->limit)
+ kill = true;
+ }
+ }
+
+ /* Previously on IRCds that send a QUIT (InspIRCD) when a user is killed, the session for a host was
+ * decremented in do_quit, which caused problems and fixed here
+ *
+ * Now, we create the user struture before calling this to fix some user tracking issues,
+ * so we must increment this here no matter what because it will either be
+ * decremented in do_kill or in do_quit - Adam
+ */
+ ++session->count;
+
+ if (kill && !exempt)
+ {
+ if (!Config->SessionLimitExceeded.empty())
+ u->SendMessage(operserv->Bot(), Config->SessionLimitExceeded.c_str(), u->host.c_str());
+ if (!Config->SessionLimitDetailsLoc.empty())
+ u->SendMessage(operserv->Bot(), "%s", Config->SessionLimitDetailsLoc.c_str());
+
+ kill_user(Config->s_OperServ, u, "Session limit exceeded");
+
+ ++session->hits;
+ if (Config->MaxSessionKill && session->hits >= Config->MaxSessionKill && SGLine)
+ {
+ const Anope::string &akillmask = "*@" + u->host;
+ const Anope::string &akillreason = "Session limit exceeded for " + u->host;
+ SGLine->Add(akillmask, Config->s_OperServ, Anope::CurTime + Config->SessionAutoKillExpiry, akillreason);
+ ircdproto->SendGlobops(operserv->Bot(), "Added a temporary AKILL for \2%s\2 due to excessive connections", akillmask.c_str());
+ }
+ }
+ }
+ else
+ {
+ session = new Session();
+ session->host = u->host;
+ session->count = 1;
+ session->hits = 0;
+
+ sessionservice->AddSession(session);
+ }
+ }
+
+ void DelSession(User *u)
+ {
+ Session *session = sessionservice->FindSession(u->host);
+ if (!session)
+ {
+ if (debug)
+ Log() << "session: Tried to delete non-existant session: " << u->host;
+ return;
+ }
+
+ if (session->count > 1)
+ {
+ --session->count;
+ return;
+ }
+
+ sessionservice->DelSession(session);
+ delete session;
+ }
+
public:
- OSSession(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
+ OSSession(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator), ss(this)
{
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(OperServ, &commandossession);
- this->AddCommand(OperServ, &commandosexception);
+ if (!operserv)
+ throw ModuleException("OperServ is not loaded!");
+
+ Implementation i[] = { I_OnUserConnect, I_OnUserLogoff };
+ ModuleManager::Attach(i, this, 2);
+
+ this->AddCommand(operserv->Bot(), &commandossession);
+ this->AddCommand(operserv->Bot(), &commandosexception);
+
+ ModuleManager::RegisterService(&this->ss);
+ }
+
+ void OnUserConnect(dynamic_reference<User> &user, bool &exempt)
+ {
+ if (user && Config->LimitSessions)
+ this->AddSession(user, exempt);
+ }
+
+ void OnUserLogoff(User *u)
+ {
+ if (Config->LimitSessions && (!u->server || !u->server->IsULined()))
+ this->DelSession(u);
}
};
diff --git a/modules/core/os_session.h b/modules/core/os_session.h
new file mode 100644
index 000000000..e08ed70fa
--- /dev/null
+++ b/modules/core/os_session.h
@@ -0,0 +1,80 @@
+#ifndef OS_SESSION_H
+#define OS_SESSION_H
+
+class SessionService : public Service
+{
+ public:
+ typedef Anope::map<Session *> SessionMap;
+ typedef std::vector<Exception *> ExceptionVector;
+ private:
+ SessionMap Sessions;
+ ExceptionVector Exceptions;
+ public:
+ SessionService(Module *m) : Service(m, "session") { }
+
+ void AddException(Exception *e)
+ {
+ this->Exceptions.push_back(e);
+ }
+
+ void DelException(Exception *e)
+ {
+ ExceptionVector::iterator it = std::find(this->Exceptions.begin(), this->Exceptions.end(), e);
+ if (it != this->Exceptions.end())
+ this->Exceptions.erase(it);
+ }
+
+ Exception *FindException(User *u)
+ {
+ for (std::vector<Exception *>::const_iterator it = this->Exceptions.begin(), it_end = this->Exceptions.end(); it != it_end; ++it)
+ {
+ Exception *e = *it;
+ if (Anope::Match(u->host, e->mask) || (u->ip() && Anope::Match(u->ip.addr(), e->mask)))
+ return e;
+ }
+ return NULL;
+ }
+
+ Exception *FindException(const Anope::string &host)
+ {
+ for (std::vector<Exception *>::const_iterator it = this->Exceptions.begin(), it_end = this->Exceptions.end(); it != it_end; ++it)
+ {
+ Exception *e = *it;
+ if (Anope::Match(host, e->mask))
+ return e;
+ }
+
+ return NULL;
+ }
+
+ ExceptionVector &GetExceptions()
+ {
+ return this->Exceptions;
+ }
+
+ void AddSession(Session *s)
+ {
+ this->Sessions[s->host] = s;
+ }
+
+ void DelSession(Session *s)
+ {
+ this->Sessions.erase(s->host);
+ }
+
+ Session *FindSession(const Anope::string &mask)
+ {
+ SessionMap::iterator it = this->Sessions.find(mask);
+ if (it != this->Sessions.end())
+ return it->second;
+ return NULL;
+ }
+
+ SessionMap &GetSessions()
+ {
+ return this->Sessions;
+ }
+};
+
+#endif
+
diff --git a/modules/core/os_set.cpp b/modules/core/os_set.cpp
index cb50aa8fe..de622537d 100644
--- a/modules/core/os_set.cpp
+++ b/modules/core/os_set.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "operserv.h"
class CommandOSSet : public Command
{
@@ -84,14 +85,14 @@ class CommandOSSet : public Command
u->isSuperAdmin = 1;
source.Reply(_("You are now a SuperAdmin"));
Log(LOG_ADMIN, u, this) << "SUPERADMIN ON";
- ircdproto->SendGlobops(OperServ, GetString(NULL, _("%s is now a Super-Admin")).c_str(), u->nick.c_str());
+ ircdproto->SendGlobops(operserv->Bot(), _("%s is now a Super-Admin"), u->nick.c_str());
}
else if (setting.equals_ci("OFF"))
{
u->isSuperAdmin = 0;
source.Reply(_("You are no longer a SuperAdmin"));
Log(LOG_ADMIN, u, this) << "SUPERADMIN OFF";
- ircdproto->SendGlobops(OperServ, GetString(NULL, _("%s is no longer a Super-Admin")).c_str(), u->nick.c_str());
+ ircdproto->SendGlobops(operserv->Bot(), _("%s is no longer a Super-Admin"), u->nick.c_str());
}
else
source.Reply(_("Setting for SuperAdmin must be \002on\002 or \002off\002 (must be enabled in services.conf)"));
@@ -206,7 +207,7 @@ class CommandOSSet : public Command
" LIST List the options"));
else if (subcommand.equals_ci("LIST"))
source.Reply(_("Syntax: \002SET LIST\n"
- "Display the various %s settings"), OperServ->nick.c_str());
+ "Display the various %s settings"), Config->s_OperServ.c_str());
else if (subcommand.equals_ci("READONLY"))
source.Reply(_("Syntax: \002SET READONLY {ON | OFF}\002\n"
" \n"
@@ -255,7 +256,10 @@ class OSSet : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(OperServ, &commandosset);
+ if (!operserv)
+ throw ModuleException("OperServ is not loaded!");
+
+ this->AddCommand(operserv->Bot(), &commandosset);
}
};
diff --git a/modules/core/os_shutdown.cpp b/modules/core/os_shutdown.cpp
index c714623af..24642f244 100644
--- a/modules/core/os_shutdown.cpp
+++ b/modules/core/os_shutdown.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "operserv.h"
class CommandOSShutdown : public Command
{
@@ -25,9 +26,6 @@ class CommandOSShutdown : public Command
{
User *u = source.u;
quitmsg = "SHUTDOWN command received from " + u->nick;
-
- if (Config->GlobalOnCycle)
- oper_global("", "%s", Config->GlobalOnCycleMessage.c_str());
shutting_down = true;
return MOD_CONT;
}
@@ -51,7 +49,10 @@ class OSShutdown : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(OperServ, &commandosshutdown);
+ if (!operserv)
+ throw ModuleException("OperServ is not loaded!");
+
+ this->AddCommand(operserv->Bot(), &commandosshutdown);
}
};
diff --git a/modules/core/os_snline.cpp b/modules/core/os_snline.cpp
index 03ec40658..8eea0dfb1 100644
--- a/modules/core/os_snline.cpp
+++ b/modules/core/os_snline.cpp
@@ -12,7 +12,7 @@
/*************************************************************************/
#include "module.h"
-#include "hashcomp.h"
+#include "operserv.h"
class SNLineDelCallback : public NumberList
{
@@ -183,35 +183,47 @@ class CommandOSSNLine : public Command
if (!mask.empty() && !reason.empty())
{
- /* Clean up the last character of the mask if it is a space
- * See bug #761
- */
- unsigned masklen = mask.length();
- if (mask[masklen - 1] == ' ')
- mask.erase(masklen - 1);
- unsigned int affected = 0;
- for (Anope::insensitive_map<User *>::iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
- if (Anope::Match(it->second->realname, mask))
- ++affected;
- float percent = static_cast<float>(affected) / static_cast<float>(UserListByNick.size()) * 100.0;
-
- if (percent > 95)
- {
+ std::pair<int, XLine *> canAdd = SNLine->CanAdd(mask, expires);
+ if (mask.find_first_not_of("*?") == Anope::string::npos)
source.Reply(_(USERHOST_MASK_TOO_WIDE), mask.c_str());
- Log(LOG_ADMIN, u, this) << "tried to SNLine " << percent << "% of the network (" << affected << " users)";
- return MOD_CONT;
- }
+ else if (canAdd.first == 1)
+ source.Reply(_("\002%s\002 already exists on the SNLINE list."), canAdd.second->Mask.c_str());
+ else if (canAdd.first == 2)
+ source.Reply(_("Expiry time of \002%s\002 changed."), canAdd.second->Mask.c_str());
+ else if (canAdd.first == 3)
+ source.Reply(_("\002%s\002 is already covered by %s."), mask.c_str(), canAdd.second->Mask.c_str());
+ else
+ {
+ /* Clean up the last character of the mask if it is a space
+ * See bug #761
+ */
+ unsigned masklen = mask.length();
+ if (mask[masklen - 1] == ' ')
+ mask.erase(masklen - 1);
+ unsigned int affected = 0;
+ for (Anope::insensitive_map<User *>::iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
+ if (Anope::Match(it->second->realname, mask))
+ ++affected;
+ float percent = static_cast<float>(affected) / static_cast<float>(UserListByNick.size()) * 100.0;
+
+ if (percent > 95)
+ {
+ source.Reply(_(USERHOST_MASK_TOO_WIDE), mask.c_str());
+ Log(LOG_ADMIN, u, this) << "tried to SNLine " << percent << "% of the network (" << affected << " users)";
+ return MOD_CONT;
+ }
- XLine *x = SNLine->Add(OperServ, u, mask, expires, reason);
+ XLine *x = SNLine->Add(mask, u->nick, expires, reason);
- if (!x)
- return MOD_CONT;
+ if (!x)
+ return MOD_CONT;
- source.Reply(_("\002%s\002 added to the SNLINE list."), mask.c_str());
- Log(LOG_ADMIN, u, this) << "on " << mask << " (" << reason << ") expires in " << (expires ? duration(expires - Anope::CurTime) : "never") << " [affects " << affected << " user(s) (" << percent << "%)]";
+ source.Reply(_("\002%s\002 added to the SNLINE list."), mask.c_str());
+ Log(LOG_ADMIN, u, this) << "on " << mask << " (" << reason << ") expires in " << (expires ? duration(expires - Anope::CurTime) : "never") << " [affects " << affected << " user(s) (" << percent << "%)]";
- if (readonly)
- source.Reply(_(READ_ONLY_MODE));
+ if (readonly)
+ source.Reply(_(READ_ONLY_MODE));
+ }
}
else
@@ -450,10 +462,13 @@ class OSSNLine : public Module
if (!ircd->snline)
throw ModuleException("Your IRCd does not support SNLine");
+ if (!operserv)
+ throw ModuleException("OperServ is not loaded!");
+
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(OperServ, &commandossnline);
+ this->AddCommand(operserv->Bot(), &commandossnline);
}
};
diff --git a/modules/core/os_sqline.cpp b/modules/core/os_sqline.cpp
index 85c42ec4c..d582945fe 100644
--- a/modules/core/os_sqline.cpp
+++ b/modules/core/os_sqline.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "operserv.h"
class SQLineDelCallback : public NumberList
{
@@ -170,28 +171,40 @@ class CommandOSSQLine : public Command
reason += " " + params[3];
if (!mask.empty() && !reason.empty())
{
- unsigned int affected = 0;
- for (Anope::insensitive_map<User *>::iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
- if (Anope::Match(it->second->nick, mask))
- ++affected;
- float percent = static_cast<float>(affected) / static_cast<float>(UserListByNick.size()) * 100.0;
-
- if (percent > 95)
- {
+ std::pair<int, XLine *> canAdd = SQLine->CanAdd(mask, expires);
+ if (mask.find_first_not_of("*") == Anope::string::npos)
source.Reply(_(USERHOST_MASK_TOO_WIDE), mask.c_str());
- Log(LOG_ADMIN, u, this) << "tried to SQLine " << percent << "% of the network (" << affected << " users)";
- return MOD_CONT;
- }
- XLine *x = SQLine->Add(OperServ, u, mask, expires, reason);
+ else if (canAdd.first == 1)
+ source.Reply(_("\002%s\002 already exists on the SQLINE list."), canAdd.second->Mask.c_str());
+ else if (canAdd.first == 2)
+ source.Reply(_("Expiry time of \002%s\002 changed."), canAdd.second->Mask.c_str());
+ else if (canAdd.first == 3)
+ source.Reply(_("\002%s\002 is already covered by %s."), mask.c_str(), canAdd.second->Mask.c_str());
+ else
+ {
+ unsigned int affected = 0;
+ for (Anope::insensitive_map<User *>::iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
+ if (Anope::Match(it->second->nick, mask))
+ ++affected;
+ float percent = static_cast<float>(affected) / static_cast<float>(UserListByNick.size()) * 100.0;
- if (!x)
- return MOD_CONT;
+ if (percent > 95)
+ {
+ source.Reply(_(USERHOST_MASK_TOO_WIDE), mask.c_str());
+ Log(LOG_ADMIN, u, this) << "tried to SQLine " << percent << "% of the network (" << affected << " users)";
+ return MOD_CONT;
+ }
+ XLine *x = SQLine->Add(mask, u->nick, expires, reason);
- source.Reply(_("\002%s\002 added to the SQLINE list."), mask.c_str());
- Log(LOG_ADMIN, u, this) << "on " << mask << " (" << reason << ") expires in " << (expires ? duration(expires - Anope::CurTime) : "never") << " [affects " << affected << " user(s) (" << percent << "%)]";
+ if (!x)
+ return MOD_CONT;
- if (readonly)
- source.Reply(_(READ_ONLY_MODE));
+ source.Reply(_("\002%s\002 added to the SQLINE list."), mask.c_str());
+ Log(LOG_ADMIN, u, this) << "on " << mask << " (" << reason << ") expires in " << (expires ? duration(expires - Anope::CurTime) : "never") << " [affects " << affected << " user(s) (" << percent << "%)]";
+
+ if (readonly)
+ source.Reply(_(READ_ONLY_MODE));
+ }
}
else
@@ -430,10 +443,13 @@ class OSSQLine : public Module
if (!ircd->sqline)
throw ModuleException("Your IRCd does not support QLines.");
+ if (!operserv)
+ throw ModuleException("OperServ is not loaded!");
+
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(OperServ, &commandossqline);
+ this->AddCommand(operserv->Bot(), &commandossqline);
}
};
diff --git a/modules/core/os_staff.cpp b/modules/core/os_staff.cpp
index f2dbc7613..2e9dce04b 100644
--- a/modules/core/os_staff.cpp
+++ b/modules/core/os_staff.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "operserv.h"
class CommandOSStaff : public Command
{
@@ -70,7 +71,10 @@ class OSStaff : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(OperServ, &commandosstaff);
+ if (!operserv)
+ throw ModuleException("OperServ is not loaded!");
+
+ this->AddCommand(operserv->Bot(), &commandosstaff);
}
};
diff --git a/modules/core/os_stats.cpp b/modules/core/os_stats.cpp
index d7680018b..acaf2e72e 100644
--- a/modules/core/os_stats.cpp
+++ b/modules/core/os_stats.cpp
@@ -12,8 +12,7 @@
/*************************************************************************/
#include "module.h"
-
-void get_operserv_stats(long *nrec, long *memuse);
+#include "operserv.h"
/**
* Count servers connected to server s
@@ -154,40 +153,6 @@ class CommandOSStats : public Command
return MOD_CONT;
}
- CommandReturn DoStatsMemory(CommandSource &source)
- {
- long count, mem;
-
- source.Reply(_("Bytes read : %5d kB"), TotalRead / 1024);
- source.Reply(_("Bytes written : %5d kB"), TotalWritten / 1024);
-
- get_user_stats(count, mem);
- source.Reply(_("User : \002%6d\002 records, \002%5d\002 kB"), count, (mem + 512) / 1024);
- get_channel_stats(&count, &mem);
- source.Reply(_("Channel : \002%6d\002 records, \002%5d\002 kB"), count, (mem + 512) / 1024);
- get_core_stats(count, mem);
- source.Reply(_("NS Groups : \002%6d\002 records, \002%5d\002 kB"), count, (mem + 512) / 1024);
- get_aliases_stats(count, mem);
- source.Reply(_("NS Aliases : \002%6d\002 records, \002%5d\002 kB"), count, (mem + 512) / 1024);
- get_chanserv_stats(&count, &mem);
- source.Reply(_("ChanServ : \002%6d\002 records, \002%5d\002 kB"), count, (mem + 512) / 1024);
- if (!Config->s_BotServ.empty())
- {
- get_botserv_stats(&count, &mem);
- source.Reply(_("BotServ : \002%6d\002 records, \002%5d\002 kB"), count, (mem + 512) / 1024);
- }
- if (!Config->s_HostServ.empty())
- {
- get_hostserv_stats(&count, &mem);
- source.Reply(_("HostServ : \002%6d\002 records, \002%5d\002 kB"), count, (mem + 512) / 1024);
- }
- get_operserv_stats(&count, &mem);
- source.Reply(_("OperServ : \002%6d\002 records, \002%5d\002 kB"), count, (mem + 512) / 1024);
- get_session_stats(count, mem);
- source.Reply(_("Sessions : \002%6d\002 records, \002%5d\002 kB"), count, (mem + 512) / 1024);
-
- return MOD_CONT;
- }
public:
CommandOSStats() : Command("STATS", 0, 1, "operserv/stats")
{
@@ -196,33 +161,28 @@ class CommandOSStats : public Command
CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
- const Anope::string &extra = !params.empty() ? params[0] : "";
+ Anope::string extra = !params.empty() ? params[0] : "";
- if (!extra.empty() && !extra.equals_ci("ALL"))
- {
- if (extra.equals_ci("AKILL"))
- return this->DoStatsAkill(source);
- else if (extra.equals_ci("RESET"))
- return this->DoStatsReset(source);
- else if (!extra.equals_ci("MEMORY") && !extra.equals_ci("UPLINK"))
- source.Reply(_("Unknown STATS option \002%s\002."), extra.c_str());
- }
+ if (extra.equals_ci("ALL"))
+ extra.clear();
- if (extra.empty() || (!extra.equals_ci("MEMORY") && !extra.equals_ci("UPLINK")))
+ if (extra.empty() || extra.equals_ci("AKILL"))
+ return this->DoStatsAkill(source);
+ else if (extra.equals_ci("RESET"))
+ return this->DoStatsReset(source);
+ else if (extra.empty() || extra.equals_ci("UPTIME"))
this->DoStatsUptime(source);
-
- if (!extra.empty() && (extra.equals_ci("ALL") || extra.equals_ci("UPLINK")))
+ else if (extra.empty() || extra.equals_ci("UPLINK"))
this->DoStatsUplink(source);
-
- if (!extra.empty() && (extra.equals_ci("ALL") || extra.equals_ci("MEMORY")))
- this->DoStatsMemory(source);
+ else if (!extra.equals_ci("UPLINK"))
+ source.Reply(_("Unknown STATS option \002%s\002."), extra.c_str());
return MOD_CONT;
}
bool OnHelp(CommandSource &source, const Anope::string &subcommand)
{
- source.Reply(_("Syntax: \002STATS [AKILL | ALL | RESET | MEMORY | UPLINK]\002\n"
+ source.Reply(_("Syntax: \002STATS [AKILL | ALL | RESET | UPLINK]\002\n"
" \n"
"Without any option, shows the current number of users and\n"
"IRCops online (excluding Services), the highest number of\n"
@@ -235,10 +195,6 @@ class CommandOSStats : public Command
"The \002RESET\002 option currently resets the maximum user count\n"
"to the number of users currently present on the network.\n"
" \n"
- "The \002MEMORY\002 option displays information on the memory\n"
- "usage of Services. Using this option can freeze Services for\n"
- "a short period of time on large networks; don't overuse it!\n"
- " \n"
"The \002UPLINK\002 option displays information about the current\n"
"server Anope uses as an uplink to the network.\n"
" \n"
@@ -258,93 +214,11 @@ class OSStats : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(OperServ, &commandosstats);
- }
-};
-
-void get_operserv_stats(long *nrec, long *memuse)
-{
- unsigned i, end;
- long mem = 0, count = 0, mem2 = 0, count2 = 0;
- XLine *x;
-
- end = SGLine->GetCount();
- count += end;
- mem += end * sizeof(XLine);
-
- for (i = 0; i < end; ++i)
- {
- x = SGLine->GetEntry(i);
-
- mem += x->GetNick().length() + 1;
- mem += x->GetUser().length() + 1;
- mem += x->GetHost().length() + 1;
- mem += x->Mask.length() + 1;
- mem += x->By.length() + 1;
- mem += x->Reason.length() + 1;
- }
-
- if (ircd->snline)
- {
- end = SNLine->GetCount();
- count += end;
- mem += end * sizeof(XLine);
-
- for (i = 0; i < end; ++i)
- {
- x = SNLine->GetEntry(i);
-
- mem += x->GetNick().length() + 1;
- mem += x->GetUser().length() + 1;
- mem += x->GetHost().length() + 1;
- mem += x->Mask.length() + 1;
- mem += x->By.length() + 1;
- mem += x->Reason.length() + 1;
- }
- }
- if (ircd->sqline)
- {
- end = SQLine->GetCount();
- count += end;
- mem += end * sizeof(XLine);
-
- for (i = 0; i < end; ++i)
- {
- x = SQLine->GetEntry(i);
-
- mem += x->GetNick().length() + 1;
- mem += x->GetUser().length() + 1;
- mem += x->GetHost().length() + 1;
- mem += x->Mask.length() + 1;
- mem += x->By.length() + 1;
- mem += x->Reason.length() + 1;
- }
- }
- if (ircd->szline)
- {
- end = SZLine->GetCount();
- count += end;
- mem += end * sizeof(XLine);
-
- for (i = 0; i < end; ++i)
- {
- x = SZLine->GetEntry(i);
+ if (!operserv)
+ throw ModuleException("OperServ is not loaded!");
- mem += x->GetNick().length() + 1;
- mem += x->GetUser().length() + 1;
- mem += x->GetHost().length() + 1;
- mem += x->Mask.length() + 1;
- mem += x->By.length() + 1;
- mem += x->Reason.length() + 1;
- }
+ this->AddCommand(operserv->Bot(), &commandosstats);
}
-
- get_exception_stats(count2, mem2);
- count += count2;
- mem += mem2;
-
- *nrec = count;
- *memuse = mem;
-}
+};
MODULE_INIT(OSStats)
diff --git a/modules/core/os_svsnick.cpp b/modules/core/os_svsnick.cpp
index 9465f84d2..be8a21729 100644
--- a/modules/core/os_svsnick.cpp
+++ b/modules/core/os_svsnick.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "operserv.h"
class CommandOSSVSNick : public Command
{
@@ -30,7 +31,7 @@ class CommandOSSVSNick : public Command
NickAlias *na;
- /* Truncate long nicknames to NICKMAX-2 characters */
+ /* Truncate long nicknames to Config->NickLen characters */
if (newnick.length() > Config->NickLen)
{
source.Reply(_("Nick \002%s\002 was truncated to %d characters."), newnick.c_str(), Config->NickLen, newnick.c_str());
@@ -60,7 +61,7 @@ class CommandOSSVSNick : public Command
else
{
source.Reply(_("The nick \002%s\002 is now being changed to \002%s\002."), nick.c_str(), newnick.c_str());
- ircdproto->SendGlobops(OperServ, "%s used SVSNICK to change %s to %s", u->nick.c_str(), nick.c_str(), newnick.c_str());
+ ircdproto->SendGlobops(operserv->Bot(), "%s used SVSNICK to change %s to %s", u->nick.c_str(), nick.c_str(), newnick.c_str());
ircdproto->SendForceNickChange(u2, newnick, Anope::CurTime);
}
return MOD_CONT;
@@ -90,10 +91,13 @@ class OSSVSNick : public Module
if (!ircd->svsnick)
throw ModuleException("Your IRCd does not support SVSNICK");
+ if (!operserv)
+ throw ModuleException("OperServ is not loaded!");
+
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(OperServ, &commandossvsnick);
+ this->AddCommand(operserv->Bot(), &commandossvsnick);
}
};
diff --git a/modules/core/os_szline.cpp b/modules/core/os_szline.cpp
index 4274e94f9..d8a4f6283 100644
--- a/modules/core/os_szline.cpp
+++ b/modules/core/os_szline.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "operserv.h"
class SZLineDelCallback : public NumberList
{
@@ -170,32 +171,46 @@ class CommandOSSZLine : public Command
reason += " " + params[3];
if (!mask.empty() && !reason.empty())
{
- User *user = finduser(mask);
- if (user && user->ip())
- mask = user->ip.addr();
- unsigned int affected = 0;
- for (Anope::insensitive_map<User *>::iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
- if (it->second->ip() && Anope::Match(it->second->ip.addr(), mask))
- ++affected;
- float percent = static_cast<float>(affected) / static_cast<float>(UserListByNick.size()) * 100.0;
-
- if (percent > 95)
- {
+ std::pair<int, XLine *> canAdd = SZLine->CanAdd(mask, expires);
+ if (mask.find('!') != Anope::string::npos || mask.find('@') != Anope::string::npos)
+ source.Reply(_("You can only add IP masks to the SZLINE list."));
+ else if (mask.find_first_not_of("*?") == Anope::string::npos)
source.Reply(_(USERHOST_MASK_TOO_WIDE), mask.c_str());
- Log(LOG_ADMIN, u, this) << "tried to SZLine " << percent << "% of the network (" << affected << " users)";
- return MOD_CONT;
- }
+ else if (canAdd.first == 1)
+ source.Reply(_("\002%s\002 already exists on the SZLINE list."), canAdd.second->Mask.c_str());
+ else if (canAdd.first == 2)
+ source.Reply(_("Expiry time of \002%s\002 changed."), canAdd.second->Mask.c_str());
+ else if (canAdd.first == 3)
+ source.Reply(_("\002%s\002 is already covered by %s."), mask.c_str(), canAdd.second->Mask.c_str());
+ else
+ {
+ User *user = finduser(mask);
+ if (user && user->ip())
+ mask = user->ip.addr();
+ unsigned int affected = 0;
+ for (Anope::insensitive_map<User *>::iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
+ if (it->second->ip() && Anope::Match(it->second->ip.addr(), mask))
+ ++affected;
+ float percent = static_cast<float>(affected) / static_cast<float>(UserListByNick.size()) * 100.0;
+
+ if (percent > 95)
+ {
+ source.Reply(_(USERHOST_MASK_TOO_WIDE), mask.c_str());
+ Log(LOG_ADMIN, u, this) << "tried to SZLine " << percent << "% of the network (" << affected << " users)";
+ return MOD_CONT;
+ }
- XLine *x = SZLine->Add(OperServ, u, mask, expires, reason);
+ XLine *x = SZLine->Add(mask, u->nick, expires, reason);
- if (!x)
- return MOD_CONT;
+ if (!x)
+ return MOD_CONT;
- source.Reply(_("\002%s\002 added to the SZLINE list."), mask.c_str());
- Log(LOG_ADMIN, u, this) << "on " << mask << " (" << reason << ") expires in " << (expires ? duration(expires - Anope::CurTime) : "never") << " [affects " << affected << " user(s) (" << percent << "%)]";
+ source.Reply(_("\002%s\002 added to the SZLINE list."), mask.c_str());
+ Log(LOG_ADMIN, u, this) << "on " << mask << " (" << reason << ") expires in " << (expires ? duration(expires - Anope::CurTime) : "never") << " [affects " << affected << " user(s) (" << percent << "%)]";
- if (readonly)
- source.Reply(_(READ_ONLY_MODE));
+ if (readonly)
+ source.Reply(_(READ_ONLY_MODE));
+ }
}
else
@@ -430,10 +445,13 @@ class OSSZLine : public Module
if (!ircd->szline)
throw ModuleException("Your IRCd does not support ZLINEs");
+ if (!operserv)
+ throw ModuleException("OperServ is not loaded!");
+
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(OperServ, &commandosszline);
+ this->AddCommand(operserv->Bot(), &commandosszline);
}
};
diff --git a/modules/core/os_update.cpp b/modules/core/os_update.cpp
index 094f3570d..8a1e10c68 100644
--- a/modules/core/os_update.cpp
+++ b/modules/core/os_update.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "operserv.h"
class CommandOSUpdate : public Command
{
@@ -48,7 +49,10 @@ class OSUpdate : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(OperServ, &commandosupdate);
+ if (!operserv)
+ throw ModuleException("OperServ is not loaded!");
+
+ this->AddCommand(operserv->Bot(), &commandosupdate);
}
};
diff --git a/modules/core/os_userlist.cpp b/modules/core/os_userlist.cpp
index a511fbf25..1b219214d 100644
--- a/modules/core/os_userlist.cpp
+++ b/modules/core/os_userlist.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "operserv.h"
class CommandOSUserList : public Command
{
@@ -100,7 +101,10 @@ class OSUserList : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
- this->AddCommand(OperServ, &commandosuserlist);
+ if (!operserv)
+ throw ModuleException("OperServ is not loaded!");
+
+ this->AddCommand(operserv->Bot(), &commandosuserlist);
}
};
diff --git a/modules/core/ss_main.cpp b/modules/core/ss_main.cpp
deleted file mode 100644
index e452f53c1..000000000
--- a/modules/core/ss_main.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/* StatServ 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"
-
-BotInfo *statserv = NULL;
-
-class CommandSSHelp : public Command
-{
- public:
- CommandSSHelp() : Command("HELP", 0, 0)
- {
- }
-
- CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
- {
- User *u = source.u;
- ircdproto->SendMessage(statserv, u->nick, "This is a test of the emergency StatServ system.");
- return MOD_CONT;
- }
-};
-
-class SSMain : public Module
-{
- CommandSSHelp commandsshelp;
-
- public:
- SSMain(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
- {
- this->SetAuthor("Anope");
- this->SetType(CORE);
- this->SetPermanent(true);
-
- statserv = findbot("StatServ");
- if (!statserv)
- {
- Log() << "Creating SS";
- statserv = new BotInfo("StatServ", Config->ServiceUser, Config->ServiceHost, "Stats Service");
- }
- Log() << "Done creating SS";
-
- this->AddCommand(statserv, &commandsshelp);
- }
-
- ~SSMain()
- {
- if (statserv)
- {
- for (CommandMap::iterator it = statserv->Commands.begin(), it_end = statserv->Commands.end(); it != it_end; ++it)
- this->DelCommand(statserv, it->second);
-
- delete statserv;
- }
- }
-};
-
-MODULE_INIT(SSMain)
diff --git a/modules/extra/cs_appendtopic.cpp b/modules/extra/cs_appendtopic.cpp
index b02717d92..dc3b40288 100644
--- a/modules/extra/cs_appendtopic.cpp
+++ b/modules/extra/cs_appendtopic.cpp
@@ -17,8 +17,7 @@
/*************************************************************************/
#include "module.h"
-
-#define AUTHOR "SGR"
+#include "chanserv.h"
/* ------------------------------------------------------------
* Name: cs_appendtopic
@@ -110,12 +109,15 @@ class CSAppendTopic : public Module
public:
CSAppendTopic(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
{
- me = this;
-
- this->SetAuthor(AUTHOR);
+ this->SetAuthor("SGR");
this->SetType(SUPPORTED);
- this->AddCommand(ChanServ, &commandcsappendtopic);
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ me = this;
+
+ this->AddCommand(chanserv->Bot(), &commandcsappendtopic);
}
};
diff --git a/modules/extra/cs_enforce.cpp b/modules/extra/cs_enforce.cpp
index 3a8e11735..6e39f33f3 100644
--- a/modules/extra/cs_enforce.cpp
+++ b/modules/extra/cs_enforce.cpp
@@ -14,6 +14,7 @@
*/
#include "module.h"
+#include "chanserv.h"
static Module *me;
@@ -217,12 +218,15 @@ class CSEnforce : public Module
public:
CSEnforce(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
{
- me = this;
-
this->SetAuthor("Anope");
this->SetType(SUPPORTED);
- this->AddCommand(ChanServ, &commandcsenforce);
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ me = this;
+
+ this->AddCommand(chanserv->Bot(), &commandcsenforce);
}
};
diff --git a/modules/extra/cs_entrymsg.cpp b/modules/extra/cs_entrymsg.cpp
index 649fd69f8..f424baede 100644
--- a/modules/extra/cs_entrymsg.cpp
+++ b/modules/extra/cs_entrymsg.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
struct EntryMsg
{
@@ -162,13 +163,16 @@ class CSEntryMessage : public Module
{
this->SetAuthor("Anope");
this->SetType(CORE);
+
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
Implementation i[] = { I_OnJoinChannel, I_OnReload, I_OnDatabaseReadMetadata, I_OnDatabaseWriteMetadata };
ModuleManager::Attach(i, this, 4);
- this->AddCommand(ChanServ, &commandentrymsg);
+ this->AddCommand(chanserv->Bot(), &commandentrymsg);
- this->OnReload(false);
+ this->OnReload();
}
void OnJoinChannel(User *u, Channel *c)
@@ -179,11 +183,11 @@ class CSEntryMessage : public Module
if (c->ci->GetExtRegular("cs_entrymsg", messages))
for (unsigned i = 0; i < messages.size(); ++i)
- u->SendMessage(whosends(c->ci), "[%s] %s", c->ci->name.c_str(), messages[i].message.c_str());
+ u->SendMessage(c->ci->WhoSends(), "[%s] %s", c->ci->name.c_str(), messages[i].message.c_str());
}
}
- void OnReload(bool)
+ void OnReload()
{
ConfigReader config;
EntryMsg::MaxEntries = config.ReadInteger("cs_entrymsg", "maxentries", "5", 0, true);
diff --git a/modules/extra/cs_set_misc.cpp b/modules/extra/cs_set_misc.cpp
index cb654a9a1..4bd7a772a 100644
--- a/modules/extra/cs_set_misc.cpp
+++ b/modules/extra/cs_set_misc.cpp
@@ -11,6 +11,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
class CommandCSSetMisc : public Command
{
@@ -77,8 +78,8 @@ class CSSetMisc : public Module
if (Commands.empty())
return;
- Command *set = FindCommand(ChanServ, "SET");
- Command *saset = FindCommand(ChanServ, "SASET");
+ Command *set = FindCommand(chanserv->Bot(), "SET");
+ Command *saset = FindCommand(chanserv->Bot(), "SASET");
if (!set && !saset)
return;
@@ -114,10 +115,13 @@ class CSSetMisc : public Module
this->SetAuthor("Anope");
this->SetType(CORE);
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
Implementation i[] = { I_OnReload, I_OnChanInfo, I_OnDatabaseWriteMetadata, I_OnDatabaseReadMetadata };
ModuleManager::Attach(i, this, 4);
- OnReload(true);
+ OnReload();
}
~CSSetMisc()
@@ -125,12 +129,12 @@ class CSSetMisc : public Module
RemoveAll();
}
- void OnReload(bool)
+ void OnReload()
{
RemoveAll();
- Command *set = FindCommand(ChanServ, "SET");
- Command *saset = FindCommand(ChanServ, "SASET");
+ Command *set = FindCommand(chanserv->Bot(), "SET");
+ Command *saset = FindCommand(chanserv->Bot(), "SASET");
if (!set && !saset)
return;
diff --git a/modules/extra/cs_tban.cpp b/modules/extra/cs_tban.cpp
index e3470504d..04d608246 100644
--- a/modules/extra/cs_tban.cpp
+++ b/modules/extra/cs_tban.cpp
@@ -16,6 +16,7 @@
/*************************************************************************/
#include "module.h"
+#include "chanserv.h"
static Module *me;
@@ -110,12 +111,15 @@ class CSTBan : public Module
public:
CSTBan(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator)
{
- me = this;
-
- this->AddCommand(ChanServ, &commandcstban);
-
this->SetAuthor("Anope");
this->SetType(SUPPORTED);
+
+ if (!chanserv)
+ throw ModuleException("ChanServ is not loaded!");
+
+ me = this;
+
+ this->AddCommand(chanserv->Bot(), &commandcstban);
}
};
diff --git a/modules/extra/db_mysql.cpp b/modules/extra/db_mysql.cpp
index 9a2c44d47..30a71c809 100644
--- a/modules/extra/db_mysql.cpp
+++ b/modules/extra/db_mysql.cpp
@@ -1,5 +1,7 @@
#include "module.h"
+#include "operserv.h"
#include "sql.h"
+#include "os_session.h"
static Anope::string ToString(const std::vector<Anope::string> &strings)
{
@@ -89,6 +91,7 @@ class DBMySQL : public Module
service_reference<SQLProvider> SQL;
public:
+ service_reference<SessionService> SessionInterface;
time_t lastwarn;
bool ro;
@@ -99,7 +102,8 @@ class DBMySQL : public Module
if (readonly && this->ro)
{
readonly = this->ro = false;
- ircdproto->SendGlobops(OperServ, "Found SQL again, going out of readonly mode...");
+ if (operserv)
+ ircdproto->SendGlobops(operserv->Bot(), "Found SQL again, going out of readonly mode...");
}
SQL->Run(&sqlinterface, query);
@@ -108,7 +112,8 @@ class DBMySQL : public Module
{
if (Anope::CurTime - Config->UpdateTimeout > lastwarn)
{
- ircdproto->SendGlobops(OperServ, "Unable to locate SQL reference, is m_mysql loaded? Going to readonly...");
+ if (operserv)
+ ircdproto->SendGlobops(operserv->Bot(), "Unable to locate SQL reference, is m_mysql loaded? Going to readonly...");
readonly = this->ro = true;
this->lastwarn = Anope::CurTime;
}
@@ -120,7 +125,7 @@ class DBMySQL : public Module
return SQL ? SQL->Escape(query) : query;
}
- DBMySQL(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator), sqlinterface(this), SQL("mysql/main")
+ DBMySQL(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator), sqlinterface(this), SQL("mysql/main"), SessionInterface("session")
{
me = this;
@@ -134,7 +139,8 @@ class DBMySQL : public Module
};
ModuleManager::Attach(i, this, 2);
- this->AddCommand(OperServ, &commandsqlsync);
+ if (operserv)
+ this->AddCommand(operserv->Bot(), &commandsqlsync);
if (uplink_server)
OnServerConnect();
@@ -542,12 +548,9 @@ class DBMySQL : public Module
time_t seton = r.Get(i, "seton").is_pos_number_only() ? convertTo<time_t>(r.Get(i, "seton")) : Anope::CurTime;
time_t expires = r.Get(i, "expires").is_pos_number_only() ? convertTo<time_t>(r.Get(i, "expires")) : Anope::CurTime;
- XLine *x = SGLine->Add(NULL, NULL, user + "@" + host, expires, reason);
+ XLine *x = SGLine->Add(user + "@" + host, by, expires, reason);
if (x)
- {
- x->By = by;
x->Created = seton;
- }
}
}
@@ -562,16 +565,13 @@ class DBMySQL : public Module
XLine *x = NULL;
if (SNLine && r.Get(i, "type").equals_cs("SNLINE"))
- x = SNLine->Add(NULL, NULL, mask, expires, reason);
+ x = SNLine->Add(mask, by, expires, reason);
else if (SQLine && r.Get(i, "type").equals_cs("SQLINE"))
- x = SQLine->Add(NULL, NULL, mask, expires, reason);
+ x = SQLine->Add(mask, by, expires, reason);
else if (SZLine && r.Get(i, "type").equals_cs("SZLINE"))
- x = SZLine->Add(NULL, NULL, mask, expires, reason);
+ x = SZLine->Add(mask, by, expires, reason);
if (x)
- {
- x->By = by;
x->Created = seton;
- }
}
r = SQL->RunQuery("SELECT * FROM `anope_os_exceptions`");
@@ -583,7 +583,16 @@ class DBMySQL : public Module
Anope::string reason = r.Get(i, "reason");
time_t expires = convertTo<time_t>(r.Get(i, "expires"));
- exception_add(NULL, mask, limit, reason, creator, expires);
+ if (SessionInterface)
+ {
+ Exception *e = new Exception();
+ e->mask = mask;
+ e->limit = limit;
+ e->who = creator;
+ e->reason = reason;
+ e->time = expires;
+ SessionInterface->AddException(e);
+ }
}
r = SQL->RunQuery("SELECT * FROM `anope_extra`");
@@ -661,7 +670,7 @@ class DBMySQL : public Module
BotInfo *service = command->service;
ChannelInfo *ci = source.ci;
- if (service == NickServ)
+ if (service->nick == Config->s_NickServ)
{
if (u->Account() && ((command->name.equals_ci("SET") && !params.empty()) || (command->name.equals_ci("SASET") && u->HasCommand("nickserv/saset") && params.size() > 1)))
{
@@ -691,7 +700,7 @@ class DBMySQL : public Module
}
}
}
- else if (service == ChanServ)
+ else if (service->nick == Config->s_ChanServ)
{
if (command->name.equals_ci("SET") && u->Account() && params.size() > 1)
{
@@ -721,7 +730,7 @@ class DBMySQL : public Module
}
}
}
- else if (service == BotServ)
+ else if (service->nick == Config->s_BotServ)
{
if (command->name.equals_ci("KICK") && params.size() > 2)
{
@@ -773,7 +782,7 @@ class DBMySQL : public Module
}
}
}
- else if (service == MemoServ)
+ else if (service->nick == Config->s_MemoServ)
{
if (command->name.equals_ci("IGNORE") && params.size() > 0)
{
@@ -1049,18 +1058,12 @@ class DBMySQL : public Module
this->RunQuery(query);
}
- void OnMemoSend(User *, NickCore *nc, Memo *m)
- {
- this->RunQuery("INSERT INTO `anope_ms_info` (receiver, flags, time, sender, text, serv) VALUES('" +
- this->Escape(nc->display) + "', '" + ToString(m->ToString()) + "', " + stringify(m->time) + ", '" +
- this->Escape(m->sender) + "', '" + this->Escape(m->text) + "', 'NICK')");
- }
-
- void OnMemoSend(User *, ChannelInfo *ci, Memo *m)
+ void OnMemoSend(const Anope::string &source, const Anope::string &target, MemoInfo *mi, Memo *m)
{
+ const Anope::string &mtype = (!target.empty() && target[0] == '#' ? "CHAN" : "NICK");
this->RunQuery("INSERT INTO `anope_ms_info` (receiver, flags, time, sender, text, serv) VALUES('" +
- this->Escape(ci->name) + "', '" + ToString(m->ToString()) + "', " + stringify(m->time) + ", '" +
- this->Escape(m->sender) + "', '" + this->Escape(m->text) + "', 'CHAN')");
+ this->Escape(target) + "', '" + ToString(m->ToString()) + "', " + stringify(m->time) + ", '" +
+ this->Escape(source) + "', '" + this->Escape(m->text) + "', '" + mtype + "')");
}
void OnMemoDel(const NickCore *nc, MemoInfo *mi, Memo *m)
@@ -1079,7 +1082,7 @@ class DBMySQL : public Module
this->RunQuery("DELETE FROM `anope_ms_info` WHERE `receiver` = '" + this->Escape(ci->name) + "'");
}
- EventReturn OnAddAkill(User *, XLine *ak)
+ EventReturn OnAddAkill(XLine *ak)
{
this->RunQuery("INSERT INTO `anope_os_akills` (user, host, xby, reason, seton, expire) VALUES('" +
this->Escape(ak->GetUser()) + "', '" + this->Escape(ak->GetHost()) + "', '" + this->Escape(ak->By) + "', '" +
@@ -1095,7 +1098,7 @@ class DBMySQL : public Module
this->RunQuery("TRUNCATE TABLE `anope_os_akills`");
}
- EventReturn OnExceptionAdd(User *, Exception *ex)
+ EventReturn OnExceptionAdd(Exception *ex)
{
this->RunQuery("INSERT INTO `anope_os_exceptions` (mask, slimit, who, reason, time, expires) VALUES('" +
this->Escape(ex->mask) + "', " + stringify(ex->limit) + ", '" + this->Escape(ex->who) + "', '" + this->Escape(ex->reason) + "', " +
@@ -1108,7 +1111,7 @@ class DBMySQL : public Module
this->RunQuery("DELETE FROM `anope_os_exceptions` WHERE `mask` = '" + this->Escape(ex->mask) + "'");
}
- EventReturn OnAddXLine(User *, XLine *x, XLineType Type)
+ EventReturn OnAddXLine(XLine *x, XLineType Type)
{
this->RunQuery(Anope::string("INSERT INTO `anope_os_xlines` (type, mask, xby, reason, seton, expire) VALUES('") +
(Type == X_SNLINE ? "SNLINE" : (Type == X_SQLINE ? "SQLINE" : "SZLINE")) + "', '" +
@@ -1216,7 +1219,7 @@ static void SaveDatabases()
{
Memo *m = nc->memos.memos[j];
- me->OnMemoSend(NULL, nc, m);
+ me->OnMemoSend(m->sender, nc->display, &nc->memos, m);
}
}
@@ -1267,35 +1270,35 @@ static void SaveDatabases()
{
Memo *m = ci->memos.memos[j];
- me->OnMemoSend(NULL, ci, m);
+ me->OnMemoSend(m->sender, ci->name, &ci->memos, m);
}
}
if (SGLine)
for (unsigned i = 0, end = SGLine->GetCount(); i < end; ++i)
- me->OnAddAkill(NULL, SGLine->GetEntry(i));
+ me->OnAddAkill(SGLine->GetEntry(i));
if (SZLine)
for (unsigned i = 0, end = SZLine->GetCount(); i < end; ++i)
- me->OnAddXLine(NULL, SZLine->GetEntry(i), X_SZLINE);
+ me->OnAddXLine(SZLine->GetEntry(i), X_SZLINE);
if (SQLine)
for (unsigned i = 0, end = SQLine->GetCount(); i < end; ++i)
- me->OnAddXLine(NULL, SQLine->GetEntry(i), X_SQLINE);
+ me->OnAddXLine(SQLine->GetEntry(i), X_SQLINE);
if (SNLine)
for (unsigned i = 0, end = SNLine->GetCount(); i < end; ++i)
- me->OnAddXLine(NULL, SNLine->GetEntry(i), X_SNLINE);
+ me->OnAddXLine(SNLine->GetEntry(i), X_SNLINE);
- for (unsigned i = 0, end = exceptions.size(); i < end; ++i)
- me->OnExceptionAdd(NULL, exceptions[i]);
+ if (me->SessionInterface)
+ for (SessionService::ExceptionVector::iterator it = me->SessionInterface->GetExceptions().begin(); it != me->SessionInterface->GetExceptions().end(); ++it)
+ me->OnExceptionAdd(*it);
}
CommandReturn CommandSQLSync::Execute(CommandSource &source, const std::vector<Anope::string> &params)
{
- User *u = source.u;
SaveDatabases();
- u->SendMessage(OperServ, _("Updating MySQL."));
+ source.Reply(_("Updating MySQL."));
return MOD_CONT;
}
diff --git a/modules/extra/hs_request.cpp b/modules/extra/hs_request.cpp
index 4978035d3..f208d72b3 100644
--- a/modules/extra/hs_request.cpp
+++ b/modules/extra/hs_request.cpp
@@ -16,6 +16,8 @@
*/
#include "module.h"
+#include "hostserv.h"
+#include "memoserv.h"
static bool HSRequestMemoUser = false;
static bool HSRequestMemoOper = false;
@@ -152,8 +154,8 @@ class CommandHSActivate : public Command
na->hostinfo.SetVhost(it->second->ident, it->second->host, u->nick, it->second->time);
FOREACH_MOD(I_OnSetVhost, OnSetVhost(na));
- if (HSRequestMemoUser)
- memo_send(source, na->nick, _("[auto memo] Your requested vHost has been approved."), 2);
+ if (HSRequestMemoUser && memoserv)
+ memoserv->Send(Config->s_HostServ, na->nick, _("[auto memo] Your requested vHost has been approved."), true);
me->SendMessage(source, _("vHost for %s has been activated"), na->nick.c_str());
Log(LOG_COMMAND, u, this, NULL) << "for " << na->nick << " for vhost " << (!it->second->ident.empty() ? it->second->ident + "@" : "") << it->second->host;
@@ -207,15 +209,15 @@ class CommandHSReject : public Command
delete it->second;
Requests.erase(it);
- if (HSRequestMemoUser)
+ if (HSRequestMemoUser && memoserv)
{
- char message[BUFSIZE];
+ Anope::string message;
if (!reason.empty())
- snprintf(message, sizeof(message), _("[auto memo] Your requested vHost has been rejected. Reason: %s"), reason.c_str());
+ message = Anope::printf(_("[auto memo] Your requested vHost has been rejected. Reason: %s"), reason.c_str());
else
- snprintf(message, sizeof(message), "%s", _("[auto memo] Your requested vHost has been rejected."));
+ message = _("[auto memo] Your requested vHost has been rejected.");
- memo_send(source, nick, message, 2);
+ memoserv->Send(Config->s_HostServ, nick, message, true);
}
me->SendMessage(source, _("vHost for %s has been rejected"), nick.c_str());
@@ -312,18 +314,21 @@ class HSRequest : public Module
{
me = this;
- this->AddCommand(HostServ, &commandhsrequest);
- this->AddCommand(HostServ, &commandhsactive);
- this->AddCommand(HostServ, &commandhsreject);
- this->AddCommand(HostServ, &commandhswaiting);
+ if (!hostserv)
+ throw ModuleException("HostServ is not loaded!");
+
+ this->AddCommand(hostserv->Bot(), &commandhsrequest);
+ this->AddCommand(hostserv->Bot(), &commandhsactive);
+ this->AddCommand(hostserv->Bot(), &commandhsreject);
+ this->AddCommand(hostserv->Bot(), &commandhswaiting);
this->SetAuthor("Anope");
this->SetType(SUPPORTED);
- this->OnReload(false);
-
Implementation i[] = { I_OnPreCommand, I_OnDatabaseRead, I_OnDatabaseWrite, I_OnReload };
ModuleManager::Attach(i, this, 4);
+
+ this->OnReload();
}
~HSRequest()
@@ -339,7 +344,7 @@ class HSRequest : public Module
EventReturn OnPreCommand(CommandSource &source, Command *command, const std::vector<Anope::string> &params)
{
BotInfo *service = source.owner;
- if (service == HostServ)
+ if (service->nick == Config->s_HostServ)
{
if (command->name.equals_ci("LIST"))
{
@@ -348,7 +353,7 @@ class HSRequest : public Module
if (!key.empty() && key.equals_ci("+req"))
{
std::vector<Anope::string> emptyParams;
- Command *c = FindCommand(HostServ, "WAITING");
+ Command *c = FindCommand(hostserv->Bot(), "WAITING");
if (!c)
throw CoreException("No waiting command?");
c->Execute(source, emptyParams);
@@ -356,7 +361,7 @@ class HSRequest : public Module
}
}
}
- else if (service == NickServ)
+ else if (service->nick == Config->s_NickServ)
{
if (command->name.equals_ci("DROP"))
{
@@ -402,7 +407,7 @@ class HSRequest : public Module
}
}
- void OnReload(bool)
+ void OnReload()
{
ConfigReader config;
HSRequestMemoUser = config.ReadFlag("hs_request", "memouser", "no", 0);
@@ -422,7 +427,7 @@ void req_send_memos(CommandSource &source, const Anope::string &vIdent, const An
else
host = vHost;
- if (HSRequestMemoOper == 1)
+ if (HSRequestMemoOper == 1 && memoserv)
for (unsigned i = 0; i < Config->Opers.size(); ++i)
{
Oper *o = Config->Opers[i];
@@ -431,9 +436,9 @@ void req_send_memos(CommandSource &source, const Anope::string &vIdent, const An
if (!na)
continue;
- char message[BUFSIZE];
- snprintf(message, sizeof(message), _("[auto memo] vHost \002%s\002 has been requested."), host.c_str());
- memo_send(source, na->nick, message, 2);
+ Anope::string message = Anope::printf(_("[auto memo] vHost \002%s\002 has been requested by %s."), host.c_str(), source.u->GetMask().c_str());
+
+ memoserv->Send(Config->s_HostServ, na->nick, message, true);
}
}
diff --git a/modules/extra/m_alias.cpp b/modules/extra/m_alias.cpp
index c5f52bef2..025a53df0 100644
--- a/modules/extra/m_alias.cpp
+++ b/modules/extra/m_alias.cpp
@@ -6,6 +6,7 @@
*/
#include "module.h"
+#include "chanserv.h"
struct CommandAlias
{
@@ -26,10 +27,10 @@ class ModuleAlias : public Module
Implementation i[] = { I_OnReload, I_OnPreCommandRun, I_OnBotFantasy };
ModuleManager::Attach(i, this, 3);
- OnReload(false);
+ OnReload();
}
- void OnReload(bool)
+ void OnReload()
{
ConfigReader config;
@@ -102,10 +103,10 @@ class ModuleAlias : public Module
BotInfo *target = findbot(alias.target_client);
if (!target)
- target = ChanServ;
+ target = chanserv->Bot();
Anope::string full_message = alias.target_command;
- if (target == ChanServ || target == BotServ)
+ if (target == chanserv->Bot() || target->nick == Config->s_BotServ)
{
Command *target_c = FindCommand(target, alias.target_command);
if (target_c && !target_c->HasFlag(CFLAG_STRIP_CHANNEL))
diff --git a/modules/extra/m_dnsbl.cpp b/modules/extra/m_dnsbl.cpp
index 5c88e75b5..f2572e694 100644
--- a/modules/extra/m_dnsbl.cpp
+++ b/modules/extra/m_dnsbl.cpp
@@ -6,10 +6,11 @@
*/
#include "module.h"
+#include "operserv.h"
struct FakeAkill : public Command
{
- FakeAkill() : Command("AKILL", 0, 0) { this->service = OperServ; }
+ FakeAkill() : Command("AKILL", 0, 0) { this->service = findbot(Config->s_OperServ); }
CommandReturn Execute(CommandSource &, const std::vector<Anope::string> &) { return MOD_CONT; }
} fake_akill;
@@ -61,18 +62,18 @@ class DNSBLResolver : public DNSRequest
reason = reason.replace_all_cs("%N", Config->NetworkName);
XLine *x = NULL;
- if (this->add_to_akill && SGLine && (x = SGLine->Add(NULL, NULL, Anope::string("*@") + user->host, Anope::CurTime + this->blacklist.bantime, reason)))
+ if (this->add_to_akill && SGLine && (x = SGLine->Add(Anope::string("*@") + user->host, Config->s_OperServ, Anope::CurTime + this->blacklist.bantime, reason)))
{
- Log(LOG_COMMAND, OperServ, &fake_akill) << "for " << user->GetMask() << " (Listed in " << this->blacklist.name << ")";
+ Log(LOG_COMMAND, operserv->Bot(), &fake_akill) << "for " << user->GetMask() << " (Listed in " << this->blacklist.name << ")";
/* If AkillOnAdd is disabled send it anyway, noone wants bots around... */
if (!Config->AkillOnAdd)
- ircdproto->SendAkill(*user, x);
+ ircdproto->SendAkill(user, x);
}
else
{
- Log(OperServ) << "DNSBL: " << user->GetMask() << " appears in " << this->blacklist.name;
- XLine xline(Anope::string("*@") + user->host, OperServ ? OperServ->nick : "OperServ", Anope::CurTime + this->blacklist.bantime, reason);
- ircdproto->SendAkill(*user, &xline);
+ Log(operserv->Bot()) << "DNSBL: " << user->GetMask() << " appears in " << this->blacklist.name;
+ XLine xline(Anope::string("*@") + user->host, Config->s_OperServ, Anope::CurTime + this->blacklist.bantime, reason);
+ ircdproto->SendAkill(user, &xline);
}
}
};
@@ -90,13 +91,13 @@ class ModuleDNSBL : public Module
this->SetAuthor("Anope");
this->SetType(SUPPORTED);
- OnReload(false);
-
- Implementation i[] = { I_OnReload, I_OnPreUserConnect };
+ Implementation i[] = { I_OnReload, I_OnUserConnect };
ModuleManager::Attach(i, this, 2);
+
+ OnReload();
}
- void OnReload(bool)
+ void OnReload()
{
ConfigReader config;
@@ -127,17 +128,18 @@ class ModuleDNSBL : public Module
}
}
- EventReturn OnPreUserConnect(User *u)
+ void OnUserConnect(dynamic_reference<User> &user, bool &exempt)
{
- if (!this->check_on_connect && !Me->IsSynced())
- return EVENT_CONTINUE;
- if (!this->check_on_netburst && !u->server->IsSynced())
- return EVENT_CONTINUE;
+ if (exempt || !user || (!this->check_on_connect && !Me->IsSynced()))
+ return;
+
+ if (!this->check_on_netburst && !user->server->IsSynced())
+ return;
/* At this time we only support IPv4 */
- if (u->ip.sa.sa_family != AF_INET)
- return EVENT_CONTINUE;
+ if (user->ip.sa.sa_family != AF_INET)
+ return;
- unsigned long ip = u->ip.sa4.sin_addr.s_addr;
+ unsigned long ip = user->ip.sa4.sin_addr.s_addr;
unsigned long reverse_ip = ((ip & 0xFF) << 24) | ((ip & 0xFF00) << 8) | ((ip & 0xFF0000) >> 8) | ((ip & 0xFF000000) >> 24);
sockaddrs user_ip;
@@ -151,7 +153,7 @@ class ModuleDNSBL : public Module
try
{
Anope::string dnsbl_host = user_ip.addr() + "." + b.name;
- DNSBLResolver *res = new DNSBLResolver(this, u, b, dnsbl_host, this->add_to_akill);
+ DNSBLResolver *res = new DNSBLResolver(this, user, b, dnsbl_host, this->add_to_akill);
res->Process();
}
catch (const SocketException &ex)
@@ -160,7 +162,7 @@ class ModuleDNSBL : public Module
}
}
- return EVENT_CONTINUE;
+ return;
}
};
diff --git a/modules/extra/m_helpchan.cpp b/modules/extra/m_helpchan.cpp
index 028e5e332..90a33ca79 100644
--- a/modules/extra/m_helpchan.cpp
+++ b/modules/extra/m_helpchan.cpp
@@ -6,6 +6,7 @@
*/
#include "module.h"
+#include "operserv.h"
class HelpChannel : public Module
{
@@ -20,23 +21,23 @@ class HelpChannel : public Module
Implementation i[] = { I_OnChannelModeSet, I_OnReload };
ModuleManager::Attach(i, this, 2);
- OnReload(true);
+ OnReload();
}
EventReturn OnChannelModeSet(Channel *c, ChannelModeName Name, const Anope::string &param)
{
- if (Name == CMODE_OP && c && c->ci && c->name.equals_ci(this->HelpChan))
+ if (Name == CMODE_OP && operserv && c && c->ci && c->name.equals_ci(this->HelpChan))
{
User *u = finduser(param);
if (u && check_access(u, c->ci, CA_OPDEOPME))
- u->SetMode(OperServ, UMODE_HELPOP);
+ u->SetMode(operserv->Bot(), UMODE_HELPOP);
}
return EVENT_CONTINUE;
}
- void OnReload(bool)
+ void OnReload()
{
ConfigReader config;
diff --git a/modules/extra/m_ldap.cpp b/modules/extra/m_ldap.cpp
index c7f0914a0..157bc70ac 100644
--- a/modules/extra/m_ldap.cpp
+++ b/modules/extra/m_ldap.cpp
@@ -210,7 +210,7 @@ class ModuleLDAP : public Module, public Pipe
Implementation i[] = { I_OnReload, I_OnModuleUnload };
ModuleManager::Attach(i, this, 2);
- OnReload(true);
+ OnReload();
}
~ModuleLDAP()
@@ -225,7 +225,7 @@ class ModuleLDAP : public Module, public Pipe
LDAPServices.clear();
}
- void OnReload(bool startup)
+ void OnReload()
{
ConfigReader config;
int i, num;
diff --git a/modules/extra/m_ldap_authentication.cpp b/modules/extra/m_ldap_authentication.cpp
index fa60247e5..f2caac63d 100644
--- a/modules/extra/m_ldap_authentication.cpp
+++ b/modules/extra/m_ldap_authentication.cpp
@@ -1,4 +1,5 @@
#include "module.h"
+#include "nickserv.h"
#include "ldap.h"
static Anope::string email_attribute;
@@ -44,8 +45,8 @@ class IdentifyInterface : public LDAPInterface
return;
}
- User *u = *ii->user;
- Command *c = *ii->command;
+ User *u = ii->user;
+ Command *c = ii->command;
u->Extend("m_ldap_authentication_authenticated");
@@ -56,7 +57,7 @@ class IdentifyInterface : public LDAPInterface
if (Config->NSAddAccessOnReg)
na->nc->AddAccess(create_mask(u));
- u->SendMessage(NickServ, _("Your account \002%s\002 has been successfully created."), na->nick.c_str());
+ u->SendMessage(nickserv->Bot(), _("Your account \002%s\002 has been successfully created."), na->nick.c_str());
}
enc_encrypt(ii->pass, na->nc->pass);
@@ -83,8 +84,8 @@ class IdentifyInterface : public LDAPInterface
return;
}
- User *u = *ii->user;
- Command *c = *ii->command;
+ User *u = ii->user;
+ Command *c = ii->command;
u->Extend("m_ldap_authentication_error");
@@ -128,7 +129,7 @@ class OnIdentifyInterface : public LDAPInterface
if (!email.equals_ci(u->Account()->email))
{
u->Account()->email = email;
- u->SendMessage(NickServ, _("Your email has been updated to \002%s\002"), email.c_str());
+ u->SendMessage(nickserv->Bot(), _("Your email has been updated to \002%s\002"), email.c_str());
Log() << "m_ldap_authentication: Updated email address for " << u->nick << " (" << u->Account()->display << ") to " << email;
}
}
@@ -166,10 +167,10 @@ class NSIdentifyLDAP : public Module
ModuleManager::Attach(i, this, 4);
ModuleManager::SetPriority(this, PRIORITY_FIRST);
- OnReload(false);
+ OnReload();
}
- void OnReload(bool)
+ void OnReload()
{
ConfigReader config;
@@ -182,7 +183,7 @@ class NSIdentifyLDAP : public Module
EventReturn OnPreCommand(CommandSource &source, Command *command, const std::vector<Anope::string> &params)
{
- if (this->disable_register && command->service == NickServ && command->name == "REGISTER")
+ if (this->disable_register && nickserv && command->service == nickserv->Bot() && command->name == "REGISTER")
{
source.Reply(_(this->disable_reason.c_str()));
return EVENT_STOP;
diff --git a/modules/extra/m_ldap_oper.cpp b/modules/extra/m_ldap_oper.cpp
index b8a1d5f51..8010031cb 100644
--- a/modules/extra/m_ldap_oper.cpp
+++ b/modules/extra/m_ldap_oper.cpp
@@ -93,10 +93,10 @@ class LDAPOper : public Module
Implementation i[] = { I_OnReload, I_OnNickIdentify, I_OnDelCore };
ModuleManager::Attach(i, this, 3);
- OnReload(false);
+ OnReload();
}
- void OnReload(bool)
+ void OnReload()
{
ConfigReader config;
diff --git a/modules/extra/m_mysql.cpp b/modules/extra/m_mysql.cpp
index 9895d025d..a54426b37 100644
--- a/modules/extra/m_mysql.cpp
+++ b/modules/extra/m_mysql.cpp
@@ -158,7 +158,7 @@ class ModuleSQL : public Module, public Pipe
DThread = new DispatcherThread();
threadEngine.Start(DThread);
- OnReload(true);
+ OnReload();
}
~ModuleSQL()
@@ -173,7 +173,7 @@ class ModuleSQL : public Module, public Pipe
delete DThread;
}
- void OnReload(bool startup)
+ void OnReload()
{
ConfigReader config;
int i, num;
diff --git a/modules/extra/m_xmlrpc.cpp b/modules/extra/m_xmlrpc.cpp
index db1242970..34288195a 100644
--- a/modules/extra/m_xmlrpc.cpp
+++ b/modules/extra/m_xmlrpc.cpp
@@ -218,12 +218,12 @@ class ModuleXMLRPC : public Module
{
me = this;
- OnReload(false);
-
ModuleManager::RegisterService(&this->xmlrpcinterface);
Implementation i[] = { I_OnReload };
ModuleManager::Attach(i, this, 1);
+
+ OnReload();
}
~ModuleXMLRPC()
@@ -250,7 +250,7 @@ class ModuleXMLRPC : public Module
this->listen_sockets.clear();
}
- void OnReload(bool)
+ void OnReload()
{
ConfigReader config;
diff --git a/modules/extra/m_xmlrpc_main.cpp b/modules/extra/m_xmlrpc_main.cpp
index 593aba6ef..6f4b4b05c 100644
--- a/modules/extra/m_xmlrpc_main.cpp
+++ b/modules/extra/m_xmlrpc_main.cpp
@@ -87,14 +87,15 @@ class MyXMLRPCEvent : public XMLRPCEvent
else
request->reply("online", "yes");
- mod_run_cmd(bi, *u, NULL, command);
+ mod_run_cmd(bi, u, NULL, command);
if (created && u)
{
- XMLRPCUser *myu = debug_cast<XMLRPCUser *>(*u);
+ User *useru = u;
+ XMLRPCUser *myu = debug_cast<XMLRPCUser *>(useru);
if (!myu->GetOut().empty())
request->reply("return", iface->Sanitize(myu->GetOut()));
- delete *u;
+ delete u;
}
}
}
diff --git a/modules/extra/ns_maxemail.cpp b/modules/extra/ns_maxemail.cpp
index 94b4ef12c..2a0141508 100644
--- a/modules/extra/ns_maxemail.cpp
+++ b/modules/extra/ns_maxemail.cpp
@@ -59,13 +59,13 @@ class NSMaxEmail : public Module
this->SetAuthor("Anope");
this->SetType(SUPPORTED);
- ModuleManager::Attach(I_OnReload, this);
- ModuleManager::Attach(I_OnPreCommand, this);
+ Implementation i[] = { I_OnReload, I_OnPreCommand };
+ ModuleManager::Attach(i, this, 2);
- OnReload(false);
+ OnReload();
}
- void OnReload(bool)
+ void OnReload()
{
ConfigReader config;
this->NSEmailMax = config.ReadInteger("ns_maxemail", "maxemails", "0", 0, false);
@@ -75,7 +75,7 @@ class NSMaxEmail : public Module
EventReturn OnPreCommand(CommandSource &source, Command *command, const std::vector<Anope::string> &params)
{
BotInfo *service = source.owner;
- if (service == NickServ)
+ if (service->nick == Config->s_NickServ)
{
if (command->name.equals_ci("REGISTER"))
{
diff --git a/modules/extra/ns_set_misc.cpp b/modules/extra/ns_set_misc.cpp
index a1bf091c5..385fb9648 100644
--- a/modules/extra/ns_set_misc.cpp
+++ b/modules/extra/ns_set_misc.cpp
@@ -12,6 +12,7 @@
/*************************************************************************/
#include "module.h"
+#include "nickserv.h"
class CommandNSSetMisc : public Command
{
@@ -80,8 +81,8 @@ class NSSetMisc : public Module
if (Commands.empty())
return;
- Command *set = FindCommand(NickServ, "SET");
- Command *saset = FindCommand(NickServ, "SASET");
+ Command *set = FindCommand(nickserv->Bot(), "SET");
+ Command *saset = FindCommand(nickserv->Bot(), "SASET");
if (!set && !saset)
return;
@@ -120,7 +121,7 @@ class NSSetMisc : public Module
Implementation i[] = { I_OnReload, I_OnNickInfo, I_OnDatabaseWriteMetadata, I_OnDatabaseReadMetadata };
ModuleManager::Attach(i, this, 4);
- OnReload(true);
+ OnReload();
}
~NSSetMisc()
@@ -128,12 +129,12 @@ class NSSetMisc : public Module
RemoveAll();
}
- void OnReload(bool)
+ void OnReload()
{
RemoveAll();
- Command *set = FindCommand(NickServ, "SET");
- Command *saset = FindCommand(NickServ, "SASET");
+ Command *set = FindCommand(nickserv->Bot(), "SET");
+ Command *saset = FindCommand(nickserv->Bot(), "SASET");
if (!set && !saset)
return;
diff --git a/modules/extra/os_defcon.cpp b/modules/extra/os_defcon.cpp
new file mode 100644
index 000000000..a2a536adf
--- /dev/null
+++ b/modules/extra/os_defcon.cpp
@@ -0,0 +1,693 @@
+/* OperServ 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 "operserv.h"
+#include "global.h"
+#include "os_session.h"
+
+enum DefconLevel
+{
+ DEFCON_NO_NEW_CHANNELS,
+ DEFCON_NO_NEW_NICKS,
+ DEFCON_NO_MLOCK_CHANGE,
+ DEFCON_FORCE_CHAN_MODES,
+ DEFCON_REDUCE_SESSION,
+ DEFCON_NO_NEW_CLIENTS,
+ DEFCON_OPER_ONLY,
+ DEFCON_SILENT_OPER_ONLY,
+ DEFCON_AKILL_NEW_CLIENTS,
+ DEFCON_NO_NEW_MEMOS
+};
+
+static Module *me = NULL;
+bool DefConModesSet = false;
+
+struct DefconConfig
+{
+ std::vector<std::bitset<32> > DefCon;
+ Flags<ChannelModeName, CMODE_END * 2> DefConModesOn;
+ Flags<ChannelModeName, CMODE_END * 2> DefConModesOff;
+ std::map<ChannelModeName, Anope::string> DefConModesOnParams;
+
+ int defaultlevel, sessionlimit;
+ Anope::string chanmodes, message, offmessage, akillreason;
+ std::vector<Anope::string> defcons;
+ time_t akillexpire, timeout;
+ bool globalondefcon;
+
+ DefconConfig()
+ {
+ this->DefCon.resize(5);
+ }
+
+ bool Check(DefconLevel level)
+ {
+ return this->Check(this->defaultlevel, level);
+ }
+
+ bool Check(int dlevel, DefconLevel level)
+ {
+ return this->DefCon[dlevel].test(level);
+ }
+
+ void Add(int dlevel, DefconLevel level)
+ {
+ this->DefCon[dlevel][level] = true;
+ }
+
+ void Del(int dlevel, DefconLevel level)
+ {
+ this->DefCon[dlevel][level] = false;
+ }
+
+ bool SetDefConParam(ChannelModeName Name, const Anope::string &buf)
+ {
+ return DefConModesOnParams.insert(std::make_pair(Name, buf)).second;
+ }
+
+ void UnsetDefConParam(ChannelModeName Name)
+ {
+ DefConModesOnParams.erase(Name);
+ }
+
+ bool GetDefConParam(ChannelModeName Name, Anope::string &buf)
+ {
+ std::map<ChannelModeName, Anope::string>::iterator it = DefConModesOnParams.find(Name);
+
+ buf.clear();
+
+ if (it != DefConModesOnParams.end())
+ {
+ buf = it->second;
+ return true;
+ }
+
+ return false;
+ }
+};
+
+static DefconConfig DConfig;
+
+/**************************************************************************/
+
+void defcon_sendlvls(CommandSource &source);
+void runDefCon();
+static Anope::string defconReverseModes(const Anope::string &modes);
+
+class DefConTimeout : public CallBack
+{
+ int level;
+
+ public:
+ DefConTimeout(Module *mod, int newlevel) : CallBack(mod, DConfig.timeout), level(newlevel) { }
+
+ void Tick(time_t)
+ {
+ if (DConfig.defaultlevel != level)
+ {
+ DConfig.defaultlevel = level;
+ FOREACH_MOD(I_OnDefconLevel, OnDefconLevel(level));
+ Log(operserv->Bot(), "operserv/defcon") << "Defcon level timeout, returning to level " << level;
+ ircdproto->SendGlobops(operserv->Bot(), GetString(NULL, _("\002%s\002 Changed the DEFCON level to \002%d\002")).c_str(), Config->s_OperServ.c_str(), level);
+
+ if (DConfig.globalondefcon)
+ {
+ if (!DConfig.offmessage.empty())
+ global->SendGlobal(global->Bot(), "", DConfig.offmessage);
+ else
+ global->SendGlobal(global->Bot(), "", Anope::printf(GetString(NULL, _("The Defcon Level is now at Level: \002%d\002")).c_str(), DConfig.defaultlevel));
+
+ if (!DConfig.message.empty())
+ global->SendGlobal(global->Bot(), "", DConfig.message);
+ }
+
+ runDefCon();
+ }
+ }
+};
+static DefConTimeout *timeout;
+
+class CommandOSDefcon : public Command
+{
+ void SendLevels(CommandSource &source)
+ {
+ if (DConfig.Check(DEFCON_NO_NEW_CHANNELS))
+ source.Reply(_("* No new channel registrations"));
+ if (DConfig.Check(DEFCON_NO_NEW_NICKS))
+ source.Reply(_("* No new nick registrations"));
+ if (DConfig.Check(DEFCON_NO_MLOCK_CHANGE))
+ source.Reply(_("* No MLOCK changes"));
+ if (DConfig.Check(DEFCON_FORCE_CHAN_MODES) && !DConfig.chanmodes.empty())
+ source.Reply(_("* Force Chan Modes (%s) to be set on all channels"), DConfig.chanmodes.c_str());
+ if (DConfig.Check(DEFCON_REDUCE_SESSION))
+ source.Reply(_("* Use the reduced session limit of %d"), DConfig.sessionlimit);
+ if (DConfig.Check(DEFCON_NO_NEW_CLIENTS))
+ source.Reply(_("* Kill any NEW clients connecting"));
+ if (DConfig.Check(DEFCON_OPER_ONLY))
+ source.Reply(_("* Ignore any non-opers with message"));
+ if (DConfig.Check(DEFCON_SILENT_OPER_ONLY))
+ source.Reply(_("* Silently ignore non-opers"));
+ if (DConfig.Check(DEFCON_AKILL_NEW_CLIENTS))
+ source.Reply(_("* AKILL any new clients connecting"));
+ if (DConfig.Check(DEFCON_NO_NEW_MEMOS))
+ source.Reply(_("* No new memos sent"));
+ }
+
+ public:
+ CommandOSDefcon() : Command("DEFCON", 1, 1, "operserv/defcon")
+ {
+ this->SetDesc(_("Manipulate the DefCon system"));
+ }
+
+ CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> &params)
+ {
+ User *u = source.u;
+ const Anope::string &lvl = params[0];
+
+ if (lvl.empty())
+ {
+ source.Reply(_("Services are now at DEFCON \002%d\002"), DConfig.defaultlevel);
+ this->SendLevels(source);
+ return MOD_CONT;
+ }
+
+ int newLevel = 0;
+ try
+ {
+ newLevel = convertTo<int>(lvl);
+ }
+ catch (const ConvertException &) { }
+
+ if (newLevel < 1 || newLevel > 5)
+ {
+ this->OnSyntaxError(source, "");
+ return MOD_CONT;
+ }
+
+ DConfig.defaultlevel = newLevel;
+
+ FOREACH_MOD(I_OnDefconLevel, OnDefconLevel(newLevel));
+
+ if (timeout)
+ {
+ delete timeout;
+ timeout = NULL;
+ }
+
+ if (DConfig.timeout)
+ timeout = new DefConTimeout(me, 5);
+
+ source.Reply(_("Services are now at DEFCON \002%d\002"), DConfig.defaultlevel);
+ this->SendLevels(source);
+ Log(LOG_ADMIN, u, this) << "to change defcon level to " << newLevel;
+ ircdproto->SendGlobops(operserv->Bot(), _("\002%s\002 Changed the DEFCON level to \002%d\002"), u->nick.c_str(), newLevel);
+ /* Global notice the user what is happening. Also any Message that
+ the Admin would like to add. Set in config file. */
+ if (DConfig.globalondefcon)
+ {
+ if (DConfig.defaultlevel == 5 && !DConfig.offmessage.empty())
+ global->SendGlobal(global->Bot(), "", DConfig.offmessage);
+ else if (DConfig.defaultlevel != 5)
+ {
+ global->SendGlobal(global->Bot(), "", Anope::printf(_("The Defcon level is now at: \002%d\002"), DConfig.defaultlevel));
+ if (!DConfig.message.empty())
+ global->SendGlobal(global->Bot(), "", DConfig.message);
+ }
+ }
+
+ /* Run any defcon functions, e.g. FORCE CHAN MODE */
+ runDefCon();
+ return MOD_CONT;
+ }
+
+ bool OnHelp(CommandSource &source, const Anope::string &subcommand)
+ {
+ source.Reply(_("Syntax: \002DEFCON\002 [\0021\002|\0022\002|\0023\002|\0024\002|\0025\002]\n"
+ "The defcon system can be used to implement a pre-defined\n"
+ "set of restrictions to services useful during an attempted\n"
+ "attack on the network."));
+ return true;
+ }
+
+ void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
+ {
+ SyntaxError(source, "DEFCON", _("DEFCON [\0021\002|\0022\002|\0023\002|\0024\002|\0025\002]"));
+ }
+};
+
+class OSDefcon : public Module
+{
+ service_reference<SessionService> session_service;
+ CommandOSDefcon commandosdefcon;
+
+ void ParseModeString()
+ {
+ int add = -1; /* 1 if adding, 0 if deleting, -1 if neither */
+ unsigned char mode;
+ ChannelMode *cm;
+ ChannelModeParam *cmp;
+ Anope::string modes, param;
+
+ spacesepstream ss(DConfig.chanmodes);
+
+ DConfig.DefConModesOn.ClearFlags();
+ DConfig.DefConModesOff.ClearFlags();
+ ss.GetToken(modes);
+
+ /* Loop while there are modes to set */
+ for (unsigned i = 0, end = modes.length(); i < end; ++i)
+ {
+ mode = modes[i];
+
+ switch (mode)
+ {
+ case '+':
+ add = 1;
+ continue;
+ case '-':
+ add = 0;
+ continue;
+ default:
+ if (add < 0)
+ continue;
+ }
+
+ if ((cm = ModeManager::FindChannelModeByChar(mode)))
+ {
+ if (cm->Type == MODE_STATUS || cm->Type == MODE_LIST || !cm->CanSet(NULL))
+ {
+ Log() << "DefConChanModes mode character '" << mode << "' cannot be locked";
+ continue;
+ }
+ else if (add)
+ {
+ DConfig.DefConModesOn.SetFlag(cm->Name);
+ DConfig.DefConModesOff.UnsetFlag(cm->Name);
+
+ if (cm->Type == MODE_PARAM)
+ {
+ cmp = debug_cast<ChannelModeParam *>(cm);
+
+ if (!ss.GetToken(param))
+ {
+ Log() << "DefConChanModes mode character '" << mode << "' has no parameter while one is expected";
+ continue;
+ }
+
+ if (!cmp->IsValid(param))
+ continue;
+
+ DConfig.SetDefConParam(cmp->Name, param);
+ }
+ }
+ else if (DConfig.DefConModesOn.HasFlag(cm->Name))
+ {
+ DConfig.DefConModesOn.UnsetFlag(cm->Name);
+
+ if (cm->Type == MODE_PARAM)
+ DConfig.UnsetDefConParam(cm->Name);
+ }
+ }
+ }
+
+ /* We can't mlock +L if +l is not mlocked as well. */
+ if ((cm = ModeManager::FindChannelModeByName(CMODE_REDIRECT)) && DConfig.DefConModesOn.HasFlag(cm->Name) && !DConfig.DefConModesOn.HasFlag(CMODE_LIMIT))
+ {
+ DConfig.DefConModesOn.UnsetFlag(CMODE_REDIRECT);
+
+ Log() << "DefConChanModes must lock mode +l as well to lock mode +L";
+ }
+
+ /* Some ircd we can't set NOKNOCK without INVITE */
+ /* So check if we need there is a NOKNOCK MODE and that we need INVITEONLY */
+ if (ircd->knock_needs_i && (cm = ModeManager::FindChannelModeByName(CMODE_NOKNOCK)) && DConfig.DefConModesOn.HasFlag(cm->Name) && !DConfig.DefConModesOn.HasFlag(CMODE_INVITE))
+ {
+ DConfig.DefConModesOn.UnsetFlag(CMODE_NOKNOCK);
+ Log() << "DefConChanModes must lock mode +i as well to lock mode +K";
+ }
+ }
+
+ public:
+ OSDefcon(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator), session_service("session")
+ {
+ if (!DConfig.defaultlevel)
+ throw ModuleException("Invalid configuration settings");
+
+ me = this;
+
+ this->SetAuthor("Anope");
+ this->SetType(CORE);
+
+ Implementation i[] = { I_OnReload, I_OnChannelModeSet, I_OnChannelModeUnset, I_OnPreCommandRun, I_OnPreCommand, I_OnUserConnect, I_OnChannelModeAdd, I_OnChannelCreate };
+ ModuleManager::Attach(i, this, 9);
+
+ if (!operserv)
+ throw ModuleException("OperServ is not loaded!");
+
+ this->AddCommand(operserv->Bot(), &commandosdefcon);
+
+ this->OnReload();
+ }
+
+ void OnReload()
+ {
+ ConfigReader config;
+ DefconConfig dconfig;
+
+ dconfig.defaultlevel = config.ReadInteger("defcon", "defaultlevel", 0, 0);
+ dconfig.defcons[4] = config.ReadValue("defcon", "level4", 0);
+ dconfig.defcons[3] = config.ReadValue("defcon", "level3", 0);
+ dconfig.defcons[2] = config.ReadValue("defcon", "level2", 0);
+ dconfig.defcons[1] = config.ReadValue("defcon", "level1", 0);
+ dconfig.sessionlimit = config.ReadInteger("defcon", "sessionlimit", 0, 0);
+ dconfig.akillexpire = dotime(config.ReadValue("defcon", "akillexpire", 0));
+ dconfig.chanmodes = config.ReadValue("defcon", "chanmodes", 0);
+ dconfig.timeout = dotime(config.ReadValue("defcon", "timeout", 0));
+ dconfig.globalondefcon = config.ReadFlag("defcon", "globalondefcon", 0);
+ dconfig.message = config.ReadValue("defcon", "message", 0);
+ dconfig.offmessage = config.ReadValue("defcon", "offmessage", 0);
+
+ if (dconfig.defaultlevel < 1 || dconfig.defaultlevel > 5)
+ throw ConfigException("The value for <os_defcon:defaultlevel> must be between 1 and 5");
+ else if (dconfig.akillexpire <= 0)
+ throw ConfigException("The value for <os_defcon:akillexpire> must be greater than zero!");
+
+ for (unsigned level = 1; level < 5; ++level)
+ {
+ spacesepstream operations(dconfig.defcons[level]);
+ Anope::string operation;
+ while (operations.GetToken(operation))
+ {
+ if (operation.equals_ci("nonewchannels"))
+ dconfig.Add(level, DEFCON_NO_NEW_CHANNELS);
+ else if (operation.equals_ci("nonewnicks"))
+ dconfig.Add(level, DEFCON_NO_NEW_NICKS);
+ else if (operation.equals_ci("nomlockchanges"))
+ dconfig.Add(level, DEFCON_NO_MLOCK_CHANGE);
+ else if (operation.equals_ci("forcechanmodes"))
+ dconfig.Add(level, DEFCON_FORCE_CHAN_MODES);
+ else if (operation.equals_ci("reducedsessions"))
+ dconfig.Add(level, DEFCON_REDUCE_SESSION);
+ else if (operation.equals_ci("nonewclients"))
+ dconfig.Add(level, DEFCON_NO_NEW_CLIENTS);
+ else if (operation.equals_ci("operonly"))
+ dconfig.Add(level, DEFCON_OPER_ONLY);
+ else if (operation.equals_ci("silentoperonly"))
+ dconfig.Add(level, DEFCON_SILENT_OPER_ONLY);
+ else if (operation.equals_ci("akillnewclients"))
+ dconfig.Add(level, DEFCON_AKILL_NEW_CLIENTS);
+ else if (operation.equals_ci("nonewmemos"))
+ dconfig.Add(level, DEFCON_NO_NEW_MEMOS);
+ }
+
+ if (dconfig.Check(level, DEFCON_REDUCE_SESSION) && dconfig.sessionlimit <= 0)
+ throw ConfigException("The value for <os_defcon:sessionlimit> must be greater than zero!");
+ else if (dconfig.Check(level, DEFCON_AKILL_NEW_CLIENTS) && dconfig.akillreason.empty())
+ throw ConfigException("The value for <os_defcon:akillreason> must not be empty!");
+ else if (dconfig.Check(level, DEFCON_FORCE_CHAN_MODES) && dconfig.chanmodes.empty())
+ throw ConfigException("The value for <os_defcon:chanmodes> must not be empty!");
+ }
+
+ DConfig = dconfig;
+ this->ParseModeString();
+ }
+
+ EventReturn OnUserConnect(User *u, bool &exempt)
+ {
+ if (!exempt && u->server->IsSynced() && DConfig.Check(DEFCON_AKILL_NEW_CLIENTS) && !u->server->IsULined())
+ {
+ if (DConfig.Check(DEFCON_AKILL_NEW_CLIENTS))
+ {
+ Log(operserv->Bot(), "operserv/defcon") << "DEFCON: adding akill for *@" << u->host;
+ XLine *x = SGLine->Add("*@" + u->host, Config->s_OperServ, Anope::CurTime + DConfig.akillexpire, DConfig.akillreason);
+ if (x)
+ x->By = Config->s_OperServ;
+ }
+
+ if (DConfig.Check(DEFCON_NO_NEW_CLIENTS) || DConfig.Check(DEFCON_AKILL_NEW_CLIENTS))
+ kill_user(Config->s_OperServ, u, DConfig.akillreason);
+
+ return EVENT_STOP;
+ }
+
+ return EVENT_CONTINUE;
+ }
+
+ EventReturn OnChannelModeSet(Channel *c, ChannelModeName Name, const Anope::string &param)
+ {
+ ChannelMode *cm = ModeManager::FindChannelModeByName(Name);
+
+ if (DConfig.Check(DEFCON_FORCE_CHAN_MODES) && cm && DConfig.DefConModesOff.HasFlag(Name))
+ {
+ c->RemoveMode(operserv->Bot(), Name, param);
+
+ return EVENT_STOP;
+ }
+
+ return EVENT_CONTINUE;
+ }
+
+ EventReturn OnChannelModeUnset(Channel *c, ChannelModeName Name, const Anope::string &)
+ {
+ ChannelMode *cm = ModeManager::FindChannelModeByName(Name);
+
+ if (DConfig.Check(DEFCON_FORCE_CHAN_MODES) && cm && DConfig.DefConModesOn.HasFlag(Name))
+ {
+ Anope::string param;
+
+ if (DConfig.GetDefConParam(Name, param))
+ c->SetMode(operserv->Bot(), Name, param);
+ else
+ c->SetMode(operserv->Bot(), Name);
+
+ return EVENT_STOP;
+
+ }
+
+ return EVENT_CONTINUE;
+ }
+
+ EventReturn OnPreCommandRun(User *&u, BotInfo *&bi, Anope::string &command, Anope::string &message, ChannelInfo *&ci)
+ {
+ if (!u->HasMode(UMODE_OPER) && (DConfig.Check(DEFCON_OPER_ONLY) || DConfig.Check(DEFCON_SILENT_OPER_ONLY)))
+ {
+ if (!DConfig.Check(DEFCON_SILENT_OPER_ONLY))
+ u->SendMessage(bi, _("Services are in Defcon mode, Please try again later."));
+
+ return EVENT_STOP;
+ }
+
+ return EVENT_CONTINUE;
+ }
+
+ EventReturn OnPreCommand(CommandSource &source, Command *command, const std::vector<Anope::string> &params)
+ {
+ BotInfo *service = command->service;
+ if (service->nick == Config->s_NickServ)
+ {
+ if (command->name.equals_ci("REGISTER") || command->name.equals_ci("GROUP"))
+ {
+ if (DConfig.Check(DEFCON_NO_NEW_NICKS))
+ {
+ source.Reply(_("Services are in Defcon mode, Please try again later."));
+ return EVENT_STOP;
+ }
+ }
+ }
+ else if (service->nick == Config->s_ChanServ)
+ {
+ if (command->name.equals_ci("SET"))
+ {
+ if (!params.empty() && params[0].equals_ci("MLOCK") && DConfig.Check(DEFCON_NO_MLOCK_CHANGE))
+ {
+ source.Reply(_("Services are in Defcon mode, Please try again later."));
+ return EVENT_STOP;
+ }
+ }
+ else if (command->name.equals_ci("REGISTER"))
+ {
+ if (DConfig.Check(DEFCON_NO_NEW_CHANNELS))
+ {
+ source.Reply(_("Services are in Defcon mode, Please try again later."));
+ return EVENT_STOP;
+ }
+ }
+ }
+ else if (service->nick == Config->s_MemoServ)
+ {
+ if (command->name.equals_ci("SEND") || command->name.equals_ci("SENDALL"))
+ {
+ if (DConfig.Check(DEFCON_NO_NEW_MEMOS))
+ {
+ source.Reply(_("Services are in Defcon mode, Please try again later."));
+ return EVENT_STOP;
+ }
+ }
+ }
+
+ return EVENT_CONTINUE;
+ }
+
+ void OnUserConnect(dynamic_reference<User> &u, bool &exempt)
+ {
+ if (exempt || !u || !u->server->IsSynced() || u->server->IsULined())
+ return;
+
+ if (DConfig.Check(DEFCON_AKILL_NEW_CLIENTS))
+ {
+ if (DConfig.Check(DEFCON_AKILL_NEW_CLIENTS))
+ {
+ Log(operserv->Bot(), "operserv/defcon") << "DEFCON: adding akill for *@" << u->host;
+ XLine *x = SGLine->Add("*@" + u->host, Config->s_OperServ, Anope::CurTime + DConfig.akillexpire, DConfig.akillreason);
+ if (x)
+ x->By = Config->s_OperServ;
+ }
+
+ if (DConfig.Check(DEFCON_NO_NEW_CLIENTS) || DConfig.Check(DEFCON_AKILL_NEW_CLIENTS))
+ {
+ kill_user(Config->s_OperServ, u, DConfig.akillreason);
+ return;
+ }
+ }
+
+ if (!DConfig.sessionlimit)
+ return;
+
+ if (DConfig.Check(DEFCON_AKILL_NEW_CLIENTS))
+ {
+ Log(operserv->Bot(), "operserv/defcon") << "DEFCON: adding akill for *@" << u->host;
+ XLine *x = SGLine->Add("*@" + u->host, Config->s_OperServ, Anope::CurTime + DConfig.akillexpire, !DConfig.akillreason.empty() ? DConfig.akillreason : "DEFCON AKILL");
+ if (x)
+ x->By = Config->s_OperServ;
+ }
+
+ if (DConfig.Check(DEFCON_NO_NEW_CLIENTS) || DConfig.Check(DEFCON_AKILL_NEW_CLIENTS))
+ {
+ kill_user(Config->s_OperServ, u, DConfig.akillreason);
+ return;
+ }
+
+ Session *session = session_service->FindSession(u->host);
+ Exception *exception = session_service->FindException(u);
+
+ if (DConfig.Check(DEFCON_REDUCE_SESSION) && !exception)
+ {
+ if (session && session->count > DConfig.sessionlimit)
+ {
+ if (!Config->SessionLimitExceeded.empty())
+ ircdproto->SendMessage(operserv->Bot(), u->nick, Config->SessionLimitExceeded.c_str(), u->host.c_str());
+ if (!Config->SessionLimitDetailsLoc.empty())
+ ircdproto->SendMessage(operserv->Bot(), u->nick, "%s", Config->SessionLimitDetailsLoc.c_str());
+
+ kill_user(Config->s_OperServ, u, "Defcon session limit exceeded");
+ ++session->hits;
+ if (Config->MaxSessionKill && session->hits >= Config->MaxSessionKill)
+ {
+ SGLine->Add("*@" + u->host, Config->s_OperServ, Anope::CurTime + Config->SessionAutoKillExpiry, "Defcon session limit exceeded");
+ ircdproto->SendGlobops(operserv->Bot(), "[DEFCON] Added a temporary AKILL for \2*@%s\2 due to excessive connections", u->host.c_str());
+ }
+ }
+ }
+ }
+
+ void OnChannelModeAdd(ChannelMode *cm)
+ {
+ if (DConfig.chanmodes.find(cm->ModeChar) != Anope::string::npos)
+ this->ParseModeString();
+ }
+
+ void OnChannelCreate(Channel *c)
+ {
+ if (DConfig.Check(DEFCON_FORCE_CHAN_MODES))
+ c->SetModes(operserv->Bot(), false, "%s", DConfig.chanmodes.c_str());
+ }
+};
+
+/**
+ * Send a message to the oper about which precautions are "active" for this level
+ **/
+void defcon_sendlvls(CommandSource &source)
+{
+ if (DConfig.Check(DEFCON_NO_NEW_CHANNELS))
+ source.Reply(_("* No new channel registrations"));
+ if (DConfig.Check(DEFCON_NO_NEW_NICKS))
+ source.Reply(_("* No new nick registrations"));
+ if (DConfig.Check(DEFCON_NO_MLOCK_CHANGE))
+ source.Reply(_("* No MLOCK changes"));
+ if (DConfig.Check(DEFCON_FORCE_CHAN_MODES) && !DConfig.chanmodes.empty())
+ source.Reply(_("* Force Chan Modes (%s) to be set on all channels"), DConfig.chanmodes.c_str());
+ if (DConfig.Check(DEFCON_REDUCE_SESSION))
+ source.Reply(_("* Use the reduced session limit of %d"), DConfig.sessionlimit);
+ if (DConfig.Check(DEFCON_NO_NEW_CLIENTS))
+ source.Reply(_("* Kill any NEW clients connecting"));
+ if (DConfig.Check(DEFCON_OPER_ONLY))
+ source.Reply(_("* Ignore any non-opers with message"));
+ if (DConfig.Check(DEFCON_SILENT_OPER_ONLY))
+ source.Reply(_("* Silently ignore non-opers"));
+ if (DConfig.Check(DEFCON_AKILL_NEW_CLIENTS))
+ source.Reply(_("* AKILL any new clients connecting"));
+ if (DConfig.Check(DEFCON_NO_NEW_MEMOS))
+ source.Reply(_("* No new memos sent"));
+}
+
+void runDefCon()
+{
+ if (DConfig.Check(DEFCON_FORCE_CHAN_MODES))
+ {
+ if (!DConfig.chanmodes.empty() && !DefConModesSet)
+ {
+ if (DConfig.chanmodes[0] == '+' || DConfig.chanmodes[0] == '-')
+ {
+ Log(operserv->Bot(), "operserv/defcon") << "DEFCON: setting " << DConfig.chanmodes << " on all channels";
+ DefConModesSet = true;
+ MassChannelModes(operserv->Bot(), DConfig.chanmodes);
+ }
+ }
+ }
+ else
+ {
+ if (!DConfig.chanmodes.empty() && DefConModesSet)
+ {
+ if (DConfig.chanmodes[0] == '+' || DConfig.chanmodes[0] == '-')
+ {
+ DefConModesSet = false;
+ Anope::string newmodes = defconReverseModes(DConfig.chanmodes);
+ if (!newmodes.empty())
+ {
+ Log(operserv->Bot(), "operserv/defcon") << "DEFCON: setting " << newmodes << " on all channels";
+ MassChannelModes(operserv->Bot(), newmodes);
+ }
+ }
+ }
+ }
+}
+
+static Anope::string defconReverseModes(const Anope::string &modes)
+{
+ if (modes.empty())
+ return "";
+ Anope::string newmodes;
+ for (unsigned i = 0, end = modes.length(); i < end; ++i)
+ {
+ if (modes[i] == '+')
+ newmodes += '-';
+ else if (modes[i] == '-')
+ newmodes += '+';
+ else
+ newmodes += modes[i];
+ }
+ return newmodes;
+}
+
+MODULE_INIT(OSDefcon)
diff --git a/modules/protocol/bahamut.cpp b/modules/protocol/bahamut.cpp
index 68ff578ea..f4735132e 100644
--- a/modules/protocol/bahamut.cpp
+++ b/modules/protocol/bahamut.cpp
@@ -13,6 +13,7 @@
#include "services.h"
#include "modules.h"
+#include "nickserv.h"
IRCDVar myIrcd[] = {
{"Bahamut 1.8.x", /* ircd name */
@@ -219,7 +220,7 @@ class BahamutIRCdProto : public IRCDProto
/* nc_change was = 1, and there is no na->status */
void SendUnregisteredNick(const User *u)
{
- ircdproto->SendMode(NickServ, u, "+d 1");
+ ircdproto->SendMode(nickserv->Bot(), u, "+d 1");
}
/* SERVER */
@@ -242,7 +243,7 @@ class BahamutIRCdProto : public IRCDProto
if (!u->Account())
return;
- ircdproto->SendMode(NickServ, u, "+d %d", u->timestamp);
+ ircdproto->SendMode(nickserv->Bot(), u, "+d %d", u->timestamp);
}
void SendChannel(Channel *c)
@@ -291,17 +292,17 @@ class BahamutIRCdMessage : public IRCdMessage
ip.ntop(AF_INET, params[8].c_str());
User *user = do_nick(source, params[0], params[4], params[5], params[6], params[9], Anope::string(params[2]).is_pos_number_only() ? convertTo<time_t>(params[2]) : 0, ip.addr(), "", "", params[3]);
- if (user)
+ if (user && nickserv)
{
NickAlias *na;
if (user->timestamp == convertTo<time_t>(params[7]) && (na = findnick(user->nick)))
{
user->Login(na->nc);
if (na->nc->HasFlag(NI_UNCONFIRMED) == false)
- user->SetMode(NickServ, UMODE_REGISTERED);
+ user->SetMode(nickserv->Bot(), UMODE_REGISTERED);
}
else
- validate_user(user);
+ nickserv->Validate(user);
}
}
else
@@ -464,12 +465,12 @@ class BahamutIRCdMessage : public IRCdMessage
}
};
-static bool event_xs(BotInfo *bi, const Anope::string &source, const std::vector<Anope::string> &params)
+static bool event_xs(const Anope::string &bot, const Anope::string &source, const std::vector<Anope::string> &params)
{
- if (!params.empty() && bi)
+ if (!params.empty() && !bot.empty())
{
std::vector<Anope::string> p;
- p.push_back(bi->nick);
+ p.push_back(bot);
p.push_back(params[0]);
return ircdmessage->OnPrivmsg(source, p);
}
@@ -480,31 +481,31 @@ static bool event_xs(BotInfo *bi, const Anope::string &source, const std::vector
/* EVENT : OS */
bool event_os(const Anope::string &source, const std::vector<Anope::string> &params)
{
- return event_xs(OperServ, source, params);
+ return event_xs(Config->s_OperServ, source, params);
}
/* EVENT : NS */
bool event_ns(const Anope::string &source, const std::vector<Anope::string> &params)
{
- return event_xs(NickServ, source, params);
+ return event_xs(Config->s_NickServ, source, params);
}
/* EVENT : MS */
bool event_ms(const Anope::string &source, const std::vector<Anope::string> &params)
{
- return event_xs(MemoServ, source, params);
+ return event_xs(Config->s_MemoServ, source, params);
}
/* EVENT : HS */
bool event_hs(const Anope::string &source, const std::vector<Anope::string> &params)
{
- return event_xs(HostServ, source, params);
+ return event_xs(Config->s_HostServ, source, params);
}
/* EVENT : CS */
bool event_cs(const Anope::string &source, const std::vector<Anope::string> &params)
{
- return event_xs(ChanServ, source, params);
+ return event_xs(Config->s_ChanServ, source, params);
}
bool event_burst(const Anope::string &source, const std::vector<Anope::string> &params)
diff --git a/modules/protocol/inspircd-ts6.h b/modules/protocol/inspircd-ts6.h
index ce226407c..eaa02467b 100644
--- a/modules/protocol/inspircd-ts6.h
+++ b/modules/protocol/inspircd-ts6.h
@@ -33,25 +33,28 @@ class InspIRCdTS6Proto : public IRCDProto
private:
void SendChgIdentInternal(const Anope::string &nick, const Anope::string &vIdent)
{
+ User *u = finduser(Config->s_HostServ);
if (!has_chgidentmod)
- ircdproto->SendGlobops(OperServ, "CHGIDENT not loaded!");
+ Log() << "CHGIDENT not loaded!";
else
- send_cmd(HostServ ? HostServ->GetUID() : Config->Numeric, "CHGIDENT %s %s", nick.c_str(), vIdent.c_str());
+ send_cmd(u ? u->GetUID() : Config->Numeric, "CHGIDENT %s %s", nick.c_str(), vIdent.c_str());
}
void SendChgHostInternal(const Anope::string &nick, const Anope::string &vhost)
{
+ User *u = finduser(Config->s_HostServ);
if (!has_chghostmod)
- ircdproto->SendGlobops(OperServ, "CHGHOST not loaded!");
+ Log() << "CHGHOST not loaded!";
else
- send_cmd(HostServ ? HostServ->GetUID() : Config->Numeric, "CHGHOST %s %s", nick.c_str(), vhost.c_str());
+ send_cmd(u ? u->GetUID() : Config->Numeric, "CHGHOST %s %s", nick.c_str(), vhost.c_str());
}
public:
void SendAkillDel(const XLine *x)
{
- send_cmd(OperServ ? OperServ->GetUID() : Config->Numeric, "GLINE %s", x->Mask.c_str());
+ User *u = finduser(Config->s_OperServ);
+ send_cmd(u ? u->GetUID() : Config->Numeric, "GLINE %s", x->Mask.c_str());
}
void SendTopic(BotInfo *whosets, Channel *c)
@@ -76,7 +79,8 @@ class InspIRCdTS6Proto : public IRCDProto
time_t timeleft = x->Expires - Anope::CurTime;
if (timeleft > 172800 || !x->Expires)
timeleft = 172800;
- send_cmd(OperServ ? OperServ->GetUID() : Config->Numeric, "ADDLINE G %s@%s %s %ld %ld :%s", x->GetUser().c_str(), x->GetHost().c_str(), x->By.c_str(), static_cast<long>(Anope::CurTime), static_cast<long>(timeleft), x->Reason.c_str());
+ User *u = finduser(Config->s_OperServ);
+ send_cmd(u ? u->GetUID() : Config->Numeric, "ADDLINE G %s@%s %s %ld %ld :%s", x->GetUser().c_str(), x->GetHost().c_str(), x->By.c_str(), static_cast<long>(Anope::CurTime), static_cast<long>(timeleft), x->Reason.c_str());
}
void SendSVSKillInternal(const BotInfo *source, const User *user, const Anope::string &buf)
@@ -175,13 +179,13 @@ class InspIRCdTS6Proto : public IRCDProto
/* SVSHOLD - set */
void SendSVSHold(const Anope::string &nick)
{
- send_cmd(NickServ->GetUID(), "SVSHOLD %s %u :Being held for registered user", nick.c_str(), static_cast<unsigned>(Config->NSReleaseTimeout));
+ send_cmd(nickserv->Bot()->GetUID(), "SVSHOLD %s %u :Being held for registered user", nick.c_str(), static_cast<unsigned>(Config->NSReleaseTimeout));
}
/* SVSHOLD - release */
void SendSVSHoldDel(const Anope::string &nick)
{
- send_cmd(NickServ->GetUID(), "SVSHOLD %s", nick.c_str());
+ send_cmd(nickserv->Bot()->GetUID(), "SVSHOLD %s", nick.c_str());
}
/* UNSZLINE */
diff --git a/modules/protocol/inspircd11.cpp b/modules/protocol/inspircd11.cpp
index ce0611916..0e787b0fe 100644
--- a/modules/protocol/inspircd11.cpp
+++ b/modules/protocol/inspircd11.cpp
@@ -13,6 +13,7 @@
#include "services.h"
#include "modules.h"
+#include "nickserv.h"
IRCDVar myIrcd[] = {
{"InspIRCd 1.1", /* ircd name */
@@ -59,7 +60,11 @@ void inspircd_cmd_chghost(const Anope::string &nick, const Anope::string &vhost)
send_cmd(Config->s_OperServ, "CHGHOST %s %s", nick.c_str(), vhost.c_str());
}
else
- ircdproto->SendGlobops(OperServ, "CHGHOST not loaded!");
+ {
+ BotInfo *bi = findbot(Config->s_OperServ);
+ if (bi)
+ ircdproto->SendGlobops(bi, "CHGHOST not loaded!");
+ }
}
bool event_idle(const Anope::string &source, const std::vector<Anope::string> &params)
@@ -210,7 +215,7 @@ class InspIRCdProto : public IRCDProto
send_cmd(Config->s_OperServ, "CHGIDENT %s %s", nick.c_str(), vIdent.c_str());
}
else
- ircdproto->SendGlobops(OperServ, "CHGIDENT not loaded!");
+ Log() << "CHGIDENT not loaded!";
}
/* SVSHOLD - set */
@@ -307,7 +312,7 @@ class InspircdIRCdMessage : public IRCdMessage
time_t ts = Anope::string(params[0]).is_pos_number_only() ? convertTo<time_t>(params[0]) : 0;
User *user = do_nick("", params[1], params[4], params[2], source, params[7], ts, params[6], params[3], "", params[5]);
- if (user)
+ if (user && nickserv)
{
user->SetCloakedHost(params[3]);
@@ -317,10 +322,10 @@ class InspircdIRCdMessage : public IRCdMessage
{
user->Login(na->nc);
if (na->nc->HasFlag(NI_UNCONFIRMED))
- user->SetMode(NickServ, UMODE_REGISTERED);
+ user->SetMode(nickserv->Bot(), UMODE_REGISTERED);
}
else
- validate_user(user);
+ nickserv->Validate(user);
}
}
else if (params.size() == 1)
@@ -567,11 +572,11 @@ class InspircdIRCdMessage : public IRCdMessage
return false;
}
if (!has_svsholdmod)
- ircdproto->SendGlobops(OperServ, "SVSHOLD missing, Usage disabled until module is loaded.");
+ Log() << "SVSHOLD missing, Usage disabled until module is loaded.";
if (!has_chghostmod)
- ircdproto->SendGlobops(OperServ, "CHGHOST missing, Usage disabled until module is loaded.");
+ Log() << "CHGHOST missing, Usage disabled until module is loaded.";
if (!has_chgidentmod)
- ircdproto->SendGlobops(OperServ, "CHGIDENT missing, Usage disabled until module is loaded.");
+ Log() << "CHGIDENT missing, Usage disabled until module is loaded.";
ircd->svshold = has_svsholdmod;
}
diff --git a/modules/protocol/inspircd12.cpp b/modules/protocol/inspircd12.cpp
index 82d43434c..4723a21af 100644
--- a/modules/protocol/inspircd12.cpp
+++ b/modules/protocol/inspircd12.cpp
@@ -13,6 +13,7 @@
#include "services.h"
#include "modules.h"
+#include "nickserv.h"
/* inspircd-ts6.h uses these */
static bool has_globopsmod = false;
@@ -57,11 +58,12 @@ void inspircd_cmd_chghost(const Anope::string &nick, const Anope::string &vhost)
{
if (!has_chghostmod)
{
- ircdproto->SendGlobops(OperServ, "CHGHOST not loaded!");
+ Log() << "CHGHOST not loaded!";
return;
}
- send_cmd(HostServ ? HostServ->GetUID() : Config->Numeric, "CHGHOST %s %s", nick.c_str(), vhost.c_str());
+ User *u = finduser(nick);
+ send_cmd(u ? u->GetUID() : Config->Numeric, "CHGHOST %s %s", nick.c_str(), vhost.c_str());
}
bool event_idle(const Anope::string &source, const std::vector<Anope::string> &params)
@@ -260,13 +262,14 @@ bool event_metadata(const Anope::string &source, const std::vector<Anope::string
else if (params[1].equals_cs("accountname"))
{
User *u = finduser(params[0]);
- NickAlias *user_na = u ? findnick(u->nick) : NULL;
NickCore *nc = findcore(params[2]);
if (u && nc)
{
u->Login(nc);
- if (user_na && user_na->nc == nc && user_na->nc->HasFlag(NI_UNCONFIRMED) == false)
- u->SetMode(NickServ, UMODE_REGISTERED);
+
+ NickAlias *user_na = findnick(u->nick);
+ if (nickserv && user_na && user_na->nc == nc && user_na->nc->HasFlag(NI_UNCONFIRMED) == false)
+ u->SetMode(nickserv->Bot(), UMODE_REGISTERED);
}
}
@@ -383,8 +386,8 @@ class Inspircd12IRCdMessage : public InspircdIRCdMessage
for (unsigned i = 9; i < params.size() - 1; ++i)
modes += " " + params[i];
User *user = do_nick("", params[2], params[5], params[3], source, params[params.size() - 1], ts, params[6], params[4], params[0], modes);
- if (user && user->server->IsSynced())
- validate_user(user);
+ if (user && user->server->IsSynced() && nickserv)
+ nickserv->Validate(user);
return true;
}
@@ -709,11 +712,11 @@ class Inspircd12IRCdMessage : public InspircdIRCdMessage
return false;
}
if (!has_svsholdmod)
- ircdproto->SendGlobops(OperServ, "SVSHOLD missing, Usage disabled until module is loaded.");
+ Log() << "SVSHOLD missing, Usage disabled until module is loaded.";
if (!has_chghostmod)
- ircdproto->SendGlobops(OperServ, "CHGHOST missing, Usage disabled until module is loaded.");
+ Log() << "CHGHOST missing, Usage disabled until module is loaded.";
if (!has_chgidentmod)
- ircdproto->SendGlobops(OperServ, "CHGIDENT missing, Usage disabled until module is loaded.");
+ Log() << "CHGIDENT missing, Usage disabled until module is loaded.";
ircd->svshold = has_svsholdmod;
}
@@ -763,17 +766,18 @@ class ProtoInspIRCd : public Module
/* InspIRCd 1.2 doesn't set -r on nick change, remove -r here. Note that if we have to set +r later
* this will cancel out this -r, resulting in no mode changes.
*/
- u->RemoveMode(NickServ, UMODE_REGISTERED);
+ u->RemoveMode(nickserv->Bot(), UMODE_REGISTERED);
}
void OnServerSync(Server *s)
{
- for (Anope::insensitive_map<User *>::iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
- {
- User *u = it->second;
- if (u->server == s && !u->IsIdentified())
- validate_user(u);
- }
+ if (nickserv)
+ for (Anope::insensitive_map<User *>::iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
+ {
+ User *u = it->second;
+ if (u->server == s && !u->IsIdentified())
+ nickserv->Validate(u);
+ }
}
};
diff --git a/modules/protocol/inspircd20.cpp b/modules/protocol/inspircd20.cpp
index 575958bd8..3cb4979a9 100644
--- a/modules/protocol/inspircd20.cpp
+++ b/modules/protocol/inspircd20.cpp
@@ -13,6 +13,7 @@
#include "services.h"
#include "modules.h"
+#include "nickserv.h"
/* inspircd-ts6.h uses these */
static bool has_chghostmod = false;
@@ -56,11 +57,12 @@ void inspircd_cmd_chghost(const Anope::string &nick, const Anope::string &vhost)
{
if (!has_chghostmod)
{
- ircdproto->SendGlobops(OperServ, "CHGHOST not loaded!");
+ Log() << "CHGHOST not loaded!";
return;
}
- send_cmd(HostServ ? HostServ->GetUID() : Config->Numeric, "CHGHOST %s %s", nick.c_str(), vhost.c_str());
+ User *u = finduser(nick);
+ send_cmd(u ? u->GetUID() : Config->Numeric, "CHGHOST %s %s", nick.c_str(), vhost.c_str());
}
bool event_idle(const Anope::string &source, const std::vector<Anope::string> &params)
@@ -270,13 +272,14 @@ bool event_metadata(const Anope::string &source, const std::vector<Anope::string
else if (params[1].equals_cs("accountname"))
{
User *u = finduser(params[0]);
- NickAlias *user_na = u ? findnick(u->nick) : NULL;
NickCore *nc = findcore(params[2]);
if (u && nc)
{
u->Login(nc);
- if (user_na && user_na->nc == nc && user_na->nc->HasFlag(NI_UNCONFIRMED) == false)
- u->SetMode(NickServ, UMODE_REGISTERED);
+
+ NickAlias *user_na = findnick(u->nick);
+ if (nickserv && user_na && user_na->nc == nc && user_na->nc->HasFlag(NI_UNCONFIRMED) == false)
+ u->SetMode(nickserv->Bot(), UMODE_REGISTERED);
}
}
@@ -414,8 +417,8 @@ class Inspircd20IRCdMessage : public InspircdIRCdMessage
for (unsigned i = 9; i < params.size() - 1; ++i)
modes += Anope::string(" ") + params[i];
User *user = do_nick("", params[2], params[5], params[3], source, params[params.size() - 1], ts, params[6], params[4], params[0], modes);
- if (user && user->server->IsSynced())
- validate_user(user);
+ if (user && user->server->IsSynced() && nickserv)
+ nickserv->Validate(user);
return true;
}
@@ -704,11 +707,11 @@ class Inspircd20IRCdMessage : public InspircdIRCdMessage
return false;
}
if (!has_svsholdmod)
- ircdproto->SendGlobops(OperServ, "SVSHOLD missing, Usage disabled until module is loaded.");
+ Log() << "SVSHOLD missing, Usage disabled until module is loaded.";
if (!has_chghostmod)
- ircdproto->SendGlobops(OperServ, "CHGHOST missing, Usage disabled until module is loaded.");
+ Log() << "CHGHOST missing, Usage disabled until module is loaded.";
if (!has_chgidentmod)
- ircdproto->SendGlobops(OperServ, "CHGIDENT missing, Usage disabled until module is loaded.");
+ Log() << "CHGIDENT missing, Usage disabled until module is loaded.";
ircd->svshold = has_svsholdmod;
}
@@ -759,12 +762,13 @@ class ProtoInspIRCd : public Module
void OnServerSync(Server *s)
{
- for (Anope::insensitive_map<User *>::iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
- {
- User *u = it->second;
- if (u->server == s && !u->IsIdentified())
- validate_user(u);
- }
+ if (nickserv)
+ for (Anope::insensitive_map<User *>::iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
+ {
+ User *u = it->second;
+ if (u->server == s && !u->IsIdentified())
+ nickserv->Validate(u);
+ }
}
};
diff --git a/modules/protocol/plexus.cpp b/modules/protocol/plexus.cpp
index 3b299e962..a078e6b77 100644
--- a/modules/protocol/plexus.cpp
+++ b/modules/protocol/plexus.cpp
@@ -11,6 +11,7 @@
#include "services.h"
#include "modules.h"
+#include "nickserv.h"
static Anope::string TS6UPLINK;
@@ -100,19 +101,19 @@ class PlexusProto : public IRCDProto
void SendSGLineDel(const XLine *x)
{
- BotInfo *bi = OperServ;
+ BotInfo *bi = findbot(Config->s_OperServ);
send_cmd(bi ? bi->GetUID() : Config->s_OperServ, "UNXLINE * %s", x->Mask.c_str());
}
void SendSGLine(User *, const XLine *x)
{
- BotInfo *bi = OperServ;
+ BotInfo *bi = findbot(Config->s_OperServ);
send_cmd(bi ? bi->GetUID() : Config->s_OperServ, "XLINE * %s 0 :%s", x->Mask.c_str(), x->Reason.c_str());
}
void SendAkillDel(const XLine *x)
{
- BotInfo *bi = OperServ;
+ BotInfo *bi = findbot(Config->s_OperServ);
send_cmd(bi ? bi->GetUID() : Config->s_OperServ, "UNKLINE * %s %s", x->GetUser().c_str(), x->GetHost().c_str());
}
@@ -132,7 +133,7 @@ class PlexusProto : public IRCDProto
void SendAkill(User *, const XLine *x)
{
- BotInfo *bi = OperServ;
+ BotInfo *bi = findbot(Config->s_OperServ);
send_cmd(bi ? bi->GetUID() : Config->s_OperServ, "KLINE * %ld %s %s :%s", static_cast<long>(x->Expires - Anope::CurTime), x->GetUser().c_str(), x->GetHost().c_str(), x->Reason.c_str());
}
@@ -269,7 +270,7 @@ class PlexusIRCdMessage : public IRCdMessage
ip.clear();
User *user = do_nick("", params[0], params[4], params[9], source, params[10], Anope::string(params[2]).is_pos_number_only() ? convertTo<time_t>(params[2]) : 0, ip, params[5], params[7], params[3]);
if (user && user->server->IsSynced())
- validate_user(user);
+ nickserv->Validate(user);
return true;
}
@@ -528,7 +529,7 @@ bool event_encap(const Anope::string &source, const std::vector<Anope::string> &
{
u->Login(nc);
if (user_na && user_na->nc == nc && user_na->nc->HasFlag(NI_UNCONFIRMED) == false)
- u->SetMode(NickServ, UMODE_REGISTERED);
+ u->SetMode(nickserv->Bot(), UMODE_REGISTERED);
}
}
@@ -648,7 +649,7 @@ class ProtoPlexus : public Module
{
User *u = it->second;
if (u->server == s && !u->IsIdentified())
- validate_user(u);
+ nickserv->Validate(u);
}
}
};
diff --git a/modules/protocol/ratbox.cpp b/modules/protocol/ratbox.cpp
index 62a8d5a72..11d4ccfe6 100644
--- a/modules/protocol/ratbox.cpp
+++ b/modules/protocol/ratbox.cpp
@@ -11,6 +11,7 @@
#include "services.h"
#include "modules.h"
+#include "nickserv.h"
static Anope::string TS6UPLINK;
@@ -103,19 +104,19 @@ class RatboxProto : public IRCDProto
void SendSGLineDel(const XLine *x)
{
- BotInfo *bi = OperServ;
+ BotInfo *bi = findbot(Config->s_OperServ);
send_cmd(bi ? bi->GetUID() : Config->s_OperServ, "UNXLINE * %s", x->Mask.c_str());
}
void SendSGLine(User *, const XLine *x)
{
- BotInfo *bi = OperServ;
+ BotInfo *bi = findbot(Config->s_OperServ);
send_cmd(bi ? bi->GetUID() : Config->s_OperServ, "XLINE * %s 0 :%s", x->Mask.c_str(), x->Reason.c_str());
}
void SendAkillDel(const XLine *x)
{
- BotInfo *bi = OperServ;
+ BotInfo *bi = findbot(Config->s_OperServ);
send_cmd(bi ? bi->GetUID() : Config->s_OperServ, "UNKLINE * %s %s", x->GetUser().c_str(), x->GetHost().c_str());
}
@@ -142,7 +143,7 @@ class RatboxProto : public IRCDProto
void SendAkill(User *, const XLine *x)
{
- BotInfo *bi = OperServ;
+ BotInfo *bi = findbot(Config->s_OperServ);
send_cmd(bi ? bi->GetUID() : Config->s_OperServ, "KLINE * %ld %s %s :%s", static_cast<long>(x->Expires - Anope::CurTime), x->GetUser().c_str(), x->GetHost().c_str(), x->Reason.c_str());
}
@@ -269,8 +270,8 @@ class RatboxIRCdMessage : public IRCdMessage
{
/* Source is always the server */
User *user = do_nick("", params[0], params[4], params[5], source, params[8], Anope::string(params[2]).is_pos_number_only() ? convertTo<time_t>(params[2]) : 0, params[6], "*", params[7], params[3]);
- if (user && user->server->IsSynced())
- validate_user(user);
+ if (user && user->server->IsSynced() && nickserv)
+ nickserv->Validate(user);
return true;
}
@@ -579,12 +580,13 @@ class ProtoRatbox : public Module
void OnServerSync(Server *s)
{
- for (Anope::insensitive_map<User *>::iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
- {
- User *u = it->second;
- if (u->server == s && !u->IsIdentified())
- validate_user(u);
- }
+ if (nickserv)
+ for (Anope::insensitive_map<User *>::iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
+ {
+ User *u = it->second;
+ if (u->server == s && !u->IsIdentified())
+ nickserv->Validate(u);
+ }
}
};
diff --git a/modules/protocol/unreal32.cpp b/modules/protocol/unreal32.cpp
index b6e438461..7e874838d 100644
--- a/modules/protocol/unreal32.cpp
+++ b/modules/protocol/unreal32.cpp
@@ -13,6 +13,7 @@
#include "services.h"
#include "modules.h"
+#include "nickserv.h"
IRCDVar myIrcd[] = {
{"UnrealIRCd 3.2.x", /* ircd name */
@@ -107,11 +108,11 @@ class UnrealIRCdProto : public IRCDProto
void SendVhostDel(User *u)
{
- u->RemoveMode(HostServ, UMODE_CLOAK);
- u->RemoveMode(HostServ, UMODE_VHOST);
- ModeManager::ProcessModes();
- u->SetMode(HostServ, UMODE_CLOAK);
+ BotInfo *bi = findbot(Config->s_HostServ);
+ u->RemoveMode(bi, UMODE_CLOAK);
+ u->RemoveMode(bi, UMODE_VHOST);
ModeManager::ProcessModes();
+ u->SetMode(bi, UMODE_CLOAK);
}
void SendAkill(User *, const XLine *x)
@@ -322,12 +323,12 @@ class UnrealIRCdProto : public IRCDProto
if (!u->Account())
return;
- ircdproto->SendMode(NickServ, u, "+d %d", u->timestamp);
+ ircdproto->SendMode(nickserv->Bot(), u, "+d %d", u->timestamp);
}
void SendUnregisteredNick(const User *u)
{
- ircdproto->SendMode(NickServ, u, "+d 1");
+ ircdproto->SendMode(nickserv->Bot(), u, "+d 1");
}
void SendChannel(Channel *c)
@@ -335,7 +336,7 @@ class UnrealIRCdProto : public IRCDProto
/* Unreal does not support updating a channels TS without actually joining a user,
* so we will join and part us now
*/
- BotInfo *bi = whosends(c->ci);
+ BotInfo *bi = c->ci->WhoSends();
if (c->FindUser(bi) == NULL)
{
bi->Join(c);
@@ -529,11 +530,11 @@ class Unreal32IRCdMessage : public IRCdMessage
if (na && user->timestamp == convertTo<time_t>(params[6]))
{
user->Login(na->nc);
- if (na->nc->HasFlag(NI_UNCONFIRMED) == false)
- user->SetMode(NickServ, UMODE_REGISTERED);
+ if (na->nc->HasFlag(NI_UNCONFIRMED) == false && nickserv)
+ user->SetMode(nickserv->Bot(), UMODE_REGISTERED);
}
- else
- validate_user(user);
+ else if (nickserv)
+ nickserv->Validate(user);
}
}
else if (params.size() != 2)
@@ -551,11 +552,11 @@ class Unreal32IRCdMessage : public IRCdMessage
if (na && user->timestamp == convertTo<time_t>(params[6]))
{
user->Login(na->nc);
- if (na->nc->HasFlag(NI_UNCONFIRMED) == false)
- user->SetMode(NickServ, UMODE_REGISTERED);
+ if (na->nc->HasFlag(NI_UNCONFIRMED) == false && nickserv)
+ user->SetMode(nickserv->Bot(), UMODE_REGISTERED);
}
- else
- validate_user(user);
+ else if (nickserv)
+ nickserv->Validate(user);
}
}
else