]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/users.cpp
This should save 128 bytes per user for non-opers. Well worth it imho for a reasonabl...
[user/henk/code/inspircd.git] / src / users.cpp
index 286f08fe655573b39de8332cb339b034a86f6833..43ebfe0a3a2df1d6ac71b648d6afb0d498f7537f 100644 (file)
@@ -74,7 +74,7 @@ std::string User::ProcessNoticeMasks(const char *sm)
                                        }
                                }
                                else
-                                       this->WriteServ("501 %s %c :is unknown snomask char to me", this->nick, *c);
+                                       this->WriteNumeric(501, "%s %c :is unknown snomask char to me", this->nick, *c);
 
                                oldadding = adding;
                        break;
@@ -193,7 +193,11 @@ User::User(InspIRCd* Instance, const std::string &uid) : ServerInstance(Instance
        Visibility = NULL;
        ip = NULL;
        MyClass = NULL;
+       AllowedUserModes = NULL;
+       AllowedChanModes = NULL;
        AllowedOperCommands = NULL;
+       memset(AllowedUserModes, 0, sizeof(AllowedUserModes));
+       memset(AllowedChanModes, 0, sizeof(AllowedChanModes));
        chans.clear();
        invites.clear();
        memset(modes,0,sizeof(modes));
@@ -229,6 +233,18 @@ User::~User()
                AllowedOperCommands = NULL;
        }
 
+       if (this->AllowedUserModes)
+       {
+               delete AllowedUserModes;
+               AllowedUserModes = NULL;
+       }
+
+       if (this->AllowedChanModes)
+       {
+               delete AllowedChanModes;
+               AllowedChanModes = NULL;
+       }
+
        this->InvalidateCache();
        this->DecrementModes();
 
@@ -437,6 +453,21 @@ void User::RemoveInvite(const irc::string &channel)
        }
 }
 
