diff options
-rw-r--r-- | include/channels.h | 14 | ||||
-rw-r--r-- | include/helperfuncs.h | 4 | ||||
-rw-r--r-- | include/modules.h | 6 | ||||
-rw-r--r-- | src/channels.cpp | 70 | ||||
-rw-r--r-- | src/cmd_notice.cpp | 10 | ||||
-rw-r--r-- | src/cmd_privmsg.cpp | 10 | ||||
-rw-r--r-- | src/helperfuncs.cpp | 38 | ||||
-rw-r--r-- | src/mode.cpp | 6 | ||||
-rw-r--r-- | src/modules.cpp | 6 | ||||
-rw-r--r-- | src/modules/m_spanningtree.cpp | 19 |
10 files changed, 163 insertions, 20 deletions
diff --git a/include/channels.h b/include/channels.h index dd6d3b585..2bf03d6b4 100644 --- a/include/channels.h +++ b/include/channels.h @@ -116,7 +116,10 @@ class chanrec : public Extensible * (chicken and egg scenario!) */ std::map<char*,char*> internal_userlist; - + std::map<char*,char*> internal_op_userlist; + std::map<char*,char*> internal_halfop_userlist; + std::map<char*,char*> internal_voice_userlist; + /** Channel topic. * If this is an empty string, no channel topic is set. */ @@ -199,6 +202,9 @@ class chanrec : public Extensible * as this is a very fast 32 or 64 bit integer comparison. */ void AddUser(char* castuser); + void AddOppedUser(char* castuser); + void AddHalfoppedUser(char* castuser); + void AddVoicedUser(char* castuser); /** Delete a user pointer to the internal reference list * @param castuser This should be a pointer to a userrec, casted to char* @@ -208,6 +214,9 @@ class chanrec : public Extensible * as this is a very fast 32 or 64 bit integer comparison. */ void DelUser(char* castuser); + void DelOppedUser(char* castuser); + void DelHalfoppedUser(char* castuser); + void DelVoicedUser(char* castuser); /** Obrain the internal reference list * The internal reference list contains a list of userrec* @@ -219,6 +228,9 @@ class chanrec : public Extensible * @return This function returns a vector of userrec pointers, each of which has been casted to char* to prevent circular references */ std::map<char*,char*> *GetUsers(); + std::map<char*,char*> *GetOppedUsers(); + std::map<char*,char*> *GetHalfoppedUsers(); + std::map<char*,char*> *GetVoicedUsers(); /** Creates a channel record and initialises it with default values */ diff --git a/include/helperfuncs.h b/include/helperfuncs.h index 238d8f437..aaf6cf7fa 100644 --- a/include/helperfuncs.h +++ b/include/helperfuncs.h @@ -37,7 +37,7 @@ void WriteTo(userrec *source, userrec *dest,char *data, ...); void WriteChannel(chanrec* Ptr, userrec* user, char* text, ...); void WriteChannelLocal(chanrec* Ptr, userrec* user, char* text, ...); void WriteChannelWithServ(char* ServName, chanrec* Ptr, char* text, ...); -void ChanExceptSender(chanrec* Ptr, userrec* user, char* text, ...); +void ChanExceptSender(chanrec* Ptr, userrec* user, char status, char* text, ...); void Write_NoFormat(int sock,const char *text); void WriteServ_NoFormat(int sock, const char* text); @@ -46,7 +46,7 @@ void WriteTo_NoFormat(userrec *source, userrec *dest,const char *data); void WriteChannel_NoFormat(chanrec* Ptr, userrec* user, const char* text); void WriteChannelLocal_NoFormat(chanrec* Ptr, userrec* user, const char* text); void WriteChannelWithServ_NoFormat(char* ServName, chanrec* Ptr, const char* text); -void ChanExceptSender_NoFormat(chanrec* Ptr, userrec* user, const char* text); +void ChanExceptSender_NoFormat(chanrec* Ptr, char status, userrec* user, const char* text); void WriteCommon_NoFormat(userrec *u, const char* text); void WriteCommonExcept_NoFormat(userrec *u, const char* text); diff --git a/include/modules.h b/include/modules.h index 7b4cb4585..12df69a21 100644 --- a/include/modules.h +++ b/include/modules.h @@ -585,8 +585,9 @@ class Module : public classbase * @param dest The target of the message * @param target_type The type of target (TYPE_USER or TYPE_CHANNEL) * @param text the text being sent by the user + * @param status The status being used, e.g. PRIVMSG @#chan has status== '@', 0 to send to everyone. */ - virtual void OnUserMessage(userrec* user, void* dest, int target_type, std::string text); + virtual void OnUserMessage(userrec* user, void* dest, int target_type, std::string text, char status); /** Called after any NOTICE sent from a user. * The dest variable contains a userrec* if target_type is TYPE_USER and a chanrec* @@ -595,8 +596,9 @@ class Module : public classbase * @param dest The target of the message * @param target_type The type of target (TYPE_USER or TYPE_CHANNEL) * @param text the text being sent by the user + * @param status The status being used, e.g. NOTICE @#chan has status== '@', 0 to send to everyone. */ - virtual void OnUserNotice(userrec* user, void* dest, int target_type, std::string text); + virtual void OnUserNotice(userrec* user, void* dest, int target_type, std::string text, char status); /** Called after every MODE command sent from a user * The dest variable contains a userrec* if target_type is TYPE_USER and a chanrec* diff --git a/src/channels.cpp b/src/channels.cpp index a77947126..a55fbcb88 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -176,11 +176,80 @@ void chanrec::DelUser(char* castuser) log(DEBUG,"BUG BUG BUG! Attempt to remove an uncasted user from the internal list of %s!",name); } +void chanrec::AddOppedUser(char* castuser) +{ + internal_op_userlist[castuser] = castuser; + log(DEBUG,"Added casted user to channel's internal list"); +} + +void chanrec::DelOppedUser(char* castuser) +{ + std::map<char*,char*>::iterator a = internal_op_userlist.find(castuser); + if (a != internal_op_userlist.end()) + { + log(DEBUG,"Removed casted user from channel's internal list"); + internal_op_userlist.erase(a); + return; + } + log(DEBUG,"BUG BUG BUG! Attempt to remove an uncasted user from the internal list of %s!",name); +} + +void chanrec::AddHalfoppedUser(char* castuser) +{ + internal_halfop_userlist[castuser] = castuser; + log(DEBUG,"Added casted user to channel's internal list"); +} + +void chanrec::DelHalfoppedUser(char* castuser) +{ + std::map<char*,char*>::iterator a = internal_halfop_userlist.find(castuser); + if (a != internal_halfop_userlist.end()) + { + log(DEBUG,"Removed casted user from channel's internal list"); + internal_halfop_userlist.erase(a); + return; + } + log(DEBUG,"BUG BUG BUG! Attempt to remove an uncasted user from the internal list of %s!",name); +} + +void chanrec::AddVoicedUser(char* castuser) +{ + internal_voice_userlist[castuser] = castuser; + log(DEBUG,"Added casted user to channel's internal list"); +} + +void chanrec::DelOppedUser(char* castuser) +{ + std::map<char*,char*>::iterator a = internal_voice_userlist.find(castuser); + if (a != internal_voice_userlist.end()) + { + log(DEBUG,"Removed casted user from channel's internal list"); + internal_voice_userlist.erase(a); + return; + } + log(DEBUG,"BUG BUG BUG! Attempt to remove an uncasted user from the internal list of %s!",name); +} + std::map<char*,char*> *chanrec::GetUsers() { return &internal_userlist; } +std::map<char*,char*> *chanrec::GetOppedUsers() +{ + return &internal_op_userlist; +} + +std::map<char*,char*> *chanrec::GetHalfoppedUsers() +{ + return &internal_halfop_userlist; +} + +std::map<char*,char*> *chanrec::GetVoicedUsers() +{ + return &internal_voice_userlist; +} + /* add a channel to a user, creating the record for it if needed and linking * it to the user record */ @@ -369,6 +438,7 @@ chanrec* ForceChan(chanrec* Ptr,ucrec &a,userrec* user, int created) { /* first user in is given ops */ a.uc_modes = UCMODE_OP; + Ptr->AddOppedUser((char*)user); } else { diff --git a/src/cmd_notice.cpp b/src/cmd_notice.cpp index 41122374d..264fb5a08 100644 --- a/src/cmd_notice.cpp +++ b/src/cmd_notice.cpp @@ -82,7 +82,13 @@ void cmd_notice::Handle (char **parameters, int pcnt, userrec *user) } return; } - else if (parameters[0][0] == '#') + char status = 0; + if ((*parameters[0] == '@') || (*parameters[0] == '%') || (*parameters[0] == '+')) + { + status = *parameters[0]; + parameters[0]++; + } + if (*parameters[0] == '#') { chan = FindChan(parameters[0]); if (chan) @@ -116,7 +122,7 @@ void cmd_notice::Handle (char **parameters, int pcnt, userrec *user) return; } - ChanExceptSender(chan, user, "NOTICE %s :%s", chan->name, parameters[1]); + ChanExceptSender(chan, user, status, "NOTICE %s :%s", chan->name, parameters[1]); FOREACH_MOD(I_OnUserNotice,OnUserNotice(user,chan,TYPE_CHANNEL,parameters[1])); } diff --git a/src/cmd_privmsg.cpp b/src/cmd_privmsg.cpp index 55ff8fb36..f734ed588 100644 --- a/src/cmd_privmsg.cpp +++ b/src/cmd_privmsg.cpp @@ -82,7 +82,13 @@ void cmd_privmsg::Handle (char **parameters, int pcnt, userrec *user) } return; } - else if (parameters[0][0] == '#') + char status = 0; + if ((*parameters[0] == '@') || (*parameters[0] == '%') || (*parameters[0] == '+')) + { + status = *parameters[0]; + parameters[0]++; + } + if (parameters[0][0] == '#') { chan = FindChan(parameters[0]); if (chan) @@ -115,7 +121,7 @@ void cmd_privmsg::Handle (char **parameters, int pcnt, userrec *user) return; } - ChanExceptSender(chan, user, "PRIVMSG %s :%s", chan->name, parameters[1]); + ChanExceptSender(chan, user, status, "PRIVMSG %s :%s", chan->name, parameters[1]); FOREACH_MOD(I_OnUserMessage,OnUserMessage(user,chan,TYPE_CHANNEL,parameters[1])); } else diff --git a/src/helperfuncs.cpp b/src/helperfuncs.cpp index c6396705c..20dd6cb13 100644 --- a/src/helperfuncs.cpp +++ b/src/helperfuncs.cpp @@ -484,7 +484,7 @@ void WriteChannelWithServ_NoFormat(char* ServName, chanrec* Ptr, const char* tex /* write formatted text from a source user to all users on a channel except * for the sender (for privmsg etc) */ -void ChanExceptSender(chanrec* Ptr, userrec* user, char* text, ...) +void ChanExceptSender(chanrec* Ptr, userrec* user, char status, char* text, ...) { if ((!Ptr) || (!user) || (!text)) { @@ -497,7 +497,22 @@ void ChanExceptSender(chanrec* Ptr, userrec* user, char* text, ...) vsnprintf(textbuffer, MAXBUF, text, argsPtr); va_end(argsPtr); - std::map<char*,char*> *ulist= Ptr->GetUsers(); + std::map<char*,char*> *ulist; + switch (status) + { + case '@': + Ptr->GetOppedUsers(); + break; + case '%': + Ptr->GetHalfoppedUsers(); + break; + case '+': + Ptr->GetVoicedUsers(); + break; + default: + Ptr->GetUsers(); + break; + } for (std::map<char*,char*>::iterator i = ulist->begin(); i != ulist->end(); i++) { char* o = i->second; @@ -507,14 +522,29 @@ void ChanExceptSender(chanrec* Ptr, userrec* user, char* text, ...) } } -void ChanExceptSender_NoFormat(chanrec* Ptr, userrec* user, const char* text) +void ChanExceptSender_NoFormat(chanrec* Ptr, userrec* user, char status, const char* text) { if ((!Ptr) || (!user) || (!text)) { log(DEFAULT,"*** BUG *** ChanExceptSender was given an invalid parameter"); return; } - std::map<char*,char*> *ulist= Ptr->GetUsers(); + std::map<char*,char*> *ulist; + switch (status) + { + case '@': + Ptr->GetOppedUsers(); + break; + case '%': + Ptr->GetHalfoppedUsers(); + break; + case '+': + Ptr->GetVoicedUsers(); + break; + default: + Ptr->GetUsers(); + break; + } for (std::map<char*,char*>::iterator i = ulist->begin(); i != ulist->end(); i++) { char* o = i->second; diff --git a/src/mode.cpp b/src/mode.cpp index 898492f38..993f6cd74 100644 --- a/src/mode.cpp +++ b/src/mode.cpp @@ -103,6 +103,7 @@ char* ModeParser::GiveOps(userrec *user,char *dest,chanrec *chan,int status) return NULL; } d->chans[i].uc_modes = d->chans[i].uc_modes | UCMODE_OP; + d->chans[i].channel->AddOppedUser((char*)d); log(DEBUG,"gave ops: %s %s",d->chans[i].channel->name,d->nick); return d->nick; } @@ -158,6 +159,7 @@ char* ModeParser::GiveHops(userrec *user,char *dest,chanrec *chan,int status) return NULL; } d->chans[i].uc_modes = d->chans[i].uc_modes | UCMODE_HOP; + d->chans[i].channel->AddHalfoppedUser((char*)d); log(DEBUG,"gave h-ops: %s %s",d->chans[i].channel->name,d->nick); return d->nick; } @@ -212,6 +214,7 @@ char* ModeParser::GiveVoice(userrec *user,char *dest,chanrec *chan,int status) return NULL; } d->chans[i].uc_modes = d->chans[i].uc_modes | UCMODE_VOICE; + d->chans[i].channel->AddVoicedUser((char*)d); log(DEBUG,"gave voice: %s %s",d->chans[i].channel->name,d->nick); return d->nick; } @@ -267,6 +270,7 @@ char* ModeParser::TakeOps(userrec *user,char *dest,chanrec *chan,int status) return NULL; } d->chans[i].uc_modes ^= UCMODE_OP; + d->chans[i].channel->DelOppedUser((char*)d); log(DEBUG,"took ops: %s %s",d->chans[i].channel->name,d->nick); return d->nick; } @@ -323,6 +327,7 @@ char* ModeParser::TakeHops(userrec *user,char *dest,chanrec *chan,int status) return NULL; } d->chans[i].uc_modes ^= UCMODE_HOP; + d->chans[i].channel->DelHalfoppedUser((char*)d); log(DEBUG,"took h-ops: %s %s",d->chans[i].channel->name,d->nick); return d->nick; } @@ -377,6 +382,7 @@ char* ModeParser::TakeVoice(userrec *user,char *dest,chanrec *chan,int status) return NULL; } d->chans[i].uc_modes ^= UCMODE_VOICE; + d->chans[i].channel->DelVoicedUser((char*)d); log(DEBUG,"took voice: %s %s",d->chans[i].channel->name,d->nick); return d->nick; } diff --git a/src/modules.cpp b/src/modules.cpp index c7b7fadc1..f4ba90282 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -272,8 +272,8 @@ int Module::OnRawSocketWrite(int fd, char* buffer, int count) { return 0; }; void Module::OnRawSocketClose(int fd) { }; int Module::OnRawSocketRead(int fd, char* buffer, unsigned int count, int &readresult) { return 0; }; void Module::OnUserMessage(userrec* user, void* dest, int target_type, std::string text) { }; -void Module::OnUserNotice(userrec* user, void* dest, int target_type, std::string text) { }; -void Module::OnRemoteKill(userrec* source, userrec* dest, std::string reason) { }; +void Module::OnUserNotice(userrec* user, void* dest, int target_type, std::string text, char status) { }; +void Module::OnRemoteKill(userrec* source, userrec* dest, std::string reason, char status) { }; void Module::OnUserInvite(userrec* source,userrec* dest,chanrec* channel) { }; void Module::OnPostLocalTopicChange(userrec* user, chanrec* chan, std::string topic) { }; void Module::OnGetServerDescription(std::string servername,std::string &description) { }; @@ -523,7 +523,7 @@ void Server::SendChannel(userrec* User, chanrec* Channel, std::string s,bool Inc } else { - ChanExceptSender_NoFormat(Channel,User,s.c_str()); + ChanExceptSender_NoFormat(Channel,User,0,s.c_str()); } } diff --git a/src/modules/m_spanningtree.cpp b/src/modules/m_spanningtree.cpp index fcd07d4d4..4e3d4cc1e 100644 --- a/src/modules/m_spanningtree.cpp +++ b/src/modules/m_spanningtree.cpp @@ -2296,6 +2296,11 @@ bool DoOneToAllButSenderRaw(std::string data, std::string omit, std::string pref { if ((params.size() >= 2) && (*(params[0].c_str()) != '$')) { + /* Prefixes */ + if ((*(params[0].c_str()) == '@') || (*(params[0].c_str()) == '%') || (*(params[0].c_str()) == '+')) + { + params[0] = params[0].substr(1, params[0].length()-1); + } if (*(params[0].c_str()) != '#') { // special routing for private messages/notices @@ -2984,7 +2989,7 @@ class ModuleSpanningTree : public Module } } - virtual void OnUserNotice(userrec* user, void* dest, int target_type, std::string text) + virtual void OnUserNotice(userrec* user, void* dest, int target_type, std::string text, char status) { if (target_type == TYPE_USER) { @@ -3002,6 +3007,9 @@ class ModuleSpanningTree : public Module { if (user->fd > -1) { + std::string cname = c->name; + if (status) + cname = status + cname; chanrec *c = (chanrec*)dest; std::deque<TreeServer*> list; GetListOfServersForChannel(c,list); @@ -3010,13 +3018,13 @@ class ModuleSpanningTree : public Module { TreeSocket* Sock = list[i]->GetSocket(); if (Sock) - Sock->WriteLine(":"+std::string(user->nick)+" NOTICE "+std::string(c->name)+" :"+text); + Sock->WriteLine(":"+std::string(user->nick)+" NOTICE "+cname+" :"+text); } } } } - virtual void OnUserMessage(userrec* user, void* dest, int target_type, std::string text) + virtual void OnUserMessage(userrec* user, void* dest, int target_type, std::string text, char status) { if (target_type == TYPE_USER) { @@ -3036,6 +3044,9 @@ class ModuleSpanningTree : public Module { if (user->fd > -1) { + std::string cname = c->name; + if (status) + cname = status + cname; chanrec *c = (chanrec*)dest; std::deque<TreeServer*> list; GetListOfServersForChannel(c,list); @@ -3044,7 +3055,7 @@ class ModuleSpanningTree : public Module { TreeSocket* Sock = list[i]->GetSocket(); if (Sock) - Sock->WriteLine(":"+std::string(user->nick)+" PRIVMSG "+std::string(c->name)+" :"+text); + Sock->WriteLine(":"+std::string(user->nick)+" PRIVMSG "+cname+" :"+text); } } } |