]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/channels.cpp
Fix for parameters which contain a colon (which is not the first char in the string)
[user/henk/code/inspircd.git] / src / channels.cpp
index fff2769701a12a5689bdf59ff612922605591e8c..f340e12bf1528b4edf9a75cc3ddb8aeff0e72129 100644 (file)
 
 using namespace std;
 
-#include <string>
-#include <map>
-#include <sstream>
-#include <vector>
-#include <deque>
 #include <stdarg.h>
 #include "configreader.h"
 #include "inspircd.h"
-#include "hash_map.h"
 #include "users.h"
-#include "ctables.h"
-#include "globals.h"
 #include "modules.h"
-#include "dynamic.h"
-#include "commands.h"
 #include "wildcard.h"
 #include "mode.h"
-#include "xline.h"
-#include "inspstring.h"
-#include "helperfuncs.h"
-#include "typedefs.h"
 
 chanrec::chanrec(InspIRCd* Instance) : ServerInstance(Instance)
 {
@@ -222,7 +208,7 @@ chanrec* chanrec::JoinUser(InspIRCd* Instance, userrec *user, const char* cn, bo
 
        if (!Ptr)
        {
-               if (user->fd > -1)
+               if (IS_LOCAL(user))
                {
                        MOD_RESULT = 0;
                        FOREACH_RESULT_I(Instance,I_OnUserPreJoin,OnUserPreJoin(user,NULL,cname));
@@ -430,6 +416,7 @@ chanrec* chanrec::ForceChan(InspIRCd* Instance, chanrec* Ptr,ucrec *a,userrec* u
                /* first user in is given ops */
                a->uc_modes = UCMODE_OP;
                Ptr->AddOppedUser(user);
+               Ptr->SetPrefix(user, '@', OP_VALUE, true);
        }
        else
        {
@@ -449,7 +436,6 @@ chanrec* chanrec::ForceChan(InspIRCd* Instance, chanrec* Ptr,ucrec *a,userrec* u
                        user->WriteServ("333 %s %s %s %lu", user->nick, Ptr->name, Ptr->setby, (unsigned long)Ptr->topicset);
                }
                Ptr->UserList(user);
-               user->WriteServ("366 %s %s :End of /NAMES list.", user->nick, Ptr->name);
        }
        FOREACH_MOD_I(Instance,I_OnUserJoin,OnUserJoin(user,Ptr));
        return Ptr;
@@ -481,6 +467,7 @@ long chanrec::PartUser(userrec *user, const char* reason)
                        }
                        user->chans[i]->uc_modes = 0;
                        user->chans[i]->channel = NULL;
+                       this->RemoveAllPrefixes(user);
                        break;
                }
        }
@@ -527,6 +514,7 @@ long chanrec::ServerKickUser(userrec* user, const char* reason, bool triggereven
                        this->WriteChannelWithServ(ServerInstance->Config->ServerName, "KICK %s %s :%s", this->name, user->nick, reason);
                        user->chans[i]->uc_modes = 0;
                        user->chans[i]->channel = NULL;
+                       this->RemoveAllPrefixes(user);
                        break;
                }
        }
@@ -609,6 +597,7 @@ long chanrec::KickUser(userrec *src, userrec *user, const char* reason)
                        this->WriteChannel(src, "KICK %s %s :%s", this->name, user->nick, reason);
                        (*i)->uc_modes = 0;
                        (*i)->channel = NULL;
+                       this->RemoveAllPrefixes(user);
                        break;
                }
        }
@@ -654,7 +643,7 @@ void chanrec::WriteChannel(userrec* user, const std::string &text)
 
        for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++)
        {
-               if (i->second->fd != FD_MAGIC_NUMBER)
+               if (IS_LOCAL(i->second))
                        user->WriteTo(i->second,text);
        }
 }
@@ -807,6 +796,14 @@ void chanrec::UserList(userrec *user)
 {
        char list[MAXBUF];
        size_t dlen, curlen;
+       int MOD_RESULT = 0;
+
+       FOREACH_RESULT(I_OnUserList,OnUserList(user, this));
+       ServerInstance->Log(DEBUG,"MOD_RESULT for UserList = %d",MOD_RESULT);
+       if (MOD_RESULT == 1)
+               return;
+
+       ServerInstance->Log(DEBUG,"Using builtin NAMES list generation");
 
        dlen = curlen = snprintf(list,MAXBUF,"353 %s = %s :", user->nick, this->name);
 
@@ -831,7 +828,7 @@ void chanrec::UserList(userrec *user)
                        continue;
                }
 
