summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/inspircd.conf.example11
-rw-r--r--include/modules.h2
-rw-r--r--include/users.h12
-rw-r--r--src/channels.cpp3
-rw-r--r--src/mode.cpp19
-rw-r--r--src/modules/m_hideoper.cpp2
-rw-r--r--src/modules/m_namesx.cpp6
-rw-r--r--src/users.cpp13
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 &parameter, 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;
+}