diff options
-rw-r--r-- | include/modules.h | 14 | ||||
-rw-r--r-- | src/channels.cpp | 18 | ||||
-rw-r--r-- | src/modules.cpp | 1 | ||||
-rw-r--r-- | src/modules/m_permchannels.cpp | 86 |
4 files changed, 109 insertions, 10 deletions
diff --git a/include/modules.h b/include/modules.h index 5529862f4..250613c9b 100644 --- a/include/modules.h +++ b/include/modules.h @@ -399,7 +399,7 @@ enum Implementation I_OnCheckKey, I_OnCheckLimit, I_OnCheckBan, I_OnStats, I_OnChangeLocalUserHost, I_OnChangeLocalUserGecos, I_OnLocalTopicChange, I_OnPostLocalTopicChange, I_OnEvent, I_OnRequest, I_OnOperCompre, I_OnGlobalOper, I_OnPostConnect, I_OnAddBan, I_OnDelBan, I_OnRawSocketAccept, I_OnRawSocketClose, I_OnRawSocketWrite, I_OnRawSocketRead, I_OnChangeLocalUserGECOS, I_OnUserRegister, - I_OnOperCompare, I_OnChannelDelete, I_OnPostOper, I_OnSyncOtherMetaData, I_OnSetAway, I_OnCancelAway, I_OnUserList, + I_OnOperCompare, I_OnChannelPreDelete, I_OnChannelDelete, I_OnPostOper, I_OnSyncOtherMetaData, I_OnSetAway, I_OnCancelAway, I_OnUserList, I_OnPostCommand, I_OnPostJoin, I_OnWhoisLine, I_OnBuildExemptList, I_OnRawSocketConnect, I_OnGarbageCollect, I_OnBufferFlushed, I_OnText, I_OnReadConfig, I_OnDownloadFile, I_END @@ -470,6 +470,12 @@ class CoreExport Module : public Extensible */ virtual void OnUserDisconnect(User* user); + /** Called whenever a channel is about to be deleted + * @param chan The channel being deleted + * @return An integer specifying whether or not the channel may be deleted. 0 for yes, 1 for no. + */ + virtual int OnChannelPreDelete(Channel *chan); + /** Called whenever a channel is deleted, either by QUIT, KICK or PART. * @param chan The channel being deleted */ @@ -900,12 +906,6 @@ class CoreExport Module : public Extensible */ virtual void OnDelLine(User* source, XLine* line); - /** Called whenever a zline is deleted. - * This method is triggered after the line is deleted. - * @param source The user removing the line - * @param hostmask The hostmask to delete - */ - /** Called before your module is unloaded to clean up Extensibles. * This method is called once for every user and channel on the network, * so that when your module unloads it may clear up any remaining data diff --git a/src/channels.cpp b/src/channels.cpp index 115afea52..c28ca23de 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -482,7 +482,11 @@ long Channel::PartUser(User *user, const char* reason) /* kill the record */ if (iter != ServerInstance->chanlist->end()) { - FOREACH_MOD(I_OnChannelDelete,OnChannelDelete(this)); + int MOD_RESULT = 0; + FOREACH_RESULT_I(ServerInstance,I_OnChannelPreDelete, OnChannelPreDelete(this)); + if (MOD_RESULT == 1) + return 1; // delete halted by module + FOREACH_MOD(I_OnChannelDelete, OnChannelDelete(this)); ServerInstance->chanlist->erase(iter); } return 0; @@ -528,7 +532,11 @@ long Channel::ServerKickUser(User* user, const char* reason, bool triggerevents) /* kill the record */ if (iter != ServerInstance->chanlist->end()) { - FOREACH_MOD(I_OnChannelDelete,OnChannelDelete(this)); + int MOD_RESULT = 0; + FOREACH_RESULT_I(ServerInstance,I_OnChannelPreDelete, OnChannelPreDelete(this)); + if (MOD_RESULT == 1) + return 1; // delete halted by module + FOREACH_MOD(I_OnChannelDelete, OnChannelDelete(this)); ServerInstance->chanlist->erase(iter); } return 0; @@ -606,7 +614,11 @@ long Channel::KickUser(User *src, User *user, const char* reason) /* kill the record */ if (iter != ServerInstance->chanlist->end()) { - FOREACH_MOD(I_OnChannelDelete,OnChannelDelete(this)); + int MOD_RESULT = 0; + FOREACH_RESULT_I(ServerInstance,I_OnChannelPreDelete, OnChannelPreDelete(this)); + if (MOD_RESULT == 1) + return 1; // delete halted by module + FOREACH_MOD(I_OnChannelDelete, OnChannelDelete(this)); ServerInstance->chanlist->erase(iter); } return 0; diff --git a/src/modules.cpp b/src/modules.cpp index 0ee715b27..87fd393f8 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -180,6 +180,7 @@ void Module::OnChangeName(User*, const std::string&) { } void Module::OnAddLine(User*, XLine*) { } void Module::OnDelLine(User*, XLine*) { } void Module::OnCleanup(int, void*) { } +int Module::OnChannelPreDelete(Channel*) { return 0; } void Module::OnChannelDelete(Channel*) { } void Module::OnSetAway(User*) { } void Module::OnCancelAway(User*) { } diff --git a/src/modules/m_permchannels.cpp b/src/modules/m_permchannels.cpp new file mode 100644 index 000000000..857593d02 --- /dev/null +++ b/src/modules/m_permchannels.cpp @@ -0,0 +1,86 @@ +/* +------------------------------------+ + * | Inspire Internet Relay Chat Daemon | + * +------------------------------------+ + * + * InspIRCd: (C) 2002-2007 InspIRCd Development Team + * See: http://www.inspircd.org/wiki/index.php/Credits + * + * This program is free but copyrighted software; see + * the file COPYING for details. + * + * --------------------------------------------------- + */ + +#include "inspircd.h" + +/* $ModDesc: Provides support for channel mode +P to provide permanent channels */ + + +/** Handles the +P channel mode + */ +class PermChannel : public ModeHandler +{ + public: + PermChannel(InspIRCd* Instance) : ModeHandler(Instance, 'P', 0, 0, false, MODETYPE_CHANNEL, false) { } + + ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string ¶meter, bool adding) + { + if (adding) + { + if (!channel->IsModeSet('P')) + { + channel->SetMode('P',true); + return MODEACTION_ALLOW; + } + } + else + { + if (channel->IsModeSet('P')) + { + channel->SetMode('P',false); + return MODEACTION_ALLOW; + } + } + + return MODEACTION_DENY; + } +}; + +class ModulePermanentChannels : public Module +{ + PermChannel *p; +public: + + ModulePermanentChannels(InspIRCd* Me) : Module(Me) + { + p = new PermChannel(ServerInstance); + if (!ServerInstance->AddMode(p)) + { + delete p; + throw ModuleException("Could not add new modes!"); + } + Implementation eventlist[] = { I_OnChannelPreDelete }; + ServerInstance->Modules->Attach(eventlist, this, 1); + } + + virtual ~ModulePermanentChannels() + { + ServerInstance->Modes->DelMode(p); + delete p; + } + + virtual Version GetVersion() + { + return Version(1,1,0,0,VF_COMMON|VF_VENDOR,API_VERSION); + } + + virtual int OnChannelPreDelete(Channel *c) + { + if (c->IsModeSet('P')) + return 1; + + return 0; + } +}; + +MODULE_INIT(ModulePermanentChannels) |