]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_hideoper.cpp
Merge pull request #1157 from SaberUK/insp20+fix-cron-restart
[user/henk/code/inspircd.git] / src / modules / m_hideoper.cpp
index c2b472bad9aec05b516d28ebd3ac17ee733b2e03..9d50bd2e5342b410ef4715c492c6ffdf50502944 100644 (file)
@@ -1 +1,161 @@
-/*       +------------------------------------+\r *       | Inspire Internet Relay Chat Daemon |\r *       +------------------------------------+\r *\r *  InspIRCd: (C) 2002-2007 InspIRCd Development Team\r * See: http://www.inspircd.org/wiki/index.php/Credits\r *\r * This program is free but copyrighted software; see\r *            the file COPYING for details.\r *\r * ---------------------------------------------------\r */\r\r#include "inspircd.h"\r#include "users.h"\r#include "channels.h"\r#include "modules.h"\r\r/* $ModDesc: Provides support for hiding oper status with user mode +H */\r\r/** Handles user mode +B\r */\rclass HideOper : public ModeHandler\r{\r public:\r       HideOper(InspIRCd* Instance) : ModeHandler(Instance, 'H', 0, 0, false, MODETYPE_USER, true) { }\r\r       ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string &parameter, bool adding)\r {\r              if (source != dest)\r                    return MODEACTION_DENY;\r\r               if (adding)\r            {\r                      if (!dest->IsModeSet('H'))\r                     {\r                              dest->SetMode('H',true);\r                               return MODEACTION_ALLOW;\r                       }\r              }\r              else\r           {\r                      if (dest->IsModeSet('H'))\r                      {\r                              dest->SetMode('H',false);\r                              return MODEACTION_ALLOW;\r                       }\r              }\r              \r               return MODEACTION_DENY;\r        }\r};\r\rclass ModuleHideOper : public Module\r{\r   \r       HideOper* hm;\r public:\r ModuleHideOper(InspIRCd* Me)\r           : Module(Me)\r   {\r              \r               hm = new HideOper(ServerInstance);\r             if (!ServerInstance->AddMode(hm, 'H'))\r                 throw ModuleException("Could not add new modes!");\r     }\r\r     void Implements(char* List)\r    {\r              List[I_OnWhoisLine] = 1;\r       }\r      \r       virtual ~ModuleHideOper()\r      {\r              ServerInstance->Modes->DelMode(hm);\r            DELETE(hm);\r    }\r      \r       virtual Version GetVersion()\r   {\r              return Version(1,1,0,0,VF_COMMON|VF_VENDOR,API_VERSION);\r       }\r\r     int OnWhoisLine(userrec* user, userrec* dest, int &numeric, std::string &text)\r {\r              /* Dont display numeric 313 (RPL_WHOISOPER) if they have +H set and the\r                 * person doing the WHOIS is not an oper\r                */\r            return ((!IS_OPER(user)) && (numeric == 313) && dest->IsModeSet('H'));\r }\r};\r\r\rMODULE_INIT(ModuleHideOper)\r
\ No newline at end of file
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ *   Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
+ *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
+ *   Copyright (C) 2006 Craig Edwards <craigedwards@brainbox.cc>
+ *
+ * This file is part of InspIRCd.  InspIRCd is free software: you can
+ * redistribute it and/or modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+
+/* $ModDesc: Provides support for hiding oper status with user mode +H */
+
+/** Handles user mode +H
+ */
+class HideOper : public SimpleUserModeHandler
+{
+ public:
+       size_t opercount;
+
+       HideOper(Module* Creator) : SimpleUserModeHandler(Creator, "hideoper", 'H')
+               , opercount(0)
+       {
+               oper = true;
+       }
+
+       ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string& parameter, bool adding)
+       {
+               if (SimpleUserModeHandler::OnModeChange(source, dest, channel, parameter, adding) == MODEACTION_DENY)
+                       return MODEACTION_DENY;
+
+               if (adding)
+                       opercount++;
+               else
+                       opercount--;
+
+               return MODEACTION_ALLOW;
+       }
+};
+
+class ModuleHideOper : public Module
+{
+       HideOper hm;
+       bool active;
+ public:
+       ModuleHideOper()
+               : hm(this)
+               , active(false)
+       {
+       }
+
+       void init()
+       {
+               ServerInstance->Modules->AddService(hm);
+               Implementation eventlist[] = { I_OnWhoisLine, I_OnSendWhoLine, I_OnStats, I_OnNumeric, I_OnUserQuit };
+               ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation));
+       }
+
+
+       virtual ~ModuleHideOper()
+       {
+       }
+
+       virtual Version GetVersion()
+       {
+               return Version("Provides support for hiding oper status with user mode +H", VF_VENDOR);
+       }
+
+       void OnUserQuit(User* user, const std::string&, const std::string&)
+       {
+               if (user->IsModeSet('H'))
+                       hm.opercount--;
+       }
+
+       ModResult OnNumeric(User* user, unsigned int numeric, const std::string& text)
+       {
+               if (numeric != 252 || active || user->HasPrivPermission("users/auspex"))
+                       return MOD_RES_PASSTHRU;
+
+               // If there are no visible operators then we shouldn't send the numeric.
+               size_t opercount = ServerInstance->Users->all_opers.size() - hm.opercount;
+               if (opercount)
+               {
+                       active = true;
+                       user->WriteNumeric(252, "%s %lu :operator(s) online", user->nick.c_str(),  opercount);
+                       active = false;
+               }
+               return MOD_RES_DENY;
+       }
+
+       ModResult OnWhoisLine(User* user, User* dest, int &numeric, std::string &text)
+       {
+               /* Dont display numeric 313 (RPL_WHOISOPER) if they have +H set and the
+                * person doing the WHOIS is not an oper
+                */
+               if (numeric != 313)
+                       return MOD_RES_PASSTHRU;
+
+               if (!dest->IsModeSet('H'))
+                       return MOD_RES_PASSTHRU;
+
+               if (!user->HasPrivPermission("users/auspex"))
+                       return MOD_RES_DENY;
+
+               return MOD_RES_PASSTHRU;
+       }
+
+       void OnSendWhoLine(User* source, const std::vector<std::string>& params, User* user, std::string& line)
+       {
+               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 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
+                       if (params.size() > 1 && params[1].find('o') != std::string::npos)
+                               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;
+       }
+};
+
+
+MODULE_INIT(ModuleHideOper)