]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_spanningtree.cpp
Started UserManager class
[user/henk/code/inspircd.git] / src / modules / m_spanningtree.cpp
index f14cc69deb4b913923989cc6aa31555b8d35c2f7..c4d335ef23e22c2525b60e10801ca593405a0964 100644 (file)
@@ -111,6 +111,9 @@ static Server* Srv;
 typedef nspace::hash_map<std::string, TreeServer*, nspace::hash<string>, irc::StrHashComp> server_hash;
 server_hash serverlist;
 
+typedef nspace::hash_map<std::string, userrec*> uid_hash;
+typedef nspace::hash_map<std::string, char*> sid_hash;
+
 /* More forward declarations */
 bool DoOneToOne(std::string prefix, std::string command, std::deque<std::string> &params, std::string target);
 bool DoOneToAllButSender(std::string prefix, std::string command, std::deque<std::string> &params, std::string omit);
@@ -135,6 +138,53 @@ extern std::vector<ZLine> pzlines;
 extern std::vector<QLine> pqlines;
 extern std::vector<ELine> pelines;
 
+class UserManager : public classbase
+{
+       uid_hash uids;
+       sid_hash sids;
+ public:
+       UserManager()
+       {
+               uids.clear();
+               sids.clear();
+       }
+
+       std::string UserToUID(userrec* user)
+       {
+               return "";
+       }
+
+       std::string UIDToUser(const std::string &UID)
+       {
+               return "";
+       }
+
+       std::string CreateAndAdd(userrec* user)
+       {
+               return "";
+       }
+
+       std::string CreateAndAdd(const std::string &servername)
+       {
+               return "";
+       }
+
+       std::string ServerToSID(const std::string &servername)
+       {
+               return "";
+       }
+
+       std::string SIDToServer(const std::string &SID)
+       {
+               return "";
+       }
+
+       userrec* FindByID(const std::string &UID)
+       {
+               return NULL;
+       }
+};
+
 /* Each server in the tree is represented by one class of
  * type TreeServer. A locally connected TreeServer can
  * have a class of type TreeSocket associated with it, for
@@ -555,6 +605,7 @@ class cmd_rconnect : public command_t
        cmd_rconnect (Module* Callback) : command_t("RCONNECT", 'o', 2), Creator(Callback)
        {
                this->source = "m_spanningtree.so";
+               syntax = "<remote-server-mask> <servermask>";
        }
 
        void Handle (const char** parameters, int pcnt, userrec *user)
@@ -836,14 +887,6 @@ class TreeSocket : public InspSocket
                /* Now we've whacked the kids, whack self */
                num_lost_servers++;
                num_lost_users += Current->QuitUsers(from);
