diff options
| author | Adam <Adam@anope.org> | 2015-10-27 18:57:37 -0400 |
|---|---|---|
| committer | Adam <Adam@anope.org> | 2015-10-27 18:58:48 -0400 |
| commit | 64dac60071fab652745a6e7a06cf6b7bdbbd3625 (patch) | |
| tree | f8f30161150451672b381f6370a8fdcab654bbb8 /modules | |
| parent | 162fdbe5815bbdf187f549fefac94ff476d72e62 (diff) | |
| parent | 830361e97d03c74e54cb1cf1bbf329dffdeb66f7 (diff) | |
Merge branch '2.0' into 2.1
Diffstat (limited to 'modules')
48 files changed, 846 insertions, 613 deletions
diff --git a/modules/commands/bs_bot.cpp b/modules/commands/bs_bot.cpp index 1ba22531e..726c02ab2 100644 --- a/modules/commands/bs_bot.cpp +++ b/modules/commands/bs_bot.cpp @@ -82,7 +82,10 @@ class CommandBSBot : public Command User *targ = User::Find(nick, true); if (targ) - targ->Kill(Me, "Nickname is reserved for services"); + { + source.Reply(_("\002{0}\002 is currently in use."), targ->nick); + return; + } ServiceBot *bi = new ServiceBot(nick, user, host, real); @@ -179,6 +182,13 @@ class CommandBSBot : public Command return; } + User *target = User::Find(nick, true); + if (target) + { + source.Reply(_("\002{0}\002 is currently in use."), target->nick); + return; + } + if (!nick.equals_ci(bi->nick)) { /* We check whether the nick is registered, and inform the user diff --git a/modules/commands/cs_access.cpp b/modules/commands/cs_access.cpp index 982d5763f..f8ecc6c38 100644 --- a/modules/commands/cs_access.cpp +++ b/modules/commands/cs_access.cpp @@ -704,7 +704,7 @@ class CommandCSLevels : public Command { const Anope::string &what = params[2]; - /* Don't allow disabling of the founder level. It would be hard to change it back if you dont have access to use this command */ + /* Don't allow disabling of the founder level. It would be hard to change it back if you don't have access to use this command */ if (what.equals_ci("FOUNDER")) { source.Reply(_("You can not disable the founder privilege because it would be impossible to reenable it at a later time.")); @@ -804,6 +804,14 @@ class CommandCSLevels : public Command return; } + bool has_access = false; + if (source.HasPriv("chanserv/access/modify")) + has_access = true; + else if (cmd.equals_ci("LIST") && source.HasPriv("chanserv/access/list")) + has_access = true; + else if (source.AccessFor(ci).HasPriv("FOUNDER")) + has_access = true; + /* If SET, we want two extra parameters; if DIS[ABLE] or FOUNDER, we want only * one; else, we want none. */ @@ -813,7 +821,7 @@ class CommandCSLevels : public Command return; } - if (!source.AccessFor(ci).HasPriv("FOUNDER") && !source.HasPriv("chanserv/access/modify")) + if (!has_access) { source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "FOUNDER", ci->GetName()); return; diff --git a/modules/commands/cs_ban.cpp b/modules/commands/cs_ban.cpp index a17ae48a0..f797eda0f 100644 --- a/modules/commands/cs_ban.cpp +++ b/modules/commands/cs_ban.cpp @@ -102,6 +102,9 @@ class CommandCSBan : public Command if (reason.length() > reasonmax) reason = reason.substr(0, reasonmax); + Anope::string signkickformat = Config->GetModule("chanserv")->Get<Anope::string>("signkickformat", "%m (%n)"); + signkickformat = signkickformat.replace_all_cs("%n", source.GetNick()); + User *u = source.GetUser(); User *u2 = User::Find(target, true); @@ -124,7 +127,7 @@ class CommandCSBan : public Command } /* - * Dont ban/kick the user on channels where he is excepted + * Don't ban/kick the user on channels where he is excepted * to prevent services <-> server wars. */ if (c->MatchesList(u2, "EXCEPT")) @@ -161,7 +164,10 @@ class CommandCSBan : public Command if (block->Get<bool>("kick", "yes")) { if (ci->HasFieldS("SIGNKICK") || (ci->HasFieldS("SIGNKICK_LEVEL") && !source.AccessFor(ci).HasPriv("SIGNKICK"))) - c->Kick(ci->WhoSends(), u2, "%s (%s)", reason.c_str(), source.GetNick().c_str()); + { + signkickformat = signkickformat.replace_all_cs("%m", reason); + c->Kick(ci->WhoSends(), u2, "%s", signkickformat.c_str()); + } else c->Kick(ci->WhoSends(), u2, "%s", reason.c_str()); } @@ -170,15 +176,18 @@ class CommandCSBan : public Command { bool founder = u_access.HasPriv("FOUNDER"); bool override = !founder && !u_access.HasPriv("BAN"); - Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "for " << target; - if (!c->HasMode(mode, target)) + Anope::string mask = IRCD->NormalizeMask(target); + + Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "for " << mask; + + if (!c->HasMode(mode, mask)) { - c->SetMode(NULL, mode, target); + c->SetMode(NULL, mode, mask); if (ban_time) { - new TempBan(ban_time, c, target, mode); - source.Reply(_("Ban on \002{0}\002 expires in \002{1}\002."), target, Anope::Duration(ban_time, source.GetAccount())); + new TempBan(ban_time, c, mask, mode); + source.Reply(_("Ban on \002{0}\002 expires in \002{1}\002."), mask, Anope::Duration(ban_time, source.GetAccount())); } } @@ -188,7 +197,8 @@ class CommandCSBan : public Command ChanUserContainer *uc = it->second; ++it; - if (Anope::Match(uc->user->nick, target) || Anope::Match(uc->user->GetDisplayedMask(), target)) + Entry e(mode, mask); + if (e.Matches(uc->user)) { ++matched; @@ -206,18 +216,23 @@ class CommandCSBan : public Command if (block->Get<bool>("kick", "yes")) { ++kicked; + if (ci->HasFieldS("SIGNKICK") || (ci->HasFieldS("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()); + { + reason += " (Matches " + mask + ")"; + signkickformat = signkickformat.replace_all_cs("%m", reason); + c->Kick(ci->WhoSends(), uc->user, "%s", signkickformat.c_str()); + } else - c->Kick(ci->WhoSends(), uc->user, "%s (Matches %s)", reason.c_str(), target.c_str()); + c->Kick(ci->WhoSends(), uc->user, "%s (Matches %s)", reason.c_str(), mask.c_str()); } } } if (matched) - source.Reply(_("Kicked \002{0}/{1}\002 users matching \002{2}\002 from \002{3}\002."), kicked, matched, target, c->name); + source.Reply(_("Kicked \002{0}/{1}\002 users matching \002{2}\002 from \002{3}\002."), kicked, matched, mask, c->name); else - source.Reply(_("No users on \002{0}\002 match \002{1}\002."), c->name, target); + source.Reply(_("No users on \002{0}\002 match \002{1}\002."), c->name, mask); } } diff --git a/modules/commands/cs_clone.cpp b/modules/commands/cs_clone.cpp index 69dc70bea..256446bd1 100644 --- a/modules/commands/cs_clone.cpp +++ b/modules/commands/cs_clone.cpp @@ -15,6 +15,20 @@ class CommandCSClone : public Command { +#if 0 + void CopyLevels(CommandSource &source, ChannelInfo *ci, ChannelInfo *target_ci) + { + const Anope::map<int16_t> &cilevels = ci->GetLevelEntries(); + + for (Anope::map<int16_t>::const_iterator it = cilevels.begin(); it != cilevels.end(); ++it) + { + target_ci->SetLevel(it->first, it->second); + } + + source.Reply(_("All level entries from \002%s\002 have been cloned into \002%s\002."), ci->name.c_str(), target_ci->name.c_str()); + } +#endif + public: CommandCSClone(Module *creator) : Command(creator, "chanserv/clone", 2, 3) { @@ -73,7 +87,7 @@ public: if (what.empty()) { - delete target_ci; + target_ci->Delete(); target_ci = ChanServ::channel.Create(); target_ci->SetName(target); ChanServ::registered_channel_map& map = ChanServ::service->GetChannels(); diff --git a/modules/commands/cs_entrymsg.cpp b/modules/commands/cs_entrymsg.cpp index 4a646b3b3..31253599e 100644 --- a/modules/commands/cs_entrymsg.cpp +++ b/modules/commands/cs_entrymsg.cpp @@ -138,7 +138,7 @@ class CommandEntryMessage : public Command msg->SetChannel(ci); msg->SetCreator(source.GetNick()); msg->SetMessage(message); - Log(source.IsFounder(ci) ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to add a message"; + Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to add a message"; source.Reply(_("Entry message added to \002{0}\002"), ci->GetName()); } @@ -157,8 +157,8 @@ class CommandEntryMessage : public Command unsigned i = convertTo<unsigned>(message); if (i > 0 && i <= messages.size()) { - delete messages[i - 1]; - Log(source.IsFounder(ci) ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to remove a message"; + messages[i - 1]->Delete(); + Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to remove a message"; source.Reply(_("Entry message \002{0}\002 for \002{1]\002 deleted."), i, ci->GetName()); } else @@ -176,7 +176,7 @@ class CommandEntryMessage : public Command for (EntryMsg *e : ci->GetRefs<EntryMsg *>(entrymsg)) delete e; - Log(source.IsFounder(ci) ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to remove all messages"; + Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to remove all messages"; source.Reply(_("Entry messages for \002{0}\002 have been cleared."), ci->GetName()); } @@ -207,7 +207,7 @@ class CommandEntryMessage : public Command return; } - if (!source.IsFounder(ci) && !source.HasPriv("chanserv/administration")) + if (!source.AccessFor(ci).HasPriv("SET") && !source.HasPriv("chanserv/administration")) { source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "FOUNDER", ci->GetName()); return; @@ -240,7 +240,7 @@ class CommandEntryMessage : public Command "\n" "The \002{0} CLEAR\002 command clears the entry message list.\n" "\n" - "Use of this command requires being the founder of \037channel\037."), + "Use of this command requires the \002SET\002 privilege on \037channel\037."), source.command); return true; } diff --git a/modules/commands/cs_kick.cpp b/modules/commands/cs_kick.cpp index 679ccfe06..89536df7f 100644 --- a/modules/commands/cs_kick.cpp +++ b/modules/commands/cs_kick.cpp @@ -50,6 +50,9 @@ class CommandCSKick : public Command ChanServ::AccessGroup u_access = source.AccessFor(ci); + Anope::string signkickformat = Config->GetModule("chanserv")->Get<Anope::string>("signkickformat", "%m (%n)"); + signkickformat = signkickformat.replace_all_cs("%n", source.GetNick()); + if (!u_access.HasPriv("KICK") && !source.HasPriv("chanserv/kick")) { source.Reply(_("Access denied. You do not have privilege \002{0}\002 on \002{1}\002."), "KICK", ci->GetName()); @@ -71,14 +74,19 @@ class CommandCSKick : public Command Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "for " << u2->nick; if (ci->HasFieldS("SIGNKICK") || (ci->HasFieldS("SIGNKICK_LEVEL") && !u_access.HasPriv("SIGNKICK"))) - c->Kick(ci->WhoSends(), u2, "%s (%s)", reason.c_str(), source.GetNick().c_str()); + { + signkickformat = signkickformat.replace_all_cs("%m", reason); + c->Kick(ci->WhoSends(), u2, "%s", signkickformat.c_str()); + } else c->Kick(ci->WhoSends(), u2, "%s", reason.c_str()); } } else if (u_access.HasPriv("FOUNDER")) { - Log(LOG_COMMAND, source, this, ci) << "for " << target; + Anope::string mask = IRCD->NormalizeMask(target); + + Log(LOG_COMMAND, source, this, ci) << "for " << mask; int matched = 0, kicked = 0; for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end;) @@ -86,7 +94,8 @@ class CommandCSKick : public Command ChanUserContainer *uc = it->second; ++it; - if (Anope::Match(uc->user->nick, target) || Anope::Match(uc->user->GetDisplayedMask(), target)) + Entry e("", mask); + if (e.Matches(uc->user)) { ++matched; @@ -97,17 +106,22 @@ class CommandCSKick : public Command continue; ++kicked; + if (ci->HasFieldS("SIGNKICK") || (ci->HasFieldS("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()); + { + reason += " (Matches " + mask + ")"; + signkickformat = signkickformat.replace_all_cs("%m", reason); + c->Kick(ci->WhoSends(), uc->user, "%s", signkickformat.c_str()); + } else - c->Kick(ci->WhoSends(), uc->user, "%s (Matches %s)", reason.c_str(), target.c_str()); + c->Kick(ci->WhoSends(), uc->user, "%s (Matches %s)", reason.c_str(), mask.c_str()); } } if (matched) - source.Reply(_("Kicked \002{0}/{1}\002 users matching \002{2}\002 from \002{3}\002."), kicked, matched, target, c->name); + source.Reply(_("Kicked \002{0}/{1}\002 users matching \002{2}\002 from \002{3}\002."), kicked, matched, mask, c->name); else - source.Reply(_("No users on\002{0}\002 match \002{1}\002."), c->name, target); + source.Reply(_("No users on\002{0}\002 match \002{1}\002."), c->name, mask); } else source.Reply(_("\002{0}\002 isn't currently in use."), target); diff --git a/modules/commands/cs_mode.cpp b/modules/commands/cs_mode.cpp index 67d1e5faa..121179a58 100644 --- a/modules/commands/cs_mode.cpp +++ b/modules/commands/cs_mode.cpp @@ -479,7 +479,7 @@ class CommandCSMode : public Command case '*': if (adding == -1 || !has_access) break; - for (unsigned j = 0; j < ModeManager::GetChannelModes().size(); ++j) + for (unsigned j = 0; j < ModeManager::GetChannelModes().size() && ci->c; ++j) { ChannelMode *cm = ModeManager::GetChannelModes()[j]; @@ -912,7 +912,7 @@ class CSMode : public Module } else if (cm->type == MODE_PARAM) { - /* If the channel doesnt have the mode, or it does and it isn't set correctly */ + /* If the channel doesn't have the mode, or it does and it isn't set correctly */ if (ml->GetSet()) { Anope::string param; @@ -947,16 +947,40 @@ class CSMode : public Module for (unsigned i = 0; i < mlock.length(); ++i) { if (mlock[i] == '+') + { add = true; - else if (mlock[i] == '-') + continue; + } + + if (mlock[i] == '-') + { add = false; - else + continue; + } + + ChannelMode *cm = ModeManager::FindChannelModeByChar(mlock[i]); + if (!cm) + continue; + + Anope::string param; + if (cm->type == MODE_PARAM) { - ChannelMode *cm = ModeManager::FindChannelModeByChar(mlock[i]); - Anope::string param; - if (cm && (cm->type == MODE_REGULAR || sep.GetToken(param))) - mlocks->SetMLock(ci, cm, add, param); + ChannelModeParam *cmp = anope_dynamic_static_cast<ChannelModeParam *>(cm); + if (add || !cmp->minus_no_arg) + { + sep.GetToken(param); + if (param.empty() || !cmp->IsValid(param)) + continue; + } } + else if (cm->type != MODE_REGULAR) + { + sep.GetToken(param); + if (param.empty()) + continue; + } + + mlocks->SetMLock(ci, cm, add, param); } } } diff --git a/modules/commands/cs_set.cpp b/modules/commands/cs_set.cpp index f7ee80050..06c996f52 100644 --- a/modules/commands/cs_set.cpp +++ b/modules/commands/cs_set.cpp @@ -850,7 +850,7 @@ class CommandCSSetSecureOps : public Command bool OnHelp(CommandSource &source, const Anope::string &) override { source.Reply(_("Enables or disables the \002secure ops\002 option for \037channel\037." - " When \002secure ops\002 is set, users will not be allowed to have channel operator status if they do not have the privileges to have it.")); + " When \002secure ops\002 is set, users will not be allowed to have channel operator status if they do not have the privileges for it.")); return true; } }; @@ -1066,13 +1066,11 @@ class CommandCSSetNoexpire : public Command class CSSet : public Module , public EventHook<Event::CreateChan> - , public EventHook<Event::ChannelCreate> , public EventHook<Event::ChannelSync> , public EventHook<Event::CheckKick> , public EventHook<Event::DelChan> , public EventHook<Event::ChannelModeSet> , public EventHook<Event::ChannelModeUnset> - , public EventHook<Event::CheckDelete> , public EventHook<Event::JoinChannel> , public EventHook<Event::SetCorrectModes> , public EventHook<ChanServ::Event::PreChanExpire> @@ -1097,6 +1095,8 @@ class CSSet : public Module CommandCSSetSuccessor commandcssetsuccessor; CommandCSSetNoexpire commandcssetnoexpire; + ExtensibleRef<bool> inhabit; + bool persist_lower_ts; public: @@ -1129,6 +1129,8 @@ class CSSet : public Module , commandcssetsignkick(this) , commandcssetsuccessor(this) , commandcssetnoexpire(this) + + , inhabit("inhabit") { } @@ -1142,18 +1144,13 @@ class CSSet : public Module ci->SetBanType(Config->GetModule(this)->Get<int>("defbantype", "2")); } - void OnChannelCreate(Channel *c) override + void OnChannelSync(Channel *c) override { if (c->ci && keep_modes.HasExt(c->ci)) for (ChanServ::Mode *m : c->ci->GetRefs<ChanServ::Mode *>(ChanServ::mode)) c->SetMode(c->ci->WhoSends(), m->GetMode(), m->GetParam()); } - void OnChannelSync(Channel *c) override - { - OnChannelCreate(c); - } - EventReturn OnCheckKick(User *u, Channel *c, Anope::string &mask, Anope::string &reason) override { if (!c->ci || !restricted.HasExt(c->ci) || c->MatchesList(u, "EXCEPT")) @@ -1180,7 +1177,7 @@ class CSSet : public Module if (mode->name == "PERM") persist.Set(c->ci, true); - if (mode->type != MODE_STATUS && !c->syncing && Me->IsSynced() && ChanServ::mode) + if (mode->type != MODE_STATUS && !c->syncing && Me->IsSynced() && ChanServ::mode && (!inhabit || !inhabit->HasExt(c))) { ChanServ::Mode *m = ChanServ::mode.Create(); m->SetChannel(c->ci); @@ -1200,7 +1197,7 @@ class CSSet : public Module persist.Unset(c->ci); } - if (c->ci && mode->type != MODE_STATUS && !c->syncing && Me->IsSynced()) + if (c->ci && mode->type != MODE_STATUS && !c->syncing && Me->IsSynced() && (!inhabit || !inhabit->HasExt(c))) for (ChanServ::Mode *m : c->ci->GetRefs<ChanServ::Mode *>(ChanServ::mode)) if (m->GetMode() == mode->name && m->GetParam().equals_ci(param)) m->Delete(); @@ -1208,13 +1205,6 @@ class CSSet : public Module return EVENT_CONTINUE; } - EventReturn OnCheckDelete(Channel *c) override - { - if (c->ci && persist.HasExt(c->ci)) - return EVENT_STOP; - return EVENT_CONTINUE; - } - void OnJoinChannel(User *u, Channel *c) override { if (persist_lower_ts && c->ci && persist.HasExt(c->ci) && c->creation_time > c->ci->GetTimeRegistered()) diff --git a/modules/commands/cs_topic.cpp b/modules/commands/cs_topic.cpp index 9e8b3764a..a132900a6 100644 --- a/modules/commands/cs_topic.cpp +++ b/modules/commands/cs_topic.cpp @@ -195,7 +195,7 @@ class CommandCSTopic : public Command " The \002APPEND\002 command appends the given topic to the existing topic.\n" "\n" "\002LOCK\002 and \002UNLOCK\002 may be used to enable and disable topic lock." - " When topic lock is set, the channel topic will be unchangeable except via this command.\n" + " When topic lock is set, the channel topic will be unchangeable by users who do not have the \002TOPIC\002 privilege.\n" "\n" "Use of this command requires the \002{0}\002 privilege on \037channel\037."), "TOPIC"); @@ -235,7 +235,7 @@ class CSTopic : public Module } } - void OnTopicUpdated(Channel *c, const Anope::string &user, const Anope::string &topic) override + void OnTopicUpdated(User *source, Channel *c, const Anope::string &user, const Anope::string &topic) override { if (!c->ci) return; @@ -245,7 +245,7 @@ class CSTopic : public Module * This desyncs what is really set with what we have stored, and we end up resetting the topic often when * it is not required */ - if (topiclock.HasExt(c->ci) && c->ci->GetLastTopic() != c->topic) + if (topiclock.HasExt(c->ci) && c->ci->GetLastTopic() != c->topic && (!source || !c->ci->AccessFor(source).HasPriv("TOPIC"))) { c->ChangeTopic(c->ci->GetLastTopicSetter(), c->ci->GetLastTopic(), c->ci->GetLastTopicTime()); } diff --git a/modules/commands/hs_del.cpp b/modules/commands/hs_del.cpp index 4d7e7aac9..b45c10a61 100644 --- a/modules/commands/hs_del.cpp +++ b/modules/commands/hs_del.cpp @@ -101,7 +101,8 @@ class HSDel : public Module , commandhsdelall(this, ondeletevhost) , ondeletevhost(this) { - + if (!IRCD || !IRCD->CanSetVHost) + throw ModuleException("Your IRCd does not support vhosts"); } }; diff --git a/modules/commands/hs_group.cpp b/modules/commands/hs_group.cpp index 8a7a208a6..c3971fdea 100644 --- a/modules/commands/hs_group.cpp +++ b/modules/commands/hs_group.cpp @@ -86,6 +86,8 @@ class HSGroup : public Module HSGroup(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR) , commandhsgroup(this) { + if (!IRCD || !IRCD->CanSetVHost) + throw ModuleException("Your IRCd does not support vhosts"); } void OnSetVhost(NickServ::Nick *na) override diff --git a/modules/commands/hs_list.cpp b/modules/commands/hs_list.cpp index f363c81f7..738f9f1bd 100644 --- a/modules/commands/hs_list.cpp +++ b/modules/commands/hs_list.cpp @@ -151,6 +151,8 @@ class HSList : public Module HSList(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR) , commandhslist(this) { + if (!IRCD || !IRCD->CanSetVHost) + throw ModuleException("Your IRCd does not support vhosts"); } }; |
