diff options
author | Adam <Adam@anope.org> | 2010-11-15 18:03:50 -0500 |
---|---|---|
committer | Adam <Adam@anope.org> | 2010-12-12 19:33:58 -0500 |
commit | 1625a5af0ce1368e46705a2f72578eda463f3650 (patch) | |
tree | 37b2783e32684aebc879d17f05dcf276f799beaa /modules/core/cs_clone.cpp | |
parent | 2e9a632e1410fbeadc1b7a0418cf66247e0e458c (diff) |
Added /chanserv clone command
Diffstat (limited to 'modules/core/cs_clone.cpp')
-rw-r--r-- | modules/core/cs_clone.cpp | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/modules/core/cs_clone.cpp b/modules/core/cs_clone.cpp new file mode 100644 index 000000000..a6568290c --- /dev/null +++ b/modules/core/cs_clone.cpp @@ -0,0 +1,181 @@ +/* ChanServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + */ + +/*************************************************************************/ + +#include "module.h" + +class CommandCSClone : public Command +{ +public: + CommandCSClone() : Command("CLONE", 2, 3) + { + } + + CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms) + { + const Anope::string &channel = params[0]; + const Anope::string &target = params[1]; + Anope::string what = params.size() > 2 ? params[2] : ""; + + ChannelInfo *ci = cs_findchan(channel); + if (!check_access(u, ci, CA_SET)) + { + u->SendMessage(ChanServ, ACCESS_DENIED); + return MOD_CONT; + } + ChannelInfo *target_ci = cs_findchan(target); + if (!target_ci) + { + u->SendMessage(ChanServ, CHAN_X_NOT_REGISTERED, target.c_str()); + return MOD_CONT; + } + if (!IsFounder(u, ci) || !IsFounder(u, target_ci)) + { + u->SendMessage(ChanServ, ACCESS_DENIED); + return MOD_CONT; + } + + if (Config->CSMaxReg && u->Account()->channelcount >= Config->CSMaxReg && !u->Account()->HasPriv("chanserv/no-register-limit")) + { + u->SendMessage(ChanServ, u->Account()->channelcount > Config->CSMaxReg ? CHAN_EXCEEDED_CHANNEL_LIMIT : CHAN_REACHED_CHANNEL_LIMIT, Config->CSMaxReg); + return MOD_CONT; + } + + if (what.equals_ci("ALL")) + what.clear(); + + if (what.empty()) + { + delete target_ci; + target_ci = new ChannelInfo(ci); + target_ci->name = target; + RegisteredChannelList[target_ci->name] = target_ci; + target_ci->c = findchan(target_ci->name); + if (target_ci->c) + { + target_ci->c->ci = target_ci; + + check_modes(target_ci->c); + + ChannelMode *cm; + if (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))) + target_ci->c->SetMode(NULL, cm, u->nick); + else if ((cm = ModeManager::FindChannelModeByName(CMODE_PROTECT))) + target_ci->c->RemoveMode(NULL, cm, u->nick); + } + + /* Mark the channel as persistant */ + if (target_ci->c->HasMode(CMODE_PERM)) + target_ci->SetFlag(CI_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); + + if (target_ci->bi && target_ci->c->FindUser(target_ci->bi) == NULL) + target_ci->bi->Join(target_ci->c); + } + + if (target_ci->c && !target_ci->c->topic.empty()) + { + target_ci->last_topic = target_ci->c->topic; + target_ci->last_topic_setter = target_ci->c->topic_setter; + target_ci->last_topic_time = target_ci->c->topic_time; + } + else + target_ci->last_topic_setter = Config->s_ChanServ; + + FOREACH_MOD(I_OnChanRegistered, OnChanRegistered(target_ci)); + + u->SendMessage(ChanServ, CHAN_CLONED, channel.c_str(), target.c_str()); + } + else if (what.equals_ci("ACCESS")) + { + target_ci->ClearAccess(); + for (unsigned i = 0; i < ci->GetAccessCount(); ++i) + { + ChanAccess *access = ci->GetAccess(i); + target_ci->AddAccess(access->nc, access->level, access->creator, access->last_seen); + } + + u->SendMessage(ChanServ, CHAN_CLONED_ACCESS, channel.c_str(), target.c_str()); + } + else if (what.equals_ci("AKICK")) + { + target_ci->ClearAkick(); + for (unsigned i = 0; i < ci->GetAkickCount(); ++i) + { + AutoKick *akick = ci->GetAkick(i); + if (akick->HasFlag(AK_ISNICK)) + 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); + } + + u->SendMessage(ChanServ, CHAN_CLONED_AKICK, channel.c_str(), target.c_str()); + } + else if (what.equals_ci("BADWORDS")) + { + target_ci->ClearBadWords(); + for (unsigned i = 0; i < ci->GetBadWordCount(); ++i) + { + BadWord *bw = ci->GetBadWord(i); + target_ci->AddBadWord(bw->word, bw->type); + } + + u->SendMessage(ChanServ, CHAN_CLONED_BADWORDS, channel.c_str(), target.c_str()); + } + else + { + this->OnSyntaxError(u, ""); + return MOD_CONT; + } + + Log(LOG_COMMAND, u, this, ci) << "to clone it to " << target_ci->name; + + return MOD_CONT; + } + + bool OnHelp(User *u, const Anope::string &subcommand) + { + u->SendMessage(ChanServ, CHAN_HELP_CLONE); + return true; + } + + void OnSyntaxError(User *u, const Anope::string &subcommand) + { + SyntaxError(ChanServ, u, "CLONE", CHAN_CLONE_SYNTAX); + } + + void OnServHelp(User *u) + { + u->SendMessage(ChanServ, CHAN_HELP_CMD_CLONE); + } +}; + +class CSClone : public Module +{ + CommandCSClone commandcsclone; + + public: + CSClone(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetType(CORE); + + this->AddCommand(ChanServ, &commandcsclone); + } +}; + +MODULE_INIT(CSClone) |