X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmodules%2Fm_spanningtree.cpp;h=60eb650dd17748aa078a723db55f2b78a62a1e66;hb=5da606a02777de3d91f3b88d278ce49cadb67af5;hp=a8665350cd3c7b785965e6731a5c40bd7138bde5;hpb=3f1e3f22b57e934481193811d878dafb4c78691d;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/modules/m_spanningtree.cpp b/src/modules/m_spanningtree.cpp index a8665350c..60eb650dd 100644 --- a/src/modules/m_spanningtree.cpp +++ b/src/modules/m_spanningtree.cpp @@ -86,6 +86,7 @@ class ModuleSpanningTree; */ typedef nspace::hash_map, irc::StrHashComp> server_hash; +typedef std::map TreeServerList; /** The Link class might as well be a struct, * but this is C++ and we don't believe in structs (!). @@ -179,10 +180,10 @@ class SpanningTreeUtilities void ReadConfiguration(bool rebind); /** Add a server to the server list for GetListOfServersForChannel */ - void AddThisServer(TreeServer* server, std::deque &list); + void AddThisServer(TreeServer* server, TreeServerList &list); /** Compile a list of servers which contain members of channel c */ - void GetListOfServersForChannel(chanrec* c, std::deque &list); + void GetListOfServersForChannel(chanrec* c, TreeServerList &list, char status, const CUList &exempt_list); /** Find a server by name */ TreeServer* FindServer(const std::string &ServerName); @@ -1591,6 +1592,7 @@ class TreeSocket : public InspSocket userrec* who = NULL; /* User we are currently checking */ std::string channel = params[0]; /* Channel name, as a string */ time_t TS = atoi(params[1].c_str()); /* Timestamp given to us for remote side */ + bool created = false; /* Try and find the channel */ chanrec* chan = this->Instance->FindChan(channel); @@ -1606,6 +1608,8 @@ class TreeSocket : public InspSocket /* Does this channel exist? if it does, get its REAL timestamp */ if (chan) ourTS = chan->age; + else + created = true; /* don't perform deops, and set TS to correct time after processing. */ /* In 1.1, if they have the newer channel, we immediately clear * all status modes from our users. We then accept their modes. @@ -1617,18 +1621,19 @@ class TreeSocket : public InspSocket { std::deque param_list; - if (chan) - chan->age = TS; - /* Lower the TS here */ if (Utils->AnnounceTSChange && chan) chan->WriteChannelWithServ(Instance->Config->ServerName, "NOTICE %s :TS for %s changed from %lu to %lu", chan->name, chan->name, ourTS, TS); ourTS = TS; - param_list.push_back(channel); - /* Zap all the privilage modes on our side */ - this->RemoveStatus(Instance->Config->ServerName, param_list); + + /* Zap all the privilage modes on our side, if the channel exists here */ + if (!created) + { + this->RemoveStatus(Instance->Config->ServerName, param_list); + chan->age = TS; + } } /* Put the final parameter of the FJOIN into a tokenstream ready to split it */ @@ -1801,6 +1806,20 @@ class TreeSocket : public InspSocket free(mode_users[f]); } + /* if we newly created the channel, set it's TS properly. */ + if (created) + { + /* find created channel .. */ + chan = this->Instance->FindChan(channel); + if (chan) + /* w00t said this shouldnt be needed but it is. + * This isnt strictly true, as chan can be NULL + * if a nick collision has occured and therefore + * the channel was never created. + */ + chan->age = TS; + } + /* All done. That wasnt so bad was it, you can wipe * the sweat from your forehead now. :-) */ @@ -3045,11 +3064,11 @@ class TreeSocket : public InspSocket irc::string command; std::string prefix; + line = line.substr(0, line.find_first_of("\r\n")); + if (line.empty()) return true; - line = line.substr(0, line.find_first_of("\r\n")); - Instance->Log(DEBUG,"IN: %s", line.c_str()); this->Split(line.c_str(),params); @@ -3758,25 +3777,34 @@ SpanningTreeUtilities::~SpanningTreeUtilities() delete TreeRoot; } -void SpanningTreeUtilities::AddThisServer(TreeServer* server, std::deque &list) +void SpanningTreeUtilities::AddThisServer(TreeServer* server, TreeServerList &list) { - for (unsigned int c = 0; c < list.size(); c++) - { - if (list[c] == server) - { - return; - } - } - list.push_back(server); + if (list.find(server) == list.end()) + list[server] = server; } /** returns a list of DIRECT servernames for a specific channel */ -void SpanningTreeUtilities::GetListOfServersForChannel(chanrec* c, std::deque &list) +void SpanningTreeUtilities::GetListOfServersForChannel(chanrec* c, TreeServerList &list, char status, const CUList &exempt_list) { - CUList *ulist = c->GetUsers(); + CUList *ulist; + switch (status) + { + case '@': + ulist = c->GetOppedUsers(); + break; + case '%': + ulist = c->GetHalfoppedUsers(); + break; + case '+': + ulist = c->GetVoicedUsers(); + break; + default: + ulist = c->GetUsers(); + break; + } for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++) { - if (i->second->GetFd() < 0) + if ((i->second->GetFd() < 0) && (exempt_list.find(i->second) == exempt_list.end())) { TreeServer* best = this->BestRouteTo(i->second->server); if (best) @@ -3788,6 +3816,7 @@ void SpanningTreeUtilities::GetListOfServersForChannel(chanrec* c, std::deque ¶ms) { + char pfx = 0; TreeServer* omitroute = this->BestRouteTo(omit); if ((command == "NOTICE") || (command == "PRIVMSG")) { @@ -3796,6 +3825,7 @@ bool SpanningTreeUtilities::DoOneToAllButSenderRaw(const std::string &data, cons /* Prefixes */ if ((*(params[0].c_str()) == '@') || (*(params[0].c_str()) == '%') || (*(params[0].c_str()) == '+')) { + pfx = params[0][0]; params[0] = params[0].substr(1, params[0].length()-1); } if ((*(params[0].c_str()) != '#') && (*(params[0].c_str()) != '$')) @@ -3822,15 +3852,18 @@ bool SpanningTreeUtilities::DoOneToAllButSenderRaw(const std::string &data, cons else { chanrec* c = ServerInstance->FindChan(params[0]); - if (c) + userrec* u = ServerInstance->FindNick(prefix); + if (c && u) { - std::deque list; - GetListOfServersForChannel(c,list); - unsigned int lsize = list.size(); - for (unsigned int i = 0; i < lsize; i++) + CUList elist; + TreeServerList list; + FOREACH_MOD(I_OnBuildExemptList, OnBuildExemptList((command == "PRIVMSG" ? MSG_PRIVMSG : MSG_NOTICE), c, u, pfx, elist)); + GetListOfServersForChannel(c,list,pfx,elist); + + for (TreeServerList::iterator i = list.begin(); i != list.end(); i++) { - TreeSocket* Sock = list[i]->GetSocket(); - if ((Sock) && (list[i]->GetName() != omit) && (omitroute != list[i])) + TreeSocket* Sock = i->second->GetSocket(); + if ((Sock) && (i->second->GetName() != omit) && (omitroute != i->second)) { Sock->WriteLine(data); } @@ -4765,7 +4798,7 @@ class ModuleSpanningTree : public Module } } - virtual void OnUserNotice(userrec* user, void* dest, int target_type, const std::string &text, char status) + virtual void OnUserNotice(userrec* user, void* dest, int target_type, const std::string &text, char status, const CUList &exempt_list) { if (target_type == TYPE_USER) { @@ -4789,12 +4822,12 @@ class ModuleSpanningTree : public Module std::string cname = c->name; if (status) cname = status + cname; - std::deque list; - Utils->GetListOfServersForChannel(c,list); - unsigned int ucount = list.size(); - for (unsigned int i = 0; i < ucount; i++) + TreeServerList list; + Utils->GetListOfServersForChannel(c,list,status,exempt_list); + + for (TreeServerList::iterator i = list.begin(); i != list.end(); i++) { - TreeSocket* Sock = list[i]->GetSocket(); + TreeSocket* Sock = i->second->GetSocket(); if (Sock) Sock->WriteLine(":"+std::string(user->nick)+" NOTICE "+cname+" :"+text); } @@ -4814,7 +4847,7 @@ class ModuleSpanningTree : public Module } } - virtual void OnUserMessage(userrec* user, void* dest, int target_type, const std::string &text, char status) + virtual void OnUserMessage(userrec* user, void* dest, int target_type, const std::string &text, char status, const CUList &exempt_list) { if (target_type == TYPE_USER) { @@ -4840,12 +4873,12 @@ class ModuleSpanningTree : public Module std::string cname = c->name; if (status) cname = status + cname; - std::deque list; - Utils->GetListOfServersForChannel(c,list); - unsigned int ucount = list.size(); - for (unsigned int i = 0; i < ucount; i++) + TreeServerList list; + Utils->GetListOfServersForChannel(c,list,status,exempt_list); + + for (TreeServerList::iterator i = list.begin(); i != list.end(); i++) { - TreeSocket* Sock = list[i]->GetSocket(); + TreeSocket* Sock = i->second->GetSocket(); if (Sock) Sock->WriteLine(":"+std::string(user->nick)+" PRIVMSG "+cname+" :"+text); }