]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_safelist.cpp
Remove some debug (im on a crusade to make debug mode useful, but at the same time...
[user/henk/code/inspircd.git] / src / modules / m_safelist.cpp
index 0ba1f28a1d1b815c59ba2e79e7e3cdcd21c68e59..7441f0ea59f00b1a027952e58728a40af5c32fe0 100644 (file)
@@ -2,47 +2,43 @@
  *       | Inspire Internet Relay Chat Daemon |
  *       +------------------------------------+
  *
- *  InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev.
- *                       E-mail:
- *                <brain@chatspike.net>
- *               <Craig@chatspike.net>
- *     
- * Written by Craig Edwards, Craig McLure, and others.
+ *  InspIRCd: (C) 2002-2007 InspIRCd Development Team
+ * See: http://www.inspircd.org/wiki/index.php/Credits
+ *
  * This program is free but copyrighted software; see
  *            the file COPYING for details.
  *
  * ---------------------------------------------------
  */
-
-using namespace std;
  
 #include "users.h"
 #include "channels.h"
 #include "modules.h"
-#include "helperfuncs.h"
-#include "message.h"
-#include <vector>
-extern time_t TIME;
+#include "configreader.h"
+#include "inspircd.h"
+#include "wildcard.h"
 
-class ListData
+/** Holds a users m_safelist state
+ */
+class ListData : public classbase
 {
  public:
        long list_start;
        long list_position;
        bool list_ended;
+       const std::string glob;
 
        ListData() : list_start(0), list_position(0), list_ended(false) {};
-       ListData(long pos, time_t t) : list_start(t), list_position(pos), list_ended(false) {};
+       ListData(long pos, time_t t, const std::string &pattern) : list_start(t), list_position(pos), list_ended(false), glob(pattern) {};
 };
 
 /* $ModDesc: A module overriding /list, and making it safe - stop those sendq problems. */
  
 typedef std::vector<userrec *> UserList;
 UserList listusers;    /* vector of people doing a /list */
+class ListTimer *timer;
 
-/*
- * To create a timer which recurs every second, we inherit from InspTimer.
+/** To create a timer which recurs every second, we inherit from InspTimer.
  * InspTimer is only one-shot however, so at the end of each Tick() we simply
  * insert another of ourselves into the pending queue :)
  */
@@ -50,14 +46,17 @@ class ListTimer : public InspTimer
 {
  private:
 
-       Server* Srv;
        char buffer[MAXBUF];
        chanrec *chan;
+       InspIRCd* ServerInstance;
+       const std::string glob;
+       size_t ServerNameSize;
 
  public:
 
-       ListTimer(long interval, Server* Me) : InspTimer(interval,TIME), Srv(Me)
+       ListTimer(InspIRCd* Instance, long interval) : InspTimer(interval,Instance->Time()), ServerInstance(Instance)
        {
+               ServerNameSize = 4 + strlen(ServerInstance->Config->ServerName);
        }
 
        virtual void Tick(time_t TIME)
@@ -72,12 +71,14 @@ class ListTimer : public InspTimer
                                /*
                                 * What we do here:
                                 *  - Get where they are up to
-                                *  - If it's > GetChannelCount, erase them from the iterator, set go_again to true
+                                *  - If it's more than total number of channels, erase
+                                *    them from the iterator, set go_again to true
                                 *  - If not, spool more channels
                                 */
                                userrec* u = (userrec*)(*iter);
-                               ListData* ld = (ListData*)u->GetExt("safelist_cache");
-                               if (ld->list_position > Srv->GetChannelCount())
+                               ListData* ld;
+                               u->GetExt("safelist_cache", ld);
+                               if ((size_t)ld->list_position > ServerInstance->chanlist->size())
                                {
                                        u->Shrink("safelist_cache");
                                        DELETE(ld);
@@ -86,28 +87,42 @@ class ListTimer : public InspTimer
                                        break;
                                }
 
-                               log(DEBUG, "m_safelist.so: resuming spool of list to client %s at channel %ld", u->nick, ld->list_position);
+                               ServerInstance->Log(DEBUG, "m_safelist.so: resuming spool of list to client %s at channel %ld", u->nick, ld->list_position);
                                chan = NULL;
-                               /* Attempt to fill up to half the user's sendq with /LIST output */
+                               /* Attempt to fill up to 25% the user's sendq with /LIST output */
                                long amount_sent = 0;
                                do
                                {
-                                       log(DEBUG,"Channel %ld",ld->list_position);
+                                       ServerInstance->Log(DEBUG,"Channel %ld",ld->list_position);
                                        if (!ld->list_position)
-                                               WriteServ(u->fd,"321 %s Channel :Users Name",u->nick);
-                                       chan = Srv->GetChannelIndex(ld->list_position);
+                                               u->WriteServ("321 %s Channel :Users Name",u->nick);
+                                       chan = ServerInstance->GetChannelIndex(ld->list_position);
                                        /* spool details */
                                        bool has_user = (chan && chan->HasUser(u));
-                                       if ((chan) && (((!(chan->modes[CM_PRIVATE])) && (!(chan->modes[CM_SECRET]))) || (has_user)))
+                                       if ((chan) && (chan->modes[CM_PRIVATE]))
+                                       {
+                                               bool display = match(chan->name, ld->glob.c_str());
+                                               long users = chan->GetUserCounter();
+                                               if ((users) && (display))
+                                               {
+                                                       int counter = snprintf(buffer, MAXBUF, "322 %s *", u->nick);
+                                                       amount_sent += counter + ServerNameSize;
+                                                       ServerInstance->Log(DEBUG, "m_safelist.so: Sent %ld of safe %ld / 4", amount_sent, u->sendqmax);
+                                                       u->WriteServ(std::string(buffer));
+                                               }
+                                       }
+                                       else if ((chan) && (((!(chan->modes[CM_PRIVATE])) && (!(chan->modes[CM_SECRET]))) || (has_user)))
                                        {
-                                               long users = usercount(chan);
-                                               if (users)
+                                               bool display = match(chan->name, ld->glob.c_str());
+                                               long users = chan->GetUserCounter();
+
+                                               if ((users) && (display))
                                                {
-                                                       int counter = snprintf(buffer,MAXBUF,"322 %s %s %ld :[+%s] %s",u->nick,chan->name,users,chanmodes(chan,has_user),chan->topic);
+                                                       int counter = snprintf(buffer, MAXBUF, "322 %s %s %ld :[+%s] %s",u->nick, chan->name, users, chan->ChanModes(has_user), chan->topic);
                                                        /* Increment total plus linefeed */
-                                                       amount_sent += counter + 4 + Srv->GetServerName().length();
-                                                       log(DEBUG,"m_safelist.so: Sent %ld of safe %ld / 4",amount_sent,u->sendqmax);
-                                                       WriteServ_NoFormat(u->fd,buffer);
+                                                       amount_sent += counter + ServerNameSize;
+                                                       ServerInstance->Log(DEBUG, "m_safelist.so: Sent %ld of safe %ld / 4", amount_sent, u->sendqmax);
+                                                       u->WriteServ(std::string(buffer));
                                                }
                                        }
                                        else
@@ -117,7 +132,7 @@ class ListTimer : public InspTimer
                                                        if (!ld->list_ended)
                                                        {
                                                                ld->list_ended = true;
-                                                               WriteServ(u->fd,"323 %s :End of channel list.",u->nick);
+                                                               u->WriteServ("323 %s :End of channel list.",u->nick);
                                                        }
                                                }
                                        }
@@ -128,32 +143,35 @@ class ListTimer : public InspTimer
                        }
                }
 
