From 02bdf55663aa8f16b667c0295d4855c65fc2a825 Mon Sep 17 00:00:00 2001 From: Keegan Date: Tue, 23 Apr 2019 18:05:26 -0400 Subject: [PATCH] update some stuff --- SQL/tgstation_schema.sql | 14 -- code/game/world.dm | 304 +-------------------------------- code/modules/admin/IsBanned.dm | 121 ++++--------- 3 files changed, 35 insertions(+), 404 deletions(-) diff --git a/SQL/tgstation_schema.sql b/SQL/tgstation_schema.sql index 4a2cf7d4a93d41..9506e05cac41d6 100644 --- a/SQL/tgstation_schema.sql +++ b/SQL/tgstation_schema.sql @@ -480,11 +480,7 @@ CREATE TABLE `stickyban` ( -- Table structure for table `stickyban_matched_ckey` -- DROP TABLE IF EXISTS `stickyban_matched_ckey`; -<<<<<<< HEAD CREATE TABLE `stickyban_matched_ckey` ( -======= -CREATE TABLE `ss13_stickyban_matched_ckey` ( ->>>>>>> c961d93... Merge pull request #42899 from MrStonedOne/sqlstickybans `stickyban` VARCHAR(32) NOT NULL, `matched_ckey` VARCHAR(32) NOT NULL, `first_matched` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, @@ -494,17 +490,10 @@ CREATE TABLE `ss13_stickyban_matched_ckey` ( ) ENGINE=InnoDB; -- -<<<<<<< HEAD -- Table structure for table `stickyban_matched_ip` -- DROP TABLE IF EXISTS `stickyban_matched_ip`; CREATE TABLE `stickyban_matched_ip` ( -======= --- Table structure for table `ss13_stickyban_matched_ip` --- -DROP TABLE IF EXISTS `ss13_stickyban_matched_ip`; -CREATE TABLE `ss13_stickyban_matched_ip` ( ->>>>>>> c961d93... Merge pull request #42899 from MrStonedOne/sqlstickybans `stickyban` VARCHAR(32) NOT NULL, `matched_ip` INT UNSIGNED NOT NULL, `first_matched` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, @@ -523,10 +512,7 @@ CREATE TABLE `stickyban_matched_cid` ( `last_matched` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`stickyban`, `matched_cid`) ) ENGINE=InnoDB; -<<<<<<< HEAD -======= ->>>>>>> c961d93... Merge pull request #42899 from MrStonedOne/sqlstickybans /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; diff --git a/code/game/world.dm b/code/game/world.dm index dc5478363e05f4..1b5d4f446911b7 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -1,4 +1,3 @@ -<<<<<<< HEAD #define RESTART_COUNTER_PATH "data/round_counter.txt" GLOBAL_VAR(restart_counter) @@ -111,9 +110,11 @@ GLOBAL_VAR_INIT(bypass_tgs_reboot, world.system_type == UNIX && world.byond_buil GLOB.world_href_log = "[GLOB.log_directory]/hrefs.log" GLOB.sql_error_log = "[GLOB.log_directory]/sql.log" GLOB.world_qdel_log = "[GLOB.log_directory]/qdel.log" + GLOB.world_map_error_log = "[GLOB.log_directory]/map_errors.log" GLOB.world_runtime_log = "[GLOB.log_directory]/runtime.log" GLOB.query_debug_log = "[GLOB.log_directory]/query_debug.log" GLOB.world_job_debug_log = "[GLOB.log_directory]/job_debug.log" + GLOB.world_paper_log = "[GLOB.log_directory]/paper.log" #ifdef UNIT_TESTS GLOB.test_log = file("[GLOB.log_directory]/tests.log") @@ -302,303 +303,4 @@ GLOBAL_VAR_INIT(bypass_tgs_reboot, world.system_type == UNIX && world.byond_buil /world/proc/incrementMaxZ() maxz++ SSmobs.MaxZChanged() - SSidlenpcpool.MaxZChanged() -======= -#define RESTART_COUNTER_PATH "data/round_counter.txt" - -GLOBAL_VAR(restart_counter) - -//This happens after the Master subsystem new(s) (it's a global datum) -//So subsystems globals exist, but are not initialised -/world/New() - - log_world("World loaded at [time_stamp()]!") - - SetupExternalRSC() - - GLOB.config_error_log = GLOB.world_manifest_log = GLOB.world_pda_log = GLOB.world_job_debug_log = GLOB.sql_error_log = GLOB.world_href_log = GLOB.world_runtime_log = GLOB.world_attack_log = GLOB.world_game_log = "data/logs/config_error.[GUID()].log" //temporary file used to record errors with loading config, moved to log directory once logging is set bl - - make_datum_references_lists() //initialises global lists for referencing frequently used datums (so that we only ever do it once) - - TgsNew(minimum_required_security_level = TGS_SECURITY_TRUSTED) - - GLOB.revdata = new - - config.Load(params[OVERRIDE_CONFIG_DIRECTORY_PARAMETER]) - - load_admins() - - //SetupLogs depends on the RoundID, so lets check - //DB schema and set RoundID if we can - SSdbcore.CheckSchemaVersion() - SSdbcore.SetRoundID() - SetupLogs() - -#ifndef USE_CUSTOM_ERROR_HANDLER - world.log = file("[GLOB.log_directory]/dd.log") -#endif - - LoadVerbs(/datum/verbs/menu) - if(CONFIG_GET(flag/usewhitelist)) - load_whitelist() - - GLOB.timezoneOffset = text2num(time2text(0,"hh")) * 36000 - - if(fexists(RESTART_COUNTER_PATH)) - GLOB.restart_counter = text2num(trim(file2text(RESTART_COUNTER_PATH))) - fdel(RESTART_COUNTER_PATH) - - if(NO_INIT_PARAMETER in params) - return - - Master.Initialize(10, FALSE, TRUE) - - if(TEST_RUN_PARAMETER in params) - HandleTestRun() - -/world/proc/HandleTestRun() - //trigger things to run the whole process - Master.sleep_offline_after_initializations = FALSE - SSticker.start_immediately = TRUE - CONFIG_SET(number/round_end_countdown, 0) - var/datum/callback/cb -#ifdef UNIT_TESTS - cb = CALLBACK(GLOBAL_PROC, /proc/RunUnitTests) -#else - cb = VARSET_CALLBACK(SSticker, force_ending, TRUE) -#endif - SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, /proc/addtimer, cb, 10 SECONDS)) - -/world/proc/SetupExternalRSC() -#if (PRELOAD_RSC == 0) - GLOB.external_rsc_urls = world.file2list("[global.config.directory]/external_rsc_urls.txt","\n") - var/i=1 - while(i<=GLOB.external_rsc_urls.len) - if(GLOB.external_rsc_urls[i]) - i++ - else - GLOB.external_rsc_urls.Cut(i,i+1) -#endif - -/world/proc/SetupLogs() - var/override_dir = params[OVERRIDE_LOG_DIRECTORY_PARAMETER] - if(!override_dir) - var/realtime = world.realtime - var/texttime = time2text(realtime, "YYYY/MM/DD") - GLOB.log_directory = "data/logs/[texttime]/round-" - GLOB.picture_logging_prefix = "L_[time2text(realtime, "YYYYMMDD")]_" - GLOB.picture_log_directory = "data/picture_logs/[texttime]/round-" - if(GLOB.round_id) - GLOB.log_directory += "[GLOB.round_id]" - GLOB.picture_logging_prefix += "R_[GLOB.round_id]_" - GLOB.picture_log_directory += "[GLOB.round_id]" - else - var/timestamp = replacetext(time_stamp(), ":", ".") - GLOB.log_directory += "[timestamp]" - GLOB.picture_log_directory += "[timestamp]" - GLOB.picture_logging_prefix += "T_[timestamp]_" - else - GLOB.log_directory = "data/logs/[override_dir]" - GLOB.picture_logging_prefix = "O_[override_dir]_" - GLOB.picture_log_directory = "data/picture_logs/[override_dir]" - - GLOB.world_game_log = "[GLOB.log_directory]/game.log" - GLOB.world_mecha_log = "[GLOB.log_directory]/mecha.log" - GLOB.world_virus_log = "[GLOB.log_directory]/virus.log" - GLOB.world_attack_log = "[GLOB.log_directory]/attack.log" - GLOB.world_pda_log = "[GLOB.log_directory]/pda.log" - GLOB.world_telecomms_log = "[GLOB.log_directory]/telecomms.log" - GLOB.world_manifest_log = "[GLOB.log_directory]/manifest.log" - GLOB.world_href_log = "[GLOB.log_directory]/hrefs.log" - GLOB.sql_error_log = "[GLOB.log_directory]/sql.log" - GLOB.world_qdel_log = "[GLOB.log_directory]/qdel.log" - GLOB.world_runtime_log = "[GLOB.log_directory]/runtime.log" - GLOB.query_debug_log = "[GLOB.log_directory]/query_debug.log" - GLOB.world_job_debug_log = "[GLOB.log_directory]/job_debug.log" - -#ifdef UNIT_TESTS - GLOB.test_log = file("[GLOB.log_directory]/tests.log") - start_log(GLOB.test_log) -#endif - start_log(GLOB.world_game_log) - start_log(GLOB.world_attack_log) - start_log(GLOB.world_pda_log) - start_log(GLOB.world_telecomms_log) - start_log(GLOB.world_manifest_log) - start_log(GLOB.world_href_log) - start_log(GLOB.world_qdel_log) - start_log(GLOB.world_runtime_log) - start_log(GLOB.world_job_debug_log) - - GLOB.changelog_hash = md5('html/changelog.html') //for telling if the changelog has changed recently - if(fexists(GLOB.config_error_log)) - fcopy(GLOB.config_error_log, "[GLOB.log_directory]/config_error.log") - fdel(GLOB.config_error_log) - - if(GLOB.round_id) - log_game("Round ID: [GLOB.round_id]") - - // This was printed early in startup to the world log and config_error.log, - // but those are both private, so let's put the commit info in the runtime - // log which is ultimately public. - log_runtime(GLOB.revdata.get_log_message()) - -/world/Topic(T, addr, master, key) - TGS_TOPIC //redirect to server tools if necessary - - var/static/list/topic_handlers = TopicHandlers() - - var/list/input = params2list(T) - var/datum/world_topic/handler - for(var/I in topic_handlers) - if(I in input) - handler = topic_handlers[I] - break - - if((!handler || initial(handler.log)) && config && CONFIG_GET(flag/log_world_topic)) - log_topic("\"[T]\", from:[addr], master:[master], key:[key]") - - if(!handler) - return - - handler = new handler() - return handler.TryRun(input) - -/world/proc/AnnouncePR(announcement, list/payload) - var/static/list/PRcounts = list() //PR id -> number of times announced this round - var/id = "[payload["pull_request"]["id"]]" - if(!PRcounts[id]) - PRcounts[id] = 1 - else - ++PRcounts[id] - if(PRcounts[id] > PR_ANNOUNCEMENTS_PER_ROUND) - return - - var/final_composed = "PR: [announcement]" - for(var/client/C in GLOB.clients) - C.AnnouncePR(final_composed) - -/world/proc/FinishTestRun() - set waitfor = FALSE - var/list/fail_reasons - if(GLOB) - if(GLOB.total_runtimes != 0) - fail_reasons = list("Total runtimes: [GLOB.total_runtimes]") -#ifdef UNIT_TESTS - if(GLOB.failed_any_test) - LAZYADD(fail_reasons, "Unit Tests failed!") -#endif - if(!GLOB.log_directory) - LAZYADD(fail_reasons, "Missing GLOB.log_directory!") - else - fail_reasons = list("Missing GLOB!") - if(!fail_reasons) - text2file("Success!", "[GLOB.log_directory]/clean_run.lk") - else - log_world("Test run failed!\n[fail_reasons.Join("\n")]") - sleep(0) //yes, 0, this'll let Reboot finish and prevent byond memes - qdel(src) //shut it down - -/world/Reboot(reason = 0, fast_track = FALSE) - if (reason || fast_track) //special reboot, do none of the normal stuff - if (usr) - log_admin("[key_name(usr)] Has requested an immediate world restart via client side debugging tools") - message_admins("[key_name_admin(usr)] Has requested an immediate world restart via client side debugging tools") - to_chat(world, "Rebooting World immediately due to host request") - else - to_chat(world, "Rebooting world...") - Master.Shutdown() //run SS shutdowns - - TgsReboot() - - if(TEST_RUN_PARAMETER in params) - FinishTestRun() - return - - if(TgsAvailable()) - var/do_hard_reboot - // check the hard reboot counter - var/ruhr = CONFIG_GET(number/rounds_until_hard_restart) - switch(ruhr) - if(-1) - do_hard_reboot = FALSE - if(0) - do_hard_reboot = TRUE - else - if(GLOB.restart_counter >= ruhr) - do_hard_reboot = TRUE - else - text2file("[++GLOB.restart_counter]", RESTART_COUNTER_PATH) - do_hard_reboot = FALSE - - if(do_hard_reboot) - log_world("World hard rebooted at [time_stamp()]") - shutdown_logging() // See comment below. - TgsEndProcess() - - log_world("World rebooted at [time_stamp()]") - shutdown_logging() // Past this point, no logging procs can be used, at risk of data loss. - ..() - -/world/proc/update_status() - - var/list/features = list() - - if(GLOB.master_mode) - features += GLOB.master_mode - - if (!GLOB.enter_allowed) - features += "closed" - - var/s = "" - var/hostedby - if(config) - var/server_name = CONFIG_GET(string/servername) - if (server_name) - s += "[server_name] — " - features += "[CONFIG_GET(flag/norespawn) ? "no " : ""]respawn" - if(CONFIG_GET(flag/allow_vote_mode)) - features += "vote" - if(CONFIG_GET(flag/allow_ai)) - features += "AI allowed" - hostedby = CONFIG_GET(string/hostedby) - - s += "[station_name()]"; - s += " (" - s += "" //Change this to wherever you want the hub to link to. - s += "Default" //Replace this with something else. Or ever better, delete it and uncomment the game version. - s += "" - s += ")" - - var/n = 0 - for (var/mob/M in GLOB.player_list) - if (M.client) - n++ - - if (n > 1) - features += "~[n] players" - else if (n > 0) - features += "~[n] player" - - if (!host && hostedby) - features += "hosted by [hostedby]" - - if (features) - s += ": [jointext(features, ", ")]" - - status = s - -/world/proc/update_hub_visibility(new_visibility) - if(new_visibility == GLOB.hub_visibility) - return - GLOB.hub_visibility = new_visibility - if(GLOB.hub_visibility) - hub_password = "kMZy3U5jJHSiBQjr" - else - hub_password = "SORRYNOPASSWORD" - -/world/proc/incrementMaxZ() - maxz++ - SSmobs.MaxZChanged() - SSidlenpcpool.MaxZChanged() ->>>>>>> c961d93... Merge pull request #42899 from MrStonedOne/sqlstickybans + SSidlenpcpool.MaxZChanged() \ No newline at end of file diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm index c485013c2048a0..faf7a378af8c53 100644 --- a/code/modules/admin/IsBanned.dm +++ b/code/modules/admin/IsBanned.dm @@ -2,42 +2,34 @@ //How many new ckey matches before we revert the stickyban to it's roundstart state //These are exclusive, so once it goes over one of these numbers, it reverts the ban -#define STICKYBAN_MAX_MATCHES 15 -#define STICKYBAN_MAX_EXISTING_USER_MATCHES 3 //ie, users who were connected before the ban triggered -#define STICKYBAN_MAX_ADMIN_MATCHES 1 +#define STICKYBAN_MAX_MATCHES 20 +#define STICKYBAN_MAX_EXISTING_USER_MATCHES 5 //ie, users who were connected before the ban triggered +#define STICKYBAN_MAX_ADMIN_MATCHES 2 -/world/IsBanned(key, address, computer_id, type, real_bans_only=FALSE) - debug_world_log("isbanned(): '[args.Join("', '")]'") - if (!key || (!real_bans_only && (!address || !computer_id))) +/world/IsBanned(key,address,computer_id,type,real_bans_only=FALSE) + if (!key || !address || !computer_id) if(real_bans_only) return FALSE log_access("Failed Login (invalid data): [key] [address]-[computer_id]") return list("reason"="invalid login data", "desc"="Error: Could not check ban status, Please try again. Error message: Your computer provided invalid or blank information to the server on connection (byond username, IP, and Computer ID.) Provided information for reference: Username:'[key]' IP:'[address]' Computer ID:'[computer_id]'. (If you continue to get this error, please restart byond or contact byond support.)") - var/admin = FALSE + if (text2num(computer_id) == 2147483647) //this cid causes stickybans to go haywire + log_access("Failed Login (invalid cid): [key] [address]-[computer_id]") + return list("reason"="invalid login data", "desc"="Error: Could not check ban status, Please try again. Error message: Your computer provided an invalid Computer ID.)") + var/admin = 0 var/ckey = ckey(key) - - //IsBanned can get re-called on a user in certain situations, this prevents that leading to repeated messages to admins. - var/static/list/checkedckeys = list() - //magic voodo to check for a key in a list while also adding that key to the list without having to do two associated lookups - var/message = !checkedckeys[ckey]++ - if(GLOB.admin_datums[ckey] || GLOB.deadmins[ckey]) admin = TRUE -<<<<<<< HEAD var/client/C = GLOB.directory[ckey] -======= ->>>>>>> c961d93... Merge pull request #42899 from MrStonedOne/sqlstickybans //Whitelist if(!real_bans_only && !C && CONFIG_GET(flag/usewhitelist)) if(!check_whitelist(ckey)) if (admin) log_admin("The admin [key] has been allowed to bypass the whitelist") - if (message) - message_admins("The admin [key] has been allowed to bypass the whitelist") - addclientmessage(ckey,"You have been allowed to bypass the whitelist") + message_admins("The admin [key] has been allowed to bypass the whitelist") + addclientmessage(ckey,"You have been allowed to bypass the whitelist") else log_access("Failed Login: [key] - Not on whitelist") return list("reason"="whitelist", "desc" = "\nReason: You are not on the white list for this server") @@ -53,25 +45,18 @@ //Population Cap Checking var/extreme_popcap = CONFIG_GET(number/extreme_popcap) -<<<<<<< HEAD if(!real_bans_only && !C && extreme_popcap && !admin) var/popcap_value = GLOB.clients.len if(popcap_value >= extreme_popcap && !GLOB.joined_player_list.Find(ckey)) if(!CONFIG_GET(flag/byond_member_bypass_popcap) || !world.IsSubscribed(ckey, "BYOND")) log_access("Failed Login: [key] - Population cap reached") return list("reason"="popcap", "desc"= "\nReason: [CONFIG_GET(string/extreme_popcap_message)]") -======= - if(!real_bans_only && extreme_popcap && living_player_count() >= extreme_popcap && !admin) - log_access("Failed Login: [key] - Population cap reached") - return list("reason"="popcap", "desc"= "\nReason: [CONFIG_GET(string/extreme_popcap_message)]") ->>>>>>> c961d93... Merge pull request #42899 from MrStonedOne/sqlstickybans if(CONFIG_GET(flag/sql_enabled)) if(!SSdbcore.Connect()) var/msg = "Ban database connection failure. Key [ckey] not checked" log_world(msg) - if (message) - message_admins(msg) + message_admins(msg) else var/list/ban_details = is_banned_from_with_details(ckey, address, computer_id, "Server") for(var/i in ban_details) @@ -79,14 +64,12 @@ if(text2num(i["applies_to_admins"])) var/msg = "Admin [key] is admin banned, and has been disallowed access." log_admin(msg) - if (message) - message_admins(msg) + message_admins(msg) else var/msg = "Admin [key] has been allowed to bypass a matching non-admin ban on [i["key"]] [i["ip"]]-[i["computerid"]]." log_admin(msg) - if (message) - message_admins(msg) - addclientmessage(ckey,"Admin [key] has been allowed to bypass a matching non-admin ban on [i["key"]] [i["ip"]]-[i["computerid"]].") + message_admins(msg) + addclientmessage(ckey,"Admin [key] has been allowed to bypass a matching non-admin ban on [i["key"]] [i["ip"]]-[i["computerid"]].") continue var/expires = "This is a permanent ban." if(i["expiration_time"]) @@ -97,27 +80,16 @@ [expires]"} log_access("Failed Login: [key] [computer_id] [address] - Banned (#[i["id"]])") return list("reason"="Banned","desc"="[desc]") - var/list/ban = ..() //default pager ban stuff - if (ban) - if (!admin) - . = ban - if (real_bans_only) - return var/bannedckey = "ERROR" if (ban["ckey"]) bannedckey = ban["ckey"] var/newmatch = FALSE -<<<<<<< HEAD -======= - var/client/C = GLOB.directory[ckey] ->>>>>>> c961d93... Merge pull request #42899 from MrStonedOne/sqlstickybans var/list/cachedban = SSstickyban.cache[bannedckey] //rogue ban in the process of being reverted. - if (cachedban && (cachedban["reverting"] || cachedban["timeout"])) - world.SetConfig("ban", bannedckey, null) + if (cachedban && cachedban["reverting"]) return null if (cachedban && ckey != bannedckey) @@ -130,80 +102,51 @@ if (newmatch && cachedban) var/list/newmatches = cachedban["matches_this_round"] - var/list/pendingmatches = cachedban["matches_this_round"] var/list/newmatches_connected = cachedban["existing_user_matches_this_round"] var/list/newmatches_admin = cachedban["admin_matches_this_round"] + newmatches[ckey] = ckey if (C) newmatches_connected[ckey] = ckey - newmatches_connected = cachedban["existing_user_matches_this_round"] - pendingmatches[ckey] = ckey - sleep(STICKYBAN_ROGUE_CHECK_TIME) - pendingmatches -= ckey if (admin) newmatches_admin[ckey] = ckey - if (cachedban["reverting"] || cachedban["timeout"]) - return null - - newmatches[ckey] = ckey - - if (\ - newmatches.len+pendingmatches.len > STICKYBAN_MAX_MATCHES || \ + newmatches.len > STICKYBAN_MAX_MATCHES || \ newmatches_connected.len > STICKYBAN_MAX_EXISTING_USER_MATCHES || \ newmatches_admin.len > STICKYBAN_MAX_ADMIN_MATCHES \ - ) - - var/action - if (ban["fromdb"]) - cachedban["timeout"] = TRUE - action = "putting it on timeout for the remainder of the round" - else - cachedban["reverting"] = TRUE - action = "reverting to its roundstart state" + ) + if (cachedban["reverting"]) + return null + cachedban["reverting"] = TRUE world.SetConfig("ban", bannedckey, null) - //we always report this - log_game("Stickyban on [bannedckey] detected as rogue, [action]") - message_admins("Stickyban on [bannedckey] detected as rogue, [action]") + log_game("Stickyban on [bannedckey] detected as rogue, reverting to its roundstart state") + message_admins("Stickyban on [bannedckey] detected as rogue, reverting to its roundstart state") //do not convert to timer. spawn (5) world.SetConfig("ban", bannedckey, null) sleep(1) world.SetConfig("ban", bannedckey, null) - if (!ban["fromdb"]) - cachedban = cachedban.Copy() //so old references to the list still see the ban as reverting - cachedban["matches_this_round"] = list() - cachedban["existing_user_matches_this_round"] = list() - cachedban["admin_matches_this_round"] = list() - cachedban -= "reverting" - SSstickyban.cache[bannedckey] = cachedban - world.SetConfig("ban", bannedckey, list2stickyban(cachedban)) + cachedban["matches_this_round"] = list() + cachedban["existing_user_matches_this_round"] = list() + cachedban["admin_matches_this_round"] = list() + cachedban -= "reverting" + world.SetConfig("ban", bannedckey, list2stickyban(cachedban)) return null - if (ban["fromdb"]) - if(SSdbcore.Connect()) - INVOKE_ASYNC(SSdbcore, /datum/controller/subsystem/dbcore/proc.QuerySelect, list( - SSdbcore.NewQuery("INSERT INTO [format_table_name("stickyban_matched_ckey")] (matched_ckey, stickyban) VALUES ('[sanitizeSQL(ckey)]', '[sanitizeSQL(bannedckey)]') ON DUPLICATE KEY UPDATE last_matched = now()"), - SSdbcore.NewQuery("INSERT INTO [format_table_name("stickyban_matched_ip")] (matched_ip, stickyban) VALUES ( INET_ATON('[sanitizeSQL(address)]'), '[sanitizeSQL(bannedckey)]') ON DUPLICATE KEY UPDATE last_matched = now()"), - SSdbcore.NewQuery("INSERT INTO [format_table_name("stickyban_matched_cid")] (matched_cid, stickyban) VALUES ('[sanitizeSQL(computer_id)]', '[sanitizeSQL(bannedckey)]') ON DUPLICATE KEY UPDATE last_matched = now()") - ), FALSE, TRUE) - - //byond will not trigger isbanned() for "global" host bans, //ie, ones where the "apply to this game only" checkbox is not checked (defaults to not checked) //So it's safe to let admins walk thru host/sticky bans here if (admin) log_admin("The admin [key] has been allowed to bypass a matching host/sticky ban on [bannedckey]") - if (message) - message_admins("The admin [key] has been allowed to bypass a matching host/sticky ban on [bannedckey]") - addclientmessage(ckey,"You have been allowed to bypass a matching host/sticky ban on [bannedckey]") + message_admins("The admin [key] has been allowed to bypass a matching host/sticky ban on [bannedckey]") + addclientmessage(ckey,"You have been allowed to bypass a matching host/sticky ban on [bannedckey]") return null if (C) //user is already connected!. - to_chat(C, "You are about to get disconnected for matching a sticky ban after you connected. If this turns out to be the ban evasion detection system going haywire, we will automatically detect this and revert the matches. if you feel that this is the case, please wait EXACTLY 6 seconds then reconnect using file -> reconnect to see if the match was automatically reversed.") + to_chat(C, "You are about to get disconnected for matching a sticky ban after you connected. If this turns out to be the ban evasion detection system going haywire, we will automatically detect this and revert the matches. if you feel that this is the case, please wait EXACTLY 6 seconds then reconnect using file -> reconnect to see if the match was reversed.") var/desc = "\nReason:(StickyBan) You, or another user of this computer or connection ([bannedckey]) is banned from playing here. The ban reason is:\n[ban["message"]]\nThis ban was applied by [ban["admin"]]\nThis is a BanEvasion Detection System ban, if you think this ban is a mistake, please wait EXACTLY 6 seconds, then try again before filing an appeal.\n" . = list("reason" = "Stickyban", "desc" = desc)