0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-10-02 13:48:53 +02:00

Upgrade the channel invite list.

This commit is contained in:
Jason Volk 2016-08-19 00:02:18 -07:00
parent a84fe8a09b
commit 276cad4275
7 changed files with 41 additions and 70 deletions

View file

@ -134,7 +134,7 @@ struct chan
rb_dlink_list members; rb_dlink_list members;
rb_dlink_list locmembers; rb_dlink_list locmembers;
rb_dlink_list invites; std::set<client *> invites;
list bans; list bans;
list excepts; list excepts;
@ -202,13 +202,15 @@ const ban &get(const chan &, const mode::type &, const std::string &mask);
bool add(chan &, const mode::type &, const std::string &mask, client &source, const std::string &forward = {}); bool add(chan &, const mode::type &, const std::string &mask, client &source, const std::string &forward = {});
bool del(chan &, const mode::type &, const std::string &mask); bool del(chan &, const mode::type &, const std::string &mask);
void del_invite(chan &, client &);
void clear_invites(chan &);
bool flood_attack_channel(int p_or_n, client *source, chan *); bool flood_attack_channel(int p_or_n, client *source, chan *);
void add_user_to_channel(chan *, client *, int flags); void add_user_to_channel(chan *, client *, int flags);
void remove_user_from_channel(membership *); void remove_user_from_channel(membership *);
void remove_user_from_channels(client *); void remove_user_from_channels(client *);
void invalidate_bancache_user(client *); void invalidate_bancache_user(client *);
void channel_member_names(chan *, client *, int show_eon); void channel_member_names(chan *, client *, int show_eon);
void del_invite(chan *, client *who);
const char *channel_modes(chan *, client *who); const char *channel_modes(chan *, client *who);
chan *find_bannickchange_channel(client *); chan *find_bannickchange_channel(client *);
void check_spambot_warning(client *source, const char *name); void check_spambot_warning(client *source, const char *name);

View file

