Add target change for channels.
This has a separate enabling option channel::channel_target_change. It applies to PRIVMSG, NOTICE and TOPIC by unvoiced unopped non-opers. The same slots are used for channels and users.
This commit is contained in:
parent
7f3998618e
commit
9e94d9ea13
|
@ -400,6 +400,7 @@ channel {
|
||||||
cycle_host_change = yes;
|
cycle_host_change = yes;
|
||||||
host_in_topic = yes;
|
host_in_topic = yes;
|
||||||
resv_forcepart = yes;
|
resv_forcepart = yes;
|
||||||
|
channel_target_change = yes;
|
||||||
};
|
};
|
||||||
|
|
||||||
serverhide {
|
serverhide {
|
||||||
|
|
|
@ -914,6 +914,12 @@ channel {
|
||||||
* when a RESV is issued.
|
* when a RESV is issued.
|
||||||
*/
|
*/
|
||||||
resv_forcepart = yes;
|
resv_forcepart = yes;
|
||||||
|
|
||||||
|
/* channel target change: restrict how many channels users can
|
||||||
|
* message per unit of time. IRC operators, channel operators and
|
||||||
|
* voiced users are exempt.
|
||||||
|
*/
|
||||||
|
channel_target_change = yes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,15 +3,17 @@ Lee H <lee -at- leeh.co.uk>
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
Reworked by Jilles Tjoelker, February 2010.
|
Reworked by Jilles Tjoelker, February 2010.
|
||||||
|
Channel target change added by Jilles Tjoelker, August 2010.
|
||||||
|
|
||||||
If the server you are using uses the target change mechanism, then
|
If the server you are using uses the target change mechanism, then
|
||||||
restrictions are placed on how many different users you can message in a set
|
restrictions are placed on how many different users and/or channels you can
|
||||||
timeframe. This also applies to invites.
|
message in a set timeframe. This also applies to invites (for the target
|
||||||
|
user) and topic changes.
|
||||||
|
|
||||||
Target change does not apply to channels, ctcp replies, messages to
|
Target change does not apply to ctcp replies, messages to yourself, messages
|
||||||
yourself or messages to services.
|
to services and joins.
|
||||||
|
|
||||||
You will have a set number of 'slots', each different client you message
|
You will have a set number of 'slots', each different target you message
|
||||||
will take up one slot. A client doing a nick change will not use a new slot,
|
will take up one slot. A client doing a nick change will not use a new slot,
|
||||||
however a client disconnecting from the server it is on and reconnecting
|
however a client disconnecting from the server it is on and reconnecting
|
||||||
will. You will receive 1 new slot roughly every minute.
|
will. You will receive 1 new slot roughly every minute.
|
||||||
|
@ -20,14 +22,14 @@ Additionally, clients that message or invite you are placed in one of a
|
||||||
small number of special slots, in many cases allowing replies without using
|
small number of special slots, in many cases allowing replies without using
|
||||||
a slot.
|
a slot.
|
||||||
|
|
||||||
When all slots are filled, messages to new clients will not be accepted.
|
When all slots are filled, messages to new targets will not be accepted.
|
||||||
Messages to clients already filling a slot will be accepted. If all slots
|
Messages to targets already filling a slot will be accepted. If all slots
|
||||||
are full, you will receive the ERR_TARGCHANGE numeric, number 707 in the
|
are full, you will receive the ERR_TARGCHANGE numeric, number 707 in the
|
||||||
form:
|
form:
|
||||||
:<server> 707 <yournick> <targetnick> :Targets changing too fast, message dropped
|
:<server> 707 <yournick> <target> :Targets changing too fast, message dropped
|
||||||
|
|
||||||
The slots are operated in an LRU (least recently used), so the person you
|
The slots are operated in an LRU (least recently used), so the person or
|
||||||
have talked to least recently will be replaced.
|
channel you have talked to least recently will be replaced.
|
||||||
|
|
||||||
The number of slots in use will be kept through a reconnection, though the
|
The number of slots in use will be kept through a reconnection, though the
|
||||||
information in those slots will be dropped. However, you will always
|
information in those slots will be dropped. However, you will always
|
||||||
|
@ -35,8 +37,9 @@ receive one free slot on a reconnection. Other servers using this mechanism
|
||||||
will also be made aware of details about slots.
|
will also be made aware of details about slots.
|
||||||
|
|
||||||
Target change does not apply if you are opped or voiced in a channel, and
|
Target change does not apply if you are opped or voiced in a channel, and
|
||||||
you are messaging a client within that channel. This can be done explicitly
|
you are messaging that channel or a client within that channel. The latter
|
||||||
using the CNOTICE and CPRIVMSG commands, see /quote help cnotice and /quote
|
can be done explicitly using the CNOTICE and CPRIVMSG commands, see
|
||||||
help cprivmsg, but is also implicit in a normal /msg, /notice or /invite.
|
/quote help cnotice and /quote help cprivmsg, but is also implicit in a
|
||||||
|
normal /msg, /notice or /invite.
|
||||||
|
|
||||||
--
|
--
|
||||||
|
|
|
@ -261,6 +261,7 @@ struct config_channel_entry
|
||||||
int cycle_host_change;
|
int cycle_host_change;
|
||||||
int host_in_topic;
|
int host_in_topic;
|
||||||
int resv_forcepart;
|
int resv_forcepart;
|
||||||
|
int channel_target_change;
|
||||||
|
|
||||||
int exempt_cmode_c;
|
int exempt_cmode_c;
|
||||||
int exempt_cmode_C;
|
int exempt_cmode_C;
|
||||||
|
|
|
@ -30,6 +30,8 @@
|
||||||
struct Channel *find_allowing_channel(struct Client *source_p, struct Client *target_p);
|
struct Channel *find_allowing_channel(struct Client *source_p, struct Client *target_p);
|
||||||
/* checks if source_p is allowed to send to target_p */
|
/* checks if source_p is allowed to send to target_p */
|
||||||
int add_target(struct Client *source_p, struct Client *target_p);
|
int add_target(struct Client *source_p, struct Client *target_p);
|
||||||
|
/* checks if source_p is allowed to send to chptr */
|
||||||
|
int add_channel_target(struct Client *source_p, struct Channel *chptr);
|
||||||
/* allows source_p to send to target_p */
|
/* allows source_p to send to target_p */
|
||||||
void add_reply_target(struct Client *source_p, struct Client *target_p);
|
void add_reply_target(struct Client *source_p, struct Client *target_p);
|
||||||
|
|
||||||
|
|
|
@ -536,6 +536,14 @@ msg_channel(int p_or_n, const char *command,
|
||||||
/* chanops and voiced can flood their own channel with impunity */
|
/* chanops and voiced can flood their own channel with impunity */
|
||||||
if((result = can_send(chptr, source_p, NULL)))
|
if((result = can_send(chptr, source_p, NULL)))
|
||||||
{
|
{
|
||||||
|
if(result != CAN_SEND_OPV && MyClient(source_p) &&
|
||||||
|
!IsOper(source_p) &&
|
||||||
|
!add_channel_target(source_p, chptr))
|
||||||
|
{
|
||||||
|
sendto_one(source_p, form_str(ERR_TARGCHANGE),
|
||||||
|
me.name, source_p->name, chptr->chname);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if(result == CAN_SEND_OPV ||
|
if(result == CAN_SEND_OPV ||
|
||||||
!flood_attack_channel(p_or_n, source_p, chptr, chptr->chname))
|
!flood_attack_channel(p_or_n, source_p, chptr, chptr->chname))
|
||||||
{
|
{
|
||||||
|
@ -586,6 +594,13 @@ msg_channel(int p_or_n, const char *command,
|
||||||
(!(chptr->mode.mode & MODE_NOPRIVMSGS) ||
|
(!(chptr->mode.mode & MODE_NOPRIVMSGS) ||
|
||||||
IsMember(source_p, chptr)))
|
IsMember(source_p, chptr)))
|
||||||
{
|
{
|
||||||
|
if(MyClient(source_p) && !IsOper(source_p) &&
|
||||||
|
!add_channel_target(source_p, chptr))
|
||||||
|
{
|
||||||
|
sendto_one(source_p, form_str(ERR_TARGCHANGE),
|
||||||
|
me.name, source_p->name, chptr->chname);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if(!flood_attack_channel(p_or_n, source_p, chptr, chptr->chname))
|
if(!flood_attack_channel(p_or_n, source_p, chptr, chptr->chname))
|
||||||
{
|
{
|
||||||
sendto_channel_opmod(client_p, source_p, chptr,
|
sendto_channel_opmod(client_p, source_p, chptr,
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "parse.h"
|
#include "parse.h"
|
||||||
#include "modules.h"
|
#include "modules.h"
|
||||||
#include "packet.h"
|
#include "packet.h"
|
||||||
|
#include "tgchange.h"
|
||||||
|
|
||||||
static int m_topic(struct Client *, struct Client *, int, const char **);
|
static int m_topic(struct Client *, struct Client *, int, const char **);
|
||||||
static int ms_topic(struct Client *, struct Client *, int, const char **);
|
static int ms_topic(struct Client *, struct Client *, int, const char **);
|
||||||
|
@ -115,6 +116,15 @@ m_topic(struct Client *client_p, struct Client *source_p, int parc, const char *
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(MyClient(source_p) && !is_chanop_voiced(msptr) &&
|
||||||
|
!IsOper(source_p) &&
|
||||||
|
!add_channel_target(source_p, chptr))
|
||||||
|
{
|
||||||
|
sendto_one(source_p, form_str(ERR_TARGCHANGE),
|
||||||
|
me.name, source_p->name, chptr->chname);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if(MyClient(source_p) && (chptr->mode.mode & MODE_TOPICLIMIT) && !is_any_op(msptr))
|
if(MyClient(source_p) && (chptr->mode.mode & MODE_TOPICLIMIT) && !is_any_op(msptr))
|
||||||
{
|
{
|
||||||
if(IsOverride(source_p))
|
if(IsOverride(source_p))
|
||||||
|
|
|
@ -2287,6 +2287,7 @@ static struct ConfEntry conf_channel_table[] =
|
||||||
{ "use_knock", CF_YESNO, NULL, 0, &ConfigChannel.use_knock },
|
{ "use_knock", CF_YESNO, NULL, 0, &ConfigChannel.use_knock },
|
||||||
{ "use_local_channels", CF_YESNO, NULL, 0, &ConfigChannel.use_local_channels },
|
{ "use_local_channels", CF_YESNO, NULL, 0, &ConfigChannel.use_local_channels },
|
||||||
{ "resv_forcepart", CF_YESNO, NULL, 0, &ConfigChannel.resv_forcepart },
|
{ "resv_forcepart", CF_YESNO, NULL, 0, &ConfigChannel.resv_forcepart },
|
||||||
|
{ "channel_target_change", CF_YESNO, NULL, 0, &ConfigChannel.channel_target_change },
|
||||||
{ "exempt_cmode_c", CF_YESNO, NULL, 0, &ConfigChannel.exempt_cmode_c },
|
{ "exempt_cmode_c", CF_YESNO, NULL, 0, &ConfigChannel.exempt_cmode_c },
|
||||||
{ "exempt_cmode_C", CF_YESNO, NULL, 0, &ConfigChannel.exempt_cmode_C },
|
{ "exempt_cmode_C", CF_YESNO, NULL, 0, &ConfigChannel.exempt_cmode_C },
|
||||||
{ "exempt_cmode_D", CF_YESNO, NULL, 0, &ConfigChannel.exempt_cmode_D },
|
{ "exempt_cmode_D", CF_YESNO, NULL, 0, &ConfigChannel.exempt_cmode_D },
|
||||||
|
|
|
@ -787,6 +787,7 @@ set_default_conf(void)
|
||||||
ConfigChannel.no_join_on_split = NO;
|
ConfigChannel.no_join_on_split = NO;
|
||||||
ConfigChannel.no_create_on_split = YES;
|
ConfigChannel.no_create_on_split = YES;
|
||||||
ConfigChannel.resv_forcepart = YES;
|
ConfigChannel.resv_forcepart = YES;
|
||||||
|
ConfigChannel.channel_target_change = YES;
|
||||||
|
|
||||||
ConfigChannel.exempt_cmode_c = NO;
|
ConfigChannel.exempt_cmode_c = NO;
|
||||||
ConfigChannel.exempt_cmode_C = NO;
|
ConfigChannel.exempt_cmode_C = NO;
|
||||||
|
|
|
@ -30,6 +30,8 @@
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "s_newconf.h"
|
#include "s_newconf.h"
|
||||||
|
|
||||||
|
static int add_hashed_target(struct Client *source_p, uint32_t hashv);
|
||||||
|
|
||||||
struct Channel *
|
struct Channel *
|
||||||
find_allowing_channel(struct Client *source_p, struct Client *target_p)
|
find_allowing_channel(struct Client *source_p, struct Client *target_p)
|
||||||
{
|
{
|
||||||
|
@ -48,9 +50,7 @@ find_allowing_channel(struct Client *source_p, struct Client *target_p)
|
||||||
int
|
int
|
||||||
add_target(struct Client *source_p, struct Client *target_p)
|
add_target(struct Client *source_p, struct Client *target_p)
|
||||||
{
|
{
|
||||||
int i, j;
|
|
||||||
uint32_t hashv;
|
uint32_t hashv;
|
||||||
uint32_t *targets;
|
|
||||||
|
|
||||||
/* can msg themselves or services without using any target slots */
|
/* can msg themselves or services without using any target slots */
|
||||||
if(source_p == target_p || IsService(target_p))
|
if(source_p == target_p || IsService(target_p))
|
||||||
|
@ -65,6 +65,24 @@ add_target(struct Client *source_p, struct Client *target_p)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
hashv = fnv_hash_upper((const unsigned char *)use_id(target_p), 32);
|
hashv = fnv_hash_upper((const unsigned char *)use_id(target_p), 32);
|
||||||
|
return add_hashed_target(source_p, hashv);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
add_channel_target(struct Client *source_p, struct Channel *chptr)
|
||||||
|
{
|
||||||
|
uint32_t hashv;
|
||||||
|
|
||||||
|
hashv = fnv_hash_upper((const unsigned char *)chptr->chname, 32);
|
||||||
|
return add_hashed_target(source_p, hashv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
add_hashed_target(struct Client *source_p, uint32_t hashv)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
uint32_t *targets;
|
||||||
|
|
||||||
targets = source_p->localClient->targets;
|
targets = source_p->localClient->targets;
|
||||||
|
|
||||||
/* check for existing target, and move it to the head */
|
/* check for existing target, and move it to the head */
|
||||||
|
|
Loading…
Reference in New Issue