So, I said I'd make a seperate post about extended bans, and here it is.

The general comment is that I have them coming out of my ears. I love the concept of extended bans, at least the general idea of being able to restrict someone from performing specific actions.

That having been said, I don't think I've ever seen it end up quite this flexible.

I've not talked about how our extended bans work in detail, so I will now, both on a user and a developmental level.

We have multiple (15, so far -- full list later!) types of extended bans. These affect different ways a user may interact with a channel.

Each banmask only affects the user in *one* way (e.g. +b some!user@here only stops matching users from joining, whereas +b m:some!user@here will *only* stop that user from talking, and +b V:some!user@here will *only* affect their ability to invite, etc).

All of these bans can be exempted using +e if m_banexempt is loaded, and the extended exempts again *only* apply to the type that they match (e.g. +e some!user@here only affects joins, whereas +e m:some!user@here means that the matched user may always talk).

This provides pretty good flexibility.

About some of the bantypes themselves... Virtually every channel mode which applies a restriction to users has an equivilant extban (I don't say all, because not all of them we think makes sense - if you think we missed one, talk to me!).

We also have a few extra, like +b j: and +b s: - stop a user joining a channel if in a banned channel (e.g. +b j:#badchan) and stop a user joining if connected to a matching server mask (e.g. +b s:some.server.here).

The second one is interesting, as it can essentially be used to simulate local channels (+be s:* s:my.server.only).

Second last thing, a list of currently implemented extbans:
N m_nonicks prevents nickchanges from +b'd masks, allows +e
r m_gecosban prevents matching +b from joining, allows +e
m m_muteban prevents matching +b from speaking, allows +e
M m_services_account prevents matching accounts from speaking, allows +e
R m_services_account prevents +b accounts from joining, allows +e
B m_blockcaps prevents matching +b from using caps, allows +e
c m_blockcolours prevents matching +b from using colours, allows +e
V m_noinvite prevents matching +b from using /invite, allows +e
T m_nonotice prevents matching +b from using /notice to channel, allows +e
Q m_nokicks prevents matching +b from using /kick, allows +e
S m_stripcolor strips colours from matching +b, allows +e
O m_operchans prevents matching +b opertype mask from joining, allows +e
C m_noctcp prevents matching +b from CTCP, allows +e
j m_channelban prevents user from joining a channel if a channel they are already on matches a +b j: mask, allows +e
s m_serverban prevents user from joining if connected to a server matching a mask, allows +e


Now, as to how they may be used in code, easy.

Modules implementing an extban MUST hook On005Numeric and use ServerInstance->AddExtBanChar(). It's not mandatory, but I will come and hit you with something heavy if you don't.

After doing that, hook whatever event you want, and use chan->IsExtBanned(user or string, 'typechar'), e.g in pseeudocode:

onuserprejoin(channel, user)
foreach c in user's channels
if (c->IsExtBanned(channel->name, 'j'))
return 1;

That code is essentially how the 'j' extban works. Exempts to extbans are handled internally inside IsExtBanned, so it's really a piece of total piss to write one. :)

Be creative, and show me what you can do! :D

(And yes, speedfreaks, I do have plans on how to make this faster in the future)