-               ListTimer* MyTimer = new ListTimer(1,Srv);
-               Srv->AddTimer(MyTimer);
+               if (listusers.size())
+               {
+                       timer = new ListTimer(ServerInstance,1);
+                       ServerInstance->Timers->AddTimer(timer);
+               }
+               else
+               {
+                       timer = NULL;
+               }
        }
 };
 
 class ModuleSafeList : public Module
 {
- private:
-        Server *Srv;
-        ListTimer* MyTimer;
  public:
-       ModuleSafeList(Server* Me) : Module::Module(Me)
+       ModuleSafeList(InspIRCd* Me) : Module::Module(Me)
        {
-               Srv = Me;
-
-               MyTimer = new ListTimer(1,Srv);
-               Srv->AddTimer(MyTimer);
+               timer = NULL;
        }
  
        virtual ~ModuleSafeList()
        {
+               if (timer)
+                       ServerInstance->Timers->DelTimer(timer);
        }
  
        virtual Version GetVersion()
        {
-               return Version(1,0,0,0,VF_VENDOR);
+               return Version(1,1,0,0,VF_VENDOR,API_VERSION);
        }
  
        void Implements(char* List)
@@ -165,7 +183,7 @@ class ModuleSafeList : public Module
         * OnPreCommand()
         *   Intercept the LIST command.
         */ 
-       virtual int OnPreCommand(const std::string &command, char **parameters, int pcnt, userrec *user, bool validated)
+       virtual int OnPreCommand(const std::string &command, const char** parameters, int pcnt, userrec *user, bool validated, const std::string &original_line)
        {
                /* If the command doesnt appear to be valid, we dont want to mess with it. */
                if (!validated)
@@ -182,10 +200,11 @@ class ModuleSafeList : public Module
         * HandleList()
         *   Handle (override) the LIST command.
         */
-       int HandleList(char** parameters, int pcnt, userrec* user)
+       int HandleList(const char** parameters, int pcnt, userrec* user)
        {
                /* First, let's check if the user is currently /list'ing */
-               ListData *ld = (ListData*)user->GetExt("safelist_cache");
+               ListData *ld;
+               user->GetExt("safelist_cache", ld);
  
                if (ld)
                {
@@ -193,12 +212,19 @@ class ModuleSafeList : public Module
                        return 1;
                }
 
-               time_t* last_list_time = (time_t*)user->GetExt("safelist_last");
+               /* Work around mIRC suckyness. YOU SUCK, KHALED! */
+               if ((pcnt == 1) && (*parameters[0] == '<'))
+                       pcnt = 0;
+
+               time_t* last_list_time;
+               user->GetExt("safelist_last", last_list_time);
                if (last_list_time)
                {
-                       if (TIME < (*last_list_time)+60)
+                       if (ServerInstance->Time() < (*last_list_time)+60)
                        {
-                               WriteServ(user->fd,"NOTICE %s :*** Woah there, slow down a little, you can't /LIST so often!",user->nick);
+                               user->WriteServ("NOTICE %s :*** Woah there, slow down a little, you can't /LIST so often!",user->nick);
+                               user->WriteServ("321 %s Channel :Users Name",user->nick);
+                               user->WriteServ("323 %s :End of channel list.",user->nick);
                                return 1;
                        }
 
@@ -209,14 +235,20 @@ class ModuleSafeList : public Module
                /*
                 * start at channel 0! ;)
                 */
-               ld = new ListData(0,TIME);
-               user->Extend("safelist_cache", (char*)ld);
+               ld = new ListData(0,ServerInstance->Time(), pcnt ? parameters[0] : "*");
+               user->Extend("safelist_cache", ld);
                listusers.push_back(user);
 
                time_t* llt = new time_t;
-               *llt = TIME;
-               user->Extend("safelist_last",(char*)llt);
-       
+               *llt = ServerInstance->Time();
+               user->Extend("safelist_last", llt);
+
+               if (!timer)
+               {
+                       timer = new ListTimer(ServerInstance,1);
+                       ServerInstance->Timers->AddTimer(timer);
+               }
+
                return 1;
        }
 
@@ -225,7 +257,8 @@ class ModuleSafeList : public Module
                if(target_type == TYPE_USER)
                {
                        userrec* u = (userrec*)item;
-                       ListData* ld = (ListData*)u->GetExt("safelist_cache");
+                       ListData* ld;
+                       u->GetExt("safelist_cache", ld);
                        if (ld)
                        {
                                u->Shrink("safelist_cache");
@@ -240,7 +273,8 @@ class ModuleSafeList : public Module
                                        break;
                                }
                        }
-                       time_t* last_list_time = (time_t*)u->GetExt("safelist_last");
+                       time_t* last_list_time;
+                       u->GetExt("safelist_last", last_list_time);
                        if (last_list_time)
                        {
                                DELETE(last_list_time);
@@ -260,11 +294,8 @@ class ModuleSafeList : public Module
        }
 
 };
-/******************************************************************************************************/
+
+
 class ModuleSafeListFactory : public ModuleFactory
 {
  public:
@@ -276,7 +307,7 @@ class ModuleSafeListFactory : public ModuleFactory
        {
        }
  
-       virtual Module * CreateModule(Server* Me)
+       virtual Module * CreateModule(InspIRCd* Me)
        {
                return new ModuleSafeList(Me);
        }