summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/channels.cpp4
-rw-r--r--src/language.cpp19
-rw-r--r--src/regchannel.cpp47
3 files changed, 67 insertions, 3 deletions
diff --git a/src/channels.cpp b/src/channels.cpp
index 6e1e25f23..72e573029 100644
--- a/src/channels.cpp
+++ b/src/channels.cpp
@@ -566,7 +566,7 @@ void Channel::SetMode(BotInfo *bi, ChannelMode *cm, const Anope::string &param,
else if (cm->Type == MODE_STATUS)
{
User *u = finduser(param);
- if (u && HasUserStatus(u, debug_cast<ChannelModeStatus *>(cm)))
+ if (!u || HasUserStatus(u, debug_cast<ChannelModeStatus *>(cm)))
return;
}
else if (cm->Type == MODE_LIST)
@@ -607,7 +607,7 @@ void Channel::RemoveMode(BotInfo *bi, ChannelMode *cm, const Anope::string &para
else if (cm->Type == MODE_STATUS)
{
User *u = finduser(param);
- if (u && !HasUserStatus(u, debug_cast<ChannelModeStatus *>(cm)))
+ if (!u || !HasUserStatus(u, debug_cast<ChannelModeStatus *>(cm)))
return;
}
else if (cm->Type == MODE_LIST)
diff --git a/src/language.cpp b/src/language.cpp
index a49508d0c..4a89ac626 100644
--- a/src/language.cpp
+++ b/src/language.cpp
@@ -1322,6 +1322,16 @@ const char *const language_strings[LANG_STRING_COUNT] = {
_("All users have been kicked from channel %s."),
/* CHAN_CLEARED_INVITES */
_("All invites on channel %s have been removed."),
+ /* CHAN_CLONED */
+ _("All settings from \002%s\002 have been transferred to \002%s\002"),
+ /* CHAN_CLONED_ACCESS */
+ _("All access entries from \002%s\002 have been transferred to \002%s\002"),
+ /* CHAN_CLONED_AKICK */
+ _("All akick entries from \002%s\002 have been transferred to \002%s\002"),
+ /* CHAN_CLONED_BADWORDS */
+ _("All badword entries from \002%s\002 have been transferred to \002%s\002"),
+ /* CHAN_CLONE_SYNTAX */
+ _("CLONE \037channel\037 \037target\037"),
/* CHAN_GETKEY_SYNTAX */
_("GETKEY channel"),
/* CHAN_GETKEY_NOKEY */
@@ -3354,6 +3364,8 @@ const char *const language_strings[LANG_STRING_COUNT] = {
_(" PROTECT Protects a selected nick on a channel"),
/* CHAN_HELP_CMD_DEOP */
_(" DEOP Deops a selected nick on a channel"),
+ /* CHAN_HELP_CMD_CLONE */
+ _(" CLONE Copy all settings from one channel to another"),
/* CHAN_HELP */
_("%S allows you to register and control various\n"
"aspects of channels. %S can often prevent\n"
@@ -4131,6 +4143,13 @@ const char *const language_strings[LANG_STRING_COUNT] = {
_("Syntax: GETKEY channel\n"
" \n"
"Returns the key of the given channel."),
+ /* CHAN_HELP_CLONE */
+ _("Syntax: \002CLONE \037channel\037 \037target\037 [all | access | akick | badwords]\002\n"
+ " \n"
+ "Copies all settings, access, akicks, etc from channel to the\n"
+ "target channel. If access, akick, or badwords is specified then only\n"
+ "the respective settings are transferred. You must have founder level\n"
+ "access to \037channel\037 and \037target\037."),
/* CHAN_SERVADMIN_HELP */
_(" \n"
"Services Operators can also drop any channel without needing\n"
diff --git a/src/regchannel.cpp b/src/regchannel.cpp
index b4cded05b..b4c42cb82 100644
--- a/src/regchannel.cpp
+++ b/src/regchannel.cpp
@@ -52,7 +52,7 @@ ChannelInfo::ChannelInfo(const Anope::string &chname)
this->memos.memomax = Config->MSMaxMemos;
this->last_used = this->time_registered = Anope::CurTime;
- this->ttb = new int16[2 * TTB_SIZE];
+ this->ttb = new int16[TTB_SIZE];
for (int i = 0; i < TTB_SIZE; ++i)
this->ttb[i] = 0;
@@ -61,6 +61,51 @@ ChannelInfo::ChannelInfo(const Anope::string &chname)
RegisteredChannelList[this->name] = this;
}
+/** Copy constructor
+ * @param ci The ChannelInfo to copy settings to
+ */
+ChannelInfo::ChannelInfo(ChannelInfo *ci)
+{
+ *this = *ci;
+
+ if (this->founder)
+ ++this->founder->channelcount;
+
+ this->access.clear();
+ this->akick.clear();
+ this->badwords.clear();
+
+ if (this->bi)
+ ++this->bi->chancount;
+
+ this->ttb = new int16[TTB_SIZE];
+ for (int i = 0; i < TTB_SIZE; ++i)
+ this->ttb[i] = ci->ttb[i];
+
+ this->levels = new int16[CA_SIZE];
+ for (int i = 0; i < CA_SIZE; ++i)
+ this->levels[i] = ci->levels[i];
+
+ for (unsigned i = 0; i < ci->GetAccessCount(); ++i)
+ {
+ ChanAccess *access = ci->GetAccess(i);
+ this->AddAccess(access->nc, access->level, access->creator, access->last_seen);
+ }
+ for (unsigned i = 0; i < ci->GetAkickCount(); ++i)
+ {
+ AutoKick *akick = ci->GetAkick(i);
+ if (akick->HasFlag(AK_ISNICK))
+ this->AddAkick(akick->creator, akick->nc, akick->reason, akick->addtime, akick->last_used);
+ else
+ this->AddAkick(akick->creator, akick->mask, akick->reason, akick->addtime, akick->last_used);
+ }
+ for (unsigned i = 0; i < ci->GetBadWordCount(); ++i)
+ {
+ BadWord *bw = ci->GetBadWord(i);
+ this->AddBadWord(bw->word, bw->type);
+ }
+}
+
/** Default destructor, cleans up the channel complete and removes it from the internal list
*/
ChannelInfo::~ChannelInfo()