-               /*for (user_hash::iterator u = clientlist.begin(); u != clientlist.end(); u++)
-               {
-                       if (!strcasecmp(u->second->server,Current->GetName().c_str()))
-                       {
-                               Goners->AddItem(u->second,from);
-                               num_lost_users++;
-                       }
-               }*/
        }
 
        /* This is a wrapper function for SquitServer above, which
@@ -881,83 +924,378 @@ class TreeSocket : public InspSocket
                }
        }
 
-       /* FMODE command */
+       /* FMODE command - server mode with timestamp checks */
        bool ForceMode(std::string source, std::deque<std::string> &params)
        {
+               /* Chances are this is a 1.0 FMODE without TS */
                if (params.size() < 3)
                {
                        this->WriteLine("ERROR :Version 1.0 FMODE sent to version 1.1 server");
                        return false;
                }
-               userrec* who = new userrec();
-               who->fd = FD_MAGIC_NUMBER;
+               
+               bool smode = false;
+               std::string sourceserv;
+
+               /* Are we dealing with an FMODE from a user, or from a server? */
+               userrec* who = Srv->FindNick(source);
+               if (who)
+               {
+                       /* FMODE from a user, set sourceserv to the users server name */
+                       sourceserv = who->server;
+               }
+               else
+               {
+                       /* FMODE from a server, create a fake user to receive mode feedback */
+                       who = new userrec();
+                       who->fd = FD_MAGIC_NUMBER;
+                       smode = true;           /* Setting this flag tells us we should free the userrec later */
+                       sourceserv = source;    /* Set sourceserv to the actual source string */
+               }
                const char* modelist[64];
                time_t TS = 0;
                int n = 0;
                memset(&modelist,0,sizeof(modelist));
-               for (unsigned int q = 0; q < params.size(); q++, n++)
+               for (unsigned int q = 0; (q < params.size()) && (q < 64); q++)
                {
                        if (q == 1)
                        {
-                               /* The timestamp */
+                               /* The timestamp is in this position.
+                                * We don't want to pass that up to the
+                                * server->client protocol!
+                                */
                                TS = atoi(params[q].c_str());
                        }
-                       modelist[n] = params[q].c_str();
+                       else
+                       {
+                               /* Everything else is fine to append to the modelist */
+                               modelist[n++] = params[q].c_str();
+                       }
+                               
                }
-                // Insert the TS value of the object, either userrec or chanrec
-               userrec* a = Srv->FindNick(params[0]);
+                /* Extract the TS value of the object, either userrec or chanrec */
+               userrec* dst = Srv->FindNick(params[0]);
+               chanrec* chan = NULL;
                time_t ourTS = 0;
-               if (a)
+               if (dst)
                {
-                       ourTS = a->age;
+                       ourTS = dst->age;
                }
-               //classbase* a = reinterpret_cast<classbase*>(Srv->FindNick(params[0]));
                else
                {
-                       chanrec* a = Srv->FindChannel(params[0]);
-                       if (a)
+                       chan = Srv->FindChannel(params[0]);
+                       if (chan)
                        {
-                               ourTS = a->age;
+                               ourTS = chan->age;
                        }
                }
+
+               /* TS is equal: Merge the mode changes, use voooodoooooo on modes
+                * with parameters.
+                */
+               if (TS == ourTS)
+               {
+                       log(DEBUG,"Entering TS equality check");
+                       ModeHandler* mh = NULL;
+                       unsigned long paramptr = 3;
+                       std::string to_bounce = "";
+                       std::string to_keep = "";
+                       std::vector<std::string> params_to_keep;
+                       std::string params_to_bounce = "";
+                       bool adding = true;
+                       char cur_change = 1;
+                       char old_change = 0;
+                       char old_bounce_change = 0;
+                       /* Merge modes, basically do special stuff to mode with params */
+                       for (std::string::iterator x = params[2].begin(); x != params[2].end(); x++)
+                       {
+                               switch (*x)
+                               {
+                                       case '-':
+                                               adding = false;
+                                       break;
+                                       case '+':
+                                               adding = true;
+                                       break;
+                                       default:
+                                               if (adding)
+                                               {
+                                                       /* We only care about whats being set,
+                                                        * not whats being unset
+                                                        */
+                                                       mh = ServerInstance->ModeGrok->FindMode(*x, chan ? MODETYPE_CHANNEL : MODETYPE_USER);
+
+                                                       if ((mh->GetNumParams(adding) > 0) && (!mh->IsListMode()))
+                                                       {
+                                                               /* We only want to do special things to
+                                                                * modes with parameters, we are going to rewrite
+                                                                * those parameters
+                                                                */
+                                                               ModePair ret;
+                                                               adding ? cur_change = '+' : cur_change = '-';
+
+                                                               ret = mh->ModeSet(smode ? NULL : who, dst, chan, params[paramptr]);
+
+                                                               /* The mode is set here, check which we should keep */
+                                                               if (ret.first)
+                                                               {
+                                                                       bool which_to_keep = mh->CheckTimeStamp(TS, ourTS, params[paramptr], ret.second, chan);
+
+                                                                       if (which_to_keep == true)
+                                                                       {
+                                                                               /* Keep ours, bounce theirs:
+                                                                                * Send back ours to them and
+                                                                                * drop their mode changs
+                                                                                */
+                                                                               adding ? cur_change = '+' : cur_change = '-';
+                                                                               if (cur_change != old_bounce_change)
+                                                                                       to_bounce += cur_change;
+                                                                               to_bounce += *x;
+                                                                               old_bounce_change = cur_change;
+
+                                                                               if ((mh->GetNumParams(adding) > 0) && (paramptr < params.size()))
+                                                                                       params_to_bounce.append(" ").append(ret.second);
+                                                                       }
+                                                                       else
+                                                                       {
+                                                                               /* Keep theirs: Accept their mode change,
+                                                                                * do nothing else
+                                                                                */
+                                                                               adding ? cur_change = '+' : cur_change = '-';
+                                                                               if (cur_change != old_change)
+                                                                                       to_keep += cur_change;
+                                                                               to_keep += *x;
+                                                                               old_change = cur_change;
+
+                                                                               if ((mh->GetNumParams(adding) > 0) && (paramptr < params.size()))
+                                                                                       params_to_keep.push_back(params[paramptr]);
+                                                                       }
+                                                               }
+                                                               else
+                                                               {
+                                                                       /* Mode isnt set here, we want it */
+                                                                       adding ? cur_change = '+' : cur_change = '-';
+                                                                       if (cur_change != old_change)
+                                                                               to_keep += cur_change;
+                                                                       to_keep += *x;
+                                                                       old_change = cur_change;
+
+                                                                       if ((mh->GetNumParams(adding) > 0) && (paramptr < params.size()))
+                                                                               params_to_keep.push_back(params[paramptr]);
+                                                               }
+
+                                                               paramptr++;
+                                                       }
+                                                       else
+                                                       {
+                                                               mh = ServerInstance->ModeGrok->FindMode(*x, chan ? MODETYPE_CHANNEL : MODETYPE_USER);
+
+                                                               if (mh)
+                                                               {
+                                                                       adding ? cur_change = '+' : cur_change = '-';
+       
+                                                                       /* Just keep this, safe to merge with no checks
+                                                                        * it has no parameters
+                                                                        */
+       
+                                                                       if (cur_change != old_change)
+                                                                               to_keep += cur_change;
+                                                                       to_keep += *x;
+                                                                       old_change = cur_change;
+       
+                                                                       if ((mh->GetNumParams(adding) > 0) && (paramptr < params.size()))
+                                                                       {
+                                                                               log(DEBUG,"Mode removal %d %d",adding, mh->GetNumParams(adding));
+                                                                               params_to_keep.push_back(params[paramptr++]);
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                               else
+                                               {
+                                                       mh = ServerInstance->ModeGrok->FindMode(*x, chan ? MODETYPE_CHANNEL : MODETYPE_USER);
+
+                                                       if (mh)
+                                                       {
+                                                               /* Taking a mode away */
+                                                               adding ? cur_change = '+' : cur_change = '-';
+
+                                                               if (cur_change != old_change)
+                                                                       to_keep += cur_change;
+                                                               to_keep += *x;
+                                                               old_change = cur_change;
+
+                                                               if ((mh->GetNumParams(adding) > 0) && (paramptr < params.size()))
+                                                                       params_to_keep.push_back(params[paramptr++]);
+                                                       }
+                                               }
+                                       break;
+                               }
+                       }
+
+                       if (to_bounce.length())
+                       {
+                               std::deque<std::string> newparams;
+                               newparams.push_back(params[0]);
+                               newparams.push_back(ConvToStr(ourTS));
+                               newparams.push_back(to_bounce+params_to_bounce);
+                               DoOneToOne(Srv->GetServerName(),"FMODE",newparams,sourceserv);
+                       }
+
+                       if (to_keep.length())
+                       {
+                               n = 0;
+                               modelist[0] = params[0].c_str();
+                               modelist[1] = to_keep.c_str();
+
+                               for (unsigned int q = 2; (q < params.size()) && (q < 64); q++)
+                                               modelist[q] = params_to_keep[n++].c_str();
+
+                               if (smode)
+                               {
+                                       Srv->SendMode(modelist, n+2, who);
+                               }
+                               else
+                               {
+                                       Srv->CallCommandHandler("MODE", modelist, n+2, who);
+                               }
+
+                               /* HOT POTATO! PASS IT ON! */
+                               DoOneToAllButSender(source,"FMODE",params,sourceserv);
+                       }
+               }
+               else
                /* U-lined servers always win regardless of their TS */
                if ((TS > ourTS) && (!Srv->IsUlined(source)))
                {
-                       /* Bounce the mode back to its sender.
-                        * We use our higher TS, so the other end
+                       /* Bounce the mode back to its sender.* We use our lower TS, so the other end
                         * SHOULD accept it, if its clock is right.
-                        * If its clock is wrong well bully for you :p
+                        *
+                        * NOTE: We should check that we arent bouncing anything thats already set at this end.
+                        * If we are, bounce +ourmode to 'reinforce' it. This prevents desyncs.
+                        * e.g. They send +l 50, we have +l 10 set. rather than bounce -l 50, we bounce +l 10.
+                        *
+                        * Thanks to jilles for pointing out this one-hell-of-an-issue before i even finished
+                        * writing the code. It took me a while to come up with this solution.
+                        *
+                        * XXX: BE SURE YOU UNDERSTAND THIS CODE FULLY BEFORE YOU MESS WITH IT.
                         */
-                       params[1] = ConvToStr(ourTS);
-                       /* Invert the mode string by changing + to -,
-                        * and - to + in the first param.
+
+                       std::deque<std::string> newparams;      /* New parameter list we send back */
+                       newparams.push_back(params[0]);         /* Target, user or channel */
+                       newparams.push_back(ConvToStr(ourTS));  /* Timestamp value of the target */
+                       newparams.push_back("");                /* This contains the mode string. For now
+                                                                * it's empty, we fill it below.
+                                                                */
+
+                       /* Intelligent mode bouncing. Don't just invert, reinforce any modes which are already
+                        * set to avoid a desync here.
                         */
+                       std::string modebounce = "";
+                       bool adding = true;
+                       unsigned int t = 3;
+                       ModeHandler* mh = NULL;
+                       char cur_change = 1;
+                       char old_change = 0;
                        for (std::string::iterator x = params[2].begin(); x != params[2].end(); x++)
                        {
+                               /* Iterate over all mode chars in the sent set */
                                switch (*x)
                                {
+                                       /* Adding or subtracting modes? */
                                        case '-':
-                                               *x = '+';
+                                               adding = false;
                                        break;
                                        case '+':
-                                               *x = '-';
+                                               adding = true;
+                                       break;
+                                       default:
+                                               /* Find the mode handler for this mode */
+                                               mh = ServerInstance->ModeGrok->FindMode(*x, chan ? MODETYPE_CHANNEL : MODETYPE_USER);
+
+                                               /* Got a mode handler?
+                                                * This also prevents us bouncing modes we have no handler for.
+                                                */
+                                               if (mh)
+                                               {
+                                                       ModePair ret;
+                                                       std::string p = "";
+
+                                                       /* Does the mode require a parameter right now?
+                                                        * If it does, fetch it if we can
+                                                        */
+                                                       if ((mh->GetNumParams(adding) > 0) && (t < params.size()))
+                                                               p = params[t++];
+
+                                                       /* Call the ModeSet method to determine if its set with the
+                                                        * given parameter here or not.
+                                                        */
+                                                       ret = mh->ModeSet(smode ? NULL : who, dst, chan, p);
+
+                                                       /* XXX: Really. Dont ask.
+                                                        * Determine from if its set combined with what the current
+                                                        * 'state' is (adding or not) as to wether we should 'invert'
+                                                        * or 'reinforce' the mode change
+                                                        */
+                                                       (!ret.first ? (adding ? cur_change = '-' : cur_change = '+') : (!adding ? cur_change = '-' : cur_change = '+'));
+
+                                                       /* Quickly determine if we have 'flipped' from + to -,
+                                                        * or - to +, to prevent unneccessary +/- chars in the
+                                                        * output string that waste bandwidth
+                                                        */
+                                                       if (cur_change != old_change)
+                                                               modebounce += cur_change;
+                                                       old_change = cur_change;
+
+                                                       /* Add the mode character to the output string */
+                                                       modebounce += mh->GetModeChar();
+
+                                                       /* We got a parameter back from ModeHandler::ModeSet,
+                                                        * are we supposed to be sending one out right now?
+                                                        */
+                                                       if (ret.second.length())
+                                                       {
+                                                               if (mh->GetNumParams(cur_change == '+') > 0)
+                                                                       /* Yes we're supposed to be sending out
+                                                                        * the parameter. Make sure it goes
+                                                                        */
+                                                                       newparams.push_back(ret.second);
+                                                       }
+
+                                               }
                                        break;
                                }
                        }
-                       DoOneToOne(source,"FMODE",params,source);
-                       log(DEBUG,"Mode bounced, our TS less than theirs");
+                       
+                       /* Update the parameters for FMODE with the new 'bounced' string */
+                       newparams[2] = modebounce;
+                       /* Only send it back the way it came, no need to send it anywhere else */
+                       DoOneToOne(Srv->GetServerName(),"FMODE",newparams,sourceserv);
+                       log(DEBUG,"FMODE bounced intelligently, our TS less than theirs and the other server is NOT a uline.");
                }
                else
                {
-                       if ((Srv->IsUlined(source)) && (TS > ourTS))
+                       log(DEBUG,"Allow modes, TS lower for sender");
+                       /* The server was ulined, but something iffy is up with the TS.
+                        * Sound the alarm bells!
+                        */
+                       if ((Srv->IsUlined(sourceserv)) && (TS > ourTS))
                        {
-                               WriteOpers("\2WARNING!\2 U-Lined server '%s' has bad TS for '%s' (accepted change): \2SYNC YOUR CLOCKS\2 to avoid this notice",source.c_str(),params[0].c_str());
+                               WriteOpers("\2WARNING!\2 U-Lined server '%s' has bad TS for '%s' (accepted change): \2SYNC YOUR CLOCKS\2 to avoid this notice",sourceserv.c_str(),params[0].c_str());
                        }
-                       /* Allow the mode */
-                       Srv->SendMode(modelist,params.size(),who);
-                       DoOneToAllButSender(source,"FMODE",params,source);
+                       /* Allow the mode, route it to either server or user command handling */
+                       if (smode)
+                               Srv->SendMode(modelist,n,who);
+                       else
+                               Srv->CallCommandHandler("MODE", modelist, n, who);
+
+                       /* HOT POTATO! PASS IT ON! */
+                       DoOneToAllButSender(source,"FMODE",params,sourceserv);
                }
-               DELETE(who);
+               /* Are we supposed to free the userrec? */
+               if (smode)
+                       DELETE(who);
+
                return true;
        }
 
@@ -1214,7 +1552,7 @@ class TreeSocket : public InspSocket
                clientlist[tempnick]->server = FindServerNamePtr(source.c_str());
                strlcpy(clientlist[tempnick]->ident, params[4].c_str(),IDENTMAX);
                strlcpy(clientlist[tempnick]->fullname, params[7].c_str(),MAXGECOS);
-               clientlist[tempnick]->registered = 7;
+               clientlist[tempnick]->registered = REG_ALL;
                clientlist[tempnick]->signon = age;
                
                for (std::string::iterator v = params[5].begin(); v != params[5].end(); v++)
@@ -1426,7 +1764,7 @@ class TreeSocket : public InspSocket
                int iterations = 0;
                for (user_hash::iterator u = clientlist.begin(); u != clientlist.end(); u++, iterations++)
                {
-                       if (u->second->registered == 7)
+                       if (u->second->registered == REG_ALL)
                        {
                                snprintf(data,MAXBUF,":%s NICK %lu %s %s %s %s +%s %s :%s",u->second->server,(unsigned long)u->second->age,u->second->nick,u->second->host,u->second->dhost,u->second->ident,u->second->FormatModes(),inet_ntoa(u->second->ip4),u->second->fullname);
                                this->WriteLine(data);
@@ -1884,7 +2222,7 @@ class TreeSocket : public InspSocket
                        if (params.size() == 1)
                        {
                                userrec* x = Srv->FindNick(params[0]);
-                               if ((x) && (x->fd > -1))
+                               if ((x) && (IS_LOCAL(x)))
                                {
                                        userrec* x = Srv->FindNick(params[0]);
                                        log(DEBUG,"Got IDLE");
@@ -1910,14 +2248,14 @@ class TreeSocket : public InspSocket
                        {
                                std::string who_did_the_whois = params[0];
                                userrec* who_to_send_to = Srv->FindNick(who_did_the_whois);
-                               if ((who_to_send_to) && (who_to_send_to->fd > -1))
+                               if ((who_to_send_to) && (IS_LOCAL(who_to_send_to)))
                                {
                                        log(DEBUG,"Got final IDLE");
                                        // an incoming reply to a whois we sent out
                                        std::string nick_whoised = prefix;
                                        unsigned long signon = atoi(params[1].c_str());
                                        unsigned long idle = atoi(params[2].c_str());
-                                       if ((who_to_send_to) && (who_to_send_to->fd > -1))
+                                       if ((who_to_send_to) && (IS_LOCAL(who_to_send_to)))
                                                do_whois(who_to_send_to,u,signon,idle,nick_whoised.c_str());
                                }
                                else
@@ -2671,7 +3009,7 @@ class TreeSocket : public InspSocket
                        /* XXX: Fixme: blocks for a very short amount of time,
                         * we should cache these on rehash/startup
                         */
-                       if (CleanAndResolve(resolved_host,i->IPAddr.c_str(),true))
+                       if (CleanAndResolve(resolved_host,i->IPAddr.c_str(),true,1))
                        {
                                if (std::string(resolved_host) == ip)
                                {
@@ -3189,7 +3527,7 @@ class ModuleSpanningTree : public Module
 
        int HandleTime(const char** parameters, int pcnt, userrec* user)
        {
-               if ((user->fd > -1) && (pcnt))
+               if ((IS_LOCAL(user)) && (pcnt))
                {
                        TreeServer* found = FindServerMask(parameters[0]);
                        if (found)
@@ -3213,7 +3551,7 @@ class ModuleSpanningTree : public Module
 
        int HandleRemoteWhois(const char** parameters, int pcnt, userrec* user)
        {
-               if ((user->fd > -1) && (pcnt > 1))
+               if ((IS_LOCAL(user)) && (pcnt > 1))
                {
                        userrec* remote = Srv->FindNick(parameters[1]);
                        if ((remote) && (remote->fd < 0))
@@ -3458,7 +3796,7 @@ class ModuleSpanningTree : public Module
 
        virtual void OnUserInvite(userrec* source,userrec* dest,chanrec* channel)
        {
-               if (source->fd > -1)
+               if (IS_LOCAL(source))
                {
                        std::deque<std::string> params;
                        params.push_back(dest->nick);
@@ -3477,7 +3815,7 @@ class ModuleSpanningTree : public Module
 
        virtual void OnWallops(userrec* user, const std::string &text)
        {
-               if (user->fd > -1)
+               if (IS_LOCAL(user))
                {
                        std::deque<std::string> params;
                        params.push_back(":"+text);
@@ -3490,7 +3828,7 @@ class ModuleSpanningTree : public Module
                if (target_type == TYPE_USER)
                {
                        userrec* d = (userrec*)dest;
-                       if ((d->fd < 0) && (user->fd > -1))
+                       if ((d->fd < 0) && (IS_LOCAL(user)))
                        {
                                std::deque<std::string> params;
                                params.clear();
@@ -3501,7 +3839,7 @@ class ModuleSpanningTree : public Module
                }
                else if (target_type == TYPE_CHANNEL)
                {
-                       if (user->fd > -1)
+                       if (IS_LOCAL(user))
                        {
                                chanrec *c = (chanrec*)dest;
                                std::string cname = c->name;
@@ -3520,7 +3858,7 @@ class ModuleSpanningTree : public Module
                }
                 else if (target_type == TYPE_SERVER)
                {
-                       if (user->fd > -1)
+                       if (IS_LOCAL(user))
                        {
                                char* target = (char*)dest;
                                std::deque<std::string> par;
@@ -3538,7 +3876,7 @@ class ModuleSpanningTree : public Module
                        // route private messages which are targetted at clients only to the server
                        // which needs to receive them
                        userrec* d = (userrec*)dest;
-                       if ((d->fd < 0) && (user->fd > -1))
+                       if ((d->fd < 0) && (IS_LOCAL(user)))
                        {
                                std::deque<std::string> params;
                                params.clear();
@@ -3549,7 +3887,7 @@ class ModuleSpanningTree : public Module
                }
                else if (target_type == TYPE_CHANNEL)
                {
-                       if (user->fd > -1)
+                       if (IS_LOCAL(user))
                        {
                                chanrec *c = (chanrec*)dest;
                                std::string cname = c->name;
@@ -3568,7 +3906,7 @@ class ModuleSpanningTree : public Module
                }
                else if (target_type == TYPE_SERVER)
                {
-                       if (user->fd > -1)
+                       if (IS_LOCAL(user))
                        {
                                char* target = (char*)dest;
                                std::deque<std::string> par;
@@ -3588,7 +3926,7 @@ class ModuleSpanningTree : public Module
        virtual void OnUserJoin(userrec* user, chanrec* channel)
        {
                // Only do this for local users
-               if (user->fd > -1)
+               if (IS_LOCAL(user))
                {
                        std::deque<std::string> params;
                        params.clear();
@@ -3617,7 +3955,7 @@ class ModuleSpanningTree : public Module
        virtual void OnChangeHost(userrec* user, const std::string &newhost)
        {
                // only occurs for local clients
-               if (user->registered != 7)
+               if (user->registered != REG_ALL)
                        return;
                std::deque<std::string> params;
                params.push_back(newhost);
@@ -3627,7 +3965,7 @@ class ModuleSpanningTree : public Module
        virtual void OnChangeName(userrec* user, const std::string &gecos)
        {
                // only occurs for local clients
-               if (user->registered != 7)
+               if (user->registered != REG_ALL)
                        return;
                std::deque<std::string> params;
                params.push_back(gecos);
@@ -3636,7 +3974,7 @@ class ModuleSpanningTree : public Module
 
        virtual void OnUserPart(userrec* user, chanrec* channel, const std::string &partmessage)
        {
-               if (user->fd > -1)
+               if (IS_LOCAL(user))
                {
                        std::deque<std::string> params;
                        params.push_back(channel->name);
@@ -3649,7 +3987,7 @@ class ModuleSpanningTree : public Module
        virtual void OnUserConnect(userrec* user)
        {
                char agestr[MAXBUF];
-               if (user->fd > -1)
+               if (IS_LOCAL(user))
                {
                        std::deque<std::string> params;
                        snprintf(agestr,MAXBUF,"%lu",(unsigned long)user->age);
@@ -3675,7 +4013,7 @@ class ModuleSpanningTree : public Module
 
        virtual void OnUserQuit(userrec* user, const std::string &reason)
        {
-               if ((user->fd > -1) && (user->registered == 7))
+               if ((IS_LOCAL(user)) && (user->registered == REG_ALL))
                {
                        std::deque<std::string> params;
                        params.push_back(":"+reason);
@@ -3692,7 +4030,7 @@ class ModuleSpanningTree : public Module
 
        virtual void OnUserPostNick(userrec* user, const std::string &oldnick)
        {
-               if (user->fd > -1)
+               if (IS_LOCAL(user))
                {
                        std::deque<std::string> params;
                        params.push_back(user->nick);
@@ -3702,7 +4040,7 @@ class ModuleSpanningTree : public Module
 
        virtual void OnUserKick(userrec* source, userrec* user, chanrec* chan, const std::string &reason)
        {
-               if ((source) && (source->fd > -1))
+               if ((source) && (IS_LOCAL(source)))
                {
                        std::deque<std::string> params;
                        params.push_back(chan->name);
@@ -3750,7 +4088,7 @@ class ModuleSpanningTree : public Module
        // locally.
        virtual void OnOper(userrec* user, const std::string &opertype)
        {
-               if (user->fd > -1)
+               if (IS_LOCAL(user))
                {
                        std::deque<std::string> params;
                        params.push_back(opertype);
@@ -3760,7 +4098,7 @@ class ModuleSpanningTree : public Module
 
        void OnLine(userrec* source, const std::string &host, bool adding, char linetype, long duration, const std::string &reason)
        {
-               if (source->fd > -1)
+               if (IS_LOCAL(source))
                {
                        char type[8];
                        snprintf(type,8,"%cLINE",linetype);
@@ -3826,7 +4164,7 @@ class ModuleSpanningTree : public Module
 
        virtual void OnMode(userrec* user, void* dest, int target_type, const std::string &text)
        {
-               if ((user->fd > -1) && (user->registered == 7))
+               if ((IS_LOCAL(user)) && (user->registered == REG_ALL))
                {
                        if (target_type == TYPE_USER)
                        {