+bool User::HasModePermission(unsigned char mode, ModeType type)
+{
+       if (!IS_LOCAL(this))
+               return true;
+
+       if (!IS_OPER(this))
+               return false;
+
+       if (!AllowedUserModes || !AllowedChanModes)
+               return false;
+
+       return ((type == MODETYPE_USER ? AllowedUserModes : AllowedChanModes))[(mode - 'A')];
+       
+}
+
 bool User::HasPermission(const std::string &command)
 {
        /*
@@ -669,6 +700,15 @@ void User::Oper(const std::string &opertype, const std::string &opername)
                        else
                                AllowedOperCommands = new std::map<std::string, bool>;
 
+                       if (!AllowedChanModes)
+                               AllowedChanModes = new bool[64];
+
+                       if (!AllowedUserModes)
+                               AllowedUserModes = new bool[64];
+
+                       memset(AllowedUserModes, 0, 64);
+                       memset(AllowedChanModes, 0, 64);
+
                        char* Classes = strdup(iter_opertype->second);
                        char* myclass = strtok_r(Classes," ",&savept);
                        while (myclass)
@@ -676,7 +716,7 @@ void User::Oper(const std::string &opertype, const std::string &opername)
                                operclass_t::iterator iter_operclass = ServerInstance->Config->operclass.find(myclass);
                                if (iter_operclass != ServerInstance->Config->operclass.end())
                                {
-                                       char* CommandList = strdup(iter_operclass->second);
+                                       char* CommandList = strdup(iter_operclass->second.commandlist);
                                        mycmd = strtok_r(CommandList," ",&savept2);
                                        while (mycmd)
                                        {
@@ -684,6 +724,29 @@ void User::Oper(const std::string &opertype, const std::string &opername)
                                                mycmd = strtok_r(NULL," ",&savept2);
                                        }
                                        free(CommandList);
+                                       this->AllowedUserModes['o' - 'A'] = true; // Call me paranoid if you want.
+                                       for (unsigned char* c = (unsigned char*)iter_operclass->second.umodelist; *c; ++c)
+                                       {
+                                               if (*c == '*')
+                                               {
+                                                       memset(this->AllowedUserModes, (int)(true), sizeof(this->AllowedUserModes));
+                                               }
+                                               else
+                                               {
+                                                       this->AllowedUserModes[*c - 'A'] = true;
+                                               }
+                                       }
+                                       for (unsigned char* c = (unsigned char*)iter_operclass->second.cmodelist; *c; ++c)
+                                       {
+                                               if (*c == '*')
+                                               {
+                                                       memset(this->AllowedChanModes, (int)(true), sizeof(this->AllowedChanModes));
+                                               }
+                                               else
+                                               {
+                                                       this->AllowedChanModes[*c - 'A'] = true;
+                                               }
+                                       }
                                }
                                myclass = strtok_r(NULL," ",&savept);
                        }
@@ -833,14 +896,14 @@ void User::FullConnect()
        }
 
        this->WriteServ("NOTICE Auth :Welcome to \002%s\002!",ServerInstance->Config->Network);
-       this->WriteServ("001 %s :Welcome to the %s IRC Network %s!%s@%s",this->nick, ServerInstance->Config->Network, this->nick, this->ident, this->host);
-       this->WriteServ("002 %s :Your host is %s, running version %s",this->nick,ServerInstance->Config->ServerName,VERSION);
-       this->WriteServ("003 %s :This server was created %s %s", this->nick, __TIME__, __DATE__);
-       this->WriteServ("004 %s %s %s %s %s %s", this->nick, ServerInstance->Config->ServerName, VERSION, ServerInstance->Modes->UserModeList().c_str(), ServerInstance->Modes->ChannelModeList().c_str(), ServerInstance->Modes->ParaModeList().c_str());
+       this->WriteNumeric(001, "%s :Welcome to the %s IRC Network %s!%s@%s",this->nick, ServerInstance->Config->Network, this->nick, this->ident, this->host);
+       this->WriteNumeric(002, "%s :Your host is %s, running version %s",this->nick,ServerInstance->Config->ServerName,VERSION);
+       this->WriteNumeric(003, "%s :This server was created %s %s", this->nick, __TIME__, __DATE__);
+       this->WriteNumeric(004, "%s %s %s %s %s %s", this->nick, ServerInstance->Config->ServerName, VERSION, ServerInstance->Modes->UserModeList().c_str(), ServerInstance->Modes->ChannelModeList().c_str(), ServerInstance->Modes->ParaModeList().c_str());
 
        ServerInstance->Config->Send005(this);
 
-       this->WriteServ("042 %s %s :your unique ID", this->nick, this->uuid);
+       this->WriteNumeric(42, "%s %s :your unique ID", this->nick, this->uuid);
 
 
        this->ShowMOTD();
@@ -1175,7 +1238,7 @@ void User::WriteNumeric(unsigned int numeric, const std::string &text)
        if (MOD_RESULT)
                return;
 
-       snprintf(textbuffer,MAXBUF,":%s %u %s %s",ServerInstance->Config->ServerName, numeric, this->nick, text.c_str());
+       snprintf(textbuffer,MAXBUF,":%s %03u %s",ServerInstance->Config->ServerName, numeric, text.c_str());
        this->Write(std::string(textbuffer));
 }
 
@@ -1464,7 +1527,7 @@ bool User::ChangeDisplayedHost(const char* shost)
        }
 
        if (IS_LOCAL(this))
-               this->WriteServ("396 %s %s :is now your displayed host",this->nick,this->dhost);
+               this->WriteNumeric(396, "%s %s :is now your displayed host",this->nick,this->dhost);
 
        return true;
 }
@@ -1708,31 +1771,31 @@ void User::ShowMOTD()
 {
        if (!ServerInstance->Config->MOTD.size())
        {
-               this->WriteServ("422 %s :Message of the day file is missing.",this->nick);
+               this->WriteNumeric(422, "%s :Message of the day file is missing.",this->nick);
                return;
        }
-       this->WriteServ("375 %s :%s message of the day", this->nick, ServerInstance->Config->ServerName);
+       this->WriteNumeric(375, "%s :%s message of the day", this->nick, ServerInstance->Config->ServerName);
 
        for (file_cache::iterator i = ServerInstance->Config->MOTD.begin(); i != ServerInstance->Config->MOTD.end(); i++)
-               this->WriteServ("372 %s :- %s",this->nick,i->c_str());
+               this->WriteNumeric(372, "%s :- %s",this->nick,i->c_str());
 
-       this->WriteServ("376 %s :End of message of the day.", this->nick);
+       this->WriteNumeric(376, "%s :End of message of the day.", this->nick);
 }
 
 void User::ShowRULES()
 {
        if (!ServerInstance->Config->RULES.size())
        {
-               this->WriteServ("434 %s :RULES File is missing",this->nick);
+               this->WriteNumeric(434, "%s :RULES File is missing",this->nick);
                return;
        }
 
-       this->WriteServ("308 %s :- %s Server Rules -",this->nick,ServerInstance->Config->ServerName);
+       this->WriteNumeric(308, "%s :- %s Server Rules -",this->nick,ServerInstance->Config->ServerName);
 
        for (file_cache::iterator i = ServerInstance->Config->RULES.begin(); i != ServerInstance->Config->RULES.end(); i++)
-               this->WriteServ("232 %s :- %s",this->nick,i->c_str());
+               this->WriteNumeric(232, "%s :- %s",this->nick,i->c_str());
 
-       this->WriteServ("309 %s :End of RULES command.",this->nick);
+       this->WriteNumeric(309, "%s :End of RULES command.",this->nick);
 }
 
 void User::HandleEvent(EventType et, int errornum)