summaryrefslogtreecommitdiff
path: root/src/modes.cpp
diff options
context:
space:
mode:
authorAdam- <Adam-@5417fbe8-f217-4b02-8779-1006273d7864>2009-10-13 21:26:38 +0000
committerAdam- <Adam-@5417fbe8-f217-4b02-8779-1006273d7864>2009-10-13 21:26:38 +0000
commitd3d64c27b199622c90075d6f59dd08e44acbb378 (patch)
tree68029e10dc754271235e2a4e3d04b3fb19ddd15c /src/modes.cpp
parent1fd66851320e239b531720c27614a5ad4c604c97 (diff)
Complete rewrite of everything associated with modes, this breaks saving and reading mlocked modes from the databases until the new databases are implemented
git-svn-id: http://anope.svn.sourceforge.net/svnroot/anope/trunk@2560 5417fbe8-f217-4b02-8779-1006273d7864
Diffstat (limited to 'src/modes.cpp')
-rw-r--r--src/modes.cpp364
1 files changed, 364 insertions, 0 deletions
diff --git a/src/modes.cpp b/src/modes.cpp
new file mode 100644
index 000000000..948eee97f
--- /dev/null
+++ b/src/modes.cpp
@@ -0,0 +1,364 @@
+/* Mode support
+ *
+ * (C) 2009 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * $Id$
+ *
+ */
+
+#include "services.h"
+
+std::map<char, UserMode *> ModeManager::UserModesByChar;
+std::map<UserModeName, UserMode *> ModeManager::UserModesByName;
+/* Channel modes */
+std::map<char, ChannelMode *> ModeManager::ChannelModesByChar;
+std::map<ChannelModeName, ChannelMode *> ModeManager::ChannelModesByName;
+/* Although there are two different maps for UserModes and ChannelModes
+ * the pointers in each are the same. This is used to increase
+ * efficiency.
+ */
+
+/** Add a user mode to Anope
+ * @param Mode The mode
+ * @param um A UserMode or UserMode derived class
+ * @return true on success, false on error
+ */
+bool ModeManager::AddUserMode(char Mode, UserMode *um)
+{
+ bool ret = ModeManager::UserModesByChar.insert(std::make_pair(Mode, um)).second;
+ if (ret)
+ ret = ModeManager::UserModesByName.insert(std::make_pair(um->Name, um)).second;
+
+ return ret;
+}
+
+/** Add a channel mode to Anope
+ * @param Mode The mode
+ * @param cm A ChannelMode or ChannelMode derived class
+ * @return true on success, false on error
+ */
+bool ModeManager::AddChannelMode(char Mode, ChannelMode *cm)
+{
+ bool ret = ModeManager::ChannelModesByChar.insert(std::make_pair(Mode, cm)).second;
+ if (ret)
+ ret = ModeManager::ChannelModesByName.insert(std::make_pair(cm->Name, cm)).second;
+
+ return ret;
+}
+
+/** Find a channel mode
+ * @param Mode The mode
+ * @return The mode class
+ */
+ChannelMode *ModeManager::FindChannelModeByChar(char Mode)
+{
+ std::map<char, ChannelMode *>::iterator it = ModeManager::ChannelModesByChar.find(Mode);
+
+ if (it != ModeManager::ChannelModesByChar.end())
+ {
+ return it->second;
+ }
+
+ return NULL;
+}
+
+/** Find a user mode
+ * @param Mode The mode
+ * @return The mode class
+ */
+UserMode *ModeManager::FindUserModeByChar(char Mode)
+{
+ std::map<char, UserMode *>::iterator it = ModeManager::UserModesByChar.find(Mode);
+
+ if (it != ModeManager::UserModesByChar.end())
+ {
+ return it->second;
+ }
+
+ return NULL;
+}
+
+/** Find a channel mode
+ * @param Mode The modename
+ * @return The mode class
+ */
+ChannelMode *ModeManager::FindChannelModeByName(ChannelModeName Name)
+{
+ std::map<ChannelModeName, ChannelMode *>::iterator it = ModeManager::ChannelModesByName.find(Name);
+
+ if (it != ModeManager::ChannelModesByName.end())
+ {
+ return it->second;
+ }
+
+ return NULL;
+}
+
+/** Find a user mode
+ * @param Mode The modename
+ * @return The mode class
+ */
+UserMode *ModeManager::FindUserModeByName(UserModeName Name)
+{
+ std::map<UserModeName, UserMode *>::iterator it = ModeManager::UserModesByName.find(Name);
+
+ if (it != ModeManager::UserModesByName.end())
+ {
+ return it->second;
+ }
+
+ return NULL;
+}
+
+/** Gets the channel mode char for a symbol (eg + returns v)
+ * @param Value The symbol
+ * @return The char
+ */
+char ModeManager::GetStatusChar(char Value)
+{
+ std::map<char, ChannelMode *>::iterator it;
+ ChannelMode *cm;
+ ChannelModeStatus *cms;
+
+ for (it = ModeManager::ChannelModesByChar.begin(); it != ModeManager::ChannelModesByChar.end(); ++it)
+ {
+ cm = it->second;
+
+ if (cm->Type == MODE_STATUS)
+ {
+ cms = static_cast<ChannelModeStatus *>(cm);
+
+ if (Value == cms->Symbol)
+ {
+ return it->first;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/** Is the key valid
+ * @param value The key
+ * @return true or false
+ */
+bool ChannelModeKey::IsValid(const char *value)
+{
+ if (value && *value != ':' && !strchr(value, ','))
+ return true;
+
+ return false;
+}
+
+/** Can admin only mode be set by the user
+ * @param u The user - can be NULL if defcon is checking
+ * @return true or false
+ */
+bool ChannelModeAdmin::CanSet(User *u)
+{
+ if (u && is_oper(u))
+ return true;
+
+ return false;
+}
+
+/** Can oper only mode be set by the user
+ * @param u The user - can be NULL if defcon is checking
+ * @return true or false
+ */
+bool ChannelModeOper::CanSet(User *u)
+{
+ if (u && is_oper(u))
+ return true;
+
+ return false;
+}
+
+/** Can the user set the registerd mode?
+ * No.
+ * @return false
+ */
+bool ChannelModeRegistered::CanSet(User *u)
+{
+ return false;
+}
+
+/** Add a ban to the channel
+ * @param chan The channel
+ * @param mask The ban
+ */
+void ChannelModeBan::AddMask(Channel *chan, const char *mask)
+{
+ Entry *ban;
+
+ /* check for NULL values otherwise we will segfault */
+ if (!chan || !mask)
+ {
+ if (debug)
+ alog("debug: add_ban called with NULL values");
+ return;
+ }
+
+ /* Check if the list already exists, if not create it.
+ * Create a new ban and add it to the list.. ~ Viper */
+ if (!chan->bans)
+ chan->bans = list_create();
+ ban = entry_add(chan->bans, mask);
+
+ if (!ban)
+ fatal("Creating new ban entry failed");
+
+ /* Check whether it matches a botserv bot after adding internally
+ * and parsing it through cidr support. ~ Viper */
+ if (s_BotServ && BSSmartJoin && chan->ci && chan->ci->bi
+ && chan->usercount >= BSMinUsers)
+ {
+ BotInfo *bi = chan->ci->bi;
+
+ if (entry_match(ban, bi->nick, bi->user, bi->host, 0))
+ {
+ ircdproto->SendMode(bi, chan->name, "-b %s", mask);
+ entry_delete(chan->bans, ban);
+ return;
+ }
+ }
+
+ if (debug)
+ alog("debug: Added ban %s to channel %s", mask, chan->name);
+}
+
+/** Remove a ban from the channel
+ * @param chan The channel
+ * @param mask The ban
+ */
+void ChannelModeBan::DelMask(Channel *chan, const char *mask)
+{
+ AutoKick *akick;
+ Entry *ban;
+
+ /* Sanity check as it seems some IRCD will just send -b without a mask */
+ if (!mask || !chan->bans || (chan->bans->count == 0))
+ return;
+
+ ban = elist_find_mask(chan->bans, mask);
+
+ if (ban)
+ {
+ entry_delete(chan->bans, ban);
+
+ if (debug)
+ alog("debug: Deleted ban %s from channel %s", mask,
+ chan->name);
+ }
+
+ if (chan->ci && (akick = is_stuck(chan->ci, mask)))
+ stick_mask(chan->ci, akick);
+
+}
+
+/** Add an except to the channel
+ * @param chan The channel
+ * @param mask The except
+ */
+void ChannelModeExcept::AddMask(Channel *chan, const char *mask)
+{
+ Entry *exception;
+
+ if (!chan || !mask)
+ {
+ if (debug)
+ alog("debug: add_exception called with NULL values");
+ return;
+ }
+
+ /* Check if the list already exists, if not create it.
+ * Create a new exception and add it to the list.. ~ Viper */
+ if (!chan->excepts)
+ chan->excepts = list_create();
+ exception = entry_add(chan->excepts, mask);
+
+ if (!exception)
+ fatal("Creating new exception entry failed");
+
+ if (debug)
+ alog("debug: Added except %s to channel %s", mask, chan->name);
+}
+
+/** Remove an except from the channel
+ * @param chan The channel
+ * @param mask The except
+ */
+void ChannelModeExcept::DelMask(Channel *chan, const char *mask)
+{
+ Entry *exception;
+
+ /* Sanity check as it seems some IRCD will just send -e without a mask */
+ if (!mask || !chan->excepts || (chan->excepts->count == 0))
+ return;
+
+ exception = elist_find_mask(chan->excepts, mask);
+
+ if (exception)
+ {
+ entry_delete(chan->excepts, exception);
+
+ if (debug)
+ alog("debug: Deleted except %s to channel %s", mask, chan->name);
+ }
+}
+
+/** Add an invex to the channel
+ * @param chan The channel
+ * @param mask The invex
+ */
+void ChannelModeInvite::AddMask(Channel *chan, const char *mask)
+{
+ Entry *invite;
+
+ if (!chan || !mask)
+ {
+ if (debug)
+ alog("debug: add_invite called with NULL values");
+ return;
+ }
+
+ /* Check if the list already exists, if not create it.
+ * Create a new invite and add it to the list.. ~ Viper */
+ if (!chan->invites)
+ chan->invites = list_create();
+ invite = entry_add(chan->invites, mask);
+
+ if (!invite)
+ fatal("Creating new exception entry failed");
+
+ if (debug)
+ alog("debug: Added invite %s to channel %s", mask, chan->name);
+
+}
+
+/** Remove an invex from the channel
+ * @param chan The channel
+ * @param mask The index
+ */
+void ChannelModeInvite::DelMask(Channel *chan, const char *mask)
+{
+ Entry *invite;
+
+ /* Sanity check as it seems some IRCD will just send -I without a mask */
+ if (!mask || !chan->invites || (chan->invites->count == 0))
+ return;
+
+ invite = elist_find_mask(chan->invites, mask);
+
+ if (invite)
+ {
+ entry_delete(chan->invites, invite);
+
+ if (debug)
+ alog("debug: Deleted invite %s to channel %s", mask,
+ chan->name);
+ }
+}