int tmw_CheckChatSpam(dumb_ptr<map_session_data> sd, XString message) { nullpo_retr(1, sd); TimeT now = TimeT::now(); if (pc_isGM(sd)) return 0; if (now > sd->chat_reset_due) { sd->chat_reset_due = static_cast<time_t>(now) + battle_config.chat_spam_threshold; sd->chat_lines_in = 0; } if (now > sd->chat_repeat_reset_due) { sd->chat_repeat_reset_due = static_cast<time_t>(now) + (battle_config.chat_spam_threshold * 60); sd->chat_total_repeats = 0; } sd->chat_lines_in++; // Penalty for repeats. if (sd->chat_lastmsg.startswith(message) || message.startswith(sd->chat_lastmsg)) { sd->chat_lines_in += battle_config.chat_lame_penalty; sd->chat_total_repeats++; } else { sd->chat_total_repeats = 0; } // Penalty for lame, it can stack on top of the repeat penalty. if (tmw_CheckChatLameness(sd, message)) sd->chat_lines_in += battle_config.chat_lame_penalty; sd->chat_lastmsg = message; if (sd->chat_lines_in >= battle_config.chat_spam_flood || sd->chat_total_repeats >= battle_config.chat_spam_flood) { sd->chat_lines_in = sd->chat_total_repeats = 0; tmw_AutoBan(sd, "chat"_s, battle_config.chat_spam_ban); return 1; } if (battle_config.chat_spam_ban && (sd->chat_lines_in >= battle_config.chat_spam_warn || sd->chat_total_repeats >= battle_config.chat_spam_warn)) { clif_displaymessage(sd->sess, "WARNING: You are about to be automatically banned for spam!"_s); clif_displaymessage(sd->sess, "WARNING: Please slow down, do not repeat, and do not SHOUT!"_s); } return 0; }
inline bool extract(XString str, HumanTimeDiff *iv) { // str is a sequence of [-+]?[0-9]+([ay]|m|[jd]|h|mn|s) // there are NO spaces here // parse by counting the number starts auto is_num = [](char c) { return c == '-' || c == '+' || ('0' <= c && c <= '9'); }; if (!str || !is_num(str.front())) return false; *iv = HumanTimeDiff{}; while (str) { auto it = std::find_if_not(str.begin(), str.end(), is_num); auto it2 = std::find_if(it, str.end(), is_num); XString number = str.xislice_h(it); XString suffix = str.xislice(it, it2); str = str.xislice_t(it2); short *ptr = nullptr; if (suffix == "y"_s || suffix == "a"_s) ptr = &iv->year; else if (suffix == "m"_s) ptr = &iv->month; else if (suffix == "j"_s || suffix == "d"_s) ptr = &iv->day; else if (suffix == "h"_s) ptr = &iv->hour; else if (suffix == "mn"_s) ptr = &iv->minute; else if (suffix == "s"_s) ptr = &iv->second; else return false; if (number.startswith('+') && !number.startswith("+-"_s)) number = number.xslice_t(1); if (*ptr || !extract(number, ptr)) return false; } return true; }
bool is_comment(XString line) { return not line or line.startswith("//"_s); }