@ -69,7 +69,7 @@ typedef int SSL_OPEN_CB(struct Client *, int status);
struct User struct User
{ {
rb_dlink_list channel; /* chain of channel pointer blocks */ rb_dlink_list channel; /* chain of channel pointer blocks */
rb_dlink_list invited; /* chain of invite pointer blocks */ std::set<chan::chan *> invited;
char *away; /* pointer to away message */ char *away; /* pointer to away message */
int refcnt; /* Number of times this block is referenced */ int refcnt; /* Number of times this block is referenced */

View file

@ -51,7 +51,6 @@ chan::chan::chan(const std::string &name)
,topic{} ,topic{}
,members{0} ,members{0}
,locmembers{0} ,locmembers{0}
,invites{0}
,join_count{0} ,join_count{0}
,join_delta{0} ,join_delta{0}
,flood_noticed{0} ,flood_noticed{0}
@ -70,10 +69,7 @@ chan::chan::chan(const std::string &name)
chan::chan::~chan() chan::chan::~chan()
noexcept noexcept
{ {
rb_dlink_node *ptr, *next_ptr; clear_invites(*this);
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, invites.head)
del_invite(this, reinterpret_cast<client *>(ptr->data));
rb_dlinkDelete(&node, &global_channel_list); rb_dlinkDelete(&node, &global_channel_list);
del_from_channel_hash(name.c_str(), this); del_from_channel_hash(name.c_str(), this);
} }
@ -440,17 +436,18 @@ chan::channel_member_names(chan *chptr, client *client_p, int show_eon)
me.name, client_p->name, chptr->name.c_str()); me.name, client_p->name, chptr->name.c_str());
} }
/* del_invite()
*
* input - channel to remove invite from, client to remove
* output -
* side effects - user is removed from invite list, if exists
*/
void void
chan::del_invite(chan *chptr, client *who) chan::clear_invites(chan &chan)
{ {
rb_dlinkFindDestroy(who, &chptr->invites); for (auto &client : chan.invites)
rb_dlinkFindDestroy(chptr, &who->user->invited); client->user->invited.erase(&chan);
}
void
chan::del_invite(chan &chan, client &client)
{
chan.invites.erase(&client);
client.user->invited.erase(&chan);
} }
bool bool
@ -642,8 +639,8 @@ chan::check(chan &chan,
int int
chan::can_join(client *source_p, chan *chptr, const char *key, const char **forward) chan::can_join(client *source_p, chan *chptr, const char *key, const char **forward)
{ {
rb_dlink_node *invite = NULL;
rb_dlink_node *ptr; rb_dlink_node *ptr;
bool invited(false);
ban *invex = NULL; ban *invex = NULL;
char src_host[NICKLEN + USERLEN + HOSTLEN + 6]; char src_host[NICKLEN + USERLEN + HOSTLEN + 6];
char src_iphost[NICKLEN + USERLEN + HOSTLEN + 6]; char src_iphost[NICKLEN + USERLEN + HOSTLEN + 6];
@ -703,11 +700,7 @@ chan::can_join(client *source_p, chan *chptr, const char *key, const char **forw
if (chptr->mode.mode & mode::INVITEONLY) if (chptr->mode.mode & mode::INVITEONLY)
{ {
RB_DLINK_FOREACH(invite, source_p->user->invited.head) if (!(invited = chptr->invites.count(source_p)))
if (invite->data == chptr)
break;
if (!invite)
{ {
if (!ConfigChannel.use_invex) if (!ConfigChannel.use_invex)
moduledata.approved = ERR_INVITEONLYCHAN; moduledata.approved = ERR_INVITEONLYCHAN;
@ -755,14 +748,9 @@ chan::can_join(client *source_p, chan *chptr, const char *key, const char **forw
} }
/* allow /invite to override +l/+r/+j also -- jilles */ /* allow /invite to override +l/+r/+j also -- jilles */
if (i != 0 && invite == NULL) if (i != 0 && !invited)
{ {
RB_DLINK_FOREACH(invite, source_p->user->invited.head) if (!(invited = chptr->invites.count(source_p)))
{
if(invite->data == chptr)
break;
}
if (invite == NULL)
moduledata.approved = i; moduledata.approved = i;
} }

View file

@ -1270,11 +1270,9 @@ exit_generic_client(struct Client *client_p, struct Client *source_p, struct Cli
/* Should not be in any channels now */ /* Should not be in any channels now */
s_assert(source_p->user->channel.head == NULL); s_assert(source_p->user->channel.head == NULL);
/* Clean up invitefield */ // Clean up invitefield
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, source_p->user->invited.head) for (auto &chan : source_p->user->invited)
{ chan->invites.erase(source_p);
del_invite(reinterpret_cast<chan::chan *>(ptr->data), source_p);
}
/* Clean up allow lists */ /* Clean up allow lists */
del_all_accepts(source_p); del_all_accepts(source_p);
@ -1841,22 +1839,22 @@ free_user(struct User *user, struct Client *client_p)
/* /*
* sanity check * sanity check
*/ */
if(user->refcnt < 0 || user->invited.head || user->channel.head) if(user->refcnt < 0 || !user->invited.empty() || user->channel.head)
{ {
sendto_realops_snomask(SNO_GENERAL, L_ALL, sendto_realops_snomask(SNO_GENERAL, L_ALL,
"* %p user (%s!%s@%s) %p %p %p %lu %d *", "* %p user (%s!%s@%s) %p %lu %p %lu %d *",
client_p, client_p,
client_p ? client_p-> client_p ? client_p->
name : "<noname>", name : "<noname>",
client_p->username, client_p->username,
client_p->host, client_p->host,
user, user,
user->invited.head, user->invited.size(),
user->channel.head, user->channel.head,
rb_dlink_list_length(&user->channel), rb_dlink_list_length(&user->channel),
user->refcnt); user->refcnt);
s_assert(!user->refcnt); s_assert(!user->refcnt);
s_assert(!user->invited.head); s_assert(user->invited.empty());
s_assert(!user->channel.head); s_assert(!user->channel.head);
} }

View file

@ -349,7 +349,7 @@ m_join(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p
chptr->name.c_str()); chptr->name.c_str());
} }
del_invite(chptr, source_p); del_invite(*chptr, *source_p);
if(chptr->topic) if(chptr->topic)
{ {
@ -450,8 +450,7 @@ ms_join(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_
set_final_mode(&mode, &chptr->mode); set_final_mode(&mode, &chptr->mode);
chptr->mode = mode; chptr->mode = mode;
remove_our_modes(chptr, source_p); remove_our_modes(chptr, source_p);
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->invites.head) clear_invites(*chptr);
del_invite(chptr, (Client *)ptr->data);
/* If setting -j, clear join throttle state -- jilles */ /* If setting -j, clear join throttle state -- jilles */
chptr->join_count = chptr->join_delta = 0; chptr->join_count = chptr->join_delta = 0;
@ -706,8 +705,7 @@ ms_sjoin(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
using chan::empty; using chan::empty;
remove_our_modes(chptr, fakesource_p); remove_our_modes(chptr, fakesource_p);
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->invites.head) clear_invites(*chptr);
del_invite(chptr, (Client *)ptr->data);
if (!empty(*chptr, chan::mode::BAN)) if (!empty(*chptr, chan::mode::BAN))
remove_ban_list(*chptr, *fakesource_p, get(*chptr, mode::BAN), 'b', chan::ALL_MEMBERS); remove_ban_list(*chptr, *fakesource_p, get(*chptr, mode::BAN), 'b', chan::ALL_MEMBERS);

View file

@ -43,7 +43,7 @@ mapi_cap_list_av2 invite_cap_list[] = {
DECLARE_MODULE_AV2(invite, NULL, NULL, invite_clist, NULL, NULL, invite_cap_list, NULL, invite_desc); DECLARE_MODULE_AV2(invite, NULL, NULL, invite_clist, NULL, NULL, invite_cap_list, NULL, invite_desc);
static bool add_invite(chan::chan *, struct Client *); static bool add_invite(chan::chan &, Client &);
/* m_invite() /* m_invite()
* parv[1] - user to invite * parv[1] - user to invite
@ -207,7 +207,7 @@ m_invite(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
if(store_invite) if(store_invite)
{ {
if (!add_invite(chptr, target_p)) if (!add_invite(*chptr, *target_p))
return; return;
sendto_channel_local_with_capability(chan::CHANOP, 0, CAP_INVITE_NOTIFY, chptr, sendto_channel_local_with_capability(chan::CHANOP, 0, CAP_INVITE_NOTIFY, chptr,
@ -231,30 +231,15 @@ m_invite(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
* side effects - client is added to invite list. * side effects - client is added to invite list.
*/ */
static bool static bool
add_invite(chan::chan *chptr, struct Client *who) add_invite(chan::chan &chan, Client &client)
{ {
rb_dlink_node *ptr; if (client.user->invited.size() >= ConfigChannel.max_chans_per_user)
return false;
/* already invited? */ if (chan.invites.size() >= ConfigChannel.max_chans_per_user)
RB_DLINK_FOREACH(ptr, who->user->invited.head) return false;
{
if(ptr->data == chptr)
return false;
}
/* ok, if their invite list is too long, remove the tail */
if((int)rb_dlink_list_length(&who->user->invited) >=
ConfigChannel.max_chans_per_user)
{
ptr = who->user->invited.tail;
del_invite((chan::chan *)ptr->data, who);
}
/* add user to channel invite list */
rb_dlinkAddAlloc(who, &chptr->invites);
/* add channel to user invite list */
rb_dlinkAddAlloc(chptr, &who->user->invited);
chan.invites.emplace(&client);
client.user->invited.emplace(&chan);
return true; return true;
} }

View file

@ -1335,7 +1335,7 @@ stats_memory (struct Client *source_p)
if(target_p->user) if(target_p->user)
{ {
users_counted++; users_counted++;
users_invited_count += rb_dlink_list_length(&target_p->user->invited); users_invited_count += target_p->user->invited.size();
user_channels += rb_dlink_list_length(&target_p->user->channel); user_channels += rb_dlink_list_length(&target_p->user->channel);
if(target_p->user->away) if(target_p->user->away)
{ {
@ -1353,7 +1353,7 @@ stats_memory (struct Client *source_p)
channel_memory += (strlen(chptr->name.c_str()) + sizeof(chan::chan)); channel_memory += (strlen(chptr->name.c_str()) + sizeof(chan::chan));
channel_users += rb_dlink_list_length(&chptr->members); channel_users += rb_dlink_list_length(&chptr->members);
channel_invites += rb_dlink_list_length(&chptr->invites); channel_invites += chptr->invites.size();
channel_bans += size(*chptr, chan::mode::BAN); channel_bans += size(*chptr, chan::mode::BAN);
channel_ban_memory += size(*chptr, chan::mode::BAN) * sizeof(chan::ban); channel_ban_memory += size(*chptr, chan::mode::BAN) * sizeof(chan::ban);