From 57f524cbeddb0a56d4cd1c91457cf391a5eaabdb Mon Sep 17 00:00:00 2001 From: Bram Matthys Date: Tue, 5 May 2020 20:16:56 +0200 Subject: [PATCH] Support for +draft/typing This is the work from May 3rd.. need to commit it so i can merge the flood protection that is related to this... The final implementation will still need tweaking before pushed. [skip ci] --- include/h.h | 1 + include/modules.h | 14 +-- include/struct.h | 6 ++ src/misc.c | 12 +++ src/modules/Makefile.in | 5 + src/modules/chanmodes/censor.c | 4 +- src/modules/chanmodes/delayjoin.c | 4 +- src/modules/chanmodes/floodprot.c | 8 +- src/modules/chanmodes/history.c | 10 +- src/modules/chanmodes/nocolor.c | 4 +- src/modules/chanmodes/noctcp.c | 4 +- src/modules/chanmodes/nonotice.c | 9 +- src/modules/chanmodes/regonlyspeak.c | 4 +- src/modules/chanmodes/stripcolor.c | 4 +- src/modules/dccdeny.c | 10 +- src/modules/echo-message.c | 16 +-- src/modules/message-tags.c | 10 -- src/modules/message.c | 144 ++++++++++++++++---------- src/modules/nocodes.c | 4 +- src/modules/restrict-commands.c | 17 +-- src/modules/typing-indicator.c | 93 +++++++++++++++++ src/modules/usermodes/censor.c | 4 +- src/modules/usermodes/noctcp.c | 7 +- src/modules/usermodes/privdeaf.c | 4 +- src/modules/usermodes/regonlymsg.c | 4 +- src/modules/usermodes/secureonlymsg.c | 4 +- 26 files changed, 275 insertions(+), 131 deletions(-) create mode 100644 src/modules/typing-indicator.c diff --git a/include/h.h b/include/h.h index 27596f3e0..9aac51ae3 100644 --- a/include/h.h +++ b/include/h.h @@ -971,3 +971,4 @@ extern void link_generator(void); extern void update_throttling_timer_settings(void); extern int hide_idle_time(Client *client, Client *target); extern void lost_server_link(Client *serv, FORMAT_STRING(const char *fmt), ...); +extern char *sendtype_to_cmd(SendType sendtype); diff --git a/include/modules.h b/include/modules.h index 5dfaceb46..dad438670 100644 --- a/include/modules.h +++ b/include/modules.h @@ -1042,12 +1042,12 @@ char *hooktype_pre_local_kick(Client *client, Client *victim, Channel *channel, int hooktype_can_kick(Client *client, Client *victim, Channel *channel, char *comment, long client_flags, long victim_flags, char **error); int hooktype_local_kick(Client *client, Client *victim, Channel *channel, MessageTag *mtags, char *comment); int hooktype_remote_kick(Client *client, Client *victim, Channel *channel, MessageTag *mtags, char *comment); -char *hooktype_pre_usermsg(Client *client, Client *to, char *text, int notice); -int hooktype_usermsg(Client *client, Client *to, MessageTag *mtags, char *text, int notice); -int hooktype_can_send_to_channel(Client *client, Channel *channel, Membership *member, char **text, char **errmsg, int notice); -int hooktype_can_send_to_user(Client *client, Client *target, char **text, char **errmsg, int notice); -int hooktype_pre_chanmsg(Client *client, Channel *channel, MessageTag *mtags, char *text, int notice); -int hooktype_chanmsg(Client *client, Channel *channel, int sendflags, int prefix, char *target, MessageTag *mtags, char *text, int notice); +char *hooktype_pre_usermsg(Client *client, Client *to, char *text, SendType sendtype); +int hooktype_usermsg(Client *client, Client *to, MessageTag *mtags, char *text, SendType sendtype); +int hooktype_can_send_to_channel(Client *client, Channel *channel, Membership *member, char **text, char **errmsg, SendType sendtype); +int hooktype_can_send_to_user(Client *client, Client *target, char **text, char **errmsg, SendType sendtype); +int hooktype_pre_chanmsg(Client *client, Channel *channel, MessageTag *mtags, char *text, SendType sendtype); +int hooktype_chanmsg(Client *client, Channel *channel, int sendflags, int prefix, char *target, MessageTag *mtags, char *text, SendType sendtype); char *hooktype_pre_local_topic(Client *client, Channel *channel, char *topic); int hooktype_local_topic(Client *client, Channel *channel, char *topic); int hooktype_topic(Client *client, Channel *channel, MessageTag *mtags, char *topic); @@ -1084,7 +1084,7 @@ int hooktype_tkl_add(Client *client, TKL *tkl); int hooktype_tkl_del(Client *client, TKL *tkl); int hooktype_log(int flags, char *timebuf, char *buf); int hooktype_local_spamfilter(Client *acptr, char *str, char *str_in, int type, char *target, TKL *tkl); -int hooktype_silenced(Client *client, Client *to, int notice); +int hooktype_silenced(Client *client, Client *to, SendType sendtype); int hooktype_rawpacket_in(Client *client, char *readbuf, int *length); int hooktype_packet(Client *from, Client *to, Client *intended_to, char **msg, int *length); int hooktype_handshake(Client *client); diff --git a/include/struct.h b/include/struct.h index 458c30c77..385b98087 100644 --- a/include/struct.h +++ b/include/struct.h @@ -140,6 +140,12 @@ typedef enum OperClassEntryType { OPERCLASSENTRY_ALLOW=1, OPERCLASSENTRY_DENY=2} typedef enum OperPermission { OPER_ALLOW=1, OPER_DENY=0} OperPermission; +typedef enum SendType { + SEND_TYPE_PRIVMSG = 0, + SEND_TYPE_NOTICE = 1, + SEND_TYPE_TAGMSG = 2 +} SendType; + struct OperClassValidator; typedef struct OperClassValidator OperClassValidator; typedef struct OperClassACLPath OperClassACLPath; diff --git a/src/misc.c b/src/misc.c index 5b723e579..7f42ffc5d 100644 --- a/src/misc.c +++ b/src/misc.c @@ -1912,3 +1912,15 @@ void freemultiline(MultiLine *l) safe_free(l); } } + +/** Convert a sendtype to a command string */ +char *sendtype_to_cmd(SendType sendtype) +{ + if (sendtype == SEND_TYPE_PRIVMSG) + return "PRIVMSG"; + if (sendtype == SEND_TYPE_NOTICE) + return "NOTICE"; + if (sendtype == SEND_TYPE_TAGMSG) + return "TAGMSG"; + return NULL; +} diff --git a/src/modules/Makefile.in b/src/modules/Makefile.in index 5e749e3fa..593a64f47 100644 --- a/src/modules/Makefile.in +++ b/src/modules/Makefile.in @@ -71,6 +71,7 @@ R_MODULES= \ account-tag.so labeled-response.so link-security.so \ message-ids.so plaintext-policy.so server-time.so sts.so \ echo-message.so userip-tag.so userhost-tag.so \ + typing-indicator.so \ ident_lookup.so history.so MODULES=cloak.so $(R_MODULES) @@ -610,6 +611,10 @@ userhost-tag.so: userhost-tag.c $(INCLUDES) $(CC) $(CFLAGS) $(MODULEFLAGS) -DDYNAMIC_LINKING \ -o userhost-tag.so userhost-tag.c +typing-indicator.so: typing-indicator.c $(INCLUDES) + $(CC) $(CFLAGS) $(MODULEFLAGS) -DDYNAMIC_LINKING \ + -o typing-indicator.so typing-indicator.c + require-module.so: require-module.c $(INCLUDES) $(CC) $(CFLAGS) $(MODULEFLAGS) -DDYNAMIC_LINKING \ -o require-module.so require-module.c diff --git a/src/modules/chanmodes/censor.c b/src/modules/chanmodes/censor.c index 52cabb6a1..6090c91a8 100644 --- a/src/modules/chanmodes/censor.c +++ b/src/modules/chanmodes/censor.c @@ -20,7 +20,7 @@ Cmode_t EXTMODE_CENSOR = 0L; #define IsCensored(x) ((x)->mode.extmode & EXTMODE_CENSOR) -int censor_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, int notice); +int censor_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, SendType sendtype); char *censor_pre_local_part(Client *client, Channel *channel, char *text); char *censor_pre_local_quit(Client *client, char *text); @@ -253,7 +253,7 @@ char *stripbadwords_channel(char *str, int *blocked) return stripbadwords(str, conf_badword_channel, blocked); } -int censor_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, int notice) +int censor_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, SendType sendtype) { int blocked; Hook *h; diff --git a/src/modules/chanmodes/delayjoin.c b/src/modules/chanmodes/delayjoin.c index c16fad43f..0eedb3102 100644 --- a/src/modules/chanmodes/delayjoin.c +++ b/src/modules/chanmodes/delayjoin.c @@ -30,7 +30,7 @@ int moded_part(Client *client, Channel *channel, MessageTag *mtags, char *commen int deny_all(Client *client, Channel *channel, char mode, char *para, int checkt, int what); int moded_chanmode(Client *client, Channel *channel, MessageTag *mtags, char *modebuf, char *parabuf, time_t sendts, int samode); -int moded_prechanmsg(Client *client, Channel *channel, MessageTag *mtags, char *text, int notice); +int moded_prechanmsg(Client *client, Channel *channel, MessageTag *mtags, char *text, SendType sendtype); char *moded_serialize(ModData *m); void moded_unserialize(char *str, ModData *m); @@ -367,7 +367,7 @@ int moded_chanmode(Client *client, Channel *channel, MessageTag *recv_mtags, cha return 0; } -int moded_prechanmsg(Client *client, Channel *channel, MessageTag *mtags, char *text, int notice) +int moded_prechanmsg(Client *client, Channel *channel, MessageTag *mtags, char *text, SendType sendtype) { if ((channel_is_delayed(channel) || channel_is_post_delayed(channel)) && (moded_user_invisible(client, channel))) clear_user_invisible_announce(channel, client, mtags); diff --git a/src/modules/chanmodes/floodprot.c b/src/modules/chanmodes/floodprot.c index d3bbc9763..d9cab8f6e 100644 --- a/src/modules/chanmodes/floodprot.c +++ b/src/modules/chanmodes/floodprot.c @@ -117,8 +117,8 @@ int cmodef_sjoin_check(Channel *channel, void *ourx, void *theirx); int floodprot_join(Client *client, Channel *channel, MessageTag *mtags, char *parv[]); EVENT(modef_event); int cmodef_channel_destroy(Channel *channel, int *should_destroy); -int floodprot_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, int notice); -int floodprot_post_chanmsg(Client *client, Channel *channel, int sendflags, int prefix, char *target, MessageTag *mtags, char *text, int notice); +int floodprot_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, SendType sendtype); +int floodprot_post_chanmsg(Client *client, Channel *channel, int sendflags, int prefix, char *target, MessageTag *mtags, char *text, SendType sendtype); int floodprot_knock(Client *client, Channel *channel, MessageTag *mtags, char *comment); int floodprot_nickchange(Client *client, char *oldnick); int floodprot_chanmode_del(Channel *channel, int m); @@ -939,7 +939,7 @@ char *channel_modef_string(ChannelFloodProtection *x, char *retbuf) return retbuf; } -int floodprot_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, int notice) +int floodprot_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, SendType sendtype) { Membership *mb; ChannelFloodProtection *chp; @@ -1061,7 +1061,7 @@ int floodprot_can_send_to_channel(Client *client, Channel *channel, Membership * return HOOK_CONTINUE; } -int floodprot_post_chanmsg(Client *client, Channel *channel, int sendflags, int prefix, char *target, MessageTag *mtags, char *text, int notice) +int floodprot_post_chanmsg(Client *client, Channel *channel, int sendflags, int prefix, char *target, MessageTag *mtags, char *text, SendType sendtype) { if (!IsFloodLimit(channel) || is_skochanop(client, channel) || IsULine(client)) return 0; diff --git a/src/modules/chanmodes/history.c b/src/modules/chanmodes/history.c index d948713f8..d31d91a84 100644 --- a/src/modules/chanmodes/history.c +++ b/src/modules/chanmodes/history.c @@ -47,7 +47,7 @@ void history_chanmode_free_param(void *r); void *history_chanmode_dup_struct(void *r_in); int history_chanmode_sjoin_check(Channel *channel, void *ourx, void *theirx); int history_channel_destroy(Channel *channel, int *should_destroy); -int history_chanmsg(Client *client, Channel *channel, int sendflags, int prefix, char *target, MessageTag *mtags, char *text, int notice); +int history_chanmsg(Client *client, Channel *channel, int sendflags, int prefix, char *target, MessageTag *mtags, char *text, SendType sendtype); int history_join(Client *client, Channel *channel, MessageTag *mtags, char *parv[]); MOD_TEST() @@ -490,7 +490,7 @@ int history_channel_destroy(Channel *channel, int *should_destroy) return 0; } -int history_chanmsg(Client *client, Channel *channel, int sendflags, int prefix, char *target, MessageTag *mtags, char *text, int notice) +int history_chanmsg(Client *client, Channel *channel, int sendflags, int prefix, char *target, MessageTag *mtags, char *text, SendType sendtype) { char buf[512]; char source[64]; @@ -503,6 +503,10 @@ int history_chanmsg(Client *client, Channel *channel, int sendflags, int prefix, if ((*text == '\001') && strncmp(text+1, "ACTION", 6)) return 0; + /* Filter out TAGMSG */ + if (sendtype == SEND_TYPE_TAGMSG) + return 0; + /* Lazy: if any prefix is addressed (eg: @#channel) then don't record it. * This so we don't have to check privileges during history playback etc. */ @@ -516,7 +520,7 @@ int history_chanmsg(Client *client, Channel *channel, int sendflags, int prefix, snprintf(buf, sizeof(buf), ":%s %s %s :%s", source, - notice ? "NOTICE" : "PRIVMSG", + sendtype_to_cmd(sendtype), channel->chname, text); diff --git a/src/modules/chanmodes/nocolor.c b/src/modules/chanmodes/nocolor.c index 781f9833a..6f2dab502 100644 --- a/src/modules/chanmodes/nocolor.c +++ b/src/modules/chanmodes/nocolor.c @@ -34,7 +34,7 @@ Cmode_t EXTCMODE_NOCOLOR; #define IsNoColor(channel) (channel->mode.extmode & EXTCMODE_NOCOLOR) -int nocolor_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, int notice); +int nocolor_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, SendType sendtype); char *nocolor_prelocalpart(Client *client, Channel *channel, char *comment); char *nocolor_prelocalquit(Client *client, char *comment); @@ -85,7 +85,7 @@ static int IsUsingColor(char *s) return 0; } -int nocolor_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, int notice) +int nocolor_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, SendType sendtype) { Hook *h; int i; diff --git a/src/modules/chanmodes/noctcp.c b/src/modules/chanmodes/noctcp.c index 0402ed7df..058f20a50 100644 --- a/src/modules/chanmodes/noctcp.c +++ b/src/modules/chanmodes/noctcp.c @@ -34,7 +34,7 @@ Cmode_t EXTCMODE_NOCTCP; #define IsNoCTCP(channel) (channel->mode.extmode & EXTCMODE_NOCTCP) -int noctcp_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, int notice); +int noctcp_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, SendType sendtype); MOD_TEST() { @@ -78,7 +78,7 @@ static int IsACTCP(char *s) return 0; } -int noctcp_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, int notice) +int noctcp_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, SendType sendtype) { if (IsNoCTCP(channel) && IsACTCP(*msg)) { diff --git a/src/modules/chanmodes/nonotice.c b/src/modules/chanmodes/nonotice.c index deadff9f4..0d600237e 100644 --- a/src/modules/chanmodes/nonotice.c +++ b/src/modules/chanmodes/nonotice.c @@ -32,7 +32,7 @@ Cmode_t EXTCMODE_NONOTICE; #define IsNoNotice(channel) (channel->mode.extmode & EXTCMODE_NONOTICE) -int nonotice_check_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, int notice); +int nonotice_check_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, SendType sendtype); MOD_TEST() { @@ -65,13 +65,14 @@ MOD_UNLOAD() return MOD_SUCCESS; } -int nonotice_check_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, int notice) +int nonotice_check_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, SendType sendtype) { Hook *h; int i; - if (notice && IsNoNotice(channel) && - (!lp || !(lp->flags & (CHFL_CHANOP | CHFL_CHANOWNER | CHFL_CHANADMIN)))) + if ((sendtype == SEND_TYPE_NOTICE) && + IsNoNotice(channel) && + (!lp || !(lp->flags & (CHFL_CHANOP | CHFL_CHANOWNER | CHFL_CHANADMIN)))) { for (h = Hooks[HOOKTYPE_CAN_BYPASS_CHANNEL_MESSAGE_RESTRICTION]; h; h = h->next) { diff --git a/src/modules/chanmodes/regonlyspeak.c b/src/modules/chanmodes/regonlyspeak.c index b703bb434..33e2c5b56 100644 --- a/src/modules/chanmodes/regonlyspeak.c +++ b/src/modules/chanmodes/regonlyspeak.c @@ -34,7 +34,7 @@ static char errMsg[2048]; #define IsRegOnlySpeak(channel) (channel->mode.extmode & EXTCMODE_REGONLYSPEAK) -int regonlyspeak_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, int notice); +int regonlyspeak_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, SendType sendtype); char *regonlyspeak_part_message (Client *client, Channel *channel, char *comment); MOD_TEST() @@ -81,7 +81,7 @@ char *regonlyspeak_part_message (Client *client, Channel *channel, char *comment return comment; } -int regonlyspeak_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, int notice) +int regonlyspeak_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, SendType sendtype) { Hook *h; int i; diff --git a/src/modules/chanmodes/stripcolor.c b/src/modules/chanmodes/stripcolor.c index c12b6ccdd..11f9f31bf 100644 --- a/src/modules/chanmodes/stripcolor.c +++ b/src/modules/chanmodes/stripcolor.c @@ -34,7 +34,7 @@ Cmode_t EXTCMODE_STRIPCOLOR; #define IsStripColor(channel) (channel->mode.extmode & EXTCMODE_STRIPCOLOR) -int stripcolor_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, int notice); +int stripcolor_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, SendType sendtype); char *stripcolor_prelocalpart(Client *client, Channel *channel, char *comment); char *stripcolor_prelocalquit(Client *client, char *comment); @@ -73,7 +73,7 @@ MOD_UNLOAD() return MOD_SUCCESS; } -int stripcolor_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, int notice) +int stripcolor_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, SendType sendtype) { Hook *h; int i; diff --git a/src/modules/dccdeny.c b/src/modules/dccdeny.c index f1c32e01c..9aaf23e52 100644 --- a/src/modules/dccdeny.c +++ b/src/modules/dccdeny.c @@ -44,8 +44,8 @@ int dccdeny_stats(Client *client, char *para); CMD_FUNC(cmd_dccdeny); CMD_FUNC(cmd_undccdeny); CMD_FUNC(cmd_svsfline); -int dccdeny_can_send_to_user(Client *client, Client *target, char **text, char **errmsg, int notice); -int dccdeny_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, int notice); +int dccdeny_can_send_to_user(Client *client, Client *target, char **text, char **errmsg, SendType sendtype); +int dccdeny_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, SendType sendtype); int dccdeny_server_sync(Client *client); static ConfigItem_deny_dcc *dcc_isforbidden(Client *client, char *filename); static ConfigItem_deny_dcc *dcc_isdiscouraged(Client *client, char *filename); @@ -489,7 +489,7 @@ int dccdeny_server_sync(Client *client) } /** Check if a DCC should be blocked (user-to-user) */ -int dccdeny_can_send_to_user(Client *client, Client *target, char **text, char **errmsg, int notice) +int dccdeny_can_send_to_user(Client *client, Client *target, char **text, char **errmsg, SendType sendtype) { if (**text == '\001') { @@ -507,7 +507,7 @@ int dccdeny_can_send_to_user(Client *client, Client *target, char **text, char * } /** Check if a DCC should be blocked (user-to-channel, unusual) */ -int dccdeny_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, int notice) +int dccdeny_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, SendType sendtype) { static char errbuf[512]; @@ -517,7 +517,7 @@ int dccdeny_can_send_to_channel(Client *client, Channel *channel, Membership *lp char *filename = get_dcc_filename(*msg); if (filename && !can_dcc(client, channel->chname, NULL, filename, &err)) { - if (!IsDead(client) && !notice) + if (!IsDead(client) && (sendtype != SEND_TYPE_NOTICE)) { strlcpy(errbuf, err, sizeof(errbuf)); *errmsg = errbuf; diff --git a/src/modules/echo-message.c b/src/modules/echo-message.c index 20d856558..1cb1687f3 100644 --- a/src/modules/echo-message.c +++ b/src/modules/echo-message.c @@ -35,8 +35,8 @@ ModuleHeader MOD_HEADER long CAP_ECHO_MESSAGE = 0L; /* Forward declarations */ -int em_chanmsg(Client *client, Channel *channel, int sendflags, int prefix, char *target, MessageTag *mtags, char *text, int notice); -int em_usermsg(Client *client, Client *to, MessageTag *mtags, char *text, int notice); +int em_chanmsg(Client *client, Channel *channel, int sendflags, int prefix, char *target, MessageTag *mtags, char *text, SendType sendtype); +int em_usermsg(Client *client, Client *to, MessageTag *mtags, char *text, SendType sendtype); MOD_INIT() { @@ -64,26 +64,26 @@ MOD_UNLOAD() return MOD_SUCCESS; } -int em_chanmsg(Client *client, Channel *channel, int sendflags, int prefix, char *target, MessageTag *mtags, char *text, int notice) +int em_chanmsg(Client *client, Channel *channel, int sendflags, int prefix, char *target, MessageTag *mtags, char *text, SendType sendtype) { - if (MyUser(client) && HasCapabilityFast(client, CAP_ECHO_MESSAGE)) + if (MyUser(client) && HasCapabilityFast(client, CAP_ECHO_MESSAGE) && (sendtype != SEND_TYPE_TAGMSG)) { sendto_prefix_one(client, client, mtags, ":%s %s %s :%s", client->name, - notice ? "NOTICE" : "PRIVMSG", + sendtype_to_cmd(sendtype), target, text); } return 0; } -int em_usermsg(Client *client, Client *to, MessageTag *mtags, char *text, int notice) +int em_usermsg(Client *client, Client *to, MessageTag *mtags, char *text, SendType sendtype) { - if (MyUser(client) && HasCapabilityFast(client, CAP_ECHO_MESSAGE)) + if (MyUser(client) && HasCapabilityFast(client, CAP_ECHO_MESSAGE) && (sendtype != SEND_TYPE_TAGMSG)) { sendto_prefix_one(client, client, mtags, ":%s %s %s :%s", client->name, - notice ? "NOTICE" : "PRIVMSG", + sendtype_to_cmd(sendtype), to->name, text); } diff --git a/src/modules/message-tags.c b/src/modules/message-tags.c index 138959be8..1eab0fd52 100644 --- a/src/modules/message-tags.c +++ b/src/modules/message-tags.c @@ -34,7 +34,6 @@ ModuleHeader MOD_HEADER long CAP_MESSAGE_TAGS = 0L; char *_mtags_to_string(MessageTag *m, Client *client); void _parse_message_tags(Client *client, char **str, MessageTag **mtag_list); -CMD_FUNC(cmd_tagmsg); MOD_TEST() { @@ -55,7 +54,6 @@ MOD_INIT() memset(&cap, 0, sizeof(cap)); cap.name = "message-tags"; ClientCapabilityAdd(modinfo->handle, &cap, &CAP_MESSAGE_TAGS); - CommandAdd(modinfo->handle, "TAGMSG", cmd_tagmsg, 1, CMD_USER); return MOD_SUCCESS; } @@ -296,11 +294,3 @@ char *_mtags_to_string(MessageTag *m, Client *client) return buf; } - -/* Dummy handler for TAGMSG. - * We do not permit user tags, so implementing a real TAGMSG makes no sense. - * By having a dummy command we avoid clients from getting "Unknown command". - */ -CMD_FUNC(cmd_tagmsg) -{ -} diff --git a/src/modules/message.c b/src/modules/message.c index e97635f32..af588c827 100644 --- a/src/modules/message.c +++ b/src/modules/message.c @@ -27,13 +27,10 @@ int ban_version(Client *client, char *text); CMD_FUNC(cmd_private); CMD_FUNC(cmd_notice); -void cmd_message(Client *client, MessageTag *recv_mtags, int parc, char *parv[], int notice); -int _can_send_to_channel(Client *client, Channel *channel, char **msgtext, char **errmsg, int notice); -int can_send_to_user(Client *client, Client *target, char **msgtext, char **errmsg, int notice); - -/* Place includes here */ -#define MSG_PRIVATE "PRIVMSG" /* PRIV */ -#define MSG_NOTICE "NOTICE" /* NOTI */ +CMD_FUNC(cmd_tagmsg); +void cmd_message(Client *client, MessageTag *recv_mtags, int parc, char *parv[], SendType sendtype); +int _can_send_to_channel(Client *client, Channel *channel, char **msgtext, char **errmsg, SendType sendtype); +int can_send_to_user(Client *client, Client *target, char **msgtext, char **errmsg, SendType sendtype); ModuleHeader MOD_HEADER = { @@ -56,8 +53,9 @@ MOD_TEST() /* This is called on module init, before Server Ready */ MOD_INIT() { - CommandAdd(modinfo->handle, MSG_PRIVATE, cmd_private, 2, CMD_USER|CMD_SERVER|CMD_RESETIDLE|CMD_VIRUS); - CommandAdd(modinfo->handle, MSG_NOTICE, cmd_notice, 2, CMD_USER|CMD_SERVER); + CommandAdd(modinfo->handle, "PRIVMSG", cmd_private, 2, CMD_USER|CMD_SERVER|CMD_RESETIDLE|CMD_VIRUS); + CommandAdd(modinfo->handle, "NOTICE", cmd_notice, 2, CMD_USER|CMD_SERVER); + CommandAdd(modinfo->handle, "TAGMSG", cmd_tagmsg, 1, CMD_USER|CMD_SERVER); MARK_AS_OFFICIAL_MODULE(modinfo); return MOD_SUCCESS; } @@ -79,11 +77,11 @@ MOD_UNLOAD() /** Check if PRIVMSG's are permitted from a person to another person. * client: source client * target: target client - * notice: 1 if notice, 0 if privmsg + * sendtype: One of SEND_TYPE_* * text: Pointer to a pointer to a text [in, out] * cmd: Pointer to a pointer which contains the command to use [in, out] */ -int can_send_to_user(Client *client, Client *target, char **msgtext, char **errmsg, int notice) +int can_send_to_user(Client *client, Client *target, char **msgtext, char **errmsg, SendType sendtype) { int ret; Hook *h; @@ -109,19 +107,19 @@ int can_send_to_user(Client *client, Client *target, char **msgtext, char **errm if (is_silenced(client, target)) { - RunHook3(HOOKTYPE_SILENCED, client, target, notice); + RunHook3(HOOKTYPE_SILENCED, client, target, sendtype); /* Silently discarded, no error message */ return 0; } // Possible FIXME: make match_spamfilter also use errmsg, or via a wrapper? or use same numeric? - if (MyUser(client) && match_spamfilter(client, *msgtext, (notice ? SPAMF_USERNOTICE : SPAMF_USERMSG), target->name, 0, NULL)) + if (MyUser(client) && match_spamfilter(client, *msgtext, (sendtype == SEND_TYPE_NOTICE ? SPAMF_USERNOTICE : SPAMF_USERMSG), target->name, 0, NULL)) return 0; n = HOOK_CONTINUE; for (h = Hooks[HOOKTYPE_CAN_SEND_TO_USER]; h; h = h->next) { - n = (*(h->func.intfunc))(client, target, msgtext, errmsg, notice); + n = (*(h->func.intfunc))(client, target, msgtext, errmsg, sendtype); if (n == HOOK_DENY) { if (!*errmsg) @@ -132,13 +130,14 @@ int can_send_to_user(Client *client, Client *target, char **msgtext, char **errm return 0; } if (!*msgtext || !**msgtext) - return 0; + { + if (sendtype != SEND_TYPE_TAGMSG) + return 0; + else + *msgtext = ""; + } } - /* This may happen, if nothing is left to send anymore (don't send empty messages) */ - if (!*msgtext || !**msgtext) - return 0; - return 1; } @@ -249,18 +248,19 @@ int can_send_to_prefix(Client *client, Channel *channel, int prefix) return 1; } -/* -** cmd_message (used in cmd_private() and cmd_notice()) -** the general function to deliver MSG's between users/channels -** -** parv[1] = receiver list -** parv[2] = message text -** -** massive cleanup -** rev argv 6/91 -** -*/ -void cmd_message(Client *client, MessageTag *recv_mtags, int parc, char *parv[], int notice) +int has_client_mtags(MessageTag *mtags) +{ + MessageTag *m; + + for (m = mtags; m; m = m->next) + if (*m->name == '+') + return 1; + return 0; +} + +/* General message handler to users and channels. Used by PRIVMSG, NOTICE, etc. + */ +void cmd_message(Client *client, MessageTag *recv_mtags, int parc, char *parv[], SendType sendtype) { Client *target; Channel *channel; @@ -269,7 +269,7 @@ void cmd_message(Client *client, MessageTag *recv_mtags, int parc, char *parv[], char pfixchan[CHANNELLEN + 4]; int ret; int ntargets = 0; - char *cmd = notice ? "NOTICE" : "PRIVMSG"; + char *cmd = sendtype_to_cmd(sendtype); int maxtargets = max_targets_for_command(cmd); Hook *h; MessageTag *mtags; @@ -287,7 +287,7 @@ void cmd_message(Client *client, MessageTag *recv_mtags, int parc, char *parv[], return; } - if (parc < 3 || *parv[2] == '\0') + if ((sendtype != SEND_TYPE_TAGMSG) && (parc < 3 || *parv[2] == '\0')) { sendnumeric(client, ERR_NOTEXTTOSEND); return; @@ -352,7 +352,7 @@ void cmd_message(Client *client, MessageTag *recv_mtags, int parc, char *parv[], errmsg = NULL; if (MyUser(client) && !IsULine(client)) { - if (!can_send_to_channel(client, channel, &text, &errmsg, notice)) + if (!can_send_to_channel(client, channel, &text, &errmsg, sendtype)) { /* Send the error message, but only if: * 1) The user has not been killed @@ -360,7 +360,7 @@ void cmd_message(Client *client, MessageTag *recv_mtags, int parc, char *parv[], */ if (IsDead(client)) return; - if (!IsDead(client) && !notice && errmsg) + if (!IsDead(client) && (sendtype != SEND_TYPE_NOTICE) && errmsg) sendnumeric(client, ERR_CANNOTSENDTOCHAN, channel->chname, errmsg, p2); continue; /* skip delivery to this target */ } @@ -374,12 +374,12 @@ void cmd_message(Client *client, MessageTag *recv_mtags, int parc, char *parv[], if ((*parv[2] == '\001') && strncmp(&parv[2][1], "ACTION ", 7)) sendflags |= SKIP_CTCP; - if (MyUser(client) && match_spamfilter(client, text, notice ? SPAMF_CHANNOTICE : SPAMF_CHANMSG, channel->chname, 0, NULL)) + if (MyUser(client) && match_spamfilter(client, text, (sendtype == SEND_TYPE_NOTICE ? SPAMF_CHANNOTICE : SPAMF_CHANMSG), channel->chname, 0, NULL)) return; new_message(client, recv_mtags, &mtags); - RunHook5(HOOKTYPE_PRE_CHANMSG, client, channel, mtags, text, notice); + RunHook5(HOOKTYPE_PRE_CHANMSG, client, channel, mtags, text, sendtype); if (!text) { @@ -387,12 +387,28 @@ void cmd_message(Client *client, MessageTag *recv_mtags, int parc, char *parv[], continue; } - sendto_channel(channel, client, client->direction, - prefix, 0, sendflags, mtags, - notice ? ":%s NOTICE %s :%s" : ":%s PRIVMSG %s :%s", - client->name, targetstr, text); + if (sendtype != SEND_TYPE_TAGMSG) + { + /* PRIVMSG or NOTICE */ + sendto_channel(channel, client, client->direction, + prefix, 0, sendflags, mtags, + ":%s %s %s :%s", + client->name, cmd, targetstr, text); + } else { + /* TAGMSG: + * Only send if the message includes any user message tags. + * In other words: disallow empty and useless TAGMSG. + */ + if (has_client_mtags(mtags)) + { + sendto_channel(channel, client, client->direction, + prefix, 0, sendflags, mtags, + ":%s TAGMSG %s", + client->name, targetstr); + } + } - RunHook8(HOOKTYPE_CHANMSG, client, channel, sendflags, prefix, targetstr, mtags, text, notice); + RunHook8(HOOKTYPE_CHANMSG, client, channel, sendflags, prefix, targetstr, mtags, text, sendtype); free_message_tags(mtags); @@ -436,12 +452,12 @@ void cmd_message(Client *client, MessageTag *recv_mtags, int parc, char *parv[], { char *errmsg = NULL; text = parv[2]; - if (!can_send_to_user(client, target, &text, &errmsg, notice)) + if (!can_send_to_user(client, target, &text, &errmsg, sendtype)) { /* Message is discarded */ if (IsDead(client)) return; - if (!notice && errmsg) + if ((sendtype != SEND_TYPE_NOTICE) && errmsg) sendnumeric(client, ERR_CANTSENDTOUSER, target->name, errmsg); } else { @@ -449,7 +465,7 @@ void cmd_message(Client *client, MessageTag *recv_mtags, int parc, char *parv[], MessageTag *mtags = NULL; /* Inform sender that recipient is away, if this is so */ - if (!notice && MyConnect(client) && target->user && target->user->away) + if ((sendtype == SEND_TYPE_PRIVMSG) && MyConnect(client) && target->user && target->user->away) sendnumeric(client, RPL_AWAY, target->name, target->user->away); new_message(client, recv_mtags, &mtags); @@ -465,7 +481,7 @@ void cmd_message(Client *client, MessageTag *recv_mtags, int parc, char *parv[], client->id, cmd, target->id, text); } labeled_response_inhibit = 0; - RunHook5(HOOKTYPE_USERMSG, client, target, mtags, text, notice); + RunHook5(HOOKTYPE_USERMSG, client, target, mtags, text, sendtype); free_message_tags(mtags); continue; } @@ -496,7 +512,7 @@ void cmd_message(Client *client, MessageTag *recv_mtags, int parc, char *parv[], */ CMD_FUNC(cmd_private) { - cmd_message(client, recv_mtags, parc, parv, 0); + cmd_message(client, recv_mtags, parc, parv, SEND_TYPE_PRIVMSG); } /* @@ -506,7 +522,19 @@ CMD_FUNC(cmd_private) */ CMD_FUNC(cmd_notice) { - cmd_message(client, recv_mtags, parc, parv, 1); + cmd_message(client, recv_mtags, parc, parv, SEND_TYPE_PRIVMSG); +} + +/* +** cmd_tagmsg +** parv[1] = receiver list +*/ +CMD_FUNC(cmd_tagmsg) +{ + /* compatibility hack */ + parv[2] = ""; + parv[3] = NULL; + cmd_message(client, recv_mtags, parc, parv, SEND_TYPE_TAGMSG); } /* Taken from xchat by Peter Zelezny @@ -707,13 +735,13 @@ int ban_version(Client *client, char *text) /** Can user send a message to this channel? * @param client The client * @param channel The channel - * @param msgtext The message to send (MAY be changed, even if user is allowed to send) - * @param errmsg The error message (will be filled in) - * @param notice If it's a NOTICE then this is set to 1. Set to 0 for PRIVMSG. + * @param msgtext The message to send (MAY be changed, even if user is allowed to send) + * @param errmsg The error message (will be filled in) + * @param sendtype One of SEND_TYPE_* * @returns Returns 1 if the user is allowed to send, otherwise 0. * (note that this behavior was reversed in UnrealIRCd versions <5.x. */ -int _can_send_to_channel(Client *client, Channel *channel, char **msgtext, char **errmsg, int notice) +int _can_send_to_channel(Client *client, Channel *channel, char **msgtext, char **errmsg, SendType sendtype) { Membership *lp; int member, i = 0; @@ -769,7 +797,7 @@ int _can_send_to_channel(Client *client, Channel *channel, char **msgtext, char /* Modules can plug in as well */ for (h = Hooks[HOOKTYPE_CAN_SEND_TO_CHANNEL]; h; h = h->next) { - i = (*(h->func.intfunc))(client, channel, lp, msgtext, errmsg, notice); + i = (*(h->func.intfunc))(client, channel, lp, msgtext, errmsg, sendtype); if (i != HOOK_CONTINUE) { if (!*errmsg) @@ -780,7 +808,12 @@ int _can_send_to_channel(Client *client, Channel *channel, char **msgtext, char break; } if (!*msgtext || !**msgtext) - return 0; + { + if (sendtype != SEND_TYPE_TAGMSG) + return 0; + else + *msgtext = ""; + } } if (i != HOOK_CONTINUE) @@ -794,9 +827,6 @@ int _can_send_to_channel(Client *client, Channel *channel, char **msgtext, char *errmsg = NULL; return 0; } - if (!*msgtext || !**msgtext) - return 0; - /* Now we are going to check bans */ diff --git a/src/modules/nocodes.c b/src/modules/nocodes.c index a8f14fd8f..def29857d 100644 --- a/src/modules/nocodes.c +++ b/src/modules/nocodes.c @@ -29,7 +29,7 @@ ModuleHeader MOD_HEADER "unrealircd-5", }; -int nocodes_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, int notice); +int nocodes_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, SendType sendtype); MOD_INIT() { @@ -57,7 +57,7 @@ static int has_controlcodes(char *p) return 0; } -int nocodes_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, int notice) +int nocodes_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, SendType sendtype) { static char retbuf[4096]; Hook *h; diff --git a/src/modules/restrict-commands.c b/src/modules/restrict-commands.c index c1aac5309..ce71f4470 100644 --- a/src/modules/restrict-commands.c +++ b/src/modules/restrict-commands.c @@ -51,9 +51,9 @@ RestrictedCommand *find_restrictions_bycmd(char *cmd); RestrictedCommand *find_restrictions_byconftag(char *conftag); int rcmd_configtest(ConfigFile *cf, ConfigEntry *ce, int type, int *errs); int rcmd_configrun(ConfigFile *cf, ConfigEntry *ce, int type); -int rcmd_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, int notice); -int rcmd_can_send_to_user(Client *client, Client *target, char **text, char **errmsg, int notice); -int rcmd_block_message(Client *client, char *text, int notice, char **errmsg, char *display, char *conftag); +int rcmd_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, SendType sendtype); +int rcmd_can_send_to_user(Client *client, Client *target, char **text, char **errmsg, SendType sendtype); +int rcmd_block_message(Client *client, char *text, SendType sendtype, char **errmsg, char *display, char *conftag); CMD_OVERRIDE_FUNC(rcmd_override); // Globals @@ -308,27 +308,27 @@ int rcmd_canbypass(Client *client, RestrictedCommand *rcmd) return 0; } -int rcmd_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, int notice) +int rcmd_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, SendType sendtype) { - if (rcmd_block_message(client, *msg, notice, errmsg, "channel", (notice ? "channel-notice" : "channel-message"))) + if (rcmd_block_message(client, *msg, sendtype, errmsg, "channel", (sendtype == SEND_TYPE_NOTICE ? "channel-notice" : "channel-message"))) return HOOK_DENY; return HOOK_CONTINUE; } -int rcmd_can_send_to_user(Client *client, Client *target, char **text, char **errmsg, int notice) +int rcmd_can_send_to_user(Client *client, Client *target, char **text, char **errmsg, SendType sendtype) { // Need a few extra exceptions for user messages only =] if ((client == target) || IsULine(target)) return HOOK_CONTINUE; /* bypass/exempt */ - if (rcmd_block_message(client, *text, notice, errmsg, "user", (notice ? "private-notice" : "private-message"))) + if (rcmd_block_message(client, *text, sendtype, errmsg, "user", (sendtype == SEND_TYPE_NOTICE ? "private-notice" : "private-message"))) return HOOK_DENY; return HOOK_CONTINUE; } -int rcmd_block_message(Client *client, char *text, int notice, char **errmsg, char *display, char *conftag) +int rcmd_block_message(Client *client, char *text, SendType sendtype, char **errmsg, char *display, char *conftag) { RestrictedCommand *rcmd; static char errbuf[256]; @@ -340,6 +340,7 @@ int rcmd_block_message(Client *client, char *text, int notice, char **errmsg, ch rcmd = find_restrictions_byconftag(conftag); if (rcmd && !rcmd_canbypass(client, rcmd)) { + int notice = (sendtype == SEND_TYPE_NOTICE ? 1 : 0); // temporary hack FIXME !!! if (rcmd->connect_delay) { ircsnprintf(errbuf, sizeof(errbuf), diff --git a/src/modules/typing-indicator.c b/src/modules/typing-indicator.c new file mode 100644 index 000000000..47ca6aa41 --- /dev/null +++ b/src/modules/typing-indicator.c @@ -0,0 +1,93 @@ +/* + * IRC - Internet Relay Chat, src/modules/typing-indicator.c + * (C) 2020 Syzop & The UnrealIRCd Team + * + * See file AUTHORS in IRC package for additional names of + * the programmers. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "unrealircd.h" + +ModuleHeader MOD_HEADER + = { + "typing-indicator", + "5.0", + "+draft/typing client tag", + "UnrealIRCd Team", + "unrealircd-5", + }; + +int ti_mtag_is_ok(Client *client, char *name, char *value); +void mtag_add_ti(Client *client, MessageTag *recv_mtags, MessageTag **mtag_list, char *signature); + +MOD_INIT() +{ + MessageTagHandlerInfo mtag; + + MARK_AS_OFFICIAL_MODULE(modinfo); + + memset(&mtag, 0, sizeof(mtag)); + mtag.name = "+draft/typing"; + mtag.is_ok = ti_mtag_is_ok; + mtag.flags = MTAG_HANDLER_FLAGS_NO_CAP_NEEDED; + MessageTagHandlerAdd(modinfo->handle, &mtag); + + HookAddVoid(modinfo->handle, HOOKTYPE_NEW_MESSAGE, 0, mtag_add_ti); + + return MOD_SUCCESS; +} + +MOD_LOAD() +{ + return MOD_SUCCESS; +} + +MOD_UNLOAD() +{ + return MOD_SUCCESS; +} + +/** This function verifies if the client sending the mtag is permitted to do so. + */ +int ti_mtag_is_ok(Client *client, char *name, char *value) +{ + /* Require a non-empty parameter */ + if (BadPtr(value)) + return 0; + + /* These are the only valid values: */ + if (!strcmp(value, "active") || !strcmp(value, "paused") || !strcmp(value, "done")) + return 1; + + /* All the rest is considered illegal */ + return 0; +} + +void mtag_add_ti(Client *client, MessageTag *recv_mtags, MessageTag **mtag_list, char *signature) +{ + MessageTag *m; + + if (IsUser(client)) + { + MessageTag *m = find_mtag(recv_mtags, "+draft/typing"); + if (m) + { + m = duplicate_mtag(m); + AddListItem(m, *mtag_list); + } + } +} diff --git a/src/modules/usermodes/censor.c b/src/modules/usermodes/censor.c index 68452abeb..1b47ebd75 100644 --- a/src/modules/usermodes/censor.c +++ b/src/modules/usermodes/censor.c @@ -20,7 +20,7 @@ long UMODE_CENSOR = 0L; #define IsCensored(x) (x->umodes & UMODE_CENSOR) -int censor_can_send_to_user(Client *client, Client *target, char **text, char **errmsg, int notice); +int censor_can_send_to_user(Client *client, Client *target, char **text, char **errmsg, SendType sendtype); int censor_config_test(ConfigFile *, ConfigEntry *, int, int *); int censor_config_run(ConfigFile *, ConfigEntry *, int); @@ -237,7 +237,7 @@ char *stripbadwords_message(char *str, int *blocked) return stripbadwords(str, conf_badword_message, blocked); } -int censor_can_send_to_user(Client *client, Client *target, char **text, char **errmsg, int notice) +int censor_can_send_to_user(Client *client, Client *target, char **text, char **errmsg, SendType sendtype) { int blocked = 0; diff --git a/src/modules/usermodes/noctcp.c b/src/modules/usermodes/noctcp.c index 92498091a..cc3e7dee7 100644 --- a/src/modules/usermodes/noctcp.c +++ b/src/modules/usermodes/noctcp.c @@ -34,7 +34,7 @@ long UMODE_NOCTCP = 0L; #define IsNoCTCP(client) (client->umodes & UMODE_NOCTCP) -int noctcp_can_send_to_user(Client *client, Client *target, char **text, char **errmsg, int notice); +int noctcp_can_send_to_user(Client *client, Client *target, char **text, char **errmsg, SendType sendtype); MOD_TEST() { @@ -74,9 +74,10 @@ static int IsACTCP(char *s) return 0; } -int noctcp_can_send_to_user(Client *client, Client *target, char **text, char **errmsg, int notice) +int noctcp_can_send_to_user(Client *client, Client *target, char **text, char **errmsg, SendType sendtype) { - if (MyUser(client) && !notice && IsNoCTCP(target) && !IsOper(client) && IsACTCP(*text)) + if (MyUser(client) && (sendtype == SEND_TYPE_PRIVMSG) && + IsNoCTCP(target) && !IsOper(client) && IsACTCP(*text)) { *errmsg = "User does not accept CTCPs"; return HOOK_DENY; diff --git a/src/modules/usermodes/privdeaf.c b/src/modules/usermodes/privdeaf.c index a788c0053..657e64530 100644 --- a/src/modules/usermodes/privdeaf.c +++ b/src/modules/usermodes/privdeaf.c @@ -17,7 +17,7 @@ ModuleHeader MOD_HEADER static long UMODE_PRIVDEAF = 0; static Umode *UmodePrivdeaf = NULL; -int privdeaf_can_send_to_user(Client *client, Client *target, char **text, char **errmsg, int notice); +int privdeaf_can_send_to_user(Client *client, Client *target, char **text, char **errmsg, SendType sendtype); MOD_INIT() { @@ -47,7 +47,7 @@ MOD_UNLOAD() return MOD_SUCCESS; } -int privdeaf_can_send_to_user(Client *client, Client *target, char **text, char **errmsg, int notice) +int privdeaf_can_send_to_user(Client *client, Client *target, char **text, char **errmsg, SendType sendtype) { if ((target->umodes & UMODE_PRIVDEAF) && !IsOper(client) && !IsULine(client) && !IsServer(client) && (client != target)) diff --git a/src/modules/usermodes/regonlymsg.c b/src/modules/usermodes/regonlymsg.c index bc9cc7847..4555e67e4 100644 --- a/src/modules/usermodes/regonlymsg.c +++ b/src/modules/usermodes/regonlymsg.c @@ -35,7 +35,7 @@ ModuleHeader MOD_HEADER long UMODE_REGONLYMSG = 0L; /* Forward declarations */ -int regonlymsg_can_send_to_user(Client *client, Client *target, char **text, char **errmsg, int notice); +int regonlymsg_can_send_to_user(Client *client, Client *target, char **text, char **errmsg, SendType sendtype); MOD_INIT() { @@ -57,7 +57,7 @@ MOD_UNLOAD() return MOD_SUCCESS; } -int regonlymsg_can_send_to_user(Client *client, Client *target, char **text, char **errmsg, int notice) +int regonlymsg_can_send_to_user(Client *client, Client *target, char **text, char **errmsg, SendType sendtype) { if (IsRegOnlyMsg(target) && !IsServer(client) && !IsULine(client) && !IsLoggedIn(client)) { diff --git a/src/modules/usermodes/secureonlymsg.c b/src/modules/usermodes/secureonlymsg.c index ecc818368..28859dbd4 100644 --- a/src/modules/usermodes/secureonlymsg.c +++ b/src/modules/usermodes/secureonlymsg.c @@ -36,7 +36,7 @@ ModuleHeader MOD_HEADER long UMODE_SECUREONLYMSG = 0L; /* Forward declarations */ -int secureonlymsg_can_send_to_user(Client *client, Client *target, char **text, char **errmsg, int notice); +int secureonlymsg_can_send_to_user(Client *client, Client *target, char **text, char **errmsg, SendType sendtype); MOD_INIT() { @@ -58,7 +58,7 @@ MOD_UNLOAD() return MOD_SUCCESS; } -int secureonlymsg_can_send_to_user(Client *client, Client *target, char **text, char **errmsg, int notice) +int secureonlymsg_can_send_to_user(Client *client, Client *target, char **text, char **errmsg, SendType sendtype) { if (IsSecureOnlyMsg(target) && !IsServer(client) && !IsULine(client) && !IsSecureConnect(client)) {