diff options
-rw-r--r-- | docs/inspircd.conf.example | 11 | ||||
-rw-r--r-- | include/modules.h | 2 | ||||
-rw-r--r-- | include/users.h | 12 | ||||
-rw-r--r-- | src/channels.cpp | 3 | ||||
-rw-r--r-- | src/mode.cpp | 19 | ||||
-rw-r--r-- | src/modules/m_hideoper.cpp | 2 | ||||
-rw-r--r-- | src/modules/m_namesx.cpp | 6 | ||||
-rw-r--r-- | src/users.cpp | 13 |
8 files changed, 63 insertions, 5 deletions
diff --git a/docs/inspircd.conf.example b/docs/inspircd.conf.example index d43d484a9..9691153ea 100644 --- a/docs/inspircd.conf.example +++ b/docs/inspircd.conf.example @@ -1487,6 +1487,17 @@ #<module name="m_inviteexception.so"> #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# +# Invisible module - Adds support for usermode +Q (quiet) which lets an +# oper go 'invisible' similar to unrealircd 3.1's +I mode. Note that +# opers are still able to see invisible users, and if an oper with +Q +# deopers, they will become visible. +# +# IMPORTANT NOTE: To allow this mode to be used by a type of oper, you +# must first add the value canquiet="yes" to that oper's type tag. +# +#<module name="m_invisible.so"> + +#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# # Join flood module: Adds support for join flood protection (+j) #<module name="m_joinflood.so"> diff --git a/include/modules.h b/include/modules.h index 7655517ea..51eb5a19b 100644 --- a/include/modules.h +++ b/include/modules.h @@ -75,7 +75,7 @@ enum MessageType { * ipv4 servers, so this value will be ten times as * high on ipv6 servers. */ -#define NATIVE_API_VERSION 11020 +#define NATIVE_API_VERSION 11021 #ifdef IPV6 #define API_VERSION (NATIVE_API_VERSION * 10) #else diff --git a/include/users.h b/include/users.h index 0b5bc467f..84bde46b9 100644 --- a/include/users.h +++ b/include/users.h @@ -247,6 +247,16 @@ typedef std::vector<ConnectClass> ClassVector; typedef std::map<chanrec*, char> UserChanList; typedef UserChanList::iterator UCListIter; +class userrec; + +class VisData +{ + public: + VisData(); + virtual ~VisData(); + virtual bool VisibleTo(userrec* user); +}; + /** Holds all information about a user * This class stores all information about a user connected to the irc server. Everything about a * connection is stored here primarily, from the user's socket ID (file descriptor) through to the @@ -308,6 +318,8 @@ class userrec : public connection */ UserResolver* res_reverse; + VisData* Visibility; + /** Stored reverse lookup from res_forward */ std::string stored_host; diff --git a/src/channels.cpp b/src/channels.cpp index 23aeb32a1..00f8dbce6 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -838,6 +838,9 @@ void chanrec::UserList(userrec *user) continue; } + if (i->second->Visibility && !i->second->Visibility->VisibleTo(user)) + continue; + size_t ptrlen = snprintf(ptr, MAXBUF, "%s%s ", this->GetPrefixChar(i->second), i->second->nick); curlen += ptrlen; diff --git a/src/mode.cpp b/src/mode.cpp index 7a31038a6..8f74f92bf 100644 --- a/src/mode.cpp +++ b/src/mode.cpp @@ -490,6 +490,7 @@ void ModeParser::Process(const char** parameters, int pcnt, userrec *user, bool for (ModeWatchIter watchers = modewatchers[handler_id].begin(); watchers != modewatchers[handler_id].end(); watchers++) { + ServerInstance->Log(DEBUG,"Call mode watcher"); if ((*watchers)->BeforeMode(user, targetuser, targetchannel, parameter, adding, type) == false) { abort = true; @@ -506,13 +507,28 @@ void ModeParser::Process(const char** parameters, int pcnt, userrec *user, bool if (abort) continue; } + else + { + /* Fix by brain: mode watchers not being called for parameterless modes */ + for (ModeWatchIter watchers = modewatchers[handler_id].begin(); watchers != modewatchers[handler_id].end(); watchers++) + { + if ((*watchers)->BeforeMode(user, targetuser, targetchannel, parameter, adding, type) == false) + { + abort = true; + break; + } + } + + if (abort) + continue; + } /* It's an oper only mode, check if theyre an oper. If they arent, * eat any parameter that came with the mode, and continue to next */ if ((IS_LOCAL(user)) && (modehandlers[handler_id]->NeedsOper()) && (!*user->oper)) { - user->WriteServ("481 %s :Permission Denied- Only IRC operators may %sset %s mode %c", user->nick, + user->WriteServ("481 %s :Permission Denied - Only IRC operators may %sset %s mode %c", user->nick, adding ? "" : "un", type == MODETYPE_CHANNEL ? "channel" : "user", modehandlers[handler_id]->GetModeChar()); continue; @@ -925,6 +941,7 @@ bool ModeParser::AddModeWatcher(ModeWatcher* mw) pos = (mw->GetModeChar()-65) | mask; modewatchers[pos].push_back(mw); + return true; } diff --git a/src/modules/m_hideoper.cpp b/src/modules/m_hideoper.cpp index 43bfef445..364771398 100644 --- a/src/modules/m_hideoper.cpp +++ b/src/modules/m_hideoper.cpp @@ -23,7 +23,7 @@ class HideOper : public ModeHandler { public: - HideOper(InspIRCd* Instance) : ModeHandler(Instance, 'H', 0, 0, false, MODETYPE_USER, true) { } + HideOper(InspIRCd* Instance) : ModeHandler(Instance, 'H', 0, 'o', false, MODETYPE_USER, true) { } ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding) { diff --git a/src/modules/m_namesx.cpp b/src/modules/m_namesx.cpp index 8aa15f965..badbae074 100644 --- a/src/modules/m_namesx.cpp +++ b/src/modules/m_namesx.cpp @@ -81,9 +81,11 @@ class ModuleNamesX : public Module for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++) { if ((!has_user) && (i->second->modes[UM_INVISIBLE])) - { continue; - } + + if (i->second->Visibility && !i->second->Visibility->VisibleTo(user)) + continue; + size_t ptrlen = snprintf(ptr, MAXBUF, "%s%s ", Ptr->GetAllPrefixChars(i->second), i->second->nick); curlen += ptrlen; ptr += ptrlen; diff --git a/src/users.cpp b/src/users.cpp index f75a2cf9f..59d19adff 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -338,6 +338,7 @@ userrec::userrec(InspIRCd* Instance) : ServerInstance(Instance) sendq = ""; WriteError = ""; res_forward = res_reverse = NULL; + Visibility = NULL; ip = NULL; chans.clear(); invites.clear(); @@ -1952,4 +1953,16 @@ const char* userrec::GetOperQuit() return operquit ? operquit : ""; } +VisData::VisData() +{ +} + +VisData::~VisData() +{ +} + +bool VisData::VisibleTo(userrec* user) +{ + return true; +} |