diff options
-rw-r--r-- | include/message.h | 1 | ||||
-rw-r--r-- | src/message.cpp | 18 | ||||
-rw-r--r-- | src/modules/m_spanningtree.cpp | 43 |
3 files changed, 61 insertions, 1 deletions
diff --git a/include/message.h b/include/message.h index a7c2c4036..fb0e7cb64 100644 --- a/include/message.h +++ b/include/message.h @@ -46,5 +46,6 @@ int has_channel(userrec *u, chanrec *c); void TidyBan(char *ban); std::string chlist(userrec *user, userrec* source); void send_network_quit(const char* nick, const char* reason); +int cflags(userrec *user, chanrec *chan); #endif diff --git a/src/message.cpp b/src/message.cpp index 0f49f9a0a..d071b13f0 100644 --- a/src/message.cpp +++ b/src/message.cpp @@ -325,6 +325,24 @@ char* cmode(userrec *user, chanrec *chan) return ""; } +int cflags(userrec *user, chanrec *chan) +{ + if ((!chan) || (!user)) + return 0; + + for (unsigned int i = 0; i < user->chans.size(); i++) + { + if (user->chans[i].channel) + { + if ((!strcasecmp(user->chans[i].channel->name,chan->name)) && (chan != NULL)) + { + return user->chans[i].uc_modes; + } + } + } + return 0; +} + /* returns the status value for a given user on a channel, e.g. STATUS_OP for * op, STATUS_VOICE for voice etc. If the user has several modes set, the * highest mode the user has must be returned. */ diff --git a/src/modules/m_spanningtree.cpp b/src/modules/m_spanningtree.cpp index a95d40b2f..060c4c39b 100644 --- a/src/modules/m_spanningtree.cpp +++ b/src/modules/m_spanningtree.cpp @@ -1129,26 +1129,67 @@ class TreeSocket : public InspSocket { log(DEBUG,"Sending FJOINs to other server for %s",c->name); char list[MAXBUF]; + std::string individual_halfops = ":"+Srv->GetServerName()+" FMODE "+c->name; snprintf(list,MAXBUF,":%s FJOIN %s %lu",Srv->GetServerName().c_str(),c->name,(unsigned long)c->age); std::map<char*,char*> *ulist = c->GetUsers(); + std::vector<userrec*> specific_halfop; + std::vector<userrec*> specific_voice; for (std::map<char*,char*>::iterator i = ulist->begin(); i != ulist->end(); i++) { char* o = i->second; userrec* otheruser = (userrec*)o; strlcat(list," ",MAXBUF); - strlcat(list,cmode(otheruser,c),MAXBUF); + int x = cflags(otheruser,c); + if ((x & UCMODE_HOP) && (x & UCMODE_OP)) + { + specific_halfop.push_back(otheruser); + } + if (((x & UCMODE_HOP) || (x & UCMODE_OP)) && (x & UCMODE_VOICE)) + { + specific_voice.push_back(otheruser); + } + char* n = ""; + if (x & UCMODE_OP) + { + n = "@"; + } + else if (x & UCMODE_HOP) + { + n = "%"; + } + else if (x & UCMODE_VOICE) + { + n = "+"; + } + strlcat(list,n,MAXBUF); strlcat(list,otheruser->nick,MAXBUF); if (strlen(list)>(480-NICKMAX)) { log(DEBUG,"FJOIN line wrapped"); this->WriteLine(list); snprintf(list,MAXBUF,":%s FJOIN %s %lu",Srv->GetServerName().c_str(),c->name,(unsigned long)c->age); + for (unsigned int y = 0; y < specific_voice.size(); y++) + { + this->WriteLine(":"+Srv->GetServerName()+" FMODE "+c->name+" +v "+specific_voice[y]->nick); + } + for (unsigned int y = 0; y < specific_halfop.size(); y++) + { + this->WriteLine(":"+Srv->GetServerName()+" FMODE "+c->name+" +h "+specific_halfop[y]->nick); + } } } if (list[strlen(list)-1] != ':') { log(DEBUG,"Final FJOIN line"); this->WriteLine(list); + for (unsigned int y = 0; y < specific_voice.size(); y++) + { + this->WriteLine(":"+Srv->GetServerName()+" FMODE "+c->name+" +v "+specific_voice[y]->nick); + } + for (unsigned int y = 0; y < specific_halfop.size(); y++) + { + this->WriteLine(":"+Srv->GetServerName()+" FMODE "+c->name+" +h "+specific_halfop[y]->nick); + } } } |