-               size_t ptrlen = snprintf(ptr, MAXBUF, "%s%s ", this->GetStatusChar(i->second), i->second->nick);
+               size_t ptrlen = snprintf(ptr, MAXBUF, "%s%s ", this->GetPrefixChar(i->second), i->second->nick);
 
                curlen += ptrlen;
                ptr += ptrlen;
@@ -857,6 +854,8 @@ void chanrec::UserList(userrec *user)
        {
                user->WriteServ(list);
        }
+
+       user->WriteServ("366 %s %s :End of /NAMES list.", user->nick, this->name);
 }
 
 long chanrec::GetMaxBans()
@@ -876,30 +875,67 @@ long chanrec::GetMaxBans()
 
 /* returns the status character for a given user on a channel, e.g. @ for op,
  * % for halfop etc. If the user has several modes set, the highest mode
- * the user has must be returned. */
-
-const char* chanrec::GetStatusChar(userrec *user)
+ * the user has must be returned.
+ */
+const char* chanrec::GetPrefixChar(userrec *user)
 {
-       for (std::vector<ucrec*>::const_iterator i = user->chans.begin(); i != user->chans.end(); i++)
+       static char px[2];
+       unsigned int mx = 0;
+
+       *px = 0;
+       *(px+1) = 0;
+
+       prefixlist::iterator n = prefixes.find(user);
+       if (n != prefixes.end())
        {
-               if ((*i)->channel == this)
+               for (std::vector<prefixtype>::iterator x = n->second.begin(); x != n->second.end(); x++)
                {
-                       if (((*i)->uc_modes & UCMODE_OP) > 0)
-                       {
-                               return "@";
-                       }
-                       if (((*i)->uc_modes & UCMODE_HOP) > 0)
-                       {
-                               return "%";
-                       }
-                       if (((*i)->uc_modes & UCMODE_VOICE) > 0)
+                       if (x->second > mx)
                        {
-                               return "+";
+                               *px = x->first;
+                               mx  = x->second;
                        }
-                       return "";
                }
        }
-       return "";
+
+       return px;
+}
+
+const char* chanrec::GetAllPrefixChars(userrec* user)
+{
+       static char prefix[MAXBUF];
+       int ctr = 0;
+       *prefix = 0;
+
+       prefixlist::iterator n = prefixes.find(user);
+       if (n != prefixes.end())
+       {
+               for (std::vector<prefixtype>::iterator x = n->second.begin(); x != n->second.end(); x++)
+               {
+                       prefix[ctr++] = x->first;
+               }
+       }
+
+       prefix[ctr] = 0;
+
+       return prefix;
+}
+
+unsigned int chanrec::GetPrefixValue(userrec* user)
+{
+       unsigned int mx = 0;
+
+       prefixlist::iterator n = prefixes.find(user);
+       if (n != prefixes.end())
+       {
+               for (std::vector<prefixtype>::iterator x = n->second.begin(); x != n->second.end(); x++)
+               {
+                       if (x->second > mx)
+                               mx  = x->second;
+               }
+       }
+
+       return mx;
 }
 
 
@@ -916,7 +952,6 @@ int chanrec::GetStatusFlags(userrec *user)
 }
 
 
-
 int chanrec::GetStatus(userrec *user)
 {
        if (ServerInstance->ULine(user->server))
@@ -944,4 +979,47 @@ int chanrec::GetStatus(userrec *user)
        return STATUS_NORMAL;
 }
 
+/*bool ModeParser::PrefixComparison(const prefixtype one, const prefixtype two)
+{       
+        return one.second > two.second;
+}*/
+
+void chanrec::SetPrefix(userrec* user, char prefix, unsigned int prefix_value, bool adding)
+{
+       prefixlist::iterator n = prefixes.find(user);
+       prefixtype pfx = std::make_pair(prefix,prefix_value);
+       if (adding)
+       {
+               if (n != prefixes.end())
+               {
+                       if (std::find(n->second.begin(), n->second.end(), pfx) == n->second.end())
+                       {
+                               n->second.push_back(pfx);
+                               std::sort(n->second.begin(), n->second.end(), ModeParser::PrefixComparison);
+                       }
+               }
+               else
+               {
+                       pfxcontainer one;
+                       one.push_back(pfx);
+                       prefixes.insert(std::make_pair<userrec*,pfxcontainer>(user, one));
+               }
+       }
+       else
+       {
+               if (n != prefixes.end())
+               {
+                       pfxcontainer::iterator x = std::find(n->second.begin(), n->second.end(), pfx);
+                       if (x != n->second.end())
+                               n->second.erase(x);
+               }
+       }
+}
+
+void chanrec::RemoveAllPrefixes(userrec* user)
+{
+       prefixlist::iterator n = prefixes.find(user);
+       if (n != prefixes.end())
+               prefixes.erase(n);
+}