mirror of
https://github.com/inspircd/inspircd.git
synced 2025-03-09 18:49:03 -04:00
Convert UserChanList to an intrusively linked list
This commit is contained in:
parent
9a962e1c51
commit
932e8d13f8
@ -43,6 +43,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "intrusive_list.h"
|
||||
#include "compat.h"
|
||||
#include "typedefs.h"
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* InspIRCd -- Internet Relay Chat Daemon
|
||||
*
|
||||
* Copyright (C) 2012-2014 Attila Molnar <attilamolnar@hush.com>
|
||||
* Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
|
||||
*
|
||||
* This file is part of InspIRCd. InspIRCd is free software: you can
|
||||
@ -19,7 +20,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
class CoreExport Membership : public Extensible
|
||||
class CoreExport Membership : public Extensible, public intrusive_list_node<Membership>
|
||||
{
|
||||
public:
|
||||
User* const user;
|
||||
|
@ -556,7 +556,7 @@ class CoreExport Module : public classbase, public usecountbase
|
||||
*
|
||||
* Set exceptions[user] = true to include, exceptions[user] = false to exclude
|
||||
*/
|
||||
virtual void OnBuildNeighborList(User* source, UserChanList &include_c, std::map<User*,bool> &exceptions);
|
||||
virtual void OnBuildNeighborList(User* source, IncludeChanList& include_c, std::map<User*, bool>& exceptions);
|
||||
|
||||
/** Called before any nickchange, local or remote. This can be used to implement Q-lines etc.
|
||||
* Please note that although you can see remote nickchanges through this function, you should
|
||||
|
@ -72,12 +72,16 @@ typedef std::vector<reference<ConnectClass> > ClassVector;
|
||||
|
||||
/** Typedef for the list of user-channel records for a user
|
||||
*/
|
||||
typedef std::set<Channel*> UserChanList;
|
||||
typedef intrusive_list<Membership> UserChanList;
|
||||
|
||||
/** Shorthand for an iterator into a UserChanList
|
||||
*/
|
||||
typedef UserChanList::iterator UCListIter;
|
||||
|
||||
/** List of channels to consider when building the neighbor list of a user
|
||||
*/
|
||||
typedef std::vector<Membership*> IncludeChanList;
|
||||
|
||||
/** A list of custom modes parameters on a channel
|
||||
*/
|
||||
typedef std::map<char,std::string> CustomModeList;
|
||||
|
@ -331,7 +331,7 @@ void Channel::ForceJoin(User* user, const std::string* privs, bool bursting, boo
|
||||
if (!memb)
|
||||
return; // Already on the channel
|
||||
|
||||
user->chans.insert(this);
|
||||
user->chans.push_front(memb);
|
||||
|
||||
if (privs)
|
||||
{
|
||||
@ -466,7 +466,7 @@ void Channel::PartUser(User *user, std::string &reason)
|
||||
WriteAllExcept(user, false, 0, except_list, "PART %s%s%s", this->name.c_str(), reason.empty() ? "" : " :", reason.c_str());
|
||||
|
||||
// Remove this channel from the user's chanlist
|
||||
user->chans.erase(this);
|
||||
user->chans.erase(memb);
|
||||
// Remove the Membership from this channel's userlist and destroy it
|
||||
this->DelUser(membiter);
|
||||
}
|
||||
@ -520,7 +520,7 @@ void Channel::KickUser(User* src, User* victim, const std::string& reason, Membe
|
||||
|
||||
WriteAllExcept(src, false, 0, except_list, "KICK %s %s :%s", name.c_str(), victim->nick.c_str(), reason.c_str());
|
||||
|
||||
victim->chans.erase(this);
|
||||
victim->chans.erase(memb);
|
||||
this->DelUser(victimiter);
|
||||
}
|
||||
|
||||
|
@ -45,10 +45,9 @@ class CommandWho : public Command
|
||||
|
||||
Channel* get_first_visible_channel(User *u)
|
||||
{
|
||||
UCListIter i = u->chans.begin();
|
||||
while (i != u->chans.end())
|
||||
for (UCListIter i = u->chans.begin(); i != u->chans.end(); ++i)
|
||||
{
|
||||
Channel* c = *i++;
|
||||
Channel* c = (*i)->chan;
|
||||
if (!c->IsModeSet(secretmode))
|
||||
return c;
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ std::string CommandWhois::ChannelList(User* source, User* dest, bool spy)
|
||||
|
||||
for (UCListIter i = dest->chans.begin(); i != dest->chans.end(); i++)
|
||||
{
|
||||
Channel* c = *i;
|
||||
Channel* c = (*i)->chan;
|
||||
/* If the target is the sender, neither +p nor +s is set, or
|
||||
* the channel contains the user, it is not a spy channel
|
||||
*/
|
||||
|
@ -147,7 +147,7 @@ ModResult Module::OnChannelPreDelete(Channel*) { DetachEvent(I_OnChannelPreDelet
|
||||
void Module::OnChannelDelete(Channel*) { DetachEvent(I_OnChannelDelete); }
|
||||
ModResult Module::OnSetAway(User*, const std::string &) { DetachEvent(I_OnSetAway); return MOD_RES_PASSTHRU; }
|
||||
ModResult Module::OnWhoisLine(User*, User*, int&, std::string&) { DetachEvent(I_OnWhoisLine); return MOD_RES_PASSTHRU; }
|
||||
void Module::OnBuildNeighborList(User*, UserChanList&, std::map<User*,bool>&) { DetachEvent(I_OnBuildNeighborList); }
|
||||
void Module::OnBuildNeighborList(User*, IncludeChanList&, std::map<User*,bool>&) { DetachEvent(I_OnBuildNeighborList); }
|
||||
void Module::OnGarbageCollect() { DetachEvent(I_OnGarbageCollect); }
|
||||
ModResult Module::OnSetConnectClass(LocalUser* user, ConnectClass* myclass) { DetachEvent(I_OnSetConnectClass); return MOD_RES_PASSTHRU; }
|
||||
void Module::OnText(User*, void*, int, const std::string&, char, CUList&) { DetachEvent(I_OnText); }
|
||||
|
@ -129,19 +129,21 @@ class ModuleAuditorium : public Module
|
||||
BuildExcept(memb, excepts);
|
||||
}
|
||||
|
||||
void OnBuildNeighborList(User* source, UserChanList &include, std::map<User*,bool> &exception) CXX11_OVERRIDE
|
||||
void OnBuildNeighborList(User* source, IncludeChanList& include, std::map<User*, bool>& exception) CXX11_OVERRIDE
|
||||
{
|
||||
UCListIter i = include.begin();
|
||||
while (i != include.end())
|
||||
for (IncludeChanList::iterator i = include.begin(); i != include.end(); )
|
||||
{
|
||||
Channel* c = *i++;
|
||||
Membership* memb = c->GetUser(source);
|
||||
if (!memb || IsVisible(memb))
|
||||
Membership* memb = *i;
|
||||
if (IsVisible(memb))
|
||||
{
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
|
||||
// this channel should not be considered when listing my neighbors
|
||||
include.erase(c);
|
||||
i = include.erase(i);
|
||||
// however, that might hide me from ops that can see me...
|
||||
const UserMembList* users = c->GetUsers();
|
||||
const UserMembList* users = memb->chan->GetUsers();
|
||||
for(UserMembCIter j = users->begin(); j != users->end(); j++)
|
||||
{
|
||||
if (IS_LOCAL(j->first) && CanSee(j->first, memb))
|
||||
|
@ -42,15 +42,9 @@ class ModuleBadChannelExtban : public Module
|
||||
}
|
||||
for (UCListIter i = user->chans.begin(); i != user->chans.end(); i++)
|
||||
{
|
||||
if (InspIRCd::Match((**i).name, rm))
|
||||
if (InspIRCd::Match((*i)->chan->name, rm))
|
||||
{
|
||||
if (status)
|
||||
{
|
||||
Membership* memb = (**i).GetUser(user);
|
||||
if (memb && memb->hasMode(status))
|
||||
return MOD_RES_DENY;
|
||||
}
|
||||
else
|
||||
if (!status || (*i)->hasMode(status))
|
||||
return MOD_RES_DENY;
|
||||
}
|
||||
}
|
||||
|
@ -192,7 +192,7 @@ class CommandCheck : public Command
|
||||
|
||||
for (UCListIter i = targuser->chans.begin(); i != targuser->chans.end(); i++)
|
||||
{
|
||||
Channel* c = *i;
|
||||
Channel* c = (*i)->chan;
|
||||
chliststr.append(c->GetPrefixChar(targuser)).append(c->name).append(" ");
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ class ModuleDelayJoin : public Module
|
||||
void CleanUser(User* user);
|
||||
void OnUserPart(Membership*, std::string &partmessage, CUList&) CXX11_OVERRIDE;
|
||||
void OnUserKick(User* source, Membership*, const std::string &reason, CUList&) CXX11_OVERRIDE;
|
||||
void OnBuildNeighborList(User* source, UserChanList &include, std::map<User*,bool> &exception) CXX11_OVERRIDE;
|
||||
void OnBuildNeighborList(User* source, IncludeChanList& include, std::map<User*, bool>& exception) CXX11_OVERRIDE;
|
||||
void OnText(User* user, void* dest, int target_type, const std::string &text, char status, CUList &exempt_list) CXX11_OVERRIDE;
|
||||
ModResult OnRawMode(User* user, Channel* channel, const char mode, const std::string ¶m, bool adding, int pcnt) CXX11_OVERRIDE;
|
||||
};
|
||||
@ -123,15 +123,15 @@ void ModuleDelayJoin::OnUserKick(User* source, Membership* memb, const std::stri
|
||||
populate(except, memb);
|
||||
}
|
||||
|
||||
void ModuleDelayJoin::OnBuildNeighborList(User* source, UserChanList &include, std::map<User*,bool> &exception)
|
||||
void ModuleDelayJoin::OnBuildNeighborList(User* source, IncludeChanList& include, std::map<User*, bool>& exception)
|
||||
{
|
||||
UCListIter i = include.begin();
|
||||
while (i != include.end())
|
||||
for (IncludeChanList::iterator i = include.begin(); i != include.end(); )
|
||||
{
|
||||
Channel* c = *i++;
|
||||
Membership* memb = c->GetUser(source);
|
||||
if (memb && unjoined.get(memb))
|
||||
include.erase(c);
|
||||
Membership* memb = *i;
|
||||
if (unjoined.get(memb))
|
||||
i = include.erase(i);
|
||||
else
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ class ModuleHostCycle : public Module
|
||||
already_sent_t silent_id = ++LocalUser::already_sent_id;
|
||||
already_sent_t seen_id = ++LocalUser::already_sent_id;
|
||||
|
||||
UserChanList include_chans(user->chans);
|
||||
IncludeChanList include_chans(user->chans.begin(), user->chans.end());
|
||||
std::map<User*,bool> exceptions;
|
||||
|
||||
FOREACH_MOD(OnBuildNeighborList, (user, include_chans, exceptions));
|
||||
@ -56,10 +56,10 @@ class ModuleHostCycle : public Module
|
||||
|
||||
std::string newfullhost = user->nick + "!" + newident + "@" + newhost;
|
||||
|
||||
for (UCListIter i = include_chans.begin(); i != include_chans.end(); ++i)
|
||||
for (IncludeChanList::const_iterator i = include_chans.begin(); i != include_chans.end(); ++i)
|
||||
{
|
||||
Channel* c = *i;
|
||||
Membership* memb = c->GetUser(user);
|
||||
Membership* memb = *i;
|
||||
Channel* c = memb->chan;
|
||||
const std::string joinline = ":" + newfullhost + " JOIN " + c->name;
|
||||
std::string modeline;
|
||||
|
||||
|
@ -33,7 +33,7 @@ class ModuleIRCv3 : public Module
|
||||
|
||||
void WriteNeighboursWithExt(User* user, const std::string& line, const LocalIntExt& ext)
|
||||
{
|
||||
UserChanList chans(user->chans);
|
||||
IncludeChanList chans(user->chans.begin(), user->chans.end());
|
||||
|
||||
std::map<User*, bool> exceptions;
|
||||
FOREACH_MOD(OnBuildNeighborList, (user, chans, exceptions));
|
||||
@ -48,9 +48,9 @@ class ModuleIRCv3 : public Module
|
||||
|
||||
// Now consider sending it to all other users who has at least a common channel with the user
|
||||
std::set<User*> already_sent;
|
||||
for (UCListIter i = chans.begin(); i != chans.end(); ++i)
|
||||
for (IncludeChanList::const_iterator i = chans.begin(); i != chans.end(); ++i)
|
||||
{
|
||||
const UserMembList* userlist = (*i)->GetUsers();
|
||||
const UserMembList* userlist = (*i)->chan->GetUsers();
|
||||
for (UserMembList::const_iterator m = userlist->begin(); m != userlist->end(); ++m)
|
||||
{
|
||||
/*
|
||||
|
@ -140,7 +140,7 @@ class ModuleNickFlood : public Module
|
||||
{
|
||||
for (UCListIter i = user->chans.begin(); i != user->chans.end(); i++)
|
||||
{
|
||||
Channel *channel = *i;
|
||||
Channel* channel = (*i)->chan;
|
||||
ModResult res;
|
||||
|
||||
nickfloodsettings *f = nf.ext.get(channel);
|
||||
@ -179,7 +179,7 @@ class ModuleNickFlood : public Module
|
||||
|
||||
for (UCListIter i = user->chans.begin(); i != user->chans.end(); ++i)
|
||||
{
|
||||
Channel *channel = *i;
|
||||
Channel* channel = (*i)->chan;
|
||||
ModResult res;
|
||||
|
||||
nickfloodsettings *f = nf.ext.get(channel);
|
||||
|
@ -53,7 +53,7 @@ class ModuleNoNickChange : public Module
|
||||
|
||||
for (UCListIter i = user->chans.begin(); i != user->chans.end(); i++)
|
||||
{
|
||||
Channel* curr = *i;
|
||||
Channel* curr = (*i)->chan;
|
||||
|
||||
ModResult res = ServerInstance->OnCheckExemption(user,curr,"nonick");
|
||||
|
||||
|
@ -81,7 +81,7 @@ class ModuleOperPrefixMode : public Module
|
||||
modechange.push_back(user->nick);
|
||||
for (UCListIter v = user->chans.begin(); v != user->chans.end(); v++)
|
||||
{
|
||||
modechange[0] = (*v)->name;
|
||||
modechange[0] = (*v)->chan->name;
|
||||
ServerInstance->Modes->Process(modechange, ServerInstance->FakeClient);
|
||||
}
|
||||
}
|
||||
|
@ -682,7 +682,7 @@ bool User::ChangeNick(const std::string& newnick, bool force)
|
||||
{
|
||||
for (UCListIter i = this->chans.begin(); i != this->chans.end(); i++)
|
||||
{
|
||||
Channel *chan = *i;
|
||||
Channel* chan = (*i)->chan;
|
||||
if (chan->GetPrefixValue(this) < VOICE_VALUE && chan->IsBanned(this))
|
||||
{
|
||||
this->WriteNumeric(ERR_CANNOTSENDTOCHAN, "%s :Cannot send to channel (you're banned)", chan->name.c_str());
|
||||
@ -962,7 +962,7 @@ void User::WriteCommonRaw(const std::string &line, bool include_self)
|
||||
|
||||
LocalUser::already_sent_id++;
|
||||
|
||||
UserChanList include_c(chans);
|
||||
IncludeChanList include_c(chans.begin(), chans.end());
|
||||
std::map<User*,bool> exceptions;
|
||||
|
||||
exceptions[this] = include_self;
|
||||
@ -979,9 +979,9 @@ void User::WriteCommonRaw(const std::string &line, bool include_self)
|
||||
u->Write(line);
|
||||
}
|
||||
}
|
||||
for (UCListIter v = include_c.begin(); v != include_c.end(); ++v)
|
||||
for (IncludeChanList::const_iterator v = include_c.begin(); v != include_c.end(); ++v)
|
||||
{
|
||||
Channel* c = *v;
|
||||
Channel* c = (*v)->chan;
|
||||
const UserMembList* ulist = c->GetUsers();
|
||||
for (UserMembList::const_iterator i = ulist->begin(); i != ulist->end(); i++)
|
||||
{
|
||||
@ -1005,7 +1005,7 @@ void User::WriteCommonQuit(const std::string &normal_text, const std::string &op
|
||||
const std::string normalMessage = ":" + this->GetFullHost() + " QUIT :" + normal_text;
|
||||
const std::string operMessage = ":" + this->GetFullHost() + " QUIT :" + oper_text;
|
||||
|
||||
UserChanList include_c(chans);
|
||||
IncludeChanList include_c(chans.begin(), chans.end());
|
||||
std::map<User*,bool> exceptions;
|
||||
|
||||
FOREACH_MOD(OnBuildNeighborList, (this, include_c, exceptions));
|
||||
@ -1020,9 +1020,9 @@ void User::WriteCommonQuit(const std::string &normal_text, const std::string &op
|
||||
u->Write(u->IsOper() ? operMessage : normalMessage);
|
||||
}
|
||||
}
|
||||
for (UCListIter v = include_c.begin(); v != include_c.end(); ++v)
|
||||
for (IncludeChanList::const_iterator v = include_c.begin(); v != include_c.end(); ++v)
|
||||
{
|
||||
const UserMembList* ulist = (*v)->GetUsers();
|
||||
const UserMembList* ulist = (*v)->chan->GetUsers();
|
||||
for (UserMembList::const_iterator i = ulist->begin(); i != ulist->end(); i++)
|
||||
{
|
||||
LocalUser* u = IS_LOCAL(i->first);
|
||||
@ -1096,7 +1096,7 @@ bool User::SharesChannelWith(User *other)
|
||||
/* Eliminate the inner loop (which used to be ~equal in size to the outer loop)
|
||||
* by replacing it with a map::find which *should* be more efficient
|
||||
*/
|
||||
if ((*i)->HasUser(other))
|
||||
if ((*i)->chan->HasUser(other))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -1277,9 +1277,10 @@ void LocalUser::SetClass(const std::string &explicit_name)
|
||||
void User::PurgeEmptyChannels()
|
||||
{
|
||||
// firstly decrement the count on each channel
|
||||
for (UCListIter f = this->chans.begin(); f != this->chans.end(); f++)
|
||||
for (UCListIter i = this->chans.begin(); i != this->chans.end(); )
|
||||
{
|
||||
Channel* c = *f;
|
||||
Channel* c = (*i)->chan;
|
||||
++i;
|
||||
c->DelUser(this);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user