]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_hideoper.cpp
m_hideoper Fix wrong /WHO output for hidden opers if the channel name contains '*'
[user/henk/code/inspircd.git] / src / modules / m_hideoper.cpp
index 00e7deb9116ce2e9138fc49576154603ffb82208..88b0c4cdffbf544f5ed12a1a5746162cdf152a6d 100644 (file)
@@ -45,9 +45,8 @@ class ModuleHideOper : public Module
 
        void init()
        {
-               if (!ServerInstance->Modes->AddMode(&hm))
-                       throw ModuleException("Could not add new modes!");
-               Implementation eventlist[] = { I_OnWhoisLine, I_OnSendWhoLine };
+               ServerInstance->Modules->AddService(hm);
+               Implementation eventlist[] = { I_OnWhoisLine, I_OnSendWhoLine, I_OnStats };
                ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation));
        }
 
@@ -83,7 +82,11 @@ class ModuleHideOper : public Module
                if (user->IsModeSet('H') && !source->HasPrivPermission("users/auspex"))
                {
                        // hide the "*" that marks the user as an oper from the /WHO line
-                       std::string::size_type pos = line.find("*");
+                       std::string::size_type spcolon = line.find(" :");
+                       if (spcolon == std::string::npos)
+                               return; // Another module hid the user completely
+                       std::string::size_type sp = line.rfind(' ', spcolon-1);
+                       std::string::size_type pos = line.find('*', sp);
                        if (pos != std::string::npos)
                                line.erase(pos, 1);
                        // hide the line completely if doing a "/who * o" query
@@ -91,6 +94,27 @@ class ModuleHideOper : public Module
                                line.clear();
                }
        }
+
+       ModResult OnStats(char symbol, User* user, string_list &results)
+       {
+               if (symbol != 'P')
+                       return MOD_RES_PASSTHRU;
+
+               unsigned int count = 0;
+               for (std::list<User*>::const_iterator i = ServerInstance->Users->all_opers.begin(); i != ServerInstance->Users->all_opers.end(); ++i)
+               {
+                       User* oper = *i;
+                       if (!ServerInstance->ULine(oper->server) && (IS_OPER(user) || !oper->IsModeSet('H')))
+                       {
+                               results.push_back(ServerInstance->Config->ServerName+" 249 " + user->nick + " :" + oper->nick + " (" + oper->ident + "@" + oper->dhost + ") Idle: " +
+                                               (IS_LOCAL(oper) ? ConvToStr(ServerInstance->Time() - oper->idle_lastmsg) + " secs" : "unavailable"));
+                               count++;
+                       }
+               }
+               results.push_back(ServerInstance->Config->ServerName+" 249 "+user->nick+" :"+ConvToStr(count)+" OPER(s)");
+
+               return MOD_RES_DENY;
+       }
 };