mirror of
https://github.com/matrix-construct/construct
synced 2025-01-13 16:33:53 +01:00
Upgrade the channel invite list.
This commit is contained in:
parent
a84fe8a09b
commit
276cad4275
7 changed files with 41 additions and 70 deletions
|
@ -134,7 +134,7 @@ struct chan
|
|||
|
||||
rb_dlink_list members;
|
||||
rb_dlink_list locmembers;
|
||||
rb_dlink_list invites;
|
||||
std::set<client *> invites;
|
||||
|
||||
list bans;
|
||||
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 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 *);
|
||||
void add_user_to_channel(chan *, client *, int flags);
|
||||
void remove_user_from_channel(membership *);
|
||||
void remove_user_from_channels(client *);
|
||||
void invalidate_bancache_user(client *);
|
||||
void channel_member_names(chan *, client *, int show_eon);
|
||||
void del_invite(chan *, client *who);
|
||||
const char *channel_modes(chan *, client *who);
|
||||
chan *find_bannickchange_channel(client *);
|
||||
void check_spambot_warning(client *source, const char *name);
|
||||
|
|
|
@ -69,7 +69,7 @@ typedef int SSL_OPEN_CB(struct Client *, int status);
|
|||
struct User
|
||||
{
|
||||
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 */
|
||||
int refcnt; /* Number of times this block is referenced */
|
||||
|
||||
|
|
|
@ -51,7 +51,6 @@ chan::chan::chan(const std::string &name)
|
|||
,topic{}
|
||||
,members{0}
|
||||
,locmembers{0}
|
||||
,invites{0}
|
||||
,join_count{0}
|
||||
,join_delta{0}
|
||||
,flood_noticed{0}
|
||||
|
@ -70,10 +69,7 @@ chan::chan::chan(const std::string &name)
|
|||
chan::chan::~chan()
|
||||
noexcept
|
||||
{
|
||||
rb_dlink_node *ptr, *next_ptr;
|
||||
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, invites.head)
|
||||
del_invite(this, reinterpret_cast<client *>(ptr->data));
|
||||
|
||||
clear_invites(*this);
|
||||
rb_dlinkDelete(&node, &global_channel_list);
|
||||
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());
|
||||
}
|
||||
|
||||
/* del_invite()
|
||||
*
|
||||
* input - channel to remove invite from, client to remove
|
||||
* output -
|
||||
* side effects - user is removed from invite list, if exists
|
||||
*/
|
||||
void
|
||||
chan::del_invite(chan *chptr, client *who)
|
||||
chan::clear_invites(chan &chan)
|
||||
{
|
||||
rb_dlinkFindDestroy(who, &chptr->invites);
|
||||
rb_dlinkFindDestroy(chptr, &who->user->invited);
|
||||
for (auto &client : chan.invites)
|
||||
client->user->invited.erase(&chan);
|
||||
}
|
||||
|
||||
void
|
||||
chan::del_invite(chan &chan, client &client)
|
||||
{
|
||||
chan.invites.erase(&client);
|
||||
client.user->invited.erase(&chan);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -642,8 +639,8 @@ chan::check(chan &chan,
|
|||
int
|
||||
chan::can_join(client *source_p, chan *chptr, const char *key, const char **forward)
|
||||
{
|
||||
rb_dlink_node *invite = NULL;
|
||||
rb_dlink_node *ptr;
|
||||
bool invited(false);
|
||||
ban *invex = NULL;
|
||||
char src_host[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)
|
||||
{
|
||||
RB_DLINK_FOREACH(invite, source_p->user->invited.head)
|
||||
if (invite->data == chptr)
|
||||
break;
|
||||
|
||||
if (!invite)
|
||||
if (!(invited = chptr->invites.count(source_p)))
|
||||
{
|
||||
if (!ConfigChannel.use_invex)
|
||||
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 */
|
||||
if (i != 0 && invite == NULL)
|
||||
if (i != 0 && !invited)
|
||||
{
|
||||
RB_DLINK_FOREACH(invite, source_p->user->invited.head)
|
||||
{
|
||||
if(invite->data == chptr)
|
||||
break;
|
||||
}
|
||||
if (invite == NULL)
|
||||
if (!(invited = chptr->invites.count(source_p)))
|
||||
moduledata.approved = i;
|
||||
}
|
||||
|
||||
|
|
|
@ -1270,11 +1270,9 @@ exit_generic_client(struct Client *client_p, struct Client *source_p, struct Cli
|
|||
/* Should not be in any channels now */
|
||||
s_assert(source_p->user->channel.head == NULL);
|
||||
|
||||
/* Clean up invitefield */
|
||||
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, source_p->user->invited.head)
|
||||
{
|
||||
del_invite(reinterpret_cast<chan::chan *>(ptr->data), source_p);
|
||||
}
|
||||
// Clean up invitefield
|
||||
for (auto &chan : source_p->user->invited)
|
||||
chan->invites.erase(source_p);
|
||||
|
||||
/* Clean up allow lists */
|
||||
del_all_accepts(source_p);
|
||||
|
@ -1841,22 +1839,22 @@ free_user(struct User *user, struct Client *client_p)
|
|||
/*
|
||||
* 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,
|
||||
"* %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->
|
||||
name : "<noname>",
|
||||
client_p->username,
|
||||
client_p->host,
|
||||
user,
|
||||
user->invited.head,
|
||||
user->invited.size(),
|
||||
user->channel.head,
|
||||
rb_dlink_list_length(&user->channel),
|
||||
user->refcnt);
|
||||
s_assert(!user->refcnt);
|
||||
s_assert(!user->invited.head);
|
||||
s_assert(user->invited.empty());
|
||||
s_assert(!user->channel.head);
|
||||
}
|
||||
|
||||
|
|
|
@ -349,7 +349,7 @@ m_join(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p
|
|||
chptr->name.c_str());
|
||||
}
|
||||
|
||||
del_invite(chptr, source_p);
|
||||
del_invite(*chptr, *source_p);
|
||||
|
||||
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);
|
||||
chptr->mode = mode;
|
||||
remove_our_modes(chptr, source_p);
|
||||
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->invites.head)
|
||||
del_invite(chptr, (Client *)ptr->data);
|
||||
clear_invites(*chptr);
|
||||
|
||||
/* If setting -j, clear join throttle state -- jilles */
|
||||
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;
|
||||
|
||||
remove_our_modes(chptr, fakesource_p);
|
||||
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->invites.head)
|
||||
del_invite(chptr, (Client *)ptr->data);
|
||||
clear_invites(*chptr);
|
||||
|
||||
if (!empty(*chptr, chan::mode::BAN))
|
||||
remove_ban_list(*chptr, *fakesource_p, get(*chptr, mode::BAN), 'b', chan::ALL_MEMBERS);
|
||||
|
|
|
@ -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);
|
||||
|
||||
static bool add_invite(chan::chan *, struct Client *);
|
||||
static bool add_invite(chan::chan &, Client &);
|
||||
|
||||
/* m_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 (!add_invite(chptr, target_p))
|
||||
if (!add_invite(*chptr, *target_p))
|
||||
return;
|
||||
|
||||
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.
|
||||
*/
|
||||
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? */
|
||||
RB_DLINK_FOREACH(ptr, who->user->invited.head)
|
||||
{
|
||||
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);
|
||||
if (chan.invites.size() >= ConfigChannel.max_chans_per_user)
|
||||
return false;
|
||||
|
||||
chan.invites.emplace(&client);
|
||||
client.user->invited.emplace(&chan);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1335,7 +1335,7 @@ stats_memory (struct Client *source_p)
|
|||
if(target_p->user)
|
||||
{
|
||||
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);
|
||||
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_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_ban_memory += size(*chptr, chan::mode::BAN) * sizeof(chan::ban);
|
||||
|
|
Loading…
Reference in a new issue