diff options
Diffstat (limited to 'modules')
238 files changed, 6607 insertions, 7394 deletions
diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index e1adec666..228618b0e 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -76,9 +76,8 @@ foreach(MODULE_FOLDER ${MODULES_FOLDERS}) else(WIN32) set(WIN32_NO_LIBS) endif(WIN32) - set_target_properties(${SO} PROPERTIES LINKER_LANGUAGE CXX PREFIX "" SUFFIX "" LINK_FLAGS "${TEMP_LDFLAGS} ${WIN32_NO_LIBS}") + set_target_properties(${SO} PROPERTIES LINKER_LANGUAGE CXX PREFIX "" SUFFIX "" LINK_FLAGS "${TEMP_LDFLAGS} ${WIN32_NO_LIBS}" INSTALL_RPATH_USE_LINK_PATH ON BUILD_WITH_INSTALL_RPATH ON) add_dependencies(${SO} ${PROGRAM_NAME}) - target_link_libraries(${SO} ${PROGRAM_NAME}) if(GETTEXT_FOUND) add_dependencies(${SO} module_language) endif(GETTEXT_FOUND) @@ -87,7 +86,7 @@ foreach(MODULE_FOLDER ${MODULES_FOLDERS}) target_link_libraries(${SO} ${PROGRAM_NAME} wsock32 Ws2_32 ${WIN32_MEMORY} ${TEMP_DEPENDENCIES}) set_target_properties(${PROGRAM_NAME} PROPERTIES VERSION "${VERSION_DOTTED}") else(WIN32) - target_link_libraries(${SO} ${PROGRAM_NAME} ${TEMP_DEPENDENCIES}) + target_link_libraries(${SO} ${TEMP_DEPENDENCIES}) endif(WIN32) # Set the module to be installed to the module directory under the data directory install(TARGETS ${SO} @@ -179,7 +178,7 @@ foreach(MODULE_FOLDER ${MODULES_FOLDERS}) # Generate the module and set it's linker flags, also set it to depend on the main Anope executable to be built beforehand add_library(${SO} MODULE ${MODULES_SUBDIR_SRCS}) - set_target_properties(${SO} PROPERTIES LINKER_LANGUAGE CXX PREFIX "" SUFFIX "" LINK_FLAGS "${SUBDIR_LDFLAGS}") + set_target_properties(${SO} PROPERTIES LINKER_LANGUAGE CXX PREFIX "" SUFFIX "" LINK_FLAGS "${SUBDIR_LDFLAGS}" INSTALL_RPATH_USE_LINK_PATH ON BUILD_WITH_INSTALL_RPATH ON) add_dependencies(${SO} ${PROGRAM_NAME}) target_link_libraries(${SO} ${PROGRAM_NAME}) if(GETTEXT_FOUND) diff --git a/modules/commands/bs_assign.cpp b/modules/commands/bs_assign.cpp index ac809b952..93cb5f907 100644 --- a/modules/commands/bs_assign.cpp +++ b/modules/commands/bs_assign.cpp @@ -1,6 +1,6 @@ /* BotServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -48,13 +48,13 @@ class CommandBSAssign : public Command } AccessGroup access = source.AccessFor(ci); - if (ci->botflags.HasFlag(BS_NOBOT) || (!access.HasPriv("ASSIGN") && !source.HasPriv("botserv/administration"))) + if (ci->HasExt("BS_NOBOT") || (!access.HasPriv("ASSIGN") && !source.HasPriv("botserv/administration"))) { source.Reply(ACCESS_DENIED); return; } - if (bi->HasFlag(BI_PRIVATE) && !source.HasCommand("botserv/assign/private")) + if (bi->oper_only && !source.HasPriv("botserv/administration")) { source.Reply(ACCESS_DENIED); return; @@ -121,7 +121,7 @@ class CommandBSUnassign : public Command return; } - if (ci->HasFlag(CI_PERSIST) && !ModeManager::FindChannelModeByName(CMODE_PERM)) + if (ci->HasExt("PERSIST") && !ModeManager::FindChannelModeByName("PERM")) { source.Reply(_("You can not unassign bots while persist is set on the channel.")); return; diff --git a/modules/commands/bs_badwords.cpp b/modules/commands/bs_badwords.cpp index 36a83b717..147b23b95 100644 --- a/modules/commands/bs_badwords.cpp +++ b/modules/commands/bs_badwords.cpp @@ -1,6 +1,6 @@ /* BotServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -110,18 +110,18 @@ class CommandBSBadwords : public Command } if (list.IsEmpty()) - source.Reply(_("No matching entries on %s badword list."), ci->name.c_str()); + source.Reply(_("No matching entries on %s bad words list."), ci->name.c_str()); else { std::vector<Anope::string> replies; list.Process(replies); - source.Reply(_("Badword list for %s:"), ci->name.c_str()); + source.Reply(_("Bad words list for %s:"), ci->name.c_str()); for (unsigned i = 0; i < replies.size(); ++i) source.Reply(replies[i]); - source.Reply(_("End of badword list.")); + source.Reply(_("End of bad words list.")); } } @@ -222,7 +222,7 @@ class CommandBSBadwords : public Command public: CommandBSBadwords(Module *creator) : Command(creator, "botserv/badwords", 2, 3) { - this->SetDesc(_("Maintains bad words list")); + this->SetDesc(_("Maintains the bad words list")); this->SetSyntax(_("\037channel\037 ADD \037word\037 [\037SINGLE\037 | \037START\037 | \037END\037]")); this->SetSyntax(_("\037channel\037 DEL {\037word\037 | \037entry-num\037 | \037list\037}")); this->SetSyntax(_("\037channel\037 LIST [\037mask\037 | \037list\037]")); @@ -282,8 +282,8 @@ class CommandBSBadwords : public Command "type \002%s%s HELP KICK %s\002.\n" " \n" "The \002ADD\002 command adds the given word to the\n" - "badword list. If SINGLE is specified, a kick will be\n" - "done only if a user says the entire word. If START is \n" + "bad words list. If SINGLE is specified, a kick will be\n" + "done only if a user says the entire word. If START is\n" "specified, a kick will be done if a user says a word\n" "that starts with \037word\037. If END is specified, a kick\n" "will be done if a user says a word that ends with\n" diff --git a/modules/commands/bs_bot.cpp b/modules/commands/bs_bot.cpp index 8246692d0..dd6da27d6 100644 --- a/modules/commands/bs_bot.cpp +++ b/modules/commands/bs_bot.cpp @@ -1,6 +1,6 @@ /* BotServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -31,38 +31,37 @@ class CommandBSBot : public Command if (nick.length() > Config->NickLen) { - source.Reply(_("Bot Nicks may only contain valid nick characters.")); + source.Reply(_("Bot nicks may only be %d characters long."), Config->NickLen); return; } if (user.length() > Config->UserLen) { - source.Reply(_("Bot Idents may only contain %d characters."), Config->UserLen); + source.Reply(_("Bot idents may only be %d characters long."), Config->UserLen); return; } if (host.length() > Config->HostLen) { - source.Reply(_("Bot Hosts may only contain %d characters."), Config->HostLen); + source.Reply(_("Bot hosts may only be %d characters long."), Config->HostLen); return; } if (!IRCD->IsNickValid(nick)) { - source.Reply(_("Bot Nicks may only contain valid nick characters.")); + source.Reply(_("Bot nicks may only contain valid nick characters.")); return; } - /* Check the host is valid */ - if (!IRCD->IsHostValid(host)) + if (!IRCD->IsIdentValid(user)) { - source.Reply(_("Bot Hosts may only contain valid host characters.")); + source.Reply(_("Bot idents may only contain valid ident characters.")); return; } - if (!IRCD->IsIdentValid(user)) + if (!IRCD->IsHostValid(host)) { - source.Reply(_("Bot Idents may only contain valid characters.")); + source.Reply(_("Bot hosts may only contain valid host characters.")); return; } @@ -107,27 +106,27 @@ class CommandBSBot : public Command return; } - if (bi->HasFlag(BI_CONF)) + if (bi->conf) { - source.Reply(_("Bot %s is not changable."), bi->nick.c_str()); + source.Reply(_("Bot %s is not changeable."), bi->nick.c_str()); return; } if (nick.length() > Config->NickLen) { - source.Reply(_("Bot Nicks may only contain valid nick characters.")); + source.Reply(_("Bot nicks may only be %d characters long."), Config->NickLen); return; } if (!user.empty() && user.length() > Config->UserLen) { - source.Reply(_("Bot Idents may only contain %d characters."), Config->UserLen); + source.Reply(_("Bot idents may only be %d characters long."), Config->UserLen); return; } if (!host.empty() && host.length() > Config->HostLen) { - source.Reply(_("Bot Hosts may only contain %d characters."), Config->HostLen); + source.Reply(_("Bot hosts may only be %d characters long."), Config->HostLen); return; } @@ -144,19 +143,19 @@ class CommandBSBot : public Command if (!IRCD->IsNickValid(nick)) { - source.Reply(_("Bot Nicks may only contain valid nick characters.")); + source.Reply(_("Bot nicks may only contain valid nick characters.")); return; } - if (!host.empty() && !IRCD->IsHostValid(host)) + if (!user.empty() && !IRCD->IsIdentValid(user)) { - source.Reply(_("Bot Hosts may only contain valid host characters.")); + source.Reply(_("Bot idents may only contain valid ident characters.")); return; } - if (!user.empty() && !IRCD->IsIdentValid(user)) + if (!host.empty() && !IRCD->IsHostValid(host)) { - source.Reply(_("Bot Idents may only contain valid characters."), Config->UserLen); + source.Reply(_("Bot hosts may only contain valid host characters.")); return; } @@ -208,7 +207,7 @@ class CommandBSBot : public Command bi->RejoinAll(); } - source.Reply(_("Bot \002%s\002 has been changed to %s!%s@%s (%s)"), oldnick.c_str(), bi->nick.c_str(), bi->GetIdent().c_str(), bi->host.c_str(), bi->realname.c_str()); + source.Reply(_("Bot \002%s\002 has been changed to %s!%s@%s (%s)."), oldnick.c_str(), bi->nick.c_str(), bi->GetIdent().c_str(), bi->host.c_str(), bi->realname.c_str()); Log(LOG_ADMIN, source, this) << "CHANGE " << oldnick << " to " << bi->GetMask() << " " << bi->realname; FOREACH_MOD(I_OnBotChange, OnBotChange(bi)); @@ -232,7 +231,7 @@ class CommandBSBot : public Command return; } - if (bi->HasFlag(BI_CONF)) + if (bi->conf) { source.Reply(_("Bot %s is not deletable."), bi->nick.c_str()); return; @@ -243,7 +242,7 @@ class CommandBSBot : public Command Log(LOG_ADMIN, source, this) << "DEL " << bi->nick; source.Reply(_("Bot \002%s\002 has been deleted."), nick.c_str()); - bi->Destroy(); + delete bi; return; } public: @@ -337,12 +336,12 @@ class CommandBSBot : public Command "channels.\n" " \n" "\002BOT ADD\002 adds a bot with the given nickname, username,\n" - "hostname and realname. Since no integrity checks are done \n" + "hostname and realname. Since no integrity checks are done\n" "for these settings, be really careful.\n" "\002BOT CHANGE\002 allows to change nickname, username, hostname\n" "or realname of a bot without actually delete it (and all\n" "the data associated with it).\n" - "\002BOT DEL\002 removes the given bot from the bot list. \n" + "\002BOT DEL\002 removes the given bot from the bot list.\n" " \n" "\002Note\002: you cannot create a bot that has a nick that is\n" "currently registered. If an unregistered user is currently\n" diff --git a/modules/commands/bs_botlist.cpp b/modules/commands/bs_botlist.cpp index 1cdd93c45..cacfce903 100644 --- a/modules/commands/bs_botlist.cpp +++ b/modules/commands/bs_botlist.cpp @@ -1,6 +1,6 @@ /* BotServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -33,11 +33,11 @@ class CommandBSBotList : public Command { BotInfo *bi = it->second; - if (source.HasCommand("botserv/botlist") || !bi->HasFlag(BI_PRIVATE)) + if (source.HasPriv("botserv/administration") || !bi->oper_only) { ++count; ListFormatter::ListEntry entry; - entry["Nick"] = (bi->HasFlag(BI_PRIVATE) ? "* " : "") + bi->nick; + entry["Nick"] = (bi->oper_only ? "* " : "") + bi->nick; entry["Mask"] = bi->GetIdent() + "@" + bi->host; list.AddEntry(entry); } @@ -65,7 +65,7 @@ class CommandBSBotList : public Command this->SendSyntax(source); source.Reply(" "); source.Reply(_("Lists all available bots on this network.\n" - "Bots prefixed by a * are reserved for IRC operators.")); + "Bots prefixed by a * are reserved for IRC Operators.")); return true; } }; diff --git a/modules/commands/bs_control.cpp b/modules/commands/bs_control.cpp index 3ee0401d6..37dc2c489 100644 --- a/modules/commands/bs_control.cpp +++ b/modules/commands/bs_control.cpp @@ -1,6 +1,6 @@ /* BotServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/commands/bs_info.cpp b/modules/commands/bs_info.cpp index a4312cea6..b1e05bb17 100644 --- a/modules/commands/bs_info.cpp +++ b/modules/commands/bs_info.cpp @@ -1,6 +1,6 @@ /* BotServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -38,9 +38,9 @@ class CommandBSInfo : public Command buffers.push_back(buf); } - void CheckOptStr(Anope::string &buf, BotServFlag flag, const char *option, Flags<BotServFlag> &flags, const NickCore *nc) + void CheckOptStr(Anope::string &buf, const Anope::string &flag, const char *option, Extensible *flags, const NickCore *nc) { - if (flags.HasFlag(flag)) + if (flags->HasExt(flag)) { if (!buf.empty()) buf += ", "; @@ -52,7 +52,7 @@ class CommandBSInfo : public Command CommandBSInfo(Module *creator) : Command(creator, "botserv/info", 1, 1) { this->SetDesc(_("Allows you to see BotServ information about a channel or a bot")); - this->SetSyntax(_("\002INFO {\037chan\037 | \037nick\037}\002")); + this->SetSyntax(_("{\037chan\037|\037nick\037}")); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override @@ -69,7 +69,7 @@ class CommandBSInfo : public Command info[_("Mask")] = bi->GetIdent() + "@" + bi->host; info[_("Real name")] = bi->realname; info[_("Created")] = Anope::strftime(bi->created); - info[_("Options")] = bi->HasFlag(BI_PRIVATE) ? _("Private") : _("None"); + info[_("Options")] = bi->oper_only ? _("Private") : _("None"); info[_("Used on")] = stringify(bi->GetChannelCount()) + " channel(s)"; std::vector<Anope::string> replies; @@ -89,7 +89,7 @@ class CommandBSInfo : public Command } else if ((ci = ChannelInfo::Find(query))) { - if (!source.AccessFor(ci).HasPriv("FOUNDER") && !source.HasPriv("botserv/administration")) + if (!source.AccessFor(ci).HasPriv("INFO") && !source.HasPriv("botserv/administration")) { source.Reply(ACCESS_DENIED); return; @@ -101,7 +101,7 @@ class CommandBSInfo : public Command Anope::string enabled = Language::Translate(source.nc, _("Enabled")); Anope::string disabled = Language::Translate(source.nc, _("Disabled")); - if (ci->botflags.HasFlag(BS_KICK_BADWORDS)) + if (ci->HasExt("BS_KICK_BADWORDS")) { if (ci->ttb[TTB_BADWORDS]) info[_("Bad words kicker")] = Anope::printf("%s (%d kick(s) to ban)", enabled.c_str(), ci->ttb[TTB_BADWORDS]); @@ -111,7 +111,7 @@ class CommandBSInfo : public Command else info[_("Bad words kicker")] = disabled; - if (ci->botflags.HasFlag(BS_KICK_BOLDS)) + if (ci->HasExt("BS_KICK_BOLDS")) { if (ci->ttb[TTB_BOLDS]) info[_("Bolds kicker")] = Anope::printf("%s (%d kick(s) to ban)", enabled.c_str(), ci->ttb[TTB_BOLDS]); @@ -121,7 +121,7 @@ class CommandBSInfo : public Command else info[_("Bolds kicker")] = disabled; - if (ci->botflags.HasFlag(BS_KICK_CAPS)) + if (ci->HasExt("BS_KICK_CAPS")) { if (ci->ttb[TTB_CAPS]) info[_("Caps kicker")] = Anope::printf(_("%s (%d kick(s) to ban; minimum %d/%d%%"), enabled.c_str(), ci->ttb[TTB_CAPS], ci->capsmin, ci->capspercent); @@ -131,7 +131,7 @@ class CommandBSInfo : public Command else info[_("Caps kicker")] = disabled; - if (ci->botflags.HasFlag(BS_KICK_COLORS)) + if (ci->HasExt("BS_KICK_COLORS")) { if (ci->ttb[TTB_COLORS]) info[_("Colors kicker")] = Anope::printf(_("%s (%d kick(s) to ban)"), enabled.c_str(), ci->ttb[TTB_COLORS]); @@ -141,7 +141,7 @@ class CommandBSInfo : public Command else info[_("Colors kicker")] = disabled; - if (ci->botflags.HasFlag(BS_KICK_FLOOD)) + if (ci->HasExt("BS_KICK_FLOOD")) { if (ci->ttb[TTB_FLOOD]) info[_("Flood kicker")] = Anope::printf(_("%s (%d kick(s) to ban; %d lines in %ds"), enabled.c_str(), ci->ttb[TTB_FLOOD], ci->floodlines, ci->floodsecs); @@ -151,7 +151,7 @@ class CommandBSInfo : public Command else info[_("Flood kicker")] = disabled; - if (ci->botflags.HasFlag(BS_KICK_REPEAT)) + if (ci->HasExt("BS_KICK_REPEAT")) { if (ci->ttb[TTB_REPEAT]) info[_("Repeat kicker")] = Anope::printf(_("%s (%d kick(s) to ban; %d times)"), enabled.c_str(), ci->ttb[TTB_REPEAT], ci->repeattimes); @@ -161,7 +161,7 @@ class CommandBSInfo : public Command else info[_("Repeat kicker")] = disabled; - if (ci->botflags.HasFlag(BS_KICK_REVERSES)) + if (ci->HasExt("BS_KICK_REVERSES")) { if (ci->ttb[TTB_REVERSES]) info[_("Reverses kicker")] = Anope::printf(_("%s (%d kick(s) to ban)"), enabled.c_str(), ci->ttb[TTB_REVERSES]); @@ -171,7 +171,7 @@ class CommandBSInfo : public Command else info[_("Reverses kicker")] = disabled; - if (ci->botflags.HasFlag(BS_KICK_UNDERLINES)) + if (ci->HasExt("BS_KICK_UNDERLINES")) { if (ci->ttb[TTB_UNDERLINES]) info[_("Underlines kicker")] = Anope::printf(_("%s (%d kick(s) to ban)"), enabled.c_str(), ci->ttb[TTB_UNDERLINES]); @@ -181,7 +181,7 @@ class CommandBSInfo : public Command else info[_("Underlines kicker")] = disabled; - if (ci->botflags.HasFlag(BS_KICK_ITALICS)) + if (ci->HasExt("BS_KICK_ITALICS")) { if (ci->ttb[TTB_ITALICS]) info[_("Italics kicker")] = Anope::printf(_("%s (%d kick(s) to ban)"), enabled.c_str(), ci->ttb[TTB_ITALICS]); @@ -191,7 +191,7 @@ class CommandBSInfo : public Command else info[_("Italics kicker")] = disabled; - if (ci->botflags.HasFlag(BS_KICK_AMSGS)) + if (ci->HasExt("BS_KICK_AMSGS")) { if (ci->ttb[TTB_AMSGS]) info[_("AMSG kicker")] = Anope::printf(_("%s (%d kick(s) to ban)"), enabled.c_str(), ci->ttb[TTB_AMSGS]); @@ -202,11 +202,11 @@ class CommandBSInfo : public Command info[_("AMSG kicker")] = disabled; Anope::string flags; - CheckOptStr(flags, BS_DONTKICKOPS, _("Ops protection"), ci->botflags, source.nc); - CheckOptStr(flags, BS_DONTKICKVOICES, _("Voices protection"), ci->botflags, source.nc); - CheckOptStr(flags, BS_FANTASY, _("Fantasy"), ci->botflags, source.nc); - CheckOptStr(flags, BS_GREET, _("Greet"), ci->botflags, source.nc); - CheckOptStr(flags, BS_NOBOT, _("No bot"), ci->botflags, source.nc); + CheckOptStr(flags, "BS_DONTKICKOPS", _("Ops protection"), ci, source.nc); + CheckOptStr(flags, "BS_DONTKICKVOICES", _("Voices protection"), ci, source.nc); + CheckOptStr(flags, "BS_FANTASY", _("Fantasy"), ci, source.nc); + CheckOptStr(flags, "BS_GREET", _("Greet"), ci, source.nc); + CheckOptStr(flags, "BS_NOBOT", _("No bot"), ci, source.nc); info[_("Options")] = flags.empty() ? _("None") : flags; diff --git a/modules/commands/bs_kick.cpp b/modules/commands/bs_kick.cpp index 3e569696e..d351d29b2 100644 --- a/modules/commands/bs_kick.cpp +++ b/modules/commands/bs_kick.cpp @@ -1,6 +1,6 @@ /* BotServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -72,19 +72,19 @@ class CommandBSKick : public Command else ci->ttb[TTB_BADWORDS] = 0; - ci->botflags.SetFlag(BS_KICK_BADWORDS); + ci->ExtendMetadata("BS_KICK_BADWORDS"); if (ci->ttb[TTB_BADWORDS]) - source.Reply(_("Bot will now kick \002bad words\002, and will place a ban after \n" - "%d kicks for the same user. Use the BADWORDS command\n" - "to add or remove a bad word."), ci->ttb[TTB_BADWORDS]); + source.Reply(_("Bot will now kick for \002bad words\002, and will place a ban\n" + "after %d kicks for the same user. Use the BADWORDS command\n" + "to add or remove a bad word."), ci->ttb[TTB_BADWORDS]); else - source.Reply(_("Bot will now kick \002bad words\002. Use the BADWORDS command\n" + source.Reply(_("Bot will now kick for \002bad words\002. Use the BADWORDS command\n" "to add or remove a bad word.")); } else { - ci->botflags.UnsetFlag(BS_KICK_BADWORDS); - source.Reply(_("Bot won't kick \002bad words\002 anymore.")); + ci->Shrink("BS_KICK_BADWORDS"); + source.Reply(_("Bot won't kick for \002bad words\002 anymore.")); } } else if (option.equals_ci("BOLDS")) @@ -108,16 +108,17 @@ class CommandBSKick : public Command } else ci->ttb[TTB_BOLDS] = 0; - ci->botflags.SetFlag(BS_KICK_BOLDS); + ci->ExtendMetadata("BS_KICK_BOLDS"); if (ci->ttb[TTB_BOLDS]) - source.Reply(_("Bot will now kick \002bolds\002, and will place a ban after\n%d kicks to the same user."), ci->ttb[TTB_BOLDS]); + source.Reply(_("Bot will now kick for \002bolds\002, and will place a ban\n" + "after %d kicks for the same user."), ci->ttb[TTB_BOLDS]); else - source.Reply(_("Bot will now kick \002bolds\002.")); + source.Reply(_("Bot will now kick for \002bolds\002.")); } else { - ci->botflags.UnsetFlag(BS_KICK_BOLDS); - source.Reply(_("Bot won't kick \002bolds\002 anymore.")); + ci->Shrink("BS_KICK_BOLDS"); + source.Reply(_("Bot won't kick for \002bolds\002 anymore.")); } } else if (option.equals_ci("CAPS")) @@ -163,19 +164,19 @@ class CommandBSKick : public Command if (ci->capspercent < 1 || ci->capspercent > 100) ci->capspercent = 25; - ci->botflags.SetFlag(BS_KICK_CAPS); + ci->ExtendMetadata("BS_KICK_CAPS"); if (ci->ttb[TTB_CAPS]) - source.Reply(_("Bot will now kick \002caps\002 (they must constitute at least\n" - "%d characters and %d%% of the entire message), and will \n" + source.Reply(_("Bot will now kick for \002caps\002 (they must constitute at least\n" + "%d characters and %d%% of the entire message), and will\n" "place a ban after %d kicks for the same user."), ci->capsmin, ci->capspercent, ci->ttb[TTB_CAPS]); else - source.Reply(_("Bot will now kick \002caps\002 (they must constitute at least\n" + source.Reply(_("Bot will now kick for \002caps\002 (they must constitute at least\n" "%d characters and %d%% of the entire message)."), ci->capsmin, ci->capspercent); } else { - ci->botflags.UnsetFlag(BS_KICK_CAPS); - source.Reply(_("Bot won't kick \002caps\002 anymore.")); + ci->Shrink("BS_KICK_CAPS"); + source.Reply(_("Bot won't kick for \002caps\002 anymore.")); } } else if (option.equals_ci("COLORS")) @@ -200,16 +201,17 @@ class CommandBSKick : public Command else ci->ttb[TTB_COLORS] = 0; - ci->botflags.SetFlag(BS_KICK_COLORS); + ci->ExtendMetadata("BS_KICK_COLORS"); if (ci->ttb[TTB_COLORS]) - source.Reply(_("Bot will now kick \002colors\002, and will place a ban after %d\nkicks for the same user."), ci->ttb[TTB_COLORS]); + source.Reply(_("Bot will now kick for \002colors\002, and will place a ban\n" + "after %d kicks for the same user."), ci->ttb[TTB_COLORS]); else - source.Reply(_("Bot will now kick \002colors\002.")); + source.Reply(_("Bot will now kick for \002colors\002.")); } else { - ci->botflags.UnsetFlag(BS_KICK_COLORS); - source.Reply(_("Bot won't kick \002colors\002 anymore.")); + ci->Shrink("BS_KICK_COLORS"); + source.Reply(_("Bot won't kick for \002colors\002 anymore.")); } } else if (option.equals_ci("FLOOD")) @@ -257,16 +259,17 @@ class CommandBSKick : public Command if (ci->floodsecs > Config->BSKeepData) ci->floodsecs = Config->BSKeepData; - ci->botflags.SetFlag(BS_KICK_FLOOD); + ci->ExtendMetadata("BS_KICK_FLOOD"); if (ci->ttb[TTB_FLOOD]) - source.Reply(_("Bot will now kick \002flood\002 (%d lines in %d seconds and\nwill place a ban after %d kicks for the same user."), ci->floodlines, ci->floodsecs, ci->ttb[TTB_FLOOD]); + source.Reply(_("Bot will now kick for \002flood\002 (%d lines in %d seconds\n" + "and will place a ban after %d kicks for the same user."), ci->floodlines, ci->floodsecs, ci->ttb[TTB_FLOOD]); else - source.Reply(_("Bot will now kick \002flood\002 (%d lines in %d seconds)."), ci->floodlines, ci->floodsecs); + source.Reply(_("Bot will now kick for \002flood\002 (%d lines in %d seconds)."), ci->floodlines, ci->floodsecs); } else { - ci->botflags.UnsetFlag(BS_KICK_FLOOD); - source.Reply(_("Bot won't kick \002flood\002 anymore.")); + ci->Shrink("BS_KICK_FLOOD"); + source.Reply(_("Bot won't kick for \002flood\002 anymore.")); } } else if (option.equals_ci("REPEAT")) @@ -302,19 +305,19 @@ class CommandBSKick : public Command if (ci->repeattimes < 2) ci->repeattimes = 3; - ci->botflags.SetFlag(BS_KICK_REPEAT); + ci->ExtendMetadata("BS_KICK_REPEAT"); if (ci->ttb[TTB_REPEAT]) - source.Reply(_("Bot will now kick \002repeats\002 (users that say the\n" - "same thing %d times), and will place a ban after %d \n" + source.Reply(_("Bot will now kick for \002repeats\002 (users that say the\n" + "same thing %d times), and will place a ban after %d\n" "kicks for the same user."), ci->repeattimes, ci->ttb[TTB_REPEAT]); else - source.Reply(_("Bot will now kick \002repeats\002 (users that say the\n" + source.Reply(_("Bot will now kick for \002repeats\002 (users that say the\n" "same thing %d times)."), ci->repeattimes); } else { - ci->botflags.UnsetFlag(BS_KICK_REPEAT); - source.Reply(_("Bot won't kick \002repeats\002 anymore.")); + ci->Shrink("BS_KICK_REPEAT"); + source.Reply(_("Bot won't kick for \002repeats\002 anymore.")); } } else if (option.equals_ci("REVERSES")) @@ -338,16 +341,17 @@ class CommandBSKick : public Command } else ci->ttb[TTB_REVERSES] = 0; - ci->botflags.SetFlag(BS_KICK_REVERSES); + ci->ExtendMetadata("BS_KICK_REVERSES"); if (ci->ttb[TTB_REVERSES]) - source.Reply(_("Bot will now kick \002reverses\002, and will place a ban after %d\nkicks for the same user."), ci->ttb[TTB_REVERSES]); + source.Reply(_("Bot will now kick for \002reverses\002, and will place a ban\n" + "after %d kicks for the same user."), ci->ttb[TTB_REVERSES]); else - source.Reply(_("Bot will now kick \002reverses\002.")); + source.Reply(_("Bot will now kick for \002reverses\002.")); } else { - ci->botflags.UnsetFlag(BS_KICK_REVERSES); - source.Reply(_("Bot won't kick \002reverses\002 anymore.")); + ci->Shrink("BS_KICK_REVERSES"); + source.Reply(_("Bot won't kick for \002reverses\002 anymore.")); } } else if (option.equals_ci("UNDERLINES")) @@ -372,16 +376,17 @@ class CommandBSKick : public Command else ci->ttb[TTB_UNDERLINES] = 0; - ci->botflags.SetFlag(BS_KICK_UNDERLINES); + ci->ExtendMetadata("BS_KICK_UNDERLINES"); if (ci->ttb[TTB_UNDERLINES]) - source.Reply(_("Bot will now kick \002underlines\002, and will place a ban after %d\nkicks for the same user."), ci->ttb[TTB_UNDERLINES]); + source.Reply(_("Bot will now kick for \002underlines\002, and will place a ban\n" + "after %d kicks for the same user."), ci->ttb[TTB_UNDERLINES]); else - source.Reply(_("Bot will now kick \002underlines\002.")); + source.Reply(_("Bot will now kick for \002underlines\002.")); } else { - ci->botflags.UnsetFlag(BS_KICK_UNDERLINES); - source.Reply(_("Bot won't kick \002underlines\002 anymore.")); + ci->Shrink("BS_KICK_UNDERLINES"); + source.Reply(_("Bot won't kick for \002underlines\002 anymore.")); } } else if (option.equals_ci("ITALICS")) @@ -406,16 +411,17 @@ class CommandBSKick : public Command else ci->ttb[TTB_ITALICS] = 0; - ci->botflags.SetFlag(BS_KICK_ITALICS); + ci->ExtendMetadata("BS_KICK_ITALICS"); if (ci->ttb[TTB_ITALICS]) - source.Reply(_("Bot will now kick \002italics\002, and will place a ban after\n%d kicks for the same user."), ci->ttb[TTB_ITALICS]); + source.Reply(_("Bot will now kick for \002italics\002, and will place a ban\n" + "after %d kicks for the same user."), ci->ttb[TTB_ITALICS]); else - source.Reply(_("Bot will now kick \002italics\002.")); + source.Reply(_("Bot will now kick for \002italics\002.")); } else { - ci->botflags.UnsetFlag(BS_KICK_ITALICS); - source.Reply(_("Bot won't kick \002italics\002 anymore.")); + ci->Shrink("BS_KICK_ITALICS"); + source.Reply(_("Bot won't kick for \002italics\002 anymore.")); } } else if (option.equals_ci("AMSGS")) @@ -440,15 +446,16 @@ class CommandBSKick : public Command else ci->ttb[TTB_AMSGS] = 0; - ci->botflags.SetFlag(BS_KICK_AMSGS); + ci->ExtendMetadata("BS_KICK_AMSGS"); if (ci->ttb[TTB_AMSGS]) - source.Reply(_("Bot will now kick for \002amsgs\002, and will place a ban after %d\nkicks for the same user."), ci->ttb[TTB_AMSGS]); + source.Reply(_("Bot will now kick for \002amsgs\002, and will place a ban\n" + "after %d kicks for the same user."), ci->ttb[TTB_AMSGS]); else source.Reply(_("Bot will now kick for \002amsgs\002")); } else { - ci->botflags.UnsetFlag(BS_KICK_AMSGS); + ci->Shrink("BS_KICK_AMSGS"); source.Reply(_("Bot won't kick for \002amsgs\002 anymore.")); } } @@ -485,7 +492,7 @@ class CommandBSKick : public Command "level SET."), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str()); } else if (subcommand.equals_ci("BADWORDS")) - source.Reply(_("Syntax: \002\037#channel\037 BADWORDS {\037ON|OFF\037} [\037ttb\037]\002\n" + source.Reply(_("Syntax: \002\037channel\037 BADWORDS {\037ON|OFF\037} [\037ttb\037]\002\n" "Sets the bad words kicker on or off. When enabled, this\n" "option tells the bot to kick users who say certain words\n" "on the channels.\n" @@ -508,7 +515,7 @@ class CommandBSKick : public Command "option tells the bot to kick users who are talking in\n" "CAPS.\n" "The bot kicks only if there are at least \002min\002 caps\n" - "and they constitute at least \002percent\002%% of the total \n" + "and they constitute at least \002percent\002%% of the total\n" "text line (if not given, it defaults to 10 characters\n" "and 25%%).\n" "ttb is the number of times a user can be kicked\n" @@ -708,7 +715,7 @@ class BSKick : public Module UserData *GetUserData(User *u, Channel *c) { - UserContainer *uc = c->FindUser(u); + ChanUserContainer *uc = c->FindUser(u); if (uc == NULL) return NULL; @@ -741,7 +748,7 @@ class BSKick : public Module Anope::string mask = ci->GetIdealBan(u); - ci->c->SetMode(NULL, CMODE_BAN, mask); + ci->c->SetMode(NULL, "BAN", mask); FOREACH_MOD(I_OnBotBan, OnBotBan(u, ci, mask)); } } @@ -776,7 +783,7 @@ class BSKick : public Module for (channel_map::const_iterator cit = ChannelList.begin(), cit_end = ChannelList.end(); cit != cit_end; ++cit) { Channel *c = cit->second; - for (CUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ++it) + for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ++it) (*it)->Shrink("bs_main_userdata"); c->Shrink("bs_main_bandata"); } @@ -796,15 +803,11 @@ class BSKick : public Module if (ci == NULL) return; - bool Allow = true; if (ci->AccessFor(u).HasPriv("NOKICK")) - Allow = false; - else if (ci->botflags.HasFlag(BS_DONTKICKOPS) && (c->HasUserStatus(u, CMODE_HALFOP) || c->HasUserStatus(u, CMODE_OP) || c->HasUserStatus(u, CMODE_PROTECT) || c->HasUserStatus(u, CMODE_OWNER))) - Allow = false; - else if (ci->botflags.HasFlag(BS_DONTKICKVOICES) && c->HasUserStatus(u, CMODE_VOICE)) - Allow = false; - - if (!Allow) + return; + else if (ci->HasExt("BS_DONTKICKOPS") && (c->HasUserStatus(u, "HALFOP") || c->HasUserStatus(u, "OP") || c->HasUserStatus(u, "PROTECT") || c->HasUserStatus(u, "OWNER"))) + return; + else if (ci->HasExt("BS_DONTKICKVOICES") && c->HasUserStatus(u, "VOICE")) return; Anope::string realbuf = msg; @@ -822,7 +825,7 @@ class BSKick : public Module return; /* Bolds kicker */ - if (ci->botflags.HasFlag(BS_KICK_BOLDS) && realbuf.find(2) != Anope::string::npos) + if (ci->HasExt("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!")); @@ -830,7 +833,7 @@ class BSKick : public Module } /* Color kicker */ - if (ci->botflags.HasFlag(BS_KICK_COLORS) && realbuf.find(3) != Anope::string::npos) + if (ci->HasExt("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!")); @@ -838,7 +841,7 @@ class BSKick : public Module } /* Reverses kicker */ - if (ci->botflags.HasFlag(BS_KICK_REVERSES) && realbuf.find(22) != Anope::string::npos) + if (ci->HasExt("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!")); @@ -846,7 +849,7 @@ class BSKick : public Module } /* Italics kicker */ - if (ci->botflags.HasFlag(BS_KICK_ITALICS) && realbuf.find(29) != Anope::string::npos) + if (ci->HasExt("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!")); @@ -854,7 +857,7 @@ class BSKick : public Module } /* Underlines kicker */ - if (ci->botflags.HasFlag(BS_KICK_UNDERLINES) && realbuf.find(31) != Anope::string::npos) + if (ci->HasExt("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!")); @@ -862,7 +865,7 @@ class BSKick : public Module } /* Caps kicker */ - if (ci->botflags.HasFlag(BS_KICK_CAPS) && realbuf.length() >= static_cast<unsigned>(ci->capsmin)) + if (ci->HasExt("BS_KICK_CAPS") && realbuf.length() >= static_cast<unsigned>(ci->capsmin)) { int i = 0, l = 0; @@ -888,7 +891,7 @@ class BSKick : public Module } /* Bad words kicker */ - if (ci->botflags.HasFlag(BS_KICK_BADWORDS)) + if (ci->HasExt("BS_KICK_BADWORDS")) { bool mustkick = false; @@ -969,7 +972,7 @@ class BSKick : public Module if (ud) { /* Flood kicker */ - if (ci->botflags.HasFlag(BS_KICK_FLOOD)) + if (ci->HasExt("BS_KICK_FLOOD")) { if (Anope::CurTime - ud->last_start > ci->floodsecs) { @@ -987,7 +990,7 @@ class BSKick : public Module } /* Repeat kicker */ - if (ci->botflags.HasFlag(BS_KICK_REPEAT)) + if (ci->HasExt("BS_KICK_REPEAT")) { if (!ud->lastline.equals_ci(realbuf)) ud->times = 0; @@ -1004,12 +1007,12 @@ class BSKick : public Module if (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();) + for (User::ChanUserList::iterator it = u->chans.begin(); it != u->chans.end();) { Channel *chan = (*it)->chan; ++it; - if (chan->ci && chan->ci->botflags.HasFlag(BS_KICK_AMSGS) && !chan->ci->AccessFor(u).HasPriv("NOKICK")) + if (chan->ci && chan->ci->HasExt("BS_KICK_AMSGS") && !chan->ci->AccessFor(u).HasPriv("NOKICK")) { check_ban(chan->ci, u, TTB_AMSGS); bot_kick(chan->ci, u, _("Don't use AMSGs!")); diff --git a/modules/commands/bs_set.cpp b/modules/commands/bs_set.cpp index 6f458bec0..123120289 100644 --- a/modules/commands/bs_set.cpp +++ b/modules/commands/bs_set.cpp @@ -1,6 +1,6 @@ /* BotServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -9,8 +9,6 @@ * Based on the original code of Services by Andy Church. */ -/*************************************************************************/ - #include "module.h" class CommandBSSet : public Command @@ -56,13 +54,375 @@ class CommandBSSet : public Command } }; +class CommandBSSetDontKickOps : public Command +{ + public: + CommandBSSetDontKickOps(Module *creator, const Anope::string &sname = "botserv/set/dontkickops") : Command(creator, sname, 2, 2) + { + this->SetDesc(_("To protect ops against bot kicks")); + this->SetSyntax(_("\037channel\037 {ON | OFF}")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + ChannelInfo *ci = ChannelInfo::Find(params[0]); + if (ci == NULL) + { + source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); + return; + } + + AccessGroup access = source.AccessFor(ci); + if (!source.HasPriv("botserv/administration") && !access.HasPriv("SET")) + { + source.Reply(ACCESS_DENIED); + return; + } + + if (Anope::ReadOnly) + { + source.Reply(_("Sorry, bot option setting is temporarily disabled.")); + return; + } + + if (params[1].equals_ci("ON")) + { + bool override = !access.HasPriv("SET"); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enable dontkickops"; + + ci->ExtendMetadata("BS_DONTKICKOPS"); + source.Reply(_("Bot \002won't kick ops\002 on channel %s."), ci->name.c_str()); + } + else if (params[1].equals_ci("OFF")) + { + bool override = !access.HasPriv("SET"); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to disable dontkickops"; + + ci->Shrink("BS_DONTKICKOPS"); + source.Reply(_("Bot \002will kick ops\002 on channel %s."), ci->name.c_str()); + } + else + this->OnSyntaxError(source, source.command); + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(_(" \n" + "Enables or disables \002ops protection\002 mode on a channel.\n" + "When it is enabled, ops won't be kicked by the bot\n" + "even if they don't match the NOKICK level.")); + return true; + } +}; + +class CommandBSSetDontKickVoices : public Command +{ + public: + CommandBSSetDontKickVoices(Module *creator, const Anope::string &sname = "botserv/set/dontkickvoices") : Command(creator, sname, 2, 2) + { + this->SetDesc(_("To protect voices against bot kicks")); + this->SetSyntax(_("\037channel\037 {ON | OFF}")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + ChannelInfo *ci = ChannelInfo::Find(params[0]); + if (ci == NULL) + { + source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); + return; + } + + AccessGroup access = source.AccessFor(ci); + if (!source.HasPriv("botserv/administration") && !access.HasPriv("SET")) + { + source.Reply(ACCESS_DENIED); + return; + } + + if (Anope::ReadOnly) + { + source.Reply(_("Sorry, bot option setting is temporarily disabled.")); + return; + } + + if (params[1].equals_ci("ON")) + { + bool override = !access.HasPriv("SET"); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enable dontkickvoices"; + + ci->ExtendMetadata("BS_DONTKICKVOICES"); + source.Reply(_("Bot \002won't kick voices\002 on channel %s."), ci->name.c_str()); + } + else if (params[1].equals_ci("OFF")) + { + bool override = !access.HasPriv("SET"); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to disable dontkickvoices"; + + ci->Shrink("BS_DONTKICKVOICES"); + source.Reply(_("Bot \002will kick voices\002 on channel %s."), ci->name.c_str()); + } + else + this->OnSyntaxError(source, source.command); + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(_(" \n" + "Enables or disables \002voices protection\002 mode on a channel.\n" + "When it is enabled, voices won't be kicked by the bot\n" + "even if they don't match the NOKICK level.")); + return true; + } +}; + +class CommandBSSetFantasy : public Command +{ + public: + CommandBSSetFantasy(Module *creator, const Anope::string &sname = "botserv/set/fantasy") : Command(creator, sname, 2, 2) + { + this->SetDesc(_("Enable fantaisist commands")); + this->SetSyntax(_("\037channel\037 {\037ON|OFF\037}")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + ChannelInfo *ci = ChannelInfo::Find(params[0]); + const Anope::string &value = params[1]; + + if (ci == NULL) + { + source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); + return; + } + + if (!source.HasPriv("botserv/administration") && !source.AccessFor(ci).HasPriv("SET")) + { + source.Reply(ACCESS_DENIED); + return; + } + + if (Anope::ReadOnly) + { + source.Reply(_("Sorry, bot option setting is temporarily disabled.")); + return; + } + + if (value.equals_ci("ON")) + { + bool override = !source.AccessFor(ci).HasPriv("SET"); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enable fantasy"; + + ci->ExtendMetadata("BS_FANTASY"); + source.Reply(_("Fantasy mode is now \002on\002 on channel %s."), ci->name.c_str()); + } + else if (value.equals_ci("OFF")) + { + bool override = !source.AccessFor(ci).HasPriv("SET"); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to disable fantasy"; + + ci->Shrink("BS_FANTASY"); + source.Reply(_("Fantasy mode is now \002off\002 on channel %s."), ci->name.c_str()); + } + else + this->OnSyntaxError(source, source.command); + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(_(" \n" + "Enables or disables \002fantasy\002 mode on a channel.\n" + "When it is enabled, users will be able to use\n" + "%s commands on a channel when prefixed\n" + "with one of the following fantasy characters: \002%s\002\n" + " \n" + "Note that users wanting to use fantaisist\n" + "commands MUST have enough level for both\n" + "the FANTASIA and another level depending\n" + "of the command if required (for example, to use\n" + "!op, user must have enough access for the OPDEOP\n" + "level)."), Config->ChanServ.c_str(), Config->BSFantasyCharacter.c_str()); + return true; + } +}; + +class CommandBSSetGreet : public Command +{ + public: + CommandBSSetGreet(Module *creator, const Anope::string &sname = "botserv/set/greet") : Command(creator, sname, 2, 2) + { + this->SetDesc(_("Enable greet messages")); + this->SetSyntax(_("\037channel\037 {\037ON|OFF\037}")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + ChannelInfo *ci = ChannelInfo::Find(params[0]); + const Anope::string &value = params[1]; + + if (ci == NULL) + { + source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); + return; + } + + if (!source.HasPriv("botserv/administration") && !source.AccessFor(ci).HasPriv("SET")) + { + source.Reply(ACCESS_DENIED); + return; + } + + if (Anope::ReadOnly) + { + source.Reply(_("Sorry, bot option setting is temporarily disabled.")); + return; + } + + if (value.equals_ci("ON")) + { + bool override = !source.AccessFor(ci).HasPriv("SET"); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enable greets"; + + ci->ExtendMetadata("BS_GREET"); + source.Reply(_("Greet mode is now \002on\002 on channel %s."), ci->name.c_str()); + } + else if (value.equals_ci("OFF")) + { + bool override = !source.AccessFor(ci).HasPriv("SET"); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to disable greets"; + + ci->Shrink("BS_GREET"); + source.Reply(_("Greet mode is now \002off\002 on channel %s."), ci->name.c_str()); + } + else + this->OnSyntaxError(source, source.command); + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(_(" \n" + "Enables or disables \002greet\002 mode on a channel.\n" + "When it is enabled, the bot will display greet\n" + "messages of users joining the channel, provided\n" + "they have enough access to the channel.")); + return true; + } +}; + +class CommandBSSetNoBot : public Command +{ + public: + CommandBSSetNoBot(Module *creator, const Anope::string &sname = "botserv/set/nobot") : Command(creator, sname, 2, 2) + { + this->SetDesc(_("Prevent a bot from being assigned to a channel")); + this->SetSyntax(_("\037channel\037 {\037ON|OFF\037}")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + ChannelInfo *ci = ChannelInfo::Find(params[0]); + const Anope::string &value = params[1]; + + if (ci == NULL) + { + source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); + return; + } + + if (value.equals_ci("ON")) + { + bool override = !source.AccessFor(ci).HasPriv("SET"); + Log(override ? LOG_ADMIN : LOG_COMMAND, source, this, ci) << "to enable nobot"; + + ci->ExtendMetadata("BS_NOBOT"); + if (ci->bi) + ci->bi->UnAssign(source.GetUser(), ci); + source.Reply(_("No-bot mode is now \002on\002 on channel %s."), ci->name.c_str()); + } + else if (value.equals_ci("OFF")) + { + bool override = !source.AccessFor(ci).HasPriv("SET"); + Log(override ? LOG_ADMIN : LOG_COMMAND, source, this, ci) << "to disable nobot"; + + ci->Shrink("BS_NOBOT"); + source.Reply(_("No-bot mode is now \002off\002 on channel %s."), ci->name.c_str()); + } + else + this->OnSyntaxError(source, source.command); + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(_(" \n" + "This option makes a channel be unassignable. If a bot\n" + "is already assigned to the channel, it is unassigned\n" + "automatically when you enable the option.")); + return true; + } +}; + +class CommandBSSetPrivate : public Command +{ + public: + CommandBSSetPrivate(Module *creator, const Anope::string &sname = "botserv/set/private") : Command(creator, sname, 2, 2) + { + this->SetDesc(_("Prevent a bot from being assigned by non IRC operators")); + this->SetSyntax(_("\037botname\037 {\037ON|OFF\037}")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + BotInfo *bi = BotInfo::Find(params[0], true); + const Anope::string &value = params[1]; + + if (bi == NULL) + { + source.Reply(BOT_DOES_NOT_EXIST, params[0].c_str()); + return; + } + + if (value.equals_ci("ON")) + { + bi->ExtendMetadata("PRIVATE"); + source.Reply(_("Private mode of bot %s is now \002on\002."), bi->nick.c_str()); + } + else if (value.equals_ci("OFF")) + { + bi->Shrink("PRIVATE"); + source.Reply(_("Private mode of bot %s is now \002off\002."), bi->nick.c_str()); + } + else + this->OnSyntaxError(source, source.command); + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(_(" \n" + "This option prevents a bot from being assigned to a\n" + "channel by users that aren't IRC Operators.")); + return true; + } +}; + class BSSet : public Module { CommandBSSet commandbsset; + CommandBSSetDontKickOps commandbssetdontkickops; + CommandBSSetDontKickVoices commandbssetdontkickvoices; + CommandBSSetFantasy commandbssetfantasy; + CommandBSSetNoBot commandbssetnobot; + CommandBSSetPrivate commandbssetprivate; public: BSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandbsset(this) + commandbsset(this), commandbssetdontkickops(this), commandbssetdontkickvoices(this), + commandbssetfantasy(this), commandbssetnobot(this), commandbssetprivate(this) { this->SetAuthor("Anope"); diff --git a/modules/commands/bs_set_dontkickops.cpp b/modules/commands/bs_set_dontkickops.cpp deleted file mode 100644 index 5346074a6..000000000 --- a/modules/commands/bs_set_dontkickops.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* BotServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandBSSetDontKickOps : public Command -{ - public: - CommandBSSetDontKickOps(Module *creator, const Anope::string &sname = "botserv/set/dontkickops") : Command(creator, sname, 2, 2) - { - this->SetDesc(_("To protect ops against bot kicks")); - this->SetSyntax(_("\037channel\037 {ON | OFF}")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - ChannelInfo *ci = ChannelInfo::Find(params[0]); - if (ci == NULL) - { - source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); - return; - } - - AccessGroup access = source.AccessFor(ci); - if (!source.HasPriv("botserv/administration") && !access.HasPriv("SET")) - { - source.Reply(ACCESS_DENIED); - return; - } - - if (Anope::ReadOnly) - { - source.Reply(_("Sorry, bot option setting is temporarily disabled.")); - return; - } - - if (params[1].equals_ci("ON")) - { - bool override = !access.HasPriv("SET"); - Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enable dontkickops"; - - ci->botflags.SetFlag(BS_DONTKICKOPS); - source.Reply(_("Bot \002won't kick ops\002 on channel %s."), ci->name.c_str()); - } - else if (params[1].equals_ci("OFF")) - { - bool override = !access.HasPriv("SET"); - Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to disable dontkickops"; - - ci->botflags.UnsetFlag(BS_DONTKICKOPS); - source.Reply(_("Bot \002will kick ops\002 on channel %s."), ci->name.c_str()); - } - else - this->OnSyntaxError(source, source.command); - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(_(" \n" - "Enables or disables \002ops protection\002 mode on a channel.\n" - "When it is enabled, ops won't be kicked by the bot\n" - "even if they don't match the NOKICK level.")); - return true; - } -}; - -class BSSetDontKickOps : public Module -{ - CommandBSSetDontKickOps commandbssetdontkickops; - - public: - BSSetDontKickOps(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandbssetdontkickops(this) - { - this->SetAuthor("Anope"); - } -}; - -MODULE_INIT(BSSetDontKickOps) diff --git a/modules/commands/bs_set_dontkickvoices.cpp b/modules/commands/bs_set_dontkickvoices.cpp deleted file mode 100644 index b4b0cd7ec..000000000 --- a/modules/commands/bs_set_dontkickvoices.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* BotServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandBSSetDontKickVoices : public Command -{ - public: - CommandBSSetDontKickVoices(Module *creator, const Anope::string &sname = "botserv/set/dontkickvoices") : Command(creator, sname, 2, 2) - { - this->SetDesc(_("To protect voices against bot kicks")); - this->SetSyntax(_("\037channel\037 {ON | OFF}")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - ChannelInfo *ci = ChannelInfo::Find(params[0]); - if (ci == NULL) - { - source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); - return; - } - - AccessGroup access = source.AccessFor(ci); - if (!source.HasPriv("botserv/administration") && !access.HasPriv("SET")) - { - source.Reply(ACCESS_DENIED); - return; - } - - if (Anope::ReadOnly) - { - source.Reply(_("Sorry, bot option setting is temporarily disabled.")); - return; - } - - if (params[1].equals_ci("ON")) - { - bool override = !access.HasPriv("SET"); - Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enable dontkickvoices"; - - ci->botflags.SetFlag(BS_DONTKICKVOICES); - source.Reply(_("Bot \002won't kick voices\002 on channel %s."), ci->name.c_str()); - } - else if (params[1].equals_ci("OFF")) - { - bool override = !access.HasPriv("SET"); - Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to disable dontkickvoices"; - - ci->botflags.UnsetFlag(BS_DONTKICKVOICES); - source.Reply(_("Bot \002will kick voices\002 on channel %s."), ci->name.c_str()); - } - else - this->OnSyntaxError(source, source.command); - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(_(" \n" - "Enables or disables \002voices protection\002 mode on a channel.\n" - "When it is enabled, voices won't be kicked by the bot\n" - "even if they don't match the NOKICK level.")); - return true; - } -}; - -class BSSetDontKickVoices : public Module -{ - CommandBSSetDontKickVoices commandbssetdontkickvoices; - - public: - BSSetDontKickVoices(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandbssetdontkickvoices(this) - { - this->SetAuthor("Anope"); - } -}; - -MODULE_INIT(BSSetDontKickVoices) diff --git a/modules/commands/bs_set_fantasy.cpp b/modules/commands/bs_set_fantasy.cpp deleted file mode 100644 index 29c722026..000000000 --- a/modules/commands/bs_set_fantasy.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/* BotServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandBSSetFantasy : public Command -{ - public: - CommandBSSetFantasy(Module *creator, const Anope::string &sname = "botserv/set/fantasy") : Command(creator, sname, 2, 2) - { - this->SetDesc(_("Enable fantaisist commands")); - this->SetSyntax(_("\037channel\037 {\037ON|OFF\037}")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - ChannelInfo *ci = ChannelInfo::Find(params[0]); - const Anope::string &value = params[1]; - - if (ci == NULL) - { - source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); - return; - } - - if (!source.HasPriv("botserv/administration") && !source.AccessFor(ci).HasPriv("SET")) - { - source.Reply(ACCESS_DENIED); - return; - } - - if (Anope::ReadOnly) - { - source.Reply(_("Sorry, bot option setting is temporarily disabled.")); - return; - } - - if (value.equals_ci("ON")) - { - bool override = !source.AccessFor(ci).HasPriv("SET"); - Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enable fantasy"; - - ci->botflags.SetFlag(BS_FANTASY); - source.Reply(_("Fantasy mode is now \002on\002 on channel %s."), ci->name.c_str()); - } - else if (value.equals_ci("OFF")) - { - bool override = !source.AccessFor(ci).HasPriv("SET"); - Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to disable fantasy"; - - ci->botflags.UnsetFlag(BS_FANTASY); - source.Reply(_("Fantasy mode is now \002off\002 on channel %s."), ci->name.c_str()); - } - else - this->OnSyntaxError(source, source.command); - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(_(" \n" - "Enables or disables \002fantasy\002 mode on a channel.\n" - "When it is enabled, users will be able to use\n" - "%s commands on a channel when prefixed\n" - "with one of the following fantasy characters: \002%s\002\n" - " \n" - "Note that users wanting to use fantaisist\n" - "commands MUST have enough level for both\n" - "the FANTASIA and another level depending\n" - "of the command if required (for example, to use \n" - "!op, user must have enough access for the OPDEOP\n" - "level)."), Config->ChanServ.c_str(), Config->BSFantasyCharacter.c_str()); - return true; - } -}; - -class BSSetFantasy : public Module -{ - CommandBSSetFantasy commandbssetfantasy; - - public: - BSSetFantasy(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandbssetfantasy(this) - { - this->SetAuthor("Anope"); - } -}; - -MODULE_INIT(BSSetFantasy) diff --git a/modules/commands/bs_set_greet.cpp b/modules/commands/bs_set_greet.cpp deleted file mode 100644 index ad5220203..000000000 --- a/modules/commands/bs_set_greet.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/* BotServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandBSSetGreet : public Command -{ - public: - CommandBSSetGreet(Module *creator, const Anope::string &sname = "botserv/set/greet") : Command(creator, sname, 2, 2) - { - this->SetDesc(_("Enable greet messages")); - this->SetSyntax(_("\037channel\037 {\037ON|OFF\037}")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - ChannelInfo *ci = ChannelInfo::Find(params[0]); - const Anope::string &value = params[1]; - - if (ci == NULL) - { - source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); - return; - } - - if (!source.HasPriv("botserv/administration") && !source.AccessFor(ci).HasPriv("SET")) - { - source.Reply(ACCESS_DENIED); - return; - } - - if (Anope::ReadOnly) - { - source.Reply(_("Sorry, bot option setting is temporarily disabled.")); - return; - } - - if (value.equals_ci("ON")) - { - bool override = !source.AccessFor(ci).HasPriv("SET"); - Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enable greets"; - - ci->botflags.SetFlag(BS_GREET); - source.Reply(_("Greet mode is now \002on\002 on channel %s."), ci->name.c_str()); - } - else if (value.equals_ci("OFF")) - { - bool override = !source.AccessFor(ci).HasPriv("SET"); - Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to disable greets"; - - ci->botflags.UnsetFlag(BS_GREET); - source.Reply(_("Greet mode is now \002off\002 on channel %s."), ci->name.c_str()); - } - else - this->OnSyntaxError(source, source.command); - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(_(" \n" - "Enables or disables \002greet\002 mode on a channel.\n" - "When it is enabled, the bot will display greet\n" - "messages of users joining the channel, provided\n" - "they have enough access to the channel.")); - return true; - } -}; - -class BSSetGreet : public Module -{ - CommandBSSetGreet commandbssetgreet; - - public: - BSSetGreet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandbssetgreet(this) - { - this->SetAuthor("Anope"); - } -}; - -MODULE_INIT(BSSetGreet) diff --git a/modules/commands/bs_set_nobot.cpp b/modules/commands/bs_set_nobot.cpp deleted file mode 100644 index f3f749aa5..000000000 --- a/modules/commands/bs_set_nobot.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* BotServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandBSSetNoBot : public Command -{ - public: - CommandBSSetNoBot(Module *creator, const Anope::string &sname = "botserv/set/nobot") : Command(creator, sname, 2, 2) - { - this->SetDesc(_("Prevent a bot from being assigned to a channel")); - this->SetSyntax(_("\037channel\037 {\037ON|OFF\037}")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - ChannelInfo *ci = ChannelInfo::Find(params[0]); - const Anope::string &value = params[1]; - - if (ci == NULL) - { - source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); - return; - } - - if (!source.HasCommand("botserv/set/nobot")) - { - source.Reply(ACCESS_DENIED); - return; - } - - if (value.equals_ci("ON")) - { - bool override = !source.AccessFor(ci).HasPriv("SET"); - Log(override ? LOG_ADMIN : LOG_COMMAND, source, this, ci) << "to enable nobot"; - - ci->botflags.SetFlag(BS_NOBOT); - if (ci->bi) - ci->bi->UnAssign(source.GetUser(), ci); - source.Reply(_("No Bot mode is now \002on\002 on channel %s."), ci->name.c_str()); - } - else if (value.equals_ci("OFF")) - { - bool override = !source.AccessFor(ci).HasPriv("SET"); - Log(override ? LOG_ADMIN : LOG_COMMAND, source, this, ci) << "to disable nobot"; - - ci->botflags.UnsetFlag(BS_NOBOT); - source.Reply(_("No Bot mode is now \002off\002 on channel %s."), ci->name.c_str()); - } - else - this->OnSyntaxError(source, source.command); - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(_(" \n" - "This option makes a channel be unassignable. If a bot \n" - "is already assigned to the channel, it is unassigned\n" - "automatically when you enable the option.")); - return true; - } -}; - -class BSSetNoBot : public Module -{ - CommandBSSetNoBot commandbssetnobot; - - public: - BSSetNoBot(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandbssetnobot(this) - { - this->SetAuthor("Anope"); - } -}; - -MODULE_INIT(BSSetNoBot) diff --git a/modules/commands/bs_set_private.cpp b/modules/commands/bs_set_private.cpp deleted file mode 100644 index 920c97d37..000000000 --- a/modules/commands/bs_set_private.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* BotServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandBSSetPrivate : public Command -{ - public: - CommandBSSetPrivate(Module *creator, const Anope::string &sname = "botserv/set/private") : Command(creator, sname, 2, 2) - { - this->SetDesc(_("Prevent a bot from being assigned by non IRC operators")); - this->SetSyntax(_("\037botname\037 {\037ON|OFF\037}")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - BotInfo *bi = BotInfo::Find(params[0], true); - const Anope::string &value = params[1]; - - if (bi == NULL) - { - source.Reply(BOT_DOES_NOT_EXIST, params[0].c_str()); - return; - } - - if (!source.HasCommand("botserv/set/private")) - { - source.Reply(ACCESS_DENIED); - return; - } - - if (value.equals_ci("ON")) - { - bi->SetFlag(BI_PRIVATE); - source.Reply(_("Private mode of bot %s is now \002on\002."), bi->nick.c_str()); - } - else if (value.equals_ci("OFF")) - { - bi->UnsetFlag(BI_PRIVATE); - source.Reply(_("Private mode of bot %s is now \002off\002."), bi->nick.c_str()); - } - else - this->OnSyntaxError(source, source.command); - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(_(" \n" - "This option prevents a bot from being assigned to a\n" - "channel by users that aren't IRC operators.")); - return true; - } -}; - -class BSSetPrivate : public Module -{ - CommandBSSetPrivate commandbssetprivate; - - public: - BSSetPrivate(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandbssetprivate(this) - { - this->SetAuthor("Anope"); - } -}; - -MODULE_INIT(BSSetPrivate) diff --git a/modules/commands/cs_access.cpp b/modules/commands/cs_access.cpp index ed6f4f7fa..239c344ab 100644 --- a/modules/commands/cs_access.cpp +++ b/modules/commands/cs_access.cpp @@ -1,6 +1,6 @@ /* ChanServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -188,7 +188,7 @@ class CommandCSAccess : public Command { Anope::string mask = params[2]; - if (mask.find_first_of("!*@") == Anope::string::npos && !NickAlias::Find(mask)) + if (!isdigit(mask[0]) && mask.find_first_of("!*@") == Anope::string::npos && !NickAlias::Find(mask)) { User *targ = User::Find(mask, true); if (targ != NULL) @@ -286,7 +286,7 @@ class CommandCSAccess : public Command Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to delete " << access->mask; FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, source, access)); - ci->EraseAccess(access); + delete access; } return; } @@ -325,7 +325,7 @@ class CommandCSAccess : public Command Anope::string timebuf; if (ci->c) - for (CUserList::const_iterator cit = ci->c->users.begin(), cit_end = ci->c->users.end(); cit != cit_end; ++cit) + for (Channel::ChanUserList::const_iterator cit = ci->c->users.begin(), cit_end = ci->c->users.end(); cit != cit_end; ++cit) if (access->Matches((*cit)->user, (*cit)->user->Account())) timebuf = "Now"; if (timebuf.empty()) @@ -359,7 +359,7 @@ class CommandCSAccess : public Command Anope::string timebuf; if (ci->c) - for (CUserList::const_iterator cit = ci->c->users.begin(), cit_end = ci->c->users.end(); cit != cit_end; ++cit) + for (Channel::ChanUserList::const_iterator cit = ci->c->users.begin(), cit_end = ci->c->users.end(); cit != cit_end; ++cit) if (access->Matches((*cit)->user, (*cit)->user->Account())) timebuf = "Now"; if (timebuf.empty()) @@ -604,7 +604,7 @@ class CommandCSLevels : public Command { Privilege *p = PrivilegeManager::FindPrivilege(what); if (p == NULL) - source.Reply(_("Setting \002%s\002 not known. Type \002%s%s HELP LEVELS \002 for a list of valid settings."), what.c_str(), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str()); + source.Reply(_("Setting \002%s\002 not known. Type \002%s%s HELP LEVELS\002 for a list of valid settings."), what.c_str(), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str()); else { ci->SetLevel(p->name, level); @@ -642,7 +642,7 @@ class CommandCSLevels : public Command } } - source.Reply(_("Setting \002%s\002 not known. Type \002%s%s HELP LEVELS \002 for a list of valid settings."), what.c_str(), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str()); + source.Reply(_("Setting \002%s\002 not known. Type \002%s%s HELP LEVELS\002 for a list of valid settings."), what.c_str(), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str()); return; } @@ -741,7 +741,7 @@ class CommandCSLevels : public Command { if (subcommand.equals_ci("DESC")) { - source.Reply(_("The following feature/function names are understood.")); + source.Reply(_("The following feature/function names are available:")); ListFormatter list; list.AddColumn("Name").AddColumn("Description"); diff --git a/modules/commands/cs_akick.cpp b/modules/commands/cs_akick.cpp index 9447b1aed..3eea49097 100644 --- a/modules/commands/cs_akick.cpp +++ b/modules/commands/cs_akick.cpp @@ -1,6 +1,6 @@ /* ChanServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -72,7 +72,7 @@ class CommandCSAKick : public Command /* Check excepts BEFORE we get this far */ if (ci->c) { - std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> modes = ci->c->GetModeList(CMODE_EXCEPT); + std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> modes = ci->c->GetModeList("EXCEPT"); for (; modes.first != modes.second; ++modes.first) { if (Anope::Match(modes.first->second, mask)) @@ -85,7 +85,7 @@ class CommandCSAKick : public Command /* Check whether target nick has equal/higher access * or whether the mask matches a user with higher/equal access - Viper */ - if (ci->HasFlag(CI_PEACE) && nc) + if (ci->HasExt("PEACE") && nc) { AccessGroup nc_access = ci->AccessFor(nc), u_access = source.AccessFor(ci); if (nc == ci->GetFounder() || nc_access >= u_access) @@ -94,7 +94,7 @@ class CommandCSAKick : public Command return; } } - else if (ci->HasFlag(CI_PEACE)) + else if (ci->HasExt("PEACE")) { /* Match against all currently online users with equal or * higher access. - Viper */ @@ -103,7 +103,7 @@ class CommandCSAKick : public Command User *u2 = it->second; AccessGroup nc_access = ci->AccessFor(nc), u_access = source.AccessFor(ci); - Entry entry_mask(CMODE_BEGIN, mask); + Entry entry_mask("", mask); if ((ci->AccessFor(u2).HasPriv("FOUNDER") || nc_access >= u_access) && entry_mask.Matches(u2)) { @@ -134,9 +134,9 @@ class CommandCSAKick : public Command for (unsigned j = 0, end = ci->GetAkickCount(); j < end; ++j) { akick = ci->GetAkick(j); - if (akick->HasFlag(AK_ISNICK) ? akick->nc == nc : mask.equals_ci(akick->mask)) + if (akick->nc ? akick->nc == nc : mask.equals_ci(akick->mask)) { - source.Reply(_("\002%s\002 already exists on %s autokick list."), akick->HasFlag(AK_ISNICK) ? akick->nc->display.c_str() : akick->mask.c_str(), ci->name.c_str()); + source.Reply(_("\002%s\002 already exists on %s autokick list."), akick->nc ? akick->nc->display.c_str() : akick->mask.c_str(), ci->name.c_str()); return; } } @@ -223,7 +223,7 @@ class CommandCSAKick : public Command { const AutoKick *akick = ci->GetAkick(i); - if ((akick->HasFlag(AK_ISNICK) && akick->nc == nc) || (!akick->HasFlag(AK_ISNICK) && mask.equals_ci(akick->mask))) + if (akick->nc ? akick->nc == nc : mask.equals_ci(akick->mask)) break; } @@ -298,9 +298,9 @@ class CommandCSAKick : public Command if (!mask.empty()) { - if (!akick->HasFlag(AK_ISNICK) && !Anope::Match(akick->mask, mask)) + if (!akick->nc && !Anope::Match(akick->mask, mask)) continue; - if (akick->HasFlag(AK_ISNICK) && !Anope::Match(akick->nc->display, mask)) + if (akick->nc && !Anope::Match(akick->nc->display, mask)) continue; } @@ -378,9 +378,9 @@ class CommandCSAKick : public Command return; } - for (CUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ) + for (User::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ) { - UserContainer *uc = *it++; + ChanUserContainer *uc = *it++; if (ci->CheckKick(uc->user)) ++count; @@ -479,7 +479,7 @@ class CommandCSAKick : public Command "optionally only those AutoKick entries which match the\n" "given mask.\n" " \n" - "The \002AKICK VIEW\002 command is a more verbose version of\n" + "The \002AKICK VIEW\002 command is a more verbose version of the\n" "\002AKICK LIST\002 command.\n" " \n" "The \002AKICK ENFORCE\002 command causes %s to enforce the\n" @@ -502,6 +502,44 @@ class CSAKick : public Module { this->SetAuthor("Anope"); + Implementation i[] = { I_OnCheckKick }; + ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); + } + + EventReturn OnCheckKick(User *u, ChannelInfo *ci, Anope::string &mask, Anope::string &reason) anope_override + { + if (ci->c->MatchesList(u, "EXCEPT")) + return EVENT_CONTINUE; + + for (unsigned j = 0, end = ci->GetAkickCount(); j < end; ++j) + { + AutoKick *autokick = ci->GetAkick(j); + bool kick = false; + + if (autokick->nc) + { + if (autokick->nc == u->Account()) + kick = true; + } + else + { + Entry akick_mask("", autokick->mask); + if (akick_mask.Matches(u)) + kick = true; + } + + if (kick) + { + Log(LOG_DEBUG_2) << u->nick << " matched akick " << (autokick->nc ? autokick->nc->display : autokick->mask); + autokick->last_used = Anope::CurTime; + if (!autokick->nc) + mask = autokick->mask; + reason = autokick->reason.empty() ? Config->CSAutokickReason : autokick->reason; + return EVENT_STOP; + } + } + + return EVENT_CONTINUE; } }; diff --git a/modules/commands/cs_appendtopic.cpp b/modules/commands/cs_appendtopic.cpp deleted file mode 100644 index 2d7c0f278..000000000 --- a/modules/commands/cs_appendtopic.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* cs_appendtopic.c - Add text to a channels topic - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Based on the original module by SGR <Alex_SGR@ntlworld.com> - * Included in the Anope module pack since Anope 1.7.9 - * Anope Coder: GeniusDex <geniusdex@anope.org> - * - * Please read COPYING and README for further details. - * - * Send bug reports to the Anope Coder instead of the module - * author, because any changes since the inclusion into anope - * are not supported by the original author. - */ - -/*************************************************************************/ - -#include "module.h" - -/* ------------------------------------------------------------ - * Name: cs_appendtopic - * Author: SGR <Alex_SGR@ntlworld.com> - * Date: 31/08/2003 - * ------------------------------------------------------------ - * - * This module has no configurable options. For information on - * this module, load it and refer to /ChanServ APPENDTOPIC HELP - * - * Thanks to dengel, Rob and Certus for all there support. - * Especially Rob, who always manages to show me where I have - * not allocated any memory. Even if it takes a few weeks of - * pestering to get him to look at it. - * - * ------------------------------------------------------------ - */ - -/* ---------------------------------------------------------------------- */ -/* DO NOT EDIT BELOW THIS LINE UNLESS YOU KNOW WHAT YOU ARE DOING */ -/* ---------------------------------------------------------------------- */ - -class CommandCSAppendTopic : public Command -{ - public: - CommandCSAppendTopic(Module *creator) : Command(creator, "chanserv/appendtopic", 2, 2) - { - this->SetDesc(_("Add text to a channels topic")); - this->SetSyntax(_("\037channel\037 \037text\037")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - const Anope::string &newtopic = params[1]; - - Channel *c = Channel::Find(params[0]);; - - if (!c) - source.Reply(CHAN_X_NOT_IN_USE, params[0].c_str()); - else if (!c->ci) - source.Reply(CHAN_X_NOT_REGISTERED, c->name.c_str()); - else if (!source.AccessFor(c->ci).HasPriv("TOPIC") && !source.HasCommand("chanserv/topic")) - source.Reply(ACCESS_DENIED); - else - { - Anope::string topic; - if (!c->ci->last_topic.empty()) - { - topic = c->ci->last_topic + " " + newtopic; - c->ci->last_topic.clear(); - } - else - topic = newtopic; - - bool has_topiclock = c->ci->HasFlag(CI_TOPICLOCK); - c->ci->UnsetFlag(CI_TOPICLOCK); - c->ChangeTopic(source.GetNick(), topic, Anope::CurTime); - if (has_topiclock) - c->ci->SetFlag(CI_TOPICLOCK); - - bool override = !source.AccessFor(c->ci).HasPriv("TOPIC"); - Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, c->ci) << "to append: " << topic; - } - return; - } - - bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("This command allows users to append text to a currently set\n" - "channel topic. When TOPICLOCK is on, the topic is updated and\n" - "the new, updated topic is locked.")); - - return true; - } -}; - -class CSAppendTopic : public Module -{ - CommandCSAppendTopic commandcsappendtopic; - - public: - CSAppendTopic(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandcsappendtopic(this) - { - this->SetAuthor("SGR"); - - } -}; - -MODULE_INIT(CSAppendTopic) diff --git a/modules/commands/cs_ban.cpp b/modules/commands/cs_ban.cpp index 0fb65ecf6..2da17bb98 100644 --- a/modules/commands/cs_ban.cpp +++ b/modules/commands/cs_ban.cpp @@ -1,6 +1,6 @@ /* ChanServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -13,53 +13,96 @@ #include "module.h" +static Module *me; + +class TempBan : public CallBack +{ + private: + Anope::string channel; + Anope::string mask; + + public: + TempBan(time_t seconds, Channel *c, const Anope::string &banmask) : CallBack(me, seconds), channel(c->name), mask(banmask) { } + + void Tick(time_t ctime) anope_override + { + Channel *c = Channel::Find(this->channel); + if (c) + c->RemoveMode(NULL, "BAN", this->mask); + } +}; + class CommandCSBan : public Command { public: - CommandCSBan(Module *creator) : Command(creator, "chanserv/ban", 2, 3) + CommandCSBan(Module *creator) : Command(creator, "chanserv/ban", 2, 4) { - this->SetDesc(_("Bans a selected nick on a channel")); - this->SetSyntax(_("\037channel\037 \037nick\037 [\037reason\037]")); - this->SetSyntax(_("\037channel\037 \037mask\037 [\037reason\037]")); + this->SetDesc(_("Bans a given nick or mask on a channel")); + this->SetSyntax(_("\037channel\037 [+\037expiry\037] \037nick\037 [\037reason\037]")); + this->SetSyntax(_("\037channel\037 [+\037expiry\037] \037mask\037 [\037reason\037]")); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { const Anope::string &chan = params[0]; - const Anope::string &target = params[1]; - Anope::string reason = params.size() > 2 ? params[2] : "Requested"; - ChannelInfo *ci = ChannelInfo::Find(params[0]); + ChannelInfo *ci = ChannelInfo::Find(chan); if (ci == NULL) { - source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); + source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str()); return; } + Anope::string expiry, target, reason; + time_t ban_time; + if (params[1][0] == '+') + { + ban_time = Anope::DoTime(params[1]); + if (params.size() < 3) + { + this->SendSyntax(source); + return; + } + target = params[2]; + reason = "Requested"; + if (params.size() > 3) + reason = params[3]; + } + else + { + ban_time = 0; + target = params[1]; + reason = "Requested"; + if (params.size() > 2) + reason = params[2]; + if (params.size() > 3) + reason += " " + params[3]; + } + + if (reason.length() > Config->CSReasonMax) + reason = reason.substr(0, Config->CSReasonMax); + Channel *c = ci->c; User *u = source.GetUser(); User *u2 = User::Find(target, true); AccessGroup u_access = source.AccessFor(ci); - if (reason.length() > Config->CSReasonMax) - reason = reason.substr(0, Config->CSReasonMax); - if (!c) source.Reply(CHAN_X_NOT_IN_USE, chan.c_str()); else if (!u_access.HasPriv("BAN")) source.Reply(ACCESS_DENIED); - /* - * Dont ban/kick the user on channels where he is excepted - * to prevent services <-> server wars. - */ else if (u2) { AccessGroup u2_access = ci->AccessFor(u2); - if (u != u2 && ci->HasFlag(CI_PEACE) && u2_access >= u_access) + if (u != u2 && ci->HasExt("PEACE") && u2_access >= u_access) source.Reply(ACCESS_DENIED); - else if (ci->c->MatchesList(u2, CMODE_EXCEPT)) + /* + * Dont ban/kick the user on channels where he is excepted + * to prevent services <-> server wars. + */ + else if (ci->c->MatchesList(u2, "EXCEPT")) source.Reply(CHAN_EXCEPTED, u2->nick.c_str(), ci->name.c_str()); else if (u2->IsProtected()) source.Reply(ACCESS_DENIED); @@ -70,13 +113,21 @@ class CommandCSBan : public Command // XXX need a way to detect if someone is overriding Log(LOG_COMMAND, source, this, ci) << "for " << mask; - c->SetMode(NULL, CMODE_BAN, mask); + if (!c->HasMode("BAN", mask)) + { + c->SetMode(NULL, "BAN", mask); + if (ban_time) + { + new TempBan(ban_time, c, mask); + source.Reply(_("Ban on \002%s\002 expires in %s."), mask.c_str(), Anope::Duration(ban_time, source.GetAccount()).c_str()); + } + } /* We still allow host banning while not allowing to kick */ if (!c->FindUser(u2)) return; - if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !source.AccessFor(ci).HasPriv("SIGNKICK"))) + if (ci->HasExt("SIGNKICK") || (ci->HasExt("SIGNKICK_LEVEL") && !source.AccessFor(ci).HasPriv("SIGNKICK"))) c->Kick(ci->WhoSends(), u2, "%s (%s)", reason.c_str(), source.GetNick().c_str()); else c->Kick(ci->WhoSends(), u2, "%s", reason.c_str()); @@ -86,12 +137,20 @@ class CommandCSBan : public Command { Log(LOG_COMMAND, source, this, ci) << "for " << target; - c->SetMode(NULL, CMODE_BAN, target); + if (!c->HasMode("BAN", target)) + { + c->SetMode(NULL, "BAN", target); + if (ban_time) + { + new TempBan(ban_time, c, target); + source.Reply(_("Ban on \002%s\002 expires in %s."), target.c_str(), Anope::Duration(ban_time, source.GetAccount()).c_str()); + } + } int matched = 0, kicked = 0; - for (CUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end;) + for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end;) { - UserContainer *uc = *it++; + ChanUserContainer *uc = *it++; if (Anope::Match(uc->user->nick, target) || Anope::Match(uc->user->GetDisplayedMask(), target)) { @@ -99,15 +158,15 @@ class CommandCSBan : public Command AccessGroup u2_access = ci->AccessFor(uc->user); - if (u != uc->user && ci->HasFlag(CI_PEACE) && u2_access >= u_access) + if (u != uc->user && ci->HasExt("PEACE") && u2_access >= u_access) continue; - else if (ci->c->MatchesList(uc->user, CMODE_EXCEPT)) + else if (ci->c->MatchesList(uc->user, "EXCEPT")) continue; else if (uc->user->IsProtected()) continue; ++kicked; - if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !u_access.HasPriv("SIGNKICK"))) + if (ci->HasExt("SIGNKICK") || (ci->HasExt("SIGNKICK_LEVEL") && !u_access.HasPriv("SIGNKICK"))) c->Kick(ci->WhoSends(), uc->user, "%s (Matches %s) (%s)", reason.c_str(), target.c_str(), source.GetNick().c_str()); else c->Kick(ci->WhoSends(), uc->user, "%s (Matches %s)", reason.c_str(), target.c_str()); @@ -127,7 +186,9 @@ class CommandCSBan : public Command { this->SendSyntax(source); source.Reply(" "); - source.Reply(_("Bans a selected nick on a channel.\n" + source.Reply(_("Bans a given nick or mask on a channel. An optional expiry may\n" + "be given to cause services to remove the ban after a set amount\n" + "of time.\n" " \n" "By default, limited to AOPs or those with level 5 access\n" "and above on the channel. Channel founders may ban masks.")); @@ -143,7 +204,7 @@ class CSBan : public Module CSBan(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), commandcsban(this) { this->SetAuthor("Anope"); - + me = this; } }; diff --git a/modules/commands/cs_clearusers.cpp b/modules/commands/cs_clearusers.cpp deleted file mode 100644 index 3a424e4ce..000000000 --- a/modules/commands/cs_clearusers.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* ChanServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandCSClearUsers : public Command -{ - public: - CommandCSClearUsers(Module *creator) : Command(creator, "chanserv/clearusers", 1, 1) - { - this->SetDesc(_("Kicks all users on a channel")); - this->SetSyntax(_("\037channel\037")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - const Anope::string &chan = params[0]; - - Channel *c = Channel::Find(chan); - Anope::string modebuf; - - if (!c) - { - source.Reply(CHAN_X_NOT_IN_USE, chan.c_str()); - return; - } - else if (!c->ci) - { - source.Reply(CHAN_X_NOT_REGISTERED, c->name.c_str()); - return; - } - else if (!source.AccessFor(c->ci).HasPriv("FOUNDER") && !source.HasCommand("chanserv/clearusers")) - { - source.Reply(ACCESS_DENIED); - return; - } - - Anope::string buf = "CLEARUSERS command from " + source.GetNick() + " (" + source.nc->display + ")"; - - std::vector<User *> users; - for (CUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ++it) - { - User *user = (*it)->user; - if (!user->HasMode(UMODE_OPER) && user->server != Me) - users.push_back(user); - } - - for (unsigned i = 0; i < users.size(); ++i) - c->Kick(NULL, users[i], "%s", buf.c_str()); - - bool override = !source.AccessFor(c->ci).HasPriv("FOUNDER"); - Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, c->ci); - - source.Reply(_("All users have been kicked from \002%s\002."), chan.c_str()); - - return; - } - - bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Tells %s to clear (kick) all users on a channel." - " \n" - "By default, limited to those with founder access on the\n" - "channel."), source.service->nick.c_str()); - return true; - } -}; - -class CSClearUsers : public Module -{ - CommandCSClearUsers commandcsclearusers; - - public: - CSClearUsers(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandcsclearusers(this) - { - this->SetAuthor("Anope"); - - } -}; - -MODULE_INIT(CSClearUsers) diff --git a/modules/commands/cs_clone.cpp b/modules/commands/cs_clone.cpp index 19a8ad436..9a33a6fab 100644 --- a/modules/commands/cs_clone.cpp +++ b/modules/commands/cs_clone.cpp @@ -1,6 +1,6 @@ /* ChanServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -59,7 +59,7 @@ public: if (what.empty()) { - target_ci->Destroy(); + delete target_ci; target_ci = new ChannelInfo(*ci); target_ci->name = target; (*RegisteredChannelList)[target_ci->name] = target_ci; @@ -74,18 +74,18 @@ public: if (u && u->FindChannel(target_ci->c) != NULL) { /* On most ircds you do not receive the admin/owner mode till its registered */ - if ((cm = ModeManager::FindChannelModeByName(CMODE_OWNER))) + if ((cm = ModeManager::FindChannelModeByName("OWNER"))) target_ci->c->SetMode(NULL, cm, u->GetUID()); - else if ((cm = ModeManager::FindChannelModeByName(CMODE_PROTECT))) + else if ((cm = ModeManager::FindChannelModeByName("PROTECT"))) target_ci->c->RemoveMode(NULL, cm, u->GetUID()); } /* Mark the channel as persistent */ - if (target_ci->c->HasMode(CMODE_PERM)) - target_ci->SetFlag(CI_PERSIST); + if (target_ci->c->HasMode("PERM")) + target_ci->ExtendMetadata("PERSIST"); /* Persist may be in def cflags, set it here */ - else if (target_ci->HasFlag(CI_PERSIST) && (cm = ModeManager::FindChannelModeByName(CMODE_PERM))) - target_ci->c->SetMode(NULL, CMODE_PERM); + else if (target_ci->HasExt("PERSIST") && (cm = ModeManager::FindChannelModeByName("PERM"))) + target_ci->c->SetMode(NULL, cm); if (target_ci->bi && target_ci->c->FindUser(target_ci->bi) == NULL) target_ci->bi->Join(target_ci->c, &ModeManager::DefaultBotModes); @@ -102,7 +102,7 @@ public: FOREACH_MOD(I_OnChanRegistered, OnChanRegistered(target_ci)); - source.Reply(_("All settings from \002%s\002 have been cloned to \002%s\002"), channel.c_str(), target.c_str()); + source.Reply(_("All settings from \002%s\002 have been cloned to \002%s\002."), channel.c_str(), target.c_str()); } else if (what.equals_ci("ACCESS")) { @@ -122,7 +122,7 @@ public: target_ci->AddAccess(newaccess); } - source.Reply(_("All access entries from \002%s\002 have been cloned to \002%s\002"), channel.c_str(), target.c_str()); + source.Reply(_("All access entries from \002%s\002 have been cloned to \002%s\002."), channel.c_str(), target.c_str()); } else if (what.equals_ci("AKICK")) { @@ -130,13 +130,13 @@ public: for (unsigned i = 0; i < ci->GetAkickCount(); ++i) { const AutoKick *akick = ci->GetAkick(i); - if (akick->HasFlag(AK_ISNICK)) + if (akick->nc) target_ci->AddAkick(akick->creator, akick->nc, akick->reason, akick->addtime, akick->last_used); else target_ci->AddAkick(akick->creator, akick->mask, akick->reason, akick->addtime, akick->last_used); } - source.Reply(_("All akick entries from \002%s\002 have been cloned to \002%s\002"), channel.c_str(), target.c_str()); + source.Reply(_("All akick entries from \002%s\002 have been cloned to \002%s\002."), channel.c_str(), target.c_str()); } else if (what.equals_ci("BADWORDS")) { @@ -147,7 +147,7 @@ public: target_ci->AddBadWord(bw->word, bw->type); } - source.Reply(_("All badword entries from \002%s\002 have been cloned to \002%s\002"), channel.c_str(), target.c_str()); + source.Reply(_("All badword entries from \002%s\002 have been cloned to \002%s\002."), channel.c_str(), target.c_str()); } else { diff --git a/modules/commands/cs_drop.cpp b/modules/commands/cs_drop.cpp index 829f44026..884544211 100644 --- a/modules/commands/cs_drop.cpp +++ b/modules/commands/cs_drop.cpp @@ -1,6 +1,6 @@ /* ChanServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -39,25 +39,25 @@ class CommandCSDrop : public Command return; } - if (ci->HasFlag(CI_SUSPENDED) && !source.HasCommand("chanserv/drop")) + if (ci->HasExt("SUSPENDED") && !source.HasCommand("chanserv/drop")) { source.Reply(CHAN_X_SUSPENDED, chan.c_str()); return; } - if ((ci->HasFlag(CI_SECUREFOUNDER) ? !source.IsFounder(ci) : !source.AccessFor(ci).HasPriv("FOUNDER")) && !source.HasCommand("chanserv/drop")) + if ((ci->HasExt("SECUREFOUNDER") ? !source.IsFounder(ci) : !source.AccessFor(ci).HasPriv("FOUNDER")) && !source.HasCommand("chanserv/drop")) { source.Reply(ACCESS_DENIED); return; } - bool override = (ci->HasFlag(CI_SECUREFOUNDER) ? !source.IsFounder(ci) : !source.AccessFor(ci).HasPriv("FOUNDER")); + bool override = (ci->HasExt("SECUREFOUNDER") ? !source.IsFounder(ci) : !source.AccessFor(ci).HasPriv("FOUNDER")); Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "(founder was: " << (ci->GetFounder() ? ci->GetFounder()->display : "none") << ")"; FOREACH_MOD(I_OnChanDrop, OnChanDrop(ci)); Channel *c = ci->c; - ci->Destroy(); + delete ci; source.Reply(_("Channel \002%s\002 has been dropped."), chan.c_str()); @@ -73,10 +73,10 @@ class CommandCSDrop : public Command source.Reply(" "); if (source.IsServicesOper()) source.Reply(_("Unregisters the named channel. Only \002Services Operators\002\n" - "can drop a channel for which they have not identified.")); + "can drop a channel of which they are not the founder.")); else source.Reply(_("Unregisters the named channel. Can only be used by\n" - "\002channel founder\002.")); + "the \002channel founder\002.")); return true; } diff --git a/modules/commands/cs_enforce.cpp b/modules/commands/cs_enforce.cpp index 4622af04b..4d5ba0242 100644 --- a/modules/commands/cs_enforce.cpp +++ b/modules/commands/cs_enforce.cpp @@ -1,11 +1,9 @@ -/* cs_enforce - Add a /cs ENFORCE command to enforce various set - * options and channelmodes on a channel. +/* ChanServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * - * Included in the Anope module pack since Anope 1.7.9 - * Anope Coder: GeniusDex <geniusdex@anope.org> + * Original Coder: GeniusDex <geniusdex@anope.org> * * Please read COPYING and README for further details. * @@ -18,171 +16,244 @@ class CommandCSEnforce : public Command { private: - void DoSet(CommandSource &source, Channel *c) + void DoSecureOps(CommandSource &source, ChannelInfo *ci) { - const ChannelInfo *ci = c->ci; + bool override = !source.AccessFor(ci).HasPriv("AKICK") && source.HasPriv("chanserv/access/modify"); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enforce secureops"; - if (!ci) - return; + /* Dirty hack to allow Channel::SetCorrectModes to work ok. + * We pretend like SECUREOPS is on so it doesn't ignore that + * part of the code. This way we can enforce SECUREOPS even + * if it's off. + */ + bool hadsecureops = ci->HasExt("SECUREOPS"); + ci->ExtendMetadata("SECUREOPS"); + + for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it) + { + ChanUserContainer *uc = *it; - Log(LOG_COMMAND, source, this) << "to enforce set"; + ci->c->SetCorrectModes(uc->user, false, false); + } + + if (!hadsecureops) + ci->Shrink("SECUREOPS"); - if (ci->HasFlag(CI_SECUREOPS)) - this->DoSecureOps(source, c); - if (ci->HasFlag(CI_RESTRICTED)) - this->DoRestricted(source, c); + source.Reply(_("Secureops enforced on %s."), ci->name.c_str()); } - void DoModes(CommandSource &source, Channel *c) + void DoRestricted(CommandSource &source, ChannelInfo *ci) { - Log(LOG_COMMAND, source, this) << "to enforce modes"; + bool override = !source.AccessFor(ci).HasPriv("AKICK") && source.HasPriv("chanserv/access/modify"); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enforce restricted"; + + std::vector<User *> users; + for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it) + { + ChanUserContainer *uc = *it; + User *user = uc->user; + + if (user->IsProtected()) + continue; + + if (ci->AccessFor(user).empty()) + users.push_back(user); + } + + for (unsigned i = 0; i < users.size(); ++i) + { + User *user = users[i]; + + Anope::string mask = ci->GetIdealBan(user); + Anope::string reason = Language::Translate(user, _("RESTRICTED enforced by ")) + source.GetNick(); + ci->c->SetMode(NULL, "BAN", mask); + ci->c->Kick(NULL, user, "%s", reason.c_str()); + } - if (c->HasMode(CMODE_REGISTEREDONLY)) - this->DoCModeR(source, c); + source.Reply(_("Restricted enforced on %s."), ci->name.c_str()); } - void DoSecureOps(CommandSource &source, Channel *c) + void DoRegOnly(CommandSource &source, ChannelInfo *ci) { - ChannelInfo *ci = c->ci; + bool override = !source.AccessFor(ci).HasPriv("AKICK") && source.HasPriv("chanserv/access/modify"); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enforce registered only"; - if (!ci) - return; + std::vector<User *> users; + for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it) + { + ChanUserContainer *uc = *it; + User *user = uc->user; - Log(LOG_COMMAND, source, this) << "to enforce secureops"; + if (user->IsProtected()) + continue; - /* Dirty hack to allow Channel::SetCorrectModes to work ok. - * We pretend like SECUREOPS is on so it doesn't ignore that - * part of the code. This way we can enforce SECUREOPS even - * if it's off. - */ - bool hadsecureops = false; - if (!ci->HasFlag(CI_SECUREOPS)) - { - ci->SetFlag(CI_SECUREOPS); - hadsecureops = true; + if (!user->IsIdentified()) + users.push_back(user); } - for (CUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ++it) + for (unsigned i = 0; i < users.size(); ++i) { - UserContainer *uc = *it; + User *user = users[i]; - c->SetCorrectModes(uc->user, false, false); + Anope::string mask = ci->GetIdealBan(user); + Anope::string reason = Language::Translate(user, _("REGONLY enforced by ")) + source.GetNick(); + if (!ci->c->HasMode("REGISTEREDONLY")) + ci->c->SetMode(NULL, "BAN", mask); + ci->c->Kick(NULL, user, "%s", reason.c_str()); } - if (hadsecureops) - ci->UnsetFlag(CI_SECUREOPS); + source.Reply(_("Registered only enforced on %s."), ci->name.c_str()); } - void DoRestricted(CommandSource &source, Channel *c) + void DoSSLOnly(CommandSource &source, ChannelInfo *ci) { - ChannelInfo *ci = c->ci; - if (ci == NULL) - return; - - Log(LOG_COMMAND, source, this) << "to enforce restricted"; + bool override = !source.AccessFor(ci).HasPriv("AKICK") && source.HasPriv("chanserv/access/modify"); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enforce SSL only"; std::vector<User *> users; - for (CUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ++it) + for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it) { - UserContainer *uc = *it; + ChanUserContainer *uc = *it; User *user = uc->user; - if (ci->AccessFor(user).empty()) + if (user->IsProtected()) + continue; + + if (!user->HasMode("SSL")) users.push_back(user); } for (unsigned i = 0; i < users.size(); ++i) - { + { User *user = users[i]; Anope::string mask = ci->GetIdealBan(user); - Anope::string reason = Language::Translate(user, CHAN_NOT_ALLOWED_TO_JOIN); - c->SetMode(NULL, CMODE_BAN, mask); - c->Kick(NULL, user, "%s", reason.c_str()); + Anope::string reason = Language::Translate(user, _("SSLONLY enforced by ")) + source.GetNick(); + if (!ci->c->HasMode("SSL")) + ci->c->SetMode(NULL, "BAN", mask); + ci->c->Kick(NULL, user, "%s", reason.c_str()); } + + source.Reply(_("SSL only enforced on %s."), ci->name.c_str()); } - void DoCModeR(CommandSource &source, Channel *c) + void DoBans(CommandSource &source, ChannelInfo *ci) { - ChannelInfo *ci = c->ci; + bool override = !source.AccessFor(ci).HasPriv("AKICK") && source.HasPriv("chanserv/access/modify"); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enforce bans"; - if (!ci) + std::vector<User *> users; + for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it) + { + ChanUserContainer *uc = *it; + User *user = uc->user; + + if (user->IsProtected()) + continue; + + if (ci->c->MatchesList(user, "BAN") && !ci->c->MatchesList(user, "EXCEPT")) + users.push_back(user); + } + + for (unsigned i = 0; i < users.size(); ++i) + { + User *user = users[i]; + + Anope::string reason = Language::Translate(user, _("BANS enforced by ")) + source.GetNick(); + ci->c->Kick(NULL, user, "%s", reason.c_str()); + } + + source.Reply(_("Bans enforced on %s."), ci->name.c_str()); + } + + void DoLimit(CommandSource &source, ChannelInfo *ci) + { + bool override = !source.AccessFor(ci).HasPriv("AKICK") && source.HasPriv("chanserv/access/modify"); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enforce limit"; + + Anope::string l_str; + if (!ci->c->GetParam("LIMIT", l_str)) + { + source.Reply(_("No limit is set on %s."), ci->name.c_str()); return; + } - Log(LOG_COMMAND, source, this) << "to enforce registered only"; + int l; + try + { + l = convertTo<int>(l_str); + if (l < 0) + throw ConvertException(); + } + catch (const ConvertException &) + { + source.Reply(_("The limit on %s is not valid."), ci->name.c_str()); + return; + } std::vector<User *> users; - for (CUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ++it) + /* The newer users are at the end of the list, so kick users starting from the end */ + for (Channel::ChanUserList::reverse_iterator it = ci->c->users.rbegin(), it_end = ci->c->users.rend(); it != it_end; ++it) { - UserContainer *uc = *it; + ChanUserContainer *uc = *it; User *user = uc->user; - if (!user->IsIdentified()) - users.push_back(user); + if (user->IsProtected()) + continue; + + if (!ci->AccessFor(user).empty()) + continue; + + if (ci->c->users.size() - users.size() <= static_cast<unsigned>(l)) + continue; + + users.push_back(user); } for (unsigned i = 0; i < users.size(); ++i) { User *user = users[i]; - - Anope::string mask = ci->GetIdealBan(user); - Anope::string reason = Language::Translate(user, CHAN_NOT_ALLOWED_TO_JOIN); - if (!c->HasMode(CMODE_REGISTEREDONLY)) - c->SetMode(NULL, CMODE_BAN, mask); - c->Kick(NULL, user, "%s", reason.c_str()); + + Anope::string reason = Language::Translate(user, _("LIMIT enforced by ")) + source.GetNick(); + ci->c->Kick(NULL, user, "%s", reason.c_str()); } + + source.Reply(_("LIMIT enforced on %s, %d users removed."), ci->name.c_str(), users.size()); } + public: - CommandCSEnforce(Module *creator) : Command(creator, "chanserv/enforce", 1, 2) + CommandCSEnforce(Module *creator) : Command(creator, "chanserv/enforce", 2, 2) { this->SetDesc(_("Enforce various channel modes and set options")); - this->SetSyntax(_("\037channel\037 [\037what\037]")); + this->SetSyntax(_("\037channel\037 \037what\037")); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { const Anope::string &what = params.size() > 1 ? params[1] : ""; - Channel *c = Channel::Find(params[0]); + ChannelInfo *ci = ChannelInfo::Find(params[0]); - if (!c) - source.Reply(CHAN_X_NOT_IN_USE, params[0].c_str()); - else if (!c->ci) - source.Reply(CHAN_X_NOT_REGISTERED, c->name.c_str()); - else if (!source.AccessFor(c->ci).HasPriv("AKICK")) + if (!ci) + source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); + else if (!ci->c) + source.Reply(CHAN_X_NOT_IN_USE, ci->name.c_str()); + else if (!source.AccessFor(ci).HasPriv("AKICK") && !source.HasPriv("chanserv/access/modify")) source.Reply(ACCESS_DENIED); + else if (what.equals_ci("SECUREOPS")) + this->DoSecureOps(source, ci); + else if (what.equals_ci("RESTRICTED")) + this->DoRestricted(source, ci); + else if (what.equals_ci("REGONLY")) + this->DoRegOnly(source, ci); + else if (what.equals_ci("SSLONLY")) + this->DoSSLOnly(source, ci); + else if (what.equals_ci("BANS")) + this->DoBans(source, ci); + else if (what.equals_ci("LIMIT")) + this->DoLimit(source, ci); else - { - if (what.empty() || what.equals_ci("SET")) - { - this->DoSet(source, c); - source.Reply(_("Enforced %s"), !what.empty() ? what.c_str() : "SET"); - } - else if (what.equals_ci("MODES")) - { - this->DoModes(source, c); - source.Reply(_("Enforced %s"), what.c_str()); - } - else if (what.equals_ci("SECUREOPS")) - { - this->DoSecureOps(source, c); - source.Reply(_("Enforced %s"), what.c_str()); - } - else if (what.equals_ci("RESTRICTED")) - { - this->DoRestricted(source, c); - source.Reply(_("Enforced %s"), what.c_str()); - } - else if (what.equals_ci("+R")) - { - this->DoCModeR(source, c); - source.Reply(_("Enforced %s"), what.c_str()); - } - else - this->OnSyntaxError(source, ""); - } - - return; + this->OnSyntaxError(source, ""); } bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override @@ -192,28 +263,16 @@ class CommandCSEnforce : public Command source.Reply(_("Enforce various channel modes and set options. The \037channel\037\n" "option indicates what channel to enforce the modes and options\n" "on. The \037what\037 option indicates what modes and options to\n" - "enforce, and can be any of SET, SECUREOPS, RESTRICTED, MODES,\n" - "or +R. When left out, it defaults to SET.\n" + "enforce, and can be any of \002SECUREOPS\002, \002RESTRICTED\002, \002REGONLY\002, \002SSLONLY\002,\n" + "\002BANS\002, or \002LIMIT\002.\n" " \n" - "If \037what\037 is SET, it will enforce SECUREOPS and RESTRICTED\n" - "on the users currently in the channel, if they are set. Give\n" - "SECUREOPS to enforce the SECUREOPS option, even if it is not\n" - "enabled. Use RESTRICTED to enfore the RESTRICTED option, also\n" - "if it's not enabled.")); - source.Reply(" "); - if (ModeManager::FindChannelModeByName(CMODE_REGISTERED)) - source.Reply(_("If \037what\037 is MODES, it will enforce channelmode +R if it is\n" - "set. If +R is specified for \037what\037, the +R channelmode will\n" - "also be enforced, but even if it is not set. If it is not set,\n" - "users will be banned to ensure they don't just rejoin.")); - else - source.Reply(_("If \037what\037 is MODES, nothing will be enforced, since it would\n" - "enforce modes that the current ircd does not support. If +R is\n" - "specified for \037what\037, an equalivant of channelmode +R on\n" - "other ircds will be enforced. All users that are in the channel\n" - "but have not identified for their nickname will be kicked and\n" - "banned from the channel.")); - + "Use \002SECUREOPS\002 to enforce the SECUREOPS option, even if it is not\n" + "enabled. Use \002RESTRICTED\002 to enfore the RESTRICTED option, also\n" + "if it's not enabled. Use \002REGONLY\002 to kick all unregistered users\n" + "from the channel. Use \002SSLONLY\002 to kick all users not using a secure\n" + "connection from the channel. \002BANS\002 will enforce bans on the channel by\n" + "kicking users affected by them, and \002LIMIT\002 will kick users until the\n" + "user count drops below the channel limit, if one is set.")); return true; } }; diff --git a/modules/commands/cs_entrymsg.cpp b/modules/commands/cs_entrymsg.cpp index ab9c4d0c4..6c39016ef 100644 --- a/modules/commands/cs_entrymsg.cpp +++ b/modules/commands/cs_entrymsg.cpp @@ -1,6 +1,6 @@ /* ChanServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -161,7 +161,7 @@ class CommandEntryMessage : public Command unsigned i = convertTo<unsigned>(message); if (i > 0 && i <= (*messages)->size()) { - (*messages)->at(i - 1)->Destroy(); + delete (*messages)->at(i - 1); (*messages)->erase((*messages)->begin() + i - 1); if ((*messages)->empty()) ci->Shrink("cs_entrymsg"); @@ -184,7 +184,7 @@ class CommandEntryMessage : public Command if (messages != NULL) { for (unsigned i = 0; i < (*messages)->size(); ++i) - (*messages)->at(i)->Destroy(); + delete (*messages)->at(i); (*messages)->clear(); ci->Shrink("cs_entrymsg"); } diff --git a/modules/commands/cs_fantasy_stats.cpp b/modules/commands/cs_fantasy_stats.cpp index 5b25cccce..580307441 100644 --- a/modules/commands/cs_fantasy_stats.cpp +++ b/modules/commands/cs_fantasy_stats.cpp @@ -1,6 +1,6 @@ /* Chanstats core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -38,7 +38,6 @@ class CommandCSStats : public Command public: CommandCSStats(Module *creator) : Command (creator, "chanserv/stats", 0, 2) { - this->SetFlag(CFLAG_STRIP_CHANNEL); this->SetDesc(_("Displays your Channel Stats")); this->SetSyntax(_("\037nick\037")); } @@ -51,7 +50,6 @@ class CommandCSGStats : public Command public: CommandCSGStats(Module *creator) : Command (creator, "chanserv/gstats", 0, 2) { - this->SetFlag(CFLAG_STRIP_CHANNEL); this->SetDesc(_("Displays your Global Stats")); this->SetSyntax(_("\037nick\037")); } @@ -142,7 +140,7 @@ class CSStats : public Module res.Get(0, "actions").c_str()); } else - source.Reply(_("No stats for %s"), display.c_str()); + source.Reply(_("No stats for %s."), display.c_str()); } catch (const SQL::Exception &ex) { diff --git a/modules/commands/cs_fantasy_top.cpp b/modules/commands/cs_fantasy_top.cpp index ca9572039..16d65dd05 100644 --- a/modules/commands/cs_fantasy_top.cpp +++ b/modules/commands/cs_fantasy_top.cpp @@ -1,6 +1,6 @@ /* Chanstats core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -37,7 +37,6 @@ class CommandCSTop : public Command public: CommandCSTop(Module *creator) : Command (creator, "chanserv/top", 0, 2) { - this->SetFlag(CFLAG_STRIP_CHANNEL); this->SetDesc(_("Displays the top 3 users of a channel")); this->SetSyntax(_("\037channel\037")); } @@ -50,7 +49,6 @@ class CommandCSTop10 : public Command public: CommandCSTop10(Module *creator) : Command (creator, "chanserv/top10", 0, 2) { - this->SetFlag(CFLAG_STRIP_CHANNEL); this->SetDesc(_("Displays the top 10 users of a channel")); this->SetSyntax(_("\037channel\037")); } @@ -63,7 +61,6 @@ class CommandCSGTop : public Command public: CommandCSGTop(Module *creator) : Command (creator, "chanserv/gtop", 0, 1) { - this->SetFlag(CFLAG_STRIP_CHANNEL); this->SetDesc(_("Displays the top 3 users of the network")); this->SetSyntax(""); } @@ -76,7 +73,6 @@ class CommandCSGTop10 : public Command public: CommandCSGTop10(Module *creator) : Command (creator, "chanserv/gtop10", 0, 1) { - this->SetFlag(CFLAG_STRIP_CHANNEL); this->SetDesc(_("Displays the top 10 users of the network")); this->SetSyntax(""); } @@ -174,7 +170,7 @@ class CSTop : public Module } } else - source.Reply(_("No stats for %s"), is_global ? "Network" : channel.c_str()); + source.Reply(_("No stats for %s."), is_global ? "Network" : channel.c_str()); } catch (const SQL::Exception &ex) { diff --git a/modules/commands/cs_flags.cpp b/modules/commands/cs_flags.cpp index 65ae33f2f..4681c3d61 100644 --- a/modules/commands/cs_flags.cpp +++ b/modules/commands/cs_flags.cpp @@ -1,6 +1,6 @@ /* ChanServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -180,13 +180,13 @@ class CommandCSFlags : public Command if (current != NULL) { FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, source, current)); - ci->EraseAccess(current); + delete current; Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to delete " << mask; source.Reply(_("\002%s\002 removed from the %s access list."), mask.c_str(), ci->name.c_str()); } else { - source.Reply(_("Insufficient flags given")); + source.Reply(_("Insufficient flags given.")); } return; } @@ -203,7 +203,7 @@ class CommandCSFlags : public Command access->flags = current_flags; if (current != NULL) - ci->EraseAccess(current); + delete current; ci->AddAccess(access); @@ -348,19 +348,19 @@ class CommandCSFlags : public Command source.Reply(_("%s is another way to modify the channel access list, similar to\n" "the XOP and ACCESS methods."), source.command.c_str()); source.Reply(" "); - source.Reply(_("The MODIFY command allows you to modify the access list. If mask is\n" + source.Reply(_("The \002MODIFY\002 command allows you to modify the access list. If mask is\n" "not already on the access list is it added, then the changes are applied.\n" "If the mask has no more flags, then the mask is removed from the access list.\n" "Additionally, you may use +* or -* to add or remove all flags, respectively. You are\n" "only able to modify the access list if you have the proper permission on the channel,\n" "and even then you can only give other people access to up what you already have.")); source.Reply(" "); - source.Reply(_("The LIST command allows you to list existing entries on the channel access list.\n" + source.Reply(_("The \002LIST\002 command allows you to list existing entries on the channel access list.\n" "If a mask is given, the mask is wildcard matched against all existing entries on the\n" "access list, and only those entries are returned. If a set of flags is given, only those\n" "on the access list with the specified flags are returned.")); source.Reply(" "); - source.Reply(_("The CLEAR command clears the channel access list, which requires channel founder.")); + source.Reply(_("The \002CLEAR\002 command clears the channel access list, which requires channel founder.")); source.Reply(" "); source.Reply(_("The available flags are:")); diff --git a/modules/commands/cs_getkey.cpp b/modules/commands/cs_getkey.cpp index 212388e3f..1ac5633ea 100644 --- a/modules/commands/cs_getkey.cpp +++ b/modules/commands/cs_getkey.cpp @@ -1,6 +1,6 @@ /* ChanServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -40,7 +40,7 @@ class CommandCSGetKey : public Command } Anope::string key; - if (!ci->c || !ci->c->GetParam(CMODE_KEY, key)) + if (!ci->c || !ci->c->GetParam("KEY", key)) { source.Reply(_("Channel \002%s\002 has no key."), chan.c_str()); return; diff --git a/modules/commands/cs_info.cpp b/modules/commands/cs_info.cpp index c485c3cb4..9485e81fd 100644 --- a/modules/commands/cs_info.cpp +++ b/modules/commands/cs_info.cpp @@ -1,6 +1,6 @@ /* ChanServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -15,9 +15,9 @@ class CommandCSInfo : public Command { - void CheckOptStr(Anope::string &buf, ChannelInfoFlag opt, const char *str, const ChannelInfo *ci, const NickCore *nc) + void CheckOptStr(Anope::string &buf, const Anope::string &opt, const char *str, const ChannelInfo *ci, const NickCore *nc) { - if (ci->HasFlag(opt)) + if (ci->HasExt(opt)) { if (!buf.empty()) buf += ", "; @@ -29,9 +29,9 @@ class CommandCSInfo : public Command public: CommandCSInfo(Module *creator) : Command(creator, "chanserv/info", 1, 2) { - this->SetFlag(CFLAG_ALLOW_UNREGISTERED); this->SetDesc(_("Lists information about the named registered channel")); this->SetSyntax(_("\037channel\037")); + this->AllowUnregistered(true); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override @@ -59,8 +59,8 @@ class CommandCSInfo : public Command if (ci->GetFounder()) info["Founder"] = ci->GetFounder()->display; - if (show_all && ci->successor) - info["Successor"] = ci->successor->display; + if (show_all && ci->GetSuccessor()) + info["Successor"] = ci->GetSuccessor()->display; if (!ci->desc.empty()) info["Description"] = ci->desc; @@ -68,8 +68,8 @@ class CommandCSInfo : public Command info["Registered"] = Anope::strftime(ci->time_registered); info["Last used"] = Anope::strftime(ci->last_used); - const ModeLock *secret = ci->GetMLock(CMODE_SECRET); - if (!ci->last_topic.empty() && (show_all || ((!secret || secret->set == false) && (!ci->c || !ci->c->HasMode(CMODE_SECRET))))) + const ModeLock *secret = ci->GetMLock("SECRET"); + if (!ci->last_topic.empty() && (show_all || ((!secret || secret->set == false) && (!ci->c || !ci->c->HasMode("SECRET"))))) { info["Last topic"] = ci->last_topic; info["Topic set by"] = ci->last_topic_setter; @@ -80,21 +80,21 @@ class CommandCSInfo : public Command info["Ban type"] = stringify(ci->bantype); Anope::string optbuf; - CheckOptStr(optbuf, CI_KEEPTOPIC, _("Topic Retention"), ci, nc); - CheckOptStr(optbuf, CI_PEACE, _("Peace"), ci, nc); - CheckOptStr(optbuf, CI_PRIVATE, _("Private"), ci, nc); - CheckOptStr(optbuf, CI_RESTRICTED, _("Restricted Access"), ci, nc); - CheckOptStr(optbuf, CI_SECURE, _("Secure"), ci, nc); - CheckOptStr(optbuf, CI_SECUREFOUNDER, _("Secure Founder"), ci, nc); - CheckOptStr(optbuf, CI_SECUREOPS, _("Secure Ops"), ci, nc); - if (ci->HasFlag(CI_SIGNKICK)) - CheckOptStr(optbuf, CI_SIGNKICK, _("Signed kicks"), ci, nc); + CheckOptStr(optbuf, "KEEPTOPIC", _("Topic Retention"), ci, nc); + CheckOptStr(optbuf, "PEACE", _("Peace"), ci, nc); + CheckOptStr(optbuf, "PRIVATE", _("Private"), ci, nc); + CheckOptStr(optbuf, "RESTRICTED", _("Restricted Access"), ci, nc); + CheckOptStr(optbuf, "SECURE", _("Secure"), ci, nc); + CheckOptStr(optbuf, "SECUREFOUNDER", _("Secure Founder"), ci, nc); + CheckOptStr(optbuf, "SECUREOPS", _("Secure Ops"), ci, nc); + if (ci->HasExt("SIGNKICK")) + CheckOptStr(optbuf, "SIGNKICK", _("Signed kicks"), ci, nc); else - CheckOptStr(optbuf, CI_SIGNKICK_LEVEL, _("Signed kicks"), ci, nc); - CheckOptStr(optbuf, CI_TOPICLOCK, _("Topic Lock"), ci, nc); - CheckOptStr(optbuf, CI_PERSIST, _("Persistant"), ci, nc); - CheckOptStr(optbuf, CI_NO_EXPIRE, _("No expire"), ci, nc); - CheckOptStr(optbuf, CI_STATS, _("Chanstats"), ci, nc); + CheckOptStr(optbuf, "SIGNKICK_LEVEL", _("Signed kicks"), ci, nc); + CheckOptStr(optbuf, "TOPICLOCK", _("Topic Lock"), ci, nc); + CheckOptStr(optbuf, "PERSIST", _("Persistent"), ci, nc); + CheckOptStr(optbuf, "NO_EXPIRE", _("No expire"), ci, nc); + CheckOptStr(optbuf, "STATS", _("Chanstats"), ci, nc); info["Options"] = optbuf.empty() ? _("None") : optbuf; @@ -102,10 +102,10 @@ class CommandCSInfo : public Command if (!ml.empty()) info["Mode lock"] = ml; - if (!ci->HasFlag(CI_NO_EXPIRE)) + if (!ci->HasExt("NO_EXPIRE")) info["Expires on"] = Anope::strftime(ci->last_used + Config->CSExpire); } - if (ci->HasFlag(CI_SUSPENDED)) + if (ci->HasExt("SUSPENDED")) { Anope::string *by = ci->GetExt<ExtensibleItemClass<Anope::string> *>("suspend_by"), *reason = ci->GetExt<ExtensibleItemClass<Anope::string> *>("suspend_reason"); if (by != NULL) diff --git a/modules/commands/cs_invite.cpp b/modules/commands/cs_invite.cpp index 1085947a2..bb59d538e 100644 --- a/modules/commands/cs_invite.cpp +++ b/modules/commands/cs_invite.cpp @@ -1,6 +1,6 @@ /* ChanServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/commands/cs_kick.cpp b/modules/commands/cs_kick.cpp index e02ab5185..062c8f04d 100644 --- a/modules/commands/cs_kick.cpp +++ b/modules/commands/cs_kick.cpp @@ -1,6 +1,6 @@ /* ChanServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -18,7 +18,7 @@ class CommandCSKick : public Command public: CommandCSKick(Module *creator) : Command(creator, "chanserv/kick", 2, 3) { - this->SetDesc(_("Kicks a selected nick from a channel")); + this->SetDesc(_("Kicks a specified nick from a channel")); this->SetSyntax(_("\037channel\037 \037nick\037 [\037reason\037]")); this->SetSyntax(_("\037channel\037 \037mask\037 [\037reason\037]")); } @@ -55,7 +55,7 @@ class CommandCSKick : public Command else if (u2) { AccessGroup u2_access = ci->AccessFor(u2); - if (u != u2 && ci->HasFlag(CI_PEACE) && u2_access >= u_access) + if (u != u2 && ci->HasExt("PEACE") && u2_access >= u_access) source.Reply(ACCESS_DENIED); else if (u2->IsProtected()) source.Reply(ACCESS_DENIED); @@ -66,7 +66,7 @@ class CommandCSKick : public Command // XXX Log(LOG_COMMAND, source, this, ci) << "for " << u2->nick; - if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !u_access.HasPriv("SIGNKICK"))) + if (ci->HasExt("SIGNKICK") || (ci->HasExt("SIGNKICK_LEVEL") && !u_access.HasPriv("SIGNKICK"))) c->Kick(ci->WhoSends(), u2, "%s (%s)", reason.c_str(), source.GetNick().c_str()); else c->Kick(ci->WhoSends(), u2, "%s", reason.c_str()); @@ -77,22 +77,22 @@ class CommandCSKick : public Command Log(LOG_COMMAND, source, this, ci) << "for " << target; int matched = 0, kicked = 0; - for (CUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end;) + for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end;) { - UserContainer *uc = *it++; + ChanUserContainer *uc = *it++; if (Anope::Match(uc->user->nick, target) || Anope::Match(uc->user->GetDisplayedMask(), target)) { ++matched; AccessGroup u2_access = ci->AccessFor(uc->user); - if (u != uc->user && ci->HasFlag(CI_PEACE) && u2_access >= u_access) + if (u != uc->user && ci->HasExt("PEACE") && u2_access >= u_access) continue; else if (uc->user->IsProtected()) continue; ++kicked; - if (ci->HasFlag(CI_SIGNKICK) || (ci->HasFlag(CI_SIGNKICK_LEVEL) && !u_access.HasPriv("SIGNKICK"))) + if (ci->HasExt("SIGNKICK") || (ci->HasExt("SIGNKICK_LEVEL") && !u_access.HasPriv("SIGNKICK"))) c->Kick(ci->WhoSends(), uc->user, "%s (Matches %s) (%s)", reason.c_str(), target.c_str(), source.GetNick().c_str()); else c->Kick(ci->WhoSends(), uc->user, "%s (Matches %s)", reason.c_str(), target.c_str()); @@ -112,7 +112,7 @@ class CommandCSKick : public Command { this->SendSyntax(source); source.Reply(" "); - source.Reply(_("Kicks a selected nick on a channel.\n" + source.Reply(_("Kicks a specified nick from a channel.\n" " \n" "By default, limited to AOPs or those with level 5 access\n" "and above on the channel. Channel founders may use masks too.")); diff --git a/modules/commands/cs_list.cpp b/modules/commands/cs_list.cpp index 9132d07a8..29c8a827b 100644 --- a/modules/commands/cs_list.cpp +++ b/modules/commands/cs_list.cpp @@ -1,6 +1,6 @@ /* ChanServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -18,7 +18,6 @@ class CommandCSList : public Command public: CommandCSList(Module *creator) : Command(creator, "chanserv/list", 1, 2) { - this->SetFlag(CFLAG_STRIP_CHANNEL); this->SetDesc(_("Lists all registered channels matching the given pattern")); this->SetSyntax(_("\037pattern\037 [SUSPENDED] [NOEXPIRE]")); } @@ -75,15 +74,19 @@ class CommandCSList : public Command ListFormatter list; list.AddColumn("Name").AddColumn("Description"); + Anope::map<ChannelInfo *> ordered_map; for (registered_channel_map::const_iterator it = RegisteredChannelList->begin(), it_end = RegisteredChannelList->end(); it != it_end; ++it) + ordered_map[it->first] = it->second; + + for (Anope::map<ChannelInfo *>::const_iterator it = ordered_map.begin(), it_end = ordered_map.end(); it != it_end; ++it) { const ChannelInfo *ci = it->second; - if (!is_servadmin && (ci->HasFlag(CI_PRIVATE) || ci->HasFlag(CI_SUSPENDED))) + if (!is_servadmin && (ci->HasExt("PRIVATE") || ci->HasExt("SUSPENDED"))) continue; - else if (suspended && !ci->HasFlag(CI_SUSPENDED)) + else if (suspended && !ci->HasExt("SUSPENDED")) continue; - else if (channoexpire && !ci->HasFlag(CI_NO_EXPIRE)) + else if (channoexpire && !ci->HasExt("NO_EXPIRE")) continue; if (pattern.equals_ci(ci->name) || ci->name.equals_ci(spattern) || Anope::Match(ci->name, pattern, false, true) || Anope::Match(ci->name, spattern, false, true)) @@ -91,12 +94,12 @@ class CommandCSList : public Command if (((count + 1 >= from && count + 1 <= to) || (!from && !to)) && ++nchans <= Config->CSListMax) { bool isnoexpire = false; - if (is_servadmin && (ci->HasFlag(CI_NO_EXPIRE))) + if (is_servadmin && (ci->HasExt("NO_EXPIRE"))) isnoexpire = true; ListFormatter::ListEntry entry; entry["Name"] = (isnoexpire ? "!" : "") + ci->name; - if (ci->HasFlag(CI_SUSPENDED)) + if (ci->HasExt("SUSPENDED")) entry["Description"] = "[Suspended]"; else entry["Description"] = ci->desc; @@ -145,11 +148,15 @@ class CommandCSList : public Command " Lists all registered channels which have been set to not expire.\n" " \n" " \002LIST #51-100\002\n" - " Lists all registered channels within the given range (51-100).\n")); + " Lists all registered channels within the given range (51-100).")); + if (!Config->RegexEngine.empty()) - source.Reply(" \n" - "Regex matches are also supported using the %s engine.\n" - "Enclose your pattern in // if this desired.", Config->RegexEngine.c_str()); + { + source.Reply(" "); + source.Reply(_("Regex matches are also supported using the %s engine.\n" + "Enclose your pattern in // if this is desired."), Config->RegexEngine.c_str()); + } + return true; } }; diff --git a/modules/commands/cs_log.cpp b/modules/commands/cs_log.cpp index 4965ab561..41d8229f6 100644 --- a/modules/commands/cs_log.cpp +++ b/modules/commands/cs_log.cpp @@ -1,6 +1,6 @@ /* ChanServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -117,7 +117,7 @@ public: { if (log->extra == extra) { - log->Destroy(); + delete log; ci->log_settings->erase(ci->log_settings->begin() + i - 1); Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to remove logging for " << command << " with method " << method << (extra == "" ? "" : " ") << extra; source.Reply(_("Logging for command %s on %s with log method %s%s%s has been removed."), command_name.c_str(), bi->nick.c_str(), method.c_str(), extra.empty() ? "" : " ", extra.empty() ? "" : extra.c_str()); @@ -181,10 +181,12 @@ public: class CSLog : public Module { + ServiceReference<MemoServService> MSService; CommandCSLog commandcslog; public: - CSLog(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), commandcslog(this) + CSLog(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + MSService("MemoServService", "MemoServ"), commandcslog(this) { this->SetAuthor("Anope"); @@ -212,8 +214,8 @@ class CSLog : public Module } else if (log->method.equals_ci("NOTICE") && l->ci->c && l->ci->bi && l->ci->c->FindUser(l->ci->bi) != NULL) IRCD->SendNotice(l->ci->bi, log->extra + l->ci->c->name, "%s", buffer.c_str()); - else if (log->method.equals_ci("MEMO") && MemoServService && l->ci->WhoSends() != NULL) - MemoServService->Send(l->ci->WhoSends()->nick, l->ci->name, buffer, true); + else if (log->method.equals_ci("MEMO") && MSService && l->ci->WhoSends() != NULL) + MSService->Send(l->ci->WhoSends()->nick, l->ci->name, buffer, true); } } } diff --git a/modules/commands/cs_mode.cpp b/modules/commands/cs_mode.cpp index c33b317a2..d44e7e07b 100644 --- a/modules/commands/cs_mode.cpp +++ b/modules/commands/cs_mode.cpp @@ -1,6 +1,6 @@ /* ChanServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -15,29 +15,30 @@ class CommandCSMode : public Command { - bool CanSet(CommandSource &source, ChannelInfo *ci, ChannelMode *cm) + bool CanSet(CommandSource &source, ChannelInfo *ci, ChannelMode *cm, bool self) { if (!ci || !cm || cm->type != MODE_STATUS) return false; - const Anope::string accesses[] = { "VOICE", "HALFOP", "OPDEOP", "PROTECT", "OWNER", "" }; - const ChannelModeName modes[] = { CMODE_VOICE, CMODE_HALFOP, CMODE_OP, CMODE_PROTECT, CMODE_OWNER }; + const Anope::string accesses[] = { "VOICE", "HALFOP", "OPDEOP", "PROTECT", "OWNER", "" }, + accesses_self[] = { "VOICEME", "HALFOPME", "OPDEOPME", "PROTECTME", "OWNERME", "" }; + const Anope::string modes[] = { "VOICE", "HALFOP", "OP", "PROTECT", "OWNER" }; ChannelModeStatus *cms = anope_dynamic_static_cast<ChannelModeStatus *>(cm); AccessGroup access = source.AccessFor(ci); - unsigned short u_level = 0; + short u_level = -1; for (int i = 0; !accesses[i].empty(); ++i) - if (access.HasPriv(accesses[i])) + if (access.HasPriv(self ? accesses_self[i] : accesses[i])) { ChannelMode *cm2 = ModeManager::FindChannelModeByName(modes[i]); if (cm2 == NULL || cm2->type != MODE_STATUS) continue; ChannelModeStatus *cms2 = anope_dynamic_static_cast<ChannelModeStatus *>(cm2); - if (cms2->Level > u_level) - u_level = cms2->Level; + if (cms2->level > u_level) + u_level = cms2->level; } - return u_level >= cms->Level; + return u_level >= cms->level; } void DoLock(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> ¶ms) @@ -48,12 +49,29 @@ class CommandCSMode : public Command bool override = !source.AccessFor(ci).HasPriv("MODE"); - if (subcommand.equals_ci("ADD") && !param.empty()) + if ((subcommand.equals_ci("ADD") || subcommand.equals_ci("SET")) && !param.empty()) { + /* If setting, remove the existing locks */ + if (subcommand.equals_ci("SET")) + { + const ChannelInfo::ModeList &mlocks = ci->GetMLock(); + for (ChannelInfo::ModeList::const_iterator it = mlocks.begin(), it_next; it != mlocks.end(); it = it_next) + { + const ModeLock *ml = it->second; + ChannelMode *cm = ModeManager::FindChannelModeByName(ml->name); + it_next = it; + ++it_next; + if (cm && cm->CanSet(source.GetUser())) + ci->RemoveMLock(cm, ml->set, ml->param); + } + } + spacesepstream sep(param); Anope::string modes; sep.GetToken(modes); + + Anope::string pos = "+", neg = "-", pos_params, neg_params; int adding = -1; for (size_t i = 0; i < modes.length(); ++i) @@ -87,14 +105,32 @@ class CommandCSMode : public Command else { ci->SetMLock(cm, adding, mode_param, source.GetNick()); - if (!mode_param.empty()) - mode_param = " " + mode_param; - source.Reply(_("%c%c%s locked on %s"), adding ? '+' : '-', cm->mchar, mode_param.c_str(), ci->name.c_str()); - Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to lock " << (adding ? '+' : '-') << cm->mchar << mode_param; + + if (adding) + { + pos += cm->mchar; + if (!mode_param.empty()) + pos_params += " " + mode_param; + } + else + { + neg += cm->mchar; + if (!mode_param.empty()) + neg_params += " " + mode_param; + } } } } + if (pos == "+") + pos.clear(); + if (neg == "-") + neg.clear(); + Anope::string reply = pos + neg + pos_params + neg_params; + + source.Reply(_("%s locked on %s."), ci->GetMLockAsString(true).c_str(), ci->name.c_str()); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to lock " << ci->GetMLockAsString(true); + if (ci->c) ci->c->CheckModes(); } @@ -193,10 +229,12 @@ class CommandCSMode : public Command { User *u = source.GetUser(); + bool has_access = source.AccessFor(ci).HasPriv("MODE") || source.HasPriv("chanserv/set"); + spacesepstream sep(params.size() > 3 ? params[3] : ""); Anope::string modes = params[2], param; - bool override = !source.AccessFor(ci).HasPriv("MODE"); + bool override = !source.AccessFor(ci).HasPriv("MODE") && source.HasPriv("chanserv/set"); Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to set " << params[2]; int adding = -1; @@ -211,7 +249,7 @@ class CommandCSMode : public Command adding = 0; break; case '*': - if (adding == -1) + if (adding == -1 || !has_access) break; for (unsigned j = 0; j < ModeManager::ChannelModes.size(); ++j) { @@ -237,12 +275,16 @@ class CommandCSMode : public Command switch (cm->type) { case MODE_REGULAR: + if (!has_access) + break; if (adding) ci->c->SetMode(NULL, cm); else ci->c->RemoveMode(NULL, cm); break; case MODE_PARAM: + if (!has_access) + break; if (adding && !sep.GetToken(param)) break; if (adding) @@ -253,25 +295,25 @@ class CommandCSMode : public Command case MODE_STATUS: { if (!sep.GetToken(param)) - break; - - if (!this->CanSet(source, ci, cm)) - { - source.Reply(_("You do not have access to set mode %c."), cm->mchar); - break; - } + param = source.GetNick(); AccessGroup u_access = source.AccessFor(ci); if (param.find_first_of("*?") != Anope::string::npos) { - for (CUserList::const_iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it) + if (!this->CanSet(source, ci, cm, false)) { - UserContainer *uc = *it; + source.Reply(_("You do not have access to set mode %c."), cm->mchar); + break; + } + + for (Channel::ChanUserList::const_iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it) + { + ChanUserContainer *uc = *it; AccessGroup targ_access = ci->AccessFor(uc->user); - if (targ_access > u_access) + if (uc->user->IsProtected() || targ_access > u_access) { source.Reply(_("You do not have the access to change %s's modes."), uc->user->nick.c_str()); continue; @@ -295,13 +337,27 @@ class CommandCSMode : public Command break; } - AccessGroup targ_access = ci->AccessFor(target); - if (targ_access > u_access) + if (!this->CanSet(source, ci, cm, source.GetUser() == target)) { - source.Reply(_("You do not have the access to change %s's modes."), target->nick.c_str()); + source.Reply(_("You do not have access to set mode %c."), cm->mchar); break; } + if (source.GetUser() != target) + { + AccessGroup targ_access = ci->AccessFor(target); + if (targ_access > u_access) + { + source.Reply(_("You do not have the access to change %s's modes."), target->nick.c_str()); + break; + } + else if (target->IsProtected()) + { + source.Reply(ACCESS_DENIED); + break; + } + } + if (adding) ci->c->SetMode(NULL, cm, target->GetUID()); else @@ -310,6 +366,8 @@ class CommandCSMode : public Command break; } case MODE_LIST: + if (!has_access) + break; if (!sep.GetToken(param)) break; if (adding) @@ -331,12 +389,46 @@ class CommandCSMode : public Command } } + void DoClear(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> ¶ms) + { + const Anope::string ¶m = params.size() > 2 ? params[2] : ""; + + if (param.empty()) + { + std::vector<Anope::string> new_params; + new_params.push_back(params[0]); + new_params.push_back("SET"); + new_params.push_back("-*"); + this->DoSet(source, ci, new_params); + } + else if (param.equals_ci("BANS") || param.equals_ci("EXCEPTS") || param.equals_ci("INVITEOVERRIDES") || param.equals_ci("VOICES") || param.equals_ci("HALFOPS") || param.equals_ci("OPS")) + { + const Anope::string &mname = param.upper().substr(0, param.length() - 1); + ChannelMode *cm = ModeManager::FindChannelModeByName(mname); + if (cm == NULL) + { + source.Reply(_("Your IRCD does not support %s."), mname.upper().c_str()); + return; + } + + std::vector<Anope::string> new_params; + new_params.push_back(params[0]); + new_params.push_back("SET"); + new_params.push_back("-" + stringify(cm->mchar)); + new_params.push_back("*"); + this->DoSet(source, ci, new_params); + } + else + this->SendSyntax(source); + } + public: - CommandCSMode(Module *creator) : Command(creator, "chanserv/mode", 3, 4) + CommandCSMode(Module *creator) : Command(creator, "chanserv/mode", 2, 4) { this->SetDesc(_("Control modes and mode locks on a channel")); - this->SetSyntax(_("\037channel\037 LOCK {ADD|DEL|LIST} [\037what\037]")); + this->SetSyntax(_("\037channel\037 LOCK {ADD|DEL|SET|LIST} [\037what\037]")); this->SetSyntax(_("\037channel\037 SET \037modes\037")); + this->SetSyntax(_("\037channel\037 CLEAR [\037what\037]")); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override @@ -347,16 +439,24 @@ class CommandCSMode : public Command if (!ci || !ci->c) source.Reply(CHAN_X_NOT_IN_USE, params[0].c_str()); - else if (!source.AccessFor(ci).HasPriv("MODE") && !source.HasPriv("chanserv/set")) - source.Reply(ACCESS_DENIED); - else if (subcommand.equals_ci("LOCK")) - this->DoLock(source, ci, params); - else if (subcommand.equals_ci("SET")) + else if (subcommand.equals_ci("LOCK") && params.size() > 2) + { + if (!source.AccessFor(ci).HasPriv("MODE") && !source.HasPriv("chanserv/set")) + source.Reply(ACCESS_DENIED); + else + this->DoLock(source, ci, params); + } + else if (subcommand.equals_ci("SET") && params.size() > 2) this->DoSet(source, ci, params); + else if (subcommand.equals_ci("CLEAR")) + { + if (!source.AccessFor(ci).HasPriv("MODE") && !source.HasPriv("chanserv/set")) + source.Reply(ACCESS_DENIED); + else + this->DoClear(source, ci, params); + } else this->OnSyntaxError(source, ""); - - return; } bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override @@ -366,19 +466,26 @@ class CommandCSMode : public Command source.Reply(_("Mainly controls mode locks and mode access (which is different from channel access)\n" "on a channel.\n" " \n" - "The \002MODE LOCK\002 command allows you to add, delete, and view mode locks on a channel.\n" - "If a mode is locked on or off, services will not allow that mode to be changed.\n" + "The \002%s LOCK\002 command allows you to add, delete, and view mode locks on a channel.\n" + "If a mode is locked on or off, services will not allow that mode to be changed. The \2SET\2\n" + "command will clear all existing mode locks and set the new one given, while \2ADD\2 and \2DEL\2\n" + "modify the existing mode lock.\n" "Example:\n" " \002MODE #channel LOCK ADD +bmnt *!*@*aol*\002\n" " \n" - "The \002MODE SET\002 command allows you to set modes through services. Wildcards * and ? may\n" + "The \002%s SET\002 command allows you to set modes through services. Wildcards * and ? may\n" "be given as parameters for list and status modes.\n" "Example:\n" " \002MODE #channel SET +v *\002\n" " Sets voice status to all users in the channel.\n" " \n" " \002MODE #channel SET -b ~c:*\n" - " Clears all extended bans that start with ~c:")); + " Clears all extended bans that start with ~c:\n" + " \n" + "The \002%s CLEAR\002 command is an easy way to clear modes on a channel. \037what\037 may be\n" + "one of bans, exempts, inviteoverrides, ops, halfops, or voices. If \037what\037 is not given then all\n" + "basic modes are removed."), + source.command.upper().c_str(), source.command.upper().c_str(), source.command.upper().c_str()); return true; } }; diff --git a/modules/commands/cs_modes.cpp b/modules/commands/cs_modes.cpp deleted file mode 100644 index 696c38dde..000000000 --- a/modules/commands/cs_modes.cpp +++ /dev/null @@ -1,430 +0,0 @@ -/* ChanServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandModeBase : public Command -{ - void do_mode(CommandSource &source, Command *com, ChannelMode *cm, const Anope::string &chan, const Anope::string &nick, bool set, const Anope::string &level, const Anope::string &levelself) - { - User *u = source.GetUser(); - User *u2 = User::Find(nick, true); - Channel *c = Channel::Find(chan); - - if (!c) - { - source.Reply(CHAN_X_NOT_IN_USE, chan.c_str()); - return; - - } - - if (!u2) - { - source.Reply(NICK_X_NOT_IN_USE, nick.c_str()); - return; - } - - ChannelInfo *ci = c->ci; - if (!ci) - { - source.Reply(CHAN_X_NOT_REGISTERED, c->name.c_str()); - return; - } - - bool is_same = u == u2; - AccessGroup u_access = source.AccessFor(ci), u2_access = ci->AccessFor(u2); - - if (is_same ? !source.AccessFor(ci).HasPriv(levelself) : !source.AccessFor(ci).HasPriv(level)) - source.Reply(ACCESS_DENIED); - else if (!set && !is_same && ci->HasFlag(CI_PEACE) && u2_access >= u_access) - source.Reply(ACCESS_DENIED); - else if (!set && u2->IsProtected() && !is_same) - source.Reply(ACCESS_DENIED); - else if (!c->FindUser(u2)) - source.Reply(NICK_X_NOT_ON_CHAN, u2->nick.c_str(), c->name.c_str()); - else - { - if (set) - c->SetMode(NULL, cm, u2->GetUID()); - else - c->RemoveMode(NULL, cm, u2->GetUID()); - - Log(LOG_COMMAND, source, com, ci) << "for " << u2->nick; - } - } - - protected: - /** do_util: not a command, but does the job of others - * @param source The source of the command - * @param com The command calling this function - * @param cm A channel mode class - * @param chan The channel its being set on - * @param nick The nick the modes being set on - * @param set Is the mode being set or removed - * @param level The access level required to set this mode on someone else - * @param levelself The access level required to set this mode on yourself - */ - void do_util(CommandSource &source, Command *com, ChannelMode *cm, const Anope::string &chan, const Anope::string &nick, bool set, const Anope::string &level, const Anope::string &levelself) - { - User *u = source.GetUser(); - - if (chan.empty() && u) - for (UChannelList::iterator it = u->chans.begin(); it != u->chans.end(); ++it) - do_mode(source, com, cm, (*it)->chan->name, u->nick, set, level, levelself); - else if (!chan.empty()) - do_mode(source, com, cm, chan, !nick.empty() ? nick : u->nick, set, level, levelself); - } - - public: - CommandModeBase(Module *creator, const Anope::string &cname) : Command(creator, cname, 0, 2) - { - this->SetSyntax(_("[\037channel\037] [\037nick\037]")); - } -}; - -class CommandCSOp : public CommandModeBase -{ - public: - CommandCSOp(Module *creator) : CommandModeBase(creator, "chanserv/op") - { - this->SetDesc(_("Gives Op status to a selected nick on a channel")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OP); - - return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, "OPDEOP", "OPDEOPME"); - } - - bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Ops a selected nick on a channel. If nick is not given,\n" - "it will op you. If channel is not given, it will op you\n" - "on every channel.\n" - " \n" - "By default, limited to AOPs or those with level 5 access\n" - "and above on the channel.")); - return true; - } -}; - -class CommandCSDeOp : public CommandModeBase -{ - public: - CommandCSDeOp(Module *creator) : CommandModeBase(creator, "chanserv/deop") - { - this->SetDesc(_("Deops a selected nick on a channel")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OP); - - return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, "OPDEOP", "OPDEOPME"); - } - - bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply("Deops a selected nick on a channel. If nick is not given,\n" - "it will deop you. If channel is not given, it will deop\n" - "you on every channel.\n" - " \n" - "By default, limited to AOPs or those with level 5 access\n" - "and above on the channel."); - return true; - } -}; - -class CommandCSVoice : public CommandModeBase -{ - public: - CommandCSVoice(Module *creator) : CommandModeBase(creator, "chanserv/voice") - { - this->SetDesc(_("Voices a selected nick on a channel")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_VOICE); - - return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, "VOICE", "VOICEME"); - } - - bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Voices a selected nick on a channel. If nick is not given,\n" - "it will voice you. If channel is not given, it will voice you\n" - "on every channel.\n" - " \n" - "By default, limited to AOPs or those with level 5 access\n" - "and above on the channel, or to VOPs or those with level 3\n" - "and above for self voicing.")); - return true; - } -}; - -class CommandCSDeVoice : public CommandModeBase -{ - public: - CommandCSDeVoice(Module *creator) : CommandModeBase(creator, "chanserv/devoice") - { - this->SetDesc(_("Devoices a selected nick on a channel")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_VOICE); - - return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, "VOICE", "VOICEME"); - } - - bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Devoices a selected nick on a channel. If nick is not given,\n" - "it will devoice you. If channel is not given, it will devoice\n" - "you on every channel.\n" - " \n" - "By default, limited to AOPs or those with level 5 access\n" - "and above on the channel, or to VOPs or those with level 3\n" - "and above for self devoicing.")); - return true; - } -}; - -class CommandCSHalfOp : public CommandModeBase -{ - public: - CommandCSHalfOp(Module *creator) : CommandModeBase(creator, "chanserv/halfop") - { - this->SetDesc(_("Halfops a selected nick on a channel")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_HALFOP); - - if (!cm) - return; - - return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, "HALFOP", "HALFOPME"); - } - - bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Halfops a selected nick on a channel. If nick is not given,\n" - "it will halfop you. If channel is not given, it will halfop\n" - "you on every channel.\n" - " \n" - "By default, limited to AOPs and those with level 5 access\n" - "and above on the channel, or to HOPs or those with level 4\n" - "and above for self halfopping.")); - return true; - } -}; - -class CommandCSDeHalfOp : public CommandModeBase -{ - public: - CommandCSDeHalfOp(Module *creator) : CommandModeBase(creator, "chanserv/dehalfop") - { - this->SetDesc(_("Dehalfops a selected nick on a channel")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_HALFOP); - - if (!cm) - return; - - return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, "HALFOP", "HALFOPME"); - } - - bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Dehalfops a selected nick on a channel. If nick is not given,\n" - "it will dehalfop you. If channel is not given, it will dehalfop\n" - "you on every channel.\n" - " \n" - "By default, limited to AOPs and those with level 5 access\n" - "and above on the channel, or to HOPs or those with level 4\n" - "and above for self dehalfopping.")); - return true; - } -}; - -class CommandCSProtect : public CommandModeBase -{ - public: - CommandCSProtect(Module *creator) : CommandModeBase(creator, "chanserv/protect") - { - this->SetDesc(_("Protects a selected nick on a channel")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_PROTECT); - - if (!cm) - return; - - return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, "PROTECT", "PROTECTME"); - } - - bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Protects a selected nick on a channel. If nick is not given,\n" - "it will protect you. If channel is not given, it will protect\n" - "you on every channel.\n" - " \n" - "By default, limited to the founder, or to SOPs or those with\n" - "level 10 and above on the channel for self protecting.")); - return true; - } -}; - -class CommandCSDeProtect : public CommandModeBase -{ - public: - CommandCSDeProtect(Module *creator) : CommandModeBase(creator, "chanserv/deprotect") - { - this->SetDesc(_("Deprotects a selected nick on a channel")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_PROTECT); - - if (!cm) - return; - - return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, "PROTECT", "PROTECTME"); - } - - bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Deprotects a selected nick on a channel. If nick is not given,\n" - "it will deprotect you. If channel is not given, it will deprotect\n" - "you on every channel.\n" - " \n" - "By default, limited to the founder, or to SOPs or those with\n" - "level 10 and above on the channel for self deprotecting.")); - return true; - } -}; - -class CommandCSOwner : public CommandModeBase -{ - public: - CommandCSOwner(Module *creator) : CommandModeBase(module, "chanserv/owner") - { - this->SetDesc(_("Gives you owner status on channel")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OWNER); - - if (!cm) - return; - - return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", true, "OWNER", "OWNERME"); - } - - bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Gives the selected nick owner status on \002channel\002. If nick is not\n" - "given, it will give you owner. If channel is not given, it will\n" - "give you owner on every channel.\n" - " \n" - "Limited to those with founder access on the channel.")); - return true; - } -}; - -class CommandCSDeOwner : public CommandModeBase -{ - public: - CommandCSDeOwner(Module *creator) : CommandModeBase(creator, "chanserv/deowner") - { - this->SetDesc(_("Removes your owner status on a channel")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_OWNER); - - if (!cm) - return; - - return do_util(source, this, cm, !params.empty() ? params[0] : "", params.size() > 1 ? params[1] : "", false, "OWNER", "OWNERME"); - } - - bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Removes owner status from the selected nick on \002channel\002. If nick\n" - "is not given, it will deowner you. If channel is not given, it will\n" - "deowner you on every channel.\n" - " \n" - "Limited to those with founder access on the channel.")); - return true; - } -}; - -class CSModes : public Module -{ - CommandCSOwner commandcsowner; - CommandCSDeOwner commandcsdeowner; - CommandCSProtect commandcsprotect; - CommandCSDeProtect commandcsdeprotect; - CommandCSOp commandcsop; - CommandCSDeOp commandcsdeop; - CommandCSHalfOp commandcshalfop; - CommandCSDeHalfOp commandcsdehalfop; - CommandCSVoice commandcsvoice; - CommandCSDeVoice commandcsdevoice; - - public: - CSModes(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandcsowner(this), commandcsdeowner(this), commandcsprotect(this), commandcsdeprotect(this), - commandcsop(this), commandcsdeop(this), commandcshalfop(this), commandcsdehalfop(this), - commandcsvoice(this), commandcsdevoice(this) - { - this->SetAuthor("Anope"); - - - } -}; - -MODULE_INIT(CSModes) diff --git a/modules/commands/cs_register.cpp b/modules/commands/cs_register.cpp index d1ada3c19..a79942fc3 100644 --- a/modules/commands/cs_register.cpp +++ b/modules/commands/cs_register.cpp @@ -1,6 +1,6 @@ /* ChanServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -34,7 +34,7 @@ class CommandCSRegister : public Command if (Anope::ReadOnly) source.Reply(_("Sorry, channel registration is temporarily disabled.")); - else if (nc->HasFlag(NI_UNCONFIRMED)) + else if (nc->HasExt("UNCONFIRMED")) source.Reply(_("You must confirm your account before you can register a channel.")); else if (chan[0] == '&') source.Reply(_("Local channels cannot be registered.")); @@ -46,7 +46,7 @@ class CommandCSRegister : public Command source.Reply(CHAN_X_NOT_IN_USE, chan.c_str()); else if (ci) source.Reply(_("Channel \002%s\002 is already registered!"), chan.c_str()); - else if (c && !c->HasUserStatus(u, CMODE_OP)) + else if (c && !c->HasUserStatus(u, "OP")) source.Reply(_("You must be a channel operator to register the channel.")); else if (Config->CSMaxReg && nc->channelcount >= Config->CSMaxReg && !source.HasPriv("chanserv/no-register-limit")) source.Reply(nc->channelcount > Config->CSMaxReg ? CHAN_EXCEEDED_CHANNEL_LIMIT : CHAN_REACHED_CHANNEL_LIMIT, Config->CSMaxReg); @@ -54,16 +54,12 @@ class CommandCSRegister : public Command { ci = new ChannelInfo(chan); ci->SetFounder(nc); - if (!chdesc.empty()) - ci->desc = chdesc; + ci->desc = chdesc; - for (ChannelInfo::ModeList::iterator it = ModeManager::DefaultModeLocks.begin(), it_end = ModeManager::DefaultModeLocks.end(); it != it_end; ++it) - { - ModeLock *ml = new ModeLock(*it->second); - ml->setter = source.GetNick(); - ml->ci = ci; - ci->mode_locks->insert(std::make_pair(it->first, ml)); - } + for (std::list<std::pair<Anope::string, Anope::string> >::const_iterator it = ModeManager::ModeLockOn.begin(), it_end = ModeManager::ModeLockOn.end(); it != it_end; ++it) + ci->SetMLock(ModeManager::FindChannelModeByName(it->first), true, it->second, source.GetNick()); + for (std::list<Anope::string>::const_iterator it = ModeManager::ModeLockOff.begin(), it_end = ModeManager::ModeLockOff.end(); it != it_end; ++it) + ci->SetMLock(ModeManager::FindChannelModeByName(*it), false, "", source.GetNick()); if (c && !c->topic.empty()) { @@ -86,18 +82,18 @@ class CommandCSRegister : public Command if (u && u->FindChannel(c) != NULL) { /* On most ircds you do not receive the admin/owner mode till its registered */ - if ((cm = ModeManager::FindChannelModeByName(CMODE_OWNER))) + if ((cm = ModeManager::FindChannelModeByName("OWNER"))) c->SetMode(NULL, cm, u->GetUID()); - else if ((cm = ModeManager::FindChannelModeByName(CMODE_PROTECT))) + else if ((cm = ModeManager::FindChannelModeByName("PROTECT"))) c->RemoveMode(NULL, cm, u->GetUID()); } /* Mark the channel as persistent */ - if (c->HasMode(CMODE_PERM)) - ci->SetFlag(CI_PERSIST); + if (c->HasMode("PERM")) + ci->Extend("PERSIST"); /* Persist may be in def cflags, set it here */ - else if (ci->HasFlag(CI_PERSIST) && (cm = ModeManager::FindChannelModeByName(CMODE_PERM))) - c->SetMode(NULL, CMODE_PERM); + else if (ci->HasExt("PERSIST") && (cm = ModeManager::FindChannelModeByName("PERM"))) + c->SetMode(NULL, "PERM"); } FOREACH_MOD(I_OnChanRegistered, OnChanRegistered(ci)); diff --git a/modules/commands/cs_saset.cpp b/modules/commands/cs_saset.cpp deleted file mode 100644 index 211148e13..000000000 --- a/modules/commands/cs_saset.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* ChanServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandCSSASet : public Command -{ - public: - CommandCSSASet(Module *creator) : Command(creator, "chanserv/saset", 2, 3) - { - this->SetDesc(_("Forcefully set channel options and information")); - this->SetSyntax(_("\037option\037 \037channel\037 \037parameters\037")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - this->OnSyntaxError(source, ""); - return; - } - - bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Allows Services Operators to forcefully change settings\n" - "on channels.\n" - " \n" - "Available options:")); - Anope::string this_name = source.command; - for (CommandInfo::map::const_iterator it = source.service->commands.begin(), it_end = source.service->commands.end(); it != it_end; ++it) - { - const Anope::string &c_name = it->first; - const CommandInfo &info = it->second; - if (c_name.find_ci(this_name + " ") == 0) - { - ServiceReference<Command> command("Command", info.name); - if (command) - { - source.command = it->first; - command->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(), source.service->nick.c_str()); - return true; - } -}; - -class CSSASet : public Module -{ - CommandCSSASet commandcssaset; - - public: - CSSASet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandcssaset(this) - { - this->SetAuthor("Anope"); - - } -}; - -MODULE_INIT(CSSASet) diff --git a/modules/commands/cs_saset_noexpire.cpp b/modules/commands/cs_saset_noexpire.cpp deleted file mode 100644 index 1c7b260ec..000000000 --- a/modules/commands/cs_saset_noexpire.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* ChanServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandCSSASetNoexpire : public Command -{ - public: - CommandCSSASetNoexpire(Module *creator) : Command(creator, "chanserv/saset/noexpire", 2, 2) - { - this->SetDesc(_("Prevent the channel from expiring")); - this->SetSyntax(_("\037channel\037 {ON | OFF}")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - ChannelInfo *ci = ChannelInfo::Find(params[0]); - if (ci == NULL) - { - source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); - return; - } - - if (source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) - { - source.Reply(ACCESS_DENIED); - return; - } - - if (params[1].equals_ci("ON")) - { - ci->SetFlag(CI_NO_EXPIRE); - source.Reply(_("Channel %s \002will not\002 expire."), ci->name.c_str()); - } - else if (params[1].equals_ci("OFF")) - { - ci->UnsetFlag(CI_NO_EXPIRE); - source.Reply(_("Channel %s \002will\002 expire."), ci->name.c_str()); - } - else - this->OnSyntaxError(source, "NOEXPIRE"); - - return; - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Sets whether the given channel will expire. Setting this\n" - "to ON prevents the channel from expiring.")); - return true; - } -}; - -class CSSetNoexpire : public Module -{ - CommandCSSASetNoexpire commandcssasetnoexpire; - - public: - CSSetNoexpire(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandcssasetnoexpire(this) - { - this->SetAuthor("Anope"); - - } -}; - -MODULE_INIT(CSSetNoexpire) diff --git a/modules/commands/cs_seen.cpp b/modules/commands/cs_seen.cpp index 8f90e2f08..b7c821078 100644 --- a/modules/commands/cs_seen.cpp +++ b/modules/commands/cs_seen.cpp @@ -1,6 +1,6 @@ /* cs_seen: provides a seen command by tracking all users * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -98,11 +98,11 @@ static bool ShouldHide(const Anope::string &channel, User *u) Channel *targetchan = Channel::Find(channel); const ChannelInfo *targetchan_ci = targetchan ? *targetchan->ci : ChannelInfo::Find(channel); - if (targetchan && targetchan->HasMode(CMODE_SECRET)) + if (targetchan && targetchan->HasMode("SECRET")) return true; - else if (targetchan_ci && targetchan_ci->HasFlag(CI_PRIVATE)) + else if (targetchan_ci && targetchan_ci->HasExt("PRIVATE")) return true; - else if (u && u->HasMode(UMODE_PRIV)) + else if (u && u->HasMode("PRIV")) return true; return false; } @@ -113,8 +113,8 @@ class CommandOSSeen : public Command CommandOSSeen(Module *creator) : Command(creator, "operserv/seen", 1, 2) { this->SetDesc(_("Statistics and maintenance for seen data")); - this->SetSyntax(_("\037STATS\037")); - this->SetSyntax(_("\037CLEAR\037 \037time\037")); + this->SetSyntax(_("STATS")); + this->SetSyntax(_("CLEAR \037time\037")); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override @@ -132,7 +132,7 @@ class CommandOSSeen : public Command mem_counter += it->second->channel.capacity(); mem_counter += it->second->message.capacity(); } - source.Reply(_("%lu nicks are stored in the database, using %.2Lf kB of memory"), database.size(), static_cast<long double>(mem_counter) / 1024); + source.Reply(_("%lu nicks are stored in the database, using %.2Lf kB of memory."), database.size(), static_cast<long double>(mem_counter) / 1024); } else if (params[0].equals_ci("CLEAR")) { @@ -152,13 +152,13 @@ class CommandOSSeen : public Command if (time < buf->second->last) { Log(LOG_DEBUG) << buf->first << " was last seen " << Anope::strftime(buf->second->last) << ", deleting entry"; - buf->second->Destroy(); + delete buf->second; database.erase(buf); counter++; } } Log(LOG_ADMIN, source, this) << "CLEAR and removed " << counter << " nicks that were added after " << Anope::strftime(time, NULL, true); - source.Reply(_("Database cleared, removed %lu nicks that were added after %s"), counter, Anope::strftime(time, source.nc, true).c_str()); + source.Reply(_("Database cleared, removed %lu nicks that were added after %s."), counter, Anope::strftime(time, source.nc, true).c_str()); } else this->SendSyntax(source); @@ -173,8 +173,8 @@ class CommandOSSeen : public Command "entries from the database that were added within \037time\037.\n" " \n" "Example:\n" - "%s CLEAR 30m\n" - "will remove all entries that were added within the last 30 minutes."), source.command.c_str()); + " %s CLEAR 30m\n" + " Will remove all entries that were added within the last 30 minutes."), source.command.c_str()); return true; } }; @@ -184,7 +184,6 @@ class CommandSeen : public Command public: CommandSeen(Module *creator) : Command(creator, "chanserv/seen", 1, 2) { - this->SetFlag(CFLAG_STRIP_CHANNEL); this->SetDesc(_("Tells you about the last time a user was seen")); this->SetSyntax(_("\037nick\037")); } @@ -195,7 +194,7 @@ class CommandSeen : public Command if (target.length() > Config->NickLen) { - source.Reply(_("Nick too long, max length is %u chars"), Config->NickLen); + source.Reply(_("Nick too long, max length is %u characters."), Config->NickLen); return; } @@ -239,7 +238,7 @@ class CommandSeen : public Command if (u2) onlinestatus = Anope::printf( _(". %s is still online."), u2->nick.c_str()); else - onlinestatus = Anope::printf(_(", but %s mysteriously dematerialized"), info->nick2.c_str()); + onlinestatus = Anope::printf(_(", but %s mysteriously dematerialized."), info->nick2.c_str()); source.Reply(_("%s (%s) was last seen changing nick to %s %s ago%s"), target.c_str(), info->vhost.c_str(), info->nick2.c_str(), timebuf.c_str(), onlinestatus.c_str()); @@ -309,12 +308,12 @@ class DataBasePurger : public CallBack if ((Anope::CurTime - cur->second->last) > purgetime) { - Log(LOG_DEBUG) << cur->first << " was last seen " << Anope::strftime(cur->second->last) << ", purging entry"; - cur->second->Destroy(); + Log(LOG_DEBUG) << cur->first << " was last seen " << Anope::strftime(cur->second->last) << ", purging entries"; + delete cur->second; database.erase(cur); } } - Log(LOG_DEBUG) << "cs_seen: Purged Database, checked " << previous_size << " nicks and removed " << (previous_size - database.size()) << " old entries."; + Log(LOG_DEBUG) << "cs_seen: Purged database, checked " << previous_size << " nicks and removed " << (previous_size - database.size()) << " old entries."; } }; @@ -351,9 +350,9 @@ class CSSeen : public Module purger.SetSecs(expiretimeout); } - void OnUserConnect(Reference<User> &u, bool &exempt) anope_override + void OnUserConnect(User *u, bool &exempt) anope_override { - if (u) + if (!u->Quitting()) UpdateUser(u, NEW, u->nick, "", "", ""); } diff --git a/modules/commands/cs_set.cpp b/modules/commands/cs_set.cpp index 0ac07e2b2..730f31deb 100644 --- a/modules/commands/cs_set.cpp +++ b/modules/commands/cs_set.cpp @@ -1,6 +1,6 @@ /* ChanServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -9,8 +9,6 @@ * Based on the original code of Services by Andy Church. */ -/*************************************************************************/ - #include "module.h" class CommandCSSet : public Command @@ -57,16 +55,1144 @@ class CommandCSSet : public Command } }; +class CommandCSSASet : public Command +{ + public: + CommandCSSASet(Module *creator) : Command(creator, "chanserv/saset", 2, 3) + { + this->SetDesc(_("Forcefully set channel options and information")); + this->SetSyntax(_("\037option\037 \037channel\037 \037parameters\037")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + this->OnSyntaxError(source, ""); + return; + } + + bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Allows Services Operators to forcefully change settings\n" + "on channels.\n" + " \n" + "Available options:")); + Anope::string this_name = source.command; + for (CommandInfo::map::const_iterator it = source.service->commands.begin(), it_end = source.service->commands.end(); it != it_end; ++it) + { + const Anope::string &c_name = it->first; + const CommandInfo &info = it->second; + if (c_name.find_ci(this_name + " ") == 0) + { + ServiceReference<Command> command("Command", info.name); + if (command) + { + source.command = it->first; + command->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(), source.service->nick.c_str()); + return true; + } +}; + +class CommandCSSetAutoOp : public Command +{ + public: + CommandCSSetAutoOp(Module *creator, const Anope::string &cname = "chanserv/set/autoop") : Command(creator, cname, 2, 2) + { + this->SetDesc(_("Should services automatically give status to users")); + this->SetSyntax(_("\037channel\037 {ON | OFF}")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + ChannelInfo *ci = ChannelInfo::Find(params[0]); + if (ci == NULL) + { + source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); + return; + } + + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnSetChannelOption, OnSetChannelOption(source, this, ci, params[1])); + if (MOD_RESULT == EVENT_STOP) + return; + + if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) + { + source.Reply(ACCESS_DENIED); + return; + } + + if (params[1].equals_ci("ON")) + { + ci->Shrink("NOAUTOOP"); + source.Reply(_("Services will now automatically give modes to users in \002%s\002."), ci->name.c_str()); + } + else if (params[1].equals_ci("OFF")) + { + ci->ExtendMetadata("NOAUTOOP"); + source.Reply(_("Services will no longer automatically give modes to users in \002%s\002."), ci->name.c_str()); + } + else + this->OnSyntaxError(source, "AUTOOP"); + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Enables or disables %s's autoop feature for a\n" + "channel. When disabled, users who join the channel will\n" + "not automatically gain any status from %s."), Config->ChanServ.c_str(), + Config->ChanServ.c_str(), this->name.c_str()); + return true; + } +}; + +class CommandCSSetBanType : public Command +{ + public: + CommandCSSetBanType(Module *creator, const Anope::string &cname = "chanserv/set/bantype") : Command(creator, cname, 2, 2) + { + this->SetDesc(_("Set how Services make bans on the channel")); + this->SetSyntax(_("\037channel\037 \037bantype\037")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + ChannelInfo *ci = ChannelInfo::Find(params[0]); + if (ci == NULL) + { + source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); + return; + } + + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnSetChannelOption, OnSetChannelOption(source, this, ci, params[1])); + if (MOD_RESULT == EVENT_STOP) + return; + + if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) + { + source.Reply(ACCESS_DENIED); + return; + } + + try + { + int16_t new_type = convertTo<int16_t>(params[1]); + if (new_type < 0 || new_type > 3) + throw ConvertException("Invalid range"); + ci->bantype = new_type; + source.Reply(_("Ban type for channel %s is now #%d."), ci->name.c_str(), ci->bantype); + } + catch (const ConvertException &) + { + source.Reply(_("\002%s\002 is not a valid ban type."), params[1].c_str()); + } + + return; + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Sets the ban type that will be used by services whenever\n" + "they need to ban someone from your channel.\n" + " \n" + "Bantype is a number between 0 and 3 that means:\n" + " \n" + "0: ban in the form *!user@host\n" + "1: ban in the form *!*user@host\n" + "2: ban in the form *!*@host\n" + "3: ban in the form *!*user@*.domain"), this->name.c_str()); + return true; + } +}; + +class CommandCSSetChanstats : public Command +{ + public: + CommandCSSetChanstats(Module *creator) : Command(creator, "chanserv/set/chanstats", 2, 2) + { + this->SetDesc(_("Turn chanstat statistics on or off")); + this->SetSyntax(_("\037channel\037 {ON | OFF}")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + ChannelInfo *ci = ChannelInfo::Find(params[0]); + if (!ci) + { + source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); + return; + } + + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnSetChannelOption, OnSetChannelOption(source, this, ci, params[1])); + if (MOD_RESULT == EVENT_STOP) + return; + + if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) + { + source.Reply(ACCESS_DENIED); + return; + } + + if (params[1].equals_ci("ON")) + { + ci->ExtendMetadata("STATS"); + source.Reply(_("Chanstats statistics are now enabled for this channel.")); + } + else if (params[1].equals_ci("OFF")) + { + ci->Shrink("STATS"); + source.Reply(_("Chanstats statistics are now disabled for this channel.")); + } + else + this->OnSyntaxError(source, ""); + return; + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply("Turn Chanstats channel statistics ON or OFF."); + return true; + } +}; + +class CommandCSSetDescription : public Command +{ + public: + CommandCSSetDescription(Module *creator, const Anope::string &cname = "chanserv/set/description") : Command(creator, cname, 1, 2) + { + this->SetDesc(_("Set the channel description")); + this->SetSyntax(_("\037channel\037 [\037description\037]")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + ChannelInfo *ci = ChannelInfo::Find(params[0]); + if (ci == NULL) + { + source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); + return; + } + + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnSetChannelOption, OnSetChannelOption(source, this, ci, params[1])); + if (MOD_RESULT == EVENT_STOP) + return; + + if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) + { + source.Reply(ACCESS_DENIED); + return; + } + + if (params.size() > 1) + { + ci->desc = params[1]; + source.Reply(_("Description of %s changed to \002%s\002."), ci->name.c_str(), ci->desc.c_str()); + } + else + { + ci->desc.clear(); + source.Reply(_("Description of %s unset."), ci->name.c_str()); + } + + return; + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Sets the description for the channel, which shows up with\n" + "the \002LIST\002 and \002INFO\002 commands."), this->name.c_str()); + return true; + } +}; + +class CommandCSSetFounder : public Command +{ + public: + CommandCSSetFounder(Module *creator, const Anope::string &cname = "chanserv/set/founder") : Command(creator, cname, 2, 2) + { + this->SetDesc(_("Set the founder of a channel")); + this->SetSyntax(_("\037channel\037 \037nick\037")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + ChannelInfo *ci = ChannelInfo::Find(params[0]); + if (ci == NULL) + { + source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); + return; + } + + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnSetChannelOption, OnSetChannelOption(source, this, ci, params[1])); + if (MOD_RESULT == EVENT_STOP) + return; + + if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) + { + source.Reply(ACCESS_DENIED); + return; + } + + if (source.permission.empty() && (ci->HasExt("SECUREFOUNDER") ? !source.IsFounder(ci) : !source.AccessFor(ci).HasPriv("FOUNDER"))) + { + source.Reply(ACCESS_DENIED); + return; + } + + const NickAlias *na = NickAlias::Find(params[1]); + if (!na) + { + source.Reply(NICK_X_NOT_REGISTERED, params[1].c_str()); + return; + } + + NickCore *nc = na->nc; + if (Config->CSMaxReg && nc->channelcount >= Config->CSMaxReg && !source.HasPriv("chanserv/no-register-limit")) + { + source.Reply(_("\002%s\002 has too many channels registered."), na->nick.c_str()); + return; + } + + Log(!source.permission.empty() ? LOG_ADMIN : LOG_COMMAND, source, this, ci) << "to change the founder from " << (ci->GetFounder() ? ci->GetFounder()->display : "(none)") << " to " << nc->display; + + ci->SetFounder(nc); + + source.Reply(_("Founder of \002%s\002 changed to \002%s\002."), ci->name.c_str(), na->nick.c_str()); + + return; + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Changes the founder of a channel. The new nickname must\n" + "be a registered one."), this->name.c_str()); + return true; + } +}; + +class CommandCSSetKeepTopic : public Command +{ + public: + CommandCSSetKeepTopic(Module *creator, const Anope::string &cname = "chanserv/set/keeptopic") : Command(creator, cname, 2, 2) + { + this->SetDesc(_("Retain topic when channel is not in use")); + this->SetSyntax(_("\037channel\037 {ON | OFF}")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + ChannelInfo *ci = ChannelInfo::Find(params[0]); + if (ci == NULL) + { + source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); + return; + } + + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnSetChannelOption, OnSetChannelOption(source, this, ci, params[1])); + if (MOD_RESULT == EVENT_STOP) + return; + + if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) + { + source.Reply(ACCESS_DENIED); + return; + } + + if (params[1].equals_ci("ON")) + { + ci->ExtendMetadata("KEEPTOPIC"); + source.Reply(_("Topic retention option for %s is now \002on\002."), ci->name.c_str()); + } + else if (params[1].equals_ci("OFF")) + { + ci->Shrink("KEEPTOPIC"); + source.Reply(_("Topic retention option for %s is now \002off\002."), ci->name.c_str()); + } + else + this->OnSyntaxError(source, "KEEPTOPIC"); + + return; + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Enables or disables the \002topic retention\002 option for a\n" + "channel. When \002%s\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(), source.service->nick.c_str()); + return true; + } +}; + +class CommandCSSetPeace : public Command +{ + public: + CommandCSSetPeace(Module *creator, const Anope::string &cname = "chanserv/set/peace") : Command(creator, cname, 2, 2) + { + this->SetDesc(_("Regulate the use of critical commands")); + this->SetSyntax(_("\037channel\037 {ON | OFF}")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + ChannelInfo *ci = ChannelInfo::Find(params[0]); + if (ci == NULL) + { + source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); + return; + } + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnSetChannelOption, OnSetChannelOption(source, this, ci, params[1])); + if (MOD_RESULT == EVENT_STOP) + return; + + if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) + { + source.Reply(ACCESS_DENIED); + return; + } + + if (params[1].equals_ci("ON")) + { + ci->ExtendMetadata("PEACE"); + source.Reply(_("Peace option for %s is now \002on\002."), ci->name.c_str()); + } + else if (params[1].equals_ci("OFF")) + { + ci->Shrink("PEACE"); + source.Reply(_("Peace option for %s is now \002off\002."), ci->name.c_str()); + } + else + this->OnSyntaxError(source, "PEACE"); + + return; + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("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."), source.service->nick.c_str()); + return true; + } +}; + +class CommandCSSetPersist : public Command +{ + public: + CommandCSSetPersist(Module *creator, const Anope::string &cname = "chanserv/set/persist") : Command(creator, cname, 2, 2) + { + this->SetDesc(_("Set the channel as permanent")); + this->SetSyntax(_("\037channel\037 {ON | OFF}")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + ChannelInfo *ci = ChannelInfo::Find(params[0]); + if (ci == NULL) + { + source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); + return; + } + + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnSetChannelOption, OnSetChannelOption(source, this, ci, params[1])); + if (MOD_RESULT == EVENT_STOP) + return; + + if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) + { + source.Reply(ACCESS_DENIED); + return; + } + + ChannelMode *cm = ModeManager::FindChannelModeByName("PERM"); + + if (params[1].equals_ci("ON")) + { + if (!ci->HasExt("PERSIST")) + { + ci->ExtendMetadata("PERSIST"); + if (ci->c) + ci->c->Extend("PERSIST"); + + /* Channel doesn't exist, create it */ + if (!ci->c) + { + Channel *c = new Channel(ci->name); + if (ci->bi) + ci->bi->Join(c); + } + + /* No botserv bot, no channel mode, give them ChanServ. + * Yes, this works fine with no Config->BotServ. + */ + if (!ci->bi && !cm) + { + if (!ChanServ) + { + source.Reply(_("ChanServ is required to enable persist on this network.")); + return; + } + ChanServ->Assign(NULL, ci); + if (!ci->c->FindUser(ChanServ)) + ChanServ->Join(ci->c); + } + + /* Set the perm mode */ + if (cm) + { + if (ci->c && !ci->c->HasMode("PERM")) + ci->c->SetMode(NULL, cm); + /* Add it to the channels mlock */ + ci->SetMLock(cm, true); + } + } + + source.Reply(_("Channel \002%s\002 is now persistent."), ci->name.c_str()); + } + else if (params[1].equals_ci("OFF")) + { + if (ci->HasExt("PERSIST")) + { + ci->Shrink("PERSIST"); + if (ci->c) + ci->c->Shrink("PERSIST"); + + /* Unset perm mode */ + if (cm) + { + if (ci->c && ci->c->HasMode("PERM")) + ci->c->RemoveMode(NULL, cm); + /* Remove from mlock */ + ci->RemoveMLock(cm, true); + } + + /* No channel mode, no BotServ, but using ChanServ as the botserv bot + * which was assigned when persist was set on + */ + if (!cm && Config->BotServ.empty() && ci->bi) + { + if (!ChanServ) + { + source.Reply(_("ChanServ is required to enable persist on this network.")); + return; + } + /* Unassign bot */ + ChanServ->UnAssign(NULL, ci); + } + } + + source.Reply(_("Channel \002%s\002 is no longer persistent."), ci->name.c_str()); + } + else + this->OnSyntaxError(source, "PERSIST"); + + return; + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Enables or disables the persistent channel setting.\n" + "When persistent is set, the service bot will remain\n" + "in the channel when it has emptied of users.\n" + " \n" + "If your IRCd does not have a permanent (persistent) channel\n" + "mode you must have a service bot in your channel to\n" + "set persist on, and it can not be unassigned while persist\n" + "is on.\n" + " \n" + "If this network does not have BotServ enabled and does\n" + "not have a permanent channel mode, ChanServ will\n" + "join your channel when you set persist on (and leave when\n" + "it has been set off).\n" + " \n" + "If your IRCd has a permanent (persistent) channel mode\n" + "and it is set or unset (for any reason, including MODE LOCK),\n" + "persist is automatically set and unset for the channel aswell.\n" + "Additionally, services will set or unset this mode when you\n" + "set persist on or off.")); + return true; + } +}; + +class CommandCSSetPrivate : public Command +{ + public: + CommandCSSetPrivate(Module *creator, const Anope::string &cname = "chanserv/set/private") : Command(creator, cname, 2, 2) + { + this->SetDesc(_("Hide channel from the LIST command")); + this->SetSyntax(_("\037channel\037 {ON | OFF}")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + ChannelInfo *ci = ChannelInfo::Find(params[0]); + if (ci == NULL) + { + source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); + return; + } + + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnSetChannelOption, OnSetChannelOption(source, this, ci, params[1])); + if (MOD_RESULT == EVENT_STOP) + return; + + if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) + { + source.Reply(ACCESS_DENIED); + return; + } + + if (params[1].equals_ci("ON")) + { + ci->ExtendMetadata("PRIVATE"); + source.Reply(_("Private option for %s is now \002on\002."), ci->name.c_str()); + } + else if (params[1].equals_ci("OFF")) + { + ci->Shrink("PRIVATE"); + source.Reply(_("Private option for %s is now \002off\002."), ci->name.c_str()); + } + else + this->OnSyntaxError(source, "PRIVATE"); + + return; + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("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."), + Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str()); + return true; + } +}; + +class CommandCSSetRestricted : public Command +{ + public: + CommandCSSetRestricted(Module *creator, const Anope::string &cname = "chanserv/set/restricted") : Command(creator, cname, 2, 2) + { + this->SetDesc(_("Restrict access to the channel")); + this->SetSyntax(_("\037channel\037 {ON | OFF}")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + ChannelInfo *ci = ChannelInfo::Find(params[0]); + if (ci == NULL) + { + source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); + return; + } + + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnSetChannelOption, OnSetChannelOption(source, this, ci, params[1])); + if (MOD_RESULT == EVENT_STOP) + return; + + if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) + { + source.Reply(ACCESS_DENIED); + return; + } + + if (params[1].equals_ci("ON")) + { + ci->ExtendMetadata("RESTRICTED"); + source.Reply(_("Restricted access option for %s is now \002on\002."), ci->name.c_str()); + } + else if (params[1].equals_ci("OFF")) + { + ci->Shrink("RESTRICTED"); + source.Reply(_("Restricted access option for %s is now \002off\002."), ci->name.c_str()); + } + else + this->OnSyntaxError(source, "RESTRICTED"); + + return; + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Enables or disables the \002restricted access\002 option for a\n" + "channel. When \002restricted access\002 is set, users not on the access list will\n" + "instead be kicked and banned from the channel.")); + return true; + } +}; + +class CommandCSSetSecure : public Command +{ + public: + CommandCSSetSecure(Module *creator, const Anope::string &cname = "chanserv/set/secure") : Command(creator, cname, 2, 2) + { + this->SetDesc(_("Activate security features")); + this->SetSyntax(_("\037channel\037 {ON | OFF}")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + ChannelInfo *ci = ChannelInfo::Find(params[0]); + if (ci == NULL) + { + source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); + return; + } + + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnSetChannelOption, OnSetChannelOption(source, this, ci, params[1])); + if (MOD_RESULT == EVENT_STOP) + return; + + if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) + { + source.Reply(ACCESS_DENIED); + return; + } + + if (params[1].equals_ci("ON")) + { + ci->ExtendMetadata("SECURE"); + source.Reply(_("Secure option for %s is now \002on\002."), ci->name.c_str()); + } + else if (params[1].equals_ci("OFF")) + { + ci->Shrink("SECURE"); + source.Reply(_("Secure option for %s is now \002off\002."), ci->name.c_str()); + } + else + this->OnSyntaxError(source, "SECURE"); + + return; + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Enables or disables security features for a\n" + "channel. When \002%s\002 is set, only users who have\n" + "registered their nicknames 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()); + return true; + } +}; + +class CommandCSSetSecureFounder : public Command +{ + public: + CommandCSSetSecureFounder(Module *creator, const Anope::string &cname = "chanserv/set/securefounder") : Command(creator, cname, 2, 2) + { + this->SetDesc(_("Stricter control of channel founder status")); + this->SetSyntax(_("\037channel\037 {ON | OFF}")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + ChannelInfo *ci = ChannelInfo::Find(params[0]); + if (ci == NULL) + { + source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); + return; + } + + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnSetChannelOption, OnSetChannelOption(source, this, ci, params[1])); + if (MOD_RESULT == EVENT_STOP) + return; + + if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) + { + source.Reply(ACCESS_DENIED); + return; + } + + if (params[1].equals_ci("ON")) + { + ci->ExtendMetadata("SECUREFOUNDER"); + source.Reply(_("Secure founder option for %s is now \002on\002."), ci->name.c_str()); + } + else if (params[1].equals_ci("OFF")) + { + ci->Shrink("SECUREFOUNDER"); + source.Reply(_("Secure founder option for %s is now \002off\002."), ci->name.c_str()); + } + else + this->OnSyntaxError(source, "SECUREFOUNDER"); + + return; + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Enables or disables the \002secure founder\002 option for a channel.\n" + "When \002secure founder\002 is set, only the real founder will be\n" + "able to drop the channel, change its founder and its successor,\n" + "and not those who have founder level access through\n" + "the access/qop command.")); + return true; + } +}; + +class CommandCSSetSecureOps : public Command +{ + public: + CommandCSSetSecureOps(Module *creator, const Anope::string &cname = "chanserv/set/secureops") : Command(creator, cname, 2, 2) + { + this->SetDesc(_("Stricter control of chanop status")); + this->SetSyntax(_("\037channel\037 {ON | OFF}")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + ChannelInfo *ci = ChannelInfo::Find(params[0]); + if (ci == NULL) + { + source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); + return; + } + + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnSetChannelOption, OnSetChannelOption(source, this, ci, params[1])); + if (MOD_RESULT == EVENT_STOP) + return; + + if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) + { + source.Reply(ACCESS_DENIED); + return; + } + + if (params[1].equals_ci("ON")) + { + ci->ExtendMetadata("SECUREOPS"); + source.Reply(_("Secure ops option for %s is now \002on\002."), ci->name.c_str()); + } + else if (params[1].equals_ci("OFF")) + { + ci->Shrink("SECUREOPS"); + source.Reply(_("Secure ops option for %s is now \002off\002."), ci->name.c_str()); + } + else + this->OnSyntaxError(source, "SECUREOPS"); + + return; + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Enables or disables the \002secure ops\002 option for a channel.\n" + "When \002secure ops\002 is set, users who are not on the userlist\n" + "will not be allowed chanop status.")); + return true; + } +}; + +class CommandCSSetSignKick : public Command +{ + public: + CommandCSSetSignKick(Module *creator, const Anope::string &cname = "chanserv/set/signkick") : Command(creator, cname, 2, 2) + { + this->SetDesc(_("Sign kicks that are done with the KICK command")); + this->SetSyntax(_("\037channel\037 SIGNKICK {ON | LEVEL | OFF}")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + ChannelInfo *ci = ChannelInfo::Find(params[0]); + if (ci == NULL) + { + source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); + return; + } + + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnSetChannelOption, OnSetChannelOption(source, this, ci, params[1])); + if (MOD_RESULT == EVENT_STOP) + return; + + if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) + { + source.Reply(ACCESS_DENIED); + return; + } + + if (params[1].equals_ci("ON")) + { + ci->ExtendMetadata("SIGNKICK"); + ci->Shrink("SIGNKICK_LEVEL"); + source.Reply(_("Signed kick option for %s is now \002on\002."), ci->name.c_str()); + } + else if (params[1].equals_ci("LEVEL")) + { + ci->ExtendMetadata("SIGNKICK_LEVEL"); + ci->Shrink("SIGNKICK"); + source.Reply(_("Signed kick option for %s is now \002on\002, but depends of the\n" + "level of the user that is using the command."), ci->name.c_str()); + } + else if (params[1].equals_ci("OFF")) + { + ci->Shrink("SIGNKICK"); + ci->Shrink("SIGNKICK_LEVEL"); + source.Reply(_("Signed kick option for %s is now \002off\002."), ci->name.c_str()); + } + else + this->OnSyntaxError(source, "SIGNKICK"); + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Enables or disables signed kicks for a\n" + "channel. When \002SIGNKICK\002 is set, kicks issued with\n" + "the \002KICK\002 command will have the nick that used the\n" + "command in their reason.\n" + " \n" + "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.")); + return true; + } +}; + +class CommandCSSetSuccessor : public Command +{ + public: + CommandCSSetSuccessor(Module *creator, const Anope::string &cname = "chanserv/set/successor") : Command(creator, cname, 1, 2) + { + this->SetDesc(_("Set the successor for a channel")); + this->SetSyntax(_("\037channel\037 \037nick\037")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + ChannelInfo *ci = ChannelInfo::Find(params[0]); + if (ci == NULL) + { + source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); + return; + } + + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnSetChannelOption, OnSetChannelOption(source, this, ci, params[1])); + if (MOD_RESULT == EVENT_STOP) + return; + + if (MOD_RESULT != EVENT_ALLOW && source.permission.empty()) + { + if (!source.AccessFor(ci).HasPriv("SET")) + { + source.Reply(ACCESS_DENIED); + return; + } + + if (ci->HasExt("SECUREFOUNDER") ? !source.IsFounder(ci) : !source.AccessFor(ci).HasPriv("FOUNDER")) + { + source.Reply(ACCESS_DENIED); + return; + } + } + + NickCore *nc; + + if (params.size() > 1) + { + const NickAlias *na = NickAlias::Find(params[1]); + + if (!na) + { + source.Reply(NICK_X_NOT_REGISTERED, params[1].c_str()); + return; + } + if (na->nc == ci->GetFounder()) + { + source.Reply(_("%s cannot be the successor on channel %s as they are the founder."), na->nick.c_str(), ci->name.c_str()); + return; + } + nc = na->nc; + } + else + nc = NULL; + + Log(!source.permission.empty() ? LOG_ADMIN : LOG_COMMAND, source, this, ci) << "to change the successor from " << (ci->GetSuccessor() ? ci->GetSuccessor()->display : "(none)") << " to " << (nc ? nc->display : "(none)"); + + ci->SetSuccessor(nc); + + if (nc) + source.Reply(_("Successor for \002%s\002 changed to \002%s\002."), ci->name.c_str(), nc->display.c_str()); + else + source.Reply(_("Successor for \002%s\002 unset."), ci->name.c_str()); + + return; + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Changes the successor of a channel. If the founder's\n" + "nickname expires or is dropped while the channel is still\n" + "registered, the successor will become the new founder of the\n" + "channel. However, if the successor already has too many\n" + "channels registered (%d), the channel will be dropped\n" + "instead, just as if no successor had been set. The new\n" + "nickname must be a registered one."), Config->CSMaxReg); + return true; + } +}; + +class CommandCSSASetNoexpire : public Command +{ + public: + CommandCSSASetNoexpire(Module *creator) : Command(creator, "chanserv/saset/noexpire", 2, 2) + { + this->SetDesc(_("Prevent the channel from expiring")); + this->SetSyntax(_("\037channel\037 {ON | OFF}")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + ChannelInfo *ci = ChannelInfo::Find(params[0]); + if (ci == NULL) + { + source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); + return; + } + + if (source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) + { + source.Reply(ACCESS_DENIED); + return; + } + + if (params[1].equals_ci("ON")) + { + ci->ExtendMetadata("NO_EXPIRE"); + source.Reply(_("Channel %s \002will not\002 expire."), ci->name.c_str()); + } + else if (params[1].equals_ci("OFF")) + { + ci->Shrink("NO_EXPIRE"); + source.Reply(_("Channel %s \002will\002 expire."), ci->name.c_str()); + } + else + this->OnSyntaxError(source, "NOEXPIRE"); + + return; + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Sets whether the given channel will expire. Setting this\n" + "to ON prevents the channel from expiring.")); + return true; + } +}; + class CSSet : public Module { CommandCSSet commandcsset; + CommandCSSASet commandcssaset; + CommandCSSetAutoOp commandcssetautoop; + CommandCSSetBanType commandcssetbantype; + CommandCSSetChanstats commandcssetchanstats; + bool CSDefChanstats; + CommandCSSetDescription commandcssetdescription; + CommandCSSetFounder commandcssetfounder; + CommandCSSetKeepTopic commandcssetkeeptopic; + CommandCSSetPeace commandcssetpeace; + CommandCSSetPersist commandcssetpersist; + CommandCSSetPrivate commandcssetprivate; + CommandCSSetRestricted commandcssetrestricted; + CommandCSSetSecure commandcssetsecure; + CommandCSSetSecureFounder commandcssetsecurefounder; + CommandCSSetSecureOps commandcssetsecureops; + CommandCSSetSignKick commandcssetsignkick; + CommandCSSetSuccessor commandcssetsuccessor; + CommandCSSASetNoexpire commandcssasetnoexpire; public: CSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandcsset(this) + commandcsset(this), commandcssaset(this), commandcssetautoop(this), commandcssetbantype(this), commandcssetchanstats(this), + CSDefChanstats(false), commandcssetdescription(this), commandcssetfounder(this), commandcssetkeeptopic(this), + commandcssetpeace(this), commandcssetpersist(this), commandcssetprivate(this), commandcssetrestricted(this), + commandcssetsecure(this), commandcssetsecurefounder(this), commandcssetsecureops(this), commandcssetsignkick(this), + commandcssetsuccessor(this), commandcssasetnoexpire(this) { this->SetAuthor("Anope"); + Implementation i[] = { I_OnReload, I_OnChanRegistered, I_OnCheckKick }; + ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); + + this->OnReload(); + } + + void OnReload() anope_override + { + ConfigReader config; + CSDefChanstats = config.ReadFlag("chanstats", "CSDefChanstats", "0", 0); + } + + void OnChanRegistered(ChannelInfo *ci) anope_override + { + if (CSDefChanstats) + ci->ExtendMetadata("STATS"); + } + + EventReturn OnCheckKick(User *u, ChannelInfo *ci, Anope::string &mask, Anope::string &reason) anope_override + { + if (!ci->HasExt("RESTRICTED") || ci->c->MatchesList(u, "EXCEPT")) + return EVENT_CONTINUE; + + if (ci->AccessFor(u).empty() && (!ci->GetFounder() || u->Account() != ci->GetFounder())) + return EVENT_STOP; + + return EVENT_CONTINUE; } }; diff --git a/modules/commands/cs_set_autoop.cpp b/modules/commands/cs_set_autoop.cpp deleted file mode 100644 index 0b00b151b..000000000 --- a/modules/commands/cs_set_autoop.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* ChanServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandCSSetAutoOp : public Command -{ - public: - CommandCSSetAutoOp(Module *creator, const Anope::string &cname = "chanserv/set/autoop") : Command(creator, cname, 2, 2) - { - this->SetDesc(_("Should services automatically give status to users")); - this->SetSyntax(_("\037channel\037 {ON | OFF}")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - ChannelInfo *ci = ChannelInfo::Find(params[0]); - if (ci == NULL) - { - source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); - return; - } - - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnSetChannelOption, OnSetChannelOption(source, this, ci, params[1])); - if (MOD_RESULT == EVENT_STOP) - return; - - if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) - { - source.Reply(ACCESS_DENIED); - return; - } - - if (params[1].equals_ci("ON")) - { - ci->UnsetFlag(CI_NOAUTOOP); - source.Reply(_("Services will now automatically give modes to users in \2%s\2"), ci->name.c_str()); - } - else if (params[1].equals_ci("OFF")) - { - ci->SetFlag(CI_NOAUTOOP); - source.Reply(_("Services will no longer automatically give modes to users in \2%s\2"), ci->name.c_str()); - } - else - this->OnSyntaxError(source, "AUTOOP"); - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Enables or disables %s's autoop feature for a\n" - "channel. When disabled, users who join the channel will\n" - "not automatically gain any status from %s"), Config->ChanServ.c_str(), - Config->ChanServ.c_str(), this->name.c_str()); - return true; - } -}; - - -class CSSetAutoOp : public Module -{ - CommandCSSetAutoOp commandcssetautoop; - - public: - CSSetAutoOp(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandcssetautoop(this) - { - this->SetAuthor("Anope"); - - } -}; - -MODULE_INIT(CSSetAutoOp) diff --git a/modules/commands/cs_set_bantype.cpp b/modules/commands/cs_set_bantype.cpp deleted file mode 100644 index e7dfc52ee..000000000 --- a/modules/commands/cs_set_bantype.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/* ChanServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandCSSetBanType : public Command -{ - public: - CommandCSSetBanType(Module *creator, const Anope::string &cname = "chanserv/set/bantype") : Command(creator, cname, 2, 2) - { - this->SetDesc(_("Set how Services make bans on the channel")); - this->SetSyntax(_("\037channel\037 \037bantype\037")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - ChannelInfo *ci = ChannelInfo::Find(params[0]); - if (ci == NULL) - { - source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); - return; - } - - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnSetChannelOption, OnSetChannelOption(source, this, ci, params[1])); - if (MOD_RESULT == EVENT_STOP) - return; - - if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) - { - source.Reply(ACCESS_DENIED); - return; - } - - try - { - int16_t new_type = convertTo<int16_t>(params[1]); - if (new_type < 0 || new_type > 3) - throw ConvertException("Invalid range"); - ci->bantype = new_type; - source.Reply(_("Ban type for channel %s is now #%d."), ci->name.c_str(), ci->bantype); - } - catch (const ConvertException &) - { - source.Reply(_("\002%s\002 is not a valid ban type."), params[1].c_str()); - } - - return; - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Sets the ban type that will be used by services whenever\n" - "they need to ban someone from your channel.\n" - " \n" - "bantype is a number between 0 and 3 that means:\n" - " \n" - "0: ban in the form *!user@host\n" - "1: ban in the form *!*user@host\n" - "2: ban in the form *!*@host\n" - "3: ban in the form *!*user@*.domain"), this->name.c_str()); - return true; - } -}; - -class CSSetBanType : public Module -{ - CommandCSSetBanType commandcssetbantype; - - public: - CSSetBanType(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandcssetbantype(this) - { - this->SetAuthor("Anope"); - - } -}; - -MODULE_INIT(CSSetBanType) diff --git a/modules/commands/cs_set_chanstats.cpp b/modules/commands/cs_set_chanstats.cpp deleted file mode 100644 index 118387ee4..000000000 --- a/modules/commands/cs_set_chanstats.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* NickServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandCSSetChanstats : public Command -{ - public: - CommandCSSetChanstats(Module *creator) : Command(creator, "chanserv/set/chanstats", 2, 2) - { - this->SetDesc(_("Turn chanstat statistics on or off")); - this->SetSyntax(_("\037channel\037 {ON | OFF}")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - ChannelInfo *ci = ChannelInfo::Find(params[0]); - if (!ci) - { - source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); - return; - } - - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnSetChannelOption, OnSetChannelOption(source, this, ci, params[1])); - if (MOD_RESULT == EVENT_STOP) - return; - - if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) - { - source.Reply(ACCESS_DENIED); - return; - } - - if (params[1].equals_ci("ON")) - { - ci->SetFlag(CI_STATS); - source.Reply(_("Chanstats statistics are now enabled for this channel")); - } - else if (params[1].equals_ci("OFF")) - { - ci->UnsetFlag(CI_STATS); - source.Reply(_("Chanstats statistics are now disabled for this channel")); - } - else - this->OnSyntaxError(source, ""); - return; - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply("Turn Chanstats channel statistics ON or OFF"); - return true; - } -}; - -class CSSetChanstats : public Module -{ - CommandCSSetChanstats commandcssetchanstats; - bool CSDefChanstats; - public: - CSSetChanstats(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandcssetchanstats(this) - { - this->SetAuthor("Anope"); - Implementation i[] = { I_OnReload, I_OnChanRegistered }; - ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - this->OnReload(); - } - void OnReload() anope_override - { - ConfigReader config; - CSDefChanstats = config.ReadFlag("chanstats", "CSDefChanstats", "0", 0); - } - void OnChanRegistered(ChannelInfo *ci) anope_override - { - if (CSDefChanstats) - ci->SetFlag(CI_STATS); - } -}; - -MODULE_INIT(CSSetChanstats) diff --git a/modules/commands/cs_set_description.cpp b/modules/commands/cs_set_description.cpp deleted file mode 100644 index a5ad525ab..000000000 --- a/modules/commands/cs_set_description.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* ChanServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandCSSetDescription : public Command -{ - public: - CommandCSSetDescription(Module *creator, const Anope::string &cname = "chanserv/set/description") : Command(creator, cname, 1, 2) - { - this->SetDesc(_("Set the channel description")); - this->SetSyntax(_("\037channel\037 [\037description\037]")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - ChannelInfo *ci = ChannelInfo::Find(params[0]); - if (ci == NULL) - { - source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); - return; - } - - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnSetChannelOption, OnSetChannelOption(source, this, ci, params[1])); - if (MOD_RESULT == EVENT_STOP) - return; - - if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) - { - source.Reply(ACCESS_DENIED); - return; - } - - if (params.size() > 1) - { - ci->desc = params[1]; - source.Reply(_("Description of %s changed to \002%s\002."), ci->name.c_str(), ci->desc.c_str()); - } - else - { - ci->desc.clear(); - source.Reply(_("Description of %s unset."), ci->name.c_str()); - } - - return; - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Sets the description for the channel, which shows up with\n" - "the \002LIST\002 and \002INFO\002 commands."), this->name.c_str()); - return true; - } -}; - -class CSSetDescription : public Module -{ - CommandCSSetDescription commandcssetdescription; - - public: - CSSetDescription(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandcssetdescription(this) - { - this->SetAuthor("Anope"); - - } -}; - -MODULE_INIT(CSSetDescription) diff --git a/modules/commands/cs_set_founder.cpp b/modules/commands/cs_set_founder.cpp deleted file mode 100644 index 25b43d481..000000000 --- a/modules/commands/cs_set_founder.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* ChanServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandCSSetFounder : public Command -{ - public: - CommandCSSetFounder(Module *creator, const Anope::string &cname = "chanserv/set/founder") : Command(creator, cname, 2, 2) - { - this->SetDesc(_("Set the founder of a channel")); - this->SetSyntax(_("\037channel\037 \037nick\037")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - ChannelInfo *ci = ChannelInfo::Find(params[0]); - if (ci == NULL) - { - source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); - return; - } - - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnSetChannelOption, OnSetChannelOption(source, this, ci, params[1])); - if (MOD_RESULT == EVENT_STOP) - return; - - if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) - { - source.Reply(ACCESS_DENIED); - return; - } - - if (source.permission.empty() && (ci->HasFlag(CI_SECUREFOUNDER) ? !source.IsFounder(ci) : !source.AccessFor(ci).HasPriv("FOUNDER"))) - { - source.Reply(ACCESS_DENIED); - return; - } - - const NickAlias *na = NickAlias::Find(params[1]); - if (!na) - { - source.Reply(NICK_X_NOT_REGISTERED, params[1].c_str()); - return; - } - - NickCore *nc = na->nc; - if (Config->CSMaxReg && nc->channelcount >= Config->CSMaxReg && !source.HasPriv("chanserv/no-register-limit")) - { - source.Reply(_("\002%s\002 has too many channels registered."), na->nick.c_str()); - return; - } - - Log(!source.permission.empty() ? LOG_ADMIN : LOG_COMMAND, source, this, ci) << "to change the founder from " << (ci->GetFounder() ? ci->GetFounder()->display : "(none)") << " to " << nc->display; - - ci->SetFounder(nc); - - source.Reply(_("Founder of \002%s\002 changed to \002%s\002."), ci->name.c_str(), na->nick.c_str()); - - return; - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Changes the founder of a channel. The new nickname must\n" - "be a registered one."), this->name.c_str()); - return true; - } -}; - -class CSSetFounder : public Module -{ - CommandCSSetFounder commandcssetfounder; - - public: - CSSetFounder(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandcssetfounder(this) - { - this->SetAuthor("Anope"); - - } -}; - -MODULE_INIT(CSSetFounder) diff --git a/modules/commands/cs_set_keeptopic.cpp b/modules/commands/cs_set_keeptopic.cpp deleted file mode 100644 index 24b3d4f03..000000000 --- a/modules/commands/cs_set_keeptopic.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* ChanServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandCSSetKeepTopic : public Command -{ - public: - CommandCSSetKeepTopic(Module *creator, const Anope::string &cname = "chanserv/set/keeptopic") : Command(creator, cname, 2, 2) - { - this->SetDesc(_("Retain topic when channel is not in use")); - this->SetSyntax(_("\037channel\037 {ON | OFF}")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - ChannelInfo *ci = ChannelInfo::Find(params[0]); - if (ci == NULL) - { - source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); - return; - } - - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnSetChannelOption, OnSetChannelOption(source, this, ci, params[1])); - if (MOD_RESULT == EVENT_STOP) - return; - - if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) - { - source.Reply(ACCESS_DENIED); - return; - } - - if (params[1].equals_ci("ON")) - { - ci->SetFlag(CI_KEEPTOPIC); - source.Reply(_("Topic retention option for %s is now \002on\002."), ci->name.c_str()); - } - else if (params[1].equals_ci("OFF")) - { - ci->UnsetFlag(CI_KEEPTOPIC); - source.Reply(_("Topic retention option for %s is now \002off\002."), ci->name.c_str()); - } - else - this->OnSyntaxError(source, "KEEPTOPIC"); - - return; - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Enables or disables the \002topic retention\002 option for a\n" - "channel. When \002%s\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(), source.service->nick.c_str()); - return true; - } -}; - -class CSSetKeepTopic : public Module -{ - CommandCSSetKeepTopic commandcssetkeeptopic; - - public: - CSSetKeepTopic(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandcssetkeeptopic(this) - { - this->SetAuthor("Anope"); - - } -}; - -MODULE_INIT(CSSetKeepTopic) diff --git a/modules/commands/cs_set_misc.cpp b/modules/commands/cs_set_misc.cpp index 1fb25c79a..3b6e761a7 100644 --- a/modules/commands/cs_set_misc.cpp +++ b/modules/commands/cs_set_misc.cpp @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -12,6 +12,8 @@ #include "module.h" +static std::map<Anope::string, Anope::string> descriptions; + struct CSMiscData : ExtensibleItem, Serializable { Serialize::Reference<ChannelInfo> ci; @@ -106,6 +108,25 @@ class CommandCSSetMisc : public Command else source.Reply(CHAN_SETTING_UNSET, scommand.c_str(), ci->name.c_str()); } + + void OnServHelp(CommandSource &source) anope_override + { + if (descriptions.count(source.command)) + { + this->SetDesc(descriptions[source.command]); + Command::OnServHelp(source); + } + } + + bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override + { + if (descriptions.count(source.command)) + { + source.Reply("%s", Language::Translate(source.nc, descriptions[source.command].c_str())); + return true; + } + return false; + } }; class CSSetMisc : public Module @@ -119,8 +140,31 @@ class CSSetMisc : public Module { this->SetAuthor("Anope"); - Implementation i[] = { I_OnChanInfo }; + Implementation i[] = { I_OnReload, I_OnChanInfo }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); + + this->OnReload(); + } + + void OnReload() + { + ConfigReader config; + + descriptions.clear(); + + for (int i = 0; i < config.Enumerate("command"); ++i) + { + if (config.ReadValue("command", "command", "", i) != "chanserv/set/misc") + continue; + + Anope::string cname = config.ReadValue("command", "name", "", i); + Anope::string desc = config.ReadValue("command", "misc_description", "", i); + + if (cname.empty() || desc.empty()) + continue; + + descriptions[cname] = desc; + } } void OnChanInfo(CommandSource &source, ChannelInfo *ci, InfoFormatter &info, bool ShowHidden) anope_override diff --git a/modules/commands/cs_set_peace.cpp b/modules/commands/cs_set_peace.cpp deleted file mode 100644 index 35459b59b..000000000 --- a/modules/commands/cs_set_peace.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* ChanServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandCSSetPeace : public Command -{ - public: - CommandCSSetPeace(Module *creator, const Anope::string &cname = "chanserv/set/peace") : Command(creator, cname, 2, 2) - { - this->SetDesc(_("Regulate the use of critical commands")); - this->SetSyntax(_("\037channel\037 {ON | OFF}")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - ChannelInfo *ci = ChannelInfo::Find(params[0]); - if (ci == NULL) - { - source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); - return; - } - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnSetChannelOption, OnSetChannelOption(source, this, ci, params[1])); - if (MOD_RESULT == EVENT_STOP) - return; - - if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) - { - source.Reply(ACCESS_DENIED); - return; - } - - if (params[1].equals_ci("ON")) - { - ci->SetFlag(CI_PEACE); - source.Reply(_("Peace option for %s is now \002on\002."), ci->name.c_str()); - } - else if (params[1].equals_ci("OFF")) - { - ci->UnsetFlag(CI_PEACE); - source.Reply(_("Peace option for %s is now \002off\002."), ci->name.c_str()); - } - else - this->OnSyntaxError(source, "PEACE"); - - return; - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("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."), source.service->nick.c_str()); - return true; - } -}; - -class CSSetPeace : public Module -{ - CommandCSSetPeace commandcssetpeace; - - public: - CSSetPeace(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandcssetpeace(this) - { - this->SetAuthor("Anope"); - - } -}; - -MODULE_INIT(CSSetPeace) diff --git a/modules/commands/cs_set_persist.cpp b/modules/commands/cs_set_persist.cpp deleted file mode 100644 index 03e5d3a84..000000000 --- a/modules/commands/cs_set_persist.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/* ChanServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandCSSetPersist : public Command -{ - public: - CommandCSSetPersist(Module *creator, const Anope::string &cname = "chanserv/set/persist") : Command(creator, cname, 2, 2) - { - this->SetDesc(_("Set the channel as permanent")); - this->SetSyntax(_("\037channel\037 {ON | OFF}")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - ChannelInfo *ci = ChannelInfo::Find(params[0]); - if (ci == NULL) - { - source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); - return; - } - - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnSetChannelOption, OnSetChannelOption(source, this, ci, params[1])); - if (MOD_RESULT == EVENT_STOP) - return; - - if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) - { - source.Reply(ACCESS_DENIED); - return; - } - - ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_PERM); - - if (params[1].equals_ci("ON")) - { - if (!ci->HasFlag(CI_PERSIST)) - { - ci->SetFlag(CI_PERSIST); - if (ci->c) - ci->c->SetFlag(CH_PERSIST); - - /* Channel doesn't exist, create it */ - if (!ci->c) - { - Channel *c = new Channel(ci->name); - if (ci->bi) - ci->bi->Join(c); - } - - /* No botserv bot, no channel mode, give them ChanServ. - * Yes, this works fine with no Config->BotServ. - */ - if (!ci->bi && !cm) - { - if (!ChanServ) - { - source.Reply(_("ChanServ is required to enable persist on this network.")); - return; - } - ChanServ->Assign(NULL, ci); - if (!ci->c->FindUser(ChanServ)) - ChanServ->Join(ci->c); - } - - /* Set the perm mode */ - if (cm) - { - if (ci->c && !ci->c->HasMode(CMODE_PERM)) - ci->c->SetMode(NULL, cm); - /* Add it to the channels mlock */ - ci->SetMLock(cm, true); - } - } - - source.Reply(_("Channel \002%s\002 is now persistent."), ci->name.c_str()); - } - else if (params[1].equals_ci("OFF")) - { - if (ci->HasFlag(CI_PERSIST)) - { - ci->UnsetFlag(CI_PERSIST); - if (ci->c) - ci->c->UnsetFlag(CH_PERSIST); - - /* Unset perm mode */ - if (cm) - { - if (ci->c && ci->c->HasMode(CMODE_PERM)) - ci->c->RemoveMode(NULL, cm); - /* Remove from mlock */ - ci->RemoveMLock(cm, true); - } - - /* No channel mode, no BotServ, but using ChanServ as the botserv bot - * which was assigned when persist was set on - */ - if (!cm && Config->BotServ.empty() && ci->bi) - { - if (!ChanServ) - { - source.Reply(_("ChanServ is required to enable persist on this network.")); - return; - } - /* Unassign bot */ - ChanServ->UnAssign(NULL, ci); - } - } - - source.Reply(_("Channel \002%s\002 is no longer persistent."), ci->name.c_str()); - } - else - this->OnSyntaxError(source, "PERSIST"); - - return; - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Enables or disables the persistent channel setting.\n" - "When persistent is set, the service bot will remain\n" - "in the channel when it has emptied of users.\n" - " \n" - "If your IRCd does not have a permanent (persistent) channel\n" - "mode you must have a service bot in your channel to\n" - "set persist on, and it can not be unassigned while persist\n" - "is on.\n" - " \n" - "If this network does not have BotServ enabled and does\n" - "not have a permanent channel mode, ChanServ will\n" - "join your channel when you set persist on (and leave when\n" - "it has been set off).\n" - " \n" - "If your IRCd has a permanent (persistent) channel mode\n" - "and it is set or unset (for any reason, including MODE LOCK),\n" - "persist is automatically set and unset for the channel aswell.\n" - "Additionally, services will set or unset this mode when you\n" - "set persist on or off.")); - return true; - } -}; - -class CSSetPersist : public Module -{ - CommandCSSetPersist commandcssetpeace; - - public: - CSSetPersist(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandcssetpeace(this) - { - this->SetAuthor("Anope"); - - ModuleManager::Attach(I_OnDelChan, this); - } - - void OnDelChan(ChannelInfo *ci) anope_override - { - if (ci->c && ci->HasFlag(CI_PERSIST)) - ci->c->RemoveMode(NULL, CMODE_PERM, "", false); - } -}; - -MODULE_INIT(CSSetPersist) diff --git a/modules/commands/cs_set_private.cpp b/modules/commands/cs_set_private.cpp deleted file mode 100644 index a677aaf38..000000000 --- a/modules/commands/cs_set_private.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* ChanServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandCSSetPrivate : public Command -{ - public: - CommandCSSetPrivate(Module *creator, const Anope::string &cname = "chanserv/set/private") : Command(creator, cname, 2, 2) - { - this->SetDesc(_("Hide channel from LIST command")); - this->SetSyntax(_("\037channel\037 {ON | OFF}")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - ChannelInfo *ci = ChannelInfo::Find(params[0]); - if (ci == NULL) - { - source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); - return; - } - - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnSetChannelOption, OnSetChannelOption(source, this, ci, params[1])); - if (MOD_RESULT == EVENT_STOP) - return; - - if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) - { - source.Reply(ACCESS_DENIED); - return; - } - - if (params[1].equals_ci("ON")) - { - ci->SetFlag(CI_PRIVATE); - source.Reply(_("Private option for %s is now \002on\002."), ci->name.c_str()); - } - else if (params[1].equals_ci("OFF")) - { - ci->UnsetFlag(CI_PRIVATE); - source.Reply(_("Private option for %s is now \002off\002."), ci->name.c_str()); - } - else - this->OnSyntaxError(source, "PRIVATE"); - - return; - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("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."), - Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str()); - return true; - } -}; - -class CSSetPrivate : public Module -{ - CommandCSSetPrivate commandcssetprivate; - - public: - CSSetPrivate(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandcssetprivate(this) - { - this->SetAuthor("Anope"); - - } -}; - -MODULE_INIT(CSSetPrivate) diff --git a/modules/commands/cs_set_restricted.cpp b/modules/commands/cs_set_restricted.cpp deleted file mode 100644 index 45a9b188e..000000000 --- a/modules/commands/cs_set_restricted.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* ChanServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ -/*************************************************************************/ - -#include "module.h" - -class CommandCSSetRestricted : public Command -{ - public: - CommandCSSetRestricted(Module *creator, const Anope::string &cname = "chanserv/set/restricted") : Command(creator, cname, 2, 2) - { - this->SetDesc(_("Restrict access to the channel")); - this->SetSyntax(_("\037channel\037 {ON | OFF}")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - ChannelInfo *ci = ChannelInfo::Find(params[0]); - if (ci == NULL) - { - source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); - return; - } - - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnSetChannelOption, OnSetChannelOption(source, this, ci, params[1])); - if (MOD_RESULT == EVENT_STOP) - return; - - if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) - { - source.Reply(ACCESS_DENIED); - return; - } - - if (params[1].equals_ci("ON")) - { - ci->SetFlag(CI_RESTRICTED); - source.Reply(_("Restricted access option for %s is now \002on\002."), ci->name.c_str()); - } - else if (params[1].equals_ci("OFF")) - { - ci->UnsetFlag(CI_RESTRICTED); - source.Reply(_("Restricted access option for %s is now \002off\002."), ci->name.c_str()); - } - else - this->OnSyntaxError(source, "RESTRICTED"); - - return; - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Enables or disables the \002restricted access\002 option for a\n" - "channel. When \002restricted access\002 is set, users not on the access list will\n" - "instead be kicked and banned from the channel.")); - return true; - } -}; - -class CSSetRestricted : public Module -{ - CommandCSSetRestricted commandcssetrestricted; - - public: - CSSetRestricted(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandcssetrestricted(this) - { - this->SetAuthor("Anope"); - - } -}; - -MODULE_INIT(CSSetRestricted) diff --git a/modules/commands/cs_set_secure.cpp b/modules/commands/cs_set_secure.cpp deleted file mode 100644 index 7659c8674..000000000 --- a/modules/commands/cs_set_secure.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* ChanServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandCSSetSecure : public Command -{ - public: - CommandCSSetSecure(Module *creator, const Anope::string &cname = "chanserv/set/secure") : Command(creator, cname, 2, 2) - { - this->SetDesc(_("Activate security features")); - this->SetSyntax(_("\037channel\037 {ON | OFF}")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - ChannelInfo *ci = ChannelInfo::Find(params[0]); - if (ci == NULL) - { - source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); - return; - } - - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnSetChannelOption, OnSetChannelOption(source, this, ci, params[1])); - if (MOD_RESULT == EVENT_STOP) - return; - - if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) - { - source.Reply(ACCESS_DENIED); - return; - } - - if (params[1].equals_ci("ON")) - { - ci->SetFlag(CI_SECURE); - source.Reply(_("Secure option for %s is now \002on\002."), ci->name.c_str()); - } - else if (params[1].equals_ci("OFF")) - { - ci->UnsetFlag(CI_SECURE); - source.Reply(_("Secure option for %s is now \002off\002."), ci->name.c_str()); - } - else - this->OnSyntaxError(source, "SECURE"); - - return; - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Enables or disables security features for a\n" - "channel. When \002%s\002 is set, only users who have\n" - "registered their nicknames 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()); - return true; - } -}; - -class CSSetSecure : public Module -{ - CommandCSSetSecure commandcssetsecure; - - public: - CSSetSecure(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandcssetsecure(this) - { - this->SetAuthor("Anope"); - - } -}; - -MODULE_INIT(CSSetSecure) diff --git a/modules/commands/cs_set_securefounder.cpp b/modules/commands/cs_set_securefounder.cpp deleted file mode 100644 index d3d22f294..000000000 --- a/modules/commands/cs_set_securefounder.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* ChanServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandCSSetSecureFounder : public Command -{ - public: - CommandCSSetSecureFounder(Module *creator, const Anope::string &cname = "chanserv/set/securefounder") : Command(creator, cname, 2, 2) - { - this->SetDesc(_("Stricter control of channel founder status")); - this->SetSyntax(_("\037channel\037 {ON | OFF}")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - ChannelInfo *ci = ChannelInfo::Find(params[0]); - if (ci == NULL) - { - source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); - return; - } - - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnSetChannelOption, OnSetChannelOption(source, this, ci, params[1])); - if (MOD_RESULT == EVENT_STOP) - return; - - if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) - { - source.Reply(ACCESS_DENIED); - return; - } - - if (params[1].equals_ci("ON")) - { - ci->SetFlag(CI_SECUREFOUNDER); - source.Reply(_("Secure founder option for %s is now \002on\002."), ci->name.c_str()); - } - else if (params[1].equals_ci("OFF")) - { - ci->UnsetFlag(CI_SECUREFOUNDER); - source.Reply(_("Secure founder option for %s is now \002off\002."), ci->name.c_str()); - } - else - this->OnSyntaxError(source, "SECUREFOUNDER"); - - return; - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Enables or disables the \002secure founder\002 option for a channel.\n" - "When \002secure founder\002 is set, only the real founder will be\n" - "able to drop the channel, change its founder and its successor,\n" - "and not those who have founder level access through\n" - "the access/qop command.")); - return true; - } -}; - -class CSSetSecureFounder : public Module -{ - CommandCSSetSecureFounder commandcssetsecurefounder; - - public: - CSSetSecureFounder(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandcssetsecurefounder(this) - { - this->SetAuthor("Anope"); - - } -}; - -MODULE_INIT(CSSetSecureFounder) diff --git a/modules/commands/cs_set_secureops.cpp b/modules/commands/cs_set_secureops.cpp deleted file mode 100644 index 9a95735be..000000000 --- a/modules/commands/cs_set_secureops.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* ChanServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandCSSetSecureOps : public Command -{ - public: - CommandCSSetSecureOps(Module *creator, const Anope::string &cname = "chanserv/set/secureops") : Command(creator, cname, 2, 2) - { - this->SetDesc(_("Stricter control of chanop status")); - this->SetSyntax(_("\037channel\037 {ON | OFF}")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - ChannelInfo *ci = ChannelInfo::Find(params[0]); - if (ci == NULL) - { - source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); - return; - } - - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnSetChannelOption, OnSetChannelOption(source, this, ci, params[1])); - if (MOD_RESULT == EVENT_STOP) - return; - - if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) - { - source.Reply(ACCESS_DENIED); - return; - } - - if (params[1].equals_ci("ON")) - { - ci->SetFlag(CI_SECUREOPS); - source.Reply(_("Secure ops option for %s is now \002on\002."), ci->name.c_str()); - } - else if (params[1].equals_ci("OFF")) - { - ci->UnsetFlag(CI_SECUREOPS); - source.Reply(_("Secure ops option for %s is now \002off\002."), ci->name.c_str()); - } - else - this->OnSyntaxError(source, "SECUREOPS"); - - return; - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Enables or disables the \002secure ops\002 option for a channel.\n" - "When \002secure ops\002 is set, users who are not on the userlist\n" - "will not be allowed chanop status.")); - return true; - } -}; - -class CSSetSecureOps : public Module -{ - CommandCSSetSecureOps commandcssetsecureops; - - public: - CSSetSecureOps(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandcssetsecureops(this) - { - this->SetAuthor("Anope"); - - } -}; - -MODULE_INIT(CSSetSecureOps) diff --git a/modules/commands/cs_set_signkick.cpp b/modules/commands/cs_set_signkick.cpp deleted file mode 100644 index f3b482a67..000000000 --- a/modules/commands/cs_set_signkick.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* ChanServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandCSSetSignKick : public Command -{ - public: - CommandCSSetSignKick(Module *creator, const Anope::string &cname = "chanserv/set/signkick") : Command(creator, cname, 2, 2) - { - this->SetDesc(_("Sign kicks that are done with KICK command")); - this->SetSyntax(_("\037channel\037 SIGNKICK {ON | LEVEL | OFF}")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - ChannelInfo *ci = ChannelInfo::Find(params[0]); - if (ci == NULL) - { - source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); - return; - } - - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnSetChannelOption, OnSetChannelOption(source, this, ci, params[1])); - if (MOD_RESULT == EVENT_STOP) - return; - - if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) - { - source.Reply(ACCESS_DENIED); - return; - } - - if (params[1].equals_ci("ON")) - { - ci->SetFlag(CI_SIGNKICK); - ci->UnsetFlag(CI_SIGNKICK_LEVEL); - source.Reply(_("Signed kick option for %s is now \002on\002."), ci->name.c_str()); - } - else if (params[1].equals_ci("LEVEL")) - { - ci->SetFlag(CI_SIGNKICK_LEVEL); - ci->UnsetFlag(CI_SIGNKICK); - source.Reply(_("Signed kick option for %s is now \002ON\002, but depends of the\n" - "level of the user that is using the command."), ci->name.c_str()); - } - else if (params[1].equals_ci("OFF")) - { - ci->UnsetFlag(CI_SIGNKICK); - ci->UnsetFlag(CI_SIGNKICK_LEVEL); - source.Reply(_("Signed kick option for %s is now \002off\002."), ci->name.c_str()); - } - else - this->OnSyntaxError(source, "SIGNKICK"); - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Enables or disables signed kicks for a\n" - "channel. When \002SIGNKICK\002 is set, kicks issued with\n" - "the \002KICK\002 command will have the nick that used the\n" - "command in their reason.\n" - " \n" - "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.")); - return true; - } -}; - -class CSSetSignKick : public Module -{ - CommandCSSetSignKick commandcssetsignkick; - - public: - CSSetSignKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandcssetsignkick(this) - { - this->SetAuthor("Anope"); - - } -}; - -MODULE_INIT(CSSetSignKick) diff --git a/modules/commands/cs_set_successor.cpp b/modules/commands/cs_set_successor.cpp deleted file mode 100644 index 8b36d6853..000000000 --- a/modules/commands/cs_set_successor.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/* ChanServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandCSSetSuccessor : public Command -{ - public: - CommandCSSetSuccessor(Module *creator, const Anope::string &cname = "chanserv/set/successor") : Command(creator, cname, 1, 2) - { - this->SetDesc(_("Set the successor for a channel")); - this->SetSyntax(_("\037channel\037 \037nick\037")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - ChannelInfo *ci = ChannelInfo::Find(params[0]); - if (ci == NULL) - { - source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); - return; - } - - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnSetChannelOption, OnSetChannelOption(source, this, ci, params[1])); - if (MOD_RESULT == EVENT_STOP) - return; - - if (MOD_RESULT != EVENT_ALLOW && source.permission.empty()) - { - if (!source.AccessFor(ci).HasPriv("SET")) - { - source.Reply(ACCESS_DENIED); - return; - } - - if (ci->HasFlag(CI_SECUREFOUNDER) ? !source.IsFounder(ci) : !source.AccessFor(ci).HasPriv("FOUNDER")) - { - source.Reply(ACCESS_DENIED); - return; - } - } - - NickCore *nc; - - if (params.size() > 1) - { - const NickAlias *na = NickAlias::Find(params[1]); - - if (!na) - { - source.Reply(NICK_X_NOT_REGISTERED, params[1].c_str()); - return; - } - if (na->nc == ci->GetFounder()) - { - source.Reply(_("%s cannot be the successor on channel %s as they are the founder."), na->nick.c_str(), ci->name.c_str()); - return; - } - nc = na->nc; - } - else - nc = NULL; - - Log(!source.permission.empty() ? LOG_ADMIN : LOG_COMMAND, source, this, ci) << "to change the successor from " << (ci->successor ? ci->successor->display : "(none)") << " to " << (nc ? nc->display : "(none)"); - - ci->successor = nc; - - if (nc) - source.Reply(_("Successor for \002%s\002 changed to \002%s\002."), ci->name.c_str(), nc->display.c_str()); - else - source.Reply(_("Successor for \002%s\002 unset."), ci->name.c_str()); - - return; - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Changes the successor of a channel. If the founder's\n" - "nickname expires or is dropped while the channel is still\n" - "registered, the successor will become the new founder of the\n" - "channel. However, if the successor already has too many\n" - "channels registered (%d), the channel will be dropped\n" - "instead, just as if no successor had been set. The new\n" - "nickname must be a registered one."), Config->CSMaxReg); - return true; - } -}; - -class CSSetSuccessor : public Module -{ - CommandCSSetSuccessor commandcssetsuccessor; - - public: - CSSetSuccessor(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandcssetsuccessor(this) - { - this->SetAuthor("Anope"); - - } -}; - -MODULE_INIT(CSSetSuccessor) diff --git a/modules/commands/cs_set_topiclock.cpp b/modules/commands/cs_set_topiclock.cpp deleted file mode 100644 index 9212d291d..000000000 --- a/modules/commands/cs_set_topiclock.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* ChanServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandCSSetTopicLock : public Command -{ - public: - CommandCSSetTopicLock(Module *creator, const Anope::string &cname = "chanserv/set/topiclock") : Command(creator, cname, 2, 2) - { - this->SetDesc(_("Topic can only be changed with TOPIC")); - this->SetSyntax(_("\037channel\037 {ON | OFF}")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - ChannelInfo *ci = ChannelInfo::Find(params[0]); - if (ci == NULL) - { - source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); - return; - } - - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnSetChannelOption, OnSetChannelOption(source, this, ci, params[1])); - if (MOD_RESULT == EVENT_STOP) - return; - - if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET")) - { - source.Reply(ACCESS_DENIED); - return; - } - - if (params[1].equals_ci("ON")) - { - ci->SetFlag(CI_TOPICLOCK); - source.Reply(_("Topic lock option for %s is now \002on\002."), ci->name.c_str()); - } - else if (params[1].equals_ci("OFF")) - { - ci->UnsetFlag(CI_TOPICLOCK); - source.Reply(_("Topic lock option for %s is now \002off\002."), ci->name.c_str()); - } - else - this->OnSyntaxError(source, "TOPICLOCK"); - - return; - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Enables or disables the \002topic lock\002 option for a channel.\n" - "When \002topic lock\002 is set, the channel topic will be unchangable\n" - "except via the \002TOPIC\002 command.")); - return true; - } -}; - -class CSSetTopicLock : public Module -{ - CommandCSSetTopicLock commandcssettopiclock; - - public: - CSSetTopicLock(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandcssettopiclock(this) - { - this->SetAuthor("Anope"); - - } -}; - -MODULE_INIT(CSSetTopicLock) diff --git a/modules/commands/cs_status.cpp b/modules/commands/cs_status.cpp index 4d609eb8d..1d1aa619c 100644 --- a/modules/commands/cs_status.cpp +++ b/modules/commands/cs_status.cpp @@ -1,6 +1,6 @@ /* ChanServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -50,20 +50,20 @@ public: } if (ag.super_admin) - source.Reply(_("\2%s\2 is a super administrator."), nick.c_str()); + source.Reply(_("\002%s\002 is a super administrator."), nick.c_str()); else if (ag.founder) - source.Reply(_("\2%s\2 is the channel founder."), nick.c_str()); + source.Reply(_("\002%s\002 is the channel founder."), nick.c_str()); else if (ag.empty()) - source.Reply(_("\2%s\2 has no access on \2%s\2."), nick.c_str(), ci->name.c_str()); + source.Reply(_("\002%s\002 has no access on \002%s\002."), nick.c_str(), ci->name.c_str()); else { - source.Reply(_("Access for \2%s\2 on \2%s\2"), nick.c_str(), ci->name.c_str()); + source.Reply(_("Access for \002%s\002 on \002%s\002:"), nick.c_str(), ci->name.c_str()); for (unsigned i = 0; i < ag.size(); ++i) { ChanAccess *acc = ag[i]; - source.Reply(_("\2%s\2 matches access entry %s, which has privilege %s."), nick.c_str(), acc->mask.c_str(), acc->AccessSerialize().c_str()); + source.Reply(_("\002%s\002 matches access entry %s, which has privilege %s."), nick.c_str(), acc->mask.c_str(), acc->AccessSerialize().c_str()); } } @@ -71,16 +71,16 @@ public: { AutoKick *autokick = ci->GetAkick(j); - if (autokick->HasFlag(AK_ISNICK)) + if (autokick->nc) { if (na && *autokick->nc == na->nc) - source.Reply(_("\2%s\2 is on the auto kick list (%s)."), na->nc->display.c_str(), autokick->reason.c_str()); + source.Reply(_("\002%s\002 is on the auto kick list (%s)."), na->nc->display.c_str(), autokick->reason.c_str()); } else if (u != NULL) { - Entry akick_mask(CMODE_BEGIN, autokick->mask); + Entry akick_mask("", autokick->mask); if (akick_mask.Matches(u)) - source.Reply(_("\2%s\2 matches auto kick entry %s (%s)."), u->nick.c_str(), autokick->mask.c_str(), autokick->reason.c_str()); + source.Reply(_("\002%s\002 matches auto kick entry %s (%s)."), u->nick.c_str(), autokick->mask.c_str(), autokick->reason.c_str()); } } } diff --git a/modules/commands/cs_suspend.cpp b/modules/commands/cs_suspend.cpp index 097de1823..fdfd2d55a 100644 --- a/modules/commands/cs_suspend.cpp +++ b/modules/commands/cs_suspend.cpp @@ -1,6 +1,6 @@ /* ChanServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -13,46 +13,6 @@ #include "module.h" -struct ChanSuspend : ExtensibleItem, Serializable -{ - Anope::string chan; - time_t when; - - ChanSuspend() : Serializable("ChanSuspend") - { - } - - void Serialize(Serialize::Data &sd) const anope_override - { - sd["chan"] << this->chan; - sd["when"] << this->when; - } - - static Serializable* Unserialize(Serializable *obj, Serialize::Data &sd) - { - Anope::string schan; - - sd["chan"] >> schan; - - ChannelInfo *ci = ChannelInfo::Find(schan); - if (ci == NULL) - return NULL; - - ChanSuspend *cs; - if (obj) - cs = anope_dynamic_static_cast<ChanSuspend *>(obj); - else - cs = new ChanSuspend(); - - sd["chan"] >> cs->chan; - sd["when"] >> cs->when; - - if (!obj) - ci->Extend("ci_suspend_expire", cs); - return cs; - } -}; - class CommandCSSuspend : public Command { public: @@ -95,20 +55,20 @@ class CommandCSSuspend : public Command return; } - ci->SetFlag(CI_SUSPENDED); - ci->Extend("suspend_by", new ExtensibleItemClass<Anope::string>(source.GetNick())); + ci->ExtendMetadata("SUSPENDED"); + ci->ExtendMetadata("suspend:by", source.GetNick()); if (!reason.empty()) - ci->Extend("suspend_reason", new ExtensibleItemClass<Anope::string>(reason)); + ci->ExtendMetadata("suspend:reason", reason); if (ci->c) { std::vector<User *> users; - for (CUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it) + for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it) { - UserContainer *uc = *it; + ChanUserContainer *uc = *it; User *user = uc->user; - if (!user->HasMode(UMODE_OPER) && user->server != Me) + if (!user->HasMode("OPER") && user->server != Me) users.push_back(user); } @@ -117,13 +77,7 @@ class CommandCSSuspend : public Command } if (expiry_secs > 0) - { - ChanSuspend *cs = new ChanSuspend(); - cs->chan = ci->name; - cs->when = Anope::CurTime + expiry_secs; - - ci->Extend("cs_suspend_expire", cs); - } + ci->ExtendMetadata("suspend:expire", stringify(Anope::CurTime + expiry_secs)); Log(LOG_ADMIN, source, this, ci) << (!reason.empty() ? reason : "No reason") << ", expires in " << (expiry_secs ? Anope::strftime(Anope::CurTime + expiry_secs) : "never"); source.Reply(_("Channel \002%s\002 is now suspended."), ci->name.c_str()); @@ -138,7 +92,7 @@ class CommandCSSuspend : public Command this->SendSyntax(source); source.Reply(" "); source.Reply(_("Disallows anyone from using the given channel.\n" - "May be cancelled by using the UNSUSPEND\n" + "May be cancelled by using the \002UNSUSPEND\002\n" "command to preserve all previous channel data/settings.\n" "If an expiry is given the channel will be unsuspended after\n" "that period of time, else the default expiry from the" @@ -172,20 +126,20 @@ class CommandCSUnSuspend : public Command } /* Only UNSUSPEND already suspended channels */ - if (!ci->HasFlag(CI_SUSPENDED)) + if (!ci->HasExt("SUSPENDED")) { - source.Reply(_("Couldn't release channel \002%s\002!"), ci->name.c_str()); + source.Reply(_("Channel \002%s\002 isn't suspended."), ci->name.c_str()); return; } - Anope::string *by = ci->GetExt<ExtensibleItemClass<Anope::string> *>("suspend_by"), *reason = ci->GetExt<ExtensibleItemClass<Anope::string> *>("suspend_reason"); + Anope::string *by = ci->GetExt<ExtensibleItemClass<Anope::string> *>("suspend:by"), *reason = ci->GetExt<ExtensibleItemClass<Anope::string> *>("suspend:reason"); if (by != NULL) Log(LOG_ADMIN, source, this, ci) << " which was suspended by " << *by << " for: " << (reason && !reason->empty() ? *reason : "No reason"); - ci->UnsetFlag(CI_SUSPENDED); - ci->Shrink("suspend_by"); - ci->Shrink("suspend_reason"); - ci->Shrink("cs_suspend_expire"); + ci->Shrink("SUSPENDED"); + ci->Shrink("suspend:by"); + ci->Shrink("suspend:reason"); + ci->Shrink("suspend:expire"); source.Reply(_("Channel \002%s\002 is now released."), ci->name.c_str()); @@ -206,49 +160,54 @@ class CommandCSUnSuspend : public Command class CSSuspend : public Module { - Serialize::Type chansuspend_type; CommandCSSuspend commandcssuspend; CommandCSUnSuspend commandcsunsuspend; public: CSSuspend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - chansuspend_type("ChanSuspend", ChanSuspend::Unserialize), commandcssuspend(this), commandcsunsuspend(this) + commandcssuspend(this), commandcsunsuspend(this) { this->SetAuthor("Anope"); - Implementation i[] = { I_OnPreChanExpire }; + Implementation i[] = { I_OnPreChanExpire, I_OnCheckKick }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } - ~CSSuspend() - { - for (registered_channel_map::const_iterator it = RegisteredChannelList->begin(), it_end = RegisteredChannelList->end(); it != it_end; ++it) - { - ChannelInfo *ci = it->second; - ci->Shrink("cs_suspend_expire"); - ci->Shrink("suspend_by"); - ci->Shrink("suspend_reason"); - } - } - void OnPreChanExpire(ChannelInfo *ci, bool &expire) anope_override { - if (!ci->HasFlag(CI_SUSPENDED)) + if (!ci->HasExt("SUSPENDED")) return; expire = false; - ChanSuspend *cs = ci->GetExt<ChanSuspend *>("cs_suspend_expire"); - if (cs != NULL && cs->when < Anope::CurTime) + Anope::string *str = ci->GetExt<ExtensibleItemClass<Anope::string> *>("suspend:expire"); + if (str == NULL) + return; + + try { - ci->last_used = Anope::CurTime; - ci->UnsetFlag(CI_SUSPENDED); - ci->Shrink("cs_suspend_expire"); - ci->Shrink("suspend_by"); - ci->Shrink("suspend_reason"); + time_t when = convertTo<time_t>(*str); + if (when < Anope::CurTime) + { + ci->last_used = Anope::CurTime; + ci->Shrink("SUSPENDED"); + ci->Shrink("suspend:expire"); + ci->Shrink("suspend:by"); + ci->Shrink("suspend:reason"); - Log(LOG_NORMAL, "expire", ChanServ) << "Expiring suspend for " << ci->name; + Log(LOG_NORMAL, "expire", ChanServ) << "Expiring suspend for " << ci->name; + } } + catch (const ConvertException &) { } + } + + EventReturn OnCheckKick(User *u, ChannelInfo *ci, Anope::string &mask, Anope::string &reason) anope_override + { + if (u->HasMode("OPER") || !ci->HasExt("SUSPENDED")) + return EVENT_CONTINUE; + + reason = Language::Translate(u, _("This channel may not be used.")); + return EVENT_STOP; } }; diff --git a/modules/commands/cs_sync.cpp b/modules/commands/cs_sync.cpp index 23d6928a1..1a02c813c 100644 --- a/modules/commands/cs_sync.cpp +++ b/modules/commands/cs_sync.cpp @@ -1,6 +1,6 @@ /* * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -34,7 +34,7 @@ class CommandCSSync : public Command { Log(LOG_COMMAND, source, this, ci); - for (CUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it) + for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it) ci->c->SetCorrectModes((*it)->user, true, false); source.Reply(_("All user modes on \002%s\002 have been synced."), ci->name.c_str()); diff --git a/modules/commands/cs_tban.cpp b/modules/commands/cs_tban.cpp deleted file mode 100644 index 40fdfedb9..000000000 --- a/modules/commands/cs_tban.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/* cs_tban.c - Bans the user for a given length of time - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Based on the original module by Rob <rob@anope.org> - * Included in the Anope module pack since Anope 1.7.8 - * Anope Coder: Rob <rob@anope.org> - * - * Please read COPYING and README for further details. - * - * Send bug reports to the Anope Coder instead of the module - * author, because any changes since the inclusion into anope - * are not supported by the original author. - */ -/*************************************************************************/ - -#include "module.h" - -static Module *me; - -class TempBan : public CallBack -{ - private: - Reference<Channel> chan; - Anope::string mask; - - public: - TempBan(time_t seconds, Channel *c, const Anope::string &banmask) : CallBack(me, seconds), chan(c), mask(banmask) { } - - void Tick(time_t ctime) anope_override - { - if (chan && chan->ci) - chan->RemoveMode(NULL, CMODE_BAN, mask); - } -}; - -class CommandCSTBan : public Command -{ - public: - CommandCSTBan(Module *creator) : Command(creator, "chanserv/tban", 3, 3) - { - this->SetDesc(_("Bans the user for a given length of time")); - this->SetSyntax(_("\037channel\037 \037nick\037 \037time\037")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - Channel *c = Channel::Find(params[0]); - - const Anope::string &nick = params[1]; - const Anope::string &time = params[2]; - - User *u2; - if (!c) - source.Reply(CHAN_X_NOT_IN_USE, params[0].c_str()); - else if (!c->ci) - source.Reply(CHAN_X_NOT_REGISTERED, c->name.c_str()); - else if (!source.AccessFor(c->ci).HasPriv("BAN")) - source.Reply(ACCESS_DENIED); - else if (!(u2 = User::Find(nick, true))) - source.Reply(NICK_X_NOT_IN_USE, nick.c_str()); - else if (c->MatchesList(u2, CMODE_EXCEPT)) - source.Reply(CHAN_EXCEPTED, u2->nick.c_str(), c->ci->name.c_str()); - else if (u2->IsProtected()) - source.Reply(ACCESS_DENIED); - else - { - time_t t = Anope::DoTime(time); - Anope::string mask = c->ci->GetIdealBan(u2); - c->SetMode(NULL, CMODE_BAN, mask); - new TempBan(t, c, mask); - - Log(LOG_COMMAND, source, this, c->ci) << "for " << mask << " to expire in " << Anope::Duration(t); - - source.Reply(_("%s banned from %s, will auto-expire in %s."), mask.c_str(), c->name.c_str(), Anope::Duration(t).c_str()); - } - - return; - } - - bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override - { - this->OnSyntaxError(source, ""); - source.Reply(" "); - source.Reply(_("Bans the user for a given length of time.\n" - " \n" - "Bans the given user from a channel for a specified length of\n" - "time. If the ban is removed before by hand, it\n" - "will NOT be replaced.")); - - return true; - } -}; - -class CSTBan : public Module -{ - CommandCSTBan commandcstban; - - public: - CSTBan(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), commandcstban(this) - { - this->SetAuthor("Anope"); - me = this; - } -}; - -MODULE_INIT(CSTBan) diff --git a/modules/commands/cs_topic.cpp b/modules/commands/cs_topic.cpp index eccb8b2f6..8b55a2da4 100644 --- a/modules/commands/cs_topic.cpp +++ b/modules/commands/cs_topic.cpp @@ -1,6 +1,6 @@ /* ChanServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -9,59 +9,100 @@ * Based on the original code of Services by Andy Church. */ -/*************************************************************************/ - #include "module.h" class CommandCSTopic : public Command { + void Lock(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> ¶ms) + { + ci->ExtendMetadata("TOPICLOCK"); + source.Reply(_("Topic lock option for %s is now \002on\002."), ci->name.c_str()); + } + + void Unlock(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> ¶ms) + { + ci->Shrink("TOPICLOCK"); + source.Reply(_("Topic lock option for %s is now \002off\002."), ci->name.c_str()); + } + + void Set(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> ¶ms) + { + const Anope::string &topic = params.size() > 2 ? params[2] : ""; + + bool has_topiclock = ci->HasExt("TOPICLOCK"); + ci->Shrink("TOPICLOCK"); + ci->c->ChangeTopic(source.GetNick(), topic, Anope::CurTime); + if (has_topiclock) + ci->ExtendMetadata("TOPICLOCK"); + + bool override = !source.AccessFor(ci).HasPriv("TOPIC"); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << (!topic.empty() ? "to change the topic to: " : "to unset the topic") << (!topic.empty() ? topic : ""); + } + + void Append(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> ¶ms) + { + const Anope::string &topic = params[2]; + + Anope::string new_topic; + if (!ci->c->topic.empty()) + { + new_topic = ci->c->topic + " " + topic; + ci->last_topic.clear(); + } + else + new_topic = topic; + + std::vector<Anope::string> new_params; + new_params.push_back("SET"); + new_params.push_back(ci->name); + new_params.push_back(new_topic); + + this->Set(source, ci, new_params); + } + public: - CommandCSTopic(Module *creator) : Command(creator, "chanserv/topic", 1, 2) + CommandCSTopic(Module *creator) : Command(creator, "chanserv/topic", 2, 3) { this->SetDesc(_("Manipulate the topic of the specified channel")); - this->SetSyntax(_("\037channel\037 [\037topic\037]")); + this->SetSyntax(_("\037channel\037 SET [\037topic\037]")); + this->SetSyntax(_("\037channel\037 APPEND \037topic\037")); + this->SetSyntax(_("\037channel\037 [UNLOCK|LOCK]")); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { - const Anope::string &topic = params.size() > 1 ? params[1] : ""; - + const Anope::string &subcmd = params[1]; ChannelInfo *ci = ChannelInfo::Find(params[0]); if (ci == NULL) - { source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str()); - return; - } - - if (!ci->c) - source.Reply(CHAN_X_NOT_IN_USE, ci->name.c_str()); else if (!source.AccessFor(ci).HasPriv("TOPIC") && !source.HasCommand("chanserv/topic")) source.Reply(ACCESS_DENIED); + else if (subcmd.equals_ci("LOCK")) + this->Lock(source, ci, params); + else if (subcmd.equals_ci("UNLOCK")) + this->Unlock(source, ci, params); + else if (!ci->c) + source.Reply(CHAN_X_NOT_IN_USE, ci->name.c_str()); + else if (subcmd.equals_ci("SET")) + this->Set(source, ci, params); + else if (subcmd.equals_ci("APPEND") && params.size() > 2) + this->Append(source, ci, params); else - { - bool has_topiclock = ci->HasFlag(CI_TOPICLOCK); - ci->UnsetFlag(CI_TOPICLOCK); - ci->c->ChangeTopic(source.GetNick(), topic, Anope::CurTime); - if (has_topiclock) - ci->SetFlag(CI_TOPICLOCK); - - bool override = !source.AccessFor(ci).HasPriv("TOPIC"); - Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << (!topic.empty() ? "to change the topic to: " : "to unset the topic") << (!topic.empty() ? topic : ""); - } - return; + this->SendSyntax(source); } bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override { this->SendSyntax(source); source.Reply(" "); - source.Reply(_("Causes %s to set the channel topic to the one\n" - "specified. If \002topic\002 is not given, then an empty topic\n" - "is set. This command is most useful in conjunction\n" - "with topic lock.\n" - "By default, limited to those with founder access on the\n" - "channel."), source.service->nick.c_str()); + source.Reply(_("Allows manipulating the topic of the specified channel.\n" + "The \002SET\002 command changes the topic of the channel to the given topic\n" + "or unsets the topic if no topic is given. The \002APPEND\002 command appends\n" + "the given topic to the existing topic.\n" + " \n" + "\002LOCK\002 and \002UNLOCK\002 may be used to enable and disable topic lock. When\n" + "topic lock is set, the channel topic will be unchangeable except via this command.")); return true; } }; diff --git a/modules/commands/cs_unban.cpp b/modules/commands/cs_unban.cpp index affe8eae9..eaf371a34 100644 --- a/modules/commands/cs_unban.cpp +++ b/modules/commands/cs_unban.cpp @@ -1,6 +1,6 @@ /* ChanServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -16,7 +16,7 @@ class CommandCSUnban : public Command { public: - CommandCSUnban(Module *creator) : Command(creator, "chanserv/unban", 1, 2) + CommandCSUnban(Module *creator) : Command(creator, "chanserv/unban", 0, 2) { this->SetDesc(_("Remove all bans preventing a user from entering a channel")); this->SetSyntax(_("\037channel\037 [\037nick\037]")); @@ -24,6 +24,31 @@ class CommandCSUnban : public Command void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { + if (params.empty()) + { + if (!source.GetUser()) + return; + + std::deque<ChannelInfo *> queue; + source.GetAccount()->GetChannelReferences(queue); + + unsigned count = 0; + for (unsigned i = 0; i < queue.size(); ++i) + { + ChannelInfo *ci = queue[i]; + + if (!ci->c || !source.AccessFor(ci).HasPriv("UNBAN")) + continue; + + if (ci->c->Unban(source.GetUser(), true)) + ++count; + } + + source.Reply(_("You have been unbanned from %d channels."), count); + + return; + } + ChannelInfo *ci = ChannelInfo::Find(params[0]); if (ci == NULL) { @@ -60,8 +85,6 @@ class CommandCSUnban : public Command source.Reply(_("You have been unbanned from \002%s\002."), ci->c->name.c_str()); else source.Reply(_("\002%s\002 has been unbanned from \002%s\002."), u2->nick.c_str(), ci->c->name.c_str()); - - return; } bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override @@ -69,7 +92,9 @@ class CommandCSUnban : public Command this->SendSyntax(source); source.Reply(" "); source.Reply(_("Tells %s to remove all bans preventing you or the given\n" - "user from entering the given channel.\n" + "user from entering the given channel. If no channel is\n" + "given, all bans affecting you in channels you have access\n" + "in are removed.\n" " \n" "By default, limited to AOPs or those with level 5 and above\n" "on the channel."), source.service->nick.c_str()); diff --git a/modules/commands/cs_updown.cpp b/modules/commands/cs_updown.cpp index 6d46c873e..196fce2e2 100644 --- a/modules/commands/cs_updown.cpp +++ b/modules/commands/cs_updown.cpp @@ -1,6 +1,6 @@ /* ChanServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -20,16 +20,15 @@ class CommandCSUp : public Command { this->SetDesc(_("Updates your status on a channel")); this->SetSyntax(_("[\037channel\037]")); + this->RequireUser(true); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { User *u = source.GetUser(); - if (!u) - return; if (params.empty()) - for (UChannelList::iterator it = u->chans.begin(); it != u->chans.end(); ++it) + for (User::ChanUserList::iterator it = u->chans.begin(); it != u->chans.end(); ++it) { Channel *c = (*it)->chan; c->SetCorrectModes(u, true, false); @@ -77,16 +76,15 @@ class CommandCSDown : public Command { this->SetDesc(_("Removes your status from a channel")); this->SetSyntax(_("[\037channel\037]")); + this->RequireUser(true); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { User *u = source.GetUser(); - if (!u) - return; if (params.empty()) - for (UChannelList::iterator it = u->chans.begin(); it != u->chans.end(); ++it) + for (User::ChanUserList::iterator it = u->chans.begin(); it != u->chans.end(); ++it) { Channel *c = (*it)->chan; RemoveAll(u, c); @@ -110,7 +108,7 @@ class CommandCSDown : public Command this->SendSyntax(source); source.Reply(" "); source.Reply(_("Removes your status modes on a channel. If \037channel\037 is ommited\n" - "your channel status is remove on every channel you are in.")); + "your channel status is removed on every channel you are in.")); return true; } }; diff --git a/modules/commands/cs_xop.cpp b/modules/commands/cs_xop.cpp index 77f6cb5a0..546175e14 100644 --- a/modules/commands/cs_xop.cpp +++ b/modules/commands/cs_xop.cpp @@ -1,6 +1,6 @@ /* ChanServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -319,7 +319,7 @@ class XOPBase : public Command const ChanAccess *highest = access.Highest(); bool override = false; - if (mask.find_first_of("!*@") == Anope::string::npos && !NickAlias::Find(mask)) + if (!isdigit(mask[0]) && mask.find_first_of("!*@") == Anope::string::npos && !NickAlias::Find(mask)) { User *targ = User::Find(mask, true); if (targ != NULL) @@ -411,7 +411,7 @@ class XOPBase : public Command source.Reply(_("\002%s\002 deleted from %s %s list."), a->mask.c_str(), ci->name.c_str(), source.command.c_str()); FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, source, a)); - ci->EraseAccess(a); + delete a; return; } @@ -622,11 +622,11 @@ class CommandCSQOP : public XOPBase " 7 through 9.\n" " \n" "The \002QOP CLEAR\002 command clears all entries of the\n" - "QOP list.\n")); + "QOP list.")); source.Reply(_(" \n" "The \002QOP\002 commands are limited to founders\n" "(unless SECUREOPS is off). However, any user on the\n" - "VOP list may use the \002QOP LIST\002 command.\n" + "VOP list or above may use the \002QOP LIST\002 command.\n" " \n")); source.Reply(_("Alternative methods of modifying channel access lists are\n" "available. See \002%s%s HELP ACCESS\002 for information\n" @@ -676,12 +676,12 @@ class CommandCSAOP : public XOPBase " 7 through 9.\n" " \n" "The \002AOP CLEAR\002 command clears all entries of the\n" - "AOP list.\n")); + "AOP list.")); source.Reply(_(" \n" "The \002AOP ADD\002 and \002AOP DEL\002 commands are limited to\n" "SOPs or above, while the \002AOP CLEAR\002 command can only\n" "be used by the channel founder. However, any user on the\n" - "VOP list may use the \002AOP LIST\002 command.\n" + "VOP list or above may use the \002AOP LIST\002 command.\n" " \n")); source.Reply(_("Alternative methods of modifying channel access lists are\n" "available. See \002%s%s HELP ACCESS\002 for information\n" @@ -730,7 +730,7 @@ class CommandCSHOP : public XOPBase " 7 through 9.\n" " \n" "The \002HOP CLEAR\002 command clears all entries of the\n" - "HOP list.\n")); + "HOP list.")); source.Reply(_(" \n" "The \002HOP ADD\002 and \002HOP DEL\002 commands are limited\n" "to SOPs or above, while \002HOP LIST\002 is available to VOPs\n" @@ -785,11 +785,11 @@ class CommandCSSOP : public XOPBase " 7 through 9.\n" " \n" "The \002SOP CLEAR\002 command clears all entries of the\n" - "SOP list.\n")); + "SOP list.")); source.Reply(_(" \n" "The \002SOP ADD\002, \002SOP DEL\002 and \002SOP CLEAR\002 commands are\n" "limited to the channel founder. However, any user on the\n" - "VOP list may use the \002SOP LIST\002 command.\n" + "VOP list or above may use the \002SOP LIST\002 command.\n" " \n")); source.Reply(_("Alternative methods of modifying channel access lists are\n" "available. See \002%s%s HELP ACCESS\002 for information\n" @@ -838,7 +838,7 @@ class CommandCSVOP : public XOPBase " 7 through 9.\n" " \n" "The \002VOP CLEAR\002 command clears all entries of the\n" - "VOP list.\n")); + "VOP list.")); source.Reply(_(" \n" "The \002VOP ADD\002 and \002VOP DEL\002 commands are limited\n" "to SOPs or above, while \002VOP LIST\002 is available to VOPs\n" diff --git a/modules/commands/gl_global.cpp b/modules/commands/gl_global.cpp index 2be0164e3..7cc4dbdc8 100644 --- a/modules/commands/gl_global.cpp +++ b/modules/commands/gl_global.cpp @@ -1,6 +1,6 @@ /* Global core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -16,8 +16,10 @@ class CommandGLGlobal : public Command { + ServiceReference<GlobalService> GService; + public: - CommandGLGlobal(Module *creator) : Command(creator, "global/global", 1, 1) + CommandGLGlobal(Module *creator) : Command(creator, "global/global", 1, 1), GService("GlobalService", "Global") { this->SetDesc(_("Send a message to all users")); this->SetSyntax(_("\037message\037")); @@ -27,12 +29,12 @@ class CommandGLGlobal : public Command { const Anope::string &msg = params[0]; - if (!GlobalService) + if (!GService) source.Reply("No global reference, is gl_main loaded?"); else { Log(LOG_ADMIN, source, this); - GlobalService->SendGlobal(Global, source.GetNick(), msg); + GService->SendGlobal(Global, source.GetNick(), msg); } } @@ -40,7 +42,7 @@ class CommandGLGlobal : public Command { this->SendSyntax(source); source.Reply(" "); - source.Reply(_("Allows Administrators to send messages to all users on the \n" + source.Reply(_("Allows Administrators to send messages to all users on the\n" "network. The message will be sent from the nick \002%s\002."), source.service->nick.c_str()); return true; } diff --git a/modules/commands/help.cpp b/modules/commands/help.cpp index 252406590..fcac6863c 100644 --- a/modules/commands/help.cpp +++ b/modules/commands/help.cpp @@ -1,6 +1,6 @@ /* Core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -15,12 +15,25 @@ class CommandHelp : public Command { + static const unsigned help_wrap_len = 40; + + static CommandGroup *FindGroup(const Anope::string &name) + { + for (unsigned i = 0; i < Config->CommandGroups.size(); ++i) + { + CommandGroup &gr = Config->CommandGroups[i]; + if (gr.name == name) + return &gr; + } + + return NULL; + } + public: CommandHelp(Module *creator) : Command(creator, "generic/help", 0) { this->SetDesc(_("Displays this list and give information about commands")); - this->SetFlag(CFLAG_STRIP_CHANNEL); - this->SetFlag(CFLAG_ALLOW_UNREGISTERED); + this->AllowUnregistered(true); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override @@ -30,16 +43,27 @@ class CommandHelp : public Command if (MOD_RESULT == EVENT_STOP) return; + Anope::string source_command = source.command; const BotInfo *bi = source.service; const CommandInfo::map &map = source.c ? Config->Fantasy : bi->commands; - if (params.empty()) + if (params.empty() || params[0].equals_ci("ALL")) { + bool all = !params.empty() && params[0].equals_ci("ALL"); + typedef std::map<CommandGroup *, std::list<Anope::string> > GroupInfo; + GroupInfo groups; + + if (all) + source.Reply(_("All available commands for \002%s\002:"), source.service->nick.c_str()); + for (CommandInfo::map::const_iterator it = map.begin(), it_end = map.end(); it != it_end; ++it) { const Anope::string &c_name = it->first; const CommandInfo &info = it->second; + if (info.hide) + continue; + // Smaller command exists Anope::string cmd; spacesepstream(c_name).GetToken(cmd, 0); @@ -51,15 +75,57 @@ class CommandHelp : public Command continue; else if (!Config->HidePrivilegedCommands) ; // Always show with HidePrivilegedCommands disabled - else if (!c->HasFlag(CFLAG_ALLOW_UNREGISTERED) && !source.GetAccount()) + else if (!c->AllowUnregistered() && !source.GetAccount()) continue; else if (!info.permission.empty() && !source.HasCommand(info.permission)) continue; + if (!info.group.empty() && !all) + { + CommandGroup *gr = FindGroup(info.group); + if (gr != NULL) + { + groups[gr].push_back(c_name); + continue; + } + } + source.command = c_name; c->OnServHelp(source); } + + for (GroupInfo::iterator it = groups.begin(), it_end = groups.end(); it != it_end; ++it) + { + CommandGroup *gr = it->first; + + source.Reply(" "); + source.Reply("%s", gr->description.c_str()); + + Anope::string buf; + for (std::list<Anope::string>::iterator it2 = it->second.begin(), it2_end = it->second.end(); it2 != it2_end; ++it2) + { + const Anope::string &c_name = *it2; + + buf += ", " + c_name; + + if (buf.length() > help_wrap_len) + { + source.Reply(" %s", buf.substr(2).c_str()); + buf.clear(); + } + } + if (buf.length() > 2) + { + source.Reply(" %s", buf.substr(2).c_str()); + buf.clear(); + } + } + if (!groups.empty()) + { + source.Reply(" "); + source.Reply(_("Use the \002%s ALL\002 command to list all commands and their descriptions."), source_command.c_str()); + } } else { @@ -100,7 +166,7 @@ class CommandHelp : public Command source.Reply(" "); source.Reply(_("Access to this command requires the permission \002%s\002 to be present in your opertype."), info.permission.c_str()); } - if (!c->HasFlag(CFLAG_ALLOW_UNREGISTERED) && !source.nc) + if (!c->AllowUnregistered() && !source.nc) { if (info.permission.empty()) source.Reply(" "); diff --git a/modules/commands/hs_del.cpp b/modules/commands/hs_del.cpp index 4e2cdc8b7..5df23e721 100644 --- a/modules/commands/hs_del.cpp +++ b/modules/commands/hs_del.cpp @@ -1,6 +1,6 @@ /* HostServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -64,9 +64,9 @@ class CommandHSDelAll : public Command { FOREACH_MOD(I_OnDeleteVhost, OnDeleteVhost(na)); const NickCore *nc = na->nc; - for (std::list<Serialize::Reference<NickAlias> >::const_iterator it = nc->aliases.begin(), it_end = nc->aliases.end(); it != it_end; ++it) + for (unsigned i = 0; i < nc->aliases->size(); ++i) { - na = *it; + na = nc->aliases->at(i); na->RemoveVhost(); } Log(LOG_ADMIN, source, this) << "for all nicks in group " << nc->display; diff --git a/modules/commands/hs_group.cpp b/modules/commands/hs_group.cpp index 5d8bc069e..ee997f704 100644 --- a/modules/commands/hs_group.cpp +++ b/modules/commands/hs_group.cpp @@ -1,6 +1,6 @@ /* HostServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -20,9 +20,9 @@ class CommandHSGroup : public Command if (!na || !na->HasVhost()) return; - for (std::list<Serialize::Reference<NickAlias> >::const_iterator it = na->nc->aliases.begin(), it_end = na->nc->aliases.end(); it != it_end;) + for (unsigned i = 0; i < na->nc->aliases->size(); ++i) { - NickAlias *nick = *it++; + NickAlias *nick = na->nc->aliases->at(i); if (nick) nick->SetVhost(na->GetVhostIdent(), na->GetVhostHost(), na->GetVhostCreator()); } @@ -42,9 +42,9 @@ class CommandHSGroup : public Command { this->Sync(na); if (!na->GetVhostIdent().empty()) - source.Reply(_("All vhost's in the group \002%s\002 have been set to \002%s\002@\002%s\002"), source.nc->display.c_str(), na->GetVhostIdent().c_str(), na->GetVhostHost().c_str()); + source.Reply(_("All vhost's in the group \002%s\002 have been set to \002%s\002@\002%s\002."), source.nc->display.c_str(), na->GetVhostIdent().c_str(), na->GetVhostHost().c_str()); else - source.Reply(_("All vhost's in the group \002%s\002 have been set to \002%s\002"), source.nc->display.c_str(), na->GetVhostHost().c_str()); + source.Reply(_("All vhost's in the group \002%s\002 have been set to \002%s\002."), source.nc->display.c_str(), na->GetVhostHost().c_str()); } else source.Reply(HOST_NOT_ASSIGNED); diff --git a/modules/commands/hs_list.cpp b/modules/commands/hs_list.cpp index 29fa145b3..96e6866f0 100644 --- a/modules/commands/hs_list.cpp +++ b/modules/commands/hs_list.cpp @@ -1,6 +1,6 @@ /* HostServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -18,8 +18,8 @@ class CommandHSList : public Command public: CommandHSList(Module *creator) : Command(creator, "hostserv/list", 0, 1) { - this->SetDesc(_("Displays one or more vhost entries.")); - this->SetSyntax(_("\002[<key>|<#X-Y>]")); + this->SetDesc(_("Displays one or more vhost entries")); + this->SetSyntax(_("[\037key\037|\037#X-Y\037]")); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override @@ -115,13 +115,13 @@ class CommandHSList : public Command } if (!key.empty()) - source.Reply(_("Displayed records matching key \002%s\002 (Count: \002%d\002)"), key.c_str(), display_counter); + source.Reply(_("Displayed records matching key \002%s\002 (count: \002%d\002)."), key.c_str(), display_counter); else { if (from) - source.Reply(_("Displayed records from \002%d\002 to \002%d\002"), from, to); + source.Reply(_("Displayed records from \002%d\002 to \002%d\002."), from, to); else - source.Reply(_("Displayed all records (Count: \002%d\002)"), display_counter); + source.Reply(_("Displayed all records (count: \002%d\002)."), display_counter); } std::vector<Anope::string> replies; @@ -136,14 +136,14 @@ class CommandHSList : public Command this->SendSyntax(source); source.Reply(" "); source.Reply(_("This command lists registered vhosts to the operator\n" - "if a Key is specified, only entries whos nick or vhost match\n" - "the pattern given in <key> are displayed e.g. Rob* for all\n" + "if a \037key\037 is specified, only entries whos nick or vhost match\n" + "the pattern given in \037key\037 are displayed e.g. Rob* for all\n" "entries beginning with \"Rob\"\n" - "If a #X-Y style is used, only entries between the range of X\n" - "and Y will be displayed, e.g. #1-3 will display the first 3\n" + "If a \037#X-Y\037 style is used, only entries between the range of \002X\002\n" + "and \002Y\002 will be displayed, e.g. \002#1-3\002 will display the first 3\n" "nick/vhost entries.\n" "The list uses the value of NSListMax as a hard limit for the\n" - "number of items to display to a operator at any 1 time.")); + "number of items to display to a operator at any one time.")); return true; } }; diff --git a/modules/commands/hs_off.cpp b/modules/commands/hs_off.cpp index 27c6c0756..3db3c1adf 100644 --- a/modules/commands/hs_off.cpp +++ b/modules/commands/hs_off.cpp @@ -1,6 +1,6 @@ /* HostServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -20,14 +20,12 @@ class CommandHSOff : public Command { this->SetDesc(_("Deactivates your assigned vhost")); this->SetSyntax(""); + this->RequireUser(true); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { User *u = source.GetUser(); - if (!u) - return; - const NickAlias *na = NickAlias::Find(u->nick); if (!na || !na->HasVhost()) @@ -48,7 +46,7 @@ class CommandHSOff : public Command source.Reply(" "); source.Reply(_("Deactivates the vhost currently assigned to the nick in use.\n" "When you use this command any user who performs a /whois\n" - "on you will see your real IP address.")); + "on you will see your real host/IP address.")); return true; } }; diff --git a/modules/commands/hs_on.cpp b/modules/commands/hs_on.cpp index c4cf2fee8..e19482c9a 100644 --- a/modules/commands/hs_on.cpp +++ b/modules/commands/hs_on.cpp @@ -1,6 +1,6 @@ /* HostServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -20,16 +20,15 @@ class CommandHSOn : public Command { this->SetDesc(_("Activates your assigned vhost")); this->SetSyntax(""); + this->RequireUser(true); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { - User *u = source.GetUser(); - if (!u) - return; - else if (!IRCD->CanSetVHost) + if (!IRCD->CanSetVHost) return; // HostServ wouldn't even be loaded at this point + User *u = source.GetUser(); const NickAlias *na = NickAlias::Find(u->nick); if (na && u->Account() == na->nc && na->HasVhost()) { @@ -56,7 +55,7 @@ class CommandHSOn : public Command source.Reply(" "); source.Reply(_("Activates the vhost currently assigned to the nick in use.\n" "When you use this command any user who performs a /whois\n" - "on you will see the vhost instead of your real IP address.")); + "on you will see the vhost instead of your real host/IP address.")); return true; } }; diff --git a/modules/commands/hs_request.cpp b/modules/commands/hs_request.cpp index 6cd2e6811..a09718621 100644 --- a/modules/commands/hs_request.cpp +++ b/modules/commands/hs_request.cpp @@ -1,7 +1,7 @@ /* hs_request.c - Add request and activate functionality to HostServ, * * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Based on the original module by Rob <rob@anope.org> @@ -18,6 +18,8 @@ #include "module.h" #include "memoserv.h" +static ServiceReference<MemoServService> MemoServService("MemoServService", "MemoServ"); + static bool HSRequestMemoUser = false; static bool HSRequestMemoOper = false; @@ -144,7 +146,7 @@ class CommandHSRequest : public Command if (HSRequestMemoOper && Config->MSSendDelay > 0 && u && u->lastmemosend + Config->MSSendDelay > Anope::CurTime) { - source.Reply(_("Please wait %d seconds before requesting a new vHost"), Config->MSSendDelay); + source.Reply(_("Please wait %d seconds before requesting a new vHost."), Config->MSSendDelay); u->lastmemosend = Anope::CurTime; return; } @@ -157,7 +159,7 @@ class CommandHSRequest : public Command req->time = Anope::CurTime; na->Extend("hs_request", req); - source.Reply(_("Your vHost has been requested")); + source.Reply(_("Your vHost has been requested.")); req_send_memos(source, user, host); Log(LOG_COMMAND, source, this) << "to request new vhost " << (!user.empty() ? user + "@" : "") << host; @@ -199,7 +201,7 @@ class CommandHSActivate : public Command if (HSRequestMemoUser && MemoServService) MemoServService->Send(Config->HostServ, na->nick, _("[auto memo] Your requested vHost has been approved."), true); - source.Reply(_("vHost for %s has been activated"), na->nick.c_str()); + source.Reply(_("vHost for %s has been activated."), na->nick.c_str()); Log(LOG_COMMAND, source, this) << "for " << na->nick << " for vhost " << (!req->ident.empty() ? req->ident + "@" : "") << req->host; na->Shrink("hs_request"); } @@ -250,7 +252,7 @@ class CommandHSReject : public Command MemoServService->Send(Config->HostServ, nick, message, true); } - source.Reply(_("vHost for %s has been rejected"), nick.c_str()); + source.Reply(_("vHost for %s has been rejected."), nick.c_str()); Log(LOG_COMMAND, source, this, NULL) << "to reject vhost for " << nick << " (" << (!reason.empty() ? reason : "") << ")"; } else @@ -305,7 +307,7 @@ class CommandHSWaiting : public Command } ++counter; } - source.Reply(_("Displayed all records (Count: \002%d\002)"), display_counter); + source.Reply(_("Displayed all records (count: \002%d\002)."), display_counter); std::vector<Anope::string> replies; list.Process(replies); @@ -330,7 +332,7 @@ class CommandHSWaiting : public Command { this->SendSyntax(source); source.Reply(" "); - source.Reply(_("This command retrieves the vhost requests")); + source.Reply(_("This command retrieves the vhost requests.")); return true; } diff --git a/modules/commands/hs_set.cpp b/modules/commands/hs_set.cpp index bb4091da4..11ecbca5a 100644 --- a/modules/commands/hs_set.cpp +++ b/modules/commands/hs_set.cpp @@ -1,6 +1,6 @@ /* HostServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -95,7 +95,7 @@ class CommandHSSet : public Command source.Reply(" "); source.Reply(_("Sets the vhost for the given nick to that of the given\n" "hostmask. If your IRCD supports vIdents, then using\n" - "SET <nick> <ident>@<hostmask> set idents for users as \n" + "SET <nick> <ident>@<hostmask> set idents for users as\n" "well as vhosts.")); return true; } @@ -108,9 +108,9 @@ class CommandHSSetAll : public Command if (!na || !na->HasVhost()) return; - for (std::list<Serialize::Reference<NickAlias> >::const_iterator it = na->nc->aliases.begin(), it_end = na->nc->aliases.end(); it != it_end;) + for (unsigned i = 0; i < na->nc->aliases->size(); ++i) { - NickAlias *nick = *it++; + NickAlias *nick = na->nc->aliases->at(i); if (nick) nick->SetVhost(na->GetVhostIdent(), na->GetVhostHost(), na->GetVhostCreator()); } diff --git a/modules/commands/ms_cancel.cpp b/modules/commands/ms_cancel.cpp index 8949baf17..e03883d91 100644 --- a/modules/commands/ms_cancel.cpp +++ b/modules/commands/ms_cancel.cpp @@ -1,6 +1,6 @@ /* MemoServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -14,6 +14,8 @@ #include "module.h" #include "memoserv.h" +static ServiceReference<MemoServService> MemoServService("MemoServService", "MemoServ"); + class CommandMSCancel : public Command { public: @@ -32,7 +34,7 @@ class CommandMSCancel : public Command const Anope::string &nname = params[0]; bool ischan; - MemoInfo *mi = MemoServService->GetMemoInfo(nname, ischan); + MemoInfo *mi = MemoInfo::GetMemoInfo(nname, ischan); if (mi == NULL) source.Reply(ischan ? CHAN_X_NOT_REGISTERED : _(NICK_X_NOT_REGISTERED), nname.c_str()); @@ -45,7 +47,7 @@ class CommandMSCancel : public Command else na = NickAlias::Find(nname); for (int i = mi->memos->size() - 1; i >= 0; --i) - if (mi->GetMemo(i)->HasFlag(MF_UNREAD) && source.nc->display.equals_ci(mi->GetMemo(i)->sender)) + if (mi->GetMemo(i)->unread && source.nc->display.equals_ci(mi->GetMemo(i)->sender)) { if (ischan) FOREACH_MOD(I_OnMemoDel, OnMemoDel(ci, mi, mi->GetMemo(i))); diff --git a/modules/commands/ms_check.cpp b/modules/commands/ms_check.cpp index 8f34e7b9a..984126ee6 100644 --- a/modules/commands/ms_check.cpp +++ b/modules/commands/ms_check.cpp @@ -1,6 +1,6 @@ /* MemoServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -47,7 +47,7 @@ class CommandMSCheck : public Command { found = true; /* Yes, we've found the memo */ - if (mi->GetMemo(i)->HasFlag(MF_UNREAD)) + if (mi->GetMemo(i)->unread) source.Reply(_("The last memo you sent to %s (sent on %s) has not yet been read."), na->nick.c_str(), Anope::strftime(mi->GetMemo(i)->time).c_str()); else source.Reply(_("The last memo you sent to %s (sent on %s) has been read."), na->nick.c_str(), Anope::strftime(mi->GetMemo(i)->time).c_str()); @@ -66,7 +66,7 @@ class CommandMSCheck : public Command this->SendSyntax(source); source.Reply(" "); source.Reply(_("Checks whether the _last_ memo you sent to \037nick\037 has been read\n" - "or not. Note that this does only work with nicks, not with chans.")); + "or not. Note that this does only work with nicks, not with channels.")); return true; } }; diff --git a/modules/commands/ms_del.cpp b/modules/commands/ms_del.cpp index 99b388e52..33175d023 100644 --- a/modules/commands/ms_del.cpp +++ b/modules/commands/ms_del.cpp @@ -1,6 +1,6 @@ /* MemoServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -114,7 +114,7 @@ class CommandMSDel : public Command FOREACH_MOD(I_OnMemoDel, OnMemoDel(ci, mi, mi->GetMemo(i))); else FOREACH_MOD(I_OnMemoDel, OnMemoDel(source.nc, mi, mi->GetMemo(i))); - mi->GetMemo(i)->Destroy(); + delete mi->GetMemo(i); } mi->memos->clear(); if (!chan.empty()) diff --git a/modules/commands/ms_ignore.cpp b/modules/commands/ms_ignore.cpp index 465714852..41e139eff 100644 --- a/modules/commands/ms_ignore.cpp +++ b/modules/commands/ms_ignore.cpp @@ -1,6 +1,6 @@ /* MemoServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -15,13 +15,17 @@ #include "module.h" #include "memoserv.h" +static ServiceReference<MemoServService> MemoServService("MemoServService", "MemoServ"); + class CommandMSIgnore : public Command { public: CommandMSIgnore(Module *creator) : Command(creator, "memoserv/ignore", 1, 3) { - this->SetDesc(_("Manage your memo ignore list")); - this->SetSyntax(_("[\037channel\037] {\002ADD|DEL|LIST\002} [\037entry\037]")); + this->SetDesc(_("Manage the memo ignore list")); + this->SetSyntax(_("[\037channel\037] ADD \037entry\037")); + this->SetSyntax(_("[\037channel\037] DEL \037entry\037")); + this->SetSyntax(_("[\037channel\037] LIST")); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override @@ -42,7 +46,7 @@ class CommandMSIgnore : public Command } bool ischan; - MemoInfo *mi = MemoServService->GetMemoInfo(channel, ischan); + MemoInfo *mi = MemoInfo::GetMemoInfo(channel, ischan); ChannelInfo *ci = ChannelInfo::Find(channel); if (!mi) source.Reply(ischan ? CHAN_X_NOT_REGISTERED : _(NICK_X_NOT_REGISTERED), channel.c_str()); @@ -53,10 +57,10 @@ class CommandMSIgnore : public Command if (std::find(mi->ignores.begin(), mi->ignores.end(), param.ci_str()) == mi->ignores.end()) { mi->ignores.push_back(param.ci_str()); - source.Reply(_("\002%s\002 added to your ignore list."), param.c_str()); + source.Reply(_("\002%s\002 added to ignore list."), param.c_str()); } else - source.Reply(_("\002%s\002 is already on your ignore list."), param.c_str()); + source.Reply(_("\002%s\002 is already on the ignore list."), param.c_str()); } else if (command.equals_ci("DEL") && !param.empty()) { @@ -65,15 +69,15 @@ class CommandMSIgnore : public Command if (it != mi->ignores.end()) { mi->ignores.erase(it); - source.Reply(_("\002%s\002 removed from your ignore list."), param.c_str()); + source.Reply(_("\002%s\002 removed from the ignore list."), param.c_str()); } else - source.Reply(_("\002%s\002 is not on your ignore list."), param.c_str()); + source.Reply(_("\002%s\002 is not on the ignore list."), param.c_str()); } else if (command.equals_ci("LIST")) { if (mi->ignores.empty()) - source.Reply(_("Your memo ignore list is empty.")); + source.Reply(_("Memo ignore list is empty.")); else { ListFormatter list; @@ -104,8 +108,10 @@ class CommandMSIgnore : public Command { this->SendSyntax(source); source.Reply(" "); - source.Reply(_("Allows you to ignore users by nick or host from memoing you. If someone on your\n" - "memo ignore list tries to memo you, they will not be told that you have them ignored.")); + source.Reply(_("Allows you to ignore users by nick or host from memoing\n" + "you or a channel. If someone on the memo ignore list tries\n" + "to memo you or a channel, they will not be told that you have\n" + "them ignored.")); return true; } }; diff --git a/modules/commands/ms_info.cpp b/modules/commands/ms_info.cpp index b209d0bf4..21ec9ba13 100644 --- a/modules/commands/ms_info.cpp +++ b/modules/commands/ms_info.cpp @@ -1,6 +1,6 @@ /* MemoServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -40,7 +40,7 @@ class CommandMSInfo : public Command return; } mi = &na->nc->memos; - hardmax = na->nc->HasFlag(NI_MEMO_HARDMAX) ? 1 : 0; + hardmax = na->nc->HasExt("MEMO_HARDMAX") ? 1 : 0; } else if (!nname.empty() && nname[0] == '#') { @@ -56,7 +56,7 @@ class CommandMSInfo : public Command return; } mi = &ci->memos; - hardmax = ci->HasFlag(CI_MEMO_HARDMAX) ? 1 : 0; + hardmax = ci->HasExt("MEMO_HARDMAX") ? 1 : 0; } else if (!nname.empty()) /* It's not a chan and we aren't services admin */ { @@ -66,7 +66,7 @@ class CommandMSInfo : public Command else { mi = &nc->memos; - hardmax = nc->HasFlag(NI_MEMO_HARDMAX) ? 1 : 0; + hardmax = nc->HasExt("MEMO_HARDMAX") ? 1 : 0; } if (!nname.empty() && (ci || na->nc != nc)) @@ -75,7 +75,7 @@ class CommandMSInfo : public Command source.Reply(_("%s currently has no memos."), nname.c_str()); else if (mi->memos->size() == 1) { - if (mi->GetMemo(0)->HasFlag(MF_UNREAD)) + if (mi->GetMemo(0)->unread) source.Reply(_("%s currently has \0021\002 memo, and it has not yet been read."), nname.c_str()); else source.Reply(_("%s currently has \0021\002 memo."), nname.c_str()); @@ -84,7 +84,7 @@ class CommandMSInfo : public Command { unsigned count = 0, i, end; for (i = 0, end = mi->memos->size(); i < end; ++i) - if (mi->GetMemo(i)->HasFlag(MF_UNREAD)) + if (mi->GetMemo(i)->unread) ++count; if (count == mi->memos->size()) source.Reply(_("%s currently has \002%d\002 memos; all of them are unread."), nname.c_str(), count); @@ -116,11 +116,11 @@ class CommandMSInfo : public Command to rewrite the whole thing (it pisses me off). */ if (na) { - if (na->nc->HasFlag(NI_MEMO_RECEIVE) && na->nc->HasFlag(NI_MEMO_SIGNON)) + if (na->nc->HasExt("MEMO_RECEIVE") && na->nc->HasExt("MEMO_SIGNON")) source.Reply(_("%s is notified of new memos at logon and when they arrive."), nname.c_str()); - else if (na->nc->HasFlag(NI_MEMO_RECEIVE)) + else if (na->nc->HasExt("MEMO_RECEIVE")) source.Reply(_("%s is notified when new memos arrive."), nname.c_str()); - else if (na->nc->HasFlag(NI_MEMO_SIGNON)) + else if (na->nc->HasExt("MEMO_SIGNON")) source.Reply(_("%s is notified of news memos at logon."), nname.c_str()); else source.Reply(_("%s is not notified of new memos."), nname.c_str()); @@ -132,7 +132,7 @@ class CommandMSInfo : public Command source.Reply(_("You currently have no memos.")); else if (mi->memos->size() == 1) { - if (mi->GetMemo(0)->HasFlag(MF_UNREAD)) + if (mi->GetMemo(0)->unread) source.Reply(_("You currently have \0021\002 memo, and it has not yet been read.")); else source.Reply(_("You currently have \0021\002 memo.")); @@ -141,7 +141,7 @@ class CommandMSInfo : public Command { unsigned count = 0, i, end; for (i = 0, end = mi->memos->size(); i < end; ++i) - if (mi->GetMemo(i)->HasFlag(MF_UNREAD)) + if (mi->GetMemo(i)->unread) ++count; if (count == mi->memos->size()) source.Reply(_("You currently have \002%d\002 memos; all of them are unread."), count); @@ -171,11 +171,11 @@ class CommandMSInfo : public Command source.Reply(_("You have no limit on the number of memos you may keep.")); /* Ripped too. But differently because of a seg fault (loughs) */ - if (nc->HasFlag(NI_MEMO_RECEIVE) && nc->HasFlag(NI_MEMO_SIGNON)) + if (nc->HasExt("MEMO_RECEIVE") && nc->HasExt("MEMO_SIGNON")) source.Reply(_("You will be notified of new memos at logon and when they arrive.")); - else if (nc->HasFlag(NI_MEMO_RECEIVE)) + else if (nc->HasExt("MEMO_RECEIVE")) source.Reply(_("You will be notified when new memos arrive.")); - else if (nc->HasFlag(NI_MEMO_SIGNON)) + else if (nc->HasExt("MEMO_SIGNON")) source.Reply(_("You will be notified of new memos at logon.")); else source.Reply(_("You will not be notified of new memos.")); @@ -195,8 +195,8 @@ class CommandMSInfo : public Command "the given channel.\n" " \n" "With a nickname parameter, displays the same information\n" - "for the given nickname. This use limited to \002Services\n" - "Operators\002.")); + "for the given nickname. This is limited to \002Services\002\n" + "\002Operators\002.")); return true; } diff --git a/modules/commands/ms_list.cpp b/modules/commands/ms_list.cpp index 91196cfee..3181f9dff 100644 --- a/modules/commands/ms_list.cpp +++ b/modules/commands/ms_list.cpp @@ -1,6 +1,6 @@ /* MemoServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -85,7 +85,7 @@ class CommandMSList : public Command const Memo *m = mi->GetMemo(number); ListFormatter::ListEntry entry; - entry["Number"] = (m->HasFlag(MF_UNREAD) ? "* " : " ") + stringify(number + 1); + entry["Number"] = (m->unread ? "* " : " ") + stringify(number + 1); entry["Sender"] = m->sender; entry["Date/Time"] = Anope::strftime(m->time); this->list.AddEntry(entry); @@ -100,7 +100,7 @@ class CommandMSList : public Command { unsigned i, end; for (i = 0, end = mi->memos->size(); i < end; ++i) - if (mi->GetMemo(i)->HasFlag(MF_UNREAD)) + if (mi->GetMemo(i)->unread) break; if (i == end) { @@ -114,13 +114,13 @@ class CommandMSList : public Command for (unsigned i = 0, end = mi->memos->size(); i < end; ++i) { - if (!param.empty() && !mi->GetMemo(i)->HasFlag(MF_UNREAD)) + if (!param.empty() && !mi->GetMemo(i)->unread) continue; const Memo *m = mi->GetMemo(i); ListFormatter::ListEntry entry; - entry["Number"] = (m->HasFlag(MF_UNREAD) ? "* " : " ") + stringify(i + 1); + entry["Number"] = (m->unread ? "* " : " ") + stringify(i + 1); entry["Sender"] = m->sender; entry["Date/Time"] = Anope::strftime(m->time); list.AddEntry(entry); diff --git a/modules/commands/ms_read.cpp b/modules/commands/ms_read.cpp index 6d5adfb05..14b952922 100644 --- a/modules/commands/ms_read.cpp +++ b/modules/commands/ms_read.cpp @@ -1,6 +1,6 @@ /* MemoServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -14,6 +14,8 @@ #include "module.h" #include "memoserv.h" +static ServiceReference<MemoServService> MemoServService("MemoServService", "MemoServ"); + static void rsend_notify(CommandSource &source, MemoInfo *mi, Memo *m, const Anope::string &targ) { /* Only send receipt if memos are allowed */ @@ -45,7 +47,7 @@ static void rsend_notify(CommandSource &source, MemoInfo *mi, Memo *m, const Ano } /* Remove receipt flag from the original memo */ - m->UnsetFlag(MF_RECEIPT); + m->receipt = false; } class MemoListCallback : public NumberList @@ -74,10 +76,10 @@ class MemoListCallback : public NumberList else source.Reply(_("Memo %d from %s (%s). To delete, type: \002%s%s DEL %d\002"), index + 1, m->sender.c_str(), Anope::strftime(m->time).c_str(), Config->UseStrictPrivMsgString.c_str(), Config->MemoServ.c_str(), index + 1); source.Reply("%s", m->text.c_str()); - m->UnsetFlag(MF_UNREAD); + m->unread = false; /* Check if a receipt notification was requested */ - if (m->HasFlag(MF_RECEIPT)) + if (m->receipt) rsend_notify(source, mi, m, ci ? ci->name : source.GetNick()); } }; @@ -136,7 +138,7 @@ class CommandMSRead : public Command { int readcount = 0; for (i = 0, end = mi->memos->size(); i < end; ++i) - if (mi->GetMemo(i)->HasFlag(MF_UNREAD)) + if (mi->GetMemo(i)->unread) { MemoListCallback::DoRead(source, mi, ci, i); ++readcount; diff --git a/modules/commands/ms_rsend.cpp b/modules/commands/ms_rsend.cpp index b08b9be85..e5c345c75 100644 --- a/modules/commands/ms_rsend.cpp +++ b/modules/commands/ms_rsend.cpp @@ -1,6 +1,6 @@ /* MemoServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -14,6 +14,8 @@ #include "module.h" #include "memoserv.h" +static ServiceReference<MemoServService> MemoServService("MemoServService", "MemoServ"); + class CommandMSRSend : public Command { public: @@ -44,7 +46,7 @@ class CommandMSRSend : public Command source.Reply(ACCESS_DENIED); else if (Config->MSMemoReceipt > 2 || Config->MSMemoReceipt == 0) { - Log(this->owner) << "MSMemoReceipt is set misconfigured to " << Config->MSMemoReceipt; + Log(this->owner) << "MSMemoReceipt is misconfigured to " << Config->MSMemoReceipt; source.Reply(_("Sorry, RSEND has been disabled on this network.")); } else @@ -55,18 +57,18 @@ class CommandMSRSend : public Command 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()); + source.Reply(_("Sorry, %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; - MemoInfo *mi = MemoServService->GetMemoInfo(nick, ischan); + MemoInfo *mi = MemoInfo::GetMemoInfo(nick, ischan); if (mi == NULL) throw CoreException("NULL mi in ms_rsend"); Memo *m = (mi->memos->size() ? mi->GetMemo(mi->memos->size() - 1) : NULL); if (m != NULL) - m->SetFlag(MF_RECEIPT); + m->receipt = true; } } diff --git a/modules/commands/ms_send.cpp b/modules/commands/ms_send.cpp index 42024227e..f92955dcf 100644 --- a/modules/commands/ms_send.cpp +++ b/modules/commands/ms_send.cpp @@ -1,6 +1,6 @@ /* MemoServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -14,6 +14,8 @@ #include "module.h" #include "memoserv.h" +static ServiceReference<MemoServService> MemoServService("MemoServService", "MemoServ"); + class CommandMSSend : public Command { public: @@ -39,7 +41,7 @@ class CommandMSSend : public Command 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()); + source.Reply(_("Sorry, %s currently has too many memos and cannot receive more."), nick.c_str()); return; } diff --git a/modules/commands/ms_sendall.cpp b/modules/commands/ms_sendall.cpp index 5ade6722b..59d532bf9 100644 --- a/modules/commands/ms_sendall.cpp +++ b/modules/commands/ms_sendall.cpp @@ -1,6 +1,6 @@ /* MemoServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -14,6 +14,8 @@ #include "module.h" #include "memoserv.h" +static ServiceReference<MemoServService> MemoServService("MemoServService", "MemoServ"); + class CommandMSSendAll : public Command { public: diff --git a/modules/commands/ms_set.cpp b/modules/commands/ms_set.cpp index 497dffd4c..f2fc15c09 100644 --- a/modules/commands/ms_set.cpp +++ b/modules/commands/ms_set.cpp @@ -1,6 +1,6 @@ /* MemoServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -23,27 +23,27 @@ class CommandMSSet : public Command if (param.equals_ci("ON")) { - nc->SetFlag(NI_MEMO_SIGNON); - nc->SetFlag(NI_MEMO_RECEIVE); + nc->ExtendMetadata("MEMO_SIGNON"); + nc->ExtendMetadata("MEMO_RECEIVE"); source.Reply(_("%s will now notify you of memos when you log on and when they are sent to you."), Config->MemoServ.c_str()); } else if (param.equals_ci("LOGON")) { - nc->SetFlag(NI_MEMO_SIGNON); - nc->UnsetFlag(NI_MEMO_RECEIVE); + nc->ExtendMetadata("MEMO_SIGNON"); + nc->Shrink("MEMO_RECEIVE"); source.Reply(_("%s will now notify you of memos when you log on or unset /AWAY."), Config->MemoServ.c_str()); } else if (param.equals_ci("NEW")) { - nc->UnsetFlag(NI_MEMO_SIGNON); - nc->SetFlag(NI_MEMO_RECEIVE); + nc->Shrink("MEMO_SIGNON"); + nc->ExtendMetadata("MEMO_RECEIVE"); source.Reply(_("%s will now notify you of memos when they are sent to you."), Config->MemoServ.c_str()); } else if (param.equals_ci("MAIL")) { if (!nc->email.empty()) { - nc->SetFlag(NI_MEMO_MAIL); + nc->ExtendMetadata("MEMO_MAIL"); source.Reply(_("You will now be informed about new memos via email.")); } else @@ -51,14 +51,14 @@ class CommandMSSet : public Command } else if (param.equals_ci("NOMAIL")) { - nc->UnsetFlag(NI_MEMO_MAIL); + nc->Shrink("MEMO_MAIL"); source.Reply(_("You will no longer be informed via email.")); } else if (param.equals_ci("OFF")) { - nc->UnsetFlag(NI_MEMO_SIGNON); - nc->UnsetFlag(NI_MEMO_RECEIVE); - nc->UnsetFlag(NI_MEMO_MAIL); + nc->Shrink("MEMO_SIGNON"); + nc->Shrink("MEMO_RECEIVE"); + nc->Shrink("MEMO_MAIL"); source.Reply(_("%s will not send you any notification of memos."), Config->MemoServ.c_str()); } else @@ -123,16 +123,16 @@ class CommandMSSet : public Command if (!chan.empty()) { if (!p2.empty()) - ci->SetFlag(CI_MEMO_HARDMAX); + ci->ExtendMetadata("MEMO_HARDMAX"); else - ci->UnsetFlag(CI_MEMO_HARDMAX); + ci->Shrink("MEMO_HARDMAX"); } else { if (!p2.empty()) - nc->SetFlag(NI_MEMO_HARDMAX); + nc->ExtendMetadata("MEMO_HARDMAX"); else - nc->UnsetFlag(NI_MEMO_HARDMAX); + nc->Shrink("MEMO_HARDMAX"); } limit = -1; try @@ -148,12 +148,12 @@ class CommandMSSet : public Command this->OnSyntaxError(source, ""); return; } - if (!chan.empty() && ci->HasFlag(CI_MEMO_HARDMAX)) + if (!chan.empty() && ci->HasExt("MEMO_HARDMAX")) { source.Reply(_("The memo limit for %s may not be changed."), chan.c_str()); return; } - else if (chan.empty() && nc->HasFlag(NI_MEMO_HARDMAX)) + else if (chan.empty() && nc->HasExt("MEMO_HARDMAX")) { source.Reply(_("You are not permitted to change your memo limit.")); return; @@ -275,7 +275,7 @@ class CommandMSSet : public Command "change the limit (even if a previous limit was set with\n" "\002HARD\002).\n" "This use of the \002SET LIMIT\002 command is limited to \002Services\002\n" - "\002admins\002. Other users may only enter a limit for themselves\n" + "\002Admins\002. Other users may only enter a limit for themselves\n" "or a channel on which they have such privileges, may not\n" "remove their limit, may not set a limit above %d, and may\n" "not set a hard limit."), Config->MSMaxMemos); diff --git a/modules/commands/ms_staff.cpp b/modules/commands/ms_staff.cpp index a1fbdf65d..6a1263fa7 100644 --- a/modules/commands/ms_staff.cpp +++ b/modules/commands/ms_staff.cpp @@ -1,6 +1,6 @@ /* MemoServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -14,6 +14,8 @@ #include "module.h" #include "memoserv.h" +static ServiceReference<MemoServService> MemoServService("MemoServService", "MemoServ"); + class CommandMSStaff : public Command { public: diff --git a/modules/commands/ns_access.cpp b/modules/commands/ns_access.cpp index f77836909..bd26dbb2c 100644 --- a/modules/commands/ns_access.cpp +++ b/modules/commands/ns_access.cpp @@ -1,6 +1,6 @@ /* NickServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -121,7 +121,7 @@ class CommandNSAccess : public Command } else if (Config->NSSecureAdmins && source.GetAccount() != na->nc && na->nc->IsServicesOper() && !cmd.equals_ci("LIST")) { - source.Reply(_("You may view but not modify the access list of other services operators.")); + source.Reply(_("You may view but not modify the access list of other Services Operators.")); return; } @@ -135,7 +135,7 @@ class CommandNSAccess : public Command source.Reply(BAD_USERHOST_MASK); source.Reply(MORE_INFO, Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str(), this->name.c_str()); } - else if (nc->HasFlag(NI_SUSPENDED)) + else if (nc->HasExt("SUSPENDED")) source.Reply(NICK_X_SUSPENDED, nc->display.c_str()); else if (cmd.equals_ci("ADD")) return this->DoAdd(source, nc, mask); @@ -158,7 +158,7 @@ class CommandNSAccess : public Command "recognized by %s as allowed to use the nick. If\n" "you want to use the nick from a different address, you\n" "need to send an \002IDENTIFY\002 command to make %s\n" - "recognize you. Services operators may provide a nick\n" + "recognize you. Services Operators may provide a nick\n" "to modify other users' access lists.\n" " \n" "Examples:\n" diff --git a/modules/commands/ns_ajoin.cpp b/modules/commands/ns_ajoin.cpp index 3a73772c1..605fd12c1 100644 --- a/modules/commands/ns_ajoin.cpp +++ b/modules/commands/ns_ajoin.cpp @@ -1,6 +1,6 @@ /* NickServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -161,7 +161,7 @@ class CommandNSAJoin : public Command source.Reply(_("%s was not found on %s's auto join list."), chan.c_str(), nc->display.c_str()); else { - (*channels)->at(i)->Destroy(); + delete (*channels)->at(i); (*channels)->erase((*channels)->begin() + i); source.Reply(_("%s was removed from %s's auto join list."), chan.c_str(), nc->display.c_str()); } @@ -171,7 +171,9 @@ class CommandNSAJoin : public Command CommandNSAJoin(Module *creator) : Command(creator, "nickserv/ajoin", 1, 3) { this->SetDesc(_("Manage your auto join list")); - this->SetSyntax(_("{ADD | DEL | LIST} \037[user]\037 [\037channel\037] [\037key\037]")); + this->SetSyntax(_("ADD [\037user\037] \037channel\037 [\037key\037]")); + this->SetSyntax(_("DEL [\037user\037] \037channel\037")); + this->SetSyntax(_("LIST [\037user\037]")); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override @@ -216,7 +218,7 @@ class CommandNSAJoin : public Command source.Reply(" "); source.Reply(_("This command manages your auto join list. When you identify\n" "you will automatically join the channels on your auto join list.\n" - "Services operators may provide a nick to modify other users'\n" + "Services Operators may provide a nick to modify other users'\n" "auto join lists.")); return true; } @@ -268,28 +270,28 @@ class NSAJoin : public Module if (ci != NULL) { - if (ci->HasFlag(CI_SUSPENDED)) + if (ci->HasExt("SUSPENDED")) continue; } if (c != NULL) { if (c->FindUser(u) != NULL) continue; - else if (c->HasMode(CMODE_OPERONLY) && !u->HasMode(UMODE_OPER)) + else if (c->HasMode("OPERONLY") && !u->HasMode("OPER")) continue; - else if (c->HasMode(CMODE_ADMINONLY) && !u->HasMode(UMODE_ADMIN)) + else if (c->HasMode("ADMINONLY") && !u->HasMode("ADMIN")) continue; - else if (c->HasMode(CMODE_SSL) && !u->HasMode(UMODE_SSL)) + else if (c->HasMode("SSL") && !u->HasMode("SSL")) continue; - else if (c->MatchesList(u, CMODE_BAN) == true && c->MatchesList(u, CMODE_EXCEPT) == false) + else if (c->MatchesList(u, "BAN") == true && c->MatchesList(u, "EXCEPT") == false) need_invite = true; - else if (c->HasMode(CMODE_INVITE) && c->MatchesList(u, CMODE_INVITEOVERRIDE) == false) + else if (c->HasMode("INVITE") && c->MatchesList(u, "INVITEOVERRIDE") == false) need_invite = true; - if (c->HasMode(CMODE_KEY)) + if (c->HasMode("KEY")) { Anope::string k; - if (c->GetParam(CMODE_KEY, k)) + if (c->GetParam("KEY", k)) { if (ci->AccessFor(u).HasPriv("GETKEY")) key = k; @@ -297,10 +299,10 @@ class NSAJoin : public Module need_invite = true; } } - if (c->HasMode(CMODE_LIMIT)) + if (c->HasMode("LIMIT")) { Anope::string l; - if (c->GetParam(CMODE_LIMIT, l)) + if (c->GetParam("LIMIT", l)) { try { diff --git a/modules/commands/ns_alist.cpp b/modules/commands/ns_alist.cpp index 8da1b8346..c8d7eef0f 100644 --- a/modules/commands/ns_alist.cpp +++ b/modules/commands/ns_alist.cpp @@ -1,6 +1,6 @@ /* NickServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -27,7 +27,7 @@ class CommandNSAList : public Command Anope::string nick = source.GetNick(); NickCore *nc = source.nc; - if (params.size() && source.IsServicesOper()) + if (params.size() && source.HasPriv("nickserv/alist")) { nick = params[0]; const NickAlias *na = NickAlias::Find(nick); @@ -46,21 +46,40 @@ class CommandNSAList : public Command source.Reply(_("Channels that \002%s\002 has access on:"), nc->display.c_str()); - for (registered_channel_map::const_iterator it = RegisteredChannelList->begin(), it_end = RegisteredChannelList->end(); it != it_end; ++it) + std::deque<ChannelInfo *> queue; + nc->GetChannelReferences(queue); + + if (queue.empty()) + { + source.Reply(_("\2%s\2 has no access in any channels."), nc->display.c_str()); + return; + } + + for (unsigned i = 0; i < queue.size(); ++i) { - ChannelInfo *ci = it->second; + ChannelInfo *ci = queue[i]; ListFormatter::ListEntry entry; - if (ci->GetFounder() && ci->GetFounder() == nc) + if (ci->GetFounder() == nc) { ++chan_count; entry["Number"] = stringify(chan_count); - entry["Channel"] = (ci->HasFlag(CI_NO_EXPIRE) ? "!" : "") + ci->name; + entry["Channel"] = (ci->HasExt("NO_EXPIRE") ? "!" : "") + ci->name; entry["Access"] = "Founder"; list.AddEntry(entry); continue; } + if (ci->GetSuccessor() == nc) + { + ++chan_count; + entry["Number"] = stringify(chan_count); + entry["Channel"] = (ci->HasExt("NO_EXPIRE") ? "!" : "") + ci->name; + entry["Access"] = "Successor"; + list.AddEntry(entry); + continue; + } + AccessGroup access = ci->AccessFor(nc); if (access.empty()) continue; @@ -68,9 +87,9 @@ class CommandNSAList : public Command ++chan_count; entry["Number"] = stringify(chan_count); - entry["Channel"] = (ci->HasFlag(CI_NO_EXPIRE) ? "!" : "") + ci->name; - for (unsigned i = 0; i < access.size(); ++i) - entry["Access"] = entry["Access"] + ", " + access[i]->AccessSerialize(); + entry["Channel"] = (ci->HasExt("NO_EXPIRE") ? "!" : "") + ci->name; + for (unsigned j = 0; j < access.size(); ++j) + entry["Access"] = entry["Access"] + ", " + access[j]->AccessSerialize(); entry["Access"] = entry["Access"].substr(2); list.AddEntry(entry); } @@ -79,6 +98,8 @@ class CommandNSAList : public Command list.Process(replies); for (unsigned i = 0; i < replies.size(); ++i) source.Reply(replies[i]); + + source.Reply(_("End of list - %d channels shown."), chan_count); } bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override diff --git a/modules/commands/ns_cert.cpp b/modules/commands/ns_cert.cpp index 6c2100adf..bbfbdd3e8 100644 --- a/modules/commands/ns_cert.cpp +++ b/modules/commands/ns_cert.cpp @@ -1,6 +1,6 @@ /* NickServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -24,7 +24,7 @@ class CommandNSCert : public Command return; } - if (nc->HasFlag(NI_SUSPENDED)) + if (nc->HasExt("SUSPENDED")) { source.Reply(NICK_X_SUSPENDED, nc->display.c_str()); return; @@ -157,7 +157,7 @@ class CommandNSCert : public Command NickCore *nc = source.nc; - if (source.nc->HasFlag(NI_SUSPENDED)) + if (source.nc->HasExt("SUSPENDED")) source.Reply(NICK_X_SUSPENDED, source.nc->display.c_str()); else if (cmd.equals_ci("ADD")) return this->DoAdd(source, nc, mask); @@ -207,7 +207,7 @@ class NSCert : public Module return; if (u->IsIdentified() && u->Account() == na->nc) return; - if (na->nc->HasFlag(NI_SUSPENDED)) + if (na->nc->HasExt("SUSPENDED")) return; if (!na->nc->FindCert(u->fingerprint)) return; diff --git a/modules/commands/ns_drop.cpp b/modules/commands/ns_drop.cpp index efd95cf1c..a94feefdb 100644 --- a/modules/commands/ns_drop.cpp +++ b/modules/commands/ns_drop.cpp @@ -1,6 +1,6 @@ /* NickServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -46,7 +46,7 @@ class CommandNSDrop : public Command if (!is_mine && !source.HasPriv("nickserv/drop")) source.Reply(ACCESS_DENIED); else if (Config->NSSecureAdmins && !is_mine && na->nc->IsServicesOper()) - source.Reply(_("You may not drop other services operators nicknames.")); + source.Reply(_("You may not drop other Services Operators' nicknames.")); else { if (Anope::ReadOnly) @@ -55,7 +55,7 @@ class CommandNSDrop : public Command FOREACH_MOD(I_OnNickDrop, OnNickDrop(source, na)); Log(!is_mine ? LOG_OVERRIDE : LOG_COMMAND, source, this) << "to drop nickname " << na->nick << " (group: " << na->nc->display << ") (email: " << (!na->nc->email.empty() ? na->nc->email : "none") << ")"; - na->Destroy(); + delete na; if (!is_mine) { @@ -81,13 +81,13 @@ class CommandNSDrop : public Command "Without a parameter, deletes your nickname.\n" " \n" "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" + "You may drop any nick within your group without any\n" + "special privileges. Dropping any nick is limited to\n" "\002Services Operators\002."), source.command.c_str()); else source.Reply(_("Syntax: \002%s [\037nickname\037 | \037password\037]\002\n" " \n" - "Deltes your nickname. A nick\n" + "Deletes your nickname. A nick\n" "that has been dropped is free for anyone to re-register.\n" " \n" "You may drop a nick within your group by passing it\n" diff --git a/modules/commands/ns_getemail.cpp b/modules/commands/ns_getemail.cpp index a21c8c1b5..7728f3178 100644 --- a/modules/commands/ns_getemail.cpp +++ b/modules/commands/ns_getemail.cpp @@ -1,6 +1,6 @@ /* NickServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -23,7 +23,7 @@ class CommandNSGetEMail : public Command CommandNSGetEMail(Module *creator) : Command(creator, "nickserv/getemail", 1, 1) { this->SetDesc(_("Matches and returns all users that registered using given email")); - this->SetSyntax(_("\037user@email-host\037")); + this->SetSyntax(_("\037email\037")); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override @@ -40,13 +40,13 @@ class CommandNSGetEMail : public Command if (!nc->email.empty() && nc->email.equals_ci(email)) { ++j; - source.Reply(_("Emails Match \002%s\002 to \002%s\002."), nc->display.c_str(), email.c_str()); + source.Reply(_("Email matched: \002%s\002 to \002%s\002."), nc->display.c_str(), email.c_str()); } } if (j <= 0) { - source.Reply(_("No Emails listed for \002%s\002."), email.c_str()); + source.Reply(_("No nick registrations matching \002%s\002 found."), email.c_str()); return; } @@ -58,9 +58,9 @@ class CommandNSGetEMail : public Command this->SendSyntax(source); source.Reply(" "); source.Reply(_("Returns the matching nicks that used given email. \002Note\002 that\n" - "you can not use wildcards for either user or emailhost. Whenever\n" - "this command is used, a message including the person who issued\n" - "the command and the email it was used on will be logged.")); + "you can not use wildcards. Whenever this command is used, a message\n" + "including the person who issued the command and the email it was used\n" + "on will be logged.")); return true; } }; diff --git a/modules/commands/ns_getpass.cpp b/modules/commands/ns_getpass.cpp index 998316f5b..987e98827 100644 --- a/modules/commands/ns_getpass.cpp +++ b/modules/commands/ns_getpass.cpp @@ -1,6 +1,6 @@ /* NickServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -31,7 +31,7 @@ class CommandNSGetPass : public Command if (!(na = NickAlias::Find(nick))) source.Reply(NICK_X_NOT_REGISTERED, nick.c_str()); else if (Config->NSSecureAdmins && na->nc->IsServicesOper()) - source.Reply(_("You may not get the password of other services operators.")); + source.Reply(_("You may not get the password of other Services Operators.")); else { if (Anope::Decrypt(na->nc->pass, tmp_pass) == 1) diff --git a/modules/commands/ns_group.cpp b/modules/commands/ns_group.cpp index ff4d5029e..b8191046a 100644 --- a/modules/commands/ns_group.cpp +++ b/modules/commands/ns_group.cpp @@ -1,6 +1,6 @@ /* NickServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -34,7 +34,7 @@ class NSGroupRequest : public IdentifyRequest if (na) { FOREACH_MOD(I_OnChangeCoreDisplay, OnChangeCoreDisplay(na->nc, u->nick)); - na->Destroy(); + delete na; } na = new NickAlias(nick, target->nc); @@ -46,8 +46,8 @@ class NSGroupRequest : public IdentifyRequest u->Login(target->nc); IRCD->SendLogin(u); - if (!Config->NoNicknameOwnership && na->nc == u->Account() && na->nc->HasFlag(NI_UNCONFIRMED) == false) - u->SetMode(NickServ, UMODE_REGISTERED); + if (!Config->NoNicknameOwnership && na->nc == u->Account() && na->nc->HasExt("UNCONFIRMED") == false) + u->SetMode(NickServ, "REGISTERED"); FOREACH_MOD(I_OnNickGroup, OnNickGroup(u, target)); Log(LOG_COMMAND, source, cmd) << "makes " << nick << " join group of " << target->nick << " (" << target->nc->display << ") (email: " << (!target->nc->email.empty() ? target->nc->email : "none") << ")"; @@ -78,18 +78,15 @@ class CommandNSGroup : public Command public: CommandNSGroup(Module *creator) : Command(creator, "nickserv/group", 1, 2) { - this->SetFlag(CFLAG_ALLOW_UNREGISTERED); this->SetDesc(_("Join a group")); this->SetSyntax(_("\037target\037 \037password\037")); + this->AllowUnregistered(true); + this->RequireUser(true); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { User *u = source.GetUser(); - - if (!u) - return; - const Anope::string &nick = params[0]; const Anope::string &pass = params.size() > 1 ? params[1] : ""; @@ -110,7 +107,7 @@ class CommandNSGroup : public Command { Oper *o = Config->Opers[i]; - if (!u->HasMode(UMODE_OPER) && u->nick.find_ci(o->name) != Anope::string::npos) + if (!u->HasMode("OPER") && u->nick.find_ci(o->name) != Anope::string::npos) { source.Reply(NICK_CANNOT_BE_REGISTERED, u->nick.c_str()); return; @@ -122,7 +119,7 @@ class CommandNSGroup : public Command source.Reply(NICK_X_NOT_REGISTERED, nick.c_str()); else if (Anope::CurTime < u->lastnickreg + Config->NSRegDelay) source.Reply(_("Please wait %d seconds before using the GROUP command again."), (Config->NSRegDelay + u->lastnickreg) - Anope::CurTime); - else if (target->nc->HasFlag(NI_SUSPENDED)) + else if (target->nc->HasExt("SUSPENDED")) { Log(LOG_COMMAND, source, this) << "tried to use GROUP for SUSPENDED nick " << target->nick; source.Reply(NICK_X_SUSPENDED, target->nick.c_str()); @@ -133,7 +130,7 @@ class CommandNSGroup : public Command source.Reply(NICK_IDENTIFY_REQUIRED, Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str()); else if (na && Config->NSNoGroupChange) source.Reply(_("Your nick is already registered.")); - else if (Config->NSMaxAliases && (target->nc->aliases.size() >= Config->NSMaxAliases) && !target->nc->IsServicesOper()) + else if (Config->NSMaxAliases && (target->nc->aliases->size() >= Config->NSMaxAliases) && !target->nc->IsServicesOper()) source.Reply(_("There are too many nicks in %s's group.")); else if (u->nick.length() <= Config->NSGuestNickPrefix.length() + 7 && u->nick.length() >= Config->NSGuestNickPrefix.length() + 1 && @@ -171,7 +168,7 @@ class CommandNSGroup : public Command { this->SendSyntax(source); source.Reply(" "); - source.Reply(_("This command makes your nickname join the \037target\037 nickname's \n" + source.Reply(_("This command makes your nickname join the \037target\037 nickname's\n" "group. \037password\037 is the password of the target nickname.\n" " \n" "Joining a group will allow you to share your configuration,\n" @@ -188,9 +185,9 @@ class CommandNSGroup : public Command "need to identify yourself before using this command.\n" " \n" "It is recommended to use this command with a non-registered\n" - "nick because it will be registered automatically when \n" - "using this command. You may use it with a registered nick (to \n" - "change your group) only if your network administrators allowed \n" + "nick because it will be registered automatically when\n" + "using this command. You may use it with a registered nick (to\n" + "change your group) only if your network administrators allowed\n" "it.\n" " \n" "You can only be in one group at a time. Group merging is\n" @@ -208,37 +205,35 @@ class CommandNSUngroup : public Command { this->SetDesc(_("Remove a nick from a group")); this->SetSyntax(_("[\037nick\037]")); + this->RequireUser(true); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { User *u = source.GetUser(); - if (!u) - return; - Anope::string nick = !params.empty() ? params[0] : ""; NickAlias *na = NickAlias::Find(!nick.empty() ? nick : u->nick); - if (u->Account()->aliases.size() == 1) + if (u->Account()->aliases->size() == 1) source.Reply(_("Your nick is not grouped to anything, you can't ungroup it.")); else if (!na) source.Reply(NICK_X_NOT_REGISTERED, !nick.empty() ? nick.c_str() : u->nick.c_str()); else if (na->nc != u->Account()) - source.Reply(_("The nick %s is not in your group."), na->nick.c_str()); + source.Reply(_("Nick %s is not in your group."), na->nick.c_str()); else { NickCore *oldcore = na->nc; - std::list<Serialize::Reference<NickAlias> >::iterator it = std::find(oldcore->aliases.begin(), oldcore->aliases.end(), na); - if (it != oldcore->aliases.end()) - oldcore->aliases.erase(it); + std::vector<NickAlias *>::iterator it = std::find(oldcore->aliases->begin(), oldcore->aliases->end(), na); + if (it != oldcore->aliases->end()) + oldcore->aliases->erase(it); if (na->nick.equals_ci(oldcore->display)) - oldcore->SetDisplay(oldcore->aliases.front()); + oldcore->SetDisplay(oldcore->aliases->front()); NickCore *nc = new NickCore(na->nick); na->nc = nc; - nc->aliases.push_back(na); + nc->aliases->push_back(na); nc->pass = oldcore->pass; if (!oldcore->email.empty()) @@ -252,7 +247,7 @@ class CommandNSUngroup : public Command User *user = User::Find(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, "REGISTERED"); } return; @@ -264,9 +259,9 @@ class CommandNSUngroup : public Command source.Reply(" "); source.Reply(_("This command ungroups your nick, or if given, the specificed nick,\n" "from the group it is in. The ungrouped nick keeps its registration\n" - "time, password, email, greet, language, url, and icq. Everything\n" - "else is reset. You may not ungroup yourself if there is only one\n" - "nick in your group.")); + "time, password, email, greet, language, and url. Everything else\n" + "is reset. You may not ungroup yourself if there is only one nick in\n" + "your group.")); return true; } }; @@ -305,15 +300,13 @@ class CommandNSGList : public Command ListFormatter list; list.AddColumn("Nick").AddColumn("Expires"); - for (std::list<Serialize::Reference<NickAlias> >::const_iterator it = nc->aliases.begin(), it_end = nc->aliases.end(); it != it_end;) + for (unsigned i = 0; i < nc->aliases->size(); ++i) { - const NickAlias *na2 = *it++; - if (!na2) - continue; + const NickAlias *na2 = nc->aliases->at(i); ListFormatter::ListEntry entry; entry["Nick"] = na2->nick; - entry["Expires"] = (na2->HasFlag(NS_NO_EXPIRE) || !Config->NSExpire) ? "Does not expire" : ("expires in " + Anope::strftime(na2->last_seen + Config->NSExpire)); + entry["Expires"] = (na2->HasExt("NO_EXPIRE") || !Config->NSExpire) ? "Does not expire" : ("expires in " + Anope::strftime(na2->last_seen + Config->NSExpire)); list.AddEntry(entry); } @@ -324,7 +317,7 @@ class CommandNSGList : public Command for (unsigned i = 0; i < replies.size(); ++i) source.Reply(replies[i]); - source.Reply(_("%d nicknames in the group."), nc->aliases.size()); + source.Reply(_("%d nicknames in the group."), nc->aliases->size()); } bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override @@ -337,7 +330,7 @@ class CommandNSGList : public Command " \n" "With a parameter, lists all nicknames that are in the\n" "group of the given nick.\n" - "This use limited to \002Services Operators\002."), + "Specifying a nick is limited to \002Services Operators\002."), source.command.c_str()); else source.Reply(_("Syntax: \002%s\002\n" diff --git a/modules/commands/ns_identify.cpp b/modules/commands/ns_identify.cpp index f1e0a7d3d..adbe97de5 100644 --- a/modules/commands/ns_identify.cpp +++ b/modules/commands/ns_identify.cpp @@ -1,6 +1,6 @@ /* NickServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -64,30 +64,28 @@ class CommandNSIdentify : public Command public: CommandNSIdentify(Module *creator) : Command(creator, "nickserv/identify", 1, 2) { - this->SetFlag(CFLAG_ALLOW_UNREGISTERED); this->SetDesc(_("Identify yourself with your password")); this->SetSyntax(_("[\037account\037] \037password\037")); + this->AllowUnregistered(true); + this->RequireUser(true); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { User *u = source.GetUser(); - if (!u) - return; - const Anope::string &nick = params.size() == 2 ? params[0] : u->nick; Anope::string pass = params[params.size() - 1]; NickAlias *na = NickAlias::Find(nick); - if (na && na->nc->HasFlag(NI_SUSPENDED)) + if (na && na->nc->HasExt("SUSPENDED")) source.Reply(NICK_X_SUSPENDED, na->nick.c_str()); else if (u->Account() && na && u->Account() == na->nc) source.Reply(_("You are already identified.")); else { NSIdentifyRequest *req = new NSIdentifyRequest(owner, source, this, na ? na->nc->display : nick, pass); - FOREACH_MOD(I_OnCheckAuthentication, OnCheckAuthentication(source.GetUser(), req)); + FOREACH_MOD(I_OnCheckAuthentication, OnCheckAuthentication(u, req)); req->Dispatch(); } return; diff --git a/modules/commands/ns_info.cpp b/modules/commands/ns_info.cpp index 976589718..fddb9c5ad 100644 --- a/modules/commands/ns_info.cpp +++ b/modules/commands/ns_info.cpp @@ -1,6 +1,6 @@ /* NickServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -16,9 +16,9 @@ class CommandNSInfo : public Command { private: - template<typename T> void CheckOptStr(NickCore *core, Anope::string &buf, T opt, const char *str, const Flags<T> *nc, bool reverse_logic = false) + void CheckOptStr(NickCore *core, Anope::string &buf, const Anope::string &opt, const char *str, const Extensible *e, bool reverse_logic = false) { - if (reverse_logic ? !nc->HasFlag(opt) : nc->HasFlag(opt)) + if (reverse_logic != e->HasExt(opt)) { if (!buf.empty()) buf += ", "; @@ -29,9 +29,9 @@ class CommandNSInfo : public Command public: CommandNSInfo(Module *creator) : Command(creator, "nickserv/info", 0, 2) { - this->SetFlag(CFLAG_ALLOW_UNREGISTERED); this->SetDesc(_("Displays information about a given nickname")); this->SetSyntax(_("[\037nickname\037]")); + this->AllowUnregistered(true); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override @@ -62,11 +62,11 @@ class CommandNSInfo : public Command source.Reply(_("%s is %s"), na->nick.c_str(), na->last_realname.c_str()); - if (na->nc->HasFlag(NI_UNCONFIRMED)) - source.Reply(_("%s nickname is unconfirmed."), na->nick.c_str()); + if (na->nc->HasExt("UNCONFIRMED")) + source.Reply(_("%s is an unconfirmed nickname."), na->nick.c_str()); - if (na->nc->IsServicesOper() && (show_hidden || !na->nc->HasFlag(NI_HIDE_STATUS))) - source.Reply(_("%s is a services operator of type %s."), na->nick.c_str(), na->nc->o->ot->GetName().c_str()); + if (na->nc->IsServicesOper() && (show_hidden || !na->nc->HasExt("HIDE_STATUS"))) + source.Reply(_("%s is a Services Operator of type %s."), na->nick.c_str(), na->nc->o->ot->GetName().c_str()); InfoFormatter info(source.nc); @@ -74,14 +74,14 @@ class CommandNSInfo : public Command { if (show_hidden && !na->last_realhost.empty()) info[_("Online from")] = na->last_realhost; - if (show_hidden || !na->nc->HasFlag(NI_HIDE_MASK)) + if (show_hidden || !na->nc->HasExt("HIDE_MASK")) info[_("Online from")] = na->last_usermask; else source.Reply(_("%s is currently online."), na->nick.c_str()); } else { - if (show_hidden || !na->nc->HasFlag(NI_HIDE_MASK)) + if (show_hidden || !na->nc->HasExt("HIDE_MASK")) info[_("Last seen address")] = na->last_usermask; if (show_hidden && !na->last_realhost.empty()) info[_("Last seen address")] = na->last_realhost; @@ -92,10 +92,10 @@ class CommandNSInfo : public Command if (!nick_online) info[_("Last seen")] = Anope::strftime(na->last_seen); - if (!na->last_quit.empty() && (show_hidden || !na->nc->HasFlag(NI_HIDE_QUIT))) + if (!na->last_quit.empty() && (show_hidden || !na->nc->HasExt("HIDE_QUIT"))) info[_("Last quit message")] = na->last_quit; - if (!na->nc->email.empty() && (show_hidden || !na->nc->HasFlag(NI_HIDE_EMAIL))) + if (!na->nc->email.empty() && (show_hidden || !na->nc->HasExt("HIDE_EMAIL"))) info[_("Email address")] = na->nc->email; if (show_hidden) @@ -113,20 +113,20 @@ class CommandNSInfo : public Command Anope::string optbuf; - CheckOptStr<NickCoreFlag>(source.nc, optbuf, NI_KILLPROTECT, _("Protection"), na->nc); - CheckOptStr<NickCoreFlag>(source.nc, optbuf, NI_SECURE, _("Security"), na->nc); - CheckOptStr<NickCoreFlag>(source.nc, optbuf, NI_PRIVATE, _("Private"), na->nc); - CheckOptStr<NickCoreFlag>(source.nc, optbuf, NI_MSG, _("Message mode"), na->nc); - CheckOptStr<NickCoreFlag>(source.nc, optbuf, NI_AUTOOP, _("Auto-op"), na->nc); - CheckOptStr<NickCoreFlag>(source.nc, optbuf, NI_SUSPENDED, _("Suspended"), na->nc); - CheckOptStr<NickCoreFlag>(source.nc, optbuf, NI_STATS, _("Chanstats"), na->nc); - CheckOptStr<NickNameFlag>(source.nc, optbuf, NS_NO_EXPIRE, _("No expire"), na); + CheckOptStr(source.nc, optbuf, "KILLPROTECT", _("Protection"), na->nc); + CheckOptStr(source.nc, optbuf, "SECURE", _("Security"), na->nc); + CheckOptStr(source.nc, optbuf, "PRIVATE", _("Private"), na->nc); + CheckOptStr(source.nc, optbuf, "MSG", _("Message mode"), na->nc); + CheckOptStr(source.nc, optbuf, "AUTOOP", _("Auto-op"), na->nc); + CheckOptStr(source.nc, optbuf, "SUSPENDED", _("Suspended"), na->nc); + CheckOptStr(source.nc, optbuf, "STATS", _("Chanstats"), na->nc); + CheckOptStr(source.nc, optbuf, "NO_EXPIRE", _("No expire"), na); info[_("Options")] = optbuf.empty() ? _("None") : optbuf; - if (na->nc->HasFlag(NI_UNCONFIRMED) == false) + if (na->nc->HasExt("UNCONFIRMED") == false) { - if (na->HasFlag(NS_NO_EXPIRE) || !Config->NSExpire) + if (na->HasExt("NO_EXPIRE") || !Config->NSExpire) ; else info[_("Expires")] = Anope::strftime(na->last_seen + Config->NSExpire); diff --git a/modules/commands/ns_list.cpp b/modules/commands/ns_list.cpp index 9c3c164dd..b96b21412 100644 --- a/modules/commands/ns_list.cpp +++ b/modules/commands/ns_list.cpp @@ -1,6 +1,6 @@ /* NickServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -75,18 +75,22 @@ class CommandNSList : public Command list.AddColumn("Nick").AddColumn("Last usermask"); + Anope::map<NickAlias *> ordered_map; for (nickalias_map::const_iterator it = NickAliasList->begin(), it_end = NickAliasList->end(); it != it_end; ++it) + ordered_map[it->first] = it->second; + + for (Anope::map<NickAlias *>::const_iterator it = ordered_map.begin(), it_end = ordered_map.end(); it != it_end; ++it) { const NickAlias *na = it->second; /* Don't show private nicks to non-services admins. */ - if (na->nc->HasFlag(NI_PRIVATE) && !is_servadmin && na->nc != mync) + if (na->nc->HasExt("PRIVATE") && !is_servadmin && na->nc != mync) continue; - else if (nsnoexpire && !na->HasFlag(NS_NO_EXPIRE)) + else if (nsnoexpire && !na->HasExt("NO_EXPIRE")) continue; - else if (suspended && !na->nc->HasFlag(NI_SUSPENDED)) + else if (suspended && !na->nc->HasExt("SUSPENDED")) continue; - else if (unconfirmed && !na->nc->HasFlag(NI_UNCONFIRMED)) + else if (unconfirmed && !na->nc->HasExt("UNCONFIRMED")) continue; /* We no longer compare the pattern against the output buffer. @@ -98,16 +102,16 @@ class CommandNSList : public Command if (((count + 1 >= from && count + 1 <= to) || (!from && !to)) && ++nnicks <= Config->NSListMax) { bool isnoexpire = false; - if (is_servadmin && na->HasFlag(NS_NO_EXPIRE)) + if (is_servadmin && na->HasExt("NO_EXPIRE")) isnoexpire = true; ListFormatter::ListEntry entry; entry["Nick"] = (isnoexpire ? "!" : "") + na->nick; - if (na->nc->HasFlag(NI_HIDE_MASK) && !is_servadmin && na->nc != mync) + if (na->nc->HasExt("HIDE_MASK") && !is_servadmin && na->nc != mync) entry["Last usermask"] = "[Hostname hidden]"; - else if (na->nc->HasFlag(NI_SUSPENDED)) + else if (na->nc->HasExt("SUSPENDED")) entry["Last usermask"] = "[Suspended]"; - else if (na->nc->HasFlag(NI_UNCONFIRMED)) + else if (na->nc->HasExt("UNCONFIRMED")) entry["Last usermask"] = "[Unconfirmed]"; else entry["Last usermask"] = na->last_usermask; @@ -160,11 +164,14 @@ class CommandNSList : public Command " Lists all registered nicks which have been set to not expire.\n" " \n" " \002LIST #51-100\002\n" - " Lists all registered nicks within the given range (51-100).\n")); + " Lists all registered nicks within the given range (51-100).")); + if (!Config->RegexEngine.empty()) - source.Reply(" \n" - "Regex matches are also supported using the %s engine.\n" - "Enclose your pattern in // if this desired.", Config->RegexEngine.c_str()); + { + source.Reply(" "); + source.Reply(_("Regex matches are also supported using the %s engine.\n" + "Enclose your pattern in // if this is desired."), Config->RegexEngine.c_str()); + } return true; } diff --git a/modules/commands/ns_logout.cpp b/modules/commands/ns_logout.cpp index 5519e6ae8..1147b390f 100644 --- a/modules/commands/ns_logout.cpp +++ b/modules/commands/ns_logout.cpp @@ -1,6 +1,6 @@ /* NickServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -14,6 +14,8 @@ #include "module.h" #include "nickserv.h" +static ServiceReference<NickServService> NickServService("NickServService", "NickServ"); + class CommandNSLogout : public Command { public: @@ -35,7 +37,7 @@ class CommandNSLogout : public Command else if (!(u2 = (!nick.empty() ? User::Find(nick, true) : source.GetUser()))) source.Reply(NICK_X_NOT_IN_USE, !nick.empty() ? nick.c_str() : source.GetNick().c_str()); else if (!nick.empty() && u2->IsServicesOper()) - source.Reply(_("You can't logout %s because they are a Services Operator."), nick.c_str()); + source.Reply(_("You can't logout %s, they are a Services Operator."), nick.c_str()); else { if (!nick.empty() && !param.empty() && param.equals_ci("REVALIDATE") && NickServService) @@ -51,7 +53,7 @@ class CommandNSLogout : public Command source.Reply(_("Your nick has been logged out.")); IRCD->SendLogout(u2); - u2->RemoveMode(NickServ, UMODE_REGISTERED); + u2->RemoveMode(NickServ, "REGISTERED"); u2->Logout(); /* Send out an event */ @@ -64,14 +66,14 @@ class CommandNSLogout : public Command { this->SendSyntax(source); source.Reply(" "); - source.Reply(_("Without a parameter, reverses the effect of the \002IDENTIFY\002 \n" + source.Reply(_("Without a parameter, reverses the effect of the \002IDENTIFY\002\n" "command, i.e. make you not recognized as the real owner of the nick\n" "anymore. Note, however, that you won't be asked to reidentify\n" "yourself.\n" " \n" - "With a parameter, does the same for the given nick. If you \n" - "specify REVALIDATE as well, Services will ask the given nick\n" - "to re-identify. This use limited to \002Services Operators\002.")); + "With a parameter, does the same for the given nick. If you\n" + "specify \002REVALIDATE\002 as well, Services will ask the given nick\n" + "to re-identify. This is limited to \002Services Operators\002.")); return true; } diff --git a/modules/commands/ns_recover.cpp b/modules/commands/ns_recover.cpp index ed258c4e4..33a97646c 100644 --- a/modules/commands/ns_recover.cpp +++ b/modules/commands/ns_recover.cpp @@ -1,6 +1,6 @@ /* NickServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -37,7 +37,7 @@ class NSRecoverRequest : public IdentifyRequest Log(LOG_COMMAND, source, cmd) << "for " << na->nick; /* Nick is being held by us, release it */ - if (na->HasFlag(NS_HELD)) + if (na->HasExt("HELD")) { na->Release(); source.Reply(_("Service's hold on \002%s\002 has been released."), na->nick.c_str()); @@ -50,7 +50,7 @@ class NSRecoverRequest : public IdentifyRequest // same person that is executing the command, so kill them off (old GHOST command). else if (u->Account() == na->nc) { - if (!source.GetAccount() && na->nc->HasFlag(NI_SECURE)) + if (!source.GetAccount() && na->nc->HasExt("SECURE")) { source.GetUser()->Login(u->Account()); Log(LOG_COMMAND, source, cmd) << "and was automatically identified to " << u->Account()->display; @@ -61,8 +61,8 @@ class NSRecoverRequest : public IdentifyRequest if (!u->chans.empty()) { NSRecoverExtensibleInfo *ei = new NSRecoverExtensibleInfo; - for (UChannelList::iterator it = u->chans.begin(), it_end = u->chans.end(); it != it_end; ++it) - (*ei)[(*it)->chan->name] = *(*it)->status; + for (User::ChanUserList::iterator it = u->chans.begin(), it_end = u->chans.end(); it != it_end; ++it) + (*ei)[(*it)->chan->name] = (*it)->status; source.GetUser()->Extend("ns_recover_info", ei); } @@ -83,7 +83,7 @@ class NSRecoverRequest : public IdentifyRequest /* User is not identified or not identified to the same account as the person using this command */ else { - if (!source.GetAccount() && na->nc->HasFlag(NI_SECURE)) + if (!source.GetAccount() && na->nc->HasExt("SECURE")) { source.GetUser()->Login(na->nc); // Identify the user using the command if they arent identified Log(LOG_COMMAND, source, cmd) << "and was automatically identified to " << na->nick << " (" << na->nc->display << ")"; @@ -126,9 +126,9 @@ class CommandNSRecover : public Command public: CommandNSRecover(Module *creator) : Command(creator, "nickserv/recover", 1, 2) { - this->SetFlag(CFLAG_ALLOW_UNREGISTERED); this->SetDesc(_("Regains control of your nick")); this->SetSyntax("\037nickname\037 [\037password\037]"); + this->AllowUnregistered(true); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override @@ -151,7 +151,7 @@ class CommandNSRecover : public Command source.Reply(NICK_X_NOT_REGISTERED, nick.c_str()); return; } - else if (na->nc->HasFlag(NI_SUSPENDED)) + else if (na->nc->HasExt("SUSPENDED")) { source.Reply(NICK_X_SUSPENDED, na->nick.c_str()); return; @@ -160,7 +160,7 @@ class CommandNSRecover : public Command bool ok = false; if (source.GetAccount() == na->nc) ok = true; - else if (!na->nc->HasFlag(NI_SECURE) && source.GetUser() && na->nc->IsOnAccess(source.GetUser())) + else if (!na->nc->HasExt("SECURE") && source.GetUser() && na->nc->IsOnAccess(source.GetUser())) ok = true; else if (source.GetUser() && !source.GetUser()->fingerprint.empty() && na->nc->FindCert(source.GetUser()->fingerprint)) ok = true; @@ -265,9 +265,8 @@ class NSRecover : public Module std::map<Anope::string, ChannelStatus>::iterator it = ei->find(c->name); if (it != ei->end()) { - for (size_t j = CMODE_BEGIN + 1; j < CMODE_END; ++j) - if (it->second.HasFlag(static_cast<ChannelModeName>(j))) - c->SetMode(c->ci->WhoSends(), ModeManager::FindChannelModeByName(static_cast<ChannelModeName>(j)), u->GetUID()); + for (std::set<Anope::string>::iterator it2 = it->second.modes.begin(), it2_end = it->second.modes.end(); it2 != it2_end; ++it2) + c->SetMode(c->ci->WhoSends(), ModeManager::FindChannelModeByName(*it2), u->GetUID()); ei->erase(it); if (ei->empty()) diff --git a/modules/commands/ns_register.cpp b/modules/commands/ns_register.cpp index d16144a18..c224f8acf 100644 --- a/modules/commands/ns_register.cpp +++ b/modules/commands/ns_register.cpp @@ -1,6 +1,6 @@ /* NickServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -20,25 +20,25 @@ class CommandNSConfirm : public Command public: CommandNSConfirm(Module *creator) : Command(creator, "nickserv/confirm", 1, 2) { - this->SetFlag(CFLAG_ALLOW_UNREGISTERED); - this->SetDesc(_("Confirm an auth code")); + this->SetDesc(_("Confirm a passcode")); this->SetSyntax(_("\037passcode\037")); + this->AllowUnregistered(true); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { const Anope::string &passcode = params[0]; - if (source.nc && !source.nc->HasFlag(NI_UNCONFIRMED) && source.HasPriv("nickserv/confirm")) + if (source.nc && !source.nc->HasExt("UNCONFIRMED") && source.HasPriv("nickserv/confirm")) { NickAlias *na = NickAlias::Find(passcode); if (na == NULL) source.Reply(NICK_X_NOT_REGISTERED, passcode.c_str()); - else if (na->nc->HasFlag(NI_UNCONFIRMED) == false) + else if (na->nc->HasExt("UNCONFIRMED") == false) source.Reply(_("Nick \002%s\002 is already confirmed."), na->nick.c_str()); else { - na->nc->UnsetFlag(NI_UNCONFIRMED); + na->nc->Shrink("UNCONFIRMED"); Log(LOG_ADMIN, source, this) << "to confirm nick " << na->nick << " (" << na->nc->display << ")"; source.Reply(_("Nick \002%s\002 has been confirmed."), na->nick.c_str()); } @@ -52,14 +52,14 @@ class CommandNSConfirm : public Command nc->Shrink("ns_register_passcode"); Log(LOG_COMMAND, source, this) << "to confirm their email"; source.Reply(_("Your email address of \002%s\002 has been confirmed."), source.nc->email.c_str()); - nc->UnsetFlag(NI_UNCONFIRMED); + nc->Shrink("UNCONFIRMED"); if (source.GetUser()) { IRCD->SendLogin(source.GetUser()); const NickAlias *na = NickAlias::Find(source.GetNick()); - if (!Config->NoNicknameOwnership && na != NULL && na->nc == source.GetAccount() && na->nc->HasFlag(NI_UNCONFIRMED) == false) - source.GetUser()->SetMode(NickServ, UMODE_REGISTERED); + if (!Config->NoNicknameOwnership && na != NULL && na->nc == source.GetAccount() && na->nc->HasExt("UNCONFIRMED") == false) + source.GetUser()->SetMode(NickServ, "REGISTERED"); } } else @@ -100,12 +100,12 @@ class CommandNSRegister : public Command public: CommandNSRegister(Module *creator) : Command(creator, "nickserv/register", 1, 2) { - this->SetFlag(CFLAG_ALLOW_UNREGISTERED); this->SetDesc(_("Register a nickname")); if (Config->NSForceEmail) this->SetSyntax(_("\037password\037 \037email\037")); else this->SetSyntax(_("\037password\037 \037[email]\037")); + this->AllowUnregistered(true); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override @@ -130,7 +130,7 @@ class CommandNSRegister : public Command return; } - if (u && !u->HasMode(UMODE_OPER) && Config->NickRegDelay && Anope::CurTime - u->timestamp < Config->NickRegDelay) + if (u && !u->HasMode("OPER") && Config->NickRegDelay && Anope::CurTime - u->timestamp < Config->NickRegDelay) { source.Reply(_("You must have been using this nick for at least %d seconds to register."), Config->NickRegDelay); return; @@ -201,7 +201,7 @@ class CommandNSRegister : public Command FOREACH_MOD(I_OnNickRegister, OnNickRegister(na)); if (Config->NSAddAccessOnReg) - source.Reply(_("Nickname \002%s\002 registered under your account: %s"), u_nick.c_str(), na->nc->GetAccess(0).c_str()); + source.Reply(_("Nickname \002%s\002 registered under your user@host-mask: %s"), u_nick.c_str(), na->nc->GetAccess(0).c_str()); else source.Reply(_("Nickname \002%s\002 registered."), u_nick.c_str()); @@ -211,15 +211,15 @@ class CommandNSRegister : public Command if (Config->NSRegistration.equals_ci("admin")) { - nc->SetFlag(NI_UNCONFIRMED); + nc->ExtendMetadata("UNCONFIRMED"); source.Reply(_("All new accounts must be validated by an administrator. Please wait for your registration to be confirmed.")); } else if (Config->NSRegistration.equals_ci("mail")) { - nc->SetFlag(NI_UNCONFIRMED); + nc->ExtendMetadata("UNCONFIRMED"); if (SendRegmail(u, na, source.service)) { - 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->NickServ.c_str()); + source.Reply(_("A passcode has been sent to %s, please type \002%s%s CONFIRM <passcode>\002 to confirm your email address."), email.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str()); source.Reply(_("If you do not confirm your email address within %s your account will expire."), Anope::Duration(Config->NSUnconfirmedExpire).c_str()); } } @@ -228,8 +228,8 @@ class CommandNSRegister : public Command if (u) { IRCD->SendLogin(u); - if (!Config->NoNicknameOwnership && na->nc == u->Account() && na->nc->HasFlag(NI_UNCONFIRMED) == false) - u->SetMode(NickServ, UMODE_REGISTERED); + if (!Config->NoNicknameOwnership && na->nc == u->Account() && na->nc->HasExt("UNCONFIRMED") == false) + u->SetMode(NickServ, "REGISTERED"); } } @@ -241,13 +241,13 @@ class CommandNSRegister : public Command bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override { this->SendSyntax(source); - source.Reply("\n"); + source.Reply(" "); source.Reply(_("Registers your nickname in the %s database. Once\n" "your nick is registered, you can use the \002SET\002 and \002ACCESS\002\n" "commands to configure your nick's settings as you like\n" "them. Make sure you remember the password you use when\n" "registering - you'll need it to make changes to your nick\n" - "later. (Note that \002case matters!\002 \037ANOPE\037, \037Anope\037, and \n" + "later. (Note that \002case matters!\002 \037ANOPE\037, \037Anope\037, and\n" "\037anope\037 are all different passwords!)\n" " \n" "Guidelines on choosing passwords:\n" @@ -258,17 +258,20 @@ class CommandNSRegister : public Command "in fact, %s will not allow it. Also, short\n" "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"), + "Finally, the space character cannot be used in passwords."), Config->NickServ.c_str(), Config->NickServ.c_str()); if (!Config->NSForceEmail) - source.Reply(_(" \n" - "The parameter \037email\037 is optional and will set the email\n" + { + source.Reply(" "); + source.Reply(_("The \037email\037 parameter is optional and will set the email\n" "for your nick immediately.\n" "Your privacy is respected; this e-mail won't be given to\n" - "any third-party person.\n" - " \n")); + "any third-party person. You may also wish to \002SET HIDE\002 it\n" + "after registering if it isn't the default setting already.")); + } + source.Reply(" "); source.Reply(_("This command also creates a new group for your nickname,\n" "that will allow you to register other nicks later sharing\n" "the same configuration, the same set of memos and the\n" @@ -294,7 +297,7 @@ class CommandNSResend : public Command if (na == NULL) source.Reply(NICK_NOT_REGISTERED); - else if (na->nc != source.GetAccount() || source.nc->HasFlag(NI_UNCONFIRMED) == false) + else if (na->nc != source.GetAccount() || source.nc->HasExt("UNCONFIRMED") == false) source.Reply(_("Your account is already confirmed.")); else { @@ -321,7 +324,7 @@ class CommandNSResend : public Command this->SendSyntax(source); source.Reply(" "); source.Reply(_("This command will re-send the auth code (also called passcode)\n" - "to the e-mail address of the user whom is performing it.")); + "to the e-mail address of the nickname in the database.")); return true; } diff --git a/modules/commands/ns_resetpass.cpp b/modules/commands/ns_resetpass.cpp index 39eead56e..e57261a9f 100644 --- a/modules/commands/ns_resetpass.cpp +++ b/modules/commands/ns_resetpass.cpp @@ -1,6 +1,6 @@ /* NickServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -20,16 +20,16 @@ class CommandNSResetPass : public Command public: CommandNSResetPass(Module *creator) : Command(creator, "nickserv/resetpass", 1, 1) { - this->SetFlag(CFLAG_ALLOW_UNREGISTERED); this->SetDesc(_("Helps you reset lost passwords")); this->SetSyntax(_("\037nickname\037")); + this->AllowUnregistered(true); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { const NickAlias *na; - if (Config->RestrictMail && source.HasCommand("nickserv/resetpass")) + if (Config->RestrictMail && !source.HasCommand("nickserv/resetpass")) source.Reply(ACCESS_DENIED); else if (!(na = NickAlias::Find(params[0]))) source.Reply(NICK_X_NOT_REGISTERED, params[0].c_str()); @@ -49,7 +49,7 @@ class CommandNSResetPass : public Command { this->SendSyntax(source); source.Reply(" "); - source.Reply(_("Sends a code key to the nickname with instructions on how to\n" + source.Reply(_("Sends a passcode to the nickname with instructions on how to\n" "reset their password.")); return true; } @@ -78,6 +78,12 @@ class NSResetPass : public Module ModuleManager::Attach(I_OnPreCommand, this); } + ~NSResetPass() + { + for (nickcore_map::const_iterator it = NickCoreList->begin(), it_end = NickCoreList->end(); it != it_end; ++it) + it->second->Shrink("ns_resetpass"); + } + EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> ¶ms) anope_override { if (command->name == "nickserv/confirm" && params.size() > 1) @@ -98,9 +104,9 @@ class NSResetPass : public Module { nc->Shrink("ns_resetpass"); - Log(LOG_COMMAND, source, &commandnsresetpass) << "confirmed RESETPASS to forcefully identify to " << na->nick; + Log(LOG_COMMAND, source, &commandnsresetpass) << "confirmed RESETPASS to forcefully identify as " << na->nick; - nc->UnsetFlag(NI_UNCONFIRMED); + nc->Shrink("UNCONFIRMED"); if (source.GetUser()) { diff --git a/modules/commands/ns_saset.cpp b/modules/commands/ns_saset.cpp deleted file mode 100644 index ac3cb1d8f..000000000 --- a/modules/commands/ns_saset.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/* NickServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandNSSASet : public Command -{ - public: - CommandNSSASet(Module *creator) : Command(creator, "nickserv/saset", 2, 4) - { - this->SetDesc(_("Set SET-options on another nickname")); - this->SetSyntax(_("\037option\037 \037nickname\037 \037parameters\037")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - this->OnSyntaxError(source, ""); - return; - } - - bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override - { - this->SendSyntax(source); - source.Reply(_("Sets various nickname options. \037option\037 can be one of:")); - Anope::string this_name = source.command; - for (CommandInfo::map::const_iterator it = source.service->commands.begin(), it_end = source.service->commands.end(); it != it_end; ++it) - { - const Anope::string &c_name = it->first; - const CommandInfo &info = it->second; - - if (c_name.find_ci(this_name + " ") == 0) - { - ServiceReference<Command> command("Command", info.name); - if (command) - { - source.command = c_name; - command->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(), Config->NickServ.c_str()); - return true; - } -}; - -class CommandNSSASetPassword : public Command -{ - public: - CommandNSSASetPassword(Module *creator) : Command(creator, "nickserv/saset/password", 2, 2) - { - this->SetDesc(_("Set the nickname password")); - this->SetSyntax(_("\037nickname\037 \037new-password\037")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - const NickAlias *setter_na = NickAlias::Find(params[0]); - if (setter_na == NULL) - { - source.Reply(NICK_X_NOT_REGISTERED, params[0].c_str()); - return; - } - NickCore *nc = setter_na->nc; - - size_t len = params[1].length(); - - if (Config->NSSecureAdmins && source.nc != nc && nc->IsServicesOper()) - { - source.Reply(_("You may not change the password of other services operators.")); - return; - } - else if (nc->display.equals_ci(params[1]) || (Config->StrictPasswords && len < 5)) - { - source.Reply(MORE_OBSCURE_PASSWORD); - return; - } - else if (len > Config->PassLen) - { - source.Reply(PASSWORD_TOO_LONG); - return; - } - - Anope::Encrypt(params[1], nc->pass); - Anope::string tmp_pass; - if (Anope::Decrypt(nc->pass, tmp_pass) == 1) - source.Reply(_("Password for \002%s\002 changed to \002%s\002."), nc->display.c_str(), tmp_pass.c_str()); - else - source.Reply(_("Password for \002%s\002 changed."), nc->display.c_str()); - - return; - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Changes the password used to identify as the nick's owner.")); - return true; - } -}; - -class NSSASet : public Module -{ - CommandNSSASet commandnssaset; - CommandNSSASetPassword commandnssasetpassword; - - public: - NSSASet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandnssaset(this), commandnssasetpassword(this) - { - this->SetAuthor("Anope"); - - } -}; - -MODULE_INIT(NSSASet) diff --git a/modules/commands/ns_saset_noexpire.cpp b/modules/commands/ns_saset_noexpire.cpp deleted file mode 100644 index ea3e946ae..000000000 --- a/modules/commands/ns_saset_noexpire.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* NickServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandNSSASetNoexpire : public Command -{ - public: - CommandNSSASetNoexpire(Module *creator) : Command(creator, "nickserv/saset/noexpire", 1, 2) - { - this->SetDesc(_("Prevent the nickname from expiring")); - this->SetSyntax(_("\037nickname\037 {ON | OFF}")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - NickAlias *na = NickAlias::Find(params[0]); - if (na == NULL) - { - source.Reply(NICK_X_NOT_REGISTERED, params[0].c_str()); - return; - } - - Anope::string param = params.size() > 1 ? params[1] : ""; - - if (param.equals_ci("ON")) - { - na->SetFlag(NS_NO_EXPIRE); - source.Reply(_("Nick %s \002will not\002 expire."), na->nick.c_str()); - } - else if (param.equals_ci("OFF")) - { - na->UnsetFlag(NS_NO_EXPIRE); - source.Reply(_("Nick %s \002will\002 expire."), na->nick.c_str()); - } - else - this->OnSyntaxError(source, "NOEXPIRE"); - - return; - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Sets whether the given nickname will expire. Setting this\n" - "to \002ON\002 prevents the nickname from expiring.")); - return true; - } -}; - -class NSSASetNoexpire : public Module -{ - CommandNSSASetNoexpire commandnssasetnoexpire; - - public: - NSSASetNoexpire(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandnssasetnoexpire(this) - { - this->SetAuthor("Anope"); - - } -}; - -MODULE_INIT(NSSASetNoexpire) diff --git a/modules/commands/ns_set.cpp b/modules/commands/ns_set.cpp index bc6a67b35..61573980e 100644 --- a/modules/commands/ns_set.cpp +++ b/modules/commands/ns_set.cpp @@ -1,6 +1,6 @@ /* NickServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -9,8 +9,6 @@ * Based on the original code of Services by Andy Church. */ -/*************************************************************************/ - #include "module.h" class CommandNSSet : public Command @@ -33,6 +31,7 @@ class CommandNSSet : public Command this->SendSyntax(source); source.Reply(" "); source.Reply(_("Sets various nickname options. \037option\037 can be one of:")); + Anope::string this_name = source.command; for (CommandInfo::map::const_iterator it = source.service->commands.begin(), it_end = source.service->commands.end(); it != it_end; ++it) { @@ -49,8 +48,52 @@ class CommandNSSet : public Command } } } + source.Reply(_("Type \002%s%s HELP %s \037option\037\002 for more information\n" - "on a specific option."), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str(), source.command.c_str()); + "on a specific option."), Config->UseStrictPrivMsgString.c_str(), source.service->nick.c_str(), source.command.c_str()); + + return true; + } +}; + +class CommandNSSASet : public Command +{ + public: + CommandNSSASet(Module *creator) : Command(creator, "nickserv/saset", 2, 4) + { + this->SetDesc(_("Set SET-options on another nickname")); + this->SetSyntax(_("\037option\037 \037nickname\037 \037parameters\037")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + this->OnSyntaxError(source, ""); + return; + } + + bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override + { + this->SendSyntax(source); + source.Reply(_("Sets various nickname options. \037option\037 can be one of:")); + Anope::string this_name = source.command; + for (CommandInfo::map::const_iterator it = source.service->commands.begin(), it_end = source.service->commands.end(); it != it_end; ++it) + { + const Anope::string &c_name = it->first; + const CommandInfo &info = it->second; + + if (c_name.find_ci(this_name + " ") == 0) + { + ServiceReference<Command> command("Command", info.name); + if (command) + { + source.command = c_name; + command->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(), Config->NickServ.c_str()); return true; } }; @@ -66,7 +109,6 @@ class CommandNSSetPassword : public Command void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { - const Anope::string ¶m = params[1]; unsigned len = param.length(); @@ -87,6 +129,61 @@ class CommandNSSetPassword : public Command source.Reply(_("Password for \002%s\002 changed to \002%s\002."), source.nc->display.c_str(), tmp_pass.c_str()); else source.Reply(_("Password for \002%s\002 changed."), source.nc->display.c_str()); + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Changes the password used to identify you as the nick's\n" + "owner.")); + return true; + } +}; + +class CommandNSSASetPassword : public Command +{ + public: + CommandNSSASetPassword(Module *creator) : Command(creator, "nickserv/saset/password", 2, 2) + { + this->SetDesc(_("Set the nickname password")); + this->SetSyntax(_("\037nickname\037 \037new-password\037")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + const NickAlias *setter_na = NickAlias::Find(params[0]); + if (setter_na == NULL) + { + source.Reply(NICK_X_NOT_REGISTERED, params[0].c_str()); + return; + } + NickCore *nc = setter_na->nc; + + size_t len = params[1].length(); + + if (Config->NSSecureAdmins && source.nc != nc && nc->IsServicesOper()) + { + source.Reply(_("You may not change the password of other Services Operators.")); + return; + } + else if (nc->display.equals_ci(params[1]) || (Config->StrictPasswords && len < 5)) + { + source.Reply(MORE_OBSCURE_PASSWORD); + return; + } + else if (len > Config->PassLen) + { + source.Reply(PASSWORD_TOO_LONG); + return; + } + + Anope::Encrypt(params[1], nc->pass); + Anope::string tmp_pass; + if (Anope::Decrypt(nc->pass, tmp_pass) == 1) + source.Reply(_("Password for \002%s\002 changed to \002%s\002."), nc->display.c_str(), tmp_pass.c_str()); + else + source.Reply(_("Password for \002%s\002 changed."), nc->display.c_str()); return; } @@ -95,8 +192,1123 @@ class CommandNSSetPassword : public Command { this->SendSyntax(source); source.Reply(" "); - source.Reply(_("Changes the password used to identify you as the nick's\n" - "owner.")); + source.Reply(_("Changes the password used to identify as the nick's owner.")); + return true; + } +}; + +class CommandNSSetAutoOp : public Command +{ + public: + CommandNSSetAutoOp(Module *creator, const Anope::string &sname = "nickserv/set/autoop", size_t min = 1) : Command(creator, sname, min, min + 1) + { + this->SetDesc(_("Sets whether services should set channel status modes on you automatically.")); + this->SetSyntax(_("{ON | OFF}")); + } + + void Run(CommandSource &source, const Anope::string &user, const Anope::string ¶m) + { + const NickAlias *na = NickAlias::Find(user); + if (na == NULL) + { + source.Reply(NICK_X_NOT_REGISTERED, user.c_str()); + return; + } + NickCore *nc = na->nc; + + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnSetNickOption, OnSetNickOption(source, this, nc, param)); + if (MOD_RESULT == EVENT_STOP) + return; + + if (param.equals_ci("ON")) + { + nc->ExtendMetadata("AUTOOP"); + source.Reply(_("Services will from now on set status modes on %s in channels."), nc->display.c_str()); + } + else if (param.equals_ci("OFF")) + { + nc->Shrink("AUTOOP"); + source.Reply(_("Services will no longer set status modes on %s in channels."), nc->display.c_str()); + } + else + this->OnSyntaxError(source, "AUTOOP"); + + return; + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + this->Run(source, source.nc->display, params[0]); + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Sets whether you will be given your channel status modes automatically.\n" + "Set to \002ON\002 to allow ChanServ to set status modes on you automatically\n" + "when entering channels. Note that depending on channel settings some modes\n" + "may not get set automatically.")); + return true; + } +}; + +class CommandNSSASetAutoOp : public CommandNSSetAutoOp +{ + public: + CommandNSSASetAutoOp(Module *creator) : CommandNSSetAutoOp(creator, "nickserv/saset/autoop", 2) + { + this->ClearSyntax(); + this->SetSyntax(_("\037nickname\037 {ON | OFF}")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + this->Run(source, params[0], params[1]); + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Sets whether the given nickname will be given its status modes\n" + "in channels automatically. Set to \002ON\002 to allow ChanServ\n" + "to set status modes on the given nickname automatically when it\n" + "is entering channels. Note that depending on channel settings\n" + "some modes may not get set automatically.")); + return true; + } +}; + +class CommandNSSetChanstats : public Command +{ + public: + CommandNSSetChanstats(Module *creator, const Anope::string &sname = "nickserv/set/chanstats", size_t min = 1 ) : Command(creator, sname, min, min + 1) + { + this->SetDesc(_("Turn chanstat statistic on or off")); + this->SetSyntax(_("{ON | OFF}")); + } + void Run(CommandSource &source, const Anope::string &user, const Anope::string ¶m) + { + NickAlias *na = NickAlias::Find(user); + if (!na) + { + source.Reply(NICK_X_NOT_REGISTERED, user.c_str()); + return; + } + + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnSetNickOption, OnSetNickOption(source, this, na->nc, param)); + if (MOD_RESULT == EVENT_STOP) + return; + + if (param.equals_ci("ON")) + { + na->nc->ExtendMetadata("STATS"); + source.Reply(_("Chanstat statistics are now enabled for your nick.")); + } + else if (param.equals_ci("OFF")) + { + na->nc->Shrink("STATS"); + source.Reply(_("Chanstat statistics are now disabled for your nick.")); + } + else + this->OnSyntaxError(source, "CHANSTATS"); + + return; + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + this->Run(source, source.nc->display, params[0]); + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Turns Chanstats statistics ON or OFF.")); + return true; + } +}; + +class CommandNSSASetChanstats : public CommandNSSetChanstats +{ + public: + CommandNSSASetChanstats(Module *creator) : CommandNSSetChanstats(creator, "nickserv/saset/chanstats", 2) + { + this->ClearSyntax(); + this->SetSyntax(_("\037nickname\037 {ON | OFF}")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + this->Run(source, params[0], params[1]); + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Turns chanstats channel statistics ON or OFF for this user.")); + return true; + } +}; + +class CommandNSSetDisplay : public Command +{ + public: + CommandNSSetDisplay(Module *creator, const Anope::string &sname = "nickserv/set/display", size_t min = 1) : Command(creator, sname, min, min + 1) + { + this->SetDesc(_("Set the display of your group in Services")); + this->SetSyntax(_("\037new-display\037")); + } + + void Run(CommandSource &source, const Anope::string &user, const Anope::string ¶m) + { + const NickAlias *user_na = NickAlias::Find(user), *na = NickAlias::Find(param); + + if (!Config->NoNicknameOwnership) + { + source.Reply(_("This command may not be used on this network because nickname ownership is disabled.")); + return; + } + if (user_na == NULL) + { + source.Reply(NICK_X_NOT_REGISTERED, user.c_str()); + return; + } + else if (!na || *na->nc != *user_na->nc) + { + source.Reply(_("The new display MUST be a nickname of the nickname group %s."), user_na->nc->display.c_str()); + return; + } + + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnSetNickOption, OnSetNickOption(source, this, user_na->nc, param)); + if (MOD_RESULT == EVENT_STOP) + return; + + user_na->nc->SetDisplay(na); + source.Reply(NICK_SET_DISPLAY_CHANGED, user_na->nc->display.c_str()); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + this->Run(source, source.nc->display, params[0]); + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Changes the display used to refer to your nickname group in\n" + "Services. The new display MUST be a nick of your group.")); + return true; + } +}; + +class CommandNSSASetDisplay : public CommandNSSetDisplay +{ + public: + CommandNSSASetDisplay(Module *creator) : CommandNSSetDisplay(creator, "nickserv/saset/display", 2) + { + this->ClearSyntax(); + this->SetSyntax(_("\037nickname\037 \037new-display\037")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + this->Run(source, params[0], params[1]); + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Changes the display used to refer to the nickname group in\n" + "Services. The new display MUST be a nick of the group.")); + return true; + } +}; + +class CommandNSSetEmail : public Command +{ + static bool SendConfirmMail(User *u, const BotInfo *bi) + { + int chars[] = { + ' ', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', + 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', + 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', + 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', + 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' + }; + int idx, min = 1, max = 62; + Anope::string code; + for (idx = 0; idx < 9; ++idx) + code += chars[1 + static_cast<int>((static_cast<float>(max - min)) * static_cast<uint16_t>(rand()) / 65536.0) + min]; + + u->Account()->Extend("ns_set_email_passcode", new ExtensibleItemClass<Anope::string>(code)); + + Anope::string subject = Config->MailEmailchangeSubject; + Anope::string message = Config->MailEmailchangeMessage; + + subject = subject.replace_all_cs("%e", u->Account()->email); + subject = subject.replace_all_cs("%N", Config->NetworkName); + subject = subject.replace_all_cs("%c", code); + + message = message.replace_all_cs("%e", u->Account()->email); + message = message.replace_all_cs("%N", Config->NetworkName); + message = message.replace_all_cs("%c", code); + + return Mail::Send(u, u->Account(), bi, subject, message); + } + + public: + CommandNSSetEmail(Module *creator, const Anope::string &cname = "nickserv/set/email", size_t min = 0) : Command(creator, cname, min, min + 1) + { + this->SetDesc(_("Associate an E-mail address with your nickname")); + this->SetSyntax(_("\037address\037")); + } + + void Run(CommandSource &source, const Anope::string &user, const Anope::string ¶m) + { + const NickAlias *na = NickAlias::Find(user); + if (!na) + { + source.Reply(NICK_X_NOT_REGISTERED, user.c_str()); + return; + } + NickCore *nc = na->nc; + + if (param.empty() && Config->NSForceEmail) + { + source.Reply(_("You cannot unset the e-mail on this network.")); + return; + } + else if (Config->NSSecureAdmins && source.nc != nc && nc->IsServicesOper()) + { + source.Reply(_("You may not change the e-mail of other Services Operators.")); + return; + } + else if (!param.empty() && !Mail::Validate(param)) + { + source.Reply(MAIL_X_INVALID, param.c_str()); + return; + } + + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnSetNickOption, OnSetNickOption(source, this, nc, param)); + if (MOD_RESULT == EVENT_STOP) + return; + + if (!param.empty() && Config->NSConfirmEmailChanges && !source.IsServicesOper()) + { + source.nc->Extend("ns_set_email", new ExtensibleItemClass<Anope::string>(param)); + Anope::string old = source.nc->email; + source.nc->email = param; + if (SendConfirmMail(source.GetUser(), source.service)) + source.Reply(_("A confirmation e-mail has been sent to \002%s\002. Follow the instructions in it to change your e-mail address."), param.c_str()); + source.nc->email = old; + } + else + { + if (!param.empty()) + { + nc->email = param; + source.Reply(_("E-mail address for \002%s\002 changed to \002%s\002."), nc->display.c_str(), param.c_str()); + } + else + { + nc->email.clear(); + source.Reply(_("E-mail address for \002%s\002 unset."), nc->display.c_str()); + } + } + + return; + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + this->Run(source, source.nc->display, params.size() ? params[0] : ""); + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Associates the given E-mail address with your nickname.\n" + "This address will be displayed whenever someone requests\n" + "information on the nickname with the \002INFO\002 command.")); + return true; + } +}; + +class CommandNSSASetEmail : public CommandNSSetEmail +{ + public: + CommandNSSASetEmail(Module *creator) : CommandNSSetEmail(creator, "nickserv/saset/email", 2) + { + this->ClearSyntax(); + this->SetSyntax(_("\037nickname\037 \037address\037")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + this->Run(source, params[0], params.size() > 1 ? params[1] : ""); + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Associates the given E-mail address with the nickname.")); + return true; + } +}; + +class CommandNSSetGreet : public Command +{ + public: + CommandNSSetGreet(Module *creator, const Anope::string &sname = "nickserv/set/greet", size_t min = 0) : Command(creator, sname, min, min + 1) + { + this->SetDesc(_("Associate a greet message with your nickname")); + this->SetSyntax(_("\037message\037")); + } + + void Run(CommandSource &source, const Anope::string &user, const Anope::string ¶m) + { + const NickAlias *na = NickAlias::Find(user); + if (!na) + { + source.Reply(NICK_X_NOT_REGISTERED, user.c_str()); + return; + } + NickCore *nc = na->nc; + + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnSetNickOption, OnSetNickOption(source, this, nc, param)); + if (MOD_RESULT == EVENT_STOP) + return; + + if (!param.empty()) + { + nc->greet = param; + source.Reply(_("Greet message for \002%s\002 changed to \002%s\002."), nc->display.c_str(), nc->greet.c_str()); + } + else + { + nc->greet.clear(); + source.Reply(_("Greet message for \002%s\002 unset."), nc->display.c_str()); + } + + return; + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + this->Run(source, source.nc->display, params.size() > 0 ? params[0] : ""); + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Makes the given message the greet of your nickname, that\n" + "will be displayed when joining a channel that has GREET\n" + "option enabled, provided that you have the necessary\n" + "access on it.")); + return true; + } +}; + +class CommandNSSASetGreet : public CommandNSSetGreet +{ + public: + CommandNSSASetGreet(Module *creator) : CommandNSSetGreet(creator, "nickserv/saset/greet", 1) + { + this->ClearSyntax(); + this->SetSyntax(_("\037nickname\037 \037message\037")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + this->Run(source, params[0], params.size() > 1 ? params[1] : ""); + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Makes the given message the greet of the nickname, that\n" + "will be displayed when joining a channel that has GREET\n" + "option enabled, provided that the user has the necessary\n" + "access on it.")); + return true; + } +}; + +class CommandNSSetHide : public Command +{ + public: + CommandNSSetHide(Module *creator, const Anope::string &sname = "nickserv/set/hide", size_t min = 2) : Command(creator, sname, min, min + 1) + { + this->SetDesc(_("Hide certain pieces of nickname information")); + this->SetSyntax(_("{EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}")); + } + + void Run(CommandSource &source, const Anope::string &user, const Anope::string ¶m, const Anope::string &arg) + { + const NickAlias *na = NickAlias::Find(user); + if (!na) + { + source.Reply(NICK_X_NOT_REGISTERED, user.c_str()); + return; + } + NickCore *nc = na->nc; + + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnSetNickOption, OnSetNickOption(source, this, nc, param)); + if (MOD_RESULT == EVENT_STOP) + return; + + Anope::string onmsg, offmsg, flag; + + if (param.equals_ci("EMAIL")) + { + flag = "HIDE_EMAIL"; + onmsg = _("The E-mail address of \002%s\002 will now be hidden from %s INFO displays."); + offmsg = _("The E-mail address of \002%s\002 will now be shown in %s INFO displays."); + } + else if (param.equals_ci("USERMASK")) + { + flag = "HIDE_MASK"; + onmsg = _("The last seen user@host mask of \002%s\002 will now be hidden from %s INFO displays."); + offmsg = _("The last seen user@host mask of \002%s\002 will now be shown in %s INFO displays."); + } + else if (param.equals_ci("STATUS")) + { + flag = "HIDE_STATUS"; + onmsg = _("The services access status of \002%s\002 will now be hidden from %s INFO displays."); + offmsg = _("The services access status of \002%s\002 will now be shown in %s INFO displays."); + } + else if (param.equals_ci("QUIT")) + { + flag = "HIDE_QUIT"; + onmsg = _("The last quit message of \002%s\002 will now be hidden from %s INFO displays."); + offmsg = _("The last quit message of \002%s\002 will now be shown in %s INFO displays."); + } + else + { + this->OnSyntaxError(source, "HIDE"); + return; + } + + if (arg.equals_ci("ON")) + { + nc->ExtendMetadata(flag); + source.Reply(onmsg.c_str(), nc->display.c_str(), Config->NickServ.c_str()); + } + else if (arg.equals_ci("OFF")) + { + nc->Shrink(flag); + source.Reply(offmsg.c_str(), nc->display.c_str(), Config->NickServ.c_str()); + } + else + this->OnSyntaxError(source, "HIDE"); + + return; + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + this->Run(source, source.nc->display, params[0], params[1]); + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Allows you to prevent certain pieces of information from\n" + "being displayed when someone does a %s \002INFO\002 on your\n" + "nick. You can hide your E-mail address (\002EMAIL\002), last seen\n" + "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)."), Config->NickServ.c_str()); + return true; + } +}; + +class CommandNSSASetHide : public CommandNSSetHide +{ + public: + CommandNSSASetHide(Module *creator) : CommandNSSetHide(creator, "nickserv/saset/hide", 3) + { + this->SetSyntax("\037nickname\037 {EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + this->ClearSyntax(); + this->Run(source, params[0], params[1], params[2]); + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Allows you to prevent certain pieces of information from\n" + "being displayed when someone does a %s \002INFO\002 on the\n" + "nick. You can hide the E-mail address (\002EMAIL\002), last seen\n" + "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)."), Config->NickServ.c_str()); + return true; + } +}; + +class CommandNSSetKill : public Command +{ + public: + CommandNSSetKill(Module *creator, const Anope::string &sname = "nickserv/set/kill", size_t min = 1) : Command(creator, sname, min, min + 1) + { + this->SetDesc(_("Turn protection on or off")); + this->SetSyntax(_("{ON | QUICK | IMMED | OFF}")); + } + + void Run(CommandSource &source, const Anope::string &user, const Anope::string ¶m) + { + if (Config->NoNicknameOwnership) + { + source.Reply(_("This command may not be used on this network because nickname ownership is disabled.")); + return; + } + + const NickAlias *na = NickAlias::Find(user); + if (!na) + { + source.Reply(NICK_X_NOT_REGISTERED, user.c_str()); + return; + } + NickCore *nc = na->nc; + + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnSetNickOption, OnSetNickOption(source, this, nc, param)); + if (MOD_RESULT == EVENT_STOP) + return; + + if (param.equals_ci("ON")) + { + nc->ExtendMetadata("KILLPROTECT"); + nc->Shrink("KILL_QUICK"); + nc->Shrink("KILL_IMMED"); + source.Reply(_("Protection is now \002on\002 for \002%s\002."), nc->display.c_str()); + } + else if (param.equals_ci("QUICK")) + { + nc->ExtendMetadata("KILLPROTECT"); + nc->ExtendMetadata("KILL_QUICK"); + nc->Shrink("KILL_IMMED"); + source.Reply(_("Protection is now \002on\002 for \002%s\002, with a reduced delay."), nc->display.c_str()); + } + else if (param.equals_ci("IMMED")) + { + if (Config->NSAllowKillImmed) + { + nc->ExtendMetadata("KILLPROTECT"); + nc->ExtendMetadata("KILL_IMMED"); + nc->Shrink("KILL_QUICK"); + source.Reply(_("Protection is now \002on\002 for \002%s\002, with no delay."), nc->display.c_str()); + } + else + source.Reply(_("The \002IMMED\002 option is not available on this network.")); + } + else if (param.equals_ci("OFF")) + { + nc->Shrink("KILLPROTECT"); + nc->Shrink("KILL_QUICK"); + nc->Shrink("KILL_IMMED"); + source.Reply(_("Protection is now \002off\002 for \002%s\002."), nc->display.c_str()); + } + else + this->OnSyntaxError(source, "KILL"); + + return; + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + this->Run(source, source.nc->display, params[0]); + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Turns the automatic protection option for your nick\n" + "on or off. With protection on, if another user\n" + "tries to take your nick, they will be given one minute to\n" + "change to another nick, after which %s will forcibly change\n" + "their nick.\n" + " \n" + "If you select \002QUICK\002, the user will be given only 20 seconds\n" + "to change nicks instead of the usual 60. If you select\n" + "\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."), Config->NickServ.c_str()); + return true; + } +}; + +class CommandNSSASetKill : public CommandNSSetKill +{ + public: + CommandNSSASetKill(Module *creator) : CommandNSSetKill(creator, "nickserv/saset/kill", 2) + { + this->SetSyntax(_("\037nickname\037 {ON | QUICK | IMMED | OFF}")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + this->ClearSyntax(); + this->Run(source, params[0], params[1]); + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Turns the automatic protection option for the nick\n" + "on or off. With protection on, if another user\n" + "tries to take the nick, they will be given one minute to\n" + "change to another nick, after which %s will forcibly change\n" + "their nick.\n" + " \n" + "If you select \002QUICK\002, the user will be given only 20 seconds\n" + "to change nicks instead of the usual 60. If you select\n" + "\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."), Config->NickServ.c_str()); + return true; + } +}; + +class CommandNSSetLanguage : public Command +{ + public: + CommandNSSetLanguage(Module *creator, const Anope::string &sname = "nickserv/set/language", size_t min = 1) : Command(creator, sname, min, min + 1) + { + this->SetDesc(_("Set the language Services will use when messaging you")); + this->SetSyntax(_("\037language\037")); + } + + void Run(CommandSource &source, const Anope::string &user, const Anope::string ¶m) + { + const NickAlias *na = NickAlias::Find(user); + if (!na) + { + source.Reply(NICK_X_NOT_REGISTERED, user.c_str()); + return; + } + NickCore *nc = na->nc; + + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnSetNickOption, OnSetNickOption(source, this, nc, param)); + if (MOD_RESULT == EVENT_STOP) + return; + + for (unsigned j = 0; j < Language::Languages.size(); ++j) + { + if (param == "en" || Language::Languages[j] == param) + break; + else if (j + 1 == Language::Languages.size()) + { + this->OnSyntaxError(source, ""); + return; + } + } + + nc->language = param != "en" ? param : ""; + source.Reply(_("Language changed to \002English\002.")); + + return; + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶m) anope_override + { + this->Run(source, source.nc->display, param[0]); + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Changes the language Services uses when sending messages to\n" + "you (for example, when responding to a command you send).\n" + "\037language\037 should be chosen from the following list of\n" + "supported languages:")); + + source.Reply(" en (English)"); + for (unsigned j = 0; j < Language::Languages.size(); ++j) + { + const Anope::string &langname = Language::Translate(Language::Languages[j].c_str(), _("English")); + if (langname == "English") + continue; + source.Reply(" %s (%s)", Language::Languages[j].c_str(), langname.c_str()); + } + + return true; + } +}; + +class CommandNSSASetLanguage : public CommandNSSetLanguage +{ + public: + CommandNSSASetLanguage(Module *creator) : CommandNSSetLanguage(creator, "nickserv/saset/language", 2) + { + this->ClearSyntax(); + this->SetSyntax(_("\037nickname\037 \037language\037")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + this->Run(source, params[0], params[1]); + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Changes the language Services uses when sending messages to\n" + "the given user (for example, when responding to a command they send).\n" + "\037language\037 should be chosen from the following list of\n" + "supported languages:")); + source.Reply(" en (English)"); + for (unsigned j = 0; j < Language::Languages.size(); ++j) + { + const Anope::string &langname = Language::Translate(Language::Languages[j].c_str(), _("English")); + if (langname == "English") + continue; + source.Reply(" %s (%s)", Language::Languages[j].c_str(), langname.c_str()); + } + return true; + } +}; + +class CommandNSSetMessage : public Command +{ + public: + CommandNSSetMessage(Module *creator, const Anope::string &sname = "nickserv/set/message", size_t min = 1) : Command(creator, sname, min, min + 1) + { + this->SetDesc(_("Change the communication method of Services")); + this->SetSyntax(_("{ON | OFF}")); + } + + void Run(CommandSource &source, const Anope::string &user, const Anope::string ¶m) + { + const NickAlias *na = NickAlias::Find(user); + if (!na) + { + source.Reply(NICK_X_NOT_REGISTERED, user.c_str()); + return; + } + NickCore *nc = na->nc; + + if (!Config->UsePrivmsg) + { + source.Reply(_("You cannot %s on this network."), source.command.c_str()); + return; + } + + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnSetNickOption, OnSetNickOption(source, this, nc, param)); + if (MOD_RESULT == EVENT_STOP) + return; + + if (param.equals_ci("ON")) + { + nc->ExtendMetadata("MSG"); + source.Reply(_("Services will now reply to \002%s\002 with \002messages\002."), nc->display.c_str()); + } + else if (param.equals_ci("OFF")) + { + nc->Shrink("MSG"); + source.Reply(_("Services will now reply to \002%s\002 with \002notices\002."), nc->display.c_str()); + } + else + this->OnSyntaxError(source, "MSG"); + + return; + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + this->Run(source, source.nc->display, params[0]); + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Allows you to choose the way Services are communicating with\n" + "you. With \002MSG\002 set, Services will use messages, else they'll\n" + "use notices.")); + return true; + } + + void OnServHelp(CommandSource &source) anope_override + { + if (Config->UsePrivmsg) + Command::OnServHelp(source); + } +}; + +class CommandNSSASetMessage : public CommandNSSetMessage +{ + public: + CommandNSSASetMessage(Module *creator) : CommandNSSetMessage(creator, "nickserv/saset/message", 2) + { + this->ClearSyntax(); + this->SetSyntax(_("\037nickname\037 {ON | OFF}")); + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Allows you to choose the way Services are communicating with\n" + "the given user. With \002MSG\002 set, Services will use messages,\n" + "else they'll use notices.")); + return true; + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + this->Run(source, params[0], params[1]); + } +}; + +class CommandNSSetPrivate : public Command +{ + public: + CommandNSSetPrivate(Module *creator, const Anope::string &sname = "nickserv/set/private", size_t min = 1) : Command(creator, sname, min, min + 1) + { + this->SetDesc(Anope::printf(_("Prevent the nickname from appearing in a \002%s%s LIST\002"), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str())); + this->SetSyntax(_("{ON | OFF}")); + } + + void Run(CommandSource &source, const Anope::string &user, const Anope::string ¶m) + { + const NickAlias *na = NickAlias::Find(user); + if (!na) + { + source.Reply(NICK_X_NOT_REGISTERED, user.c_str()); + return; + } + NickCore *nc = na->nc; + + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnSetNickOption, OnSetNickOption(source, this, nc, param)); + if (MOD_RESULT == EVENT_STOP) + return; + + if (param.equals_ci("ON")) + { + nc->ExtendMetadata("PRIVATE"); + source.Reply(_("Private option is now \002on\002 for \002%s\002."), nc->display.c_str()); + } + else if (param.equals_ci("OFF")) + { + nc->Shrink("PRIVATE"); + source.Reply(_("Private option is now \002off\002 for \002%s\002."), nc->display.c_str()); + } + else + this->OnSyntaxError(source, "PRIVATE"); + + return; + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + this->Run(source, source.nc->display, params[0]); + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Turns %s's privacy option on or off for your nick.\n" + "With \002PRIVATE\002 set, your nickname will not appear in\n" + "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.)"), + Config->NickServ.c_str(), Config->NickServ.c_str()); + return true; + } +}; + +class CommandNSSASetPrivate : public CommandNSSetPrivate +{ + public: + CommandNSSASetPrivate(Module *creator) : CommandNSSetPrivate(creator, "nickserv/saset/private", 2) + { + this->ClearSyntax(); + this->SetSyntax(_("\037nickname\037 {ON | OFF}")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + this->Run(source, params[0], params[1]); + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Turns %s's privacy option on or off for the nick.\n" + "With \002PRIVATE\002 set, the nickname will not appear in\n" + "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.)"), + Config->NickServ.c_str(), Config->NickServ.c_str()); + return true; + } +}; + +class CommandNSSetSecure : public Command +{ + public: + CommandNSSetSecure(Module *creator, const Anope::string &sname = "nickserv/set/secure", size_t min = 1) : Command(creator, sname, min, min + 1) + { + this->SetDesc(_("Turn nickname security on or off")); + this->SetSyntax(_("{ON | OFF}")); + } + + void Run(CommandSource &source, const Anope::string &user, const Anope::string ¶m) + { + const NickAlias *na = NickAlias::Find(user); + if (!na) + { + source.Reply(NICK_X_NOT_REGISTERED, user.c_str()); + return; + } + NickCore *nc = na->nc; + + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnSetNickOption, OnSetNickOption(source, this, nc, param)); + if (MOD_RESULT == EVENT_STOP) + return; + + if (param.equals_ci("ON")) + { + nc->ExtendMetadata("SECURE"); + source.Reply(_("Secure option is now \002on\002 for \002%s\002."), nc->display.c_str()); + } + else if (param.equals_ci("OFF")) + { + nc->Shrink("SECURE"); + source.Reply(_("Secure option is now \002off\002 for \002%s\002."), nc->display.c_str()); + } + else + this->OnSyntaxError(source, "SECURE"); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + this->Run(source, source.nc->display, params[0]); + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Turns %s's security features on or off for your\n" + "nick. With \002SECURE\002 set, you must enter your password\n" + "before you will be recognized as the owner of the nick,\n" + "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."), Config->NickServ.c_str(), Config->NickServ.c_str()); + return true; + } +}; + +class CommandNSSASetSecure : public CommandNSSetSecure +{ + public: + CommandNSSASetSecure(Module *creator) : CommandNSSetSecure(creator, "nickserv/saset/secure", 2) + { + this->ClearSyntax(); + this->SetSyntax(_("\037nickname\037 {ON | OFF}")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + this->Run(source, params[0], params[1]); + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Turns %s's security features on or off for your\n" + "nick. With \002SECURE\002 set, you must enter your password\n" + "before you will be recognized as the owner of the nick,\n" + "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."), Config->NickServ.c_str(), Config->NickServ.c_str()); + return true; + } +}; + +class CommandNSSASetNoexpire : public Command +{ + public: + CommandNSSASetNoexpire(Module *creator) : Command(creator, "nickserv/saset/noexpire", 1, 2) + { + this->SetDesc(_("Prevent the nickname from expiring")); + this->SetSyntax(_("\037nickname\037 {ON | OFF}")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + NickAlias *na = NickAlias::Find(params[0]); + if (na == NULL) + { + source.Reply(NICK_X_NOT_REGISTERED, params[0].c_str()); + return; + } + + Anope::string param = params.size() > 1 ? params[1] : ""; + + if (param.equals_ci("ON")) + { + na->ExtendMetadata("NO_EXPIRE"); + source.Reply(_("Nick %s \002will not\002 expire."), na->nick.c_str()); + } + else if (param.equals_ci("OFF")) + { + na->Shrink("NO_EXPIRE"); + source.Reply(_("Nick %s \002will\002 expire."), na->nick.c_str()); + } + else + this->OnSyntaxError(source, "NOEXPIRE"); + + return; + } + + bool OnHelp(CommandSource &source, const Anope::string &) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Sets whether the given nickname will expire. Setting this\n" + "to \002ON\002 prevents the nickname from expiring.")); return true; } }; @@ -104,14 +1316,106 @@ class CommandNSSetPassword : public Command class NSSet : public Module { CommandNSSet commandnsset; + CommandNSSASet commandnssaset; + + CommandNSSetAutoOp commandnssetautoop; + CommandNSSASetAutoOp commandnssasetautoop; + + CommandNSSetChanstats commandnssetchanstats; + CommandNSSASetChanstats commandnssasetchanstats; + bool NSDefChanstats; + + CommandNSSetDisplay commandnssetdisplay; + CommandNSSASetDisplay commandnssasetdisplay; + + CommandNSSetEmail commandnssetemail; + CommandNSSASetEmail commandnssasetemail; + + CommandNSSetGreet commandnssetgreet; + CommandNSSASetGreet commandnssasetgreet; + + CommandNSSetHide commandnssethide; + CommandNSSASetHide commandnssasethide; + + CommandNSSetKill commandnssetkill; + CommandNSSASetKill commandnssasetkill; + + CommandNSSetLanguage commandnssetlanguage; + CommandNSSASetLanguage commandnssasetlanguage; + + CommandNSSetMessage commandnssetmessage; + CommandNSSASetMessage commandnssasetmessage; + CommandNSSetPassword commandnssetpassword; + CommandNSSASetPassword commandnssasetpassword; + + CommandNSSetPrivate commandnssetprivate; + CommandNSSASetPrivate commandnssasetprivate; + + CommandNSSetSecure commandnssetsecure; + CommandNSSASetSecure commandnssasetsecure; + + CommandNSSASetNoexpire commandnssasetnoexpire; public: NSSet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandnsset(this), commandnssetpassword(this) + commandnsset(this), commandnssaset(this), + commandnssetautoop(this), commandnssasetautoop(this), + commandnssetchanstats(this), commandnssasetchanstats(this), NSDefChanstats(false), + commandnssetdisplay(this), commandnssasetdisplay(this), + commandnssetemail(this), commandnssasetemail(this), + commandnssetgreet(this), commandnssasetgreet(this), + commandnssethide(this), commandnssasethide(this), + commandnssetkill(this), commandnssasetkill(this), + commandnssetlanguage(this), commandnssasetlanguage(this), + commandnssetmessage(this), commandnssasetmessage(this), + commandnssetpassword(this), commandnssasetpassword(this), + commandnssetprivate(this), commandnssasetprivate(this), + commandnssetsecure(this), commandnssasetsecure(this), + commandnssasetnoexpire(this) { this->SetAuthor("Anope"); + Implementation i[] = { I_OnReload, I_OnNickRegister, I_OnPreCommand }; + ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); + + this->OnReload(); + } + + void OnReload() anope_override + { + ConfigReader config; + NSDefChanstats = config.ReadFlag("chanstats", "NSDefChanstats", "0", 0); + } + + void OnNickRegister(NickAlias *na) anope_override + { + if (NSDefChanstats) + na->nc->ExtendMetadata("STATS"); + } + + EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> ¶ms) anope_override + { + NickCore *uac = source.nc; + + if (command->name == "nickserv/confirm" && !params.empty() && uac) + { + Anope::string *new_email = uac->GetExt<ExtensibleItemClass<Anope::string> *>("ns_set_email"), *passcode = uac->GetExt<ExtensibleItemClass<Anope::string> *>("ns_set_email_passcode"); + if (new_email && passcode) + { + if (params[0] == *passcode) + { + uac->email = *new_email; + Log(LOG_COMMAND, source, command) << "to confirm their email address change to " << uac->email; + source.Reply(_("Your email address has been changed to \002%s\002."), uac->email.c_str()); + uac->Shrink("ns_set_email"); + uac->Shrink("ns_set_email_passcode"); + return EVENT_STOP; + } + } + } + + return EVENT_CONTINUE; } }; diff --git a/modules/commands/ns_set_autoop.cpp b/modules/commands/ns_set_autoop.cpp deleted file mode 100644 index e6533875b..000000000 --- a/modules/commands/ns_set_autoop.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* NickServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandNSSetAutoOp : public Command -{ - public: - CommandNSSetAutoOp(Module *creator, const Anope::string &sname = "nickserv/set/autoop", size_t min = 1) : Command(creator, sname, min, min + 1) - { - this->SetDesc(_("Should services op you automatically.")); - this->SetSyntax(_("{ON | OFF}")); - } - - void Run(CommandSource &source, const Anope::string &user, const Anope::string ¶m) - { - const NickAlias *na = NickAlias::Find(user); - if (na == NULL) - { - source.Reply(NICK_X_NOT_REGISTERED, user.c_str()); - return; - } - NickCore *nc = na->nc; - - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnSetNickOption, OnSetNickOption(source, this, nc, param)); - if (MOD_RESULT == EVENT_STOP) - return; - - if (param.equals_ci("ON")) - { - nc->SetFlag(NI_AUTOOP); - source.Reply(_("Services will now autoop %s in channels."), nc->display.c_str()); - } - else if (param.equals_ci("OFF")) - { - nc->UnsetFlag(NI_AUTOOP); - source.Reply(_("Services will no longer autoop %s in channels."), nc->display.c_str()); - } - else - this->OnSyntaxError(source, "AUTOOP"); - - return; - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - this->Run(source, source.nc->display, params[0]); - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Sets whether you will be opped automatically. Set to ON to \n" - "allow ChanServ to op you automatically when entering channels.")); - return true; - } -}; - -class CommandNSSASetAutoOp : public CommandNSSetAutoOp -{ - public: - CommandNSSASetAutoOp(Module *creator) : CommandNSSetAutoOp(creator, "nickserv/saset/autoop", 2) - { - this->ClearSyntax(); - this->SetSyntax(_("\037nickname\037 {ON | OFF}")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - this->Run(source, params[0], params[1]); - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Sets whether the given nickname will be opped automatically.\n" - "Set to \002ON\002 to allow ChanServ to op the given nickname \n" - "omatically when joining channels.")); - return true; - } -}; - -class NSSetAutoOp : public Module -{ - CommandNSSetAutoOp commandnssetautoop; - CommandNSSASetAutoOp commandnssasetautoop; - - public: - NSSetAutoOp(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandnssetautoop(this), commandnssasetautoop(this) - { - this->SetAuthor("Anope"); - - } -}; - -MODULE_INIT(NSSetAutoOp) diff --git a/modules/commands/ns_set_chanstats.cpp b/modules/commands/ns_set_chanstats.cpp deleted file mode 100644 index 7b8f371ff..000000000 --- a/modules/commands/ns_set_chanstats.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/* NickServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandNSSetChanstats : public Command -{ - public: - CommandNSSetChanstats(Module *creator, const Anope::string &sname = "nickserv/set/chanstats", size_t min = 1 ) : Command(creator, sname, min, min + 1) - { - this->SetDesc(_("Turn chanstat statistic on or off")); - this->SetSyntax(_("{ON | OFF}")); - } - void Run(CommandSource &source, const Anope::string &user, const Anope::string ¶m) - { - NickAlias *na = NickAlias::Find(user); - if (!na) - { - source.Reply(NICK_X_NOT_REGISTERED, user.c_str()); - return; - } - - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnSetNickOption, OnSetNickOption(source, this, na->nc, param)); - if (MOD_RESULT == EVENT_STOP) - return; - - if (param.equals_ci("ON")) - { - na->nc->SetFlag(NI_STATS); - source.Reply(_("Chanstat statistics are now enabled for your nick")); - } - else if (param.equals_ci("OFF")) - { - na->nc->UnsetFlag(NI_STATS); - source.Reply(_("Chanstat statistics are now disabled for your nick")); - } - else - this->OnSyntaxError(source, "CHANSTATS"); - - return; - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - this->Run(source, source.nc->display, params[0]); - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Turns Chanstats statistics ON or OFF")); - return true; - } -}; - -class CommandNSSASetChanstats : public CommandNSSetChanstats -{ - public: - CommandNSSASetChanstats(Module *creator) : CommandNSSetChanstats(creator, "nickserv/saset/chanstats", 2) - { - this->ClearSyntax(); - this->SetSyntax(_("\037nickname\037 {ON | OFF}")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - this->Run(source, params[0], params[1]); - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Turns chanstats channel statistics ON or OFF for this user")); - return true; - } -}; - -class NSSetChanstats : public Module -{ - CommandNSSetChanstats commandnssetchanstats; - CommandNSSASetChanstats commandnssasetchanstats; - bool NSDefChanstats; - - public: - NSSetChanstats(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandnssetchanstats(this), commandnssasetchanstats(this) - { - this->SetAuthor("Anope"); - - Implementation i[] = { I_OnReload, I_OnNickRegister }; - ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - - this->OnReload(); - } - void OnReload() anope_override - { - ConfigReader config; - NSDefChanstats = config.ReadFlag("chanstats", "NSDefChanstats", "0", 0); - } - void OnNickRegister(NickAlias *na) anope_override - { - if (NSDefChanstats) - na->nc->SetFlag(NI_STATS); - } -}; - -MODULE_INIT(NSSetChanstats) diff --git a/modules/commands/ns_set_display.cpp b/modules/commands/ns_set_display.cpp deleted file mode 100644 index c532f4cf1..000000000 --- a/modules/commands/ns_set_display.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/* NickServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandNSSetDisplay : public Command -{ - public: - CommandNSSetDisplay(Module *creator, const Anope::string &sname = "nickserv/set/display", size_t min = 1) : Command(creator, sname, min, min + 1) - { - this->SetDesc(_("Set the display of your group in Services")); - this->SetSyntax(_("\037new-display\037")); - } - - void Run(CommandSource &source, const Anope::string &user, const Anope::string ¶m) - { - const NickAlias *user_na = NickAlias::Find(user), *na = NickAlias::Find(param); - - if (user_na == NULL) - { - source.Reply(NICK_X_NOT_REGISTERED, user.c_str()); - return; - } - else if (!na || *na->nc != *user_na->nc) - { - source.Reply(_("The new display MUST be a nickname of the nickname group %s"), user_na->nc->display.c_str()); - return; - } - - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnSetNickOption, OnSetNickOption(source, this, user_na->nc, param)); - if (MOD_RESULT == EVENT_STOP) - return; - - user_na->nc->SetDisplay(na); - source.Reply(NICK_SET_DISPLAY_CHANGED, user_na->nc->display.c_str()); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - this->Run(source, source.nc->display, params[0]); - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Changes the display used to refer to your nickname group in \n" - "Services. The new display MUST be a nick of your group.")); - return true; - } -}; - -class CommandNSSASetDisplay : public CommandNSSetDisplay -{ - public: - CommandNSSASetDisplay(Module *creator) : CommandNSSetDisplay(creator, "nickserv/saset/display", 2) - { - this->ClearSyntax(); - this->SetSyntax(_("\037nickname\037 \037new-display\037")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - this->Run(source, params[0], params[1]); - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Changes the display used to refer to the nickname group in \n" - "Services. The new display MUST be a nick of your group.")); - return true; - } -}; - -class NSSetDisplay : public Module -{ - CommandNSSetDisplay commandnssetdisplay; - CommandNSSASetDisplay commandnssasetdisplay; - - public: - NSSetDisplay(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandnssetdisplay(this), commandnssasetdisplay(this) - { - this->SetAuthor("Anope"); - - if (Config->NoNicknameOwnership) - throw ModuleException(modname + " can not be used with options:nonicknameownership enabled"); - } -}; - -MODULE_INIT(NSSetDisplay) diff --git a/modules/commands/ns_set_email.cpp b/modules/commands/ns_set_email.cpp deleted file mode 100644 index 82b4a0cc8..000000000 --- a/modules/commands/ns_set_email.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/* NickServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -static bool SendConfirmMail(User *u, const BotInfo *bi) -{ - int chars[] = { - ' ', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', - 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', - 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', - 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', - 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' - }; - int idx, min = 1, max = 62; - Anope::string code; - for (idx = 0; idx < 9; ++idx) - code += chars[1 + static_cast<int>((static_cast<float>(max - min)) * static_cast<uint16_t>(rand()) / 65536.0) + min]; - - u->Account()->Extend("ns_set_email_passcode", new ExtensibleItemClass<Anope::string>(code)); - - Anope::string subject = Config->MailEmailchangeSubject; - Anope::string message = Config->MailEmailchangeMessage; - - subject = subject.replace_all_cs("%e", u->Account()->email); - subject = subject.replace_all_cs("%N", Config->NetworkName); - subject = subject.replace_all_cs("%c", code); - - message = message.replace_all_cs("%e", u->Account()->email); - message = message.replace_all_cs("%N", Config->NetworkName); - message = message.replace_all_cs("%c", code); - - return Mail::Send(u, u->Account(), bi, subject, message); -} - -class CommandNSSetEmail : public Command -{ - public: - CommandNSSetEmail(Module *creator, const Anope::string &cname = "nickserv/set/email", size_t min = 0) : Command(creator, cname, min, min + 1) - { - this->SetDesc(_("Associate an E-mail address with your nickname")); - this->SetSyntax(_("\037address\037")); - } - - void Run(CommandSource &source, const Anope::string &user, const Anope::string ¶m) - { - const NickAlias *na = NickAlias::Find(user); - if (!na) - { - source.Reply(NICK_X_NOT_REGISTERED, user.c_str()); - return; - } - NickCore *nc = na->nc; - - if (param.empty() && Config->NSForceEmail) - { - source.Reply(_("You cannot unset the e-mail on this network.")); - return; - } - else if (Config->NSSecureAdmins && source.nc != nc && nc->IsServicesOper()) - { - source.Reply(_("You may not change the email of other services operators.")); - return; - } - else if (!param.empty() && !Mail::Validate(param)) - { - source.Reply(MAIL_X_INVALID, param.c_str()); - return; - } - - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnSetNickOption, OnSetNickOption(source, this, nc, param)); - if (MOD_RESULT == EVENT_STOP) - return; - - if (!param.empty() && Config->NSConfirmEmailChanges && !source.IsServicesOper()) - { - source.nc->Extend("ns_set_email", new ExtensibleItemClass<Anope::string>(param)); - Anope::string old = source.nc->email; - source.nc->email = param; - if (SendConfirmMail(source.GetUser(), source.service)) - source.Reply(_("A confirmation email has been sent to \002%s\002. Follow the instructions in it to change your email address."), param.c_str()); - source.nc->email = old; - } - else - { - if (!param.empty()) - { - nc->email = param; - source.Reply(_("E-mail address for \002%s\002 changed to \002%s\002."), nc->display.c_str(), param.c_str()); - } - else - { - nc->email.clear(); - source.Reply(_("E-mail address for \002%s\002 unset."), nc->display.c_str()); - } - } - - return; - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - this->Run(source, source.nc->display, params.size() ? params[0] : ""); - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Associates the given E-mail address with your nickname.\n" - "This address will be displayed whenever someone requests\n" - "information on the nickname with the \002INFO\002 command.")); - return true; - } -}; - -class CommandNSSASetEmail : public CommandNSSetEmail -{ - public: - CommandNSSASetEmail(Module *creator) : CommandNSSetEmail(creator, "nickserv/saset/email", 2) - { - this->ClearSyntax(); - this->SetSyntax(_("\037nickname\037 \037address\037")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - this->Run(source, params[0], params.size() > 1 ? params[1] : ""); - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Associates the given E-mail address with the nickname.")); - return true; - } -}; - -class NSSetEmail : public Module -{ - CommandNSSetEmail commandnssetemail; - CommandNSSASetEmail commandnssasetemail; - - public: - NSSetEmail(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandnssetemail(this), commandnssasetemail(this) - { - this->SetAuthor("Anope"); - - ModuleManager::Attach(I_OnPreCommand, this); - - } - - EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> ¶ms) anope_override - { - NickCore *uac = source.nc; - if (command->name == "nickserv/confirm" && !params.empty() && uac) - { - Anope::string *new_email = uac->GetExt<ExtensibleItemClass<Anope::string> *>("ns_set_email"), *passcode = uac->GetExt<ExtensibleItemClass<Anope::string> *>("ns_set_email_passcode"); - if (new_email && passcode) - { - if (params[0] == *passcode) - { - uac->email = *new_email; - Log(LOG_COMMAND, source, command) << "to confirm their email address change to " << uac->email; - source.Reply(_("Your email address has been changed to \002%s\002."), uac->email.c_str()); - uac->Shrink("ns_set_email"); - uac->Shrink("ns_set_email_passcode"); - return EVENT_STOP; - } - } - } - - return EVENT_CONTINUE; - } -}; - -MODULE_INIT(NSSetEmail) diff --git a/modules/commands/ns_set_greet.cpp b/modules/commands/ns_set_greet.cpp deleted file mode 100644 index b28edc2bb..000000000 --- a/modules/commands/ns_set_greet.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* NickServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandNSSetGreet : public Command -{ - public: - CommandNSSetGreet(Module *creator, const Anope::string &sname = "nickserv/set/greet", size_t min = 0) : Command(creator, sname, min, min + 1) - { - this->SetDesc(_("Associate a greet message with your nickname")); - this->SetSyntax(_("\037message\037")); - } - - void Run(CommandSource &source, const Anope::string &user, const Anope::string ¶m) - { - const NickAlias *na = NickAlias::Find(user); - if (!na) - { - source.Reply(NICK_X_NOT_REGISTERED, user.c_str()); - return; - } - NickCore *nc = na->nc; - - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnSetNickOption, OnSetNickOption(source, this, nc, param)); - if (MOD_RESULT == EVENT_STOP) - return; - - if (!param.empty()) - { - nc->greet = param; - source.Reply(_("Greet message for \002%s\002 changed to \002%s\002."), nc->display.c_str(), nc->greet.c_str()); - } - else - { - nc->greet.clear(); - source.Reply(_("Greet message for \002%s\002 unset."), nc->display.c_str()); - } - - return; - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - this->Run(source, source.nc->display, params.size() > 0 ? params[0] : ""); - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Makes the given message the greet of your nickname, that\n" - "will be displayed when joining a channel that has GREET\n" - "option enabled, provided that you have the necessary \n" - "access on it.")); - return true; - } -}; - -class CommandNSSASetGreet : public CommandNSSetGreet -{ - public: - CommandNSSASetGreet(Module *creator) : CommandNSSetGreet(creator, "nickserv/saset/greet", 1) - { - this->ClearSyntax(); - this->SetSyntax(_("\037nickname\037 \037message\037")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - this->Run(source, params[0], params.size() > 1 ? params[1] : ""); - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Makes the given message the greet of the nickname, that\n" - "will be displayed when joining a channel that has GREET\n" - "option enabled, provided that the user has the necessary \n" - "access on it.")); - return true; - } -}; - -class NSSetGreet : public Module -{ - CommandNSSetGreet commandnssetgreet; - CommandNSSASetGreet commandnssasetgreet; - - public: - NSSetGreet(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandnssetgreet(this), commandnssasetgreet(this) - { - this->SetAuthor("Anope"); - - } -}; - -MODULE_INIT(NSSetGreet) diff --git a/modules/commands/ns_set_hide.cpp b/modules/commands/ns_set_hide.cpp deleted file mode 100644 index d7fe886ea..000000000 --- a/modules/commands/ns_set_hide.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* NickServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandNSSetHide : public Command -{ - public: - CommandNSSetHide(Module *creator, const Anope::string &sname = "nickserv/set/hide", size_t min = 2) : Command(creator, sname, min, min + 1) - { - this->SetDesc(_("Hide certain pieces of nickname information")); - this->SetSyntax(_("{EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}")); - } - - void Run(CommandSource &source, const Anope::string &user, const Anope::string ¶m, const Anope::string &arg) - { - const NickAlias *na = NickAlias::Find(user); - if (!na) - { - source.Reply(NICK_X_NOT_REGISTERED, user.c_str()); - return; - } - NickCore *nc = na->nc; - - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnSetNickOption, OnSetNickOption(source, this, nc, param)); - if (MOD_RESULT == EVENT_STOP) - return; - - Anope::string onmsg, offmsg; - NickCoreFlag flag; - - if (param.equals_ci("EMAIL")) - { - flag = NI_HIDE_EMAIL; - onmsg = _("The E-mail address of \002%s\002 will now be hidden from %s INFO displays."); - offmsg = _("The E-mail address of \002%s\002 will now be shown in %s INFO displays."); - } - else if (param.equals_ci("USERMASK")) - { - flag = NI_HIDE_MASK; - onmsg = _("The last seen user@host mask of \002%s\002 will now be hidden from %s INFO displays."); - offmsg = _("The last seen user@host mask of \002%s\002 will now be shown in %s INFO displays."); - } - else if (param.equals_ci("STATUS")) - { - flag = NI_HIDE_STATUS; - onmsg = _("The services access status of \002%s\002 will now be hidden from %s INFO displays."); - offmsg = _("The services access status of \002%s\002 will now be shown in %s INFO displays."); - } - else if (param.equals_ci("QUIT")) - { - flag = NI_HIDE_QUIT; - onmsg = _("The last quit message of \002%s\002 will now be hidden from %s INFO displays."); - offmsg = _("The last quit message of \002%s\002 will now be shown in %s INFO displays."); - } - else - { - this->OnSyntaxError(source, "HIDE"); - return; - } - - if (arg.equals_ci("ON")) - { - nc->SetFlag(flag); - source.Reply(onmsg.c_str(), nc->display.c_str(), Config->NickServ.c_str()); - } - else if (arg.equals_ci("OFF")) - { - nc->UnsetFlag(flag); - source.Reply(offmsg.c_str(), nc->display.c_str(), Config->NickServ.c_str()); - } - else - this->OnSyntaxError(source, "HIDE"); - - return; - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - this->Run(source, source.nc->display, params[0], params[1]); - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Allows you to prevent certain pieces of information from\n" - "being displayed when someone does a %s \002INFO\002 on your\n" - "nick. You can hide your E-mail address (\002EMAIL\002), last seen\n" - "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)."), Config->NickServ.c_str()); - return true; - } -}; - -class CommandNSSASetHide : public CommandNSSetHide -{ - public: - CommandNSSASetHide(Module *creator) : CommandNSSetHide(creator, "nickserv/saset/hide", 3) - { - this->SetSyntax("\037nickname\037 {EMAIL | STATUS | USERMASK | QUIT} {ON | OFF}"); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - this->ClearSyntax(); - this->Run(source, params[0], params[1], params[2]); - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Allows you to prevent certain pieces of information from\n" - "being displayed when someone does a %s \002INFO\002 on the\n" - "nick. You can hide the E-mail address (\002EMAIL\002), last seen\n" - "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)."), Config->NickServ.c_str()); - return true; - } -}; - -class NSSetHide : public Module -{ - CommandNSSetHide commandnssethide; - CommandNSSASetHide commandnssasethide; - - public: - NSSetHide(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandnssethide(this), commandnssasethide(this) - { - this->SetAuthor("Anope"); - - } -}; - -MODULE_INIT(NSSetHide) diff --git a/modules/commands/ns_set_kill.cpp b/modules/commands/ns_set_kill.cpp deleted file mode 100644 index 0f62a4ba0..000000000 --- a/modules/commands/ns_set_kill.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/* NickServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandNSSetKill : public Command -{ - public: - CommandNSSetKill(Module *creator, const Anope::string &sname = "nickserv/set/kill", size_t min = 1) : Command(creator, sname, min, min + 1) - { - this->SetDesc(_("Turn protection on or off")); - this->SetSyntax(_("{ON | QUICK | IMMED | OFF}")); - } - - void Run(CommandSource &source, const Anope::string &user, const Anope::string ¶m) - { - const NickAlias *na = NickAlias::Find(user); - if (!na) - { - source.Reply(NICK_X_NOT_REGISTERED, user.c_str()); - return; - } - NickCore *nc = na->nc; - - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnSetNickOption, OnSetNickOption(source, this, nc, param)); - if (MOD_RESULT == EVENT_STOP) - return; - - if (param.equals_ci("ON")) - { - nc->SetFlag(NI_KILLPROTECT); - nc->UnsetFlag(NI_KILL_QUICK); - nc->UnsetFlag(NI_KILL_IMMED); - source.Reply(_("Protection is now \002on\002 for \002%s\002."), nc->display.c_str()); - } - else if (param.equals_ci("QUICK")) - { - nc->SetFlag(NI_KILLPROTECT); - nc->SetFlag(NI_KILL_QUICK); - nc->UnsetFlag(NI_KILL_IMMED); - source.Reply(_("Protection is now \002on\002 for \002%s\002, with a reduced delay."), nc->display.c_str()); - } - else if (param.equals_ci("IMMED")) - { - if (Config->NSAllowKillImmed) - { - nc->SetFlag(NI_KILLPROTECT); - nc->SetFlag(NI_KILL_IMMED); - nc->UnsetFlag(NI_KILL_QUICK); - source.Reply(_("Protection is now \002on\002 for \002%s\002, with no delay."), nc->display.c_str()); - } - else - source.Reply(_("The \002IMMED\002 option is not available on this network.")); - } - else if (param.equals_ci("OFF")) - { - nc->UnsetFlag(NI_KILLPROTECT); - nc->UnsetFlag(NI_KILL_QUICK); - nc->UnsetFlag(NI_KILL_IMMED); - source.Reply(_("Protection is now \002off\002 for \002%s\002."), nc->display.c_str()); - } - else - this->OnSyntaxError(source, "KILL"); - - return; - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - this->Run(source, source.nc->display, params[0]); - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Turns the automatic protection option for your nick\n" - "on or off. With protection on, if another user\n" - "tries to take your nick, they will be given one minute to\n" - "change to another nick, after which %s will forcibly change\n" - "their nick.\n" - " \n" - "If you select \002QUICK\002, the user will be given only 20 seconds\n" - "to change nicks instead of the usual 60. If you select\n" - "\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."), Config->NickServ.c_str()); - return true; - } -}; - -class CommandNSSASetKill : public CommandNSSetKill -{ - public: - CommandNSSASetKill(Module *creator) : CommandNSSetKill(creator, "nickserv/saset/kill", 2) - { - this->SetSyntax(_("\037nickname\037 {ON | QUICK | IMMED | OFF}")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - this->ClearSyntax(); - this->Run(source, params[0], params[1]); - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Turns the automatic protection option for the nick\n" - "on or off. With protection on, if another user\n" - "tries to take the nick, they will be given one minute to\n" - "change to another nick, after which %s will forcibly change\n" - "their nick.\n" - " \n" - "If you select \002QUICK\002, the user will be given only 20 seconds\n" - "to change nicks instead of the usual 60. If you select\n" - "\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."), Config->NickServ.c_str()); - return true; - } -}; - -class NSSetKill : public Module -{ - CommandNSSetKill commandnssetkill; - CommandNSSASetKill commandnssasetkill; - - public: - NSSetKill(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandnssetkill(this), commandnssasetkill(this) - { - this->SetAuthor("Anope"); - - if (Config->NoNicknameOwnership) - throw ModuleException(modname + " can not be used with options:nonicknameownership enabled"); - } -}; - -MODULE_INIT(NSSetKill) diff --git a/modules/commands/ns_set_language.cpp b/modules/commands/ns_set_language.cpp deleted file mode 100644 index d2830d4b8..000000000 --- a/modules/commands/ns_set_language.cpp +++ /dev/null @@ -1,132 +0,0 @@ -/* NickServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandNSSetLanguage : public Command -{ - public: - CommandNSSetLanguage(Module *creator, const Anope::string &sname = "nickserv/set/language", size_t min = 1) : Command(creator, sname, min, min + 1) - { - this->SetDesc(_("Set the language Services will use when messaging you")); - this->SetSyntax(_("\037language\037")); - } - - void Run(CommandSource &source, const Anope::string &user, const Anope::string ¶m) - { - const NickAlias *na = NickAlias::Find(user); - if (!na) - { - source.Reply(NICK_X_NOT_REGISTERED, user.c_str()); - return; - } - NickCore *nc = na->nc; - - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnSetNickOption, OnSetNickOption(source, this, nc, param)); - if (MOD_RESULT == EVENT_STOP) - return; - - for (unsigned j = 0; j < Language::Languages.size(); ++j) - { - if (param == "en" || Language::Languages[j] == param) - break; - else if (j + 1 == Language::Languages.size()) - { - this->OnSyntaxError(source, ""); - return; - } - } - - nc->language = param != "en" ? param : ""; - source.Reply(_("Language changed to \002English\002.")); - - return; - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶m) anope_override - { - this->Run(source, source.nc->display, param[0]); - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Changes the language Services uses when sending messages to\n" - "you (for example, when responding to a command you send).\n" - "\037language\037 should be chosen from the following list of\n" - "supported languages:")); - - source.Reply(" en (English)"); - for (unsigned j = 0; j < Language::Languages.size(); ++j) - { - const Anope::string &langname = Language::Translate(Language::Languages[j].c_str(), _("English")); - if (langname == "English") - continue; - source.Reply(" %s (%s)", Language::Languages[j].c_str(), langname.c_str()); - } - - return true; - } -}; - -class CommandNSSASetLanguage : public CommandNSSetLanguage -{ - public: - CommandNSSASetLanguage(Module *creator) : CommandNSSetLanguage(creator, "nickserv/saset/language", 2) - { - this->ClearSyntax(); - this->SetSyntax(_("\037nickname\037 \037language\037")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - this->Run(source, params[0], params[1]); - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Changes the language Services uses when sending messages to\n" - "the given user (for example, when responding to a command they send).\n" - "\037language\037 should be chosen from the following list of\n" - "supported languages:")); - source.Reply(" en (English)"); - for (unsigned j = 0; j < Language::Languages.size(); ++j) - { - const Anope::string &langname = Language::Translate(Language::Languages[j].c_str(), _("English")); - if (langname == "English") - continue; - source.Reply(" %s (%s)", Language::Languages[j].c_str(), langname.c_str()); - } - return true; - } -}; - -class NSSetLanguage : public Module -{ - CommandNSSetLanguage commandnssetlanguage; - CommandNSSASetLanguage commandnssasetlanguage; - - public: - NSSetLanguage(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandnssetlanguage(this), commandnssasetlanguage(this) - { - this->SetAuthor("Anope"); - - } -}; - -MODULE_INIT(NSSetLanguage) diff --git a/modules/commands/ns_set_message.cpp b/modules/commands/ns_set_message.cpp deleted file mode 100644 index f515b22c1..000000000 --- a/modules/commands/ns_set_message.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/* NickServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandNSSetMessage : public Command -{ - public: - CommandNSSetMessage(Module *creator, const Anope::string &sname = "nickserv/set/message", size_t min = 1) : Command(creator, sname, min, min + 1) - { - this->SetDesc(_("Change the communication method of Services")); - this->SetSyntax(_("{ON | OFF}")); - } - - void Run(CommandSource &source, const Anope::string &user, const Anope::string ¶m) - { - const NickAlias *na = NickAlias::Find(user); - if (!na) - { - source.Reply(NICK_X_NOT_REGISTERED, user.c_str()); - return; - } - NickCore *nc = na->nc; - - if (!Config->UsePrivmsg) - { - source.Reply(_("You cannot %s on this network."), source.command.c_str()); - return; - } - - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnSetNickOption, OnSetNickOption(source, this, nc, param)); - if (MOD_RESULT == EVENT_STOP) - return; - - if (param.equals_ci("ON")) - { - nc->SetFlag(NI_MSG); - source.Reply(_("Services will now reply to \002%s\002 with \002messages\002."), nc->display.c_str()); - } - else if (param.equals_ci("OFF")) - { - nc->UnsetFlag(NI_MSG); - source.Reply(_("Services will now reply to \002%s\002 with \002notices\002."), nc->display.c_str()); - } - else - this->OnSyntaxError(source, "MSG"); - - return; - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - this->Run(source, source.nc->display, params[0]); - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Allows you to choose the way Services are communicating with \n" - "you. With \002MSG\002 set, Services will use messages, else they'll \n" - "use notices.")); - return true; - } - - void OnServHelp(CommandSource &source) anope_override - { - if (Config->UsePrivmsg) - Command::OnServHelp(source); - } -}; - -class CommandNSSASetMessage : public CommandNSSetMessage -{ - public: - CommandNSSASetMessage(Module *creator) : CommandNSSetMessage(creator, "nickserv/saset/message", 2) - { - this->ClearSyntax(); - this->SetSyntax(_("\037nickname\037 {ON | OFF}")); - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Allows you to choose the way Services are communicating with \n" - "the given user. With \002MSG\002 set, Services will use messages,\n" - "else they'll use notices.")); - return true; - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - this->Run(source, params[0], params[1]); - } -}; - -class NSSetMessage : public Module -{ - CommandNSSetMessage commandnssetmessage; - CommandNSSASetMessage commandnssasetmessage; - - public: - NSSetMessage(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandnssetmessage(this), commandnssasetmessage(this) - { - this->SetAuthor("Anope"); - - } -}; - -MODULE_INIT(NSSetMessage) diff --git a/modules/commands/ns_set_misc.cpp b/modules/commands/ns_set_misc.cpp index b6dd672a3..a5a0019b6 100644 --- a/modules/commands/ns_set_misc.cpp +++ b/modules/commands/ns_set_misc.cpp @@ -1,6 +1,6 @@ /* * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -13,6 +13,8 @@ #include "module.h" +static std::map<Anope::string, Anope::string> descriptions; + struct NSMiscData : ExtensibleItem, Serializable { Serialize::Reference<NickCore> nc; @@ -109,6 +111,25 @@ class CommandNSSetMisc : public Command { this->Run(source, source.nc->display, !params.empty() ? params[0] : ""); } + + void OnServHelp(CommandSource &source) anope_override + { + if (descriptions.count(source.command)) + { + this->SetDesc(descriptions[source.command]); + Command::OnServHelp(source); + } + } + + bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override + { + if (descriptions.count(source.command)) + { + source.Reply("%s", Language::Translate(source.nc, descriptions[source.command].c_str())); + return true; + } + return false; + } }; class CommandNSSASetMisc : public CommandNSSetMisc @@ -138,8 +159,31 @@ class NSSetMisc : public Module { this->SetAuthor("Anope"); - Implementation i[] = { I_OnNickInfo }; + Implementation i[] = { I_OnReload, I_OnNickInfo }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); + + this->OnReload(); + } + + void OnReload() + { + ConfigReader config; + + descriptions.clear(); + + for (int i = 0; i < config.Enumerate("command"); ++i) + { + if (config.ReadValue("command", "command", "", i) != "nickserv/set/misc" && config.ReadValue("command", "command", "", i) != "nickserv/saset/misc") + continue; + + Anope::string cname = config.ReadValue("command", "name", "", i); + Anope::string desc = config.ReadValue("command", "misc_description", "", i); + + if (cname.empty() || desc.empty()) + continue; + + descriptions[cname] = desc; + } } void OnNickInfo(CommandSource &source, NickAlias *na, InfoFormatter &info, bool ShowHidden) anope_override diff --git a/modules/commands/ns_set_private.cpp b/modules/commands/ns_set_private.cpp deleted file mode 100644 index 8f953fcc0..000000000 --- a/modules/commands/ns_set_private.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* NickServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandNSSetPrivate : public Command -{ - public: - CommandNSSetPrivate(Module *creator, const Anope::string &sname = "nickserv/set/private", size_t min = 1) : Command(creator, sname, min, min + 1) - { - this->SetDesc(Anope::printf(_("Prevent the nickname from appearing in a \002%s%s LIST\002"), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str())); - this->SetSyntax(_("{ON | OFF}")); - } - - void Run(CommandSource &source, const Anope::string &user, const Anope::string ¶m) - { - const NickAlias *na = NickAlias::Find(user); - if (!na) - { - source.Reply(NICK_X_NOT_REGISTERED, user.c_str()); - return; - } - NickCore *nc = na->nc; - - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnSetNickOption, OnSetNickOption(source, this, nc, param)); - if (MOD_RESULT == EVENT_STOP) - return; - - if (param.equals_ci("ON")) - { - nc->SetFlag(NI_PRIVATE); - source.Reply(_("Private option is now \002on\002 for \002%s\002."), nc->display.c_str()); - } - else if (param.equals_ci("OFF")) - { - nc->UnsetFlag(NI_PRIVATE); - source.Reply(_("Private option is now \002off\002 for \002%s\002."), nc->display.c_str()); - } - else - this->OnSyntaxError(source, "PRIVATE"); - - return; - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - this->Run(source, source.nc->display, params[0]); - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Turns %s's privacy option on or off for your nick.\n" - "With \002PRIVATE\002 set, your nickname will not appear in\n" - "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.)"), - Config->NickServ.c_str(), Config->NickServ.c_str()); - return true; - } -}; - -class CommandNSSASetPrivate : public CommandNSSetPrivate -{ - public: - CommandNSSASetPrivate(Module *creator) : CommandNSSetPrivate(creator, "nickserv/saset/private", 2) - { - this->ClearSyntax(); - this->SetSyntax(_("\037nickname\037 {ON | OFF}")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - this->Run(source, params[0], params[1]); - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Turns %s's privacy option on or off for the nick.\n" - "With \002PRIVATE\002 set, the nickname will not appear in\n" - "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.)"), - Config->NickServ.c_str(), Config->NickServ.c_str()); - return true; - } -}; - -class NSSetPrivate : public Module -{ - CommandNSSetPrivate commandnssetprivate; - CommandNSSASetPrivate commandnssasetprivate; - - public: - NSSetPrivate(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandnssetprivate(this), commandnssasetprivate(this) - { - this->SetAuthor("Anope"); - - } -}; - -MODULE_INIT(NSSetPrivate) diff --git a/modules/commands/ns_set_secure.cpp b/modules/commands/ns_set_secure.cpp deleted file mode 100644 index b7dd79969..000000000 --- a/modules/commands/ns_set_secure.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* NickServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandNSSetSecure : public Command -{ - public: - CommandNSSetSecure(Module *creator, const Anope::string &sname = "nickserv/set/secure", size_t min = 1) : Command(creator, sname, min, min + 1) - { - this->SetDesc(_("Turn nickname security on or off")); - this->SetSyntax(_("{ON | OFF}")); - } - - void Run(CommandSource &source, const Anope::string &user, const Anope::string ¶m) - { - const NickAlias *na = NickAlias::Find(user); - if (!na) - { - source.Reply(NICK_X_NOT_REGISTERED, user.c_str()); - return; - } - NickCore *nc = na->nc; - - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnSetNickOption, OnSetNickOption(source, this, nc, param)); - if (MOD_RESULT == EVENT_STOP) - return; - - if (param.equals_ci("ON")) - { - nc->SetFlag(NI_SECURE); - source.Reply(_("Secure option is now \002on\002 for \002%s\002."), nc->display.c_str()); - } - else if (param.equals_ci("OFF")) - { - nc->UnsetFlag(NI_SECURE); - source.Reply(_("Secure option is now \002off\002 for \002%s\002."), nc->display.c_str()); - } - else - this->OnSyntaxError(source, "SECURE"); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - this->Run(source, source.nc->display, params[0]); - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Turns %s's security features on or off for your\n" - "nick. With \002SECURE\002 set, you must enter your password\n" - "before you will be recognized as the owner of the nick,\n" - "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."), Config->NickServ.c_str(), Config->NickServ.c_str()); - return true; - } -}; - -class CommandNSSASetSecure : public CommandNSSetSecure -{ - public: - CommandNSSASetSecure(Module *creator) : CommandNSSetSecure(creator, "nickserv/saset/secure", 2) - { - this->ClearSyntax(); - this->SetSyntax(_("\037nickname\037 {ON | OFF}")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - this->Run(source, params[0], params[1]); - } - - bool OnHelp(CommandSource &source, const Anope::string &) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Turns %s's security features on or off for your\n" - "nick. With \002SECURE\002 set, you must enter your password\n" - "before you will be recognized as the owner of the nick,\n" - "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."), Config->NickServ.c_str(), Config->NickServ.c_str()); - return true; - } -}; - -class NSSetSecure : public Module -{ - CommandNSSetSecure commandnssetsecure; - CommandNSSASetSecure commandnssasetsecure; - - public: - NSSetSecure(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandnssetsecure(this), commandnssasetsecure(this) - { - this->SetAuthor("Anope"); - - } -}; - -MODULE_INIT(NSSetSecure) diff --git a/modules/commands/ns_status.cpp b/modules/commands/ns_status.cpp index 495ae96a1..8fc803896 100644 --- a/modules/commands/ns_status.cpp +++ b/modules/commands/ns_status.cpp @@ -1,6 +1,6 @@ /* NickServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -18,9 +18,9 @@ class CommandNSStatus : public Command public: CommandNSStatus(Module *creator) : Command(creator, "nickserv/status", 0, 16) { - this->SetFlag(CFLAG_ALLOW_UNREGISTERED); this->SetDesc(_("Returns the owner status of the given nickname")); - this->SetSyntax(_("\037nickname\037...")); + this->SetSyntax(_("\037nickname\037")); + this->AllowUnregistered(true); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override @@ -67,11 +67,7 @@ class CommandNSStatus : public Command " 0 - no such user online \002or\002 nickname not registered\n" " 1 - user not recognized as nickname's owner\n" " 2 - user recognized as owner via access list only\n" - " 3 - user recognized as owner via password identification\n" - " \n" - "Up to sixteen nicknames may be sent with each command; the\n" - "rest will be ignored. If no nickname is given, your status\n" - "will be returned.")); + " 3 - user recognized as owner via password identification")); return true; } }; diff --git a/modules/commands/ns_suspend.cpp b/modules/commands/ns_suspend.cpp index 63710ccca..a4cc7f355 100644 --- a/modules/commands/ns_suspend.cpp +++ b/modules/commands/ns_suspend.cpp @@ -1,6 +1,6 @@ /* NickServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -13,47 +13,6 @@ #include "module.h" -struct NickSuspend : ExtensibleItem, Serializable -{ - Anope::string nick; - time_t when; - - NickSuspend() : Serializable("NickSuspend") - { - } - - void Serialize(Serialize::Data &sd) const anope_override - { - sd["nick"] << this->nick; - sd["when"] << this->when; - } - - static Serializable* Unserialize(Serializable *obj, Serialize::Data &sd) - { - Anope::string snick; - - sd["nick"] >> snick; - - const NickAlias *na = NickAlias::Find(snick); - if (na == NULL) - return NULL; - - NickSuspend *ns; - if (obj) - ns = anope_dynamic_static_cast<NickSuspend *>(obj); - else - ns = new NickSuspend(); - - sd["nick"] >> ns->nick; - sd["when"] >> ns->when; - - if (!obj) - na->nc->Extend("ns_suspend_expire", ns); - - return ns; - } -}; - class CommandNSSuspend : public Command { public: @@ -95,21 +54,28 @@ class CommandNSSuspend : public Command if (Config->NSSecureAdmins && na->nc->IsServicesOper()) { - source.Reply(_("You may not suspend other services operators nicknames.")); + source.Reply(_("You may not suspend other Services Operators' nicknames.")); return; } NickCore *nc = na->nc; - nc->SetFlag(NI_SUSPENDED); - nc->SetFlag(NI_SECURE); - nc->UnsetFlag(NI_KILLPROTECT); - nc->UnsetFlag(NI_KILL_QUICK); - nc->UnsetFlag(NI_KILL_IMMED); + nc->ExtendMetadata("SUSPENDED"); + nc->ExtendMetadata("SECURE"); + nc->Shrink("KILLPROTECT"); + nc->Shrink("KILL_QUICK"); + nc->Shrink("KILL_IMMED"); + + nc->ExtendMetadata("suspend:by", source.GetNick()); + if (!reason.empty()) + nc->ExtendMetadata("suspend:reason", reason); + if (expiry_secs > 0) + nc->ExtendMetadata("suspend:expire", stringify(Anope::CurTime + expiry_secs)); + - for (std::list<Serialize::Reference<NickAlias> >::iterator it = nc->aliases.begin(), it_end = nc->aliases.end(); it != it_end;) + for (unsigned i = 0; i < nc->aliases->size(); ++i) { - NickAlias *na2 = *it++; + NickAlias *na2 = nc->aliases->at(i); if (na2 && *na2->nc == *na->nc) { @@ -124,15 +90,6 @@ class CommandNSSuspend : public Command } } - if (expiry_secs > 0) - { - NickSuspend *ns = new NickSuspend(); - ns->nick = na->nick; - ns->when = Anope::CurTime + expiry_secs; - - nc->Extend("ns_suspend_expire", ns); - } - Log(LOG_ADMIN, source, this) << "for " << nick << " (" << (!reason.empty() ? reason : "No reason") << "), expires in " << (expiry_secs ? Anope::strftime(Anope::CurTime + expiry_secs) : "never"); source.Reply(_("Nick %s is now suspended."), nick.c_str()); @@ -145,7 +102,7 @@ class CommandNSSuspend : public Command { this->SendSyntax(source); source.Reply(" "); - source.Reply(_("Suspends a registered nickname, which prevents from being used\n" + source.Reply(_("Suspends a registered nickname, which prevents it from being used\n" "while keeping all the data for that nick. If an expiry is given\n" "the nick will be unsuspended after that period of time, else the\n" "default expiry from the configuration is used.")); @@ -179,14 +136,16 @@ class CommandNSUnSuspend : public Command return; } - if (!na->nc->HasFlag(NI_SUSPENDED)) + if (!na->nc->HasExt("SUSPENDED")) { source.Reply(_("Nick %s is not suspended."), na->nick.c_str()); return; } - na->nc->UnsetFlag(NI_SUSPENDED); - na->nc->Shrink("ns_suspend_expire"); + na->nc->Shrink("SUSPENDED"); + na->nc->Shrink("suspend:expire"); + na->nc->Shrink("suspend:by"); + na->nc->Shrink("suspend:reason"); Log(LOG_ADMIN, source, this) << "for " << na->nick; source.Reply(_("Nick %s is now released."), nick.c_str()); @@ -207,13 +166,12 @@ class CommandNSUnSuspend : public Command class NSSuspend : public Module { - Serialize::Type nicksuspend_type; CommandNSSuspend commandnssuspend; CommandNSUnSuspend commandnsunsuspend; public: NSSuspend(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - nicksuspend_type("NickSuspend", NickSuspend::Unserialize), commandnssuspend(this), commandnsunsuspend(this) + commandnssuspend(this), commandnsunsuspend(this) { this->SetAuthor("Anope"); @@ -221,28 +179,32 @@ class NSSuspend : public Module ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } - ~NSSuspend() - { - for (nickcore_map::const_iterator it = NickCoreList->begin(), it_end = NickCoreList->end(); it != it_end; ++it) - it->second->Shrink("ns_suspend_expire"); - } - void OnPreNickExpire(NickAlias *na, bool &expire) anope_override { - if (!na->nc->HasFlag(NI_SUSPENDED)) + if (!na->nc->HasExt("SUSPENDED")) return; expire = false; - NickSuspend *ns = na->nc->GetExt<NickSuspend *>("ns_suspend_expire"); - if (ns != NULL && ns->when < Anope::CurTime) + Anope::string *str = na->nc->GetExt<ExtensibleItemClass<Anope::string> *>("suspend:expire"); + if (str == NULL) + return; + + try { - na->last_seen = Anope::CurTime; - na->nc->UnsetFlag(NI_SUSPENDED); - na->nc->Shrink("ns_suspend_expire"); + time_t when = convertTo<time_t>(*str); + if (when < Anope::CurTime) + { + na->last_seen = Anope::CurTime; + na->nc->Shrink("SUSPENDED"); + na->nc->Shrink("suspend:expire"); + na->nc->Shrink("suspend:by"); + na->nc->Shrink("suspend:reason"); - Log(LOG_NORMAL, "expire", NickServ) << "Expiring suspend for " << na->nick; + Log(LOG_NORMAL, "expire", NickServ) << "Expiring suspend for " << na->nick; + } } + catch (const ConvertException &) { } } }; diff --git a/modules/commands/ns_update.cpp b/modules/commands/ns_update.cpp index 8f4812b9e..309a95087 100644 --- a/modules/commands/ns_update.cpp +++ b/modules/commands/ns_update.cpp @@ -1,6 +1,6 @@ /* NickServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -20,14 +20,12 @@ class CommandNSUpdate : public Command { this->SetDesc(_("Updates your current status, i.e. it checks for new memos")); this->SetSyntax(""); + this->RequireUser(true); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { User *u = source.GetUser(); - if (!u) - return; - NickAlias *na = NickAlias::Find(u->nick); if (na && na->nc == source.GetAccount()) diff --git a/modules/commands/os_akill.cpp b/modules/commands/os_akill.cpp index 89b1d96ae..bdf609b03 100644 --- a/modules/commands/os_akill.cpp +++ b/modules/commands/os_akill.cpp @@ -1,6 +1,6 @@ /* OperServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -130,7 +130,7 @@ class CommandOSAKill : public Command ServiceReference<RegexProvider> provider("Regex", Config->RegexEngine); if (!provider) { - source.Reply(_("Unable to find regex engine %s"), Config->RegexEngine.c_str()); + source.Reply(_("Unable to find regex engine %s."), Config->RegexEngine.c_str()); return; } @@ -172,7 +172,7 @@ class CommandOSAKill : public Command { source.Reply(USERHOST_MASK_TOO_WIDE, mask.c_str()); Log(LOG_ADMIN, source, this) << "tried to akill " << percent << "% of the network (" << affected << " users)"; - x->Destroy(); + delete x; return; } @@ -180,7 +180,7 @@ class CommandOSAKill : public Command FOREACH_RESULT(I_OnAddXLine, OnAddXLine(source, x, akills)); if (MOD_RESULT == EVENT_STOP) { - x->Destroy(); + delete x; return; } @@ -304,7 +304,7 @@ class CommandOSAKill : public Command source.Reply(_("No matching entries on the AKILL list.")); else { - source.Reply(_("Current akill list:")); + source.Reply(_("Current AKILL list:")); std::vector<Anope::string> replies; list.Process(replies); @@ -312,7 +312,7 @@ class CommandOSAKill : public Command for (unsigned i = 0; i < replies.size(); ++i) source.Reply(replies[i]); - source.Reply(_("End of \2akill\2 list.")); + source.Reply(_("End of AKILL list.")); } } @@ -394,7 +394,7 @@ class CommandOSAKill : public Command { this->SendSyntax(source); source.Reply(" "); - source.Reply(_("Allows Services operators to manipulate the AKILL list. If\n" + source.Reply(_("Allows Services Operators to manipulate the AKILL list. If\n" "a user matching an AKILL mask attempts to connect, Services\n" "will issue a KILL for that user and, on supported server\n" "types, will instruct all servers to add a ban for the mask\n" @@ -405,36 +405,38 @@ class CommandOSAKill : public Command "Mask should be in the format of nick!user@host#real name,\n" "though all that is required is user@host. If a real name is specified,\n" "the reason must be prepended with a :.\n" - "\037expiry\037 is specified as an integer followed by one of \037d\037 \n" - "(days), \037h\037 (hours), or \037m\037 (minutes). Combinations (such as \n" - "\0371h30m\037) are not permitted. If a unit specifier is not \n" - "included, the default is days (so \037+30\037 by itself means 30 \n" + "\037expiry\037 is specified as an integer followed by one of \037d\037\n" + "(days), \037h\037 (hours), or \037m\037 (minutes). Combinations (such as\n" + "\0371h30m\037) are not permitted. If a unit specifier is not\n" + "included, the default is days (so \037+30\037 by itself means 30\n" "days). To add an AKILL which does not expire, use \037+0\037. If the\n" "usermask to be added starts with a \037+\037, an expiry time must\n" "be given, even if it is the same as the default. The\n" "current AKILL default expiry time can be found with the\n" - "\002STATS AKILL\002 command.\n")); + "\002STATS AKILL\002 command.")); if (!Config->RegexEngine.empty()) - source.Reply(" \n" - "Regex matches are also supported using the %s engine.\n" - "Enclose your mask in // if this desired.", Config->RegexEngine.c_str()); + { + source.Reply(" "); + source.Reply(_("Regex matches are also supported using the %s engine.\n" + "Enclose your mask in // if this is desired."), Config->RegexEngine.c_str()); + } source.Reply(_( " \n" "The \002AKILL DEL\002 command removes the given mask from the\n" - "AKILL list if it is present. If a list of entry numbers is \n" - "given, those entries are deleted. (See the example for LIST \n" + "AKILL list if it is present. If a list of entry numbers is\n" + "given, those entries are deleted. (See the example for LIST\n" "below.)\n" " \n" - "The \002AKILL LIST\002 command displays the AKILL list. \n" + "The \002AKILL LIST\002 command displays the AKILL list.\n" "If a wildcard mask is given, only those entries matching the\n" "mask are displayed. If a list of entry numbers is given,\n" "only those entries are shown; for example:\n" " \002AKILL LIST 2-5,7-9\002\n" - " Lists AKILL entries numbered 2 through 5 and 7 \n" + " Lists AKILL entries numbered 2 through 5 and 7\n" " through 9.\n" " \n" - "\002AKILL VIEW\002 is a more verbose version of \002AKILL LIST\002, and \n" - "will show who added an AKILL, the date it was added, and when \n" + "\002AKILL VIEW\002 is a more verbose version of \002AKILL LIST\002, and\n" + "will show who added an AKILL, the date it was added, and when\n" "it expires, as well as the user@host/ip mask and reason.\n" " \n" "\002AKILL CLEAR\002 clears all entries of the AKILL list.")); diff --git a/modules/commands/os_chankill.cpp b/modules/commands/os_chankill.cpp index c1d71831b..3fea40043 100644 --- a/modules/commands/os_chankill.cpp +++ b/modules/commands/os_chankill.cpp @@ -1,6 +1,6 @@ /* OperServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -72,11 +72,11 @@ class CommandOSChanKill : public Command if ((c = Channel::Find(channel))) { - for (CUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ) + for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ) { - UserContainer *uc = *it++; + ChanUserContainer *uc = *it++; - if (uc->user->server == Me || uc->user->HasMode(UMODE_OPER)) + if (uc->user->server == Me || uc->user->HasMode("OPER")) continue; XLine *x = new XLine("*@" + uc->user->host, source.GetNick(), expires, realreason, XLineManager::GenerateUID()); diff --git a/modules/commands/os_config.cpp b/modules/commands/os_config.cpp index 61cda44c0..b9c58b2b0 100644 --- a/modules/commands/os_config.cpp +++ b/modules/commands/os_config.cpp @@ -1,6 +1,6 @@ /* OperServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/commands/os_defcon.cpp b/modules/commands/os_defcon.cpp index 1457a57dc..fe2ecc99f 100644 --- a/modules/commands/os_defcon.cpp +++ b/modules/commands/os_defcon.cpp @@ -1,6 +1,6 @@ /* OperServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -34,9 +34,8 @@ bool DefConModesSet = false; struct DefconConfig { std::vector<std::bitset<32> > DefCon; - Flags<ChannelModeName> DefConModesOn; - Flags<ChannelModeName> DefConModesOff; - std::map<ChannelModeName, Anope::string> DefConModesOnParams; + std::set<Anope::string> DefConModesOn, DefConModesOff; + std::map<Anope::string, Anope::string> DefConModesOnParams; int defaultlevel, sessionlimit; Anope::string chanmodes, message, offmessage, akillreason; @@ -70,19 +69,19 @@ struct DefconConfig this->DefCon[dlevel][level] = false; } - bool SetDefConParam(ChannelModeName Name, const Anope::string &buf) + bool SetDefConParam(const Anope::string &name, const Anope::string &buf) { - return DefConModesOnParams.insert(std::make_pair(Name, buf)).second; + return DefConModesOnParams.insert(std::make_pair(name, buf)).second; } - void UnsetDefConParam(ChannelModeName Name) + void UnsetDefConParam(const Anope::string &name) { - DefConModesOnParams.erase(Name); + DefConModesOnParams.erase(name); } - bool GetDefConParam(ChannelModeName Name, Anope::string &buf) + bool GetDefConParam(const Anope::string &name, Anope::string &buf) { - std::map<ChannelModeName, Anope::string>::iterator it = DefConModesOnParams.find(Name); + std::map<Anope::string, Anope::string>::iterator it = DefConModesOnParams.find(name); buf.clear(); @@ -98,18 +97,27 @@ struct DefconConfig static DefconConfig DConfig; -/**************************************************************************/ - -void defcon_sendlvls(CommandSource &source); -void runDefCon(); +static void runDefCon(); static Anope::string defconReverseModes(const Anope::string &modes); +static ServiceReference<GlobalService> GlobalService("GlobalService", "Global"); + +static Timer *timeout; + class DefConTimeout : public CallBack { int level; public: - DefConTimeout(Module *mod, int newlevel) : CallBack(mod, DConfig.timeout), level(newlevel) { } + DefConTimeout(Module *mod, int newlevel) : CallBack(mod, DConfig.timeout), level(newlevel) + { + timeout = this; + } + + ~DefConTimeout() + { + timeout = NULL; + } void Tick(time_t) anope_override { @@ -134,7 +142,6 @@ class DefConTimeout : public CallBack } } }; -static DefConTimeout *timeout; class CommandOSDefcon : public Command { @@ -175,7 +182,7 @@ class CommandOSDefcon : public Command if (lvl.empty()) { - source.Reply(_("Services are now at DEFCON \002%d\002"), DConfig.defaultlevel); + source.Reply(_("Services are now at DEFCON \002%d\002."), DConfig.defaultlevel); this->SendLevels(source); return; } @@ -197,16 +204,12 @@ class CommandOSDefcon : public Command FOREACH_MOD(I_OnDefconLevel, OnDefconLevel(newLevel)); - if (timeout) - { - delete timeout; - timeout = NULL; - } + delete timeout; if (DConfig.timeout) timeout = new DefConTimeout(this->module, 5); - source.Reply(_("Services are now at DEFCON \002%d\002"), DConfig.defaultlevel); + source.Reply(_("Services are now at DEFCON \002%d\002."), DConfig.defaultlevel); this->SendLevels(source); Log(LOG_ADMIN, source, this) << "to change defcon level to " << newLevel; @@ -256,8 +259,8 @@ class OSDefcon : public Module spacesepstream ss(DConfig.chanmodes); - DConfig.DefConModesOn.ClearFlags(); - DConfig.DefConModesOff.ClearFlags(); + DConfig.DefConModesOn.clear(); + DConfig.DefConModesOff.clear(); ss.GetToken(modes); /* Loop while there are modes to set */ @@ -287,8 +290,8 @@ class OSDefcon : public Module } else if (add) { - DConfig.DefConModesOn.SetFlag(cm->name); - DConfig.DefConModesOff.UnsetFlag(cm->name); + DConfig.DefConModesOn.insert(cm->name); + DConfig.DefConModesOff.erase(cm->name); if (cm->type == MODE_PARAM) { @@ -306,9 +309,9 @@ class OSDefcon : public Module DConfig.SetDefConParam(cmp->name, param); } } - else if (DConfig.DefConModesOn.HasFlag(cm->name)) + else if (DConfig.DefConModesOn.count(cm->name)) { - DConfig.DefConModesOn.UnsetFlag(cm->name); + DConfig.DefConModesOn.erase(cm->name); if (cm->type == MODE_PARAM) DConfig.UnsetDefConParam(cm->name); @@ -317,9 +320,9 @@ class OSDefcon : public Module } /* 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)) + if ((cm = ModeManager::FindChannelModeByName("REDIRECT")) && DConfig.DefConModesOn.count(cm->name) && !DConfig.DefConModesOn.count("LIMIT")) { - DConfig.DefConModesOn.UnsetFlag(CMODE_REDIRECT); + DConfig.DefConModesOn.erase("REDIRECT"); Log(this) << "DefConChanModes must lock mode +l as well to lock mode +L"; } @@ -408,34 +411,13 @@ class OSDefcon : public Module this->ParseModeString(); } - EventReturn OnUserConnect(User *u, bool &exempt) + EventReturn OnChannelModeSet(Channel *c, MessageSource &, const Anope::string &mname, const Anope::string ¶m) anope_override { - if (!exempt && u->server->IsSynced() && DConfig.Check(DEFCON_AKILL_NEW_CLIENTS) && !u->server->IsULined()) - { - if (DConfig.Check(DEFCON_AKILL_NEW_CLIENTS) && akills) - { - Log(OperServ, "operserv/defcon") << "DEFCON: adding akill for *@" << u->host; - XLine *x = new XLine("*@" + u->host, Config->OperServ, Anope::CurTime + DConfig.akillexpire, DConfig.akillreason, XLineManager::GenerateUID()); - x->by = Config->OperServ; - akills->AddXLine(x); - } + ChannelMode *cm = ModeManager::FindChannelModeByName(mname); - if (DConfig.Check(DEFCON_NO_NEW_CLIENTS) || DConfig.Check(DEFCON_AKILL_NEW_CLIENTS)) - u->Kill(Config->OperServ, DConfig.akillreason); - - return EVENT_STOP; - } - - return EVENT_CONTINUE; - } - - EventReturn OnChannelModeSet(Channel *c, MessageSource &, ChannelModeName Name, const Anope::string ¶m) anope_override - { - ChannelMode *cm = ModeManager::FindChannelModeByName(Name); - - if (DConfig.Check(DEFCON_FORCE_CHAN_MODES) && cm && DConfig.DefConModesOff.HasFlag(Name)) + if (DConfig.Check(DEFCON_FORCE_CHAN_MODES) && cm && DConfig.DefConModesOff.count(mname)) { - c->RemoveMode(OperServ, Name, param); + c->RemoveMode(OperServ, cm, param); return EVENT_STOP; } @@ -443,18 +425,18 @@ class OSDefcon : public Module return EVENT_CONTINUE; } - EventReturn OnChannelModeUnset(Channel *c, MessageSource &, ChannelModeName Name, const Anope::string &) anope_override + EventReturn OnChannelModeUnset(Channel *c, MessageSource &, const Anope::string &mname, const Anope::string &) anope_override { - ChannelMode *cm = ModeManager::FindChannelModeByName(Name); + ChannelMode *cm = ModeManager::FindChannelModeByName(mname); - if (DConfig.Check(DEFCON_FORCE_CHAN_MODES) && cm && DConfig.DefConModesOn.HasFlag(Name)) + if (DConfig.Check(DEFCON_FORCE_CHAN_MODES) && cm && DConfig.DefConModesOn.count(mname)) { Anope::string param; - if (DConfig.GetDefConParam(Name, param)) - c->SetMode(OperServ, Name, param); + if (DConfig.GetDefConParam(mname, param)) + c->SetMode(OperServ, cm, param); else - c->SetMode(OperServ, Name); + c->SetMode(OperServ, cm); return EVENT_STOP; @@ -469,7 +451,7 @@ class OSDefcon : public Module { if (DConfig.Check(DEFCON_NO_NEW_NICKS)) { - source.Reply(_("Services are in Defcon mode, Please try again later.")); + source.Reply(_("Services are in DefCon mode, please try again later.")); return EVENT_STOP; } } @@ -477,7 +459,7 @@ class OSDefcon : public Module { if (DConfig.Check(DEFCON_NO_MLOCK_CHANGE)) { - source.Reply(_("Services are in Defcon mode, Please try again later.")); + source.Reply(_("Services are in DefCon mode, please try again later.")); return EVENT_STOP; } } @@ -485,7 +467,7 @@ class OSDefcon : public Module { if (DConfig.Check(DEFCON_NO_NEW_CHANNELS)) { - source.Reply(_("Services are in Defcon mode, Please try again later.")); + source.Reply(_("Services are in DefCon mode, please try again later.")); return EVENT_STOP; } } @@ -493,7 +475,7 @@ class OSDefcon : public Module { if (DConfig.Check(DEFCON_NO_NEW_MEMOS)) { - source.Reply(_("Services are in Defcon mode, Please try again later.")); + source.Reply(_("Services are in DefCon mode, please try again later.")); return EVENT_STOP; } } @@ -501,9 +483,9 @@ class OSDefcon : public Module return EVENT_CONTINUE; } - void OnUserConnect(Reference<User> &u, bool &exempt) anope_override + void OnUserConnect(User *u, bool &exempt) anope_override { - if (exempt || !u || !u->server->IsSynced() || u->server->IsULined()) + if (exempt || !u->Quitting() || !u->server->IsSynced() || u->server->IsULined()) return; if (DConfig.Check(DEFCON_AKILL_NEW_CLIENTS) && akills) @@ -553,7 +535,7 @@ class OSDefcon : public Module { XLine x("*@" + u->host, Config->OperServ, Anope::CurTime + Config->SessionAutoKillExpiry, "Defcon session limit exceeded", XLineManager::GenerateUID()); akills->Send(NULL, &x); - Log(OperServ, "akill/defcon") << "[DEFCON] Added a temporary AKILL for \2*@" << u->host << "\2 due to excessive connections"; + Log(OperServ, "akill/defcon") << "[DEFCON] Added a temporary AKILL for \002*@" << u->host << "\002 due to excessive connections"; } else { @@ -577,34 +559,7 @@ class OSDefcon : public Module } }; -/** - * 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() +static void runDefCon() { if (DConfig.Check(DEFCON_FORCE_CHAN_MODES)) { diff --git a/modules/commands/os_dns.cpp b/modules/commands/os_dns.cpp index ec72f5a5d..d690ae55a 100644 --- a/modules/commands/os_dns.cpp +++ b/modules/commands/os_dns.cpp @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -10,48 +10,130 @@ static ServiceReference<DNS::Manager> dnsmanager("DNS::Manager", "dns/manager"); +class DNSZone; class DNSServer; -static std::vector<DNSServer *> dns_servers; + +static Serialize::Checker<std::vector<DNSZone *> > zones("DNSZone"); +static Serialize::Checker<std::vector<DNSServer *> > dns_servers("DNSServer"); static std::map<Anope::string, std::list<time_t> > server_quit_times; +struct DNSZone : Serializable +{ + Anope::string name; + std::set<Anope::string, ci::less> servers; + + DNSZone(const Anope::string &n) : Serializable("DNSZone"), name(n) + { + zones->push_back(this); + } + + ~DNSZone() + { + std::vector<DNSZone *>::iterator it = std::find(zones->begin(), zones->end(), this); + if (it != zones->end()) + zones->erase(it); + } + + void Serialize(Serialize::Data &data) const anope_override + { + data["name"] << name; + unsigned count = 0; + for (std::set<Anope::string, ci::less>::iterator it = servers.begin(), it_end = servers.end(); it != it_end; ++it) + data["server" + stringify(count++)] << *it; + } + + static Serializable* Unserialize(Serializable *obj, Serialize::Data &data) + { + DNSZone *zone; + Anope::string zone_name; + + data["name"] >> zone_name; + + if (obj) + { + zone = anope_dynamic_static_cast<DNSZone *>(obj); + data["name"] >> zone->name; + } + else + zone = new DNSZone(zone_name); + + zone->servers.clear(); + for (unsigned count = 0; true; ++count) + { + Anope::string server_str; + data["server" + stringify(count)] >> server_str; + if (server_str.empty()) + break; + zone->servers.insert(server_str); + } + + return zone; + } + + static DNSZone *Find(const Anope::string &name) + { + for (unsigned i = 0; i < zones->size(); ++i) + if (zones->at(i)->name.equals_ci(name)) + { + DNSZone *z = zones->at(i); + z->QueueUpdate(); + return z; + } + return NULL; + } +}; + class DNSServer : public Serializable { Anope::string server_name; std::vector<Anope::string> ips; unsigned limit; + /* wants to be in the pool */ bool pooled; + /* is actually in the pool */ + bool active; - DNSServer() : Serializable("DNSServer"), limit(0), pooled(false), repool(0) { dns_servers.push_back(this); } public: + std::set<Anope::string, ci::less> zones; time_t repool; - DNSServer(const Anope::string &sn) : Serializable("DNSServer"), server_name(sn), limit(0), pooled(false), repool(0) + DNSServer(const Anope::string &sn) : Serializable("DNSServer"), server_name(sn), limit(0), pooled(false), active(false), repool(0) { - dns_servers.push_back(this); + dns_servers->push_back(this); } ~DNSServer() { - std::vector<DNSServer *>::iterator it = std::find(dns_servers.begin(), dns_servers.end(), this); - if (it != dns_servers.end()) - dns_servers.erase(it); + std::vector<DNSServer *>::iterator it = std::find(dns_servers->begin(), dns_servers->end(), this); + if (it != dns_servers->end()) + dns_servers->erase(it); } const Anope::string &GetName() const { return server_name; } std::vector<Anope::string> &GetIPs() { return ips; } unsigned GetLimit() const { return limit; } void SetLimit(unsigned l) { limit = l; } - bool Pooled() const { return pooled; } + bool Pooled() const { return pooled; } void Pool(bool p) { + if (!p) + this->SetActive(p); pooled = p; + } + + bool Active() const { return pooled && active; } + void SetActive(bool p) + { + if (p) + this->Pool(p); + active = p; + if (dnsmanager) dnsmanager->UpdateSerial(); } - void Serialize(Serialize::Data &data) const anope_override { data["server_name"] << server_name; @@ -59,18 +141,25 @@ class DNSServer : public Serializable data["ip" + stringify(i)] << ips[i]; data["limit"] << limit; data["pooled"] << pooled; + unsigned count = 0; + for (std::set<Anope::string, ci::less>::iterator it = zones.begin(), it_end = zones.end(); it != it_end; ++it) + data["zone" + stringify(count++)] << *it; } static Serializable* Unserialize(Serializable *obj, Serialize::Data &data) { DNSServer *req; + Anope::string server_name; + + data["server_name"] >> server_name; if (obj) + { req = anope_dynamic_static_cast<DNSServer *>(obj); + req->server_name = server_name; + } else - req = new DNSServer(); - - data["server_name"] >> req->server_name; + req = new DNSServer(server_name); for (unsigned i = 0; true; ++i) { @@ -84,14 +173,28 @@ class DNSServer : public Serializable data["limit"] >> req->limit; data["pooled"] >> req->pooled; + req->zones.clear(); + for (unsigned i = 0; true; ++i) + { + Anope::string zone_str; + data["zone" + stringify(i)] >> zone_str; + if (zone_str.empty()) + break; + req->zones.insert(zone_str); + } + return req; } static DNSServer *Find(const Anope::string &s) { - for (unsigned i = 0; i < dns_servers.size(); ++i) - if (dns_servers[i]->GetName() == s) - return dns_servers[i]; + for (unsigned i = 0; i < dns_servers->size(); ++i) + if (dns_servers->at(i)->GetName().equals_ci(s)) + { + DNSServer *serv = dns_servers->at(i); + serv->QueueUpdate(); + return serv; + } return NULL; } }; @@ -100,7 +203,7 @@ class CommandOSDNS : public Command { void DisplayPoolState(CommandSource &source) { - if (dns_servers.empty()) + if (dns_servers->empty()) { source.Reply(_("There are no configured servers.")); return; @@ -108,9 +211,9 @@ class CommandOSDNS : public Command ListFormatter lf; lf.AddColumn("Server").AddColumn("IP").AddColumn("Limit").AddColumn("State"); - for (unsigned i = 0; i < dns_servers.size(); ++i) + for (unsigned i = 0; i < dns_servers->size(); ++i) { - DNSServer *s = dns_servers[i]; + DNSServer *s = dns_servers->at(i); Server *srv = Server::Find(s->GetName()); ListFormatter::ListEntry entry; @@ -127,8 +230,10 @@ class CommandOSDNS : public Command if (!srv) entry["State"] = "Split"; + else if (s->Active()) + entry["State"] = "Pooled/Active"; else if (s->Pooled()) - entry["State"] = "Pooled"; + entry["State"] = "Pooled/Not Active"; else entry["State"] = "Unpooled"; @@ -138,47 +243,187 @@ class CommandOSDNS : public Command std::vector<Anope::string> replies; lf.Process(replies); + if (!zones->empty()) + { + ListFormatter lf2; + lf2.AddColumn("Zone").AddColumn("Servers"); + + for (unsigned i = 0; i < zones->size(); ++i) + { + const DNSZone *z = zones->at(i); + + ListFormatter::ListEntry entry; + entry["Zone"] = z->name; + + Anope::string server_str; + for (std::set<Anope::string, ci::less>::iterator it = z->servers.begin(), it_end = z->servers.end(); it != it_end; ++it) + server_str += *it + " "; + server_str.trim(); + + if (server_str.empty()) + server_str = "None"; + + entry["Servers"] = server_str; + + lf2.AddEntry(entry); + } + + lf2.Process(replies); + } + for (unsigned i = 0; i < replies.size(); ++i) source.Reply(replies[i]); } - void OnAdd(CommandSource &source, const std::vector<Anope::string> ¶ms) + void AddZone(CommandSource &source, const std::vector<Anope::string> ¶ms) + { + const Anope::string &zone = params[1]; + + if (DNSZone::Find(zone)) + { + source.Reply(_("Zone %s already exists."), zone.c_str()); + return; + } + + Log(LOG_ADMIN, source, this) << "to add zone " << zone; + + new DNSZone(zone); + source.Reply(_("Added zone %s."), zone.c_str()); + } + + void DelZone(CommandSource &source, const std::vector<Anope::string> ¶ms) + { + const Anope::string &zone = params[1]; + + DNSZone *z = DNSZone::Find(zone); + if (!z) + { + source.Reply(_("Zone %s does not exist."), zone.c_str()); + return; + } + + Log(LOG_ADMIN, source, this) << "to delete zone " << z->name; + + for (std::set<Anope::string, ci::less>::iterator it = z->servers.begin(), it_end = z->servers.end(); it != it_end; ++it) + { + DNSServer *s = DNSServer::Find(*it); + if (s) + s->zones.erase(z->name); + } + + source.Reply(_("Zone %s removed."), z->name.c_str()); + delete z; + } + + void AddServer(CommandSource &source, const std::vector<Anope::string> ¶ms) { DNSServer *s = DNSServer::Find(params[1]); + const Anope::string &zone = params.size() > 2 ? params[2] : ""; if (s) { - source.Reply(_("Server %s already exists."), params[1].c_str()); + if (zone.empty()) + { + source.Reply(_("Server %s already exists."), s->GetName().c_str()); + } + else + { + DNSZone *z = DNSZone::Find(zone); + if (!z) + { + source.Reply(_("Zone %s does not exist."), zone.c_str()); + return; + } + else if (z->servers.count(s->GetName())) + { + source.Reply(_("Server %s is already in zone %s."), s->GetName().c_str(), z->name.c_str()); + return; + } + + z->servers.insert(s->GetName()); + s->zones.insert(zone); + + Log(LOG_ADMIN, source, this) << "to add server " << s->GetName() << " to zone " << z->name; + + source.Reply(_("Server %s added to zone %s."), s->GetName().c_str(), z->name.c_str()); + } + return; } - if (!Server::Find(params[1])) + Server *serv = Server::Find(params[1]); + if (!serv || serv == Me || serv->IsJuped()) { source.Reply(_("Server %s is not linked to the network."), params[1].c_str()); return; } s = new DNSServer(params[1]); - source.Reply(_("Added server %s."), s->GetName().c_str()); + if (zone.empty()) + { + Log(LOG_ADMIN, source, this) << "to add server " << s->GetName(); + source.Reply(_("Added server %s."), s->GetName().c_str()); + } + else + { + DNSZone *z = DNSZone::Find(zone); + if (!z) + { + source.Reply(_("Zone %s does not exist."), zone.c_str()); + delete s; + return; + } + + Log(LOG_ADMIN, source, this) << "to add server " << s->GetName() << " to zone " << zone; - Log(LOG_ADMIN, source, this) << "to add server " << s->GetName(); + z->servers.insert(s->GetName()); + s->zones.insert(z->name); + } } - void OnDel(CommandSource &source, const std::vector<Anope::string> ¶ms) + void DelServer(CommandSource &source, const std::vector<Anope::string> ¶ms) { DNSServer *s = DNSServer::Find(params[1]); + const Anope::string &zone = params.size() > 2 ? params[2] : ""; if (!s) { source.Reply(_("Server %s does not exist."), params[1].c_str()); return; } + else if (!zone.empty()) + { + DNSZone *z = DNSZone::Find(zone); + if (!z) + { + source.Reply(_("Zone %s does not exist."), zone.c_str()); + return; + } + else if (!z->servers.count(s->GetName())) + { + source.Reply(_("Server %s is not in zone %s."), s->GetName().c_str(), z->name.c_str()); + return; + } + + Log(LOG_ADMIN, source, this) << "to remove server " << s->GetName() << " from zone " << z->name; + + z->servers.erase(s->GetName()); + source.Reply(_("Removed server %s from zone %s."), s->GetName().c_str(), z->name.c_str()); + return; + } else if (Server::Find(s->GetName())) { source.Reply(_("Server %s must be quit before it can be deleted."), s->GetName().c_str()); return; } + for (std::set<Anope::string, ci::less>::iterator it = s->zones.begin(), it_end = s->zones.end(); it != it_end; ++it) + { + DNSZone *z = DNSZone::Find(*it); + if (z) + z->servers.erase(s->GetName()); + } + Log(LOG_ADMIN, source, this) << "to delete server " << s->GetName(); source.Reply(_("Removed server %s."), s->GetName().c_str()); delete s; @@ -223,7 +468,7 @@ class CommandOSDNS : public Command source.Reply(_("Added IP %s to %s."), params[2].c_str(), s->GetName().c_str()); Log(LOG_ADMIN, source, this) << "to add IP " << params[2] << " to " << s->GetName(); - if (s->Pooled() && dnsmanager) + if (s->Active() && dnsmanager) dnsmanager->UpdateSerial(); } @@ -250,7 +495,7 @@ class CommandOSDNS : public Command s->Pool(false); } - if (s->Pooled() && dnsmanager) + if (s->Active() && dnsmanager) dnsmanager->UpdateSerial(); return; @@ -286,7 +531,7 @@ class CommandOSDNS : public Command } } else - source.Reply(_("Unknown SET option")); + source.Reply(_("Unknown SET option.")); } void OnPool(CommandSource &source, const std::vector<Anope::string> ¶ms) @@ -311,9 +556,10 @@ class CommandOSDNS : public Command else if (s->GetIPs().empty()) { source.Reply(_("Server %s has no configured IPs."), s->GetName().c_str()); + return; } - s->Pool(true); + s->SetActive(true); source.Reply(_("Pooled %s."), s->GetName().c_str()); Log(LOG_ADMIN, source, this) << "to pool " << s->GetName(); @@ -344,12 +590,14 @@ class CommandOSDNS : public Command public: CommandOSDNS(Module *creator) : Command(creator, "operserv/dns", 0, 3) { - this->SetDesc(_("Manage the DNS zone for this network")); - this->SetSyntax(_("ADD \037server.name\037")); - this->SetSyntax(_("DEL \037server.name\037")); + this->SetDesc(_("Manage DNS zones for this network")); + this->SetSyntax(_("ADDZONE \037zone.name\037")); + this->SetSyntax(_("DELZONE \037zone.name\037")); + this->SetSyntax(_("ADDSERVER \037server.name\037 [\037zone.name\037]")); + this->SetSyntax(_("DELSERVER \037server.name\037 [\037zone.name\037]")); this->SetSyntax(_("ADDIP \037server.name\037 \037ip\037")); this->SetSyntax(_("DELIP \037server.name\037 \037ip\037")); - this->SetSyntax(_("SET \037server.name\037 \37option\37 \037value\037")); + this->SetSyntax(_("SET \037server.name\037 \037option\037 \037value\037")); this->SetSyntax(_("POOL \037server.name\037")); this->SetSyntax(_("DEPOOL \037server.name\037")); } @@ -358,10 +606,14 @@ class CommandOSDNS : public Command { if (params.empty()) this->DisplayPoolState(source); - else if (params[0].equals_ci("ADD") && params.size() > 1) - this->OnAdd(source, params); - else if (params[0].equals_ci("DEL") && params.size() > 1) - this->OnDel(source, params); + else if (params[0].equals_ci("ADDZONE") && params.size() > 1) + this->AddZone(source, params); + else if (params[0].equals_ci("DELZONE") && params.size() > 1) + this->DelZone(source, params); + else if (params[0].equals_ci("ADDSERVER") && params.size() > 1) + this->AddServer(source, params); + else if (params[0].equals_ci("DELSERVER") && params.size() > 1) + this->DelServer(source, params); else if (params[0].equals_ci("ADDIP") && params.size() > 2) this->AddIP(source, params); else if (params[0].equals_ci("DELIP") && params.size() > 2) @@ -380,18 +632,27 @@ class CommandOSDNS : public Command { this->SendSyntax(source); source.Reply(" "); - source.Reply(_("This command allows managing a DNS zone\n" - "used for controlling what servers users\n" - "are directed to when connecting. Omitting\n" - "all parameters prints out the status of\n" - "the DNS zone.\n")); + source.Reply(_("This command allows managing DNS zones used for controlling what servers users\n" + "are directed to when connecting. Omitting all parameters prints out the status of\n" + "the DNS zone.\n" + " \n" + "\002ADDZONE\002 adds a zone, eg us.yournetwork.tld. Servers can then be added to this\n" + "zone with the \002ADDSERVER\002 command.\n" + " \n" + "The \002ADDSERVER\002 command adds a server to the given zone. When a query is done, the\n" + "zone in question is served if it exists, else all servers in all zones are served.\n" + "A server may be in more than one zone.\n" + " \n" + "The \002ADDIP\002 command associates an IP with a server.\n" + " \n" + "The \002POOL\002 and \002DEPOOL\002 commands actually add and remove servers to their given zones.")); return true; } }; class ModuleDNS : public Module { - Serialize::Type dns_type; + Serialize::Type zone_type, dns_type; CommandOSDNS commandosdns; time_t ttl; @@ -403,14 +664,29 @@ class ModuleDNS : public Module public: ModuleDNS(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, SUPPORTED), - dns_type("DNSServer", DNSServer::Unserialize), commandosdns(this) + zone_type("DNSZone", DNSZone::Unserialize), dns_type("DNSServer", DNSServer::Unserialize), commandosdns(this) { this->SetAuthor("Anope"); - Implementation i[] = { I_OnReload, I_OnNewServer, I_OnServerQuit, I_OnUserConnect, I_OnUserLogoff, I_OnDnsRequest }; + Implementation i[] = { I_OnReload, I_OnNewServer, I_OnServerQuit, I_OnUserConnect, I_OnPreUserLogoff, I_OnDnsRequest }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); this->OnReload(); + + for (unsigned j = 0; j < dns_servers->size(); ++j) + { + DNSServer *s = dns_servers->at(j); + if (s->Pooled() && Server::Find(s->GetName())) + s->SetActive(true); + } + } + + ~ModuleDNS() + { + for (unsigned i = zones->size(); i > 0; --i) + delete zones->at(i - 1); + for (unsigned i = dns_servers->size(); i > 0; --i) + delete dns_servers->at(i - 1); } void OnReload() anope_override @@ -427,55 +703,56 @@ class ModuleDNS : public Module void OnNewServer(Server *s) anope_override { - if (this->readd_connected_servers) + if (s == Me || s->IsJuped()) + return; + if (!Me->IsSynced() || this->readd_connected_servers) { DNSServer *dns = DNSServer::Find(s->GetName()); - if (dns && !dns->Pooled() && !dns->GetIPs().empty() && dns->GetLimit() < s->users) + if (dns && dns->Pooled() && !dns->Active() && !dns->GetIPs().empty()) { - dns->Pool(true); + dns->SetActive(true); Log(this) << "Pooling server " << s->GetName(); } } } - void OnServerQuit(Server *s) anope_override { DNSServer *dns = DNSServer::Find(s->GetName()); - if (dns && dns->Pooled()) + if (dns && dns->Pooled() && dns->Active()) { - dns->Pool(false); + dns->SetActive(false); Log(this) << "Depooling delinked server " << s->GetName(); } } - void OnUserConnect(Reference<User> &u, bool &exempt) anope_override + void OnUserConnect(User *u, bool &exempt) anope_override { - if (u && u->server) + if (!u->Quitting() && u->server) { DNSServer *s = DNSServer::Find(u->server->GetName()); /* Check for user limit reached */ - if (s && s->GetLimit() && s->Pooled() && u->server->users >= s->GetLimit()) + if (s && s->Pooled() && s->Active() && s->GetLimit() && u->server->users >= s->GetLimit()) { Log(this) << "Depooling full server " << s->GetName() << ": " << u->server->users << " users"; - s->Pool(false); + s->SetActive(false); } } } - void OnUserLogoff(User *u) anope_override + void OnPreUserLogoff(User *u) anope_override { if (u && u->server) { DNSServer *s = DNSServer::Find(u->server->GetName()); - if (!s) + if (!s || !s->Pooled()) return; /* Check for dropping under userlimit */ - if (s->GetLimit() && !s->Pooled() && s->GetLimit() > u->server->users) + if (s->GetLimit() && !s->Active() && s->GetLimit() > u->server->users) { Log(this) << "Pooling server " << s->GetName(); - s->Pool(true); + s->SetActive(true); } if (this->user_drop_mark > 0) @@ -485,21 +762,21 @@ class ModuleDNS : public Module if (times.size() > static_cast<unsigned>(this->user_drop_mark)) times.pop_front(); - if (s->Pooled() && times.size() == static_cast<unsigned>(this->user_drop_mark)) + if (times.size() == static_cast<unsigned>(this->user_drop_mark)) { time_t diff = Anope::CurTime - *times.begin(); /* Check for very fast user drops */ - if (diff <= this->user_drop_time) + if (s->Active() && diff <= this->user_drop_time) { Log(this) << "Depooling server " << s->GetName() << ": dropped " << this->user_drop_mark << " users in " << diff << " seconds"; s->repool = Anope::CurTime + this->user_drop_readd_time; - s->Pool(false); + s->SetActive(false); } /* Check for needing to re-pool a server that dropped users */ - else if (s->repool && s->repool <= Anope::CurTime && !s->Pooled()) + else if (!s->Active() && s->repool && s->repool <= Anope::CurTime) { - s->Pool(true); + s->SetActive(true); s->repool = 0; Log(this) << "Pooling server " << s->GetName(); } @@ -517,39 +794,68 @@ class ModuleDNS : public Module if (q.type != DNS::QUERY_A && q.type != DNS::QUERY_AAAA && q.type != DNS::QUERY_AXFR) return; - for (unsigned i = 0; i < dns_servers.size(); ++i) + DNSZone *zone = DNSZone::Find(q.name); + size_t answer_size = packet->answers.size(); + if (zone) { - DNSServer *s = dns_servers[i]; - if (!s->Pooled()) - continue; + for (std::set<Anope::string, ci::less>::iterator it = zone->servers.begin(), it_end = zone->servers.end(); it != it_end; ++it) + { + DNSServer *s = DNSServer::Find(*it); + if (!s || !s->Active()) + continue; - for (unsigned j = 0; j < s->GetIPs().size(); ++j) + for (unsigned j = 0; j < s->GetIPs().size(); ++j) + { + DNS::QueryType q_type = s->GetIPs()[j].find(':') != Anope::string::npos ? DNS::QUERY_AAAA : DNS::QUERY_A; + + if (q.type == DNS::QUERY_AXFR || q_type == q.type) + { + DNS::ResourceRecord rr(q.name, q_type); + rr.ttl = this->ttl; + rr.rdata = s->GetIPs()[j]; + packet->answers.push_back(rr); + } + } + } + } + + if (packet->answers.size() == answer_size) + { + /* Default zone */ + for (unsigned i = 0; i < dns_servers->size(); ++i) { - DNS::QueryType q_type = s->GetIPs()[j].find(':') != Anope::string::npos ? DNS::QUERY_AAAA : DNS::QUERY_A; + DNSServer *s = dns_servers->at(i); + if (!s->Active()) + continue; - if (q.type == DNS::QUERY_AXFR || q_type == q.type) + for (unsigned j = 0; j < s->GetIPs().size(); ++j) { - DNS::ResourceRecord rr(q.name, q_type); - rr.ttl = this->ttl; - rr.rdata = s->GetIPs()[j]; - packet->answers.push_back(rr); + DNS::QueryType q_type = s->GetIPs()[j].find(':') != Anope::string::npos ? DNS::QUERY_AAAA : DNS::QUERY_A; + + if (q.type == DNS::QUERY_AXFR || q_type == q.type) + { + DNS::ResourceRecord rr(q.name, q_type); + rr.ttl = this->ttl; + rr.rdata = s->GetIPs()[j]; + packet->answers.push_back(rr); + } } } } - if (packet->answers.empty()) + if (packet->answers.size() == answer_size) { static time_t last_warn = 0; if (last_warn + 60 < Anope::CurTime) { last_warn = Anope::CurTime; - Log(this) << "os_dns: Warning! There are no pooled servers!"; + Log(this) << "Warning! There are no pooled servers!"; } /* Something messed up, just return them all and hope one is available */ - for (unsigned i = 0; i < dns_servers.size(); ++i) + for (unsigned i = 0; i < dns_servers->size(); ++i) { - DNSServer *s = dns_servers[i]; + DNSServer *s = dns_servers->at(i); for (unsigned j = 0; j < s->GetIPs().size(); ++j) { @@ -565,9 +871,9 @@ class ModuleDNS : public Module } } - if (packet->answers.empty()) + if (packet->answers.size() == answer_size) { - Log(this) << "os_dns: Error! There are no servers with any IPs. At all."; + Log(this) << "Error! There are no servers with any IPs. At all."; /* Send back an empty answer anyway */ } } diff --git a/modules/commands/os_forbid.cpp b/modules/commands/os_forbid.cpp index 08710b223..e3a0c42b8 100644 --- a/modules/commands/os_forbid.cpp +++ b/modules/commands/os_forbid.cpp @@ -1,6 +1,6 @@ /* OperServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -16,22 +16,22 @@ class MyForbidService : public ForbidService { - std::vector<ForbidData *> forbidData; + Serialize::Checker<std::vector<ForbidData *> > forbid_data; public: - MyForbidService(Module *m) : ForbidService(m) { } + MyForbidService(Module *m) : ForbidService(m), forbid_data("ForbidData") { } void AddForbid(ForbidData *d) anope_override { - this->forbidData.push_back(d); + this->forbid_data->push_back(d); } void RemoveForbid(ForbidData *d) anope_override { - std::vector<ForbidData *>::iterator it = std::find(this->forbidData.begin(), this->forbidData.end(), d); - if (it != this->forbidData.end()) - this->forbidData.erase(it); - d->Destroy(); + std::vector<ForbidData *>::iterator it = std::find(this->forbid_data->begin(), this->forbid_data->end(), d); + if (it != this->forbid_data->end()) + this->forbid_data->erase(it); + delete d; } ForbidData *FindForbid(const Anope::string &mask, ForbidType ftype) anope_override @@ -49,9 +49,9 @@ class MyForbidService : public ForbidService const std::vector<ForbidData *> &GetForbids() anope_override { - for (unsigned i = this->forbidData.size(); i > 0; --i) + for (unsigned i = this->forbid_data->size(); i > 0; --i) { - ForbidData *d = this->forbidData[i - 1]; + ForbidData *d = this->forbid_data->at(i - 1); if (d->expires && Anope::CurTime >= d->expires) { @@ -64,12 +64,12 @@ class MyForbidService : public ForbidService ftype = "email"; Log(LOG_NORMAL, "expire/forbid") << "Expiring forbid for " << d->mask << " type " << ftype; - this->forbidData.erase(this->forbidData.begin() + i - 1); - d->Destroy(); + this->forbid_data->erase(this->forbid_data->begin() + i - 1); + delete d; } } - return this->forbidData; + return this->forbid_data; } }; @@ -80,9 +80,9 @@ class CommandOSForbid : public Command CommandOSForbid(Module *creator) : Command(creator, "operserv/forbid", 1, 5), fs("ForbidService", "forbid") { this->SetDesc(_("Forbid usage of nicknames, channels, and emails")); - this->SetSyntax(_("ADD {NICK|CHAN|EMAIL} [+\037expiry\037] \037entry\037\002 [\037reason\037]")); - this->SetSyntax(_("DEL {NICK|CHAN|EMAIL} \037entry\037")); - this->SetSyntax(_("LIST (NICK|CHAN|EMAIL)")); + this->SetSyntax(_("ADD {NICK|CHAN|EMAIL|REGISTER} [+\037expiry\037] \037entry\037\002 [\037reason\037]")); + this->SetSyntax(_("DEL {NICK|CHAN|EMAIL|REGISTER} \037entry\037")); + this->SetSyntax(_("LIST (NICK|CHAN|EMAIL|REGISTER)")); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override @@ -100,6 +100,8 @@ class CommandOSForbid : public Command ftype = FT_CHAN; else if (subcommand.equals_ci("EMAIL")) ftype = FT_EMAIL; + else if (subcommand.equals_ci("REGISTER")) + ftype = FT_REGISTER; if (command.equals_ci("ADD") && params.size() > 3 && ftype != FT_NONE) { @@ -152,7 +154,7 @@ class CommandOSForbid : public Command this->fs->AddForbid(d); Log(LOG_ADMIN, source, this) << "to add a forbid on " << entry << " of type " << subcommand; - source.Reply(_("Added a%s forbid on %s to expire on %s"), ftype == FT_CHAN ? "n" : "", entry.c_str(), d->expires ? Anope::strftime(d->expires).c_str() : "never"); + source.Reply(_("Added a forbid on %s to expire on %s."), entry.c_str(), d->expires ? Anope::strftime(d->expires).c_str() : "never"); } else if (command.equals_ci("DEL") && params.size() > 2 && ftype != FT_NONE) { @@ -189,6 +191,8 @@ class CommandOSForbid : public Command stype = "CHAN"; else if (d->type == FT_EMAIL) stype = "EMAIL"; + else if (d->type == FT_REGISTER) + stype = "REGISTER"; else continue; @@ -224,10 +228,14 @@ class CommandOSForbid : public Command source.Reply(" "); source.Reply(_("Forbid allows you to forbid usage of certain nicknames, channels,\n" "and email addresses. Wildcards are accepted for all entries.")); + if (!Config->RegexEngine.empty()) - source.Reply(" \n" - "Regex matches are also supported using the %s engine.\n" - "Enclose your pattern in // if this desired.", Config->RegexEngine.c_str()); + { + source.Reply(" "); + source.Reply(_("Regex matches are also supported using the %s engine.\n" + "Enclose your pattern in // if this is desired."), Config->RegexEngine.c_str()); + } + return true; } }; @@ -248,9 +256,9 @@ class OSForbid : public Module ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } - void OnUserConnect(Reference<User> &u, bool &exempt) anope_override + void OnUserConnect(User *u, bool &exempt) anope_override { - if (!u || exempt) + if (u->Quitting() || exempt) return; this->OnUserNickChange(u, ""); @@ -258,7 +266,7 @@ class OSForbid : public Module void OnUserNickChange(User *u, const Anope::string &) anope_override { - if (u->HasMode(UMODE_OPER)) + if (u->HasMode("OPER")) return; ForbidData *d = this->forbidService.FindForbid(u->nick, FT_NICK); @@ -277,7 +285,7 @@ class OSForbid : public Module void OnJoinChannel(User *u, Channel *c) anope_override { - if (u->HasMode(UMODE_OPER) || !OperServ) + if (u->HasMode("OPER") || !OperServ) return; ForbidData *d = this->forbidService.FindForbid(c->name, FT_CHAN); @@ -288,16 +296,16 @@ class OSForbid : public Module XLine x(c->name, OperServ->nick, Anope::CurTime + Config->CSInhabit, d->reason); IRCD->SendSQLine(NULL, &x); } - else if (!c->HasFlag(CH_INHABIT)) + else if (!c->HasExt("INHABIT")) { /* Join ChanServ and set a timer for this channel to part ChanServ later */ c->Hold(); /* Set +si to prevent rejoin */ - c->SetMode(NULL, CMODE_NOEXTERNAL); - c->SetMode(NULL, CMODE_TOPIC); - c->SetMode(NULL, CMODE_SECRET); - c->SetMode(NULL, CMODE_INVITE); + c->SetMode(NULL, "NOEXTERNAL"); + c->SetMode(NULL, "TOPIC"); + c->SetMode(NULL, "SECRET"); + c->SetMode(NULL, "INVITE"); } if (d->reason.empty()) @@ -315,9 +323,9 @@ class OSForbid : public Module if (d != NULL) { if (source.IsOper()) - source.Reply(_("Nick \2%s\2 is forbidden by %s: %s"), params[0].c_str(), d->creator.c_str(), d->reason.c_str()); + source.Reply(_("Nick \002%s\002 is forbidden by %s: %s"), params[0].c_str(), d->creator.c_str(), d->reason.c_str()); else - source.Reply(_("Nick \2%s\2 is forbidden."), params[0].c_str()); + source.Reply(_("Nick \002%s\002 is forbidden."), params[0].c_str()); return EVENT_STOP; } } @@ -327,9 +335,9 @@ class OSForbid : public Module if (d != NULL) { if (source.IsOper()) - source.Reply(_("Channel \2%s\2 is forbidden by %s: %s"), params[0].c_str(), d->creator.c_str(), d->reason.c_str()); + source.Reply(_("Channel \002%s\002 is forbidden by %s: %s"), params[0].c_str(), d->creator.c_str(), d->reason.c_str()); else - source.Reply(_("Channel \2%s\2 is forbidden."), params[0].c_str()); + source.Reply(_("Channel \002%s\002 is forbidden."), params[0].c_str()); return EVENT_STOP; } } @@ -337,7 +345,14 @@ class OSForbid : public Module return EVENT_CONTINUE; else if (command->name == "nickserv/register" && params.size() > 1) { - ForbidData *d = this->forbidService.FindForbid(params[1], FT_EMAIL); + ForbidData *d = this->forbidService.FindForbid(source.GetNick(), FT_REGISTER); + if (d != NULL) + { + source.Reply(NICK_CANNOT_BE_REGISTERED, source.GetNick().c_str()); + return EVENT_STOP; + } + + d = this->forbidService.FindForbid(params[1], FT_EMAIL); if (d != NULL) { source.Reply("Your email address is not allowed, choose a different one."); @@ -353,6 +368,15 @@ class OSForbid : public Module return EVENT_STOP; } } + else if (command->name == "chanserv/register" && !params.empty()) + { + ForbidData *d = this->forbidService.FindForbid(params[0], FT_REGISTER); + if (d != NULL) + { + source.Reply(CHAN_X_INVALID, params[0].c_str()); + return EVENT_STOP; + } + } return EVENT_CONTINUE; } diff --git a/modules/commands/os_forbid.h b/modules/commands/os_forbid.h index 07619f65e..b4d1ce7ce 100644 --- a/modules/commands/os_forbid.h +++ b/modules/commands/os_forbid.h @@ -6,7 +6,8 @@ enum ForbidType FT_NONE, FT_NICK, FT_CHAN, - FT_EMAIL + FT_EMAIL, + FT_REGISTER }; struct ForbidData : Serializable diff --git a/modules/commands/os_ignore.cpp b/modules/commands/os_ignore.cpp index f959e7ebc..3d30237fa 100644 --- a/modules/commands/os_ignore.cpp +++ b/modules/commands/os_ignore.cpp @@ -1,6 +1,6 @@ /* OperServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -93,7 +93,7 @@ class OSIgnoreService : public IgnoreService { for (; ign != ign_end; ++ign) { - Entry ignore_mask(CMODE_BEGIN, ign->mask); + Entry ignore_mask("", ign->mask); if (ignore_mask.Matches(u, true)) break; } @@ -259,8 +259,8 @@ class CommandOSIgnore : public Command CommandOSIgnore(Module *creator) : Command(creator, "operserv/ignore", 1, 4) { this->SetDesc(_("Modify the Services ignore list")); - this->SetSyntax(_("ADD \037time\037 \037nick\037 \037reason\037")); - this->SetSyntax(_("DEL \037nick\037")); + this->SetSyntax(_("ADD \037time\037 {\037nick\037|\037mask\037} [\037reason\037]")); + this->SetSyntax(_("DEL {\037nick\037|\037mask\037}")); this->SetSyntax(_("LIST")); this->SetSyntax(_("CLEAR")); } @@ -290,19 +290,22 @@ class CommandOSIgnore : public Command source.Reply(_("Allows Services Operators to make Services ignore a nick or mask\n" "for a certain time or until the next restart. The default\n" "time format is seconds. You can specify it by using units.\n" - "Valid units are: \037s\037 for seconds, \037m\037 for minutes, \n" - "\037h\037 for hours and \037d\037 for days. \n" + "Valid units are: \037s\037 for seconds, \037m\037 for minutes,\n" + "\037h\037 for hours and \037d\037 for days.\n" "Combinations of these units are not permitted.\n" "To make Services permanently ignore the user, type 0 as time.\n" - "When adding a \037mask\037, it should be in the format user@host\n" - "or nick!user@host, everything else will be considered a nick.\n" - "Wildcards are permitted.\n" + "When adding a \037mask\037, it should be in the format nick!user@host,\n" + "everything else will be considered a nick. Wildcards are permitted.\n" " \n" "Ignores will not be enforced on IRC Operators.")); + if (!Config->RegexEngine.empty()) - source.Reply(" \n" - "Regex matches are also supported using the %s engine.\n" - "Enclose your pattern in // if this desired.", Config->RegexEngine.c_str()); + { + source.Reply(" "); + source.Reply(_("Regex matches are also supported using the %s engine.\n" + "Enclose your pattern in // if this is desired."), Config->RegexEngine.c_str()); + } + return true; } }; @@ -325,7 +328,7 @@ class OSIgnore : public Module EventReturn OnBotPrivmsg(User *u, BotInfo *bi, Anope::string &message) anope_override { - if (!u->HasMode(UMODE_OPER) && this->osignoreservice.Find(u->nick)) + if (!u->HasMode("OPER") && this->osignoreservice.Find(u->nick)) return EVENT_STOP; return EVENT_CONTINUE; diff --git a/modules/commands/os_ignore.h b/modules/commands/os_ignore.h index 1990d95c4..6c3e237ab 100644 --- a/modules/commands/os_ignore.h +++ b/modules/commands/os_ignore.h @@ -1,6 +1,6 @@ /* OperServ ignore interface * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/commands/os_jupe.cpp b/modules/commands/os_jupe.cpp index 49095129c..fa79c9098 100644 --- a/modules/commands/os_jupe.cpp +++ b/modules/commands/os_jupe.cpp @@ -1,6 +1,6 @@ /* OperServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -29,15 +29,15 @@ class CommandOSJupe : public Command Server *server = Server::Find(jserver); if (!IRCD->IsHostValid(jserver) || jserver.find('.') == Anope::string::npos) - source.Reply(_("Please use a valid server name when juping")); + source.Reply(_("Please use a valid server name when juping.")); else if (server && (server == Me || server == Me->GetLinks().front())) - source.Reply(_("You can not jupe your services server or your uplink server.")); + source.Reply(_("You can not jupe your Services' pseudoserver or your uplink server.")); else { Anope::string rbuf = "Juped by " + source.GetNick() + (!reason.empty() ? ": " + reason : ""); if (server) IRCD->SendSquit(server, rbuf); - Server *juped_server = new Server(Me, jserver, 1, rbuf, Servers::TS6_SID_Retrieve(), SERVER_JUPED); + Server *juped_server = new Server(Me, jserver, 1, rbuf, Servers::TS6_SID_Retrieve(), true); IRCD->SendServer(juped_server); Log(LOG_ADMIN, source, this) << "on " << jserver << " (" << rbuf << ")"; diff --git a/modules/commands/os_kick.cpp b/modules/commands/os_kick.cpp index 5f33a4bbc..37866af74 100644 --- a/modules/commands/os_kick.cpp +++ b/modules/commands/os_kick.cpp @@ -1,6 +1,6 @@ /* OperServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/commands/os_kill.cpp b/modules/commands/os_kill.cpp index 83cd81f58..898e601e6 100644 --- a/modules/commands/os_kill.cpp +++ b/modules/commands/os_kill.cpp @@ -1,6 +1,6 @@ /* OperServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/commands/os_list.cpp b/modules/commands/os_list.cpp index dfb0c00c8..f4de45203 100644 --- a/modules/commands/os_list.cpp +++ b/modules/commands/os_list.cpp @@ -1,6 +1,6 @@ /* OperServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -26,13 +26,13 @@ class CommandOSChanList : public Command { const Anope::string &pattern = !params.empty() ? params[0] : ""; const Anope::string &opt = params.size() > 1 ? params[1] : ""; - std::list<ChannelModeName> Modes; + std::set<Anope::string> modes; User *u2; if (!opt.empty() && opt.equals_ci("SECRET")) { - Modes.push_back(CMODE_SECRET); - Modes.push_back(CMODE_PRIVATE); + modes.insert("SECRET"); + modes.insert("PRIVATE"); } ListFormatter list; @@ -42,12 +42,12 @@ class CommandOSChanList : public Command { source.Reply(_("\002%s\002 channel list:"), u2->nick.c_str()); - for (UChannelList::iterator uit = u2->chans.begin(), uit_end = u2->chans.end(); uit != uit_end; ++uit) + for (User::ChanUserList::iterator uit = u2->chans.begin(), uit_end = u2->chans.end(); uit != uit_end; ++uit) { - ChannelContainer *cc = *uit; + ChanUserContainer *cc = *uit; - if (!Modes.empty()) - for (std::list<ChannelModeName>::iterator it = Modes.begin(), it_end = Modes.end(); it != it_end; ++it) + if (!modes.empty()) + for (std::set<Anope::string>::iterator it = modes.begin(), it_end = modes.end(); it != it_end; ++it) if (!cc->chan->HasMode(*it)) continue; @@ -69,8 +69,8 @@ class CommandOSChanList : public Command if (!pattern.empty() && !Anope::Match(c->name, pattern, false, true)) continue; - if (!Modes.empty()) - for (std::list<ChannelModeName>::iterator it = Modes.begin(), it_end = Modes.end(); it != it_end; ++it) + if (!modes.empty()) + for (std::set<Anope::string>::iterator it = modes.begin(), it_end = modes.end(); it != it_end; ++it) if (!c->HasMode(*it)) continue; @@ -102,10 +102,14 @@ class CommandOSChanList : public Command "is given, lists only the channels the user using it is on. If SECRET is\n" "specified, lists only channels matching \002pattern\002 that have the +s or\n" "+p mode.")); + if (!Config->RegexEngine.empty()) - source.Reply(" \n" - "Regex matches are also supported using the %s engine.\n" - "Enclose your pattern in // if this desired.", Config->RegexEngine.c_str()); + { + source.Reply(" "); + source.Reply(_("Regex matches are also supported using the %s engine.\n" + "Enclose your pattern in // if this is desired."), Config->RegexEngine.c_str()); + } + return true; } }; @@ -124,10 +128,10 @@ class CommandOSUserList : public Command const Anope::string &pattern = !params.empty() ? params[0] : ""; const Anope::string &opt = params.size() > 1 ? params[1] : ""; Channel *c; - std::list<UserModeName> Modes; + std::set<Anope::string> modes; if (!opt.empty() && opt.equals_ci("INVISIBLE")) - Modes.push_back(UMODE_INVIS); + modes.insert("INVIS"); ListFormatter list; list.AddColumn("Name").AddColumn("Mask"); @@ -136,12 +140,12 @@ class CommandOSUserList : public Command { source.Reply(_("\002%s\002 users list:"), pattern.c_str()); - for (CUserList::iterator cuit = c->users.begin(), cuit_end = c->users.end(); cuit != cuit_end; ++cuit) + for (Channel::ChanUserList::iterator cuit = c->users.begin(), cuit_end = c->users.end(); cuit != cuit_end; ++cuit) { - UserContainer *uc = *cuit; + ChanUserContainer *uc = *cuit; - if (!Modes.empty()) - for (std::list<UserModeName>::iterator it = Modes.begin(), it_end = Modes.end(); it != it_end; ++it) + if (!modes.empty()) + for (std::set<Anope::string>::iterator it = modes.begin(), it_end = modes.end(); it != it_end; ++it) if (!uc->user->HasMode(*it)) continue; @@ -169,8 +173,8 @@ class CommandOSUserList : public Command Anope::string mask = u2->nick + "!" + u2->GetIdent() + "@" + u2->GetDisplayedHost(), mask2 = u2->nick + "!" + u2->GetIdent() + "@" + u2->host, mask3 = u2->nick + "!" + u2->GetIdent() + "@" + (!u2->ip.empty() ? u2->ip : u2->host); if (!Anope::Match(mask, pattern) && !Anope::Match(mask2, pattern) && !Anope::Match(mask3, pattern)) continue; - if (!Modes.empty()) - for (std::list<UserModeName>::iterator mit = Modes.begin(), mit_end = Modes.end(); mit != mit_end; ++mit) + if (!modes.empty()) + for (std::set<Anope::string>::iterator mit = modes.begin(), mit_end = modes.end(); mit != mit_end; ++mit) if (!u2->HasMode(*mit)) continue; } @@ -203,10 +207,14 @@ class CommandOSUserList : public Command "the format nick!user@host). If \002channel\002 is given, lists only users\n" "that are on the given channel. If INVISIBLE is specified, only users\n" "with the +i flag will be listed.")); + if (!Config->RegexEngine.empty()) - source.Reply(" \n" - "Regex matches are also supported using the %s engine.\n" - "Enclose your pattern in // if this desired.", Config->RegexEngine.c_str()); + { + source.Reply(" "); + source.Reply(_("Regex matches are also supported using the %s engine.\n" + "Enclose your pattern in // if this is desired."), Config->RegexEngine.c_str()); + } + return true; } }; diff --git a/modules/commands/os_login.cpp b/modules/commands/os_login.cpp index 735562819..76b9e15ba 100644 --- a/modules/commands/os_login.cpp +++ b/modules/commands/os_login.cpp @@ -1,6 +1,6 @@ /* OperServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -21,6 +21,7 @@ class CommandOSLogin : public Command { this->SetDesc(Anope::printf(_("Login to %s"), Config->OperServ.c_str())); this->SetSyntax(_("\037password\037")); + this->RequireUser(true); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override @@ -28,9 +29,6 @@ class CommandOSLogin : public Command const Anope::string &password = params[0]; User *u = source.GetUser(); - if (!u) - return; - Oper *o = source.nc->o; if (o == NULL) source.Reply(_("No oper block for your nick.")); @@ -46,7 +44,7 @@ class CommandOSLogin : public Command else { Log(LOG_ADMIN, source, this) << "and successfully identified to " << source.service->nick; - u->Extend("os_login_password_correct", NULL); + u->Extend("os_login_password_correct"); source.Reply(_("Password accepted.")); } @@ -69,16 +67,14 @@ class CommandOSLogout : public Command public: CommandOSLogout(Module *creator) : Command(creator, "operserv/logout", 0, 0) { - this->SetDesc(Anope::printf(_("Logout from to %s"), Config->OperServ.c_str())); + this->SetDesc(Anope::printf(_("Logout from %s"), Config->OperServ.c_str())); this->SetSyntax(""); + this->RequireUser(true); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { User *u = source.GetUser(); - if (!u) - return; - Oper *o = source.nc->o; if (o == NULL) source.Reply(_("No oper block for your nick.")); diff --git a/modules/commands/os_logsearch.cpp b/modules/commands/os_logsearch.cpp index 7ad806330..6eec4ba74 100644 --- a/modules/commands/os_logsearch.cpp +++ b/modules/commands/os_logsearch.cpp @@ -1,6 +1,6 @@ /* OperServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -54,7 +54,7 @@ class CommandOSLogSearch : public Command } catch (const ConvertException &) { - source.Reply(_("Invalid duration %s, using %d days"), dur.c_str(), days); + source.Reply(_("Invalid duration %s, using %d days."), dur.c_str(), days); } } break; @@ -70,12 +70,12 @@ class CommandOSLogSearch : public Command } catch (const ConvertException &) { - source.Reply(_("Invalid limit %s, using %d"), dur.c_str(), replies); + source.Reply(_("Invalid limit %s, using %d."), dur.c_str(), replies); } } break; default: - source.Reply(_("Unknown parameter %s"), params[i].c_str()); + source.Reply(_("Unknown parameter: %s"), params[i].c_str()); } } @@ -110,18 +110,18 @@ class CommandOSLogSearch : public Command unsigned found = matches.size(); if (!found) { - source.Reply(_("No matches for \2%s\2 found."), search_string.c_str()); + source.Reply(_("No matches for \002%s\002 found."), search_string.c_str()); return; } while (matches.size() > static_cast<unsigned>(replies)) matches.pop_front(); - source.Reply(_("Matches for \2%s\2:"), search_string.c_str()); + source.Reply(_("Matches for \002%s\002:"), search_string.c_str()); unsigned count = 0; for (std::list<Anope::string>::iterator it = matches.begin(), it_end = matches.end(); it != it_end; ++it) source.Reply("#%d: %s", ++count, it->c_str()); - source.Reply(_("Showed %d/%d matches for \2%s\2"), matches.size(), found, search_string.c_str()); + source.Reply(_("Showed %d/%d matches for \002%s\002."), matches.size(), found, search_string.c_str()); } bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override @@ -134,11 +134,11 @@ class CommandOSLogSearch : public Command "and the number of replies to limit to. By default this\n" "command searches one week of logs, and limits replies\n" "to 50.\n" - "\n" + " \n" "For example:\n" - " \2LOGSEARCH +21d +500l Anope\2\n" + " \002LOGSEARCH +21d +500l Anope\002\n" " Searches the last 21 days worth of logs for messages\n" - " containing Anope and lists the most recent 500 of them.\n")); + " containing Anope and lists the most recent 500 of them.")); return true; } }; diff --git a/modules/commands/os_mode.cpp b/modules/commands/os_mode.cpp index 676ef7ea5..d20c88d4e 100644 --- a/modules/commands/os_mode.cpp +++ b/modules/commands/os_mode.cpp @@ -1,6 +1,6 @@ /* OperServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -16,10 +16,11 @@ class CommandOSMode : public Command { public: - CommandOSMode(Module *creator) : Command(creator, "operserv/mode", 2, 2) + CommandOSMode(Module *creator) : Command(creator, "operserv/mode", 2, 3) { this->SetDesc(_("Change channel modes")); this->SetSyntax(_("\037channel\037 \037modes\037")); + this->SetSyntax(_("\037channel\037 CLEAR [ALL]")); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override @@ -32,6 +33,32 @@ class CommandOSMode : public Command source.Reply(CHAN_X_NOT_IN_USE, target.c_str()); else if (c->bouncy_modes) source.Reply(_("Services is unable to change modes. Are your servers' U:lines configured correctly?")); + else if (modes.equals_ci("CLEAR")) + { + bool all = params.size() > 2 && params[2].equals_ci("ALL"); + + const Channel::ModeList chmodes = c->GetModes(); + for (Channel::ModeList::const_iterator it = chmodes.begin(), it_end = chmodes.end(); it != it_end; ++it) + c->RemoveMode(c->ci->WhoSends(), it->first, it->second, false); + + if (all) + { + for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ++it) + { + ChanUserContainer *uc = *it; + + if (uc->user->HasMode("OPER")) + continue; + + for (std::set<Anope::string>::iterator it2 = uc->status.modes.begin(), it2_end = uc->status.modes.end(); it2 != it2_end; ++it2) + c->RemoveMode(c->ci->WhoSends(), *it2, uc->user->GetUID(), false); + } + + source.Reply(_("All modes cleared on %s."), c->name.c_str()); + } + else + source.Reply(_("Non-status modes cleared on %s."), c->name.c_str()); + } else { spacesepstream sep(modes); @@ -97,8 +124,10 @@ class CommandOSMode : public Command { this->SendSyntax(source); source.Reply(" "); - source.Reply(_("Allows Services operators to change modes for any channel.\n" - "Parameters are the same as for the standard /MODE command.")); + source.Reply(_("Allows Services Operators to change modes for any channel.\n" + "Parameters are the same as for the standard /MODE command.\n" + "Alternatively, CLEAR may be given to clear all modes on the channel.\n" + "If CLEAR ALL is given then all modes, including user status, is removed.\n")); return true; } }; @@ -135,7 +164,7 @@ class CommandOSUMode : public Command { this->SendSyntax(source); source.Reply(" "); - source.Reply(_("Allows Services operators to change modes for any user.\n" + source.Reply(_("Allows Services Operators to change modes for any user.\n" "Parameters are the same as for the standard /MODE command.")); return true; } diff --git a/modules/commands/os_modinfo.cpp b/modules/commands/os_modinfo.cpp index 15e2d73a2..014418e6e 100644 --- a/modules/commands/os_modinfo.cpp +++ b/modules/commands/os_modinfo.cpp @@ -1,6 +1,6 @@ /* OperServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -56,7 +56,7 @@ class CommandOSModInfo : public Command } } else - source.Reply(_("No information about module \002%s\002 is available"), file.c_str()); + source.Reply(_("No information about module \002%s\002 is available."), file.c_str()); return; } @@ -65,7 +65,7 @@ class CommandOSModInfo : public Command { this->SendSyntax(source); source.Reply(" "); - source.Reply(_("This command lists information about the specified loaded module")); + source.Reply(_("This command lists information about the specified loaded module.")); return true; } }; @@ -158,7 +158,7 @@ class CommandOSModList : public Command Module *protocol = ModuleManager::FindFirstOf(PROTOCOL); - source.Reply(_("Current Module list:")); + source.Reply(_("Current module list:")); for (std::list<Module *>::iterator it = ModuleManager::Modules.begin(), it_end = ModuleManager::Modules.end(); it != it_end; ++it) { @@ -215,9 +215,9 @@ class CommandOSModList : public Command } } if (!count) - source.Reply(_("No modules currently loaded")); + source.Reply(_("No modules currently loaded.")); else - source.Reply(_("%d Modules loaded."), count); + source.Reply(_("%d modules loaded."), count); return; } diff --git a/modules/commands/os_module.cpp b/modules/commands/os_module.cpp index 75bc82af6..aa9673019 100644 --- a/modules/commands/os_module.cpp +++ b/modules/commands/os_module.cpp @@ -1,6 +1,6 @@ /* OperServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -30,12 +30,12 @@ class CommandOSModLoad : public Command if (status == MOD_ERR_OK) { Log(LOG_ADMIN, source, this) << "to load module " << mname; - source.Reply(_("Module \002%s\002 loaded"), mname.c_str()); + source.Reply(_("Module \002%s\002 loaded."), mname.c_str()); } else if (status == MOD_ERR_EXISTS) source.Reply(_("Module \002%s\002 is already loaded."), mname.c_str()); else - source.Reply(_("Unable to load module \002%s\002"), mname.c_str()); + source.Reply(_("Unable to load module \002%s\002."), mname.c_str()); return; } @@ -44,7 +44,7 @@ class CommandOSModLoad : public Command { this->SendSyntax(source); source.Reply(" "); - source.Reply(_("This command loads the module named FileName from the modules\n" + source.Reply(_("This command loads the module named \037modname\037 from the modules\n" "directory.")); return true; } @@ -72,14 +72,14 @@ class CommandOSModReLoad : public Command if (!m->handle || m->GetPermanent()) { - source.Reply(_("Unable to remove module \002%s\002"), m->name.c_str()); + source.Reply(_("Unable to remove module \002%s\002."), m->name.c_str()); return; } Module *protocol = ModuleManager::FindFirstOf(PROTOCOL); if (m->type == PROTOCOL && m != protocol) { - source.Reply(_("You may not reload this module directly, instead reload %s."), protocol ? protocol->name.c_str() : "(unknown)"); + source.Reply(_("You can not reload this module directly, instead reload %s."), protocol ? protocol->name.c_str() : "(unknown)"); return; } @@ -89,7 +89,7 @@ class CommandOSModReLoad : public Command if (status != MOD_ERR_OK) { - source.Reply(_("Unable to remove module \002%s\002"), mname.c_str()); + source.Reply(_("Unable to remove module \002%s\002."), mname.c_str()); return; } @@ -97,7 +97,7 @@ class CommandOSModReLoad : public Command if (status == MOD_ERR_OK) { Log(LOG_ADMIN, source, this) << "to reload module " << mname; - source.Reply(_("Module \002%s\002 reloaded"), mname.c_str()); + source.Reply(_("Module \002%s\002 reloaded."), mname.c_str()); } else { @@ -107,7 +107,7 @@ class CommandOSModReLoad : public Command Anope::Quitting = true; } else - source.Reply(_("Unable to load module \002%s\002"), mname.c_str()); + source.Reply(_("Unable to load module \002%s\002."), mname.c_str()); } return; @@ -117,7 +117,7 @@ class CommandOSModReLoad : public Command { this->SendSyntax(source); source.Reply(" "); - source.Reply(_("This command reloads the module named FileName.")); + source.Reply(_("This command reloads the module named \037modname\037.")); return true; } }; @@ -144,7 +144,7 @@ class CommandOSModUnLoad : public Command if (!m->handle || m->GetPermanent() || m->type == PROTOCOL) { - source.Reply(_("Unable to remove module \002%s\002"), m->name.c_str()); + source.Reply(_("Unable to remove module \002%s\002."), m->name.c_str()); return; } @@ -155,10 +155,10 @@ class CommandOSModUnLoad : public Command if (status == MOD_ERR_OK) { Log(LOG_ADMIN, source, this) << "to unload module " << mname; - source.Reply(_("Module \002%s\002 unloaded"), mname.c_str()); + source.Reply(_("Module \002%s\002 unloaded."), mname.c_str()); } else - source.Reply(_("Unable to remove module \002%s\002"), mname.c_str()); + source.Reply(_("Unable to remove module \002%s\002."), mname.c_str()); return; } @@ -167,7 +167,7 @@ class CommandOSModUnLoad : public Command { this->SendSyntax(source); source.Reply(" "); - source.Reply(_("This command unloads the module named FileName from the modules\n" + source.Reply(_("This command unloads the module named \037modname\037 from the modules\n" "directory.")); return true; } diff --git a/modules/commands/os_news.cpp b/modules/commands/os_news.cpp index eea480d13..0833fbaa6 100644 --- a/modules/commands/os_news.cpp +++ b/modules/commands/os_news.cpp @@ -1,6 +1,6 @@ /* OperServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at info@anope.org * * Please read COPYING and README for further details. @@ -72,7 +72,7 @@ class MyNewsService : public NewsService { for (unsigned i = 0; i < 3; ++i) for (unsigned j = 0; j < newsItems[i].size(); ++j) - newsItems[i][j]->Destroy(); + delete newsItems[i][j]; } void AddNewsItem(NewsItem *n) @@ -86,7 +86,7 @@ class MyNewsService : public NewsService std::vector<NewsItem *>::iterator it = std::find(list.begin(), list.end(), n); if (it != list.end()) list.erase(it); - n->Destroy(); + delete n; } std::vector<NewsItem *> &GetNewsList(NewsType t) @@ -137,7 +137,7 @@ class NewsBase : public Command for (unsigned i = 0; i < replies.size(); ++i) source.Reply(replies[i]); - source.Reply(_("End of \2news\2 list.")); + source.Reply(_("End of news list.")); } return; @@ -399,15 +399,15 @@ class OSNews : public Module ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } - void OnUserModeSet(User *u, UserModeName Name) anope_override + void OnUserModeSet(User *u, const Anope::string &mname) anope_override { - if (Name == UMODE_OPER) + if (mname == "OPER") DisplayNews(u, NEWS_OPER); } - void OnUserConnect(Reference<User> &user, bool &) anope_override + void OnUserConnect(User *user, bool &) anope_override { - if (!user || !user->server->IsSynced()) + if (user->Quitting() || !user->server->IsSynced()) return; DisplayNews(user, NEWS_LOGON); diff --git a/modules/commands/os_noop.cpp b/modules/commands/os_noop.cpp index fa9361f7b..91a8dbfd9 100644 --- a/modules/commands/os_noop.cpp +++ b/modules/commands/os_noop.cpp @@ -1,6 +1,6 @@ /* OperServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -31,8 +31,8 @@ class CommandOSNOOP : public Command Server *s = Server::Find(server); if (s == NULL) source.Reply(_("Server %s does not exist."), server.c_str()); - else if (s == Me || s->HasFlag(SERVER_JUPED)) - source.Reply(_("You may not NOOP services.")); + else if (s == Me || s->IsJuped()) + source.Reply(_("You can not NOOP Services.")); else if (cmd.equals_ci("SET")) { /* Remove the O:lines */ @@ -49,7 +49,7 @@ class CommandOSNOOP : public Command User *u2 = it->second; ++it; - if (u2->server == s && u2->HasMode(UMODE_OPER)) + if (u2->server == s && u2->HasMode("OPER")) u2->Kill(Config->OperServ, reason); } } @@ -89,9 +89,9 @@ class OSNOOP : public Module ModuleManager::Attach(I_OnUserModeSet, this); } - void OnUserModeSet(User *u, UserModeName Name) anope_override + void OnUserModeSet(User *u, const Anope::string &mname) anope_override { - if (Name == UMODE_OPER && u->server->HasExt("noop")) + if (mname == "OPER" && u->server->HasExt("noop")) { Anope::string *setter = u->server->GetExt<ExtensibleItemClass<Anope::string> *>("noop"); if (setter) diff --git a/modules/commands/os_oline.cpp b/modules/commands/os_oline.cpp index 7b8be5768..ba6d3f54c 100644 --- a/modules/commands/os_oline.cpp +++ b/modules/commands/os_oline.cpp @@ -1,6 +1,6 @@ /* OperServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -34,7 +34,7 @@ class CommandOSOLine : public Command else if (u2 && flag[0] == '+') { IRCD->SendSVSO(source.service, nick, flag); - u2->SetMode(source.service, UMODE_OPER); + u2->SetMode(source.service, "OPER"); u2->SendMessage(source.service, _("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()); Log(LOG_ADMIN, source, this) << "for " << nick; @@ -42,7 +42,7 @@ class CommandOSOLine : public Command else if (u2 && flag[0] == '-') { IRCD->SendSVSO(source.service, nick, flag); - source.Reply(_("Operflags \002%s\002 have been added for \002%s\002."), flag.c_str(), nick.c_str()); + source.Reply(_("Operflags \002%s\002 have been removed from \002%s\002."), flag.c_str(), nick.c_str()); Log(LOG_ADMIN, source, this) << "for " << nick; } else @@ -55,7 +55,7 @@ class CommandOSOLine : public Command { this->SendSyntax(source); source.Reply(" "); - source.Reply(_("Allows Services Opers to give Operflags to any user.\n" + source.Reply(_("Allows Services Operators to give Operflags to any user.\n" "Flags have to be prefixed with a \"+\" or a \"-\". To\n" "remove all flags simply type a \"-\" instead of any flags.")); return true; diff --git a/modules/commands/os_oper.cpp b/modules/commands/os_oper.cpp index b014a1271..91efcf575 100644 --- a/modules/commands/os_oper.cpp +++ b/modules/commands/os_oper.cpp @@ -1,6 +1,6 @@ /* OperServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -53,10 +53,10 @@ class CommandOSOper : public Command public: CommandOSOper(Module *creator) : Command(creator, "operserv/oper", 1, 3) { - this->SetDesc(_("View and change services operators")); + this->SetDesc(_("View and change Services Operators")); this->SetSyntax(_("ADD \037oper\037 \037type\037")); - this->SetSyntax(_("DEL [\037oper\037]")); - this->SetSyntax(_("INFO [\037type\037]")); + this->SetSyntax(_("DEL \037oper\037")); + this->SetSyntax(_("INFO \037type\037")); this->SetSyntax(_("LIST")); } @@ -73,18 +73,18 @@ class CommandOSOper : public Command if (na == NULL) source.Reply(NICK_X_NOT_REGISTERED, oper.c_str()); else if (na->nc->o) - source.Reply(_("Nick \2%s\2 is already an operator."), na->nick.c_str()); + source.Reply(_("Nick \002%s\002 is already an operator."), na->nick.c_str()); else { OperType *ot = OperType::Find(otype); if (ot == NULL) - source.Reply(_("Oper type \2%s\2 has not been configured."), otype.c_str()); + source.Reply(_("Oper type \002%s\002 has not been configured."), otype.c_str()); else { na->nc->o = new MyOper(na->nc->display, ot); Log(LOG_ADMIN, source, this) << "ADD " << na->nick << " as type " << ot->GetName(); - source.Reply("%s (%s) added to the \2%s\2 list.", na->nick.c_str(), na->nc->display.c_str(), ot->GetName().c_str()); + source.Reply("%s (%s) added to the \002%s\002 list.", na->nick.c_str(), na->nc->display.c_str(), ot->GetName().c_str()); } } } @@ -96,7 +96,7 @@ class CommandOSOper : public Command if (na == NULL) source.Reply(NICK_X_NOT_REGISTERED, oper.c_str()); else if (!na->nc || !na->nc->o) - source.Reply(_("Nick \2%s\2 is not a services operator."), oper.c_str()); + source.Reply(_("Nick \002%s\002 is not a Services Operator."), oper.c_str()); else { delete na->nc->o; @@ -133,14 +133,14 @@ class CommandOSOper : public Command fulltype += " " + params[2]; OperType *ot = OperType::Find(fulltype); if (ot == NULL) - source.Reply(_("Oper type \2%s\2 has not been configured."), fulltype.c_str()); + source.Reply(_("Oper type \002%s\002 has not been configured."), fulltype.c_str()); else { if (ot->GetCommands().empty()) - source.Reply(_("Opertype \2%s\2 has no allowed commands."), ot->GetName().c_str()); + source.Reply(_("Opertype \002%s\002 has no allowed commands."), ot->GetName().c_str()); else { - source.Reply(_("Available commands for \2%s\2:"), ot->GetName().c_str()); + source.Reply(_("Available commands for \002%s\002:"), ot->GetName().c_str()); Anope::string buf; std::list<Anope::string> cmds = ot->GetCommands(); for (std::list<Anope::string>::const_iterator it = cmds.begin(), it_end = cmds.end(); it != it_end; ++it) @@ -159,10 +159,10 @@ class CommandOSOper : public Command } } if (ot->GetPrivs().empty()) - source.Reply(_("Opertype \2%s\2 has no allowed privileges."), ot->GetName().c_str()); + source.Reply(_("Opertype \002%s\002 has no allowed privileges."), ot->GetName().c_str()); else { - source.Reply(_("Available privileges for \2%s\2:"), ot->GetName().c_str()); + source.Reply(_("Available privileges for \002%s\002:"), ot->GetName().c_str()); Anope::string buf; std::list<Anope::string> privs = ot->GetPrivs(); for (std::list<Anope::string>::const_iterator it = privs.begin(), it_end = privs.end(); it != it_end; ++it) @@ -181,7 +181,7 @@ class CommandOSOper : public Command } } if (!ot->modes.empty()) - source.Reply(_("Opertype \2%s\2 receives modes \2%s\2 once identifying."), ot->GetName().c_str(), ot->modes.c_str()); + source.Reply(_("Opertype \002%s\002 receives modes \002%s\002 once identified."), ot->GetName().c_str(), ot->modes.c_str()); } } else @@ -194,7 +194,7 @@ class CommandOSOper : public Command { this->SendSyntax(source); source.Reply(" "); - source.Reply(_("Allows you to change and view services operators.\n" + source.Reply(_("Allows you to change and view Services Operators.\n" "Note that operators removed by this command but are still set in\n" "the configuration file are not permanently affected by this.")); return true; diff --git a/modules/commands/os_reload.cpp b/modules/commands/os_reload.cpp index e7a07054f..0370bcd2e 100644 --- a/modules/commands/os_reload.cpp +++ b/modules/commands/os_reload.cpp @@ -1,6 +1,6 @@ /* OperServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -49,7 +49,7 @@ class CommandOSReload : public Command source.Reply(" "); source.Reply(_("Causes Services to reload the configuration file. Note that\n" "some directives still need the restart of the Services to\n" - "take effect (such as Services' nicknames, activation of the \n" + "take effect (such as Services' nicknames, activation of the\n" "session limitation, etc.)")); return true; } diff --git a/modules/commands/os_session.cpp b/modules/commands/os_session.cpp index 27157d511..949aabbe8 100644 --- a/modules/commands/os_session.cpp +++ b/modules/commands/os_session.cpp @@ -1,6 +1,6 @@ /* OperServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -17,25 +17,25 @@ class MySessionService : public SessionService { SessionMap Sessions; - ExceptionVector Exceptions; + Serialize::Checker<ExceptionVector> Exceptions; public: - MySessionService(Module *m) : SessionService(m) { } + MySessionService(Module *m) : SessionService(m), Exceptions("Exception") { } void AddException(Exception *e) anope_override { - this->Exceptions.push_back(e); + this->Exceptions->push_back(e); } void DelException(Exception *e) anope_override { - ExceptionVector::iterator it = std::find(this->Exceptions.begin(), this->Exceptions.end(), e); - if (it != this->Exceptions.end()) - this->Exceptions.erase(it); + 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) anope_override { - for (std::vector<Exception *>::const_iterator it = this->Exceptions.begin(), it_end = this->Exceptions.end(); it != it_end; ++it) + 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) || Anope::Match(u->ip, e->mask)) @@ -46,7 +46,7 @@ class MySessionService : public SessionService Exception *FindException(const Anope::string &host) anope_override { - for (std::vector<Exception *>::const_iterator it = this->Exceptions.begin(), it_end = this->Exceptions.end(); it != it_end; ++it) + 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)) @@ -93,7 +93,7 @@ class ExpireTimer : public Timer void Tick(time_t) anope_override { - if (!session_service) + if (!session_service || Anope::NoExpire) return; for (unsigned i = session_service->GetExceptions().size(); i > 0; --i) { @@ -103,7 +103,7 @@ class ExpireTimer : public Timer continue; Log(OperServ, "expire/exception") << "Session exception for " << e->mask << "has expired."; session_service->DelException(e); - e->Destroy(); + delete e; } } }; @@ -144,7 +144,7 @@ class ExceptionDelCallback : public NumberList FOREACH_MOD(I_OnExceptionDel, OnExceptionDel(source, e)); session_service->DelException(e); - e->Destroy(); + delete e; } }; @@ -250,8 +250,8 @@ class CommandOSSession : public Command source.Reply(" "); source.Reply(_("Allows Services Operators to view the session list.\n" "\002SESSION LIST\002 lists hosts with at least \037threshold\037 sessions.\n" - "The threshold must be a number greater than 1. This is to \n" - "prevent accidental listing of the large number of single \n" + "The threshold must be a number greater than 1. This is to\n" + "prevent accidental listing of the large number of single\n" "session hosts.\n" "\002SESSION VIEW\002 displays detailed information about a specific\n" "host - including the current session count and session limit.\n" @@ -352,7 +352,7 @@ class CommandOSException : public Command EventReturn MOD_RESULT; FOREACH_RESULT(I_OnExceptionAdd, OnExceptionAdd(exception)); if (MOD_RESULT == EVENT_STOP) - exception->Destroy(); + delete exception; else { session_service->AddException(exception); @@ -568,7 +568,7 @@ class CommandOSException : public Command this->SendSyntax(source); source.Reply(" "); source.Reply(_("Allows Services Operators to manipulate the list of hosts that\n" - "have specific session limits - allowing certain machines, \n" + "have specific session limits - allowing certain machines,\n" "such as shell servers, to carry more than the default number\n" "of clients at a time. Once a host reaches its session limit,\n" "all clients attempting to connect from that host will be\n" @@ -593,7 +593,7 @@ class CommandOSException : public Command "sessions if the optional mask is given, the list is limited\n" "to those sessions 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" + "person who added the exception, its session limit, reason,\n" "host mask and the expiry date and time.\n" " \n" "Note that a connecting client will \"use\" the first exception\n" @@ -664,7 +664,7 @@ class OSSession : public Module XLine *x = new XLine(akillmask, Config->OperServ, Anope::CurTime + Config->SessionAutoKillExpiry, "Session limit exceeded", XLineManager::GenerateUID()); akills->AddXLine(x); akills->Send(NULL, x); - Log(OperServ, "akill/session") << "Added a temporary AKILL for \2" << akillmask << "\2 due to excessive connections"; + Log(OperServ, "akill/session") << "Added a temporary AKILL for \002" << akillmask << "\002 due to excessive connections"; } else { @@ -713,18 +713,18 @@ class OSSession : public Module { this->SetAuthor("Anope"); - Implementation i[] = { I_OnUserConnect, I_OnUserLogoff }; + Implementation i[] = { I_OnUserConnect, I_OnPreUserLogoff }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); ModuleManager::SetPriority(this, PRIORITY_FIRST); } - void OnUserConnect(Reference<User> &user, bool &exempt) anope_override + void OnUserConnect(User *user, bool &exempt) anope_override { - if (user && Config->LimitSessions) + if (!user->Quitting() && Config->LimitSessions) this->AddSession(user, exempt); } - void OnUserLogoff(User *u) anope_override + void OnPreUserLogoff(User *u) anope_override { if (Config->LimitSessions && (!u->server || !u->server->IsULined())) this->DelSession(u); diff --git a/modules/commands/os_set.cpp b/modules/commands/os_set.cpp index 1592e7936..90d4f70d9 100644 --- a/modules/commands/os_set.cpp +++ b/modules/commands/os_set.cpp @@ -1,6 +1,6 @@ /* OperServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -55,7 +55,7 @@ class CommandOSSet : public Command source.Reply(_("Services are now in \002read-write\002 mode.")); } else - source.Reply(_("Setting for READONLY must be \002on\002 or \002off\002.")); + source.Reply(_("Setting for READONLY must be \002ON\002 or \002OFF\002.")); return; } @@ -79,21 +79,21 @@ class CommandOSSet : public Command * Rob **/ if (!Config->SuperAdmin) - source.Reply(_("Superadmin can not be set because it is not enabled in the configuration")); + source.Reply(_("SuperAdmin can not be set because it is not enabled in the configuration.")); else if (setting.equals_ci("ON")) { source.GetUser()->super_admin = true; - source.Reply(_("You are now a SuperAdmin")); + source.Reply(_("You are now a SuperAdmin.")); Log(LOG_ADMIN, source, this) << "SUPERADMIN ON"; } else if (setting.equals_ci("OFF")) { source.GetUser()->super_admin = false; - source.Reply(_("You are no longer a SuperAdmin")); + source.Reply(_("You are no longer a SuperAdmin.")); Log(LOG_ADMIN, source, this) << "SUPERADMIN OFF"; } else - source.Reply(_("Setting for SuperAdmin must be \002on\002 or \002off\002.")); + source.Reply(_("Setting for SuperAdmin must be \002ON\002 or \002OFF\002.")); return; } @@ -112,13 +112,13 @@ class CommandOSSet : public Command { Anope::Debug = 1; Log(LOG_ADMIN, source, this) << "DEBUG ON"; - source.Reply(_("Services are now in debug mode.")); + source.Reply(_("Services are now in \002debug\002 mode.")); } else if (setting.equals_ci("OFF") || setting == "0") { Log(LOG_ADMIN, source, this) << "DEBUG OFF"; Anope::Debug = 0; - source.Reply(_("Services are now in non-debug mode.")); + source.Reply(_("Services are now in \002non-debug\002 mode.")); } else { @@ -126,7 +126,7 @@ class CommandOSSet : public Command { Anope::Debug = convertTo<int>(setting); Log(LOG_ADMIN, source, this) << "DEBUG " << Anope::Debug; - source.Reply(_("Services are now in debug mode (level %d)."), Anope::Debug); + source.Reply(_("Services are now in \002debug\002 mode (level %d)."), Anope::Debug); return; } catch (const ConvertException &) { } @@ -160,7 +160,7 @@ class CommandOSSet : public Command source.Reply(_("Services are now in \002expire\002 mode.")); } else - source.Reply(_("Setting for NOEXPIRE must be \002on\002 or \002off\002.")); + source.Reply(_("Setting for NOEXPIRE must be \002ON\002 or \002OFF\002.")); return; } @@ -202,7 +202,7 @@ class CommandOSSet : public Command " READONLY Set read-only or read-write mode\n" " DEBUG Activate or deactivate debug mode\n" " NOEXPIRE Activate or deactivate no expire mode\n" - " SUPERADMIN Activate or deactivate super-admin mode\n" + " SUPERADMIN Activate or deactivate SuperAdmin mode\n" " LIST List the options")); } else if (subcommand.equals_ci("LIST")) diff --git a/modules/commands/os_shutdown.cpp b/modules/commands/os_shutdown.cpp index 2f7827be3..29d1713d5 100644 --- a/modules/commands/os_shutdown.cpp +++ b/modules/commands/os_shutdown.cpp @@ -1,6 +1,6 @@ /* OperServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/commands/os_stats.cpp b/modules/commands/os_stats.cpp index 18e2e89fd..779b8bbf5 100644 --- a/modules/commands/os_stats.cpp +++ b/modules/commands/os_stats.cpp @@ -1,6 +1,6 @@ /* OperServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -133,7 +133,7 @@ class CommandOSStats : public Command time_t uptime = Anope::CurTime - Anope::StartTime; source.Reply(_("Current users: \002%d\002 (\002%d\002 ops)"), UserListByNick.size(), OperCount); source.Reply(_("Maximum users: \002%d\002 (%s)"), MaxUserCount, Anope::strftime(MaxUserTime).c_str()); - source.Reply(_("Services up %s"), Anope::Duration(uptime).c_str()); + source.Reply(_("Services up %s."), Anope::Duration(uptime).c_str()); return; } @@ -197,7 +197,7 @@ class CommandOSStats : public Command akills("XLineManager", "xlinemanager/sgline"), snlines("XLineManager", "xlinemanager/snline"), sqlines("XLineManager", "xlinemanager/sqline") { this->SetDesc(_("Show status of Services and network")); - this->SetSyntax(_("[AKILL | ALL | HASH | RESET | UPLINK]")); + this->SetSyntax(_("[AKILL | HASH | UPLINK | UPTIME | ALL | RESET]")); } void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override @@ -210,17 +210,17 @@ class CommandOSStats : public Command if (extra.equals_ci("ALL") || extra.equals_ci("AKILL")) this->DoStatsAkill(source); - if (extra.empty() || extra.equals_ci("ALL") || extra.equals_ci("UPTIME")) - this->DoStatsUptime(source); + if (extra.equals_ci("ALL") || extra.equals_ci("HASH")) + this->DoStatsHash(source); if (extra.equals_ci("ALL") || extra.equals_ci("UPLINK")) this->DoStatsUplink(source); - if (extra.equals_ci("ALL") || extra.equals_ci("HASH")) - this->DoStatsHash(source); + if (extra.empty() || extra.equals_ci("ALL") || extra.equals_ci("UPTIME")) + this->DoStatsUptime(source); - if (!extra.empty() && !extra.equals_ci("ALL") && !extra.equals_ci("AKILL") && !extra.equals_ci("UPLINK") && !extra.equals_ci("HASH")) - source.Reply(_("Unknown STATS option \002%s\002."), extra.c_str()); + if (!extra.empty() && !extra.equals_ci("ALL") && !extra.equals_ci("AKILL") && !extra.equals_ci("HASH") && !extra.equals_ci("UPLINK") && !extra.equals_ci("UPTIME")) + source.Reply(_("Unknown STATS option: \002%s\002"), extra.c_str()); } bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override diff --git a/modules/commands/os_svs.cpp b/modules/commands/os_svs.cpp new file mode 100644 index 000000000..0a0ae9638 --- /dev/null +++ b/modules/commands/os_svs.cpp @@ -0,0 +1,176 @@ +/* OperServ core functions + * + * (C) 2003-2013 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + */ + +/*************************************************************************/ + +#include "module.h" + +class CommandOSSVSNick : public Command +{ + public: + CommandOSSVSNick(Module *creator) : Command(creator, "operserv/svsnick", 2, 2) + { + this->SetDesc(_("Forcefully change a user's nickname")); + this->SetSyntax(_("\037nick\037 \037newnick\037")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + const Anope::string &nick = params[0]; + Anope::string newnick = params[1]; + User *u2; + + if (!IRCD->CanSVSNick) + { + source.Reply(_("Your IRCd does not support SVSNICK.")); + return; + } + + /* 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()); + newnick = params[1].substr(0, Config->NickLen); + } + + /* Check for valid characters */ + if (!IRCD->IsNickValid(newnick)) + { + source.Reply(_("Nick \002%s\002 is an illegal nickname and cannot be used."), newnick.c_str()); + return; + } + + /* Check for a nick in use or a forbidden/suspended nick */ + if (!(u2 = User::Find(nick, true))) + source.Reply(NICK_X_NOT_IN_USE, nick.c_str()); + else if (!nick.equals_ci(newnick) && User::Find(newnick)) + source.Reply(_("Nick \002%s\002 is currently in use."), newnick.c_str()); + else + { + source.Reply(_("The nick \002%s\002 is now being changed to \002%s\002."), nick.c_str(), newnick.c_str()); + Log(LOG_ADMIN, source, this) << "to change " << nick << " to " << newnick; + IRCD->SendForceNickChange(u2, newnick, Anope::CurTime); + } + return; + } + + bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Forcefully changes a user's nickname from \037nick\037 to \037newnick\037.")); + return true; + } +}; + +class CommandOSSVSJoin : public Command +{ + public: + CommandOSSVSJoin(Module *creator) : Command(creator, "operserv/svsjoin", 2, 2) + { + this->SetDesc(_("Forcefully join a user to a channel")); + this->SetSyntax(_("\037nick\037 \037channel\037")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + if (!IRCD->CanSVSJoin) + { + source.Reply(_("Your IRCd does not support SVSJOIN.")); + return; + } + + User *target = User::Find(params[0], true); + Channel *c = Channel::Find(params[1]); + if (target == NULL) + source.Reply(NICK_X_NOT_IN_USE, params[0].c_str()); + else if (target->IsProtected() || target->server == Me) + source.Reply(ACCESS_DENIED); + else if (!IRCD->IsChannelValid(params[1])) + source.Reply(CHAN_X_INVALID, params[1].c_str()); + else if (c && c->FindUser(target)) + source.Reply(_("\002%s\002 is already in \002%s\002."), target->nick.c_str(), c->name.c_str()); + else + { + IRCD->SendSVSJoin(OperServ, target, params[1], ""); + Log(LOG_ADMIN, source, this) << "to force " << target->nick << " to join " << params[1]; + source.Reply(_("\002%s\002 has been joined to \002%s\002."), target->nick.c_str(), params[1].c_str()); + } + } + + bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Forcefully join a user to a channel.")); + return true; + } +}; + +class CommandOSSVSPart : public Command +{ + public: + CommandOSSVSPart(Module *creator) : Command(creator, "operserv/svspart", 2, 2) + { + this->SetDesc(_("Forcefully part a user from a channel")); + this->SetSyntax(_("\037nick\037 \037channel\037")); + } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + if (!IRCD->CanSVSJoin) + { + source.Reply(_("Your IRCd does not support SVSPART.")); + return; + } + + User *target = User::Find(params[0], true); + Channel *c = Channel::Find(params[1]); + if (target == NULL) + source.Reply(NICK_X_NOT_IN_USE, params[0].c_str()); + else if (target->IsProtected() || target->server == Me) + source.Reply(ACCESS_DENIED); + else if (!c) + source.Reply(CHAN_X_NOT_IN_USE, params[1].c_str()); + else if (!c->FindUser(target)) + source.Reply(_("\002%s\002 is not in \002%s\002."), target->nick.c_str(), c->name.c_str()); + else + { + IRCD->SendSVSPart(OperServ, target, params[1], ""); + Log(LOG_ADMIN, source, this) << "to force " << target->nick << " to part " << c->name; + source.Reply(_("\002%s\002 has been parted from \002%s\002."), target->nick.c_str(), c->name.c_str()); + } + } + + bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply(_("Forcefully part a user from a channel.")); + return true; + } +}; + +class OSSVS : public Module +{ + CommandOSSVSNick commandossvsnick; + CommandOSSVSJoin commandossvsjoin; + CommandOSSVSPart commandossvspart; + + public: + OSSVS(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), + commandossvsnick(this), commandossvsjoin(this), commandossvspart(this) + { + this->SetAuthor("Anope"); + } +}; + +MODULE_INIT(OSSVS) diff --git a/modules/commands/os_svsnick.cpp b/modules/commands/os_svsnick.cpp deleted file mode 100644 index e08d5d3aa..000000000 --- a/modules/commands/os_svsnick.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* OperServ core functions - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -/*************************************************************************/ - -#include "module.h" - -class CommandOSSVSNick : public Command -{ - public: - CommandOSSVSNick(Module *creator) : Command(creator, "operserv/svsnick", 2, 2) - { - this->SetDesc(_("Forcefully change a user's nickname")); - this->SetSyntax(_("\037nick\037 \037newnick\037")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - const Anope::string &nick = params[0]; - Anope::string newnick = params[1]; - User *u2; - - /* 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()); - newnick = params[1].substr(0, Config->NickLen); - } - - /* Check for valid characters */ - if (!IRCD->IsNickValid(newnick)) - { - source.Reply(_("Nick \002%s\002 is an illegal nickname and cannot be used."), newnick.c_str()); - return; - } - - /* Check for a nick in use or a forbidden/suspended nick */ - if (!(u2 = User::Find(nick, true))) - source.Reply(NICK_X_NOT_IN_USE, nick.c_str()); - else if (!nick.equals_ci(newnick) && User::Find(newnick)) - source.Reply(_("Nick \002%s\002 is currently in use."), newnick.c_str()); - else - { - source.Reply(_("The nick \002%s\002 is now being changed to \002%s\002."), nick.c_str(), newnick.c_str()); - Log(LOG_ADMIN, source, this) << "to change " << nick << " to " << newnick; - IRCD->SendForceNickChange(u2, newnick, Anope::CurTime); - } - return; - } - - bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("Forcefully changes a user's nickname from nick to newnick.")); - return true; - } -}; - -class OSSVSNick : public Module -{ - CommandOSSVSNick commandossvsnick; - - public: - OSSVSNick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), - commandossvsnick(this) - { - this->SetAuthor("Anope"); - - if (!IRCD || !IRCD->CanSVSNick) - throw ModuleException("Your IRCd does not support SVSNICK"); - - } -}; - -MODULE_INIT(OSSVSNick) diff --git a/modules/commands/os_sxline.cpp b/modules/commands/os_sxline.cpp index 7f48a2645..af397226a 100644 --- a/modules/commands/os_sxline.cpp +++ b/modules/commands/os_sxline.cpp @@ -1,6 +1,6 @@ /* OperServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -252,7 +252,7 @@ class CommandOSSNLine : public CommandOSSXLineBase { if (!this->xlm() || !IRCD->CanSNLine) { - source.Reply(_("Your IRCd does not support SNLINE")); + source.Reply(_("Your IRCd does not support SNLINE.")); return; } @@ -321,7 +321,7 @@ class CommandOSSNLine : public CommandOSSXLineBase ServiceReference<RegexProvider> provider("Regex", Config->RegexEngine); if (!provider) { - source.Reply(_("Unable to find regex engine %s"), Config->RegexEngine.c_str()); + source.Reply(_("Unable to find regex engine %s."), Config->RegexEngine.c_str()); return; } @@ -366,7 +366,7 @@ class CommandOSSNLine : public CommandOSSXLineBase { source.Reply(USERHOST_MASK_TOO_WIDE, mask.c_str()); Log(LOG_ADMIN, source, this) << "tried to " << source.command << " " << percent << "% of the network (" << affected << " users)"; - x->Destroy(); + delete x; return; } @@ -374,7 +374,7 @@ class CommandOSSNLine : public CommandOSSXLineBase FOREACH_RESULT(I_OnAddXLine, OnAddXLine(source, x, this->xlm())); if (MOD_RESULT == EVENT_STOP) { - x->Destroy(); + delete x; return; } @@ -391,7 +391,7 @@ class CommandOSSNLine : public CommandOSSXLineBase User *user = it->second; ++it; - if (!user->HasMode(UMODE_OPER) && user->server != Me && Anope::Match(user->realname, x->mask, false, true)) + if (!user->HasMode("OPER") && user->server != Me && Anope::Match(user->realname, x->mask, false, true)) user->Kill(Config->ServerName, rreason); } } @@ -417,44 +417,46 @@ class CommandOSSNLine : public CommandOSSXLineBase { this->SendSyntax(source); source.Reply(" "); - source.Reply(_("Allows Services operators to manipulate the SNLINE list. If\n" - "a user with a realname matching an SNLINE mask attempts to \n" + source.Reply(_("Allows Services Operators to manipulate the SNLINE list. If\n" + "a user with a realname matching an SNLINE mask attempts to\n" "connect, Services will not allow it to pursue his IRC\n" - "session.\n")); + "session.")); source.Reply(_(" \n" "\002SNLINE ADD\002 adds the given realname mask to the SNLINE\n" "list for the given reason (which \002must\002 be given).\n" - "\037expiry\037 is specified as an integer followed by one of \037d\037 \n" - "(days), \037h\037 (hours), or \037m\037 (minutes). Combinations (such as \n" - "\0371h30m\037) are not permitted. If a unit specifier is not \n" - "included, the default is days (so \037+30\037 by itself means 30 \n" + "\037expiry\037 is specified as an integer followed by one of \037d\037\n" + "(days), \037h\037 (hours), or \037m\037 (minutes). Combinations (such as\n" + "\0371h30m\037) are not permitted. If a unit specifier is not\n" + "included, the default is days (so \037+30\037 by itself means 30\n" "days). To add an SNLINE which does not expire, use \037+0\037. If the\n" "realname mask to be added starts with a \037+\037, an expiry time must\n" "be given, even if it is the same as the default. The\n" "current SNLINE default expiry time can be found with the\n" "\002STATS AKILL\002 command.\n" "Note: because the realname mask may contain spaces, the\n" - "separator between it and the reason is a colon.\n")); + "separator between it and the reason is a colon.")); if (!Config->RegexEngine.empty()) - source.Reply(" \n" - "Regex matches are also supported using the %s engine.\n" - "Enclose your mask in // if this desired.", Config->RegexEngine.c_str()); + { + source.Reply(" "); + source.Reply(_("Regex matches are also supported using the %s engine.\n" + "Enclose your mask in // if this is desired."), Config->RegexEngine.c_str()); + } source.Reply(_(" \n" "The \002SNLINE DEL\002 command removes the given mask from the\n" - "SNLINE list if it is present. If a list of entry numbers is \n" - "given, those entries are deleted. (See the example for LIST \n" + "SNLINE list if it is present. If a list of entry numbers is\n" + "given, those entries are deleted. (See the example for LIST\n" "below.)\n" " \n" - "The \002SNLINE LIST\002 command displays the SNLINE list. \n" + "The \002SNLINE LIST\002 command displays the SNLINE list.\n" "If a wildcard mask is given, only those entries matching the\n" "mask are displayed. If a list of entry numbers is given,\n" "only those entries are shown; for example:\n" " \002SNLINE LIST 2-5,7-9\002\n" - " Lists SNLINE entries numbered 2 through 5 and 7 \n" + " Lists SNLINE entries numbered 2 through 5 and 7\n" " through 9.\n" " \n" - "\002SNLINE VIEW\002 is a more verbose version of \002SNLINE LIST\002, and \n" - "will show who added an SNLINE, the date it was added, and when \n" + "\002SNLINE VIEW\002 is a more verbose version of \002SNLINE LIST\002, and\n" + "will show who added an SNLINE, the date it was added, and when\n" "it expires, as well as the realname mask and reason.\n" " \n" "\002SNLINE CLEAR\002 clears all entries of the SNLINE list.")); @@ -473,7 +475,7 @@ class CommandOSSQLine : public CommandOSSXLineBase { if (!this->xlm() || !IRCD->CanSQLine) { - source.Reply(_("Your IRCd does not support SQLINE")); + source.Reply(_("Your IRCd does not support SQLINE.")); return; } @@ -531,7 +533,7 @@ class CommandOSSQLine : public CommandOSSXLineBase ServiceReference<RegexProvider> provider("Regex", Config->RegexEngine); if (!provider) { - source.Reply(_("Unable to find regex engine %s"), Config->RegexEngine.c_str()); + source.Reply(_("Unable to find regex engine %s."), Config->RegexEngine.c_str()); return; } @@ -569,7 +571,7 @@ class CommandOSSQLine : public CommandOSSXLineBase { source.Reply(USERHOST_MASK_TOO_WIDE, mask.c_str()); Log(LOG_ADMIN, source, this) << "tried to SQLine " << percent << "% of the network (" << affected << " users)"; - x->Destroy(); + delete x; return; } @@ -577,7 +579,7 @@ class CommandOSSQLine : public CommandOSSXLineBase FOREACH_RESULT(I_OnAddXLine, OnAddXLine(source, x, this->xlm())); if (MOD_RESULT == EVENT_STOP) { - x->Destroy(); + delete x; return; } @@ -596,12 +598,12 @@ class CommandOSSQLine : public CommandOSSXLineBase continue; std::vector<User *> users; - for (CUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ++it) + for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ++it) { - UserContainer *uc = *it; + ChanUserContainer *uc = *it; User *user = uc->user; - if (!user->HasMode(UMODE_OPER) && user->server != Me) + if (!user->HasMode("OPER") && user->server != Me) users.push_back(user); } @@ -616,7 +618,7 @@ class CommandOSSQLine : public CommandOSSXLineBase User *user = it->second; ++it; - if (!user->HasMode(UMODE_OPER) && user->server != Me && Anope::Match(user->nick, x->mask, false, true)) + if (!user->HasMode("OPER") && user->server != Me && Anope::Match(user->nick, x->mask, false, true)) user->Kill(Config->ServerName, rreason); } } @@ -646,44 +648,46 @@ class CommandOSSQLine : public CommandOSSXLineBase { this->SendSyntax(source); source.Reply(" "); - source.Reply(_("Allows Services operators to manipulate the SQLINE list. If\n" - "a user with a nick matching an SQLINE mask attempts to \n" + source.Reply(_("Allows Services Operators to manipulate the SQLINE list. If\n" + "a user with a nick matching an SQLINE mask attempts to\n" "connect, Services will not allow it to pursue his IRC\n" "session.\n" - "If the first character of the mask is #, services will \n" + "If the first character of the mask is #, services will\n" "prevent the use of matching channels.")); source.Reply(_(" \n" "\002SQLINE ADD\002 adds the given (nick's) mask to the SQLINE\n" "list for the given reason (which \002must\002 be given).\n" - "\037expiry\037 is specified as an integer followed by one of \037d\037 \n" - "(days), \037h\037 (hours), or \037m\037 (minutes). Combinations (such as \n" - "\0371h30m\037) are not permitted. If a unit specifier is not \n" - "included, the default is days (so \037+30\037 by itself means 30 \n" - "days). To add an SQLINE which does not expire, use \037+0\037. \n" - "If the mask to be added starts with a \037+\037, an expiry time \n" + "\037expiry\037 is specified as an integer followed by one of \037d\037\n" + "(days), \037h\037 (hours), or \037m\037 (minutes). Combinations (such as\n" + "\0371h30m\037) are not permitted. If a unit specifier is not\n" + "included, the default is days (so \037+30\037 by itself means 30\n" + "days). To add an SQLINE which does not expire, use \037+0\037.\n" + "If the mask to be added starts with a \037+\037, an expiry time\n" "must be given, even if it is the same as the default. The\n" "current SQLINE default expiry time can be found with the\n" - "\002STATS AKILL\002 command.\n")); + "\002STATS AKILL\002 command.")); if (!Config->RegexEngine.empty()) - source.Reply(" \n" - "Regex matches are also supported using the %s engine.\n" - "Enclose your mask in // if this desired.", Config->RegexEngine.c_str()); + { + source.Reply(" "); + source.Reply(_("Regex matches are also supported using the %s engine.\n" + "Enclose your mask in // if this is desired."), Config->RegexEngine.c_str()); + } source.Reply(_(" \n" "The \002SQLINE DEL\002 command removes the given mask from the\n" - "SQLINE list if it is present. If a list of entry numbers is \n" - "given, those entries are deleted. (See the example for LIST \n" + "SQLINE list if it is present. If a list of entry numbers is\n" + "given, those entries are deleted. (See the example for LIST\n" "below.)\n" " \n" - "The \002SQLINE LIST\002 command displays the SQLINE list. \n" + "The \002SQLINE LIST\002 command displays the SQLINE list.\n" "If a wildcard mask is given, only those entries matching the\n" "mask are displayed. If a list of entry numbers is given,\n" "only those entries are shown; for example:\n" " \002SQLINE LIST 2-5,7-9\002\n" - " Lists SQLINE entries numbered 2 through 5 and 7 \n" + " Lists SQLINE entries numbered 2 through 5 and 7\n" " through 9.\n" " \n" - "\002SQLINE VIEW\002 is a more verbose version of \002SQLINE LIST\002, and \n" - "will show who added an SQLINE, the date it was added, and when \n" + "\002SQLINE VIEW\002 is a more verbose version of \002SQLINE LIST\002, and\n" + "will show who added an SQLINE, the date it was added, and when\n" "it expires, as well as the mask and reason.\n" " \n" "\002SQLINE CLEAR\002 clears all entries of the SQLINE list.")); diff --git a/modules/commands/os_update.cpp b/modules/commands/os_update.cpp index 7bea34aaf..f71ebca55 100644 --- a/modules/commands/os_update.cpp +++ b/modules/commands/os_update.cpp @@ -1,6 +1,6 @@ /* OperServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/database/db_flatfile.cpp b/modules/database/db_flatfile.cpp index 66715b9f8..848356574 100644 --- a/modules/database/db_flatfile.cpp +++ b/modules/database/db_flatfile.cpp @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -15,13 +15,19 @@ class SaveData : public Serialize::Data { public: + Anope::string last; std::fstream *fs; SaveData() : fs(NULL) { } std::iostream& operator[](const Anope::string &key) anope_override { - *fs << "\nDATA " << key << " "; + if (key != last) + { + *fs << "\nDATA " << key << " "; + last = key; + } + return *fs; } }; @@ -57,6 +63,23 @@ class LoadData : public Serialize::Data this->ss << this->data[key]; return this->ss; } + + std::set<Anope::string> KeySet() const anope_override + { + std::set<Anope::string> keys; + for (std::map<Anope::string, Anope::string>::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it) + keys.insert(it->first); + return keys; + } + + size_t Hash() const anope_override + { + size_t hash = 0; + for (std::map<Anope::string, Anope::string>::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it) + if (!it->second.empty()) + hash ^= Anope::hash_cs()(it->second); + return hash; + } void Reset() { @@ -73,6 +96,7 @@ class DBFlatFile : public Module, public Pipe /* Backup file names */ std::map<Anope::string, std::list<Anope::string> > backups; bool use_fork; + bool loaded; void BackupDatabase() { @@ -101,8 +125,8 @@ class DBFlatFile : public Module, public Pipe const Anope::string &oldname = Anope::DataDir + "/" + *it; Anope::string newname = Anope::DataDir + "/backups/" + *it + "." + stringify(tm->tm_year) + "." + stringify(tm->tm_mon) + "." + stringify(tm->tm_mday); - /* Backup already exists */ - if (Anope::IsFile(newname)) + /* Backup already exists or no database to backup */ + if (Anope::IsFile(newname) || !Anope::IsFile(oldname)) continue; Log(LOG_DEBUG) << "db_flatfile: Attemping to rename " << *it << " to " << newname; @@ -128,11 +152,11 @@ class DBFlatFile : public Module, public Pipe } public: - DBFlatFile(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE), last_day(0), use_fork(false) + DBFlatFile(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE), last_day(0), use_fork(false), loaded(false) { this->SetAuthor("Anope"); - Implementation i[] = { I_OnReload, I_OnLoadDatabase, I_OnSaveDatabase }; + Implementation i[] = { I_OnReload, I_OnLoadDatabase, I_OnSaveDatabase, I_OnSerializeTypeCreate }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); OnReload(); @@ -208,6 +232,7 @@ class DBFlatFile : public Module, public Pipe fd.close(); + loaded = true; return EVENT_STOP; } @@ -230,6 +255,29 @@ class DBFlatFile : public Module, public Pipe { std::map<Module *, std::fstream *> databases; + /* First open the databases of all of the registered types. This way, if we have a type with 0 objects, that database will be properly cleared */ + for (std::map<Anope::string, Serialize::Type *>::const_iterator it = Serialize::Type::GetTypes().begin(), it_end = Serialize::Type::GetTypes().end(); it != it_end; ++it) + { + Serialize::Type *s_type = it->second; + + if (databases[s_type->GetOwner()]) + continue; + + Anope::string db_name; + if (s_type->GetOwner()) + db_name = Anope::DataDir + "/module_" + s_type->GetOwner()->name + ".db"; + else + db_name = Anope::DataDir + "/" + database_file; + + if (Anope::IsFile(db_name)) + rename(db_name.c_str(), (db_name + ".tmp").c_str()); + + std::fstream *fs = databases[s_type->GetOwner()] = new std::fstream(db_name.c_str(), std::ios_base::out | std::ios_base::trunc); + + if (!fs->is_open()) + Log(this) << "Unable to open " << db_name << " for writing"; + } + SaveData data; const std::list<Serializable *> &items = Serializable::GetItems(); for (std::list<Serializable *>::const_iterator it = items.begin(), it_end = items.end(); it != it_end; ++it) @@ -237,31 +285,8 @@ class DBFlatFile : public Module, public Pipe Serializable *base = *it; Serialize::Type *s_type = base->GetSerializableType(); - if (!s_type) - continue; - data.fs = databases[s_type->GetOwner()]; - - if (!data.fs) - { - Anope::string db_name; - if (s_type->GetOwner()) - db_name = Anope::DataDir + "/module_" + s_type->GetOwner()->name + ".db"; - else - db_name = Anope::DataDir + "/" + database_file; - - if (Anope::IsFile(db_name)) - rename(db_name.c_str(), (db_name + ".tmp").c_str()); - - data.fs = databases[s_type->GetOwner()] = new std::fstream(db_name.c_str(), std::ios_base::out | std::ios_base::trunc); - - if (!data.fs->is_open()) - { - Log(this) << "Unable to open " << db_name << " for writing"; - continue; - } - } - else if (!data.fs->is_open()) + if (!data.fs || !data.fs->is_open()) continue; *data.fs << "OBJECT " << s_type->GetName(); @@ -306,6 +331,40 @@ class DBFlatFile : public Module, public Pipe return EVENT_CONTINUE; } + + /* Load just one type. Done if a module is reloaded during runtime */ + void OnSerializeTypeCreate(Serialize::Type *stype) anope_override + { + if (!loaded) + return; + + Anope::string db_name; + if (stype->GetOwner()) + db_name = Anope::DataDir + "/module_" + stype->GetOwner()->name + ".db"; + else + db_name = Anope::DataDir + "/" + database_file; + + std::fstream fd(db_name.c_str(), std::ios_base::in); + if (!fd.is_open()) + { + Log(this) << "Unable to open " << db_name << " for reading!"; + return; + } + + LoadData ld; + ld.fs = &fd; + + for (Anope::string buf; std::getline(fd, buf.str());) + { + if (buf == "OBJECT " + stype->GetName()) + { + stype->Unserialize(NULL, ld); + ld.Reset(); + } + } + + fd.close(); + } }; MODULE_INIT(DBFlatFile) diff --git a/modules/database/db_old.cpp b/modules/database/db_old.cpp index 521b58cff..e1fe8f69d 100644 --- a/modules/database/db_old.cpp +++ b/modules/database/db_old.cpp @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -461,37 +461,37 @@ static void LoadNicks() READ(read_uint32(&uint, f)); if (uint & OLD_NI_KILLPROTECT) - nc->SetFlag(NI_KILLPROTECT); + nc->ExtendMetadata("KILLPROTECT"); if (uint & OLD_NI_SECURE) - nc->SetFlag(NI_SECURE); + nc->ExtendMetadata("SECURE"); if (uint & OLD_NI_MSG) - nc->SetFlag(NI_MSG); + nc->ExtendMetadata("MSG"); if (uint & OLD_NI_MEMO_HARDMAX) - nc->SetFlag(NI_MEMO_HARDMAX); + nc->ExtendMetadata("MEMO_HARDMAX"); if (uint & OLD_NI_MEMO_SIGNON) - nc->SetFlag(NI_MEMO_SIGNON); + nc->ExtendMetadata("MEMO_SIGNON"); if (uint & OLD_NI_MEMO_RECEIVE) - nc->SetFlag(NI_MEMO_RECEIVE); + nc->ExtendMetadata("MEMO_RECEIVE"); if (uint & OLD_NI_PRIVATE) - nc->SetFlag(NI_PRIVATE); + nc->ExtendMetadata("PRIVATE"); if (uint & OLD_NI_HIDE_EMAIL) - nc->SetFlag(NI_HIDE_EMAIL); + nc->ExtendMetadata("HIDE_EMAIL"); if (uint & OLD_NI_HIDE_MASK) - nc->SetFlag(NI_HIDE_MASK); + nc->ExtendMetadata("HIDE_MASK"); if (uint & OLD_NI_HIDE_QUIT) - nc->SetFlag(NI_HIDE_QUIT); + nc->ExtendMetadata("HIDE_QUIT"); if (uint & OLD_NI_KILL_QUICK) - nc->SetFlag(NI_KILL_QUICK); + nc->ExtendMetadata("KILL_QUICK"); if (uint & OLD_NI_KILL_IMMED) - nc->SetFlag(NI_KILL_IMMED); + nc->ExtendMetadata("KILL_IMMED"); if (uint & OLD_NI_MEMO_MAIL) - nc->SetFlag(NI_MEMO_MAIL); + nc->ExtendMetadata("MEMO_MAIL"); if (uint & OLD_NI_HIDE_STATUS) - nc->SetFlag(NI_HIDE_STATUS); + nc->ExtendMetadata("HIDE_STATUS"); if (uint & OLD_NI_SUSPENDED) - nc->SetFlag(NI_SUSPENDED); + nc->ExtendMetadata("SUSPENDED"); if (!(uint & OLD_NI_AUTOOP)) - nc->SetFlag(NI_AUTOOP); + nc->ExtendMetadata("AUTOOP"); uint16_t u16; READ(read_uint16(&u16, f)); @@ -609,7 +609,7 @@ static void LoadNicks() na->last_seen = last_seen; if (tmpu16 & OLD_NS_NO_EXPIRE) - na->SetFlag(NS_NO_EXPIRE); + na->ExtendMetadata("NO_EXPIRE"); Log(LOG_DEBUG) << "Loaded NickAlias " << na->nick; } @@ -675,7 +675,7 @@ static void LoadBots() bi->created = created; if (flags & OLD_BI_PRIVATE) - bi->SetFlag(BI_PRIVATE); + bi->ExtendMetadata("PRIVATE"); Log(LOG_DEBUG) << "Loaded bot " << bi->nick; } @@ -701,7 +701,7 @@ static void LoadChannels() ci->SetFounder(NickCore::Find(buffer)); READ(read_string(buffer, f)); - ci->successor = NickCore::Find(buffer); + ci->SetSuccessor(NickCore::Find(buffer)); char pwbuf[32]; READ(read_buffer(pwbuf, f)); @@ -730,31 +730,31 @@ static void LoadChannels() // Temporary flags cleanup tmpu32 &= ~0x80000000; if (tmpu32 & OLD_CI_KEEPTOPIC) - ci->SetFlag(CI_KEEPTOPIC); + ci->ExtendMetadata("KEEPTOPIC"); if (tmpu32 & OLD_CI_SECUREOPS) - ci->SetFlag(CI_SECUREOPS); + ci->ExtendMetadata("SECUREOPS"); if (tmpu32 & OLD_CI_PRIVATE) - ci->SetFlag(CI_PRIVATE); + ci->ExtendMetadata("PRIVATE"); if (tmpu32 & OLD_CI_TOPICLOCK) - ci->SetFlag(CI_TOPICLOCK); + ci->ExtendMetadata("TOPICLOCK"); if (tmpu32 & OLD_CI_RESTRICTED) - ci->SetFlag(CI_RESTRICTED); + ci->ExtendMetadata("RESTRICTED"); if (tmpu32 & OLD_CI_PEACE) - ci->SetFlag(CI_PEACE); + ci->ExtendMetadata("PEACE"); if (tmpu32 & OLD_CI_SECURE) - ci->SetFlag(CI_SECURE); + ci->ExtendMetadata("SECURE"); if (tmpu32 & OLD_CI_NO_EXPIRE) - ci->SetFlag(CI_NO_EXPIRE); + ci->ExtendMetadata("NO_EXPIRE"); if (tmpu32 & OLD_CI_MEMO_HARDMAX) - ci->SetFlag(CI_MEMO_HARDMAX); + ci->ExtendMetadata("MEMO_HARDMAX"); if (tmpu32 & OLD_CI_SECUREFOUNDER) - ci->SetFlag(CI_SECUREFOUNDER); + ci->ExtendMetadata("SECUREFOUNDER"); if (tmpu32 & OLD_CI_SIGNKICK) - ci->SetFlag(CI_SIGNKICK); + ci->ExtendMetadata("SIGNKICK"); if (tmpu32 & OLD_CI_SIGNKICK_LEVEL) - ci->SetFlag(CI_SIGNKICK_LEVEL); + ci->ExtendMetadata("SIGNKICK_LEVEL"); if (tmpu32 & OLD_CI_SUSPENDED) - ci->SetFlag(CI_SUSPENDED); + ci->ExtendMetadata("SUSPENDED"); READ(read_string(buffer, f)); READ(read_string(buffer, f)); @@ -775,7 +775,7 @@ static void LoadChannels() level = ACCESS_FOUNDER; if (j == 10 && level < 0) // NOJOIN - ci->UnsetFlag(CI_RESTRICTED); // If CSDefRestricted was enabled this can happen + ci->Shrink("RESTRICTED"); // If CSDefRestricted was enabled this can happen ci->SetLevel(GetLevelName(j), level); } @@ -865,31 +865,31 @@ static void LoadChannels() READ(read_int32(&tmp32, f)); if (tmp32 & OLD_BS_DONTKICKOPS) - ci->botflags.SetFlag(BS_DONTKICKOPS); + ci->ExtendMetadata("BS_DONTKICKOPS"); if (tmp32 & OLD_BS_DONTKICKVOICES) - ci->botflags.SetFlag(BS_DONTKICKVOICES); + ci->ExtendMetadata("BS_DONTKICKVOICES"); if (tmp32 & OLD_BS_FANTASY) - ci->botflags.SetFlag(BS_FANTASY); + ci->ExtendMetadata("BS_FANTASY"); if (tmp32 & OLD_BS_GREET) - ci->botflags.SetFlag(BS_GREET); + ci->ExtendMetadata("BS_GREET"); if (tmp32 & OLD_BS_NOBOT) - ci->botflags.SetFlag(BS_NOBOT); + ci->ExtendMetadata("BS_NOBOT"); if (tmp32 & OLD_BS_KICK_BOLDS) - ci->botflags.SetFlag(BS_KICK_BOLDS); + ci->ExtendMetadata("BS_KICK_BOLDS"); if (tmp32 & OLD_BS_KICK_COLORS) - ci->botflags.SetFlag(BS_KICK_COLORS); + ci->ExtendMetadata("BS_KICK_COLORS"); if (tmp32 & OLD_BS_KICK_REVERSES) - ci->botflags.SetFlag(BS_KICK_REVERSES); + ci->ExtendMetadata("BS_KICK_REVERSES"); if (tmp32 & OLD_BS_KICK_UNDERLINES) - ci->botflags.SetFlag(BS_KICK_UNDERLINES); + ci->ExtendMetadata("BS_KICK_UNDERLINES"); if (tmp32 & OLD_BS_KICK_BADWORDS) - ci->botflags.SetFlag(BS_KICK_BADWORDS); + ci->ExtendMetadata("BS_KICK_BADWORDS"); if (tmp32 & OLD_BS_KICK_CAPS) - ci->botflags.SetFlag(BS_KICK_CAPS); + ci->ExtendMetadata("BS_KICK_CAPS"); if (tmp32 & OLD_BS_KICK_FLOOD) - ci->botflags.SetFlag(BS_KICK_FLOOD); + ci->ExtendMetadata("BS_KICK_FLOOD"); if (tmp32 & OLD_BS_KICK_REPEAT) - ci->botflags.SetFlag(BS_KICK_REPEAT); + ci->ExtendMetadata("BS_KICK_REPEAT"); READ(read_int16(&tmp16, f)); for (int16_t j = 0; j < tmp16; ++j) diff --git a/modules/database/db_plain.cpp b/modules/database/db_plain.cpp index f23cf4e4a..99bdf947a 100644 --- a/modules/database/db_plain.cpp +++ b/modules/database/db_plain.cpp @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -79,7 +79,10 @@ EventReturn OnDatabaseReadMetadata(NickCore *nc, const Anope::string &key, const else if (key.equals_ci("CERT")) nc->AddCert(params[0]); else if (key.equals_ci("FLAGS")) - nc->FromVector(params); + { + for (unsigned i = 0; i < params.size(); ++i) + nc->ExtendMetadata(params[i]); + } else if (key.equals_ci("MI")) { Memo *m = new Memo; @@ -88,9 +91,9 @@ EventReturn OnDatabaseReadMetadata(NickCore *nc, const Anope::string &key, const 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); + m->unread = true; else if (params[j].equals_ci("RECEIPT")) - m->SetFlag(MF_RECEIPT); + m->receipt = true; } m->text = params[params.size() - 1]; nc->memos.memos->push_back(m); @@ -116,7 +119,8 @@ EventReturn OnDatabaseReadMetadata(NickAlias *na, const Anope::string &key, cons else if (key.equals_ci("LAST_QUIT")) na->last_quit = params[0]; else if (key.equals_ci("FLAGS")) - na->FromVector(params); + for (unsigned i = 0; i < params.size(); ++i) + na->ExtendMetadata(params[i]); else if (key.equals_ci("VHOST")) na->SetVhost(params.size() > 3 ? params[3] : "", params[2], params[0], params[1].is_pos_number_only() ? convertTo<time_t>(params[1]) : 0); return EVENT_CONTINUE; @@ -124,9 +128,6 @@ EventReturn OnDatabaseReadMetadata(NickAlias *na, const Anope::string &key, cons EventReturn OnDatabaseReadMetadata(BotInfo *bi, const Anope::string &key, const std::vector<Anope::string> ¶ms) { - if (key.equals_ci("FLAGS")) - bi->FromVector(params); - return EVENT_CONTINUE; } @@ -141,7 +142,7 @@ EventReturn OnDatabaseReadMetadata(ChannelInfo *ci, const Anope::string &key, co else if (key.equals_ci("FOUNDER")) ci->SetFounder(NickCore::Find(params[0])); else if (key.equals_ci("SUCCESSOR")) - ci->successor = NickCore::Find(params[0]); + ci->SetSuccessor(NickCore::Find(params[0])); else if (key.equals_ci("LEVELS")) { for (unsigned j = 0, end = params.size(); j < end; j += 2) @@ -153,7 +154,8 @@ EventReturn OnDatabaseReadMetadata(ChannelInfo *ci, const Anope::string &key, co } } else if (key.equals_ci("FLAGS")) - ci->FromVector(params); + for (unsigned i = 0; i < params.size(); ++i) + ci->ExtendMetadata(params[i]); else if (key.equals_ci("DESC")) ci->desc = params[0]; else if (key.equals_ci("TOPIC")) @@ -164,8 +166,8 @@ EventReturn OnDatabaseReadMetadata(ChannelInfo *ci, const Anope::string &key, co } else if (key.equals_ci("SUSPEND")) { - ci->Extend("suspend_by", new ExtensibleItemClass<Anope::string>(params[0])); - ci->Extend("suspend_reason", new ExtensibleItemClass<Anope::string>(params[1])); + ci->ExtendMetadata("suspend:by", params[0]); + ci->ExtendMetadata("suspend:reason", params[1]); } else if (key.equals_ci("ACCESS")) // Older access system, from Anope 1.9.4. { @@ -216,8 +218,6 @@ EventReturn OnDatabaseReadMetadata(ChannelInfo *ci, const Anope::string &key, co ak = ci->AddAkick(params[3], nc, params.size() > 6 ? params[6] : "", params[4].is_pos_number_only() ? convertTo<time_t>(params[4]) : 0, params[5].is_pos_number_only() ? convertTo<time_t>(params[5]) : 0); else ak = ci->AddAkick(params[3], params[2], params.size() > 6 ? params[6] : "", params[4].is_pos_number_only() ? convertTo<time_t>(params[4]) : 0, params[5].is_pos_number_only() ? convertTo<time_t>(params[5]) : 0); - if (Nick) - ak->SetFlag(AK_ISNICK); } else if (key.equals_ci("LOG")) @@ -238,18 +238,11 @@ EventReturn OnDatabaseReadMetadata(ChannelInfo *ci, const Anope::string &key, co else if (key.equals_ci("MLOCK")) { bool set = params[0] == "1" ? true : false; - Anope::string mode_name = params[1]; + Anope::string mode_name = params[1].substr(6); Anope::string setter = params[2]; time_t mcreated = params[3].is_pos_number_only() ? convertTo<time_t>(params[3]) : Anope::CurTime; Anope::string param = params.size() > 4 ? params[4] : ""; - const Anope::string* ChannelModeNameStrings = Flags<ChannelModeName>::GetFlagStrings(); - for (size_t i = CMODE_BEGIN + 1; i < CMODE_END; ++i) - if (ChannelModeNameStrings[i] == mode_name) - { - ChannelModeName n = static_cast<ChannelModeName>(i); - ci->mode_locks->insert(std::make_pair(n, new ModeLock(ci, set, n, param, setter, mcreated))); - break; - } + ci->mode_locks->insert(std::make_pair(mode_name, new ModeLock(ci, set, mode_name, param, setter, mcreated))); } else if (key.equals_ci("MI")) { @@ -259,9 +252,9 @@ EventReturn OnDatabaseReadMetadata(ChannelInfo *ci, const Anope::string &key, co 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); + m->unread = true; else if (params[j].equals_ci("RECEIPT")) - m->SetFlag(MF_RECEIPT); + m->receipt = true; } m->text = params[params.size() - 1]; ci->memos.memos->push_back(m); @@ -273,7 +266,8 @@ EventReturn OnDatabaseReadMetadata(ChannelInfo *ci, const Anope::string &key, co if (params[0].equals_ci("NAME")) ci->bi = BotInfo::Find(params[1]); else if (params[0].equals_ci("FLAGS")) - ci->botflags.FromVector(params); + for (unsigned i = 0; i < params.size(); ++i) + ci->ExtendMetadata(params[i]); else if (params[0].equals_ci("TTB")) { for (unsigned j = 1, end = params.size(); j < end; j += 2) @@ -476,7 +470,10 @@ static void LoadNickCore(const std::vector<Anope::string> ¶ms) { NickCore *nc = new NickCore(params[0]); /* Clear default flags */ - nc->ClearFlags(); + std::deque<Anope::string> list; + nc->GetExtList(list); + for (unsigned i = 0; i < list.size(); ++i) + nc->Shrink(list[i]); nc->pass = params.size() > 1 ? params[1] : ""; @@ -520,8 +517,10 @@ static void LoadChanInfo(const std::vector<Anope::string> ¶ms) /* CLear default mlock */ ci->ClearMLock(); /* Remove default channel flags */ - ci->ClearFlags(); - ci->botflags.ClearFlags(); + std::deque<Anope::string> list; + ci->GetExtList(list); + for (unsigned i = 0; i < list.size(); ++i) + ci->Shrink(list[i]); ci->time_registered = params[1].is_pos_number_only() ? convertTo<time_t>(params[1]) : 0; @@ -693,16 +692,20 @@ class DBPlain : public Module for (std::vector<Anope::string>::const_iterator it = nc->cert.begin(), it_end = nc->cert.end(); it != it_end; ++it) db_buffer << "MD CERT " << *it << endl; } - if (nc->FlagCount()) - db_buffer << "MD FLAGS " << nc->ToString() << endl; + db_buffer << "MD FLAGS "; + std::deque<Anope::string> list; + nc->GetExtList(list); + for (unsigned i = 0; i < list.size(); ++i) + db_buffer << list[i] << " "; + db_buffer << std::endl; const MemoInfo *mi = &nc->memos; for (unsigned k = 0, end = mi->memos->size(); k < end; ++k) { const Memo *m = mi->GetMemo(k); db_buffer << "MD MI " << m->time << " " << m->sender; - if (m->HasFlag(MF_UNREAD)) + if (m->unread) db_buffer << " UNREAD"; - if (m->HasFlag(MF_RECEIPT)) + if (m->receipt) db_buffer << " RECEIPT"; db_buffer << " :" << m->text << endl; } @@ -724,8 +727,12 @@ class DBPlain : public Module db_buffer << "MD LAST_REALNAME :" << na->last_realname << endl; if (!na->last_quit.empty()) db_buffer << "MD LAST_QUIT :" << na->last_quit << endl; - if (na->FlagCount()) - db_buffer << "MD FLAGS " << na->ToString() << endl; + db_buffer << "MD FLAGS "; + std::deque<Anope::string> list; + na->GetExtList(list); + for (unsigned i = 0; i < list.size(); ++i) + db_buffer << list[i] << " "; + db_buffer << std::endl; if (na->HasVhost()) db_buffer << "MD VHOST " << na->GetVhostCreator() << " " << na->GetVhostCreated() << " " << na->GetVhostHost() << " :" << na->GetVhostIdent() << endl; @@ -736,12 +743,16 @@ class DBPlain : public Module { BotInfo *bi = it->second; - if (bi->HasFlag(BI_CONF)) + if (bi->HasExt("CONF")) continue; db_buffer << "BI " << bi->nick << " " << bi->GetIdent() << " " << bi->host << " " << bi->created << " " << bi->GetChannelCount() << " :" << bi->realname << endl; - if (bi->FlagCount()) - db_buffer << "MD FLAGS " << bi->ToString() << endl; + db_buffer << "MD FLAGS "; + std::deque<Anope::string> list; + bi->GetExtList(list); + for (unsigned i = 0; i < list.size(); ++i) + db_buffer << list[i] << " "; + db_buffer << std::endl; } for (registered_channel_map::const_iterator cit = RegisteredChannelList->begin(), cit_end = RegisteredChannelList->end(); cit != cit_end; ++cit) @@ -753,8 +764,8 @@ class DBPlain : public Module db_buffer << "MD MEMOMAX " << ci->memos.memomax << endl; if (ci->GetFounder()) db_buffer << "MD FOUNDER " << ci->GetFounder()->display << endl; - if (ci->successor) - db_buffer << "MD SUCCESSOR " << ci->successor->display << endl; + if (ci->GetSuccessor()) + db_buffer << "MD SUCCESSOR " << ci->GetSuccessor()->display << endl; if (!ci->desc.empty()) db_buffer << "MD DESC :" << ci->desc << endl; if (!ci->last_topic.empty()) @@ -767,9 +778,12 @@ class DBPlain : public Module db_buffer << p.name << " " << ci->GetLevel(p.name); } db_buffer << endl; - if (ci->FlagCount()) - db_buffer << "MD FLAGS " << ci->ToString() << endl; - if (ci->HasFlag(CI_SUSPENDED)) + std::deque<Anope::string> list; + ci->GetExtList(list); + for (unsigned i = 0; i < list.size(); ++i) + db_buffer << list[i]; + db_buffer << std::endl; + if (ci->HasExt("SUSPENDED")) { Anope::string *by = ci->GetExt<ExtensibleItemClass<Anope::string> *>("suspend_by"), *reason = ci->GetExt<ExtensibleItemClass<Anope::string> *>("suspend_reason"); if (by && reason) @@ -782,8 +796,8 @@ class DBPlain : public Module } for (unsigned k = 0, end = ci->GetAkickCount(); k < end; ++k) { - db_buffer << "MD AKICK 0 " << (ci->GetAkick(k)->HasFlag(AK_ISNICK) ? "NICK " : "MASK ") << - (ci->GetAkick(k)->HasFlag(AK_ISNICK) ? ci->GetAkick(k)->nc->display : ci->GetAkick(k)->mask) << " " << ci->GetAkick(k)->creator << " " << ci->GetAkick(k)->addtime << " " << ci->last_used << " :"; + db_buffer << "MD AKICK 0 " << (ci->GetAkick(k)->nc ? "NICK " : "MASK ") << + (ci->GetAkick(k)->nc ? ci->GetAkick(k)->nc->display : ci->GetAkick(k)->mask) << " " << ci->GetAkick(k)->creator << " " << ci->GetAkick(k)->addtime << " " << ci->last_used << " :"; if (!ci->GetAkick(k)->reason.empty()) db_buffer << ci->GetAkick(k)->reason; db_buffer << endl; @@ -799,16 +813,16 @@ class DBPlain : public Module const ModeLock &ml = *it->second; ChannelMode *cm = ModeManager::FindChannelModeByName(ml.name); if (cm != NULL) - db_buffer << "MD MLOCK " << (ml.set ? 1 : 0) << " " << cm->NameAsString() << " " << ml.setter << " " << ml.created << " " << ml.param << endl; + db_buffer << "MD MLOCK " << (ml.set ? 1 : 0) << " " << cm->name << " " << ml.setter << " " << ml.created << " " << ml.param << endl; } const MemoInfo *memos = &ci->memos; for (unsigned k = 0, end = memos->memos->size(); k < end; ++k) { const Memo *m = memos->GetMemo(k); db_buffer << "MD MI " << m->time << " " << m->sender; - if (m->HasFlag(MF_UNREAD)) + if (m->unread) db_buffer << " UNREAD"; - if (m->HasFlag(MF_RECEIPT)) + if (m->receipt) db_buffer << " RECEIPT"; db_buffer << " :" << m->text << endl; } @@ -816,8 +830,6 @@ class DBPlain : public Module db_buffer << "MD MIG " << Anope::string(memos->ignores[k]) << endl; if (ci->bi) db_buffer << "MD BI NAME " << ci->bi->nick << endl; - if (ci->botflags.FlagCount()) - db_buffer << "MD BI FLAGS " << ci->botflags.ToString() << endl; db_buffer << "MD BI TTB BOLDS " << ci->ttb[0] << " COLORS " << ci->ttb[1] << " REVERSES " << ci->ttb[2] << " UNDERLINES " << ci->ttb[3] << " BADWORDS " << ci->ttb[4] << " CAPS " << ci->ttb[5] << " FLOOD " << ci->ttb[6] << " REPEAT " << ci->ttb[7] << " ITALICS " << ci->ttb[8] << " AMSGS " << ci->ttb[9] << endl; if (ci->capsmin) db_buffer << "MD BI CAPSMIN " << ci->capsmin << endl; diff --git a/modules/database/db_sql.cpp b/modules/database/db_sql.cpp index 56db7b8a0..3bb0efde2 100644 --- a/modules/database/db_sql.cpp +++ b/modules/database/db_sql.cpp @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -59,9 +59,10 @@ class DBSQL : public Module, public Pipe ServiceReference<Provider> sql; SQLSQLInterface sqlinterface; Anope::string prefix; - std::set<Reference<Serializable> > updated_items; + std::set<Serializable *> updated_items; bool shutting_down; bool loading_databases; + bool loaded; void RunBackground(const Query &q, Interface *iface = NULL) { @@ -85,11 +86,11 @@ class DBSQL : public Module, public Pipe } public: - DBSQL(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE), sql("", ""), sqlinterface(this), shutting_down(false), loading_databases(false) + DBSQL(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE), sql("", ""), sqlinterface(this), shutting_down(false), loading_databases(false), loaded(false) { this->SetAuthor("Anope"); - Implementation i[] = { I_OnReload, I_OnShutdown, I_OnRestart, I_OnLoadDatabase, I_OnSerializableConstruct, I_OnSerializableDestruct, I_OnSerializableUpdate }; + Implementation i[] = { I_OnReload, I_OnShutdown, I_OnRestart, I_OnLoadDatabase, I_OnSerializableConstruct, I_OnSerializableDestruct, I_OnSerializableUpdate, I_OnSerializeTypeCreate }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); this->OnReload(); @@ -97,20 +98,17 @@ class DBSQL : public Module, public Pipe void OnNotify() anope_override { - for (std::set<Reference<Serializable> >::iterator it = this->updated_items.begin(), it_end = this->updated_items.end(); it != it_end; ++it) + for (std::set<Serializable *>::iterator it = this->updated_items.begin(), it_end = this->updated_items.end(); it != it_end; ++it) { - Reference<Serializable> obj = *it; + Serializable *obj = *it; - if (obj && this->sql) + if (this->sql) { - Data *data = new Data(); - obj->Serialize(*data); + Data data; + obj->Serialize(data); if (obj->IsCached(data)) - { - delete data; continue; - } obj->UpdateCache(data); @@ -118,12 +116,18 @@ class DBSQL : public Module, public Pipe if (!s_type) continue; - std::vector<Query> create = this->sql->CreateTable(this->prefix + s_type->GetName(), *data); + std::vector<Query> create = this->sql->CreateTable(this->prefix + s_type->GetName(), data); for (unsigned i = 0; i < create.size(); ++i) this->RunBackground(create[i]); - Query insert = this->sql->BuildInsert(this->prefix + s_type->GetName(), obj->id, *data); - this->RunBackground(insert, new ResultSQLSQLInterface(this, obj)); + Query insert = this->sql->BuildInsert(this->prefix + s_type->GetName(), obj->id, data); + if (this->loaded) + this->RunBackground(insert, new ResultSQLSQLInterface(this, obj)); + else + /* If we aren't loading these objects then we are importing them, so don't do asynchronous + * queries in case for some reason the core has to shut down, it will cut short the import + */ + this->sql->RunQuery(insert); } } @@ -163,37 +167,11 @@ class DBSQL : public Module, public Pipe for (unsigned i = 0; i < type_order.size(); ++i) { Serialize::Type *sb = Serialize::Type::Find(type_order[i]); - - Query query("SELECT * FROM `" + this->prefix + sb->GetName() + "`"); - Result res = this->sql->RunQuery(query); - - for (int j = 0; j < res.Rows(); ++j) - { - Data *data = new Data(); - - const std::map<Anope::string, Anope::string> &row = res.Row(j); - for (std::map<Anope::string, Anope::string>::const_iterator rit = row.begin(), rit_end = row.end(); rit != rit_end; ++rit) - (*data)[rit->first] << rit->second; - - Serializable *obj = sb->Unserialize(NULL, *data); - try - { - if (obj) - obj->id = convertTo<unsigned int>(res.Get(j, "id")); - } - catch (const ConvertException &) - { - Log(this) << "Unable to convert id for object #" << j << " of type " << sb->GetName(); - } - - if (obj) - obj->UpdateCache(data); /* We know this is the most up to date copy */ - else - delete data; - } + this->OnSerializeTypeCreate(sb); } this->loading_databases = false; + this->loaded = true; return EVENT_STOP; } @@ -202,6 +180,7 @@ class DBSQL : public Module, public Pipe { if (this->shutting_down || this->loading_databases) return; + obj->UpdateTS(); this->updated_items.insert(obj); this->Notify(); } @@ -209,8 +188,9 @@ class DBSQL : public Module, public Pipe void OnSerializableDestruct(Serializable *obj) anope_override { Serialize::Type *s_type = obj->GetSerializableType(); - if (s_type) + if (s_type && obj->id > 0) this->RunBackground("DELETE FROM `" + this->prefix + s_type->GetName() + "` WHERE `id` = " + stringify(obj->id)); + this->updated_items.erase(obj); } void OnSerializableUpdate(Serializable *obj) anope_override @@ -221,6 +201,45 @@ class DBSQL : public Module, public Pipe this->updated_items.insert(obj); this->Notify(); } + + void OnSerializeTypeCreate(Serialize::Type *sb) anope_override + { + if (!this->loading_databases && !this->loaded) + return; + + Query query("SELECT * FROM `" + this->prefix + sb->GetName() + "`"); + Result res = this->sql->RunQuery(query); + + for (int j = 0; j < res.Rows(); ++j) + { + Data data; + + const std::map<Anope::string, Anope::string> &row = res.Row(j); + for (std::map<Anope::string, Anope::string>::const_iterator rit = row.begin(), rit_end = row.end(); rit != rit_end; ++rit) + data[rit->first] << rit->second; + + Serializable *obj = sb->Unserialize(NULL, data); + try + { + if (obj) + obj->id = convertTo<unsigned int>(res.Get(j, "id")); + } + catch (const ConvertException &) + { + Log(this) << "Unable to convert id for object #" << j << " of type " << sb->GetName(); + } + + if (obj) + { + Data data2; + /* The Unserialize operation is destructive so rebuild the data for UpdateCache */ + for (std::map<Anope::string, Anope::string>::const_iterator rit = row.begin(), rit_end = row.end(); rit != rit_end; ++rit) + if (rit->first != "id" && rit->first != "timestamp") + data2[rit->first] << rit->second; + obj->UpdateCache(data2); /* We know this is the most up to date copy */ + } + } + } }; MODULE_INIT(DBSQL) diff --git a/modules/database/db_sql_live.cpp b/modules/database/db_sql_live.cpp index 8d8836055..62f1c0ca4 100644 --- a/modules/database/db_sql_live.cpp +++ b/modules/database/db_sql_live.cpp @@ -13,7 +13,7 @@ class DBMySQL : public Module, public Pipe time_t lastwarn; bool ro; bool init; - std::set<Reference<Serializable> > updated_items; + std::set<Serializable *> updated_items; bool CheckSQL() { @@ -83,20 +83,17 @@ class DBMySQL : public Module, public Pipe if (!this->CheckInit()) return; - for (std::set<Reference<Serializable> >::iterator it = this->updated_items.begin(), it_end = this->updated_items.end(); it != it_end; ++it) + for (std::set<Serializable *>::iterator it = this->updated_items.begin(), it_end = this->updated_items.end(); it != it_end; ++it) { - Reference<Serializable> obj = *it; + Serializable *obj = *it; if (obj && this->SQL) { - Data *data = new Data(); - obj->Serialize(*data); + Data data; + obj->Serialize(data); if (obj->IsCached(data)) - { - delete data; continue; - } obj->UpdateCache(data); @@ -104,12 +101,12 @@ class DBMySQL : public Module, public Pipe if (!s_type) continue; - std::vector<Query> create = this->SQL->CreateTable(this->prefix + s_type->GetName(), *data); + std::vector<Query> create = this->SQL->CreateTable(this->prefix + s_type->GetName(), data); for (unsigned i = 0; i < create.size(); ++i) this->RunQueryResult(create[i]); - Result res = this->RunQueryResult(this->SQL->BuildInsert(this->prefix + s_type->GetName(), obj->id, *data)); - if (obj->id != res.GetID()) + Result res = this->RunQueryResult(this->SQL->BuildInsert(this->prefix + s_type->GetName(), obj->id, data)); + if (res.GetID() && obj->id != res.GetID()) { /* In this case obj is new, so place it into the object map */ obj->id = res.GetID(); @@ -144,6 +141,7 @@ class DBMySQL : public Module, public Pipe { if (!this->CheckInit()) return; + obj->UpdateTS(); this->updated_items.insert(obj); this->Notify(); } @@ -153,10 +151,13 @@ class DBMySQL : public Module, public Pipe if (!this->CheckInit()) return; Serialize::Type *s_type = obj->GetSerializableType(); - if (!s_type) - return; - this->RunQuery("DELETE FROM `" + this->prefix + s_type->GetName() + "` WHERE `id` = " + stringify(obj->id)); - s_type->objects.erase(obj->id); + if (s_type) + { + if (obj->id > 0) + this->RunQuery("DELETE FROM `" + this->prefix + s_type->GetName() + "` WHERE `id` = " + stringify(obj->id)); + s_type->objects.erase(obj->id); + } + this->updated_items.erase(obj); } void OnSerializeCheck(Serialize::Type *obj) anope_override @@ -191,24 +192,21 @@ class DBMySQL : public Module, public Pipe clear_null = true; std::map<unsigned int, Serializable *>::iterator it = obj->objects.find(id); if (it != obj->objects.end()) - { - it->second->Destroy(); - obj->objects.erase(it); - } + delete it->second; // This also removes this object from the map } else { - Data *data = new Data(); + Data data; for (std::map<Anope::string, Anope::string>::const_iterator it = row.begin(), it_end = row.end(); it != it_end; ++it) - (*data)[it->first] << it->second; + data[it->first] << it->second; Serializable *s = NULL; std::map<unsigned int, Serializable *>::iterator it = obj->objects.find(id); if (it != obj->objects.end()) s = it->second; - Serializable *new_s = obj->Unserialize(s, *data); + Serializable *new_s = obj->Unserialize(s, data); if (new_s) { // If s == new_s then s->id == new_s->id @@ -216,15 +214,18 @@ class DBMySQL : public Module, public Pipe { new_s->id = id; obj->objects[id] = new_s; - new_s->UpdateCache(data); /* We know this is the most up to date copy */ + + Data data2; + /* The Unserialize operation is destructive so rebuild the data for UpdateCache */ + for (std::map<Anope::string, Anope::string>::const_iterator rit = row.begin(), rit_end = row.end(); rit != rit_end; ++rit) + if (rit->first != "id" && rit->first != "timestamp") + data2[rit->first] << rit->second; + new_s->UpdateCache(data2); /* We know this is the most up to date copy */ } - else - delete data; } else { - delete data; - s->Destroy(); + delete s; } } } @@ -238,7 +239,7 @@ class DBMySQL : public Module, public Pipe void OnSerializableUpdate(Serializable *obj) anope_override { - if (obj->IsTSCached()) + if (!this->CheckInit() || obj->IsTSCached()) return; obj->UpdateTS(); this->updated_items.insert(obj); diff --git a/modules/encryption/enc_md5.cpp b/modules/encryption/enc_md5.cpp index ed7cce144..c1cf9449e 100644 --- a/modules/encryption/enc_md5.cpp +++ b/modules/encryption/enc_md5.cpp @@ -1,7 +1,7 @@ /* Module for encryption using MD5. * * Modified for Anope. - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Taken from IRC Services and is copyright (c) 1996-2002 Andrew Church. diff --git a/modules/encryption/enc_none.cpp b/modules/encryption/enc_none.cpp index 4854e5eb0..fe8b03679 100644 --- a/modules/encryption/enc_none.cpp +++ b/modules/encryption/enc_none.cpp @@ -1,6 +1,6 @@ /* Module for plain text encryption. * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * This program is free but copyrighted software; see the file COPYING for diff --git a/modules/encryption/enc_old.cpp b/modules/encryption/enc_old.cpp index f1599ccbf..03debc65a 100644 --- a/modules/encryption/enc_old.cpp +++ b/modules/encryption/enc_old.cpp @@ -1,6 +1,6 @@ /* Include file for high-level encryption routines. * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/encryption/enc_sha256.cpp b/modules/encryption/enc_sha256.cpp index 1c7f7a735..0ed0c7786 100644 --- a/modules/encryption/enc_sha256.cpp +++ b/modules/encryption/enc_sha256.cpp @@ -5,7 +5,7 @@ * IMPORTANT: DATA HASHES CANNOT BE "DECRYPTED" BACK TO PLAIN TEXT. * * Modified for Anope. - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Taken from InspIRCd ( www.inspircd.org ) diff --git a/modules/encryption/encryption.h b/modules/encryption/encryption.h index 95e5a7299..640be68e5 100644 --- a/modules/encryption/encryption.h +++ b/modules/encryption/encryption.h @@ -1,6 +1,6 @@ /* * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/extra/bs_autoassign.cpp b/modules/extra/bs_autoassign.cpp index c84e18964..8bdab26d7 100644 --- a/modules/extra/bs_autoassign.cpp +++ b/modules/extra/bs_autoassign.cpp @@ -1,6 +1,6 @@ /* * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/extra/m_statusupdate.cpp b/modules/extra/cs_statusupdate.cpp index 41ea8833e..97faae851 100644 --- a/modules/extra/m_statusupdate.cpp +++ b/modules/extra/cs_statusupdate.cpp @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -10,14 +10,14 @@ static struct ModeInfo { Anope::string priv; - ChannelModeName name; + Anope::string name; } modeInfo[] = { - { "AUTOOWNER", CMODE_OWNER }, - { "AUTOPROTECT", CMODE_PROTECT }, - { "AUTOOP", CMODE_OP }, - { "AUTOHALFOP", CMODE_HALFOP }, - { "AUTOVOICE", CMODE_VOICE }, - { "", CMODE_END } + { "AUTOOWNER", "OWNER" }, + { "AUTOPROTECT", "PROTECT" }, + { "AUTOOP", "OP" }, + { "AUTOHALFOP", "HALFOP" }, + { "AUTOVOICE", "VOICE" }, + { "", "" } }; class StatusUpdate : public Module @@ -34,7 +34,7 @@ class StatusUpdate : public Module void OnAccessAdd(ChannelInfo *ci, CommandSource &, ChanAccess *access) anope_override { if (ci->c) - for (CUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it) + for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it) { User *user = (*it)->user; @@ -51,7 +51,7 @@ class StatusUpdate : public Module void OnAccessDel(ChannelInfo *ci, CommandSource &, ChanAccess *access) anope_override { if (ci->c) - for (CUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it) + for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it) { User *user = (*it)->user; diff --git a/modules/extra/dns.h b/modules/extra/dns.h index 9d141249b..4eba1630c 100644 --- a/modules/extra/dns.h +++ b/modules/extra/dns.h @@ -1,6 +1,6 @@ /* * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/extra/m_chanstats.cpp b/modules/extra/m_chanstats.cpp index 7096b39a5..3c964b55c 100644 --- a/modules/extra/m_chanstats.cpp +++ b/modules/extra/m_chanstats.cpp @@ -56,7 +56,7 @@ class MChanstats : public Module const Anope::string GetDisplay(User *u) { - if (u && u->Account() && u->Account()->HasFlag(NI_STATS)) + if (u && u->Account() && u->Account()->HasExt("STATS")) return u->Account()->display; else return ""; @@ -350,6 +350,7 @@ class MChanstats : public Module ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); this->OnReload(); } + void OnReload() anope_override { ConfigReader config; @@ -365,30 +366,34 @@ class MChanstats : public Module else Log(this) << "no database connection to " << engine; } + void OnTopicUpdated(Channel *c, const Anope::string &user, const Anope::string &topic) anope_override { User *u = User::Find(user); - if (!u || !u->Account() || !c->ci || !c->ci->HasFlag(CI_STATS)) + if (!u || !u->Account() || !c->ci || !c->ci->HasExt("STATS")) return; query = "CALL " + prefix + "chanstats_proc_update(@channel@, @nick@, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);"; query.SetValue("channel", c->name); query.SetValue("nick", GetDisplay(u)); this->RunQuery(query); } - EventReturn OnChannelModeSet(Channel *c, MessageSource &setter, ChannelModeName Name, const Anope::string ¶m) anope_override + + EventReturn OnChannelModeSet(Channel *c, MessageSource &setter, const Anope::string &, const Anope::string ¶m) anope_override { this->OnModeChange(c, setter.GetUser()); return EVENT_CONTINUE; } - EventReturn OnChannelModeUnset(Channel *c, MessageSource &setter, ChannelModeName Name, const Anope::string ¶m) anope_override + + EventReturn OnChannelModeUnset(Channel *c, MessageSource &setter, const Anope::string &, const Anope::string ¶m) anope_override { this->OnModeChange(c, setter.GetUser()); return EVENT_CONTINUE; } + private: void OnModeChange(Channel *c, User *u) { - if (!u || !u->Account() || !c->ci || !c->ci->HasFlag(CI_STATS)) + if (!u || !u->Account() || !c->ci || !c->ci->HasExt("STATS")) return; query = "CALL " + prefix + "chanstats_proc_update(@channel@, @nick@, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0);"; @@ -399,7 +404,7 @@ class MChanstats : public Module public: void OnUserKicked(Channel *c, User *target, MessageSource &source, const Anope::string &kickmsg) anope_override { - if (!c->ci || !c->ci->HasFlag(CI_STATS)) + if (!c->ci || !c->ci->HasExt("STATS")) return; query = "CALL " + prefix + "chanstats_proc_update(@channel@, @nick@, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0);"; @@ -414,7 +419,7 @@ class MChanstats : public Module } void OnPrivmsg(User *u, Channel *c, Anope::string &msg) anope_override { - if (!c->ci || !c->ci->HasFlag(CI_STATS) || (msg[0] == Config->BSFantasyCharacter[0])) + if (!c->ci || !c->ci->HasExt("STATS") || (msg[0] == Config->BSFantasyCharacter[0])) return; size_t letters = msg.length(); diff --git a/modules/extra/m_dns.cpp b/modules/extra/m_dns.cpp index 867d81d84..90f9bee9e 100644 --- a/modules/extra/m_dns.cpp +++ b/modules/extra/m_dns.cpp @@ -1,6 +1,6 @@ /* * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/extra/m_dnsbl.cpp b/modules/extra/m_dnsbl.cpp index 1d5cdcb2e..49d39d980 100644 --- a/modules/extra/m_dnsbl.cpp +++ b/modules/extra/m_dnsbl.cpp @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -54,7 +54,7 @@ class DNSBLResolver : public Request record_reason = this->blacklist.replies[result]; } - user->Extend("m_dnsbl_akilled", NULL); + user->Extend("m_dnsbl_akilled"); Anope::string reason = this->blacklist.reason; reason = reason.replace_all_cs("%n", user->nick); @@ -75,7 +75,7 @@ class DNSBLResolver : public Request else { IRCD->SendAkill(NULL, x); - x->Destroy(); + delete x; } } }; @@ -129,9 +129,9 @@ class ModuleDNSBL : public Module } } - void OnUserConnect(Reference<User> &user, bool &exempt) anope_override + void OnUserConnect(User *user, bool &exempt) anope_override { - if (exempt || !user || (!this->check_on_connect && !Me->IsSynced()) || !dnsmanager) + if (exempt || user->Quitting() || (!this->check_on_connect && !Me->IsSynced()) || !dnsmanager) return; if (!this->check_on_netburst && !user->server->IsSynced()) diff --git a/modules/extra/m_helpchan.cpp b/modules/extra/m_helpchan.cpp index 6b450e581..32d1859fc 100644 --- a/modules/extra/m_helpchan.cpp +++ b/modules/extra/m_helpchan.cpp @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -22,14 +22,14 @@ class HelpChannel : public Module OnReload(); } - EventReturn OnChannelModeSet(Channel *c, MessageSource &setter, ChannelModeName Name, const Anope::string ¶m) anope_override + EventReturn OnChannelModeSet(Channel *c, MessageSource &setter, const Anope::string &mname, const Anope::string ¶m) anope_override { - if (Name == CMODE_OP && c && c->ci && c->name.equals_ci(this->HelpChan)) + if (mname == "OP" && c && c->ci && c->name.equals_ci(this->HelpChan)) { User *u = User::Find(param); if (u && c->ci->AccessFor(u).HasPriv("OPDEOPME")) - u->SetMode(OperServ, UMODE_HELPOP); + u->SetMode(OperServ, "HELPOP"); } return EVENT_CONTINUE; diff --git a/modules/extra/m_httpd.cpp b/modules/extra/m_httpd.cpp index 616fc61a9..d9855a226 100644 --- a/modules/extra/m_httpd.cpp +++ b/modules/extra/m_httpd.cpp @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/extra/m_mysql.cpp b/modules/extra/m_mysql.cpp index a8433fd38..e072f8dfe 100644 --- a/modules/extra/m_mysql.cpp +++ b/modules/extra/m_mysql.cpp @@ -372,7 +372,7 @@ std::vector<Query> MySQLService::CreateTable(const Anope::string &table, const D if (known_cols.empty()) { Anope::string query_text = "CREATE TABLE `" + table + "` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT," - " `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"; + " `timestamp` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"; for (Data::Map::const_iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it) { known_cols.insert(it->first); @@ -406,7 +406,7 @@ std::vector<Query> MySQLService::CreateTable(const Anope::string &table, const D return queries; } -Query MySQLService::BuildInsert(const Anope::string &table, unsigned int id, Data &data) anope_override +Query MySQLService::BuildInsert(const Anope::string &table, unsigned int id, Data &data) { /* Empty columns not present in the data set */ const std::set<Anope::string> &known_cols = this->active_schema[table]; diff --git a/modules/extra/m_proxyscan.cpp b/modules/extra/m_proxyscan.cpp index 6d2a6b7b0..feac20969 100644 --- a/modules/extra/m_proxyscan.cpp +++ b/modules/extra/m_proxyscan.cpp @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -98,7 +98,7 @@ class ProxyConnect : public ConnectionSocket IRCD->SendSZLine(NULL, x); else IRCD->SendAkill(NULL, x); - x->Destroy(); + delete x; } } }; @@ -125,9 +125,10 @@ class HTTPProxyConnect : public ProxyConnect, public BufferedSocket return "HTTP"; } - bool Read(const Anope::string &buf) anope_override + bool ProcessRead() anope_override { - if (buf == ProxyCheckString) + BufferedSocket::ProcessRead(); + if (this->GetLine() == ProxyCheckString) { this->Ban(); return false; @@ -214,7 +215,7 @@ class ModuleProxyScan : public Module ProxyConnect *p = *it; if (p->created + this->GetSecs() < Anope::CurTime) - p->SetFlag(SF_DEAD); + p->flags[SF_DEAD] = true; } } } connectionTimeout; @@ -341,9 +342,9 @@ class ModuleProxyScan : public Module } } - void OnUserConnect(Reference<User> &user, bool &exempt) anope_override + void OnUserConnect(User *user, bool &exempt) anope_override { - if (exempt || !user || !Me->IsSynced() || !user->server->IsSynced()) + if (exempt || user->Quitting() || !Me->IsSynced() || !user->server->IsSynced()) return; /* At this time we only support IPv4 */ diff --git a/modules/extra/m_rewrite.cpp b/modules/extra/m_rewrite.cpp index 70710bd8a..2df259e3d 100644 --- a/modules/extra/m_rewrite.cpp +++ b/modules/extra/m_rewrite.cpp @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -9,7 +9,7 @@ struct Rewrite { - Anope::string client, source_message, target_message; + Anope::string client, source_message, target_message, desc; bool Matches(const std::vector<Anope::string> &message) { @@ -17,13 +17,13 @@ struct Rewrite spacesepstream(this->source_message).GetTokens(sm); for (unsigned i = 0; i < sm.size(); ++i) - if (sm[i] != "$" && !sm[i].equals_ci(message[i])) + if (i >= message.size() || (sm[i] != "$" && !sm[i].equals_ci(message[i]))) return false; return true; } - Anope::string Process(const std::vector<Anope::string> ¶ms) + Anope::string Process(CommandSource &source, const std::vector<Anope::string> ¶ms) { spacesepstream sep(this->target_message); Anope::string token, message; @@ -32,6 +32,8 @@ struct Rewrite { if (token[0] != '$') message += " " + token; + else if (token == "$me") + message += " " + source.GetNick(); else { int num = -1, end = -1; @@ -66,20 +68,97 @@ struct Rewrite message.trim(); return message; } + + static std::vector<Rewrite> rewrites; + + static Rewrite *Find(const Anope::string &client, const Anope::string &cmd) + { + for (unsigned i = 0; i < rewrites.size(); ++i) + { + Rewrite &r = rewrites[i]; + + if ((client.empty() || r.client.equals_ci(client)) && (r.source_message.equals_ci(cmd) || r.source_message.find_ci(cmd + " ") == 0)) + return &r; + } + + return NULL; + } + + static Rewrite *Match(const Anope::string &client, const std::vector<Anope::string> ¶ms) + { + for (unsigned i = 0; i < rewrites.size(); ++i) + { + Rewrite &r = rewrites[i]; + + if ((client.empty() || r.client.equals_ci(client)) && r.Matches(params)) + return &r; + } + + return NULL; + } +}; + +std::vector<Rewrite> Rewrite::rewrites; + +class RewriteCommand : public Command +{ + public: + RewriteCommand(Module *creator) : Command(creator, "rewrite", 0, 0) { } + + void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override + { + std::vector<Anope::string> full_params = params; + full_params.insert(full_params.begin(), source.command); + + Rewrite *r = Rewrite::Match(!source.c ? source.service->nick : "", full_params); + if (r != NULL) + { + Anope::string new_message = r->Process(source, full_params); + Log(LOG_DEBUG) << "m_rewrite: Rewrote '" << source.command << (!params.empty() ? " " + params[0] : "") << "' to '" << new_message << "' using '" << r->source_message << "'"; + source.service = BotInfo::Find(r->client); + if (!source.service) + return; + RunCommand(source, new_message); + } + else + Log() << "m_rewrite: Unable to rewrite '" << source.command << (!params.empty() ? " " + params[0] : "") << "'"; + } + + void OnServHelp(CommandSource &source) anope_override + { + Rewrite *r = Rewrite::Find(!source.c ? source.service->nick : "", source.command); + if (r != NULL && !r->desc.empty()) + { + this->SetDesc(r->desc); + Command::OnServHelp(source); + } + } + + bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override + { + Rewrite *r = Rewrite::Find(!source.c ? source.service->nick : "", source.command); + if (r != NULL && !r->desc.empty()) + { + source.Reply(r->desc); + size_t sz = r->target_message.find(' '); + source.Reply(_("This command is an alias to the command %s."), sz != Anope::string::npos ? r->target_message.substr(0, sz).c_str() : r->target_message.c_str()); + return true; + } + return false; + } }; class ModuleRewrite : public Module { - std::vector<Rewrite> rewrites; + RewriteCommand cmdrewrite; public: - ModuleRewrite(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, SUPPORTED) + ModuleRewrite(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, SUPPORTED), cmdrewrite(this) { this->SetAuthor("Anope"); - Implementation i[] = { I_OnReload, I_OnBotPrivmsg }; + Implementation i[] = { I_OnReload }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - ModuleManager::SetPriority(this, PRIORITY_FIRST); this->OnReload(); } @@ -88,42 +167,26 @@ class ModuleRewrite : public Module { ConfigReader config; - this->rewrites.clear(); + Rewrite::rewrites.clear(); - for (int i = 0; i < config.Enumerate("rewrite"); ++i) + for (int i = 0; i < config.Enumerate("command"); ++i) { + if (!config.ReadFlag("command", "rewrite", "no", i)) + continue; + Rewrite rw; - rw.client = config.ReadValue("rewrite", "client", "", i); - rw.source_message = config.ReadValue("rewrite", "source_message", "", i), - rw.target_message = config.ReadValue("rewrite", "target_message", "", i); + rw.client = config.ReadValue("command", "service", "", i); + rw.source_message = config.ReadValue("command", "rewrite_source", "", i), + rw.target_message = config.ReadValue("command", "rewrite_target", "", i); + rw.desc = config.ReadValue("command", "rewrite_description", "", i); if (rw.client.empty() || rw.source_message.empty() || rw.target_message.empty()) continue; - this->rewrites.push_back(rw); + Rewrite::rewrites.push_back(rw); } } - - EventReturn OnBotPrivmsg(User *u, BotInfo *bi, Anope::string &message) anope_override - { - std::vector<Anope::string> tokens; - spacesepstream(message).GetTokens(tokens); - for (unsigned i = 0; i < this->rewrites.size(); ++i) - { - Rewrite &rw = this->rewrites[i]; - - if (rw.client == bi->nick && rw.Matches(tokens)) - { - Anope::string new_message = rw.Process(tokens); - Log(LOG_DEBUG) << "m_rewrite: Rewrote '" << message << "' to '" << new_message << "'"; - message = new_message; - break; - } - } - - return EVENT_CONTINUE; - } }; MODULE_INIT(ModuleRewrite) diff --git a/modules/extra/m_sql_oper.cpp b/modules/extra/m_sql_oper.cpp index dd1f13b74..f786ad36d 100644 --- a/modules/extra/m_sql_oper.cpp +++ b/modules/extra/m_sql_oper.cpp @@ -51,7 +51,7 @@ class SQLOperResult : public SQL::Interface delete user->Account()->o; user->Account()->o = NULL; Log(this->owner) << "m_sql_oper: Removed services operator from " << user->nick << " (" << user->Account()->display << ")"; - user->RemoveMode(OperServ, UMODE_OPER); // Probably not set, just incase + user->RemoveMode(OperServ, "OPER"); // Probably not set, just incase } return; } @@ -70,7 +70,7 @@ class SQLOperResult : public SQL::Interface Config->Opers.push_back(user->Account()->o); } - if (!user->HasMode(UMODE_OPER)) + if (!user->HasMode("OPER")) { IRCD->SendOper(user); diff --git a/modules/extra/m_sqlite.cpp b/modules/extra/m_sqlite.cpp index 5d59c3eb9..69fd16b9f 100644 --- a/modules/extra/m_sqlite.cpp +++ b/modules/extra/m_sqlite.cpp @@ -209,7 +209,7 @@ std::vector<Query> SQLiteService::CreateTable(const Anope::string &table, const if (known_cols.empty()) { - Anope::string query_text = "CREATE TABLE `" + table + "` (`id` INTEGER PRIMARY KEY, `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP"; + Anope::string query_text = "CREATE TABLE `" + table + "` (`id` INTEGER PRIMARY KEY, `timestamp` timestamp DEFAULT CURRENT_TIMESTAMP"; for (Data::Map::const_iterator it = data.data.begin(), it_end = data.data.end(); it != it_end; ++it) { diff --git a/modules/extra/m_ssl.cpp b/modules/extra/m_ssl.cpp index fdde28919..7158a5ce5 100644 --- a/modules/extra/m_ssl.cpp +++ b/modules/extra/m_ssl.cpp @@ -1,4 +1,4 @@ -/* RequiredLibraries: ssl,crypt */ +/* RequiredLibraries: ssl,crypto */ #include "module.h" #include "ssl.h" @@ -256,7 +256,7 @@ ClientSocket *SSLSocketIO::Accept(ListenSocket *s) if (!SSL_set_fd(io->sslsock, newsocket->GetFD())) throw SocketException("Unable to set SSL fd"); - newsocket->SetFlag(SF_ACCEPTING); + newsocket->flags[SF_ACCEPTING] = true; this->FinishAccept(newsocket); return newsocket; @@ -266,9 +266,9 @@ SocketFlag SSLSocketIO::FinishAccept(ClientSocket *cs) { if (cs->io == &NormalSocketIO) throw SocketException("Attempting to finish connect uninitialized socket with SSL"); - else if (cs->HasFlag(SF_ACCEPTED)) + else if (cs->flags[SF_ACCEPTED]) return SF_ACCEPTED; - else if (!cs->HasFlag(SF_ACCEPTING)) + else if (!cs->flags[SF_ACCEPTING]) throw SocketException("SSLSocketIO::FinishAccept called for a socket not accepted nor accepting?"); SSLSocketIO *io = anope_dynamic_static_cast<SSLSocketIO *>(cs->io); @@ -286,15 +286,15 @@ SocketFlag SSLSocketIO::FinishAccept(ClientSocket *cs) else { cs->OnError(ERR_error_string(ERR_get_error(), NULL)); - cs->SetFlag(SF_DEAD); - cs->UnsetFlag(SF_ACCEPTING); + cs->flags[SF_DEAD] = true; + cs->flags[SF_ACCEPTING] = false; return SF_DEAD; } } else { - cs->SetFlag(SF_ACCEPTED); - cs->UnsetFlag(SF_ACCEPTING); + cs->flags[SF_ACCEPTED] = true; + cs->flags[SF_ACCEPTING] = false; SocketEngine::Change(cs, false, SF_WRITABLE); SocketEngine::Change(cs, true, SF_READABLE); cs->OnAccept(); @@ -307,8 +307,7 @@ void SSLSocketIO::Connect(ConnectionSocket *s, const Anope::string &target, int if (s->io == &NormalSocketIO) throw SocketException("Attempting to connect uninitialized socket with SSL"); - s->UnsetFlag(SF_CONNECTING); - s->UnsetFlag(SF_CONNECTED); + s->flags[SF_CONNECTING] = s->flags[SF_CONNECTED] = false; s->conaddr.pton(s->IsIPv6() ? AF_INET6 : AF_INET, target, port); int c = connect(s->GetFD(), &s->conaddr.sa, s->conaddr.size()); @@ -317,19 +316,19 @@ void SSLSocketIO::Connect(ConnectionSocket *s, const Anope::string &target, int if (Anope::LastErrorCode() != EINPROGRESS) { s->OnError(Anope::LastError()); - s->SetFlag(SF_DEAD); + s->flags[SF_DEAD] = true; return; } else { SocketEngine::Change(s, true, SF_WRITABLE); - s->SetFlag(SF_CONNECTING); + s->flags[SF_CONNECTING] = true; return; } } else { - s->SetFlag(SF_CONNECTING); + s->flags[SF_CONNECTING] = true; this->FinishConnect(s); } } @@ -338,9 +337,9 @@ SocketFlag SSLSocketIO::FinishConnect(ConnectionSocket *s) { if (s->io == &NormalSocketIO) throw SocketException("Attempting to finish connect uninitialized socket with SSL"); - else if (s->HasFlag(SF_CONNECTED)) + else if (s->flags[SF_CONNECTED]) return SF_CONNECTED; - else if (!s->HasFlag(SF_CONNECTING)) + else if (!s->flags[SF_CONNECTING]) throw SocketException("SSLSocketIO::FinishConnect called for a socket not connected nor connecting?"); SSLSocketIO *io = anope_dynamic_static_cast<SSLSocketIO *>(s->io); @@ -368,15 +367,15 @@ SocketFlag SSLSocketIO::FinishConnect(ConnectionSocket *s) else { s->OnError(ERR_error_string(ERR_get_error(), NULL)); - s->UnsetFlag(SF_CONNECTING); - s->SetFlag(SF_DEAD); + s->flags[SF_CONNECTING] = false; + s->flags[SF_DEAD] = true; return SF_DEAD; } } else { - s->UnsetFlag(SF_CONNECTING); - s->SetFlag(SF_CONNECTED); + s->flags[SF_CONNECTING] = false; + s->flags[SF_CONNECTED] = true; SocketEngine::Change(s, false, SF_WRITABLE); SocketEngine::Change(s, true, SF_READABLE); s->OnConnect(); diff --git a/modules/extra/m_xmlrpc_main.cpp b/modules/extra/m_xmlrpc_main.cpp index 672ef5524..e4b761cc7 100644 --- a/modules/extra/m_xmlrpc_main.cpp +++ b/modules/extra/m_xmlrpc_main.cpp @@ -153,29 +153,29 @@ class MyXMLRPCEvent : public XMLRPCEvent if (c) { - request.reply("bancount", stringify(c->HasMode(CMODE_BAN))); + request.reply("bancount", stringify(c->HasMode("BAN"))); int count = 0; - std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> its = c->GetModeList(CMODE_BAN); + std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> its = c->GetModeList("BAN"); for (; its.first != its.second; ++its.first) request.reply("ban" + stringify(++count), iface->Sanitize(its.first->second)); - request.reply("exceptcount", stringify(c->HasMode(CMODE_EXCEPT))); + request.reply("exceptcount", stringify(c->HasMode("EXCEPT"))); count = 0; - its = c->GetModeList(CMODE_EXCEPT); + its = c->GetModeList("EXCEPT"); for (; its.first != its.second; ++its.first) request.reply("except" + stringify(++count), iface->Sanitize(its.first->second)); - request.reply("invitecount", stringify(c->HasMode(CMODE_INVITEOVERRIDE))); + request.reply("invitecount", stringify(c->HasMode("INVITEOVERRIDE"))); count = 0; - its = c->GetModeList(CMODE_INVITEOVERRIDE); + its = c->GetModeList("INVITEOVERRIDE"); for (; its.first != its.second; ++its.first) request.reply("invite" + stringify(++count), iface->Sanitize(its.first->second)); Anope::string users; - for (CUserList::const_iterator it = c->users.begin(); it != c->users.end(); ++it) + for (Channel::ChanUserList::const_iterator it = c->users.begin(); it != c->users.end(); ++it) { - UserContainer *uc = *it; - users += uc->status->BuildModePrefixList() + uc->user->nick + " "; + ChanUserContainer *uc = *it; + users += uc->status.BuildModePrefixList() + uc->user->nick + " "; } if (!users.empty()) { @@ -224,10 +224,10 @@ class MyXMLRPCEvent : public XMLRPCEvent } Anope::string channels; - for (UChannelList::const_iterator it = u->chans.begin(); it != u->chans.end(); ++it) + for (User::ChanUserList::const_iterator it = u->chans.begin(); it != u->chans.end(); ++it) { - ChannelContainer *cc = *it; - channels += cc->status->BuildModePrefixList() + cc->chan->name + " "; + ChanUserContainer *cc = *it; + channels += cc->status.BuildModePrefixList() + cc->chan->name + " "; } if (!channels.empty()) { diff --git a/modules/extra/ns_maxemail.cpp b/modules/extra/ns_maxemail.cpp index 121da057b..fda500a07 100644 --- a/modules/extra/ns_maxemail.cpp +++ b/modules/extra/ns_maxemail.cpp @@ -1,16 +1,13 @@ -/* ns_maxemail.c - Limit the amount of times an email address - * can be used for a NickServ account. +/* ns_maxemail.cpp - Limit the amount of times an email address + * can be used for a NickServ account. * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Included in the Anope module pack since Anope 1.7.9 * Anope Coder: GeniusDex <geniusdex@anope.org> * * Please read COPYING and README for further details. - * - * Send any bug reports to the Anope Coder, as he will be able - * to deal with it best. */ #include "module.h" diff --git a/modules/extra/sql.h b/modules/extra/sql.h index f8c7a5961..1c8fdd3aa 100644 --- a/modules/extra/sql.h +++ b/modules/extra/sql.h @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -28,37 +28,34 @@ namespace SQL return *ss; } - bool IsEqual(Serialize::Data *other) anope_override + std::set<Anope::string> KeySet() const anope_override { - try - { - Data *o = anope_dynamic_static_cast<Data *>(other); - - for (std::map<Anope::string, std::stringstream *>::const_iterator it = o->data.begin(), it_end = o->data.end(); it != it_end; ++it) - if (!this->data.count(it->first) || it->second->str() != this->data[it->first]->str()) - return false; - - return true; - } - catch (const CoreException &ex) - { - Log(LOG_DEBUG) << ex.GetReason(); - } + std::set<Anope::string> keys; + for (Map::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it) + keys.insert(it->first); + return keys; + } - return false; + size_t Hash() const anope_override + { + size_t hash = 0; + for (Map::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it) + if (!it->second->str().empty()) + hash ^= Anope::hash_cs()(it->second->str()); + return hash; } std::map<Anope::string, std::iostream *> GetData() const { std::map<Anope::string, std::iostream *> d; - for (std::map<Anope::string, std::stringstream *>::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it) + for (Map::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it) d[it->first] = it->second; return d; } void Clear() { - for (std::map<Anope::string, std::stringstream *>::iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it) + for (Map::const_iterator it = this->data.begin(), it_end = this->data.end(); it != it_end; ++it) delete it->second; this->data.clear(); } diff --git a/modules/extra/webcpanel/pages/chanserv/access.cpp b/modules/extra/webcpanel/pages/chanserv/access.cpp index 96fa3dca5..33250035e 100644 --- a/modules/extra/webcpanel/pages/chanserv/access.cpp +++ b/modules/extra/webcpanel/pages/chanserv/access.cpp @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -70,7 +70,7 @@ bool WebCPanel::ChanServ::Access::OnRequest(HTTPProvider *server, const Anope::s denied = true; } else - ci->EraseAccess(acc); + delete acc; break; } } diff --git a/modules/extra/webcpanel/pages/chanserv/access.h b/modules/extra/webcpanel/pages/chanserv/access.h index d5fbbf68c..0ead74154 100644 --- a/modules/extra/webcpanel/pages/chanserv/access.h +++ b/modules/extra/webcpanel/pages/chanserv/access.h @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/extra/webcpanel/pages/chanserv/akick.cpp b/modules/extra/webcpanel/pages/chanserv/akick.cpp index bb678b715..95fb8fb30 100644 --- a/modules/extra/webcpanel/pages/chanserv/akick.cpp +++ b/modules/extra/webcpanel/pages/chanserv/akick.cpp @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/extra/webcpanel/pages/chanserv/akick.h b/modules/extra/webcpanel/pages/chanserv/akick.h index cd8408934..91b3bc292 100644 --- a/modules/extra/webcpanel/pages/chanserv/akick.h +++ b/modules/extra/webcpanel/pages/chanserv/akick.h @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/extra/webcpanel/pages/chanserv/drop.cpp b/modules/extra/webcpanel/pages/chanserv/drop.cpp index f0fc0d5c2..5462aa131 100644 --- a/modules/extra/webcpanel/pages/chanserv/drop.cpp +++ b/modules/extra/webcpanel/pages/chanserv/drop.cpp @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -25,20 +25,22 @@ bool WebCPanel::ChanServ::Drop::OnRequest(HTTPProvider *server, const Anope::str } else replacements["MESSAGES"] = "Invalid Confirmation"; } - // XXX this is slightly inefficient - for (registered_channel_map::const_iterator it = RegisteredChannelList->begin(), it_end = RegisteredChannelList->end(); it != it_end; ++it) + + std::deque<ChannelInfo *> queue; + na->nc->GetChannelReferences(queue); + for (unsigned i = 0; i < queue.size(); ++i) { - ChannelInfo *ci = it->second; - if ((ci->HasFlag(CI_SECUREFOUNDER) ? ci->AccessFor(na->nc).founder : ci->AccessFor(na->nc).HasPriv("FOUNDER")) || (na->nc->IsServicesOper() && na->nc->o->ot->HasCommand("chanserv/drop"))) + ChannelInfo *ci = queue[i]; + if ((ci->HasExt("SECUREFOUNDER") ? ci->AccessFor(na->nc).founder : ci->AccessFor(na->nc).HasPriv("FOUNDER")) || (na->nc->IsServicesOper() && na->nc->o->ot->HasCommand("chanserv/drop"))) { replacements["CHANNEL_NAMES"] = ci->name; replacements["ESCAPED_CHANNEL_NAMES"] = HTTPUtils::URLEncode(ci->name); } } - if (message.get_data.count("channel") > 0) { + if (message.get_data.count("channel") > 0) replacements["CHANNEL_DROP"] = message.get_data["channel"]; - } + TemplateFileServer page("chanserv/drop.html"); page.Serve(server, page_name, client, message, reply, replacements); return true; diff --git a/modules/extra/webcpanel/pages/chanserv/drop.h b/modules/extra/webcpanel/pages/chanserv/drop.h index 9fd4be720..4f081a9f4 100644 --- a/modules/extra/webcpanel/pages/chanserv/drop.h +++ b/modules/extra/webcpanel/pages/chanserv/drop.h @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/extra/webcpanel/pages/chanserv/info.cpp b/modules/extra/webcpanel/pages/chanserv/info.cpp index 44ae98537..95592706d 100644 --- a/modules/extra/webcpanel/pages/chanserv/info.cpp +++ b/modules/extra/webcpanel/pages/chanserv/info.cpp @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -13,10 +13,11 @@ WebCPanel::ChanServ::Info::Info(const Anope::string &cat, const Anope::string &u bool WebCPanel::ChanServ::Info::OnRequest(HTTPProvider *server, const Anope::string &page_name, HTTPClient *client, HTTPMessage &message, HTTPReply &reply, NickAlias *na, TemplateFileServer::Replacements &replacements) { - // XXX this is slightly inefficient - for (registered_channel_map::const_iterator it = RegisteredChannelList->begin(), it_end = RegisteredChannelList->end(); it != it_end; ++it) + std::deque<ChannelInfo *> queue; + na->nc->GetChannelReferences(queue); + for (unsigned i = 0; i < queue.size(); ++i) { - ChannelInfo *ci = it->second; + ChannelInfo *ci = queue[i]; if (ci->AccessFor(na->nc).HasPriv("SET") || ci->AccessFor(na->nc).HasPriv("ACCESS_LIST")) { diff --git a/modules/extra/webcpanel/pages/chanserv/info.h b/modules/extra/webcpanel/pages/chanserv/info.h index c55e1b1eb..844380331 100644 --- a/modules/extra/webcpanel/pages/chanserv/info.h +++ b/modules/extra/webcpanel/pages/chanserv/info.h @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/extra/webcpanel/pages/chanserv/set.cpp b/modules/extra/webcpanel/pages/chanserv/set.cpp index 4a61b37db..20026a08a 100644 --- a/modules/extra/webcpanel/pages/chanserv/set.cpp +++ b/modules/extra/webcpanel/pages/chanserv/set.cpp @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -29,60 +29,60 @@ bool WebCPanel::ChanServ::Set::OnRequest(HTTPProvider *server, const Anope::stri if (message.post_data.empty() == false) { - if (ci->HasFlag(CI_KEEPTOPIC) != message.post_data.count("keeptopic")) + if (ci->HasExt("KEEPTOPIC") != message.post_data.count("keeptopic")) { - if (!ci->HasFlag(CI_KEEPTOPIC)) - ci->SetFlag(CI_KEEPTOPIC); + if (!ci->HasExt("KEEPTOPIC")) + ci->ExtendMetadata("KEEPTOPIC"); else - ci->UnsetFlag(CI_KEEPTOPIC); + ci->Shrink("KEEPTOPIC"); replacements["MESSAGES"] = "Secure updated"; } - if (ci->HasFlag(CI_PEACE) != message.post_data.count("peace")) + if (ci->HasExt("PEACE") != message.post_data.count("peace")) { - if (!ci->HasFlag(CI_PEACE)) - ci->SetFlag(CI_PEACE); + if (!ci->HasExt("PEACE")) + ci->ExtendMetadata("PEACE"); else - ci->UnsetFlag(CI_PEACE); + ci->Shrink("PEACE"); replacements["MESSAGES"] = "Peace updated"; } - if (ci->HasFlag(CI_PRIVATE) != message.post_data.count("private")) + if (ci->HasExt("PRIVATE") != message.post_data.count("private")) { - if (!ci->HasFlag(CI_PRIVATE)) - ci->SetFlag(CI_PRIVATE); + if (!ci->HasExt("PRIVATE")) + ci->ExtendMetadata("PRIVATE"); else - ci->UnsetFlag(CI_PRIVATE); + ci->Shrink("PRIVATE"); replacements["MESSAGES"] = "Private updated"; } - if (ci->HasFlag(CI_RESTRICTED) != message.post_data.count("restricted")) + if (ci->HasExt("RESTRICTED") != message.post_data.count("restricted")) { - if (!ci->HasFlag(CI_RESTRICTED)) - ci->SetFlag(CI_RESTRICTED); + if (!ci->HasExt("RESTRICTED")) + ci->ExtendMetadata("RESTRICTED"); else - ci->UnsetFlag(CI_RESTRICTED); + ci->Shrink("RESTRICTED"); replacements["MESSAGES"] = "Restricted updated"; } - if (ci->HasFlag(CI_SECURE) != message.post_data.count("secure")) + if (ci->HasExt("SECURE") != message.post_data.count("secure")) { - if (!ci->HasFlag(CI_SECURE)) - ci->SetFlag(CI_SECURE); + if (!ci->HasExt("SECURE")) + ci->ExtendMetadata("SECURE"); else - ci->UnsetFlag(CI_SECURE); + ci->Shrink("SECURE"); replacements["MESSAGES"] = "Secure updated"; } - if (ci->HasFlag(CI_SECUREOPS) != message.post_data.count("secureops")) + if (ci->HasExt("SECUREOPS") != message.post_data.count("secureops")) { - if (!ci->HasFlag(CI_SECUREOPS)) - ci->SetFlag(CI_SECUREOPS); + if (!ci->HasExt("SECUREOPS")) + ci->ExtendMetadata("SECUREOPS"); else - ci->UnsetFlag(CI_SECUREOPS); + ci->Shrink("SECUREOPS"); replacements["MESSAGES"] = "Secureops updated"; } - if (ci->HasFlag(CI_TOPICLOCK) != message.post_data.count("topiclock")) + if (ci->HasExt("TOPICLOCK") != message.post_data.count("topiclock")) { - if (!ci->HasFlag(CI_TOPICLOCK)) - ci->SetFlag(CI_TOPICLOCK); + if (!ci->HasExt("TOPICLOCK")) + ci->ExtendMetadata("TOPICLOCK"); else - ci->UnsetFlag(CI_TOPICLOCK); + ci->Shrink("TOPICLOCK"); replacements["MESSAGES"] = "Topiclock updated"; } } @@ -91,8 +91,8 @@ bool WebCPanel::ChanServ::Set::OnRequest(HTTPProvider *server, const Anope::stri replacements["CHANNEL_ESCAPED"] = HTTPUtils::URLEncode(ci->name); if (ci->GetFounder()) replacements["FOUNDER"] = ci->GetFounder()->display; - if (ci->successor) - replacements["SUCCESSOR"] = ci->successor->display; + if (ci->GetSuccessor()) + replacements["SUCCESSOR"] = ci->GetSuccessor()->display; replacements["TIME_REGISTERED"] = Anope::strftime(ci->time_registered, na->nc); replacements["LAST_USED"] = Anope::strftime(ci->last_used, na->nc); @@ -102,25 +102,25 @@ bool WebCPanel::ChanServ::Set::OnRequest(HTTPProvider *server, const Anope::stri replacements["LAST_TOPIC_SETTER"] = HTTPUtils::Escape(ci->last_topic_setter); } - if (ci->HasFlag(CI_KEEPTOPIC)) + if (ci->HasExt("KEEPTOPIC")) replacements["KEEPTOPIC"]; - if (ci->HasFlag(CI_PEACE)) + if (ci->HasExt("PEACE")) replacements["PEACE"]; - if (ci->HasFlag(CI_PRIVATE)) + if (ci->HasExt("PRIVATE")) replacements["PRIVATE"]; - if (ci->HasFlag(CI_RESTRICTED)) + if (ci->HasExt("RESTRICTED")) replacements["RESTRICTED"]; - if (ci->HasFlag(CI_SECURE)) + if (ci->HasExt("SECURE")) replacements["SECURE"]; - if (ci->HasFlag(CI_SECUREOPS)) + if (ci->HasExt("SECUREOPS")) replacements["SECUREOPS"]; - if (ci->HasFlag(CI_TOPICLOCK)) + if (ci->HasExt("TOPICLOCK")) replacements["TOPICLOCK"]; TemplateFileServer page("chanserv/set.html"); diff --git a/modules/extra/webcpanel/pages/chanserv/set.h b/modules/extra/webcpanel/pages/chanserv/set.h index 4d4113b5a..1a7df021f 100644 --- a/modules/extra/webcpanel/pages/chanserv/set.h +++ b/modules/extra/webcpanel/pages/chanserv/set.h @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/extra/webcpanel/pages/confirm.cpp b/modules/extra/webcpanel/pages/confirm.cpp index 18e2004b5..1f5d61cc1 100644 --- a/modules/extra/webcpanel/pages/confirm.cpp +++ b/modules/extra/webcpanel/pages/confirm.cpp @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/extra/webcpanel/pages/confirm.h b/modules/extra/webcpanel/pages/confirm.h index c6a5d180d..e0966fce3 100644 --- a/modules/extra/webcpanel/pages/confirm.h +++ b/modules/extra/webcpanel/pages/confirm.h @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/extra/webcpanel/pages/hostserv/request.cpp b/modules/extra/webcpanel/pages/hostserv/request.cpp index dfa4287f1..6335b1a56 100644 --- a/modules/extra/webcpanel/pages/hostserv/request.cpp +++ b/modules/extra/webcpanel/pages/hostserv/request.cpp @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/extra/webcpanel/pages/hostserv/request.h b/modules/extra/webcpanel/pages/hostserv/request.h index e26bea224..686e42fc2 100644 --- a/modules/extra/webcpanel/pages/hostserv/request.h +++ b/modules/extra/webcpanel/pages/hostserv/request.h @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/extra/webcpanel/pages/index.cpp b/modules/extra/webcpanel/pages/index.cpp index 6178dab29..4449f5f60 100644 --- a/modules/extra/webcpanel/pages/index.cpp +++ b/modules/extra/webcpanel/pages/index.cpp @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/extra/webcpanel/pages/index.h b/modules/extra/webcpanel/pages/index.h index e67d7181a..201b12a78 100644 --- a/modules/extra/webcpanel/pages/index.h +++ b/modules/extra/webcpanel/pages/index.h @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/extra/webcpanel/pages/logout.cpp b/modules/extra/webcpanel/pages/logout.cpp index e08a60ce7..14e1c24b5 100644 --- a/modules/extra/webcpanel/pages/logout.cpp +++ b/modules/extra/webcpanel/pages/logout.cpp @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/extra/webcpanel/pages/logout.h b/modules/extra/webcpanel/pages/logout.h index d00a83733..11e65ab99 100644 --- a/modules/extra/webcpanel/pages/logout.h +++ b/modules/extra/webcpanel/pages/logout.h @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/extra/webcpanel/pages/memoserv/memos.cpp b/modules/extra/webcpanel/pages/memoserv/memos.cpp index e3a3f9b80..db4fcfc1b 100644 --- a/modules/extra/webcpanel/pages/memoserv/memos.cpp +++ b/modules/extra/webcpanel/pages/memoserv/memos.cpp @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -93,13 +93,9 @@ bool WebCPanel::MemoServ::Memos::OnRequest(HTTPProvider *server, const Anope::st } if (!error && message.get_data["read"] == "1") - { - m->UnsetFlag(MF_UNREAD); - } + m->unread = false; else if (!error && message.get_data["read"] == "2") - { - m->SetFlag(MF_UNREAD); - } + m->unread = true; } for (unsigned i = 0; i < mi->memos->size(); ++i) @@ -109,7 +105,7 @@ bool WebCPanel::MemoServ::Memos::OnRequest(HTTPProvider *server, const Anope::st replacements["SENDER"] = m->sender; replacements["TIME"] = Anope::strftime(m->time); replacements["TEXT"] = m->text; - if (m->HasFlag(MF_UNREAD)) + if (m->unread) replacements["UNREAD"] = "YES"; else replacements["UNREAD"] = "NO"; diff --git a/modules/extra/webcpanel/pages/memoserv/memos.h b/modules/extra/webcpanel/pages/memoserv/memos.h index 32942147f..9ffdb299d 100644 --- a/modules/extra/webcpanel/pages/memoserv/memos.h +++ b/modules/extra/webcpanel/pages/memoserv/memos.h @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/extra/webcpanel/pages/nickserv/access.cpp b/modules/extra/webcpanel/pages/nickserv/access.cpp index 40128f47e..de0e544f7 100644 --- a/modules/extra/webcpanel/pages/nickserv/access.cpp +++ b/modules/extra/webcpanel/pages/nickserv/access.cpp @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/extra/webcpanel/pages/nickserv/access.h b/modules/extra/webcpanel/pages/nickserv/access.h index 068757877..604fd1e16 100644 --- a/modules/extra/webcpanel/pages/nickserv/access.h +++ b/modules/extra/webcpanel/pages/nickserv/access.h @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/extra/webcpanel/pages/nickserv/alist.cpp b/modules/extra/webcpanel/pages/nickserv/alist.cpp index 3b5b8dab0..0afe2a4f3 100644 --- a/modules/extra/webcpanel/pages/nickserv/alist.cpp +++ b/modules/extra/webcpanel/pages/nickserv/alist.cpp @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -24,7 +24,7 @@ bool WebCPanel::NickServ::Alist::OnRequest(HTTPProvider *server, const Anope::st ++chan_count; replacements["NUMBERS"] = stringify(chan_count); - replacements["CHANNELS"] = (ci->HasFlag(CI_NO_EXPIRE) ? "!" : "") + ci->name; + replacements["CHANNELS"] = (ci->HasExt("NO_EXPIRE") ? "!" : "") + ci->name; replacements["ACCESSES"] = "Founder"; continue; } @@ -36,7 +36,7 @@ bool WebCPanel::NickServ::Alist::OnRequest(HTTPProvider *server, const Anope::st ++chan_count; replacements["NUMBERS"] = stringify(chan_count); - replacements["CHANNELS"] = (ci->HasFlag(CI_NO_EXPIRE) ? "!" : "") + ci->name; + replacements["CHANNELS"] = (ci->HasExt("NO_EXPIRE") ? "!" : "") + ci->name; Anope::string access_str; for (unsigned i = 0; i < access.size(); ++i) access_str += ", " + access[i]->AccessSerialize(); diff --git a/modules/extra/webcpanel/pages/nickserv/alist.h b/modules/extra/webcpanel/pages/nickserv/alist.h index 93ec85d03..45918ce21 100644 --- a/modules/extra/webcpanel/pages/nickserv/alist.h +++ b/modules/extra/webcpanel/pages/nickserv/alist.h @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/extra/webcpanel/pages/nickserv/cert.cpp b/modules/extra/webcpanel/pages/nickserv/cert.cpp index 5c799d2f6..fc13e2ce5 100644 --- a/modules/extra/webcpanel/pages/nickserv/cert.cpp +++ b/modules/extra/webcpanel/pages/nickserv/cert.cpp @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/extra/webcpanel/pages/nickserv/cert.h b/modules/extra/webcpanel/pages/nickserv/cert.h index bcc148132..2083187a3 100644 --- a/modules/extra/webcpanel/pages/nickserv/cert.h +++ b/modules/extra/webcpanel/pages/nickserv/cert.h @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/extra/webcpanel/pages/nickserv/info.cpp b/modules/extra/webcpanel/pages/nickserv/info.cpp index cdd80b7cd..35a4a8a0a 100644 --- a/modules/extra/webcpanel/pages/nickserv/info.cpp +++ b/modules/extra/webcpanel/pages/nickserv/info.cpp @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -36,46 +36,46 @@ bool WebCPanel::NickServ::Info::OnRequest(HTTPProvider *server, const Anope::str replacements["MESSAGES"] = "Greet updated"; } } - if (na->nc->HasFlag(NI_AUTOOP) != message.post_data.count("autoop")) + if (na->nc->HasExt("AUTOOP") != message.post_data.count("autoop")) { - if (!na->nc->HasFlag(NI_AUTOOP)) - na->nc->SetFlag(NI_AUTOOP); + if (!na->nc->HasExt("AUTOOP")) + na->nc->ExtendMetadata("AUTOOP"); else - na->nc->UnsetFlag(NI_AUTOOP); + na->nc->Shrink("AUTOOP"); replacements["MESSAGES"] = "Autoop updated"; } - if (na->nc->HasFlag(NI_PRIVATE) != message.post_data.count("private")) + if (na->nc->HasExt("PRIVATE") != message.post_data.count("private")) { - if (!na->nc->HasFlag(NI_PRIVATE)) - na->nc->SetFlag(NI_PRIVATE); + if (!na->nc->HasExt("PRIVATE")) + na->nc->ExtendMetadata("PRIVATE"); else - na->nc->UnsetFlag(NI_PRIVATE); + na->nc->Shrink("PRIVATE"); replacements["MESSAGES"] = "Private updated"; } - if (na->nc->HasFlag(NI_SECURE) != message.post_data.count("secure")) + if (na->nc->HasExt("SECURE") != message.post_data.count("secure")) { - if (!na->nc->HasFlag(NI_SECURE)) - na->nc->SetFlag(NI_SECURE); + if (!na->nc->HasExt("SECURE")) + na->nc->ExtendMetadata("SECURE"); else - na->nc->UnsetFlag(NI_SECURE); + na->nc->Shrink("SECURE"); replacements["MESSAGES"] = "Secure updated"; } - if (message.post_data["kill"] == "on" && !na->nc->HasFlag(NI_KILLPROTECT)) + if (message.post_data["kill"] == "on" && !na->nc->HasExt("KILLPROTECT")) { - na->nc->SetFlag(NI_KILLPROTECT); - na->nc->UnsetFlag(NI_KILL_QUICK); + na->nc->ExtendMetadata("KILLPROTECT"); + na->nc->Shrink("KILL_QUICK"); replacements["MESSAGES"] = "Kill updated"; } - else if (message.post_data["kill"] == "quick" && !na->nc->HasFlag(NI_KILL_QUICK)) + else if (message.post_data["kill"] == "quick" && !na->nc->HasExt("KILL_QUICK")) { - na->nc->UnsetFlag(NI_KILLPROTECT); - na->nc->SetFlag(NI_KILL_QUICK); + na->nc->Shrink("KILLPROTECT"); + na->nc->ExtendMetadata("KILL_QUICK"); replacements["MESSAGES"] = "Kill updated"; } - else if (message.post_data["kill"] == "off" && (na->nc->HasFlag(NI_KILLPROTECT) || na->nc->HasFlag(NI_KILL_QUICK))) + else if (message.post_data["kill"] == "off" && (na->nc->HasExt("KILLPROTECT") || na->nc->HasExt("KILL_QUICK"))) { - na->nc->UnsetFlag(NI_KILLPROTECT); - na->nc->UnsetFlag(NI_KILL_QUICK); + na->nc->Shrink("KILLPROTECT"); + na->nc->Shrink("KILL_QUICK"); replacements["MESSAGES"] = "Kill updated"; } } @@ -92,17 +92,17 @@ bool WebCPanel::NickServ::Info::OnRequest(HTTPProvider *server, const Anope::str replacements["VHOST"] = na->GetVhostHost(); } replacements["GREET"] = HTTPUtils::Escape(na->nc->greet); - if (na->nc->HasFlag(NI_AUTOOP)) + if (na->nc->HasExt("AUTOOP")) replacements["AUTOOP"]; - if (na->nc->HasFlag(NI_PRIVATE)) + if (na->nc->HasExt("PRIVATE")) replacements["PRIVATE"]; - if (na->nc->HasFlag(NI_SECURE)) + if (na->nc->HasExt("SECURE")) replacements["SECURE"]; - if (na->nc->HasFlag(NI_KILLPROTECT)) + if (na->nc->HasExt("KILLPROTECT")) replacements["KILL_ON"]; - if (na->nc->HasFlag(NI_KILL_QUICK)) + if (na->nc->HasExt("KILL_QUICK")) replacements["KILL_QUICK"]; - if (!na->nc->HasFlag(NI_KILLPROTECT) && !na->nc->HasFlag(NI_KILL_QUICK)) + if (!na->nc->HasExt("KILLPROTECT") && !na->nc->HasExt("KILL_QUICK")) replacements["KILL_OFF"]; TemplateFileServer page("nickserv/info.html"); diff --git a/modules/extra/webcpanel/pages/nickserv/info.h b/modules/extra/webcpanel/pages/nickserv/info.h index 45ffbc882..abfc3b67e 100644 --- a/modules/extra/webcpanel/pages/nickserv/info.h +++ b/modules/extra/webcpanel/pages/nickserv/info.h @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/extra/webcpanel/pages/operserv/akill.cpp b/modules/extra/webcpanel/pages/operserv/akill.cpp index 112949d9e..87b8f94fb 100644 --- a/modules/extra/webcpanel/pages/operserv/akill.cpp +++ b/modules/extra/webcpanel/pages/operserv/akill.cpp @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/extra/webcpanel/pages/operserv/akill.h b/modules/extra/webcpanel/pages/operserv/akill.h index 270ae84a7..aba5ecfa9 100644 --- a/modules/extra/webcpanel/pages/operserv/akill.h +++ b/modules/extra/webcpanel/pages/operserv/akill.h @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/extra/webcpanel/pages/register.cpp b/modules/extra/webcpanel/pages/register.cpp index e8ed84303..409069348 100644 --- a/modules/extra/webcpanel/pages/register.cpp +++ b/modules/extra/webcpanel/pages/register.cpp @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/extra/webcpanel/pages/register.h b/modules/extra/webcpanel/pages/register.h index deb46c950..35e373a9a 100644 --- a/modules/extra/webcpanel/pages/register.h +++ b/modules/extra/webcpanel/pages/register.h @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/extra/webcpanel/static_fileserver.cpp b/modules/extra/webcpanel/static_fileserver.cpp index 1fbf46ee8..0c8bccd57 100644 --- a/modules/extra/webcpanel/static_fileserver.cpp +++ b/modules/extra/webcpanel/static_fileserver.cpp @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/extra/webcpanel/static_fileserver.h b/modules/extra/webcpanel/static_fileserver.h index 238614610..9bb274f5e 100644 --- a/modules/extra/webcpanel/static_fileserver.h +++ b/modules/extra/webcpanel/static_fileserver.h @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/extra/webcpanel/template_fileserver.cpp b/modules/extra/webcpanel/template_fileserver.cpp index 79e583388..162c2c128 100644 --- a/modules/extra/webcpanel/template_fileserver.cpp +++ b/modules/extra/webcpanel/template_fileserver.cpp @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/extra/webcpanel/template_fileserver.h b/modules/extra/webcpanel/template_fileserver.h index 58d6a4872..44e2fe708 100644 --- a/modules/extra/webcpanel/template_fileserver.h +++ b/modules/extra/webcpanel/template_fileserver.h @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/extra/webcpanel/webcpanel.cpp b/modules/extra/webcpanel/webcpanel.cpp index 816624628..77e99dd4e 100644 --- a/modules/extra/webcpanel/webcpanel.cpp +++ b/modules/extra/webcpanel/webcpanel.cpp @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/extra/webcpanel/webcpanel.h b/modules/extra/webcpanel/webcpanel.h index 7c897f9af..74a8805d4 100644 --- a/modules/extra/webcpanel/webcpanel.h +++ b/modules/extra/webcpanel/webcpanel.h @@ -1,5 +1,5 @@ /* - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. diff --git a/modules/protocol/bahamut.cpp b/modules/protocol/bahamut.cpp index 166ada3bb..8c2c131a6 100644 --- a/modules/protocol/bahamut.cpp +++ b/modules/protocol/bahamut.cpp @@ -1,6 +1,6 @@ /* Bahamut functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -16,7 +16,7 @@ class ChannelModeFlood : public ChannelModeParam { public: - ChannelModeFlood(char modeChar, bool minusNoArg) : ChannelModeParam(CMODE_FLOOD, modeChar, minusNoArg) { } + ChannelModeFlood(char modeChar, bool minusNoArg) : ChannelModeParam("FLOOD", modeChar, minusNoArg) { } bool IsValid(const Anope::string &value) const anope_override { @@ -180,13 +180,13 @@ class BahamutIRCdProto : public IRCDProto /* If the user is internally on the channel with flags, kill them so that * the stacker will allow this. */ - UserContainer *uc = c->FindUser(user); + ChanUserContainer *uc = c->FindUser(user); if (uc != NULL) - uc->status->ClearFlags(); + uc->status.modes.clear(); BotInfo *setter = BotInfo::Find(user->nick); for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i) - if (cs.HasFlag(ModeManager::ChannelModes[i]->name)) + if (cs.modes.count(ModeManager::ChannelModes[i]->name)) c->SetMode(setter, ModeManager::ChannelModes[i], user->GetUID(), false); } } @@ -371,7 +371,9 @@ struct IRCDMessageMode : IRCDMessage */ struct IRCDMessageNick : IRCDMessage { - IRCDMessageNick(Module *creator) : IRCDMessage(creator, "NICK", 2) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); } + ServiceReference<NickServService> NSService; + + IRCDMessageNick(Module *creator) : IRCDMessage(creator, "NICK", 2), NSService("NickServService", "NickServ") { SetFlag(IRCDMESSAGE_SOFT_LIMIT); } void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override { @@ -385,19 +387,13 @@ struct IRCDMessageNick : IRCDMessage } User *user = new User(params[0], params[4], params[5], "", params[8], s, params[9], params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : 0, params[3]); - if (user && NickServService) + try { - const NickAlias *na; - if (user->signon == convertTo<time_t>(params[7]) && (na = NickAlias::Find(user->nick))) - { - NickCore *nc = na->nc; - user->Login(nc); - if (!Config->NoNicknameOwnership && na->nc->HasFlag(NI_UNCONFIRMED) == false) - user->SetMode(NickServ, UMODE_REGISTERED); - } - else - NickServService->Validate(user); + NickAlias *na; + if (NSService && user->signon == convertTo<time_t>(params[7]) && (na = NickAlias::Find(user->nick))) + NSService->Login(user, na); } + catch (const ConvertException &) { } } else source.GetUser()->ChangeNick(params[0]); @@ -459,7 +455,7 @@ struct IRCDMessageSJoin : IRCDMessage continue; } - sju.first.SetFlag(cm->name); + sju.first.modes.insert(cm->name); } sju.second = User::Find(buf); @@ -523,38 +519,38 @@ class ProtoBahamut : public Module void AddModes() { /* Add user modes */ - ModeManager::AddUserMode(new UserMode(UMODE_SERV_ADMIN, 'A')); - ModeManager::AddUserMode(new UserMode(UMODE_REGPRIV, 'R')); - ModeManager::AddUserMode(new UserMode(UMODE_ADMIN, 'a')); - ModeManager::AddUserMode(new UserMode(UMODE_INVIS, 'i')); - ModeManager::AddUserMode(new UserMode(UMODE_OPER, 'o')); - ModeManager::AddUserMode(new UserMode(UMODE_REGISTERED, 'r')); - ModeManager::AddUserMode(new UserMode(UMODE_SNOMASK, 's')); - ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, 'w')); - ModeManager::AddUserMode(new UserMode(UMODE_DEAF, 'd')); + ModeManager::AddUserMode(new UserMode("SERV_ADMIN", 'A')); + ModeManager::AddUserMode(new UserMode("REGPRIV", 'R')); + ModeManager::AddUserMode(new UserMode("ADMIN", 'a')); + ModeManager::AddUserMode(new UserMode("INVIS", 'i')); + ModeManager::AddUserMode(new UserMode("OPER", 'o')); + ModeManager::AddUserMode(new UserMode("REGISTERED", 'r')); + ModeManager::AddUserMode(new UserMode("SNOMASK", 's')); + ModeManager::AddUserMode(new UserMode("WALLOPS", 'w')); + ModeManager::AddUserMode(new UserMode("DEAF", 'd')); /* b/e/I */ - ModeManager::AddChannelMode(new ChannelModeList(CMODE_BAN, 'b')); + ModeManager::AddChannelMode(new ChannelModeList("BAN", 'b')); /* v/h/o/a/q */ - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', '+', 0)); - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', '@', 1)); + ModeManager::AddChannelMode(new ChannelModeStatus("VOICE", 'v', '+', 0)); + ModeManager::AddChannelMode(new ChannelModeStatus("OP", 'o', '@', 1)); /* Add channel modes */ - ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCOLOR, 'c')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, 'i')); + ModeManager::AddChannelMode(new ChannelMode("BLOCKCOLOR", 'c')); + ModeManager::AddChannelMode(new ChannelMode("INVITE", 'i')); ModeManager::AddChannelMode(new ChannelModeFlood('f', false)); ModeManager::AddChannelMode(new ChannelModeKey('k')); - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, 'l')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, 'm')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, 'n')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_PRIVATE, 'p')); + ModeManager::AddChannelMode(new ChannelModeParam("LIMIT", 'l')); + ModeManager::AddChannelMode(new ChannelMode("MODERATED", 'm')); + ModeManager::AddChannelMode(new ChannelMode("NOEXTERNAL", 'n')); + ModeManager::AddChannelMode(new ChannelMode("PRIVATE", 'p')); ModeManager::AddChannelMode(new ChannelModeRegistered('r')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, 's')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, 't')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_REGMODERATED, 'M')); + ModeManager::AddChannelMode(new ChannelMode("SECRET", 's')); + ModeManager::AddChannelMode(new ChannelMode("TOPIC", 't')); + ModeManager::AddChannelMode(new ChannelMode("REGMODERATED", 'M')); ModeManager::AddChannelMode(new ChannelModeOper('O')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_REGISTEREDONLY, 'R')); + ModeManager::AddChannelMode(new ChannelMode("REGISTEREDONLY", 'R')); } public: @@ -577,7 +573,7 @@ class ProtoBahamut : public Module void OnUserNickChange(User *u, const Anope::string &) anope_override { - u->RemoveModeInternal(ModeManager::FindUserModeByName(UMODE_REGISTERED)); + u->RemoveModeInternal(ModeManager::FindUserModeByName("REGISTERED")); IRCD->SendLogout(u); } }; diff --git a/modules/protocol/hybrid.cpp b/modules/protocol/hybrid.cpp index 331db994f..a1e9a89e7 100644 --- a/modules/protocol/hybrid.cpp +++ b/modules/protocol/hybrid.cpp @@ -1,6 +1,6 @@ /* ircd-hybrid-8 protocol module * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * (C) 2012 by the Hybrid Development Team * * Please read COPYING and README for further details. @@ -100,10 +100,10 @@ class HybridProto : public IRCDProto /* And update our internal status for this user since this is not going through our mode handling system */ if (status != NULL) { - UserContainer *uc = c->FindUser(user); + ChanUserContainer *uc = c->FindUser(user); if (uc != NULL) - *uc->status = *status; + uc->status = *status; } } @@ -232,7 +232,7 @@ class HybridProto : public IRCDProto { ChannelStatus status; - status.SetFlag(CMODE_OP); + status.modes.insert("OP"); bi->Join(c, &status); } @@ -255,9 +255,9 @@ struct IRCDMessageBMask : IRCDMessage if (c) { - ChannelMode *ban = ModeManager::FindChannelModeByName(CMODE_BAN), - *except = ModeManager::FindChannelModeByName(CMODE_EXCEPT), - *invex = ModeManager::FindChannelModeByName(CMODE_INVITEOVERRIDE); + ChannelMode *ban = ModeManager::FindChannelModeByName("BAN"), + *except = ModeManager::FindChannelModeByName("EXCEPT"), + *invex = ModeManager::FindChannelModeByName("INVITEOVERRIDE"); spacesepstream bans(params[3]); Anope::string token; @@ -401,7 +401,7 @@ struct IRCDMessageSJoin : IRCDMessage continue; } - sju.first.SetFlag(cm->name); + sju.first.modes.insert(cm->name); } sju.second = User::Find(buf); @@ -485,7 +485,9 @@ struct IRCDMessageTMode : IRCDMessage struct IRCDMessageUID : IRCDMessage { - IRCDMessageUID(Module *creator) : IRCDMessage(creator, "UID", 10) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); } + ServiceReference<NickServService> NSService; + + IRCDMessageUID(Module *creator) : IRCDMessage(creator, "UID", 10), NSService("NickServService", "NickServ") { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); } /* 0 1 2 3 4 5 6 7 8 9 */ /* :0MC UID Steve 1 1350157102 +oi ~steve resolved.host 10.0.0.1 0MCAAAAAB 1350157108 :Mining all the time */ @@ -502,22 +504,11 @@ struct IRCDMessageUID : IRCDMessage params[9], params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : 0, params[3], params[7]); - if (user && NickServService) + if (NSService && params[8] != "0") { - const NickAlias *na = NULL; - - if (params[8] != "0") - na = NickAlias::Find(params[8]); - - if (na) - { - user->Login(na->nc); - - if (!Config->NoNicknameOwnership && na->nc->HasFlag(NI_UNCONFIRMED) == false) - user->SetMode(NickServ, UMODE_REGISTERED); - } - else - NickServService->Validate(user); + NickAlias *na = NickAlias::Find(params[8]); + if (na != NULL) + NSService->Login(user, na); } } }; @@ -563,40 +554,40 @@ class ProtoHybrid : public Module void AddModes() { /* Add user modes */ - ModeManager::AddUserMode(new UserMode(UMODE_ADMIN, 'a')); - ModeManager::AddUserMode(new UserMode(UMODE_INVIS, 'i')); - ModeManager::AddUserMode(new UserMode(UMODE_OPER, 'o')); - ModeManager::AddUserMode(new UserMode(UMODE_REGISTERED, 'r')); - ModeManager::AddUserMode(new UserMode(UMODE_SNOMASK, 's')); - ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, 'w')); - ModeManager::AddUserMode(new UserMode(UMODE_HIDEOPER, 'H')); - ModeManager::AddUserMode(new UserMode(UMODE_REGPRIV, 'R')); + ModeManager::AddUserMode(new UserMode("ADMIN", 'a')); + ModeManager::AddUserMode(new UserMode("INVIS", 'i')); + ModeManager::AddUserMode(new UserMode("OPER", 'o')); + ModeManager::AddUserMode(new UserMode("REGISTERED", 'r')); + ModeManager::AddUserMode(new UserMode("SNOMASK", 's')); + ModeManager::AddUserMode(new UserMode("WALLOPS", 'w')); + ModeManager::AddUserMode(new UserMode("HIDEOPER", 'H')); + ModeManager::AddUserMode(new UserMode("REGPRIV", 'R')); /* b/e/I */ - ModeManager::AddChannelMode(new ChannelModeList(CMODE_BAN, 'b')); - ModeManager::AddChannelMode(new ChannelModeList(CMODE_EXCEPT, 'e')); - ModeManager::AddChannelMode(new ChannelModeList(CMODE_INVITEOVERRIDE, 'I')); + ModeManager::AddChannelMode(new ChannelModeList("BAN", 'b')); + ModeManager::AddChannelMode(new ChannelModeList("EXCEPT", 'e')); + ModeManager::AddChannelMode(new ChannelModeList("INVITEOVERRIDE", 'I')); /* v/h/o/a/q */ - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', '+', 0)); - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_HALFOP, 'h', '%', 1)); - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', '@', 2)); + ModeManager::AddChannelMode(new ChannelModeStatus("VOICE", 'v', '+', 0)); + ModeManager::AddChannelMode(new ChannelModeStatus("HALFOP", 'h', '%', 1)); + ModeManager::AddChannelMode(new ChannelModeStatus("OP", 'o', '@', 2)); /* l/k */ - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, 'l')); + ModeManager::AddChannelMode(new ChannelModeParam("LIMIT", 'l')); ModeManager::AddChannelMode(new ChannelModeKey('k')); /* Add channel modes */ - ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, 'i')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, 'm')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, 'n')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_PRIVATE, 'p')); + ModeManager::AddChannelMode(new ChannelMode("INVITE", 'i')); + ModeManager::AddChannelMode(new ChannelMode("MODERATED", 'm')); + ModeManager::AddChannelMode(new ChannelMode("NOEXTERNAL", 'n')); + ModeManager::AddChannelMode(new ChannelMode("PRIVATE", 'p')); ModeManager::AddChannelMode(new ChannelModeRegistered('r')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, 's')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, 't')); + ModeManager::AddChannelMode(new ChannelMode("SECRET", 's')); + ModeManager::AddChannelMode(new ChannelMode("TOPIC", 't')); ModeManager::AddChannelMode(new ChannelModeOper('O')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_REGISTEREDONLY, 'R')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_SSL, 'S')); + ModeManager::AddChannelMode(new ChannelMode("REGISTEREDONLY", 'R')); + ModeManager::AddChannelMode(new ChannelMode("SSL", 'S')); } public: @@ -629,7 +620,7 @@ public: void OnUserNickChange(User *u, const Anope::string &) anope_override { - u->RemoveModeInternal(ModeManager::FindUserModeByName(UMODE_REGISTERED)); + u->RemoveModeInternal(ModeManager::FindUserModeByName("REGISTERED")); } }; diff --git a/modules/protocol/inspircd11.cpp b/modules/protocol/inspircd11.cpp index 23bd5bca8..6ff0211d4 100644 --- a/modules/protocol/inspircd11.cpp +++ b/modules/protocol/inspircd11.cpp @@ -1,6 +1,6 @@ /* inspircd 1.1 beta 6+ functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -101,7 +101,7 @@ class InspIRCdProto : public IRCDProto void SendVhostDel(User *u) anope_override { - if (u->HasMode(UMODE_CLOAK)) + if (u->HasMode("CLOAK")) inspircd_cmd_chghost(u->nick, u->chost); else inspircd_cmd_chghost(u->nick, u->host); @@ -213,13 +213,13 @@ class InspIRCdProto : public IRCDProto /* If the user is internally on the channel with flags, kill them so that * the stacker will allow this. */ - UserContainer *uc = c->FindUser(user); + ChanUserContainer *uc = c->FindUser(user); if (uc != NULL) - uc->status->ClearFlags(); + uc->status.modes.clear(); BotInfo *setter = BotInfo::Find(user->nick); for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i) - if (cs.HasFlag(ModeManager::ChannelModes[i]->name)) + if (cs.modes.count(ModeManager::ChannelModes[i]->name)) c->SetMode(setter, ModeManager::ChannelModes[i], user->GetUID(), false); } } @@ -327,7 +327,7 @@ class InspIRCdProto : public IRCDProto class ChannelModeFlood : public ChannelModeParam { public: - ChannelModeFlood(char modeChar, bool minusNoArg) : ChannelModeParam(CMODE_FLOOD, modeChar, minusNoArg) { } + ChannelModeFlood(char modeChar, bool minusNoArg) : ChannelModeParam("FLOOD", modeChar, minusNoArg) { } bool IsValid(const Anope::string &value) const anope_override { @@ -392,16 +392,16 @@ struct IRCDMessageCapab : Message::Capab switch (modebuf[t]) { case 'b': - ModeManager::AddChannelMode(new ChannelModeList(CMODE_BAN, 'b')); + ModeManager::AddChannelMode(new ChannelModeList("BAN", 'b')); continue; case 'e': - ModeManager::AddChannelMode(new ChannelModeList(CMODE_EXCEPT, 'e')); + ModeManager::AddChannelMode(new ChannelModeList("EXCEPT", 'e')); continue; case 'I': - ModeManager::AddChannelMode(new ChannelModeList(CMODE_INVITEOVERRIDE, 'I')); + ModeManager::AddChannelMode(new ChannelModeList("INVITEOVERRIDE", 'I')); continue; default: - ModeManager::AddChannelMode(new ChannelModeList(CMODE_END, modebuf[t])); + ModeManager::AddChannelMode(new ChannelModeList("END", modebuf[t])); } } @@ -414,7 +414,7 @@ struct IRCDMessageCapab : Message::Capab ModeManager::AddChannelMode(new ChannelModeKey('k')); continue; default: - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, modebuf[t])); + ModeManager::AddChannelMode(new ChannelModeParam("END", modebuf[t])); } } @@ -427,13 +427,13 @@ struct IRCDMessageCapab : Message::Capab ModeManager::AddChannelMode(new ChannelModeFlood('f', false)); continue; case 'l': - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, 'l', true)); + ModeManager::AddChannelMode(new ChannelModeParam("LIMIT", 'l', true)); continue; case 'L': - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_REDIRECT, 'L', true)); + ModeManager::AddChannelMode(new ChannelModeParam("REDIRECT", 'L', true)); continue; default: - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, modebuf[t], true)); + ModeManager::AddChannelMode(new ChannelModeParam("END", modebuf[t], true)); } } @@ -443,67 +443,67 @@ struct IRCDMessageCapab : Message::Capab switch (modebuf[t]) { case 'i': - ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, 'i')); + ModeManager::AddChannelMode(new ChannelMode("INVITE", 'i')); continue; case 'm': - ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, 'm')); + ModeManager::AddChannelMode(new ChannelMode("MODERATED", 'm')); continue; case 'n': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, 'n')); + ModeManager::AddChannelMode(new ChannelMode("NOEXTERNAL", 'n')); continue; case 'p': - ModeManager::AddChannelMode(new ChannelMode(CMODE_PRIVATE, 'p')); + ModeManager::AddChannelMode(new ChannelMode("PRIVATE", 'p')); continue; case 's': - ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, 's')); + ModeManager::AddChannelMode(new ChannelMode("SECRET", 's')); continue; case 't': - ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, 't')); + ModeManager::AddChannelMode(new ChannelMode("TOPIC", 't')); continue; case 'r': ModeManager::AddChannelMode(new ChannelModeRegistered('r')); continue; case 'c': - ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCOLOR, 'c')); + ModeManager::AddChannelMode(new ChannelMode("BLOCKCOLOR", 'c')); continue; case 'u': - ModeManager::AddChannelMode(new ChannelMode(CMODE_AUDITORIUM, 'u')); + ModeManager::AddChannelMode(new ChannelMode("AUDITORIUM", 'u')); continue; case 'z': - ModeManager::AddChannelMode(new ChannelMode(CMODE_SSL, 'z')); + ModeManager::AddChannelMode(new ChannelMode("SSL", 'z')); continue; case 'A': - ModeManager::AddChannelMode(new ChannelMode(CMODE_ALLINVITE, 'A')); + ModeManager::AddChannelMode(new ChannelMode("ALLINVITE", 'A')); continue; case 'C': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOCTCP, 'C')); + ModeManager::AddChannelMode(new ChannelMode("NOCTCP", 'C')); continue; case 'G': - ModeManager::AddChannelMode(new ChannelMode(CMODE_FILTER, 'G')); + ModeManager::AddChannelMode(new ChannelMode("FILTER", 'G')); continue; case 'K': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKNOCK, 'K')); + ModeManager::AddChannelMode(new ChannelMode("NOKNOCK", 'K')); continue; case 'N': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NONICK, 'N')); + ModeManager::AddChannelMode(new ChannelMode("NONICK", 'N')); continue; case 'O': ModeManager::AddChannelMode(new ChannelModeOper('O')); continue; case 'Q': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKICK, 'Q')); + ModeManager::AddChannelMode(new ChannelMode("NOKICK", 'Q')); continue; case 'R': - ModeManager::AddChannelMode(new ChannelMode(CMODE_REGISTEREDONLY, 'R')); + ModeManager::AddChannelMode(new ChannelMode("REGISTEREDONLY", 'R')); continue; case 'S': - ModeManager::AddChannelMode(new ChannelMode(CMODE_STRIPCOLOR, 'S')); + ModeManager::AddChannelMode(new ChannelMode("STRIPCOLOR", 'S')); continue; case 'V': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOINVITE, 'V')); + ModeManager::AddChannelMode(new ChannelMode("NOINVITE", 'V')); continue; default: - ModeManager::AddChannelMode(new ChannelMode(CMODE_END, modebuf[t])); + ModeManager::AddChannelMode(new ChannelMode("END", modebuf[t])); } } } @@ -518,22 +518,22 @@ struct IRCDMessageCapab : Message::Capab switch (modes[t]) { case 'q': - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, 'q', '~', level--)); + ModeManager::AddChannelMode(new ChannelModeStatus("OWNER", 'q', '~', level--)); continue; case 'a': - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT, 'a', '&', level--)); + ModeManager::AddChannelMode(new ChannelModeStatus("PROTECT", 'a', '&', level--)); continue; case 'o': - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', '@', level--)); + ModeManager::AddChannelMode(new ChannelModeStatus("OP", 'o', '@', level--)); continue; case 'h': - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_HALFOP, 'h', '%', level--)); + ModeManager::AddChannelMode(new ChannelModeStatus("HALFOP", 'h', '%', level--)); continue; case 'v': - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', '+', level--)); + ModeManager::AddChannelMode(new ChannelModeStatus("VOICE", 'v', '+', level--)); continue; default: - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_END, modes[t], chars[t], level--)); + ModeManager::AddChannelMode(new ChannelModeStatus("END", modes[t], chars[t], level--)); } } } @@ -653,7 +653,7 @@ struct IRCDMessageFJoin : IRCDMessage continue; } - sju.first.SetFlag(cm->name); + sju.first.modes.insert(cm->name); } /* Erase the , */ buf.erase(buf.begin()); @@ -752,7 +752,9 @@ struct IRCDMessageMode : IRCDMessage struct IRCDMessageNick : IRCDMessage { - IRCDMessageNick(Module *creator) : IRCDMessage(creator, "NICK", 1) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); } + ServiceReference<NickServService> NSService; + + IRCDMessageNick(Module *creator) : IRCDMessage(creator, "NICK", 1), NSService("NickServService", "NickServ") { SetFlag(IRCDMESSAGE_SOFT_LIMIT); } void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override { @@ -761,19 +763,12 @@ struct IRCDMessageNick : IRCDMessage time_t ts = Anope::string(params[0]).is_pos_number_only() ? convertTo<time_t>(params[0]) : Anope::CurTime; User *user = new User(params[1], params[4], params[2], params[3], params[6], source.GetServer(), params[7], ts, params[5]); - if (NickServService) + if (NSService) { NickAlias *na = NickAlias::Find(user->nick); Anope::string *svidbuf = na ? na->nc->GetExt<ExtensibleItemClass<Anope::string> *>("authenticationtoken") : NULL; if (na && svidbuf && *svidbuf == params[0]) - { - NickCore *nc = na->nc; - user->Login(nc); - if (!Config->NoNicknameOwnership && na->nc->HasFlag(NI_UNCONFIRMED) == false) - user->SetMode(NickServ, UMODE_REGISTERED); - } - else - NickServService->Validate(user); + NSService->Login(user, na); } } else if (params.size() == 1 && source.GetUser()) @@ -790,7 +785,7 @@ struct IRCDMessageOperType : IRCDMessage /* opertype is equivalent to mode +o because servers dont do this directly */ User *u = source.GetUser(); - if (!u->HasMode(UMODE_OPER)) + if (!u->HasMode("OPER")) u->SetModesInternal("+o"); } }; @@ -865,13 +860,13 @@ class ProtoInspIRCd : public Module void AddModes() { - ModeManager::AddUserMode(new UserMode(UMODE_CALLERID, 'g')); - ModeManager::AddUserMode(new UserMode(UMODE_HELPOP, 'h')); - ModeManager::AddUserMode(new UserMode(UMODE_INVIS, 'i')); - ModeManager::AddUserMode(new UserMode(UMODE_OPER, 'o')); - ModeManager::AddUserMode(new UserMode(UMODE_REGISTERED, 'r')); - ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, 'w')); - ModeManager::AddUserMode(new UserMode(UMODE_CLOAK, 'x')); + ModeManager::AddUserMode(new UserMode("CALLERID", 'g')); + ModeManager::AddUserMode(new UserMode("HELPOP", 'h')); + ModeManager::AddUserMode(new UserMode("INVIS", 'i')); + ModeManager::AddUserMode(new UserMode("OPER", 'o')); + ModeManager::AddUserMode(new UserMode("REGISTERED", 'r')); + ModeManager::AddUserMode(new UserMode("WALLOPS", 'w')); + ModeManager::AddUserMode(new UserMode("CLOAK", 'x')); } public: @@ -898,7 +893,7 @@ class ProtoInspIRCd : public Module void OnUserNickChange(User *u, const Anope::string &) anope_override { - u->RemoveModeInternal(ModeManager::FindUserModeByName(UMODE_REGISTERED)); + u->RemoveModeInternal(ModeManager::FindUserModeByName("REGISTERED")); } }; diff --git a/modules/protocol/inspircd12.cpp b/modules/protocol/inspircd12.cpp index 26f509781..f42b97696 100644 --- a/modules/protocol/inspircd12.cpp +++ b/modules/protocol/inspircd12.cpp @@ -1,6 +1,6 @@ /* inspircd 1.2 functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -16,7 +16,7 @@ class ChannelModeFlood : public ChannelModeParam { public: - ChannelModeFlood(char modeChar, bool minusNoArg) : ChannelModeParam(CMODE_FLOOD, modeChar, minusNoArg) { } + ChannelModeFlood(char modeChar, bool minusNoArg) : ChannelModeParam("FLOOD", modeChar, minusNoArg) { } bool IsValid(const Anope::string &value) const anope_override { @@ -35,6 +35,12 @@ class ChannelModeFlood : public ChannelModeParam class InspIRCd12Proto : public IRCDProto { private: + void SendSVSKillInternal(const BotInfo *source, User *user, const Anope::string &buf) anope_override + { + IRCDProto::SendSVSKillInternal(source, user, buf); + user->KillInternal(source ? source->nick : Me->GetName(), buf); + } + void SendChgIdentInternal(const Anope::string &nick, const Anope::string &vIdent) { if (!Servers::Capab.count("CHGIDENT")) @@ -124,7 +130,7 @@ class InspIRCd12Proto : public IRCDProto void SendVhostDel(User *u) anope_override { - if (u->HasMode(UMODE_CLOAK)) + if (u->HasMode("CLOAK")) this->SendChgHostInternal(u->nick, u->chost); else this->SendChgHostInternal(u->nick, u->host); @@ -229,14 +235,21 @@ class InspIRCd12Proto : public IRCDProto /* If the user is internally on the channel with flags, kill them so that * the stacker will allow this. */ - UserContainer *uc = c->FindUser(user); + ChanUserContainer *uc = c->FindUser(user); if (uc != NULL) - uc->status->ClearFlags(); + uc->status.modes.clear(); BotInfo *setter = BotInfo::Find(user->nick); for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i) - if (cs.HasFlag(ModeManager::ChannelModes[i]->name)) + { + ChannelMode *cm = ModeManager::ChannelModes[i]; + + if (cs.modes.count(cm->name) || cs.modes.count(cm->mchar)) + { c->SetMode(setter, ModeManager::ChannelModes[i], user->GetUID(), false); + cs.modes.insert(cm->name); + } + } } } @@ -342,7 +355,7 @@ class InspIRCd12Proto : public IRCDProto void SendLogin(User *u) anope_override { - if (!u->Account() || u->Account()->HasFlag(NI_UNCONFIRMED)) + if (!u->Account() || u->Account()->HasExt("UNCONFIRMED")) return; UplinkSocket::Message(Me) << "METADATA " << u->GetUID() << " accountname :" << u->Account()->display; @@ -366,7 +379,7 @@ class InspIRCd12Proto : public IRCDProto class InspIRCdExtBan : public ChannelModeList { public: - InspIRCdExtBan(ChannelModeName mName, char modeChar) : ChannelModeList(mName, modeChar) { } + InspIRCdExtBan(const Anope::string &mname, char modeChar) : ChannelModeList(mname, modeChar) { } bool Matches(const User *u, const Entry *e) anope_override { @@ -440,7 +453,7 @@ struct IRCDMessageCapab : Message::Capab if (params[1].find("m_chgident.so") != Anope::string::npos) Servers::Capab.insert("CHGIDENT"); if (params[1].find("m_hidechans.so") != Anope::string::npos) - Servers::Capab.insert("HIDECHANELS"); + Servers::Capab.insert("HIDECHANS"); if (params[1].find("m_servprotect.so") != Anope::string::npos) IRCD->DefaultPseudoclientModes = "+Ik"; if (params[1].find("m_rline.so") != Anope::string::npos) @@ -464,23 +477,23 @@ struct IRCDMessageCapab : Message::Capab switch (modebuf[t]) { case 'b': - ModeManager::AddChannelMode(new InspIRCdExtBan(CMODE_BAN, 'b')); + ModeManager::AddChannelMode(new InspIRCdExtBan("BAN", 'b')); continue; case 'e': - ModeManager::AddChannelMode(new InspIRCdExtBan(CMODE_EXCEPT, 'e')); + ModeManager::AddChannelMode(new InspIRCdExtBan("EXCEPT", 'e')); continue; case 'I': - ModeManager::AddChannelMode(new InspIRCdExtBan(CMODE_INVITEOVERRIDE, 'I')); + ModeManager::AddChannelMode(new InspIRCdExtBan("INVITEOVERRIDE", 'I')); continue; /* InspIRCd sends q and a here if they have no prefixes */ case 'q': - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, 'q', '@')); + ModeManager::AddChannelMode(new ChannelModeStatus("OWNER", 'q', '@')); continue; case 'a': - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT , 'a', '@')); + ModeManager::AddChannelMode(new ChannelModeStatus("PROTECT" , 'a', '@')); continue; default: - ModeManager::AddChannelMode(new ChannelModeList(CMODE_END, modebuf[t])); + ModeManager::AddChannelMode(new ChannelModeList("END", modebuf[t])); } } @@ -493,7 +506,7 @@ struct IRCDMessageCapab : Message::Capab ModeManager::AddChannelMode(new ChannelModeKey('k')); continue; default: - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, modebuf[t])); + ModeManager::AddChannelMode(new ChannelModeParam("END", modebuf[t])); } } @@ -503,25 +516,25 @@ struct IRCDMessageCapab : Message::Capab switch (modebuf[t]) { case 'F': - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_NICKFLOOD, 'F', true)); + ModeManager::AddChannelMode(new ChannelModeParam("NICKFLOOD", 'F', true)); continue; case 'J': - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_NOREJOIN, 'J', true)); + ModeManager::AddChannelMode(new ChannelModeParam("NOREJOIN", 'J', true)); continue; case 'L': - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_REDIRECT, 'L', true)); + ModeManager::AddChannelMode(new ChannelModeParam("REDIRECT", 'L', true)); continue; case 'f': ModeManager::AddChannelMode(new ChannelModeFlood('f', true)); continue; case 'j': - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_JOINFLOOD, 'j', true)); + ModeManager::AddChannelMode(new ChannelModeParam("JOINFLOOD", 'j', true)); continue; case 'l': - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, 'l', true)); + ModeManager::AddChannelMode(new ChannelModeParam("LIMIT", 'l', true)); continue; default: - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, modebuf[t], true)); + ModeManager::AddChannelMode(new ChannelModeParam("END", modebuf[t], true)); } } @@ -531,79 +544,79 @@ struct IRCDMessageCapab : Message::Capab switch (modebuf[t]) { case 'A': - ModeManager::AddChannelMode(new ChannelMode(CMODE_ALLINVITE, 'A')); + ModeManager::AddChannelMode(new ChannelMode("ALLINVITE", 'A')); continue; case 'B': - ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCAPS, 'B')); + ModeManager::AddChannelMode(new ChannelMode("BLOCKCAPS", 'B')); continue; case 'C': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOCTCP, 'C')); + ModeManager::AddChannelMode(new ChannelMode("NOCTCP", 'C')); continue; case 'D': - ModeManager::AddChannelMode(new ChannelMode(CMODE_DELAYEDJOIN, 'D')); + ModeManager::AddChannelMode(new ChannelMode("DELAYEDJOIN", 'D')); continue; case 'G': - ModeManager::AddChannelMode(new ChannelMode(CMODE_FILTER, 'G')); + ModeManager::AddChannelMode(new ChannelMode("FILTER", 'G')); continue; case 'K': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKNOCK, 'K')); + ModeManager::AddChannelMode(new ChannelMode("NOKNOCK", 'K')); continue; case 'M': - ModeManager::AddChannelMode(new ChannelMode(CMODE_REGMODERATED, 'M')); + ModeManager::AddChannelMode(new ChannelMode("REGMODERATED", 'M')); continue; case 'N': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NONICK, 'N')); + ModeManager::AddChannelMode(new ChannelMode("NONICK", 'N')); continue; case 'O': ModeManager::AddChannelMode(new ChannelModeOper('O')); continue; case 'P': - ModeManager::AddChannelMode(new ChannelMode(CMODE_PERM, 'P')); + ModeManager::AddChannelMode(new ChannelMode("PERM", 'P')); continue; case 'Q': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKICK, 'Q')); + ModeManager::AddChannelMode(new ChannelMode("NOKICK", 'Q')); continue; case 'R': - ModeManager::AddChannelMode(new ChannelMode(CMODE_REGISTEREDONLY, 'R')); + ModeManager::AddChannelMode(new ChannelMode("REGISTEREDONLY", 'R')); continue; case 'S': - ModeManager::AddChannelMode(new ChannelMode(CMODE_STRIPCOLOR, 'S')); + ModeManager::AddChannelMode(new ChannelMode("STRIPCOLOR", 'S')); continue; case 'T': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NONOTICE, 'T')); + ModeManager::AddChannelMode(new ChannelMode("NONOTICE", 'T')); continue; case 'c': - ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCOLOR, 'c')); + ModeManager::AddChannelMode(new ChannelMode("BLOCKCOLOR", 'c')); continue; case 'i': - ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, 'i')); + ModeManager::AddChannelMode(new ChannelMode("INVITE", 'i')); continue; case 'm': - ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, 'm')); + ModeManager::AddChannelMode(new ChannelMode("MODERATED", 'm')); continue; case 'n': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, 'n')); + ModeManager::AddChannelMode(new ChannelMode("NOEXTERNAL", 'n')); continue; case 'p': - ModeManager::AddChannelMode(new ChannelMode(CMODE_PRIVATE, 'p')); + ModeManager::AddChannelMode(new ChannelMode("PRIVATE", 'p')); continue; case 'r': ModeManager::AddChannelMode(new ChannelModeRegistered('r')); continue; case 's': - ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, 's')); + ModeManager::AddChannelMode(new ChannelMode("SECRET", 's')); continue; case 't': - ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, 't')); + ModeManager::AddChannelMode(new ChannelMode("TOPIC", 't')); continue; case 'u': - ModeManager::AddChannelMode(new ChannelMode(CMODE_AUDITORIUM, 'u')); + ModeManager::AddChannelMode(new ChannelMode("AUDITORIUM", 'u')); continue; case 'z': - ModeManager::AddChannelMode(new ChannelMode(CMODE_SSL, 'z')); + ModeManager::AddChannelMode(new ChannelMode("SSL", 'z')); continue; default: - ModeManager::AddChannelMode(new ChannelMode(CMODE_END, modebuf[t])); + ModeManager::AddChannelMode(new ChannelMode("END", modebuf[t])); } } } @@ -620,61 +633,61 @@ struct IRCDMessageCapab : Message::Capab switch (modebuf[t]) { case 'h': - ModeManager::AddUserMode(new UserMode(UMODE_HELPOP, 'h')); + ModeManager::AddUserMode(new UserMode("HELPOP", 'h')); continue; case 'B': - ModeManager::AddUserMode(new UserMode(UMODE_BOT, 'B')); + ModeManager::AddUserMode(new UserMode("BOT", 'B')); continue; case 'G': - ModeManager::AddUserMode(new UserMode(UMODE_FILTER, 'G')); + ModeManager::AddUserMode(new UserMode("FILTER", 'G')); continue; case 'H': - ModeManager::AddUserMode(new UserMode(UMODE_HIDEOPER, 'H')); + ModeManager::AddUserMode(new UserMode("HIDEOPER", 'H')); continue; case 'I': - ModeManager::AddUserMode(new UserMode(UMODE_PRIV, 'I')); + ModeManager::AddUserMode(new UserMode("PRIV", 'I')); continue; case 'Q': - ModeManager::AddUserMode(new UserMode(UMODE_HIDDEN, 'Q')); + ModeManager::AddUserMode(new UserMode("HIDDEN", 'Q')); continue; case 'R': - ModeManager::AddUserMode(new UserMode(UMODE_REGPRIV, 'R')); + ModeManager::AddUserMode(new UserMode("REGPRIV", 'R')); continue; case 'S': - ModeManager::AddUserMode(new UserMode(UMODE_STRIPCOLOR, 'S')); + ModeManager::AddUserMode(new UserMode("STRIPCOLOR", 'S')); continue; case 'W': - ModeManager::AddUserMode(new UserMode(UMODE_WHOIS, 'W')); + ModeManager::AddUserMode(new UserMode("WHOIS", 'W')); continue; case 'c': - ModeManager::AddUserMode(new UserMode(UMODE_COMMONCHANS, 'c')); + ModeManager::AddUserMode(new UserMode("COMMONCHANS", 'c')); continue; case 'g': - ModeManager::AddUserMode(new UserMode(UMODE_CALLERID, 'g')); + ModeManager::AddUserMode(new UserMode("CALLERID", 'g')); continue; case 'i': - ModeManager::AddUserMode(new UserMode(UMODE_INVIS, 'i')); + ModeManager::AddUserMode(new UserMode("INVIS", 'i')); continue; case 'k': - ModeManager::AddUserMode(new UserMode(UMODE_PROTECTED, 'k')); + ModeManager::AddUserMode(new UserMode("PROTECTED", 'k')); continue; case 'o': - ModeManager::AddUserMode(new UserMode(UMODE_OPER, 'o')); + ModeManager::AddUserMode(new UserMode("OPER", 'o')); continue; case 'r': - ModeManager::AddUserMode(new UserMode(UMODE_REGISTERED, 'r')); + ModeManager::AddUserMode(new UserMode("REGISTERED", 'r')); continue; case 'w': - ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, 'w')); + ModeManager::AddUserMode(new UserMode("WALLOPS", 'w')); continue; case 'x': - ModeManager::AddUserMode(new UserMode(UMODE_CLOAK, 'x')); + ModeManager::AddUserMode(new UserMode("CLOAK", 'x')); continue; case 'd': - ModeManager::AddUserMode(new UserMode(UMODE_DEAF, 'd')); + ModeManager::AddUserMode(new UserMode("DEAF", 'd')); continue; default: - ModeManager::AddUserMode(new UserMode(UMODE_END, modebuf[t])); + ModeManager::AddUserMode(new UserMode("END", modebuf[t])); } } } @@ -690,22 +703,22 @@ struct IRCDMessageCapab : Message::Capab switch (modes[t]) { case 'q': - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, 'q', chars[t], level--)); + ModeManager::AddChannelMode(new ChannelModeStatus("OWNER", 'q', chars[t], level--)); continue; case 'a': - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT, 'a', chars[t], level--)); + ModeManager::AddChannelMode(new ChannelModeStatus("PROTECT", 'a', chars[t], level--)); continue; case 'o': - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', chars[t], level--)); + ModeManager::AddChannelMode(new ChannelModeStatus("OP", 'o', chars[t], level--)); continue; case 'h': - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_HALFOP, 'h', chars[t], level--)); + ModeManager::AddChannelMode(new ChannelModeStatus("HALFOP", 'h', chars[t], level--)); continue; case 'v': - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', chars[t], level--)); + ModeManager::AddChannelMode(new ChannelModeStatus("VOICE", 'v', chars[t], level--)); continue; default: - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_END, modes[t], chars[t], level--)); + ModeManager::AddChannelMode(new ChannelModeStatus("END", modes[t], chars[t], level--)); } } } @@ -831,7 +844,7 @@ struct IRCDMessageFJoin : IRCDMessage continue; } - sju.first.SetFlag(cm->name); + sju.first.modes.insert(cm->name); } /* Erase the , */ buf.erase(buf.begin()); @@ -847,7 +860,7 @@ struct IRCDMessageFJoin : IRCDMessage } time_t ts = Anope::string(params[1]).is_pos_number_only() ? convertTo<time_t>(params[1]) : Anope::CurTime; - Message::Join::SJoin(source, params[0], ts, "", users); + Message::Join::SJoin(source, params[0], ts, modes, users); } }; @@ -929,14 +942,14 @@ struct IRCDMessageMetadata : IRCDMessage u->Login(nc); const NickAlias *user_na = NickAlias::Find(u->nick); - if (!Config->NoNicknameOwnership && user_na && user_na->nc == nc && user_na->nc->HasFlag(NI_UNCONFIRMED) == false) - u->SetMode(NickServ, UMODE_REGISTERED); + if (!Config->NoNicknameOwnership && user_na && user_na->nc == nc && user_na->nc->HasExt("UNCONFIRMED") == false) + u->SetMode(NickServ, "REGISTERED"); /* Sometimes a user connects, we send them the usual "this nickname is registered" mess (if * their server isn't syncing) and then we receive this.. so tell them about it. */ if (u->server->IsSynced() && NickServ) - u->SendMessage(NickServ, _("You have been logged in as \2%s\2."), nc->display.c_str()); + u->SendMessage(NickServ, _("You have been logged in as \002%s\002."), nc->display.c_str()); } } @@ -1072,7 +1085,7 @@ struct IRCDMessageOperType : IRCDMessage /* opertype is equivalent to mode +o because servers dont do this directly */ User *u = source.GetUser(); - if (!u->HasMode(UMODE_OPER)) + if (!u->HasMode("OPER")) u->SetModesInternal("+o"); } }; @@ -1088,11 +1101,9 @@ struct IRCDMessageRSQuit : IRCDMessage return; /* On InspIRCd we must send a SQUIT when we recieve RSQUIT for a server we have juped */ - if (s->HasFlag(SERVER_JUPED)) + if (s->IsJuped()) UplinkSocket::Message(Me) << "SQUIT " << s->GetSID() << " :" << (params.size() > 1 ? params[1].c_str() : ""); - FOREACH_MOD(I_OnServerQuit, OnServerQuit(s)); - s->Delete(s->GetName() + " " + s->GetUplink()->GetName()); } }; @@ -1161,9 +1172,7 @@ struct IRCDMessageUID : IRCDMessage for (unsigned i = 9; i < params.size() - 1; ++i) modes += " " + params[i]; - User *u = new User(params[2], params[5], params[3], params[4], params[6], source.GetServer(), params[params.size() - 1], ts, modes, params[0]); - if (u->server->IsSynced() && NickServService) - NickServService->Validate(u); + new User(params[2], params[5], params[3], params[4], params[6], source.GetServer(), params[params.size() - 1], ts, modes, params[0]); } }; @@ -1221,7 +1230,7 @@ class ProtoInspIRCd : public Module { this->SetAuthor("Anope"); - Implementation i[] = { I_OnUserNickChange, I_OnServerSync }; + Implementation i[] = { I_OnUserNickChange }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); Servers::Capab.insert("NOQUIT"); @@ -1242,18 +1251,7 @@ 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); - } - - void OnServerSync(Server *s) anope_override - { - if (NickServService) - for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it) - { - User *u = it->second; - if (u->server == s && !u->IsIdentified()) - NickServService->Validate(u); - } + u->RemoveMode(NickServ, "REGISTERED"); } }; diff --git a/modules/protocol/inspircd20.cpp b/modules/protocol/inspircd20.cpp index 62b77e6f7..dfbf75091 100644 --- a/modules/protocol/inspircd20.cpp +++ b/modules/protocol/inspircd20.cpp @@ -1,6 +1,6 @@ /* Inspircd 2.0 functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -43,6 +43,7 @@ class InspIRCd20Proto : public IRCDProto insp12->SendConnect(); } + void SendSVSKillInternal(const BotInfo *source, User *user, const Anope::string &buf) anope_override { insp12->SendSVSKillInternal(source, user, buf); } void SendGlobalNotice(const BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override { insp12->SendGlobalNotice(bi, dest, msg); } void SendGlobalPrivmsg(const BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override { insp12->SendGlobalPrivmsg(bi, dest, msg); } void SendAkillDel(const XLine *x) anope_override { insp12->SendAkillDel(x); } @@ -76,7 +77,7 @@ class InspIRCd20Proto : public IRCDProto class InspIRCdExtBan : public ChannelModeList { public: - InspIRCdExtBan(ChannelModeName mName, char modeChar) : ChannelModeList(mName, modeChar) { } + InspIRCdExtBan(const Anope::string &mname, char modeChar) : ChannelModeList(mname, modeChar) { } bool Matches(const User *u, const Entry *e) anope_override { @@ -107,9 +108,9 @@ class InspIRCdExtBan : public ChannelModeList Channel *c = Channel::Find(channel); if (c != NULL) { - UserContainer *uc = c->FindUser(u); + ChanUserContainer *uc = c->FindUser(u); if (uc != NULL) - if (cm == NULL || uc->status->HasFlag(cm->name)) + if (cm == NULL || uc->status.modes.count(cm->name)) return true; } } @@ -149,7 +150,7 @@ class InspIRCdExtBan : public ChannelModeList class ChannelModeFlood : public ChannelModeParam { public: - ChannelModeFlood(char modeChar, bool minusNoArg) : ChannelModeParam(CMODE_FLOOD, modeChar, minusNoArg) { } + ChannelModeFlood(char modeChar, bool minusNoArg) : ChannelModeParam("FLOOD", modeChar, minusNoArg) { } bool IsValid(const Anope::string &value) const anope_override { @@ -203,86 +204,88 @@ struct IRCDMessageCapab : Message::Capab ChannelMode *cm = NULL; if (modename.equals_cs("admin")) - cm = new ChannelModeStatus(CMODE_PROTECT, modechar.length() > 1 ? modechar[1] : modechar[0], modechar.length() > 1 ? modechar[0] : 0); + cm = new ChannelModeStatus("PROTECT", modechar.length() > 1 ? modechar[1] : modechar[0], modechar.length() > 1 ? modechar[0] : 0); else if (modename.equals_cs("allowinvite")) - cm = new ChannelMode(CMODE_ALLINVITE, modechar[0]); + cm = new ChannelMode("ALLINVITE", modechar[0]); else if (modename.equals_cs("auditorium")) - cm = new ChannelMode(CMODE_AUDITORIUM, modechar[0]); + cm = new ChannelMode("AUDITORIUM", modechar[0]); else if (modename.equals_cs("ban")) - cm = new InspIRCdExtBan(CMODE_BAN, modechar[0]); + cm = new InspIRCdExtBan("BAN", modechar[0]); else if (modename.equals_cs("banexception")) - cm = new InspIRCdExtBan(CMODE_EXCEPT, 'e'); + cm = new InspIRCdExtBan("EXCEPT", 'e'); else if (modename.equals_cs("blockcaps")) - cm = new ChannelMode(CMODE_BLOCKCAPS, modechar[0]); + cm = new ChannelMode("BLOCKCAPS", modechar[0]); else if (modename.equals_cs("blockcolor")) - cm = new ChannelMode(CMODE_BLOCKCOLOR, modechar[0]); + cm = new ChannelMode("BLOCKCOLOR", modechar[0]); else if (modename.equals_cs("c_registered")) cm = new ChannelModeRegistered(modechar[0]); else if (modename.equals_cs("censor")) - cm = new ChannelMode(CMODE_FILTER, modechar[0]); + cm = new ChannelMode("FILTER", modechar[0]); else if (modename.equals_cs("delayjoin")) - cm = new ChannelMode(CMODE_DELAYEDJOIN, modechar[0]); + cm = new ChannelMode("DELAYEDJOIN", modechar[0]); + else if (modename.equals_cs("filter")) + cm = new ChannelModeList("FILTER", modechar[0]); else if (modename.equals_cs("flood")) cm = new ChannelModeFlood(modechar[0], true); else if (modename.equals_cs("founder")) - cm = new ChannelModeStatus(CMODE_OWNER, modechar.length() > 1 ? modechar[1] : modechar[0], modechar.length() > 1 ? modechar[0] : 0); + cm = new ChannelModeStatus("OWNER", modechar.length() > 1 ? modechar[1] : modechar[0], modechar.length() > 1 ? modechar[0] : 0); else if (modename.equals_cs("halfop")) - cm = new ChannelModeStatus(CMODE_HALFOP, modechar.length() > 1 ? modechar[1] : modechar[0], modechar.length() > 1 ? modechar[0] : 0); + cm = new ChannelModeStatus("HALFOP", modechar.length() > 1 ? modechar[1] : modechar[0], modechar.length() > 1 ? modechar[0] : 0); else if (modename.equals_cs("invex")) - cm = new InspIRCdExtBan(CMODE_INVITEOVERRIDE, 'I'); + cm = new InspIRCdExtBan("INVITEOVERRIDE", 'I'); else if (modename.equals_cs("inviteonly")) - cm = new ChannelMode(CMODE_INVITE, modechar[0]); + cm = new ChannelMode("INVITE", modechar[0]); else if (modename.equals_cs("joinflood")) - cm = new ChannelModeParam(CMODE_JOINFLOOD, modechar[0], true); + cm = new ChannelModeParam("JOINFLOOD", modechar[0], true); else if (modename.equals_cs("key")) cm = new ChannelModeKey(modechar[0]); else if (modename.equals_cs("kicknorejoin")) - cm = new ChannelModeParam(CMODE_NOREJOIN, modechar[0], true); + cm = new ChannelModeParam("NOREJOIN", modechar[0], true); else if (modename.equals_cs("limit")) - cm = new ChannelModeParam(CMODE_LIMIT, modechar[0], true); + cm = new ChannelModeParam("LIMIT", modechar[0], true); else if (modename.equals_cs("moderated")) - cm = new ChannelMode(CMODE_MODERATED, modechar[0]); + cm = new ChannelMode("MODERATED", modechar[0]); else if (modename.equals_cs("nickflood")) - cm = new ChannelModeParam(CMODE_NICKFLOOD, modechar[0], true); + cm = new ChannelModeParam("NICKFLOOD", modechar[0], true); else if (modename.equals_cs("noctcp")) - cm = new ChannelMode(CMODE_NOCTCP, modechar[0]); + cm = new ChannelMode("NOCTCP", modechar[0]); else if (modename.equals_cs("noextmsg")) - cm = new ChannelMode(CMODE_NOEXTERNAL, modechar[0]); + cm = new ChannelMode("NOEXTERNAL", modechar[0]); else if (modename.equals_cs("nokick")) - cm = new ChannelMode(CMODE_NOKICK, modechar[0]); + cm = new ChannelMode("NOKICK", modechar[0]); else if (modename.equals_cs("noknock")) - cm = new ChannelMode(CMODE_NOKNOCK, modechar[0]); + cm = new ChannelMode("NOKNOCK", modechar[0]); else if (modename.equals_cs("nonick")) - cm = new ChannelMode(CMODE_NONICK, modechar[0]); + cm = new ChannelMode("NONICK", modechar[0]); else if (modename.equals_cs("nonotice")) - cm = new ChannelMode(CMODE_NONOTICE, modechar[0]); + cm = new ChannelMode("NONOTICE", modechar[0]); else if (modename.equals_cs("op")) - cm = new ChannelModeStatus(CMODE_OP, modechar.length() > 1 ? modechar[1] : modechar[0], modechar.length() > 1 ? modechar[0] : 0); + cm = new ChannelModeStatus("OP", modechar.length() > 1 ? modechar[1] : modechar[0], modechar.length() > 1 ? modechar[0] : 0); else if (modename.equals_cs("operonly")) cm = new ChannelModeOper(modechar[0]); else if (modename.equals_cs("permanent")) - cm = new ChannelMode(CMODE_PERM, modechar[0]); + cm = new ChannelMode("PERM", modechar[0]); else if (modename.equals_cs("private")) - cm = new ChannelMode(CMODE_PRIVATE, modechar[0]); + cm = new ChannelMode("PRIVATE", modechar[0]); else if (modename.equals_cs("redirect")) - cm = new ChannelModeParam(CMODE_REDIRECT, modechar[0], true); + cm = new ChannelModeParam("REDIRECT", modechar[0], true); else if (modename.equals_cs("reginvite")) - cm = new ChannelMode(CMODE_REGISTEREDONLY, modechar[0]); + cm = new ChannelMode("REGISTEREDONLY", modechar[0]); else if (modename.equals_cs("regmoderated")) - cm = new ChannelMode(CMODE_REGMODERATED, modechar[0]); + cm = new ChannelMode("REGMODERATED", modechar[0]); else if (modename.equals_cs("secret")) - cm = new ChannelMode(CMODE_SECRET, modechar[0]); + cm = new ChannelMode("SECRET", modechar[0]); else if (modename.equals_cs("sslonly")) - cm = new ChannelMode(CMODE_SSL, modechar[0]); + cm = new ChannelMode("SSL", modechar[0]); else if (modename.equals_cs("stripcolor")) - cm = new ChannelMode(CMODE_STRIPCOLOR, modechar[0]); + cm = new ChannelMode("STRIPCOLOR", modechar[0]); else if (modename.equals_cs("topiclock")) - cm = new ChannelMode(CMODE_TOPIC, modechar[0]); + cm = new ChannelMode("TOPIC", modechar[0]); else if (modename.equals_cs("voice")) - cm = new ChannelModeStatus(CMODE_VOICE, modechar.length() > 1 ? modechar[1] : modechar[0], modechar.length() > 1 ? modechar[0] : 0); + cm = new ChannelModeStatus("VOICE", modechar.length() > 1 ? modechar[1] : modechar[0], modechar.length() > 1 ? modechar[0] : 0); /* Unknown status mode, (customprefix) - add it */ else if (modechar.length() == 2) - cm = new ChannelModeStatus(CMODE_END, modechar[1], modechar[0]); + cm = new ChannelModeStatus("END", modechar[1], modechar[0]); /* else don't do anything here, we will get it in CAPAB CAPABILITIES */ if (cm) @@ -303,44 +306,44 @@ struct IRCDMessageCapab : Message::Capab UserMode *um = NULL; if (modename.equals_cs("bot")) - um = new UserMode(UMODE_BOT, modechar[0]); + um = new UserMode("BOT", modechar[0]); else if (modename.equals_cs("callerid")) - um = new UserMode(UMODE_CALLERID, modechar[0]); + um = new UserMode("CALLERID", modechar[0]); else if (modename.equals_cs("cloak")) - um = new UserMode(UMODE_CLOAK, modechar[0]); + um = new UserMode("CLOAK", modechar[0]); else if (modename.equals_cs("deaf")) - um = new UserMode(UMODE_DEAF, modechar[0]); + um = new UserMode("DEAF", modechar[0]); else if (modename.equals_cs("deaf_commonchan")) - um = new UserMode(UMODE_COMMONCHANS, modechar[0]); + um = new UserMode("COMMONCHANS", modechar[0]); else if (modename.equals_cs("helpop")) - um = new UserMode(UMODE_HELPOP, modechar[0]); + um = new UserMode("HELPOP", modechar[0]); else if (modename.equals_cs("hidechans")) - um = new UserMode(UMODE_PRIV, modechar[0]); + um = new UserMode("PRIV", modechar[0]); else if (modename.equals_cs("hideoper")) - um = new UserMode(UMODE_HIDEOPER, modechar[0]); + um = new UserMode("HIDEOPER", modechar[0]); else if (modename.equals_cs("invisible")) - um = new UserMode(UMODE_INVIS, modechar[0]); + um = new UserMode("INVIS", modechar[0]); else if (modename.equals_cs("invis-oper")) - um = new UserMode(UMODE_INVISIBLE_OPER, modechar[0]); + um = new UserMode("INVISIBLE_OPER", modechar[0]); else if (modename.equals_cs("oper")) - um = new UserMode(UMODE_OPER, modechar[0]); + um = new UserMode("OPER", modechar[0]); else if (modename.equals_cs("regdeaf")) - um = new UserMode(UMODE_REGPRIV, modechar[0]); + um = new UserMode("REGPRIV", modechar[0]); else if (modename.equals_cs("servprotect")) { - um = new UserMode(UMODE_PROTECTED, modechar[0]); + um = new UserMode("PROTECTED", modechar[0]); IRCD->DefaultPseudoclientModes += "k"; } else if (modename.equals_cs("showwhois")) - um = new UserMode(UMODE_WHOIS, modechar[0]); + um = new UserMode("WHOIS", modechar[0]); else if (modename.equals_cs("u_censor")) - um = new UserMode(UMODE_FILTER, modechar[0]); + um = new UserMode("FILTER", modechar[0]); else if (modename.equals_cs("u_registered")) - um = new UserMode(UMODE_REGISTERED, modechar[0]); + um = new UserMode("REGISTERED", modechar[0]); else if (modename.equals_cs("u_stripcolor")) - um = new UserMode(UMODE_STRIPCOLOR, modechar[0]); + um = new UserMode("STRIPCOLOR", modechar[0]); else if (modename.equals_cs("wallops")) - um = new UserMode(UMODE_WALLOPS, modechar[0]); + um = new UserMode("WALLOPS", modechar[0]); if (um) ModeManager::AddUserMode(um); @@ -399,7 +402,7 @@ struct IRCDMessageCapab : Message::Capab { if (ModeManager::FindChannelModeByChar(modebuf[t])) continue; - ModeManager::AddChannelMode(new ChannelModeList(CMODE_END, modebuf[t])); + ModeManager::AddChannelMode(new ChannelModeList("END", modebuf[t])); } sep.GetToken(modebuf); @@ -407,7 +410,7 @@ struct IRCDMessageCapab : Message::Capab { if (ModeManager::FindChannelModeByChar(modebuf[t])) continue; - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, modebuf[t])); + ModeManager::AddChannelMode(new ChannelModeParam("END", modebuf[t])); } sep.GetToken(modebuf); @@ -415,7 +418,7 @@ struct IRCDMessageCapab : Message::Capab { if (ModeManager::FindChannelModeByChar(modebuf[t])) continue; - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, true)); + ModeManager::AddChannelMode(new ChannelModeParam("END", true)); } sep.GetToken(modebuf); @@ -423,7 +426,7 @@ struct IRCDMessageCapab : Message::Capab { if (ModeManager::FindChannelModeByChar(modebuf[t])) continue; - ModeManager::AddChannelMode(new ChannelMode(CMODE_END, modebuf[t])); + ModeManager::AddChannelMode(new ChannelMode("END", modebuf[t])); } } else if (capab.find("USERMODES") != Anope::string::npos) @@ -437,11 +440,11 @@ struct IRCDMessageCapab : Message::Capab if (sep.GetToken(modebuf)) for (size_t t = 0, end = modebuf.length(); t < end; ++t) - ModeManager::AddUserMode(new UserModeParam(UMODE_END, modebuf[t])); + ModeManager::AddUserMode(new UserModeParam("END", modebuf[t])); if (sep.GetToken(modebuf)) for (size_t t = 0, end = modebuf.length(); t < end; ++t) - ModeManager::AddUserMode(new UserMode(UMODE_END, modebuf[t])); + ModeManager::AddUserMode(new UserMode("END", modebuf[t])); } else if (capab.find("MAXMODES=") != Anope::string::npos) { @@ -452,7 +455,7 @@ struct IRCDMessageCapab : Message::Capab { Anope::string modes(capab.begin() + 8, capab.begin() + capab.find(')')); Anope::string chars(capab.begin() + capab.find(')') + 1, capab.end()); - unsigned short level = modes.length() - 1; + short level = modes.length() - 1; for (size_t t = 0, end = modes.length(); t < end; ++t) { @@ -464,7 +467,7 @@ struct IRCDMessageCapab : Message::Capab } ChannelModeStatus *cms = anope_dynamic_static_cast<ChannelModeStatus *>(cm); - cms->Level = level--; + cms->level = level--; } } } @@ -478,7 +481,7 @@ struct IRCDMessageCapab : Message::Capab Anope::Quitting = true; return; } - if (!ModeManager::FindUserModeByName(UMODE_PRIV)) + if (!ModeManager::FindUserModeByName("PRIV")) { UplinkSocket::Message() << "ERROR :m_hidechans.so is not loaded. This is required by Anope"; Anope::QuitReason = "ERROR: Remote server does not have the m_hidechans module loaded, and this is required."; @@ -565,7 +568,12 @@ struct IRCDMessageEncap : IRCDMessage base64(account\0account\0pass) */ if (params[4] == "S") - UplinkSocket::Message(Me) << "ENCAP " << params[2].substr(0, 3) << " SASL " << Me->GetSID() << " " << params[2] << " C +"; + { + if (params[5] == "PLAIN") + UplinkSocket::Message(Me) << "ENCAP " << params[2].substr(0, 3) << " SASL " << Me->GetSID() << " " << params[2] << " C +"; + else + UplinkSocket::Message(Me) << "ENCAP " << params[2].substr(0, 3) << " SASL " << Me->GetSID() << " " << params[2] << " D F"; + } else if (params[4] == "C") { Anope::string decoded; @@ -652,7 +660,7 @@ class ProtoInspIRCd : public Module message_endburst("IRCDMessage", "inspircd20/endburst", "inspircd12/endburst"), message_fhost("IRCDMessage", "inspircd20/fhost", "inspircd12/fhost"), message_fjoin("IRCDMessage", "inspircd20/fjoin", "inspircd12/fjoin"), - message_fmode("IRCDMessage", "inspircd20/mode", "inspircd12/fmode"), + message_fmode("IRCDMessage", "inspircd20/fmode", "inspircd12/fmode"), message_ftopic("IRCDMessage", "inspircd20/ftopic", "inspircd12/ftopic"), message_idle("IRCDMessage", "inspircd20/idle", "inspircd12/idle"), message_metadata("IRCDMessage", "inspircd20/metadata", "inspircd12/metadata"), @@ -688,7 +696,7 @@ class ProtoInspIRCd : public Module void OnUserNickChange(User *u, const Anope::string &) anope_override { - u->RemoveModeInternal(ModeManager::FindUserModeByName(UMODE_REGISTERED)); + u->RemoveModeInternal(ModeManager::FindUserModeByName("REGISTERED")); } void OnServerSync(Server *s) anope_override @@ -712,7 +720,7 @@ class ProtoInspIRCd : public Module if (Config->UseServerSideTopicLock && Servers::Capab.count("TOPICLOCK") && ci->c) { - Anope::string on = ci->HasFlag(CI_TOPICLOCK) ? "1" : ""; + Anope::string on = ci->HasExt("TOPICLOCK") ? "1" : ""; SendChannelMetadata(ci->c, "topiclock", on); } } diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp index b5bf87b12..e54a4f8f7 100644 --- a/modules/protocol/ngircd.cpp +++ b/modules/protocol/ngircd.cpp @@ -93,13 +93,13 @@ class ngIRCdProto : public IRCDProto /* If the user is internally on the channel with flags, kill them so that * the stacker will allow this. */ - UserContainer *uc = c->FindUser(user); + ChanUserContainer *uc = c->FindUser(user); if (uc != NULL) - uc->status->ClearFlags(); + uc->status.modes.clear(); BotInfo *setter = BotInfo::Find(user->nick); for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i) - if (cs.HasFlag(ModeManager::ChannelModes[i]->name)) + if (cs.modes.count(ModeManager::ChannelModes[i]->name)) c->SetMode(setter, ModeManager::ChannelModes[i], user->GetUID(), false); } } @@ -157,9 +157,9 @@ class ngIRCdProto : public IRCDProto UplinkSocket::Message(Me) << "METADATA " << u->nick << " user :" << vIdent; UplinkSocket::Message(Me) << "METADATA " << u->nick << " cloakhost :" << vhost; - if (!u->HasMode(UMODE_CLOAK)) + if (!u->HasMode("CLOAK")) { - u->SetMode(HostServ, UMODE_CLOAK); + u->SetMode(HostServ, "CLOAK"); ModeManager::ProcessModes(); } } @@ -432,9 +432,7 @@ struct IRCDMessageNick : IRCDMessage else if (params.size() == 7) { // a new user is connecting to the network - User *user = new User(params[0], params[2], params[3], "", "", source.GetServer(), params[6], Anope::CurTime, params[5], ""); - if (user && NickServService) - NickServService->Validate(user); + new User(params[0], params[2], params[3], "", "", source.GetServer(), params[6], Anope::CurTime, params[5], ""); } else { @@ -480,7 +478,7 @@ struct IRCDMessageNJoin : IRCDMessage continue; } - sju.first.SetFlag(cm->name); + sju.first.modes.insert(cm->name); } sju.second = User::Find(buf); @@ -489,6 +487,7 @@ struct IRCDMessageNJoin : IRCDMessage Log(LOG_DEBUG) << "NJOIN for nonexistant user " << buf << " on " << params[0]; continue; } + users.push_back(sju); } Message::Join::SJoin(source, params[0], 0, "", users); @@ -617,46 +616,46 @@ class ProtongIRCd : public Module void AddModes() { /* Add user modes */ - ModeManager::AddUserMode(new UserMode(UMODE_NOCTCP, 'b')); - ModeManager::AddUserMode(new UserMode(UMODE_BOT, 'B')); - ModeManager::AddUserMode(new UserMode(UMODE_COMMONCHANS, 'C')); - ModeManager::AddUserMode(new UserMode(UMODE_INVIS, 'i')); - ModeManager::AddUserMode(new UserMode(UMODE_OPER, 'o')); - ModeManager::AddUserMode(new UserMode(UMODE_PROTECTED, 'q')); - ModeManager::AddUserMode(new UserMode(UMODE_RESTRICTED, 'r')); - ModeManager::AddUserMode(new UserMode(UMODE_REGISTERED, 'R')); - ModeManager::AddUserMode(new UserMode(UMODE_SNOMASK, 's')); - ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, 'w')); - ModeManager::AddUserMode(new UserMode(UMODE_CLOAK, 'x')); + ModeManager::AddUserMode(new UserMode("NOCTCP", 'b')); + ModeManager::AddUserMode(new UserMode("BOT", 'B')); + ModeManager::AddUserMode(new UserMode("COMMONCHANS", 'C')); + ModeManager::AddUserMode(new UserMode("INVIS", 'i')); + ModeManager::AddUserMode(new UserMode("OPER", 'o')); + ModeManager::AddUserMode(new UserMode("PROTECTED", 'q')); + ModeManager::AddUserMode(new UserMode("RESTRICTED", 'r')); + ModeManager::AddUserMode(new UserMode("REGISTERED", 'R')); + ModeManager::AddUserMode(new UserMode("SNOMASK", 's')); + ModeManager::AddUserMode(new UserMode("WALLOPS", 'w')); + ModeManager::AddUserMode(new UserMode("CLOAK", 'x')); /* Add modes for ban, exception, and invite lists */ - ModeManager::AddChannelMode(new ChannelModeList(CMODE_BAN, 'b')); - ModeManager::AddChannelMode(new ChannelModeList(CMODE_EXCEPT, 'e')); - ModeManager::AddChannelMode(new ChannelModeList(CMODE_INVITEOVERRIDE, 'I')); + ModeManager::AddChannelMode(new ChannelModeList("BAN", 'b')); + ModeManager::AddChannelMode(new ChannelModeList("EXCEPT", 'e')); + ModeManager::AddChannelMode(new ChannelModeList("INVITEOVERRIDE", 'I')); /* Add channel user modes */ - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', '+')); - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_HALFOP, 'h', '%')); - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', '@')); - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT, 'a', '&')); - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, 'q','~')); + ModeManager::AddChannelMode(new ChannelModeStatus("VOICE", 'v', '+')); + ModeManager::AddChannelMode(new ChannelModeStatus("HALFOP", 'h', '%')); + ModeManager::AddChannelMode(new ChannelModeStatus("OP", 'o', '@')); + ModeManager::AddChannelMode(new ChannelModeStatus("PROTECT", 'a', '&')); + ModeManager::AddChannelMode(new ChannelModeStatus("OWNER", 'q','~')); /* Add channel modes */ - ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, 'i')); + ModeManager::AddChannelMode(new ChannelMode("INVITE", 'i')); ModeManager::AddChannelMode(new ChannelModeKey('k')); - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, 'l')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, 'm')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_REGMODERATED, 'M')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, 'n')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_OPERONLY, 'O')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_PERM, 'P')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKICK, 'Q')); + ModeManager::AddChannelMode(new ChannelModeParam("LIMIT", 'l')); + ModeManager::AddChannelMode(new ChannelMode("MODERATED", 'm')); + ModeManager::AddChannelMode(new ChannelMode("REGMODERATED", 'M')); + ModeManager::AddChannelMode(new ChannelMode("NOEXTERNAL", 'n')); + ModeManager::AddChannelMode(new ChannelMode("OPERONLY", 'O')); + ModeManager::AddChannelMode(new ChannelMode("PERM", 'P')); + ModeManager::AddChannelMode(new ChannelMode("NOKICK", 'Q')); ModeManager::AddChannelMode(new ChannelModeRegistered('r')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_REGISTEREDONLY, 'R')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, 's')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, 't')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOINVITE, 'V')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_SSL, 'z')); + ModeManager::AddChannelMode(new ChannelMode("REGISTEREDONLY", 'R')); + ModeManager::AddChannelMode(new ChannelMode("SECRET", 's')); + ModeManager::AddChannelMode(new ChannelMode("TOPIC", 't')); + ModeManager::AddChannelMode(new ChannelMode("NOINVITE", 'V')); + ModeManager::AddChannelMode(new ChannelMode("SSL", 'z')); } public: @@ -682,7 +681,7 @@ class ProtongIRCd : public Module void OnUserNickChange(User *u, const Anope::string &) anope_override { - u->RemoveModeInternal(ModeManager::FindUserModeByName(UMODE_REGISTERED)); + u->RemoveModeInternal(ModeManager::FindUserModeByName("REGISTERED")); } }; diff --git a/modules/protocol/plexus.cpp b/modules/protocol/plexus.cpp index 42d282d19..1624aa28e 100644 --- a/modules/protocol/plexus.cpp +++ b/modules/protocol/plexus.cpp @@ -1,6 +1,6 @@ /* Plexus 3+ IRCD functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -22,6 +22,7 @@ class PlexusProto : public IRCDProto { DefaultPseudoclientModes = "+oiU"; CanSVSNick = true; + CanSVSJoin = true; CanSetVHost = true; CanSetVIdent = true; CanSNLine = true; @@ -55,13 +56,13 @@ class PlexusProto : public IRCDProto /* If the user is internally on the channel with flags, kill them so that * the stacker will allow this. */ - UserContainer *uc = c->FindUser(user); + ChanUserContainer *uc = c->FindUser(user); if (uc != NULL) - uc->status->ClearFlags(); + uc->status.modes.clear(); BotInfo *setter = BotInfo::Find(user->nick); for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i) - if (cs.HasFlag(ModeManager::ChannelModes[i]->name)) + if (cs.modes.count(ModeManager::ChannelModes[i]->name)) c->SetMode(setter, ModeManager::ChannelModes[i], user->GetUID(), false); } } @@ -80,8 +81,8 @@ class PlexusProto : public IRCDProto void SendVhostDel(User *u) anope_override { - if (u->HasMode(UMODE_CLOAK)) - u->RemoveMode(HostServ, UMODE_CLOAK); + if (u->HasMode("CLOAK")) + u->RemoveMode(HostServ, "CLOAK"); else this->SendVhost(u, u->GetIdent(), u->chost); } @@ -154,12 +155,12 @@ class PlexusProto : public IRCDProto void SendSVSJoin(const BotInfo *source, const User *user, const Anope::string &chan, const Anope::string ¶m) anope_override { - UplinkSocket::Message(source) << "ENCAP " << user->server->GetSID() << " SVSJOIN " << user->GetUID() << " " << chan; + UplinkSocket::Message(source) << "ENCAP " << user->server->GetName() << " SVSJOIN " << user->GetUID() << " " << chan; } void SendSVSPart(const BotInfo *source, const User *user, const Anope::string &chan, const Anope::string ¶m) anope_override { - UplinkSocket::Message(source) << "ENCAP " << user->server->GetSID() << " SVSPART " << user->GetUID() << " " << chan; + UplinkSocket::Message(source) << "ENCAP " << user->server->GetName() << " SVSPART " << user->GetUID() << " " << chan; } }; @@ -184,8 +185,8 @@ struct IRCDMessageEncap : IRCDMessage if (u && nc) { u->Login(nc); - if (!Config->NoNicknameOwnership && user_na && user_na->nc == nc && user_na->nc->HasFlag(NI_UNCONFIRMED) == false) - u->SetMode(NickServ, UMODE_REGISTERED); + if (!Config->NoNicknameOwnership && user_na && user_na->nc == nc && user_na->nc->HasExt("UNCONFIRMED") == false) + u->SetMode(NickServ, "REGISTERED"); } } @@ -237,7 +238,9 @@ struct IRCDMessageServer : IRCDMessage struct IRCDMessageUID : IRCDMessage { - IRCDMessageUID(Module *creator) : IRCDMessage(creator, "UID", 11) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); } + ServiceReference<NickServService> NSService; + + IRCDMessageUID(Module *creator) : IRCDMessage(creator, "UID", 11), NSService("NickServService", "NickServ") { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); } /* params[0] = nick @@ -260,15 +263,27 @@ struct IRCDMessageUID : IRCDMessage if (ip == "0") ip.clear(); - User *user = new User(params[0], params[4], params[9], params[5], ip, source.GetServer(), params[10], params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : 0, params[3], params[7]); - if (params[8] != "0" && params[8].is_pos_number_only() && convertTo<time_t>(params[8]) == user->timestamp) + time_t ts; + try + { + ts = convertTo<time_t>(params[2]); + } + catch (const ConvertException &) { - NickAlias *na = NickAlias::Find(user->nick); - if (na) - user->Login(na->nc); + ts = Anope::CurTime; + } + + User *user = new User(params[0], params[4], params[9], params[5], ip, source.GetServer(), params[10], ts, params[3], params[7]); + try + { + if (NSService && params[8].is_pos_number_only() && convertTo<time_t>(params[8]) == user->timestamp) + { + NickAlias *na = NickAlias::Find(user->nick); + if (na) + NSService->Login(user, na); + } } - else if (user && user->server->IsSynced() && NickServService) - NickServService->Validate(user); + catch (const ConvertException &) { } } }; @@ -310,30 +325,30 @@ class ProtoPlexus : public Module void AddModes() { /* Add user modes */ - ModeManager::RemoveUserMode(ModeManager::FindUserModeByName(UMODE_HIDEOPER)); - ModeManager::AddUserMode(new UserMode(UMODE_NOCTCP, 'C')); - ModeManager::AddUserMode(new UserMode(UMODE_DEAF, 'D')); - ModeManager::AddUserMode(new UserMode(UMODE_SOFTCALLERID, 'G')); - ModeManager::AddUserMode(new UserMode(UMODE_NETADMIN, 'N')); - ModeManager::AddUserMode(new UserMode(UMODE_SSL, 'S')); - ModeManager::AddUserMode(new UserMode(UMODE_WEBIRC, 'W')); - ModeManager::AddUserMode(new UserMode(UMODE_CALLERID, 'g')); - ModeManager::AddUserMode(new UserMode(UMODE_PRIV, 'p')); - ModeManager::AddUserMode(new UserMode(UMODE_CLOAK, 'x')); - ModeManager::AddUserMode(new UserMode(UMODE_PROTECTED, 'U')); + ModeManager::RemoveUserMode(ModeManager::FindUserModeByName("HIDEOPER")); + ModeManager::AddUserMode(new UserMode("NOCTCP", 'C')); + ModeManager::AddUserMode(new UserMode("DEAF", 'D')); + ModeManager::AddUserMode(new UserMode("SOFTCALLERID", 'G')); + ModeManager::AddUserMode(new UserMode("NETADMIN", 'N')); + ModeManager::AddUserMode(new UserMode("SSL", 'S')); + ModeManager::AddUserMode(new UserMode("WEBIRC", 'W')); + ModeManager::AddUserMode(new UserMode("CALLERID", 'g')); + ModeManager::AddUserMode(new UserMode("PRIV", 'p')); + ModeManager::AddUserMode(new UserMode("CLOAK", 'x')); + ModeManager::AddUserMode(new UserMode("PROTECTED", 'U')); /* v/h/o/a/q */ - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT, 'a', '&', 3)); - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, 'q', '~', 4)); + ModeManager::AddChannelMode(new ChannelModeStatus("PROTECT", 'a', '&', 3)); + ModeManager::AddChannelMode(new ChannelModeStatus("OWNER", 'q', '~', 4)); /* Add channel modes */ - ModeManager::RemoveChannelMode(ModeManager::FindChannelModeByName(CMODE_REGISTERED)); - ModeManager::AddChannelMode(new ChannelMode(CMODE_BANDWIDTH, 'B')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOCTCP, 'C')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_REGMODERATED, 'M')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_NONOTICE, 'N')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCOLOR, 'c')); - ModeManager::AddChannelMode(new ChannelMode(CMODE_PERM, 'z')); + ModeManager::RemoveChannelMode(ModeManager::FindChannelModeByName("REGISTERED")); + ModeManager::AddChannelMode(new ChannelMode("BANDWIDTH", 'B')); + ModeManager::AddChannelMode(new ChannelMode("NOCTCP", 'C')); + ModeManager::AddChannelMode(new ChannelMode("REGMODERATED", 'M')); + ModeManager::AddChannelMode(new ChannelMode("NONOTICE", 'N')); + ModeManager::AddChannelMode(new ChannelMode("BLOCKCOLOR", 'c')); + ModeManager::AddChannelMode(new ChannelMode("PERM", 'z')); } public: @@ -362,26 +377,12 @@ class ProtoPlexus : public Module throw ModuleException("No protocol interface for hybrid"); this->AddModes(); - - Implementation i[] = { I_OnServerSync }; - ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } ~ProtoPlexus() { ModuleManager::UnloadModule(m_hybrid, NULL); } - - void OnServerSync(Server *s) anope_override - { - if (NickServService) - for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it) - { - User *u = it->second; - if (u->server == s && !u->IsIdentified()) - NickServService->Validate(u); - } - } }; MODULE_INIT(ProtoPlexus) diff --git a/modules/protocol/ratbox.cpp b/modules/protocol/ratbox.cpp index 52795485f..247b8777a 100644 --- a/modules/protocol/ratbox.cpp +++ b/modules/protocol/ratbox.cpp @@ -1,6 +1,6 @@ /* Ratbox IRCD functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -107,8 +107,8 @@ struct IRCDMessageEncap : IRCDMessage u->Login(nc); const NickAlias *user_na = NickAlias::Find(u->nick); - if (!Config->NoNicknameOwnership && user_na && user_na->nc == nc && user_na->nc->HasFlag(NI_UNCONFIRMED) == false) - u->SetMode(NickServ, UMODE_REGISTERED); + if (!Config->NoNicknameOwnership && user_na && user_na->nc == nc && user_na->nc->HasExt("UNCONFIRMED") == false) + u->SetMode(NickServ, "REGISTERED"); } } }; @@ -171,9 +171,7 @@ struct IRCDMessageUID : IRCDMessage void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override { /* Source is always the server */ - User *user = new User(params[0], params[4], params[5], "", params[6], source.GetServer(), params[8], params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : 0, params[3], params[7]); - if (user && user->server->IsSynced() && NickServService) - NickServService->Validate(user); + new User(params[0], params[4], params[5], "", params[6], source.GetServer(), params[8], params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : 0, params[3], params[7]); } }; @@ -216,17 +214,17 @@ class ProtoRatbox : public Module void AddModes() { /* user modes */ - ModeManager::RemoveUserMode(ModeManager::FindUserModeByName(UMODE_HIDEOPER)); - ModeManager::RemoveUserMode(ModeManager::FindUserModeByName(UMODE_REGPRIV)); + ModeManager::RemoveUserMode(ModeManager::FindUserModeByName("HIDEOPER")); + ModeManager::RemoveUserMode(ModeManager::FindUserModeByName("REGPRIV")); /* v/h/o/a/q */ - ModeManager::RemoveChannelMode(ModeManager::FindChannelModeByName(CMODE_HALFOP)); + ModeManager::RemoveChannelMode(ModeManager::FindChannelModeByName("HALFOP")); /* channel modes */ - ModeManager::RemoveChannelMode(ModeManager::FindChannelModeByName(CMODE_REGISTERED)); - ModeManager::RemoveChannelMode(ModeManager::FindChannelModeByName(CMODE_OPERONLY)); - ModeManager::RemoveChannelMode(ModeManager::FindChannelModeByName(CMODE_REGISTEREDONLY)); - ModeManager::RemoveChannelMode(ModeManager::FindChannelModeByName(CMODE_SSL)); + ModeManager::RemoveChannelMode(ModeManager::FindChannelModeByName("REGISTERED")); + ModeManager::RemoveChannelMode(ModeManager::FindChannelModeByName("OPERONLY")); + ModeManager::RemoveChannelMode(ModeManager::FindChannelModeByName("REGISTEREDONLY")); + ModeManager::RemoveChannelMode(ModeManager::FindChannelModeByName("SSL")); } public: @@ -255,26 +253,12 @@ class ProtoRatbox : public Module throw ModuleException("No protocol interface for hybrid"); this->AddModes(); - - Implementation i[] = { I_OnServerSync }; - ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); } ~ProtoRatbox() { ModuleManager::UnloadModule(m_hybrid, NULL); } - - void OnServerSync(Server *s) anope_override - { - if (NickServService) - for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it) - { - User *u = it->second; - if (u->server == s && !u->IsIdentified()) - NickServService->Validate(u); - } - } }; MODULE_INIT(ProtoRatbox) diff --git a/modules/protocol/unreal.cpp b/modules/protocol/unreal.cpp index a14091c96..01141b6a3 100644 --- a/modules/protocol/unreal.cpp +++ b/modules/protocol/unreal.cpp @@ -1,6 +1,6 @@ /* Unreal IRCD 3.2.x functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -75,10 +75,10 @@ class UnrealIRCdProto : public IRCDProto void SendVhostDel(User *u) anope_override { - u->RemoveMode(HostServ, UMODE_CLOAK); - u->RemoveMode(HostServ, UMODE_VHOST); + u->RemoveMode(HostServ, "CLOAK"); + u->RemoveMode(HostServ, "VHOST"); ModeManager::ProcessModes(); - u->SetMode(HostServ, UMODE_CLOAK); + u->SetMode(HostServ, "CLOAK"); } void SendAkill(User *u, XLine *x) anope_override @@ -164,13 +164,13 @@ class UnrealIRCdProto : public IRCDProto /* If the user is internally on the channel with flags, kill them so that * the stacker will allow this. */ - UserContainer *uc = c->FindUser(user); + ChanUserContainer *uc = c->FindUser(user); if (uc != NULL) - uc->status->ClearFlags(); + uc->status.modes.clear(); BotInfo *setter = BotInfo::Find(user->nick); for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i) - if (cs.HasFlag(ModeManager::ChannelModes[i]->name)) + if (cs.modes.count(ModeManager::ChannelModes[i]->name)) c->SetMode(setter, ModeManager::ChannelModes[i], user->GetUID(), false); } } @@ -377,7 +377,7 @@ class UnrealIRCdProto : public IRCDProto class UnrealExtBan : public ChannelModeList { public: - UnrealExtBan(ChannelModeName mName, char modeChar) : ChannelModeList(mName, modeChar) { } + UnrealExtBan(const Anope::string &mname, char modeChar) : ChannelModeList(mname, modeChar) { } bool Matches(const User *u, const Entry *e) anope_override { @@ -400,9 +400,9 @@ class UnrealExtBan : public ChannelModeList Channel *c = Channel::Find(channel); if (c != NULL) { - UserContainer *uc = c->FindUser(u); + ChanUserContainer *uc = c->FindUser(u); if (uc != NULL) - if (cm == NULL || uc->status->HasFlag(cm->name)) + if (cm == NULL || uc->status.modes.count(cm->name)) return true; } } @@ -423,7 +423,7 @@ class UnrealExtBan : public ChannelModeList } else if (mask.find("~R:") == 0) { - if (u->HasMode(UMODE_REGISTERED) && mask.equals_ci(u->nick)) + if (u->HasMode("REGISTERED") && mask.equals_ci(u->nick)) return true; } else if (mask.find("~a:") == 0) @@ -441,7 +441,7 @@ class UnrealExtBan : public ChannelModeList class ChannelModeFlood : public ChannelModeParam { public: - ChannelModeFlood(char modeChar, bool minusNoArg) : ChannelModeParam(CMODE_FLOOD, modeChar, minusNoArg) { } + ChannelModeFlood(char modeChar, bool minusNoArg) : ChannelModeParam("FLOOD", modeChar, minusNoArg) { } /* Borrowed part of this check from UnrealIRCd */ bool IsValid(const Anope::string &value) const anope_override @@ -492,7 +492,7 @@ class ChannelModeFlood : public ChannelModeParam class ChannelModeUnrealSSL : public ChannelMode { public: - ChannelModeUnrealSSL(ChannelModeName n, char c) : ChannelMode(n, c) + ChannelModeUnrealSSL(const Anope::string &n, char c) : ChannelMode(n, c) { } @@ -524,16 +524,16 @@ struct IRCDMessageCapab : Message::Capab switch (modebuf[t]) { case 'b': - ModeManager::AddChannelMode(new UnrealExtBan(CMODE_BAN, 'b')); + ModeManager::AddChannelMode(new UnrealExtBan("BAN", 'b')); continue; case 'e': - ModeManager::AddChannelMode(new UnrealExtBan(CMODE_EXCEPT, 'e')); + ModeManager::AddChannelMode(new UnrealExtBan("EXCEPT", 'e')); continue; case 'I': - ModeManager::AddChannelMode(new UnrealExtBan(CMODE_INVITEOVERRIDE, 'I')); + ModeManager::AddChannelMode(new UnrealExtBan("INVITEOVERRIDE", 'I')); continue; default: - ModeManager::AddChannelMode(new ChannelModeList(CMODE_END, modebuf[t])); + ModeManager::AddChannelMode(new ChannelModeList("END", modebuf[t])); } } @@ -549,10 +549,10 @@ struct IRCDMessageCapab : Message::Capab ModeManager::AddChannelMode(new ChannelModeFlood('f', false)); continue; case 'L': - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_REDIRECT, 'L')); + ModeManager::AddChannelMode(new ChannelModeParam("REDIRECT", 'L')); continue; default: - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, modebuf[t])); + ModeManager::AddChannelMode(new ChannelModeParam("END", modebuf[t])); } } @@ -562,13 +562,13 @@ struct IRCDMessageCapab : Message::Capab switch (modebuf[t]) { case 'l': - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, 'l', true)); + ModeManager::AddChannelMode(new ChannelModeParam("LIMIT", 'l', true)); continue; case 'j': - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_JOINFLOOD, 'j', true)); + ModeManager::AddChannelMode(new ChannelModeParam("JOINFLOOD", 'j', true)); continue; default: - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_END, modebuf[t], true)); + ModeManager::AddChannelMode(new ChannelModeParam("END", modebuf[t], true)); } } @@ -578,31 +578,31 @@ struct IRCDMessageCapab : Message::Capab switch (modebuf[t]) { case 'p': - ModeManager::AddChannelMode(new ChannelMode(CMODE_PRIVATE, 'p')); + ModeManager::AddChannelMode(new ChannelMode("PRIVATE", 'p')); continue; case 's': - ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, 's')); + ModeManager::AddChannelMode(new ChannelMode("SECRET", 's')); continue; case 'm': - ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, 'm')); + ModeManager::AddChannelMode(new ChannelMode("MODERATED", 'm')); continue; case 'n': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, 'n')); + ModeManager::AddChannelMode(new ChannelMode("NOEXTERNAL", 'n')); continue; case 't': - ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, 't')); + ModeManager::AddChannelMode(new ChannelMode("TOPIC", 't')); continue; case 'i': - ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, 'i')); + ModeManager::AddChannelMode(new ChannelMode("INVITE", 'i')); continue; case 'r': ModeManager::AddChannelMode(new ChannelModeRegistered('r')); continue; case 'R': - ModeManager::AddChannelMode(new ChannelMode(CMODE_REGISTEREDONLY, 'R')); + ModeManager::AddChannelMode(new ChannelMode("REGISTEREDONLY", 'R')); continue; case 'c': - ModeManager::AddChannelMode(new ChannelMode(CMODE_BLOCKCOLOR, 'c')); + ModeManager::AddChannelMode(new ChannelMode("BLOCKCOLOR", 'c')); continue; case 'O': ModeManager::AddChannelMode(new ChannelModeOper('O')); @@ -611,43 +611,43 @@ struct IRCDMessageCapab : Message::Capab ModeManager::AddChannelMode(new ChannelModeAdmin('A')); continue; case 'Q': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKICK, 'Q')); + ModeManager::AddChannelMode(new ChannelMode("NOKICK", 'Q')); continue; case 'K': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOKNOCK, 'K')); + ModeManager::AddChannelMode(new ChannelMode("NOKNOCK", 'K')); continue; case 'V': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOINVITE, 'V')); + ModeManager::AddChannelMode(new ChannelMode("NOINVITE", 'V')); continue; case 'C': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NOCTCP, 'C')); + ModeManager::AddChannelMode(new ChannelMode("NOCTCP", 'C')); continue; case 'u': - ModeManager::AddChannelMode(new ChannelMode(CMODE_AUDITORIUM, 'u')); + ModeManager::AddChannelMode(new ChannelMode("AUDITORIUM", 'u')); continue; case 'z': - ModeManager::AddChannelMode(new ChannelMode(CMODE_SSL, 'z')); + ModeManager::AddChannelMode(new ChannelMode("SSL", 'z')); continue; case 'N': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NONICK, 'N')); + ModeManager::AddChannelMode(new ChannelMode("NONICK", 'N')); continue; case 'S': - ModeManager::AddChannelMode(new ChannelMode(CMODE_STRIPCOLOR, 'S')); + ModeManager::AddChannelMode(new ChannelMode("STRIPCOLOR", 'S')); continue; case 'M': - ModeManager::AddChannelMode(new ChannelMode(CMODE_REGMODERATED, 'M')); + ModeManager::AddChannelMode(new ChannelMode("REGMODERATED", 'M')); continue; case 'T': - ModeManager::AddChannelMode(new ChannelMode(CMODE_NONOTICE, 'T')); + ModeManager::AddChannelMode(new ChannelMode("NONOTICE", 'T')); continue; case 'G': - ModeManager::AddChannelMode(new ChannelMode(CMODE_FILTER, 'G')); + ModeManager::AddChannelMode(new ChannelMode("FILTER", 'G')); continue; case 'Z': - ModeManager::AddChannelMode(new ChannelModeUnrealSSL(CMODE_END, 'Z')); + ModeManager::AddChannelMode(new ChannelModeUnrealSSL("END", 'Z')); continue; default: - ModeManager::AddChannelMode(new ChannelMode(CMODE_END, modebuf[t])); + ModeManager::AddChannelMode(new ChannelMode("END", modebuf[t])); } } } @@ -750,7 +750,9 @@ struct IRCDMessageNetInfo : IRCDMessage struct IRCDMessageNick : IRCDMessage { - IRCDMessageNick(Module *creator) : IRCDMessage(creator, "NICK", 2) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); } + ServiceReference<NickServService> NSService; + + IRCDMessageNick(Module *creator) : IRCDMessage(creator, "NICK", 2), NSService("NickServService", "NickServ") { SetFlag(IRCDMESSAGE_SOFT_LIMIT); } /* ** NICK - new @@ -803,7 +805,7 @@ struct IRCDMessageNick : IRCDMessage User *user = new User(params[0], params[3], params[4], vhost, ip, s, params[10], user_ts, params[7]); - const NickAlias *na = NULL; + NickAlias *na = NULL; if (params[6] == "0") ; @@ -817,14 +819,8 @@ struct IRCDMessageNick : IRCDMessage na = NickAlias::Find(params[6]); } - if (na) - { - user->Login(na->nc); - if (!Config->NoNicknameOwnership && na->nc->HasFlag(NI_UNCONFIRMED) == false) - user->SetMode(NickServ, UMODE_REGISTERED); - } - else if (NickServService) - NickServService->Validate(user); + if (na && NSService) + NSService->Login(user, na); } else source.GetUser()->ChangeNick(params[0]); @@ -897,7 +893,12 @@ struct IRCDMessageSASL : IRCDMessage return; if (params[2] == "S") - UplinkSocket::Message() << "SASL " << params[1].substr(0, p) << " " << params[1] << " C +"; + { + if (params[3] == "PLAIN") + UplinkSocket::Message() << "SASL " << params[1].substr(0, p) << " " << params[1] << " C +"; + else + UplinkSocket::Message() << "SASL " << params[1].substr(0, p) << " " << params[1] << " D F"; + } else if (params[2] == "C") { Anope::string decoded; @@ -944,7 +945,7 @@ struct IRCDMessageSetHost : IRCDMessage User *u = source.GetUser(); /* When a user sets +x we recieve the new host and then the mode change */ - if (u->HasMode(UMODE_CLOAK)) + if (u->HasMode("CLOAK")) u->SetDisplayedHost(params[0]); else u->SetCloakedHost(params[0]); @@ -1049,7 +1050,7 @@ struct IRCDMessageSJoin : IRCDMessage continue; } - sju.first.SetFlag(cm->name); + sju.first.modes.insert(cm->name); } sju.second = User::Find(buf); @@ -1073,9 +1074,9 @@ struct IRCDMessageSJoin : IRCDMessage if (!c || c->creation_time != ts) return; - ChannelMode *ban = ModeManager::FindChannelModeByName(CMODE_BAN), - *except = ModeManager::FindChannelModeByName(CMODE_EXCEPT), - *invex = ModeManager::FindChannelModeByName(CMODE_INVITEOVERRIDE); + ChannelMode *ban = ModeManager::FindChannelModeByName("BAN"), + *except = ModeManager::FindChannelModeByName("EXCEPT"), + *invex = ModeManager::FindChannelModeByName("INVITEOVERRIDE"); if (ban) for (std::list<Anope::string>::iterator it = bans.begin(), it_end = bans.end(); it != it_end; ++it) @@ -1162,40 +1163,40 @@ class ProtoUnreal : public Module void AddModes() { - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', '+', 0)); - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_HALFOP, 'h', '%', 1)); - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', '@', 2)); + ModeManager::AddChannelMode(new ChannelModeStatus("VOICE", 'v', '+', 0)); + ModeManager::AddChannelMode(new ChannelModeStatus("HALFOP", 'h', '%', 1)); + ModeManager::AddChannelMode(new ChannelModeStatus("OP", 'o', '@', 2)); /* Unreal sends +q as * and +a as ~ */ - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_PROTECT, 'a', '~', 3)); - ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OWNER, 'q', '*', 4)); + ModeManager::AddChannelMode(new ChannelModeStatus("PROTECT", 'a', '~', 3)); + ModeManager::AddChannelMode(new ChannelModeStatus("OWNER", 'q', '*', 4)); /* Add user modes */ - ModeManager::AddUserMode(new UserMode(UMODE_SERV_ADMIN, 'A')); - ModeManager::AddUserMode(new UserMode(UMODE_BOT, 'B')); - ModeManager::AddUserMode(new UserMode(UMODE_CO_ADMIN, 'C')); - ModeManager::AddUserMode(new UserMode(UMODE_FILTER, 'G')); - ModeManager::AddUserMode(new UserMode(UMODE_HIDEOPER, 'H')); - ModeManager::AddUserMode(new UserMode(UMODE_HIDEIDLE, 'I')); - ModeManager::AddUserMode(new UserMode(UMODE_NETADMIN, 'N')); - ModeManager::AddUserMode(new UserMode(UMODE_REGPRIV, 'R')); - ModeManager::AddUserMode(new UserMode(UMODE_PROTECTED, 'S')); - ModeManager::AddUserMode(new UserMode(UMODE_NOCTCP, 'T')); - ModeManager::AddUserMode(new UserMode(UMODE_WEBTV, 'V')); - ModeManager::AddUserMode(new UserMode(UMODE_WHOIS, 'W')); - ModeManager::AddUserMode(new UserMode(UMODE_ADMIN, 'a')); - ModeManager::AddUserMode(new UserMode(UMODE_DEAF, 'd')); - ModeManager::AddUserMode(new UserMode(UMODE_GLOBOPS, 'g')); - ModeManager::AddUserMode(new UserMode(UMODE_HELPOP, 'h')); - ModeManager::AddUserMode(new UserMode(UMODE_INVIS, 'i')); - ModeManager::AddUserMode(new UserMode(UMODE_OPER, 'o')); - ModeManager::AddUserMode(new UserMode(UMODE_PRIV, 'p')); - ModeManager::AddUserMode(new UserMode(UMODE_GOD, 'q')); - ModeManager::AddUserMode(new UserMode(UMODE_REGISTERED, 'r')); - ModeManager::AddUserMode(new UserMode(UMODE_SNOMASK, 's')); - ModeManager::AddUserMode(new UserMode(UMODE_VHOST, 't')); - ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, 'w')); - ModeManager::AddUserMode(new UserMode(UMODE_CLOAK, 'x')); - ModeManager::AddUserMode(new UserMode(UMODE_SSL, 'z')); + ModeManager::AddUserMode(new UserMode("SERV_ADMIN", 'A')); + ModeManager::AddUserMode(new UserMode("BOT", 'B')); + ModeManager::AddUserMode(new UserMode("CO_ADMIN", 'C')); + ModeManager::AddUserMode(new UserMode("FILTER", 'G')); + ModeManager::AddUserMode(new UserMode("HIDEOPER", 'H')); + ModeManager::AddUserMode(new UserMode("HIDEIDLE", 'I')); + ModeManager::AddUserMode(new UserMode("NETADMIN", 'N')); + ModeManager::AddUserMode(new UserMode("REGPRIV", 'R')); + ModeManager::AddUserMode(new UserMode("PROTECTED", 'S')); + ModeManager::AddUserMode(new UserMode("NOCTCP", 'T')); + ModeManager::AddUserMode(new UserMode("WEBTV", 'V')); + ModeManager::AddUserMode(new UserMode("WHOIS", 'W')); + ModeManager::AddUserMode(new UserMode("ADMIN", 'a')); + ModeManager::AddUserMode(new UserMode("DEAF", 'd')); + ModeManager::AddUserMode(new UserMode("GLOBOPS", 'g')); + ModeManager::AddUserMode(new UserMode("HELPOP", 'h')); + ModeManager::AddUserMode(new UserMode("INVIS", 'i')); + ModeManager::AddUserMode(new UserMode("OPER", 'o')); + ModeManager::AddUserMode(new UserMode("PRIV", 'p')); + ModeManager::AddUserMode(new UserMode("GOD", 'q')); + ModeManager::AddUserMode(new UserMode("REGISTERED", 'r')); + ModeManager::AddUserMode(new UserMode("SNOMASK", 's')); + ModeManager::AddUserMode(new UserMode("VHOST", 't')); + ModeManager::AddUserMode(new UserMode("WALLOPS", 'w')); + ModeManager::AddUserMode(new UserMode("CLOAK", 'x')); + ModeManager::AddUserMode(new UserMode("SSL", 'z')); } public: @@ -1222,7 +1223,7 @@ class ProtoUnreal : public Module void OnUserNickChange(User *u, const Anope::string &) anope_override { - u->RemoveModeInternal(ModeManager::FindUserModeByName(UMODE_REGISTERED)); + u->RemoveModeInternal(ModeManager::FindUserModeByName("REGISTERED")); if (Servers::Capab.count("ESVID") == 0) IRCD->SendLogout(u); } diff --git a/modules/pseudoclients/botserv.cpp b/modules/pseudoclients/botserv.cpp index addb39e0c..2c506876a 100644 --- a/modules/pseudoclients/botserv.cpp +++ b/modules/pseudoclients/botserv.cpp @@ -1,6 +1,6 @@ /* BotServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -20,20 +20,24 @@ class BotServCore : public Module { this->SetAuthor("Anope"); - BotInfo *bi = BotInfo::Find(Config->BotServ); - if (!bi) + BotServ = BotInfo::Find(Config->BotServ); + if (!BotServ) throw ModuleException("No bot named " + Config->BotServ); - Implementation i[] = { I_OnPrivmsg, I_OnJoinChannel, I_OnLeaveChannel, + Implementation i[] = { I_OnBotDelete, I_OnPrivmsg, I_OnJoinChannel, I_OnLeaveChannel, I_OnPreHelp, I_OnPostHelp, I_OnChannelModeSet }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - - Service::AddAlias("BotInfo", "BotServ", bi->nick); } ~BotServCore() { - Service::DelAlias("BotInfo", "BotServ"); + BotServ = NULL; + } + + void OnBotDelete(BotInfo *bi) anope_override + { + if (bi == BotServ) + BotServ = NULL; } void OnPrivmsg(User *u, Channel *c, Anope::string &msg) anope_override @@ -59,7 +63,7 @@ class BotServCore : public Module return; } - if (realbuf.empty() || !c->ci->botflags.HasFlag(BS_FANTASY)) + if (realbuf.empty() || !c->ci->HasExt("BS_FANTASY")) return; std::vector<Anope::string> params; @@ -104,9 +108,9 @@ class BotServCore : public Module for (unsigned i = 0, j = params.size() - (count - 1); i < j; ++i) params.erase(params.begin()); - /* All ChanServ commands take the channel as a first parameter */ - if (cmd->name.find("chanserv/") == 0 && !cmd->HasFlag(CFLAG_STRIP_CHANNEL)) - params.insert(params.begin(), c->ci->name); + /* Some commands take the channel as a first parameter */ + if (info.prepend_channel) + params.insert(params.begin(), c->name); while (cmd->max_params > 0 && params.size() > cmd->max_params) { @@ -115,7 +119,7 @@ class BotServCore : public Module } // Command requires registered users only - if (!cmd->HasFlag(CFLAG_ALLOW_UNREGISTERED) && !u->Account()) + if (!cmd->AllowUnregistered() && !u->Account()) return; if (params.size() < cmd->min_params) @@ -146,19 +150,16 @@ class BotServCore : public Module if (MOD_RESULT == EVENT_STOP) return; - Reference<User> user_reference(u); Reference<NickCore> nc_reference(u->Account()); cmd->Execute(source, params); - - if (user_reference && nc_reference) - { - FOREACH_MOD(I_OnPostCommand, OnPostCommand(source, cmd, params)); - } + if (!nc_reference) + source.nc = NULL; + FOREACH_MOD(I_OnPostCommand, OnPostCommand(source, cmd, params)); } void OnJoinChannel(User *user, Channel *c) anope_override { - if (c->ci && c->ci->bi) + if (user->server != Me && c->ci && c->ci->bi) { /** * We let the bot join even if it was an ignored user, as if we don't, @@ -172,7 +173,7 @@ class BotServCore : public Module * to has synced, or we'll get greet-floods when the net * recovers from a netsplit. -GD */ - if (c->FindUser(c->ci->bi) && c->ci->botflags.HasFlag(BS_GREET) && user->Account() && !user->Account()->greet.empty() && c->ci->AccessFor(user).HasPriv("GREET") && user->server->IsSynced()) + if (c->FindUser(c->ci->bi) && c->ci->HasExt("BS_GREET") && user->Account() && !user->Account()->greet.empty() && c->ci->AccessFor(user).HasPriv("GREET") && user->server->IsSynced()) { IRCD->SendPrivmsg(c->ci->bi, c->name, "[%s] %s", user->Account()->display.c_str(), user->Account()->greet.c_str()); c->ci->bi->lastmsg = Anope::CurTime; @@ -183,26 +184,26 @@ class BotServCore : public Module void OnLeaveChannel(User *u, Channel *c) anope_override { /* Channel is persistent, it shouldn't be deleted and the service bot should stay */ - if (c->HasFlag(CH_PERSIST) || (c->ci && c->ci->HasFlag(CI_PERSIST))) + if (c->HasExt("PERSIST") || (c->ci && c->ci->HasExt("PERSIST"))) return; /* Channel is syncing from a netburst, don't destroy it as more users are probably wanting to join immediatly * We also don't part the bot here either, if necessary we will part it after the sync */ - if (c->HasFlag(CH_SYNCING)) + if (c->HasExt("SYNCING")) return; /* Additionally, do not delete this channel if ChanServ/a BotServ bot is inhabiting it */ - if (c->HasFlag(CH_INHABIT)) + if (c->HasExt("INHABIT")) return; if (c->ci && c->ci->bi && u != *c->ci->bi && c->users.size() - 1 <= Config->BSMinUsers && c->FindUser(c->ci->bi)) { - bool persist = c->HasFlag(CH_PERSIST); - c->SetFlag(CH_PERSIST); + bool persist = c->Shrink("PERSIST"); + c->Extend("PERSIST"); c->ci->bi->Part(c->ci->c); if (!persist) - c->UnsetFlag(CH_PERSIST); + c->Shrink("PERSIST"); } } @@ -213,8 +214,8 @@ class BotServCore : public Module if (source.c) { - source.Reply(_("\2%s\2 allows you to execute \"fantasy\" commands in the channel.\n" - "Fantasy commands are tied to existing commands, usually on \2%s\2,\n" + source.Reply(_("\002%s\002 allows you to execute \"fantasy\" commands in the channel.\n" + "Fantasy commands are tied to existing commands, usually on \002%s\002,\n" "and provide a more convenient way to execute commands. Commands that\n" "require a channel as a parameter will automatically have that parameter\n" "given.\n"), source.service->nick.c_str(), Config->ChanServ.c_str()); @@ -254,15 +255,15 @@ class BotServCore : public Module "the following characters: %s"), Config->ChanServ.c_str(), Config->BSFantasyCharacter.c_str()); } - EventReturn OnChannelModeSet(Channel *c, MessageSource &, ChannelModeName Name, const Anope::string ¶m) anope_override + EventReturn OnChannelModeSet(Channel *c, MessageSource &, const Anope::string &mname, const Anope::string ¶m) anope_override { - if (Config->BSSmartJoin && Name == CMODE_BAN && c->ci && c->ci->bi && c->FindUser(c->ci->bi)) + if (Config->BSSmartJoin && mname == "BAN" && c->ci && c->ci->bi && c->FindUser(c->ci->bi)) { BotInfo *bi = c->ci->bi; - Entry ban(CMODE_BAN, param); + Entry ban("BAN", param); if (ban.Matches(bi)) - c->RemoveMode(bi, CMODE_BAN, param); + c->RemoveMode(bi, "BAN", param); } return EVENT_CONTINUE; diff --git a/modules/pseudoclients/botserv.h b/modules/pseudoclients/botserv.h deleted file mode 100644 index 362b15c23..000000000 --- a/modules/pseudoclients/botserv.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef BOTSERV_H -#define BOTSERV_H - -static ServiceReference<BotInfo> BotServ("BotInfo", "BotServ"); - -#endif // BOTSERV_H diff --git a/modules/pseudoclients/chanserv.cpp b/modules/pseudoclients/chanserv.cpp index 6f5cda048..9832c622e 100644 --- a/modules/pseudoclients/chanserv.cpp +++ b/modules/pseudoclients/chanserv.cpp @@ -1,6 +1,6 @@ /* ChanServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -30,10 +30,20 @@ class ExpireCallback : public CallBack bool expire = false; - if (!ci->c && Anope::CurTime - ci->last_used >= Config->CSExpire) - expire = true; + if (Anope::CurTime - ci->last_used >= Config->CSExpire) + { + if (ci->c) + { + time_t last_used = ci->last_used; + for (User::ChanUserList::const_iterator cit = ci->c->users.begin(), cit_end = ci->c->users.end(); cit != cit_end && last_used == ci->last_used; ++cit) + ci->AccessFor((*cit)->user); + expire = last_used == ci->last_used; + } + else + expire = true; + } - if (ci->HasFlag(CI_NO_EXPIRE)) + if (ci->HasExt("NO_EXPIRE")) expire = false; FOREACH_MOD(I_OnPreChanExpire, OnPreChanExpire(ci, expire)); @@ -41,12 +51,12 @@ class ExpireCallback : public CallBack if (expire) { Anope::string extra; - if (ci->HasFlag(CI_SUSPENDED)) + if (ci->HasExt("SUSPENDED")) extra = "suspended "; Log(LOG_NORMAL, "chanserv/expire") << "Expiring " << extra << "channel " << ci->name << " (founder: " << (ci->GetFounder() ? ci->GetFounder()->display : "(none)") << ")"; FOREACH_MOD(I_OnChanExpire, OnChanExpire(ci)); - ci->Destroy(); + delete ci; } } } @@ -61,24 +71,28 @@ class ChanServCore : public Module { this->SetAuthor("Anope"); - BotInfo *bi = BotInfo::Find(Config->ChanServ); - if (!bi) + ChanServ = BotInfo::Find(Config->ChanServ); + if (!ChanServ) throw ModuleException("No bot named " + Config->ChanServ); - Implementation i[] = { I_OnBotPrivmsg, I_OnDelCore, I_OnPreHelp, I_OnPostHelp, I_OnCheckModes }; + Implementation i[] = { I_OnBotDelete, I_OnBotPrivmsg, I_OnDelCore, I_OnPreHelp, I_OnPostHelp, I_OnCheckModes }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - - Service::AddAlias("BotInfo", "ChanServ", bi->nick); } ~ChanServCore() { - Service::DelAlias("BotInfo", "ChanServ"); + ChanServ = NULL; + } + + void OnBotDelete(BotInfo *bi) anope_override + { + if (bi == ChanServ) + ChanServ = NULL; } EventReturn OnBotPrivmsg(User *u, BotInfo *bi, Anope::string &message) anope_override { - if (Config->CSOpersOnly && !u->HasMode(UMODE_OPER) && bi->nick == Config->ChanServ) + if (Config->CSOpersOnly && bi == ChanServ && !u->HasMode("OPER")) { u->SendMessage(bi, ACCESS_DENIED); return EVENT_STOP; @@ -89,17 +103,18 @@ class ChanServCore : public Module void OnDelCore(NickCore *nc) anope_override { - // XXX this is slightly inefficient - for (registered_channel_map::const_iterator it = RegisteredChannelList->begin(), it_end = RegisteredChannelList->end(); it != it_end;) + std::deque<ChannelInfo *> chans; + nc->GetChannelReferences(chans); + + for (unsigned i = 0; i < chans.size(); ++i) { - ChannelInfo *ci = it->second; - ++it; + ChannelInfo *ci = chans[i]; if (ci->GetFounder() == nc) { NickCore *newowner = NULL; - if (ci->successor && (ci->successor->IsServicesOper() || !Config->CSMaxReg || ci->successor->channelcount < Config->CSMaxReg)) - newowner = ci->successor; + if (ci->GetSuccessor() && ci->GetSuccessor() != nc && (ci->GetSuccessor()->IsServicesOper() || !Config->CSMaxReg || ci->GetSuccessor()->channelcount < Config->CSMaxReg)) + newowner = ci->GetSuccessor(); else { const ChanAccess *highest = NULL; @@ -121,19 +136,19 @@ class ChanServCore : public Module { Log(LOG_NORMAL, "chanserv/expire") << "Transferring foundership of " << ci->name << " from deleted nick " << nc->display << " to " << newowner->display; ci->SetFounder(newowner); - ci->successor = NULL; + ci->SetSuccessor(NULL); } else { Log(LOG_NORMAL, "chanserv/expire") << "Deleting channel " << ci->name << " owned by deleted nick " << nc->display; - ci->Destroy(); + delete ci; continue; } } - if (ci->successor == nc) - ci->successor = NULL; + if (ci->GetSuccessor() == nc) + ci->SetSuccessor(NULL); for (unsigned j = 0; j < ci->GetAccessCount(); ++j) { @@ -147,11 +162,14 @@ class ChanServCore : public Module } } - for (unsigned j = ci->GetAkickCount(); j > 0; --j) + for (unsigned j = 0; j < ci->GetAkickCount(); ++j) { - const AutoKick *akick = ci->GetAkick(j - 1); - if (akick->HasFlag(AK_ISNICK) && akick->nc == nc) - ci->EraseAkick(j - 1); + const AutoKick *akick = ci->GetAkick(j); + if (akick->nc == nc) + { + ci->EraseAkick(j); + break; + } } } } diff --git a/modules/pseudoclients/chanserv.h b/modules/pseudoclients/chanserv.h deleted file mode 100644 index 62ea86b22..000000000 --- a/modules/pseudoclients/chanserv.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef CHANSERV_H -#define CHANSERV_H - -static ServiceReference<BotInfo> ChanServ("BotInfo", "ChanServ"); - -#endif // CHANSERV_H diff --git a/modules/pseudoclients/global.cpp b/modules/pseudoclients/global.cpp index 3fca89039..62a3d1609 100644 --- a/modules/pseudoclients/global.cpp +++ b/modules/pseudoclients/global.cpp @@ -1,6 +1,6 @@ /* Global core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -18,7 +18,7 @@ class MyGlobalService : public GlobalService { void ServerGlobal(const BotInfo *sender, Server *s, const Anope::string &message) { - if (s != Me && !s->HasFlag(SERVER_JUPED)) + if (s != Me && !s->IsJuped()) s->Notice(sender, message); for (unsigned i = 0, j = s->GetLinks().size(); i < j; ++i) this->ServerGlobal(sender, s->GetLinks()[i], message); @@ -53,31 +53,35 @@ class GlobalCore : public Module { this->SetAuthor("Anope"); - BotInfo *bi = BotInfo::Find(Config->Global); - if (!bi) + Global = BotInfo::Find(Config->Global); + if (!Global) throw ModuleException("No bot named " + Config->Global); - Implementation i[] = { I_OnRestart, I_OnShutdown, I_OnNewServer, I_OnPreHelp }; + Implementation i[] = { I_OnBotDelete, I_OnRestart, I_OnShutdown, I_OnNewServer, I_OnPreHelp }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - - Service::AddAlias("BotInfo", "Global", bi->nick); } ~GlobalCore() { - Service::DelAlias("BotInfo", "Global"); + Global = NULL; + } + + void OnBotDelete(BotInfo *bi) anope_override + { + if (bi == Global) + Global = NULL; } void OnRestart() anope_override { if (Config->GlobalOnCycle) - GlobalService->SendGlobal(Global, "", Config->GlobalOnCycleMessage); + this->myglobalservice.SendGlobal(Global, "", Config->GlobalOnCycleMessage); } void OnShutdown() anope_override { if (Config->GlobalOnCycle) - GlobalService->SendGlobal(Global, "", Config->GlobalOnCycleMessage); + this->myglobalservice.SendGlobal(Global, "", Config->GlobalOnCycleMessage); } void OnNewServer(Server *s) anope_override diff --git a/modules/pseudoclients/global.h b/modules/pseudoclients/global.h index f776e73e3..fccd96558 100644 --- a/modules/pseudoclients/global.h +++ b/modules/pseudoclients/global.h @@ -14,8 +14,5 @@ class GlobalService : public Service virtual void SendGlobal(const BotInfo *sender, const Anope::string &source, const Anope::string &message) = 0; }; -static ServiceReference<GlobalService> GlobalService("GlobalService", "Global"); -static ServiceReference<BotInfo> Global("BotInfo", "Global"); - #endif // GLOBAL_H diff --git a/modules/pseudoclients/hostserv.cpp b/modules/pseudoclients/hostserv.cpp index 6f101720b..f11526e7a 100644 --- a/modules/pseudoclients/hostserv.cpp +++ b/modules/pseudoclients/hostserv.cpp @@ -1,6 +1,6 @@ /* HostServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -23,19 +23,23 @@ class HostServCore : public Module if (!IRCD || !IRCD->CanSetVHost) throw ModuleException("Your IRCd does not support vhosts"); - BotInfo *bi = BotInfo::Find(Config->HostServ); - if (!bi) + HostServ = BotInfo::Find(Config->HostServ); + if (!HostServ) throw ModuleException("No bot named " + Config->HostServ); - Implementation i[] = { I_OnNickIdentify, I_OnNickUpdate, I_OnPreHelp }; + Implementation i[] = { I_OnBotDelete, I_OnNickIdentify, I_OnNickUpdate, I_OnPreHelp }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - - Service::AddAlias("BotInfo", "HostServ", bi->nick); } ~HostServCore() { - Service::DelAlias("BotInfo", "HostServ"); + HostServ = NULL; + } + + void OnBotDelete(BotInfo *bi) anope_override + { + if (bi == HostServ) + HostServ = NULL; } void OnNickIdentify(User *u) anope_override diff --git a/modules/pseudoclients/hostserv.h b/modules/pseudoclients/hostserv.h deleted file mode 100644 index cfadca806..000000000 --- a/modules/pseudoclients/hostserv.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef HOSTSERV_H -#define HOSTSERV_H - -static ServiceReference<BotInfo> HostServ("BotInfo", "HostServ"); - -#endif // HOSTSERV_H diff --git a/modules/pseudoclients/memoserv.cpp b/modules/pseudoclients/memoserv.cpp index ff8d11602..73dd48b94 100644 --- a/modules/pseudoclients/memoserv.cpp +++ b/modules/pseudoclients/memoserv.cpp @@ -1,6 +1,6 @@ /* MemoServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -21,13 +21,15 @@ static bool SendMemoMail(NickCore *nc, MemoInfo *mi, Memo *m) subject = subject.replace_all_cs("%n", nc->display); subject = subject.replace_all_cs("%s", m->sender); - subject = subject.replace_all_cs("%d", mi->GetIndex(m)); + subject = subject.replace_all_cs("%d", stringify(mi->GetIndex(m) + 1)); subject = subject.replace_all_cs("%t", m->text); + subject = subject.replace_all_cs("%N", Config->NetworkName); message = message.replace_all_cs("%n", nc->display); message = message.replace_all_cs("%s", m->sender); - message = message.replace_all_cs("%d", mi->GetIndex(m)); + message = message.replace_all_cs("%d", stringify(mi->GetIndex(m) + 1)); message = message.replace_all_cs("%t", m->text); + message = message.replace_all_cs("%N", Config->NetworkName); return Mail::Send(nc, subject, message); } @@ -37,30 +39,10 @@ class MyMemoServService : public MemoServService public: MyMemoServService(Module *m) : MemoServService(m) { } - MemoInfo *GetMemoInfo(const Anope::string &target, bool &ischan) anope_override - { - if (!target.empty() && target[0] == '#') - { - ischan = true; - ChannelInfo *ci = ChannelInfo::Find(target); - if (ci != NULL) - return &ci->memos; - } - else - { - ischan = false; - NickAlias *na = NickAlias::Find(target); - if (na != NULL) - return &na->nc->memos; - } - - return NULL; - } - MemoResult Send(const Anope::string &source, const Anope::string &target, const Anope::string &message, bool force) anope_override { bool ischan; - MemoInfo *mi = this->GetMemoInfo(target, ischan); + MemoInfo *mi = MemoInfo::GetMemoInfo(target, ischan); if (mi == NULL) return MEMO_INVALID_TARGET; @@ -87,7 +69,7 @@ class MyMemoServService : public MemoServService m->sender = source; m->time = Anope::CurTime; m->text = message; - m->SetFlag(MF_UNREAD); + m->unread = true; FOREACH_MOD(I_OnMemoSend, OnMemoSend(source, target, mi, m)); @@ -97,13 +79,13 @@ class MyMemoServService : public MemoServService if (ci->c) { - for (CUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it) + for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it) { - UserContainer *cu = *it; + ChanUserContainer *cu = *it; if (ci->AccessFor(cu->user).HasPriv("MEMO")) { - if (cu->user->Account() && cu->user->Account()->HasFlag(NI_MEMO_RECEIVE)) + if (cu->user->Account() && cu->user->Account()->HasExt("MEMO_RECEIVE")) cu->user->SendMessage(MemoServ, MEMO_NEW_X_MEMO_ARRIVED, ci->name.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->MemoServ.c_str(), ci->name.c_str(), mi->memos->size()); } } @@ -113,13 +95,11 @@ class MyMemoServService : public MemoServService { NickCore *nc = NickAlias::Find(target)->nc; - if (nc->HasFlag(NI_MEMO_RECEIVE)) + if (nc->HasExt("MEMO_RECEIVE")) { - for (std::list<Serialize::Reference<NickAlias> >::const_iterator it = nc->aliases.begin(), it_end = nc->aliases.end(); it != it_end;) + for (unsigned i = 0; i < nc->aliases->size(); ++i) { - const NickAlias *na = *it++; - if (!na) - continue; + const NickAlias *na = nc->aliases->at(i); User *user = User::Find(na->nick); if (user && user->IsIdentified()) user->SendMessage(MemoServ, MEMO_NEW_MEMO_ARRIVED, source.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->MemoServ.c_str(), mi->memos->size()); @@ -127,7 +107,7 @@ class MyMemoServService : public MemoServService } /* let's get out the mail if set in the nickcore - certus */ - if (nc->HasFlag(NI_MEMO_MAIL)) + if (nc->HasExt("MEMO_MAIL")) SendMemoMail(nc, mi, m); } @@ -142,7 +122,7 @@ class MyMemoServService : public MemoServService unsigned i = 0, end = nc->memos.memos->size(), newcnt = 0; for (; i < end; ++i) - if (nc->memos.GetMemo(i)->HasFlag(MF_UNREAD)) + if (nc->memos.GetMemo(i)->unread) ++newcnt; if (newcnt > 0) u->SendMessage(MemoServ, newcnt == 1 ? _("You have 1 new memo.") : _("You have %d new memos."), newcnt); @@ -165,19 +145,23 @@ class MemoServCore : public Module { this->SetAuthor("Anope"); - BotInfo *bi = BotInfo::Find(Config->MemoServ); - if (!bi) + MemoServ = BotInfo::Find(Config->MemoServ); + if (!MemoServ) throw ModuleException("No bot named " + Config->MemoServ); - Implementation i[] = { I_OnNickIdentify, I_OnJoinChannel, I_OnUserAway, I_OnNickUpdate, I_OnPreHelp, I_OnPostHelp }; + Implementation i[] = { I_OnBotDelete, I_OnNickIdentify, I_OnJoinChannel, I_OnUserAway, I_OnNickUpdate, I_OnPreHelp, I_OnPostHelp }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - - Service::AddAlias("BotInfo", "MemoServ", bi->nick); } ~MemoServCore() { - Service::DelAlias("BotInfo", "MemoServ"); + MemoServ = NULL; + } + + void OnBotDelete(BotInfo *bi) anope_override + { + if (bi == MemoServ) + MemoServ = NULL; } void OnNickIdentify(User *u) anope_override diff --git a/modules/pseudoclients/memoserv.h b/modules/pseudoclients/memoserv.h index bd88fffd4..71ca064de 100644 --- a/modules/pseudoclients/memoserv.h +++ b/modules/pseudoclients/memoserv.h @@ -14,13 +14,6 @@ class MemoServService : public Service MemoServService(Module *m) : Service(m, "MemoServService", "MemoServ") { } - /** Retrieve the memo info for a nick or channel - * @param target Target - * @param ischan Set to true if target is a channel - * @return A memoinfo structure or NULL - */ - virtual MemoInfo *GetMemoInfo(const Anope::string &target, bool &ischan) = 0; - /** Sends a memo. * @param source The source of the memo, can be anythin. * @param target The target of the memo, nick or channel. @@ -35,8 +28,5 @@ class MemoServService : public Service virtual void Check(User *u) = 0; }; -static ServiceReference<MemoServService> MemoServService("MemoServService", "MemoServ"); -static ServiceReference<BotInfo> MemoServ("BotInfo", "MemoServ"); - #endif // MEMOSERV_H diff --git a/modules/pseudoclients/nickserv.cpp b/modules/pseudoclients/nickserv.cpp index 0efb1d261..7b1ccd80c 100644 --- a/modules/pseudoclients/nickserv.cpp +++ b/modules/pseudoclients/nickserv.cpp @@ -1,6 +1,6 @@ /* NickServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -74,7 +74,7 @@ class MyNickServService : public NickServService if (!na) return; - if (na->nc->HasFlag(NI_SUSPENDED)) + if (na->nc->HasExt("SUSPENDED")) { u->SendMessage(NickServ, NICK_X_SUSPENDED, u->nick.c_str()); u->Collide(na); @@ -89,7 +89,7 @@ class MyNickServService : public NickServService return; } - if (!na->nc->HasFlag(NI_SECURE) && u->IsRecognized()) + if (!na->nc->HasExt("SECURE") && u->IsRecognized()) { na->last_seen = Anope::CurTime; Anope::string last_usermask = u->GetIdent() + "@" + u->GetDisplayedHost(); @@ -101,22 +101,22 @@ class MyNickServService : public NickServService if (Config->NoNicknameOwnership) return; - if (u->IsRecognized(false) || !na->nc->HasFlag(NI_KILL_IMMED)) + if (u->IsRecognized(false) || !na->nc->HasExt("KILL_IMMED")) { - if (na->nc->HasFlag(NI_SECURE)) + if (na->nc->HasExt("SECURE")) u->SendMessage(NickServ, NICK_IS_SECURE, Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str()); else u->SendMessage(NickServ, NICK_IS_REGISTERED, Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str()); } - if (na->nc->HasFlag(NI_KILLPROTECT) && !u->IsRecognized(false)) + if (na->nc->HasExt("KILLPROTECT") && !u->IsRecognized(false)) { - if (na->nc->HasFlag(NI_KILL_IMMED)) + if (na->nc->HasExt("KILL_IMMED")) { u->SendMessage(NickServ, FORCENICKCHANGE_NOW); u->Collide(na); } - else if (na->nc->HasFlag(NI_KILL_QUICK)) + else if (na->nc->HasExt("KILL_QUICK")) { u->SendMessage(NickServ, _("If you do not change within %s, I will change your nick."), Anope::Duration(Config->NSKillQuick, u->Account()).c_str()); new NickServCollide(u, Config->NSKillQuick); @@ -129,6 +129,14 @@ class MyNickServService : public NickServService } } + + void Login(User *user, NickAlias *na) anope_override + { + const NickAlias *u_na = NickAlias::Find(user->nick); + user->Login(na->nc); + if (u_na && *u_na->nc == *na->nc && !Config->NoNicknameOwnership && na->nc->HasExt("UNCONFIRMED") == false) + user->SetMode(NickServ, "REGISTERED"); + } }; class ExpireCallback : public CallBack @@ -147,17 +155,17 @@ class ExpireCallback : public CallBack ++it; User *u = User::Find(na->nick); - if (u && (na->nc->HasFlag(NI_SECURE) ? u->IsIdentified(true) : u->IsRecognized())) + if (u && (na->nc->HasExt("SECURE") ? u->IsIdentified(true) : u->IsRecognized())) na->last_seen = Anope::CurTime; bool expire = false; - if (na->nc->HasFlag(NI_UNCONFIRMED)) + if (na->nc->HasExt("UNCONFIRMED")) if (Config->NSUnconfirmedExpire && Anope::CurTime - na->time_registered >= Config->NSUnconfirmedExpire) expire = true; if (Config->NSExpire && Anope::CurTime - na->last_seen >= Config->NSExpire) expire = true; - if (na->HasFlag(NS_NO_EXPIRE)) + if (na->HasExt("NO_EXPIRE")) expire = false; FOREACH_MOD(I_OnPreNickExpire, OnPreNickExpire(na, expire)); @@ -165,11 +173,11 @@ class ExpireCallback : public CallBack if (expire) { Anope::string extra; - if (na->nc->HasFlag(NI_SUSPENDED)) + if (na->nc->HasExt("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)); - na->Destroy(); + delete na; } } } @@ -185,20 +193,24 @@ class NickServCore : public Module { this->SetAuthor("Anope"); - BotInfo *bi = BotInfo::Find(Config->NickServ); - if (!bi) + NickServ = BotInfo::Find(Config->NickServ); + if (!NickServ) throw ModuleException("No bot named " + Config->NickServ); - Implementation i[] = { I_OnDelNick, I_OnDelCore, I_OnChangeCoreDisplay, I_OnNickIdentify, I_OnNickGroup, - I_OnNickUpdate, I_OnUserNickChange, I_OnPreHelp, I_OnPostHelp, I_OnUserConnect }; + Implementation i[] = { I_OnBotDelete, I_OnDelNick, I_OnDelCore, I_OnChangeCoreDisplay, I_OnNickIdentify, I_OnNickGroup, + I_OnNickUpdate, I_OnUserConnect, I_OnPostUserLogoff, I_OnServerSync, I_OnUserNickChange, I_OnPreHelp, I_OnPostHelp }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); - - Service::AddAlias("BotInfo", "NickServ", bi->nick); } ~NickServCore() { - Service::DelAlias("BotInfo", "NickServ"); + NickServ = NULL; + } + + void OnBotDelete(BotInfo *bi) anope_override + { + if (bi == NickServ) + NickServ = NULL; } void OnDelNick(NickAlias *na) anope_override @@ -207,7 +219,7 @@ class NickServCore : public Module if (u && u->Account() == na->nc) { IRCD->SendLogout(u); - u->RemoveMode(NickServ, UMODE_REGISTERED); + u->RemoveMode(NickServ, "REGISTERED"); u->Logout(); } } @@ -221,7 +233,7 @@ class NickServCore : public Module { User *user = *it++; IRCD->SendLogout(user); - user->RemoveMode(NickServ, UMODE_REGISTERED); + user->RemoveMode(NickServ, "REGISTERED"); user->Logout(); FOREACH_MOD(I_OnNickLogout, OnNickLogout(user)); } @@ -238,14 +250,14 @@ class NickServCore : public Module if (!Config->NoNicknameOwnership) { const NickAlias *this_na = NickAlias::Find(u->nick); - if (this_na && this_na->nc == u->Account() && u->Account()->HasFlag(NI_UNCONFIRMED) == false) - u->SetMode(NickServ, UMODE_REGISTERED); + if (this_na && this_na->nc == u->Account() && u->Account()->HasExt("UNCONFIRMED") == false) + u->SetMode(NickServ, "REGISTERED"); } if (Config->NSModeOnID) - for (UChannelList::iterator it = u->chans.begin(), it_end = u->chans.end(); it != it_end; ++it) + for (User::ChanUserList::iterator it = u->chans.begin(), it_end = u->chans.end(); it != it_end; ++it) { - ChannelContainer *cc = *it; + ChanUserContainer *cc = *it; Channel *c = cc->chan; if (c) c->SetCorrectModes(u, true, true); @@ -264,7 +276,7 @@ class NickServCore : public Module "any third-party person."), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str()); } - if (u->Account()->HasFlag(NI_UNCONFIRMED)) + if (u->Account()->HasExt("UNCONFIRMED")) { u->SendMessage(NickServ, _("Your email address is not confirmed. To confirm it, follow the instructions that were emailed to you when you registered.")); const NickAlias *this_na = NickAlias::Find(u->Account()->display); @@ -276,29 +288,58 @@ class NickServCore : public Module void OnNickGroup(User *u, NickAlias *target) anope_override { - if (target->nc->HasFlag(NI_UNCONFIRMED) == false) - u->SetMode(NickServ, UMODE_REGISTERED); + if (target->nc->HasExt("UNCONFIRMED") == false) + u->SetMode(NickServ, "REGISTERED"); } void OnNickUpdate(User *u) anope_override { - for (UChannelList::iterator it = u->chans.begin(), it_end = u->chans.end(); it != it_end; ++it) + for (User::ChanUserList::iterator it = u->chans.begin(), it_end = u->chans.end(); it != it_end; ++it) { - ChannelContainer *cc = *it; + ChanUserContainer *cc = *it; Channel *c = cc->chan; if (c) c->SetCorrectModes(u, true, true); } } - void OnUserNickChange(User *u, const Anope::string &oldnick) anope_override + void OnUserConnect(User *u, bool &exempt) anope_override { + if (u->Quitting() || !u->server->IsSynced()) + return; + const NickAlias *na = NickAlias::Find(u->nick); + if (!Config->NoNicknameOwnership && !Config->NSUnregisteredNotice.empty() && !na) + u->SendMessage(NickServ, Config->NSUnregisteredNotice); + else if (na) + this->mynickserv.Validate(u); + } + + void OnPostUserLogoff(User *u) anope_override + { + NickAlias *na = NickAlias::Find(u->nick); + if (na) + na->OnCancel(u); + } + + void OnServerSync(Server *s) anope_override + { + for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it) + { + User *u = it->second; + if (u->server == s && !u->IsIdentified()) + this->mynickserv.Validate(u); + } + } + + void OnUserNickChange(User *u, const Anope::string &oldnick) anope_override + { + NickAlias *old_na = NickAlias::Find(oldnick), *na = NickAlias::Find(u->nick); /* If the new nick isnt registerd or its registerd and not yours */ if (!na || na->nc != u->Account()) { /* Remove +r, but keep an account associated with the user */ - u->RemoveMode(NickServ, UMODE_REGISTERED); + u->RemoveMode(NickServ, "REGISTERED"); this->mynickserv.Validate(u); } @@ -306,28 +347,38 @@ class NickServCore : public Module { /* Reset +r and re-send account (even though it really should be set at this point) */ IRCD->SendLogin(u); - if (!Config->NoNicknameOwnership && na->nc == u->Account() && na->nc->HasFlag(NI_UNCONFIRMED) == false) - u->SetMode(NickServ, UMODE_REGISTERED); + if (!Config->NoNicknameOwnership && na->nc == u->Account() && na->nc->HasExt("UNCONFIRMED") == false) + u->SetMode(NickServ, "REGISTERED"); Log(NickServ) << u->GetMask() << " automatically identified for group " << u->Account()->display; } + + if (!u->nick.equals_ci(oldnick) && old_na) + old_na->OnCancel(u); } - void OnUserModeSet(User *u, UserModeName Name) anope_override + void OnUserModeSet(User *u, const Anope::string &mname) anope_override { - if (Name == UMODE_REGISTERED && !u->IsIdentified()) - u->RemoveMode(NickServ, Name); + if (mname == "REGISTERED" && !u->IsIdentified()) + u->RemoveMode(NickServ, mname); } EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override { if (!params.empty() || source.c || source.service->nick != Config->NickServ) return EVENT_CONTINUE; - source.Reply(_("\002%s\002 allows you to \"register\" a nickname and\n" - "prevent others from using it. The following\n" - "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 %s \037command\037\002.\n "), Config->NickServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str(), source.command.c_str()); + if (!Config->NoNicknameOwnership) + source.Reply(_("\002%s\002 allows you to register a nickname and\n" + "prevent others from using it. The following\n" + "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 %s \037command\037\002.\n "), Config->NickServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str(), source.command.c_str()); + else + source.Reply(_("\002%s\002 allows you to register an account.\n" + "The following commands allow for registration and maintenance of\n" + "accounts; to use them, type \002%s%s \037command\037\002.\n" + "For more information on a specific command, type\n" + "\002%s%s %s \037command\037\002.\n "), Config->NickServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str(), source.command.c_str()); return EVENT_CONTINUE; } @@ -342,7 +393,7 @@ class NickServCore : public Module "any nickname.")); if (Config->NSExpire >= 86400) source.Reply(_(" \n" - "Nicknames that are not used anymore are subject to \n" + "Accounts that are not used anymore are subject to \n" "the automatic expiration, i.e. they will be deleted\n" "after %d days if not used."), Config->NSExpire / 86400); source.Reply(_(" \n" @@ -353,12 +404,6 @@ class NickServCore : public Module "will result in, at minimum, loss of the abused\n" "nickname(s)."), Config->NickServ.c_str()); } - - void OnUserConnect(Reference<User> &u, bool &exempt) anope_override - { - if (!Config->NoNicknameOwnership && !Config->NSUnregisteredNotice.empty() && u && !NickAlias::Find(u->nick)) - u->SendMessage(NickServ, Config->NSUnregisteredNotice); - } }; MODULE_INIT(NickServCore) diff --git a/modules/pseudoclients/nickserv.h b/modules/pseudoclients/nickserv.h index 3115ebc79..63923de2b 100644 --- a/modules/pseudoclients/nickserv.h +++ b/modules/pseudoclients/nickserv.h @@ -7,10 +7,8 @@ class NickServService : public Service NickServService(Module *m) : Service(m, "NickServService", "NickServ") { } virtual void Validate(User *u) = 0; + virtual void Login(User *u, NickAlias *na) = 0; }; -static ServiceReference<NickServService> NickServService("NickServService", "NickServ"); -static ServiceReference<BotInfo> NickServ("BotInfo", "NickServ"); - #endif // NICKSERV_H diff --git a/modules/pseudoclients/operserv.cpp b/modules/pseudoclients/operserv.cpp index 5b61c3df9..10908ef03 100644 --- a/modules/pseudoclients/operserv.cpp +++ b/modules/pseudoclients/operserv.cpp @@ -1,6 +1,6 @@ /* OperServ core functions * - * (C) 2003-2012 Anope Team + * (C) 2003-2013 Anope Team * Contact us at team@anope.org * * Please read COPYING and README for further details. @@ -25,7 +25,7 @@ class SGLineManager : public XLineManager void OnExpire(const XLine *x) anope_override { - Log(OperServ, "expire/akill") << "AKILL on \2" << x->mask << "\2 has expired"; + Log(OperServ, "expire/akill") << "AKILL on \002" << x->mask << "\002 has expired"; } void Send(User *u, XLine *x) anope_override @@ -101,7 +101,7 @@ class SQLineManager : public XLineManager void OnExpire(const XLine *x) anope_override { - Log(OperServ, "expire/sqline") << "SQLINE on \2" << x->mask << "\2 has expired"; + Log(OperServ, "expire/sqline") << "SQLINE on \002" << x->mask << "\002 has expired"; } void Send(User *u, XLine *x) anope_override @@ -142,7 +142,7 @@ class SNLineManager : public XLineManager void OnExpire(const XLine *x) anope_override { - Log(OperServ, "expire/snline") << "SNLINE on \2" << x->mask << "\2 has expired"; + Log(OperServ, "expire/snline") << "SNLINE on \002" << x->mask << "\002 has expired"; } void Send(User *u, XLine *x) anope_override @@ -175,24 +175,22 @@ class OperServCore : public Module { this->SetAuthor("Anope"); - BotInfo *bi = BotInfo::Find(Config->OperServ); - if (!bi) + OperServ = BotInfo::Find(Config->OperServ); + if (!OperServ) throw ModuleException("No bot named " + Config->OperServ); - Implementation i[] = { I_OnBotPrivmsg, I_OnServerQuit, I_OnUserModeSet, I_OnUserModeUnset, I_OnUserConnect, I_OnUserNickChange, I_OnPreHelp }; + Implementation i[] = { I_OnBotDelete, I_OnBotPrivmsg, I_OnServerQuit, I_OnUserModeSet, I_OnUserModeUnset, I_OnUserConnect, I_OnUserNickChange, I_OnPreHelp }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); /* Yes, these are in this order for a reason. Most violent->least violent. */ XLineManager::RegisterXLineManager(&sglines); XLineManager::RegisterXLineManager(&sqlines); XLineManager::RegisterXLineManager(&snlines); - - Service::AddAlias("BotInfo", "OperServ", bi->nick); } ~OperServCore() { - Service::DelAlias("BotInfo", "OperServ"); + OperServ = NULL; this->sglines.Clear(); this->sqlines.Clear(); @@ -203,9 +201,15 @@ class OperServCore : public Module XLineManager::UnregisterXLineManager(&snlines); } + void OnBotDelete(BotInfo *bi) anope_override + { + if (bi == OperServ) + OperServ = NULL; + } + EventReturn OnBotPrivmsg(User *u, BotInfo *bi, Anope::string &message) anope_override { - if (Config->OSOpersOnly && !u->HasMode(UMODE_OPER) && bi->nick == Config->OperServ) + if (Config->OSOpersOnly && !u->HasMode("OPER") && bi->nick == Config->OperServ) { u->SendMessage(bi, ACCESS_DENIED); Log(OperServ, "bados") << "Denied access to " << Config->OperServ << " from " << u->GetMask() << " (non-oper)"; @@ -217,39 +221,37 @@ class OperServCore : public Module void OnServerQuit(Server *server) anope_override { - if (server->HasFlag(SERVER_JUPED)) + if (server->IsJuped()) Log(server, "squit", OperServ) << "Received SQUIT for juped server " << server->GetName(); } - void OnUserModeSet(User *u, UserModeName Name) anope_override + void OnUserModeSet(User *u, const Anope::string &mname) anope_override { - if (Name == UMODE_OPER) + if (mname == "OPER") Log(u, "oper", OperServ) << "is now an IRC operator."; } - void OnUserModeUnset(User *u, UserModeName Name) anope_override + void OnUserModeUnset(User *u, const Anope::string &mname) anope_override { - if (Name == UMODE_OPER) + if (mname == "OPER") Log(u, "oper", OperServ) << "is no longer an IRC operator"; } - void OnUserConnect(Reference<User> &u, bool &exempt) anope_override + void OnUserConnect(User *u, bool &exempt) anope_override { - if (u && !exempt) + if (!u->Quitting() && !exempt) XLineManager::CheckAll(u); } void OnUserNickChange(User *u, const Anope::string &oldnick) anope_override { - if (IRCD->CanSQLine && !u->HasMode(UMODE_OPER)) + if (IRCD->CanSQLine && !u->HasMode("OPER")) this->sqlines.CheckAllXLines(u); } - EventReturn OnCheckKick(User *u, ChannelInfo *ci, bool &kick) anope_override + EventReturn OnCheckKick(User *u, ChannelInfo *ci, Anope::string &mask, Anope::string &reason) anope_override { - if (this->sqlines.CheckChannel(ci->c)) - kick = true; - return EVENT_CONTINUE; + return this->sqlines.CheckChannel(ci->c) ? EVENT_STOP : EVENT_CONTINUE; } EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override diff --git a/modules/pseudoclients/operserv.h b/modules/pseudoclients/operserv.h deleted file mode 100644 index e1577db1d..000000000 --- a/modules/pseudoclients/operserv.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef OPERSERV_H -#define OPERSERV_H - -static ServiceReference<BotInfo> OperServ("BotInfo", "OperServ"); - -#endif // OPERSERV_H |