int BX_check_flooding(char *nick, int type, char *line, char *channel) { static int users = 0, pos = 0; time_t flood_time = now, diff = 0; Flooding *tmp; int flood_rate, flood_count; if (!(users = get_int_var(FLOOD_USERS_VAR)) || !*FromUserHost) return 1; if (find_name_in_genericlist(nick, no_flood_list, FLOOD_HASHSIZE, 0)) return 1; if (!(tmp = find_name_in_floodlist(nick, FromUserHost, flood_list, FLOOD_HASHSIZE, 0))) { if (pos >= users) { pos -= remove_oldest_flood_hashlist(&flood_list[0], 0, (users + 1 - pos)); } tmp = add_name_to_floodlist(nick, FromUserHost, channel, flood_list, FLOOD_HASHSIZE); tmp->type = type; tmp->cnt = 1; tmp->start = flood_time; tmp->flood = 0; pos++; return 1; } if (!(tmp->type & type)) { tmp->type |= type; return 1; } #if 0 flood_count = get_flood_count(type, NULL); /* FLOOD_AFTER_VAR */ flood_rate = get_flood_rate(type, NULL); /* FLOOD_RATE_VAR */ #endif get_flood_val(NULL, type, &flood_count, &flood_rate); if (!flood_count || !flood_rate) return 1; tmp->cnt++; if (tmp->cnt > flood_count) { int ret; diff = flood_time - tmp->start; if (diff != 0) this_flood = (double)tmp->cnt / (double)diff; else this_flood = 0; allow_flood = (double)flood_count / (double)flood_rate; if (!diff || !this_flood || (this_flood > allow_flood)) { if (tmp->flood == 0) { tmp->flood = 1; if ((ret = do_hook(FLOOD_LIST, "%s %s %s %s", nick, get_flood_types(type),channel?channel:zero, line)) != 1) return ret; switch(type) { case WALL_FLOOD: case MSG_FLOOD: case NOTICE_FLOOD: case CDCC_FLOOD: case CTCP_FLOOD: if (flood_prot(nick, FromUserHost, get_flood_types(type), type, get_int_var(IGNORE_TIME_VAR), channel)) return 0; break; case CTCP_ACTION_FLOOD: if (flood_prot(nick, FromUserHost, get_flood_types(CTCP_FLOOD), type, get_int_var(IGNORE_TIME_VAR), channel)) return 0; default: break; } if (get_int_var(FLOOD_WARNING_VAR)) put_it("%s", convert_output_format(fget_string_var(FORMAT_FLOOD_FSET), "%s %s %s %s %s", update_clock(GET_TIME), get_flood_types(type), nick, FromUserHost, channel?channel:"unknown")); } return 1; } else { tmp->flood = 0; tmp->cnt = 1; tmp->start = flood_time; } } return 1; }
static void p_privmsg(char *from, char **Args) { int level, list_type, flood_type, log_type, no_flood = 1, do_beep = 1; unsigned char ignore_type; char *ptr = NULL, *to; char *high; struct channel *channel = NULL; struct nick_list *tmpnick = NULL; if (!from) return; PasteArgs(Args, 1); to = Args[0]; ptr = Args[1]; if (!to || !ptr) { fake(); return; } doing_privmsg = 1; if (is_channel(to) && im_on_channel(to)) { message_from(to, LOG_MSG); malloc_strcpy(&public_nick, from); log_type = LOG_PUBLIC; ignore_type = IGNORE_PUBLIC; flood_type = PUBLIC_FLOOD; if (!is_on_channel(to, from_server, from)) list_type = PUBLIC_MSG_LIST; else { if (is_current_channel(to, from_server, 0)) list_type = PUBLIC_LIST; else list_type = PUBLIC_OTHER_LIST; channel = lookup_channel(to, from_server, CHAN_NOUNLINK); if (channel) tmpnick = find_nicklist_in_channellist(from, channel, 0); } } else { message_from(from, LOG_MSG); flood_type = MSG_FLOOD; if (my_stricmp(to, get_server_nickname(from_server))) { log_type = LOG_WALL; ignore_type = IGNORE_WALLS; list_type = MSG_GROUP_LIST; } else { log_type = LOG_MSG; ignore_type = IGNORE_MSGS; list_type = MSG_LIST; } } switch (check_ignore(from, FromUserHost, to, ignore_type, ptr)) { case IGNORED: if ((list_type == MSG_LIST) && get_int_var(SEND_IGNORE_MSG_VAR)) send_to_server(SERVER(from_server), "NOTICE %s :%s is ignoring you", from, get_server_nickname(from_server)); doing_privmsg = 0; return; case HIGHLIGHTED: high = highlight_char; break; case CHANNEL_GREP: high = highlight_char; break; default: high = empty_str; break; } ptr = do_ctcp(from, to, ptr); if (!ptr || !*ptr) { doing_privmsg = 0; return; } level = set_lastlog_msg_level(log_type); if (flood_type == PUBLIC_FLOOD) { int blah = 0; if (is_other_flood(channel, tmpnick, PUBLIC_FLOOD, &blah)) { no_flood = 0; flood_prot(tmpnick->nick, FromUserHost, "PUBLIC", flood_type, get_int_var(PUBFLOOD_TIME_VAR), channel->channel); } } else no_flood = check_flooding(from, flood_type, ptr, NULL); { switch (list_type) { case PUBLIC_MSG_LIST: logmsg(LOG_PUBLIC, from, ptr, 0); if (no_flood && do_hook(list_type, "%s %s %s", from, to, ptr)) put_it("%s", convert_output_format(get_format(FORMAT_PUBLIC_MSG_FSET), "%s %s %s %s %s", update_clock(GET_TIME), from, FromUserHost, to, get_int_var(MIRCS_VAR) ? mircansi(ptr) : ptr)); break; case MSG_GROUP_LIST: logmsg(LOG_PUBLIC, from, ptr, 0); if (no_flood && do_hook(list_type, "%s %s %s", from, to, ptr)) put_it("%s", convert_output_format(get_format(FORMAT_MSG_GROUP_FSET), "%s %s %s %s", update_clock(GET_TIME), from, to, get_int_var(MIRCS_VAR) ? mircansi(ptr) : ptr)); break; case MSG_LIST: { if (!no_flood) break; malloc_strcpy(&recv_nick, from); if (away_set) { do_beep = 0; beep_em(get_int_var(BEEP_WHEN_AWAY_VAR)); set_int_var(MSGCOUNT_VAR, get_int_var(MSGCOUNT_VAR) + 1); } logmsg(LOG_MSG, from, ptr, 0); addtabkey(from, "msg"); if (do_hook(list_type, "%s %s", from, ptr)) put_it("%s", convert_output_format(get_format(FORMAT_MSG_FSET), "%s %s %s %s", update_clock(GET_TIME), from, FromUserHost, get_int_var(MIRCS_VAR) ? mircansi(ptr) : ptr)); if (from_server > -1 && get_server_away(from_server) && get_int_var(SEND_AWAY_MSG_VAR)) { send_to_server(SERVER(from_server), "NOTICE %s :%s", from, stripansicodes(convert_output_format (get_format(FORMAT_SEND_AWAY_FSET), "%l %l %s", time(NULL), server_list[from_server].awaytime, get_int_var(MSGLOG_VAR) ? "On" : "Off"))); } break; } case PUBLIC_LIST:{ logmsg(LOG_PUBLIC, from, ptr, 0); if (no_flood && do_hook(list_type, "%s %s %s", from, to, ptr)) put_it("%s", convert_output_format(get_format(FORMAT_PUBLIC_FSET), "%s %s %s %s", update_clock(GET_TIME), from, to, get_int_var(MIRCS_VAR) ? mircansi(ptr) : ptr)); break; } case PUBLIC_OTHER_LIST:{ logmsg(LOG_PUBLIC, from, ptr, 0); if (no_flood && do_hook(list_type, "%s %s %s", from, to, ptr)) put_it("%s", convert_output_format(get_format(FORMAT_PUBLIC_OTHER_FSET), "%s %s %s %s", update_clock(GET_TIME), from, to, get_int_var(MIRCS_VAR) ? mircansi(ptr) : ptr)); break; } /* case */ } /* switch */ } if (beep_on_level & log_type && do_beep) beep_em(1); set_lastlog_msg_level(level); message_from(NULL, LOG_CRAP); doing_privmsg = 0; }