/* * Color ban. (C) 2015 Sam van Kampen. * * 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 blah blah blah * licensing crap find it at https://www.gnu.org/licenses/gpl-3.0.en.html */ #include #include "config.h" #include "struct.h" #include "sys.h" #include "numeric.h" #include "msg.h" #include "proto.h" #include "channel.h" #include #include #include #include #include #include #include "h.h" #define MAX_EXTBANC_PER_CHAN 15 /* Maximum amount of color bans */ #define MAX_LENGTH 150 /* Max ban length (in characters) */ /* Taken from xchat by Peter Zelezny * changed very slightly by codemastr * RGB color stripping support added -- codemastr */ char *_StripColors(unsigned char *text) { int i = 0, len = strlen(text), save_len=0; char nc = 0, col = 0, rgb = 0, *save_text=NULL; static unsigned char new_str[4096]; while (len > 0) { if ((col && isdigit(*text) && nc < 2) || (col && *text == ',' && nc < 3)) { nc++; if (*text == ',') nc = 0; } /* Syntax for RGB is ^DHHHHHH where H is a hex digit. * If < 6 hex digits are specified, the code is displayed * as text */ else if ((rgb && isxdigit(*text) && nc < 6) || (rgb && *text == ',' && nc < 7)) { nc++; if (*text == ',') nc = 0; } else { if (col) col = 0; if (rgb) { if (nc != 6) { text = save_text+1; len = save_len-1; rgb = 0; continue; } rgb = 0; } if (*text == '\003') { col = 1; nc = 0; } else if (*text == '\004') { save_text = text; save_len = len; rgb = 1; nc = 0; } else if (*text != '\026') /* (strip reverse too) */ { new_str[i] = *text; i++; } } text++; len--; } new_str[i] = 0; return new_str; } ModuleHeader MOD_HEADER(colorban) = { "colorban", "v1.0", "ExtBan ~C (colorban) by Sam van Kampen", "3.2-b8-1", NULL }; char *extban_modeC_conv_param(char *parameters); int extban_modeC_is_banned(aClient *sptr, aChannel *chptr, char *ban, int type); int extban_modeC_is_ok(aClient *sptr, aChannel *chptr, char *para, int checkt, int mode, int exbtype); DLLFUNC char *colorban_chanmsg(aClient *, aClient *, aChannel *, char *, int); DLLFUNC int MOD_INIT(colorban)(ModuleInfo *modinfo) { ExtbanInfo request; memset(&request, 0, sizeof(ExtbanInfo)); request.flag = 'C'; request.conv_param = extban_modeC_conv_param; request.is_banned = extban_modeC_is_banned; request.is_ok = extban_modeC_is_ok; if (!ExtbanAdd(modinfo->handle, request)) { config_error("colorban: adding extban ~C failed; module not loaded."); return MOD_FAILED; } ModuleSetOptions(modinfo->handle, MOD_OPT_PERM); HookAddPCharEx(modinfo->handle, HOOKTYPE_CHANMSG, colorban_chanmsg); sendto_opers("Successfully loaded module: colorban"); return MOD_SUCCESS; } DLLFUNC int MOD_LOAD(colorban)(int module_load) { return MOD_SUCCESS; } DLLFUNC int MOD_UNLOAD(colorban)(int module_unload) { return MOD_SUCCESS; } _Bool isColorBan(char *string) { return strncmp("~C:", string, 3) == 0; } unsigned int countcolorbans(aChannel *chptr) { Ban *ban; unsigned int count = 0; for (ban = chptr->banlist; ban; ban = ban->next) { if (isColorBan(ban->banstr)) count++; } for (ban = chptr->exlist; ban; ban = ban->next) { if (isColorBan(ban->banstr)) count++; } return count; } int extban_modeC_is_ok(aClient *sptr, aChannel *chptr, char *param, int checkt, int mode, int exbtype) { int n; if ((mode == MODE_ADD) && (exbtype == EXBTYPE_EXCEPT) && MyClient(sptr)) return 0; /* check the # of bans in the channel, may not exceed maximum */ if ((mode == MODE_ADD) && (checkt == EXBCHK_PARAM) && MyClient(sptr) && !IsAnOper(sptr) && (( n = countcolorbans(chptr)) >= MAX_EXTBANC_PER_CHAN)) { sendto_one(sptr, err_str(ERR_BANLISTFULL), me.name, sptr->name, chptr->chname, param); sendnotice(sptr, "Too many colorbans for this channel"); return 0; } return 1; } char *extban_modeC_conv_param(char *parameters) { // TODO: parameter checking? return parameters; } int extban_modeC_is_banned(aClient *sptr, aChannel *chptr, char *ban, int type) { /* Never banned here */ return 0; } _Bool uhostMatches(char *banstring, char *uhost) { char tmp[512] = {0}; strncpy(tmp, banstring + 3, strlen(banstring)); return match(banstring, uhost); } DLLFUNC char *colorban_chanmsg(aClient *cptr, aClient *sptr, aChannel *chptr, char *text, int notice) { char uhost[USERLEN + HOSTLEN + 16]; size_t text_length = strlen(text); ircsprintf(uhost, "%s@%s", sptr->user->username, GetHost(sptr)); Ban *ban; if (!MyClient(sptr)) return text; /* Remote server */ for (ban = chptr->banlist; ban; ban = ban->next) { if (isColorBan(ban->banstr) && uhostMatches(ban->banstr, uhost)) { char *stripped = _StripColors(text); memset(text, 0, text_length); memcpy(text, stripped, strlen(stripped)); break; } } return text; }