From 86e43f1f144cfd04b039a844959af1f7aec3e6da Mon Sep 17 00:00:00 2001 From: Adam- Date: Wed, 11 Nov 2009 02:47:05 +0000 Subject: Added support for permanent channels. This supports both permanent channel modes and the ability to have BotServ bots stay in the channel to keep it open. git-svn-id: http://anope.svn.sourceforge.net/svnroot/anope/trunk@2638 5417fbe8-f217-4b02-8779-1006273d7864 --- src/core/bs_unassign.c | 8 +++-- src/core/cs_info.c | 1 + src/core/cs_register.c | 10 ++++++ src/core/cs_set.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 97 insertions(+), 4 deletions(-) (limited to 'src/core') diff --git a/src/core/bs_unassign.c b/src/core/bs_unassign.c index 6b8a89eba..25a5c2ada 100644 --- a/src/core/bs_unassign.c +++ b/src/core/bs_unassign.c @@ -15,8 +15,6 @@ #include "module.h" -int do_unassign(User * u); - class CommandBSUnassign : public Command { public: @@ -28,6 +26,7 @@ class CommandBSUnassign : public Command { const char *chan = params[0].c_str(); ChannelInfo *ci = cs_findchan(chan); + ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_PERM); if (readonly) notice_lang(s_BotServ, u, BOT_ASSIGN_READONLY); @@ -35,7 +34,10 @@ class CommandBSUnassign : public Command notice_lang(s_BotServ, u, ACCESS_DENIED); else if (!ci->bi) notice_help(s_BotServ, u, BOT_NOT_ASSIGNED); - else { + else if (ci->HasFlag(CI_PERSIST) && !cm) + notice_help(s_BotServ, u, BOT_UNASSIGN_PERSISTANT_CHAN); + else + { ci->bi->UnAssign(u, ci); notice_lang(s_BotServ, u, BOT_UNASSIGN_UNASSIGNED, ci->name); } diff --git a/src/core/cs_info.c b/src/core/cs_info.c index 52699b515..6d89ada02 100644 --- a/src/core/cs_info.c +++ b/src/core/cs_info.c @@ -118,6 +118,7 @@ class CommandCSInfo : public Command CheckOptStr(optbuf, CI_SIGNKICK_LEVEL, getstring(u, CHAN_INFO_OPT_SIGNKICK), ci, u->nc); CheckOptStr(optbuf, CI_TOPICLOCK, getstring(u, CHAN_INFO_OPT_TOPICLOCK), ci, u->nc); CheckOptStr(optbuf, CI_XOP, getstring(u, CHAN_INFO_OPT_XOP), ci, u->nc); + CheckOptStr(optbuf, CI_PERSIST, getstring(u, CHAN_INFO_OPT_PERSIST), ci, u->nc); notice_lang(s_ChanServ, u, CHAN_INFO_OPTIONS, optbuf.empty() ? getstring(u, CHAN_INFO_OPT_NONE) : optbuf.c_str()); notice_lang(s_ChanServ, u, CHAN_INFO_MODE_LOCK, get_mlock_modes(ci, 1)); diff --git a/src/core/cs_register.c b/src/core/cs_register.c index e6ccde8cf..0ea7e58dc 100644 --- a/src/core/cs_register.c +++ b/src/core/cs_register.c @@ -86,6 +86,16 @@ class CommandCSRegister : public Command else if ((cm = ModeManager::FindChannelModeByName(CMODE_PROTECT))) ircdproto->SendMode(findbot(s_ChanServ), chan, "+%c %s", cm->ModeChar, u->nick); + /* Mark the channel as persistant */ + if (c->HasMode(CMODE_PERM)) + ci->SetFlag(CI_PERSIST); + /* Persist may be in def cflags, set it here */ + else if (ci->HasFlag(CI_PERSIST) && (cm = ModeManager::FindChannelModeByName(CMODE_PERM))) + { + ircdproto->SendMode(whosends(ci), chan, "+%c", cm->ModeChar); + ci->SetFlag(CI_PERSIST); + } + FOREACH_MOD(I_OnChanRegistered, OnChanRegistered(ci)); } return MOD_CONT; diff --git a/src/core/cs_set.c b/src/core/cs_set.c index 48eef2ba9..96c8ae35c 100644 --- a/src/core/cs_set.c +++ b/src/core/cs_set.c @@ -498,6 +498,82 @@ class CommandCSSet : public Command return MOD_CONT; } + CommandReturn DoSetPersist(User *u, ChannelInfo *ci, const char *param) + { + ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_PERM); + + if (!stricmp(param, "ON")) + { + if (!ci->HasFlag(CI_PERSIST)) + { + ci->SetFlag(CI_PERSIST); + + /* Channel doesn't exist, create it internally */ + if (!ci->c) + { + chan_create(ci->name, time(NULL)); + if (ci->bi) + bot_join(ci); + } + + /* No botserv bot, no channel mode */ + if (!ci->bi && !cm) + { + /* Give them ChanServ + * Yes, this works fine with no s_BotServ + */ + findbot(s_ChanServ)->Assign(NULL, ci); + } + + /* Set the perm mode */ + if (cm && ci->c && !ci->c->HasMode(CMODE_PERM)) + { + ci->c->SetMode(CMODE_PERM); + ircdproto->SendMode(whosends(ci), ci->c->name, "+%c", cm->ModeChar); + } + } + + notice_lang(s_ChanServ, u, CHAN_SET_PERSIST_ON, ci->name); + } + else if (!stricmp(param, "OFF")) + { + if (ci->HasFlag(CI_PERSIST)) + { + ci->UnsetFlag(CI_PERSIST); + + /* Unset perm mode */ + if (ci->c && ci->c->HasMode(CMODE_PERM)) + { + ircdproto->SendMode(whosends(ci), ci->c->name, "-%c", cm->ModeChar); + ci->c->RemoveMode(CMODE_PERM); + } + /* Persist is set off... remove the bot and delete the channel if its empty */ + else if (ci->c) + { + if (s_BotServ && ci->bi && ci->c->usercount == BSMinUsers - 1) + ircdproto->SendPart(ci->bi, ci->c->name, NULL); + if (!ci->c->users) + chan_delete(ci->c); + + /* No channel mode, no BotServ, but using ChanServ as the botserv bot + * which was assigned when persist was set on + */ + if (!cm && !s_BotServ && ci->bi) + { + /* Unassign bot */ + findbot(s_ChanServ)->UnAssign(NULL, ci); + } + } + } + + notice_lang(s_ChanServ, u, CHAN_SET_PERSIST_OFF, ci->name); + } + else + syntax_error(s_ChanServ, u, "SET PERSIST", CHAN_SET_PERSIST_SYNTAX); + + return MOD_CONT; + } + CommandReturn DoSetNoExpire(User * u, ChannelInfo * ci, const char *param) { if (!u->nc->HasCommand("chanserv/set/noexpire")) @@ -593,7 +669,9 @@ class CommandCSSet : public Command } } else if (cmd == "PEACE") { DoSetPeace(u, ci, param); - } else if (cmd == "NOEXPIRE") { + } else if (cmd == "PERSIST") + DoSetPersist(u, ci, param); + else if (cmd == "NOEXPIRE") { DoSetNoExpire(u, ci, param); } else { notice_lang(s_ChanServ, u, CHAN_SET_UNKNOWN_OPTION, cmd.c_str()); @@ -648,6 +726,8 @@ class CommandCSSet : public Command notice_help(s_ChanServ, u, CHAN_HELP_SET_XOP); else if (subcommand == "PEACE") notice_help(s_ChanServ, u, CHAN_HELP_SET_PEACE); + else if (subcommand == "PERSIST") + notice_help(s_ChanServ, u, CHAN_HELP_SET_PERSIST); else if (subcommand == "NOEXPIRE") notice_help(s_ChanServ, u, CHAN_SERVADMIN_HELP_SET_NOEXPIRE); else -- cgit