diff --git a/SQL/migrate/V012__Deleteable_mirrors.sql b/SQL/migrate/V012__Deleteable_mirrors.sql new file mode 100644 index 00000000000..35e9cd5c82a --- /dev/null +++ b/SQL/migrate/V012__Deleteable_mirrors.sql @@ -0,0 +1,29 @@ +-- +-- Implemented in PR #4026. +-- Adds a deleted_at column for mirrors. +-- Also adds indexes for speeding up search queries around the ban database. +-- + +ALTER TABLE `ss13_ban_mirrors` + ADD `deleted_at` DATETIME NULL DEFAULT NULL AFTER `extra_info`; + +CREATE INDEX `idx_mirrors_isbanned` ON `ss13_ban_mirrors` ( + `deleted_at`, + `ckey`, + `ip`, + `computerid` +); + +CREATE INDEX `idx_mirrors_select` ON `ss13_ban_mirrors` ( + `deleted_at`, + `ban_id` +); + +CREATE INDEX `idx_ban_isbanned` ON `ss13_ban` ( + `unbanned`, + `bantype`, + `expiration_time`, + `ckey`, + `computerid`, + `ip` +); diff --git a/code/modules/admin/DB ban/ban_mirroring.dm b/code/modules/admin/DB ban/ban_mirroring.dm index c0d90ffdd40..ae2d7001188 100644 --- a/code/modules/admin/DB ban/ban_mirroring.dm +++ b/code/modules/admin/DB ban/ban_mirroring.dm @@ -30,7 +30,7 @@ bad_data &= ~BAD_CID if (bad_data) - var/DBQuery/mirrored_bans = dbcon.NewQuery("SELECT ckey, ip, computerid FROM ss13_ban_mirrors WHERE ban_id = :ban_id:") + var/DBQuery/mirrored_bans = dbcon.NewQuery("SELECT ckey, ip, computerid FROM ss13_ban_mirrors WHERE isnull(deleted_at) AND ban_id = :ban_id:") mirrored_bans.Execute(list("ban_id" = ban_id)) while (mirrored_bans.NextRow()) @@ -66,7 +66,7 @@ log_misc("Ban database connection failure while attempting to check mirrors. Key passed for mirror checking: [ckey].") return null - var/DBQuery/initial_query = dbcon.NewQuery("SELECT DISTINCT ban_id FROM ss13_ban_mirrors WHERE ckey = :ckey: OR ip = :address: OR computerid = :computerid:") + var/DBQuery/initial_query = dbcon.NewQuery("SELECT DISTINCT ban_id FROM ss13_ban_mirrors WHERE isnull(deleted_at) AND (ckey = :ckey: OR ip = :address: OR computerid = :computerid:)") initial_query.Execute(list("ckey" = ckey, "address" = address, "computerid" = computer_id)) var/list/ban_ids = list() @@ -78,7 +78,7 @@ if (!ban_ids.len) return null - var/DBQuery/search_query = dbcon.NewQuery("SELECT id FROM ss13_ban WHERE id IN :vars: AND (bantype = 'PERMABAN' OR (bantype = 'TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)") + var/DBQuery/search_query = dbcon.NewQuery("SELECT id FROM ss13_ban WHERE id IN :vars: AND isnull(unbanned) AND (bantype = 'PERMABAN' OR (bantype = 'TEMPBAN' AND expiration_time > Now()))") search_query.Execute(list("vars" = ban_ids)) var/list/active_bans = list() @@ -116,7 +116,7 @@ if (!dbcon.IsConnected()) return null - var/DBQuery/query = dbcon.NewQuery("SELECT id, ckey, ip, computerid, date(datetime) as datetime, source, extra_info FROM ss13_ban_mirrors WHERE ban_id = :ban_id:") + var/DBQuery/query = dbcon.NewQuery("SELECT id, ckey, ip, computerid, date(datetime) as datetime, source, extra_info, deleted_at FROM ss13_ban_mirrors WHERE ban_id = :ban_id:") query.Execute(list("ban_id" = ban_id)) var/list/mirrors = list() @@ -137,6 +137,11 @@ items["extra"] = TRUE catch() + if (query.item[8]) + items["inactive"] = TRUE + else + items["inactive"] = FALSE + mirrors += list(items) return mirrors @@ -169,18 +174,17 @@ var/static/list/bg_colors = list("#ffeeee", "#ffdddd") var/i = 0 for (var/mirror in mirrors) - var/bg = bg_colors[i + 1] var/list/details = mirror + var/bg = details["inactive"] ? "#aaaaaa" : bg_colors[i + 1] output += "" output += "[details["source"]]" output += "[details["ckey"]]" output += "[details["date"]]" + output += "[details["inactive"] ? "Reactivate" : "Deactivate"]" if (details["extra"]) - output += "View Ckeys" - else - output += "" - output += "" + output += " | View Ckeys" + output += "" output += "" output += "IP: [details["ip"]]" @@ -227,6 +231,22 @@ output += "

Back" user << browse(output, "window=banmirrors") +/proc/toggle_mirror_status(mob/user, mirror_id, inactive = FALSE) + if (!user || !check_rights(R_MOD|R_ADMIN) || !mirror_id) + return + + if (!establish_db_connection(dbcon)) + to_chat(user, "Database connection failed!") + return + + var/DBQuery/query = dbcon.NewQuery("UPDATE ss13_ban_mirrors SET deleted_at = :new_state: WHERE id = :id:") + query.Execute(list("new_state" = inactive ? null : "NOW()", "id" = mirror_id)) + + if (query.ErrorMsg()) + to_chat(user, "An error occured while toggling mirror status!") + else + to_chat(user, "Mirror set to [inactive ? "ACTIVE" : "INACTIVE"].") + /proc/handle_connection_info(var/client/C, var/data) if (!C) return diff --git a/code/modules/admin/DB ban/functions.dm b/code/modules/admin/DB ban/functions.dm index bb47a240948..cd2aa4a2496 100644 --- a/code/modules/admin/DB ban/functions.dm +++ b/code/modules/admin/DB ban/functions.dm @@ -133,7 +133,7 @@ else bantype_sql = "bantype = '[bantype_str]'" - var/sql = "SELECT id FROM ss13_ban WHERE ckey = '[ckey]' AND [bantype_sql] AND (unbanned is null OR unbanned = false)" + var/sql = "SELECT id FROM ss13_ban WHERE isnull(unbanned) AND [bantype_sql] AND ckey = '[ckey]'" if(job) sql += " AND job = '[job]'" @@ -437,7 +437,7 @@ if (!match) var/DBQuery/mirror_query = dbcon.NewQuery({"SELECT DISTINCT(mirrors.ban_id), bans.ckey FROM ss13_ban_mirrors mirrors JOIN ss13_ban bans ON mirrors.ban_id = bans.id - WHERE (1 [mirror_player] [mirror_ip] [mirror_cid]) + WHERE (isnull(mirrors.deleted_at) AND (1 [mirror_player] [mirror_ip] [mirror_cid])) AND ( ISNULL(bans.unbanned) AND ( (bans.bantype = 'PERMABAN') diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm index 5e4ad4371d1..15a7b1a6451 100644 --- a/code/modules/admin/IsBanned.dm +++ b/code/modules/admin/IsBanned.dm @@ -44,10 +44,10 @@ world/IsBanned(key,address,computer_id) var/params[] = list() var/query_content = "" if (pulled_ban_id) - query_content = "SELECT id, ckey, ip, computerid, a_ckey, reason, expiration_time, duration, bantime, bantype FROM ss13_ban WHERE id = :ban_id: AND (bantype = 'PERMABAN' OR (bantype = 'TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)" + query_content = "SELECT id, ckey, ip, computerid, a_ckey, reason, expiration_time, duration, bantime, bantype FROM ss13_ban WHERE id = :ban_id: AND isnull(unbanned) AND (bantype = 'PERMABAN' OR (bantype = 'TEMPBAN' AND expiration_time > Now()))" params["ban_id"] = pulled_ban_id else - query_content = "SELECT id, ckey, ip, computerid, a_ckey, reason, expiration_time, duration, bantime, bantype FROM ss13_ban WHERE (ckey = :ckey: OR computerid = :computerid: OR ip = :address:) AND (bantype = 'PERMABAN' OR (bantype = 'TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)" + query_content = "SELECT id, ckey, ip, computerid, a_ckey, reason, expiration_time, duration, bantime, bantype FROM ss13_ban WHERE isnull(unbanned) AND (bantype = 'PERMABAN' OR (bantype = 'TEMPBAN' AND expiration_time > Now())) AND (ckey = :ckey: OR computerid = :computerid: OR ip = :address:)" params["ckey"] = ckey params["computerid"] = computer_id params["address"] = address diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index bbe9fd8d1eb..1f0f2a70094 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -97,8 +97,13 @@ display_mirrors_panel(usr, text2num(href_list["dbbanmirrors"])) return - else if(href_list["dbbanmirrorckeys"]) - display_mirrors_ckeys(usr, text2num(href_list["dbbanmirrorckeys"])) + else if(href_list["dbbanmirroract"]) + // Mirror act contains the ID of the mirror being acted upon. + var/mirror_id = text2num(href_list["dbbanmirroract"]) + if (href_list["mirrorckeys"]) + display_mirrors_ckeys(usr, mirror_id) + else if (href_list["mirrorstatus"]) + toggle_mirror_status(usr, mirror_id, text2num(href_list["mirrorstatus"])) return else if(href_list["editrights"])