From fc6221eeee64dab9ee7e4c5b2c4c6b786e246887 Mon Sep 17 00:00:00 2001 From: skull132 Date: Sat, 6 Feb 2016 18:17:55 +0200 Subject: [PATCH] Mirroring Bans No more "New ban for every attempted dodge." Mirrored bans are linked to an associative table, and then checked against the referenced original ban. Cuts down on the amount of clutter that exists. --- baystation12.dme | 1 + code/modules/admin/DB ban/ban_mirroring.dm | 65 ++++++++++++++++++++++ code/modules/admin/DB ban/functions.dm | 13 +++++ code/modules/admin/IsBanned.dm | 38 +++++++++---- 4 files changed, 106 insertions(+), 11 deletions(-) create mode 100644 code/modules/admin/DB ban/ban_mirroring.dm diff --git a/baystation12.dme b/baystation12.dme index 3143cb39c7c..cebbe82d3a8 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -823,6 +823,7 @@ #include "code\modules\admin\player_panel.dm" #include "code\modules\admin\topic.dm" #include "code\modules\admin\ToRban.dm" +#include "code\modules\admin\DB ban\ban_mirroring.dm" #include "code\modules\admin\DB ban\functions.dm" #include "code\modules\admin\permissionverbs\permissionedit.dm" #include "code\modules\admin\verbs\adminhelp.dm" diff --git a/code/modules/admin/DB ban/ban_mirroring.dm b/code/modules/admin/DB ban/ban_mirroring.dm new file mode 100644 index 00000000000..a2be1c78074 --- /dev/null +++ b/code/modules/admin/DB ban/ban_mirroring.dm @@ -0,0 +1,65 @@ +#define BAD_CKEY 1 +#define BAD_IP 2 +#define BAD_CID 4 + +/proc/handle_ban_mirroring(var/ckey, var/address, var/computer_id, var/ban_id) + if (!ckey || !address || !computer_id || !ban_id) + return + + establish_db_connection() + + if (!dbcon.IsConnected()) + error("Ban database connection failure while attempting to mirror. Key passed for mirror handling: [ckey].") + log_misc("Ban database connection failure while attempting to mirror. Key passed for mirror handling: [ckey].") + return + + ckey = ckey(ckey) + + var/bad_data = BAD_CKEY|BAD_IP|BAD_CID + + var/DBQuery/original_ban = dbcon.NewQuery("SELECT ckey, ip, computerid FROM ss13_ban WHERE id = :ban_id") + original_ban.Execute(list(":ban_id" = ban_id)) + + if (original_ban.NextRow()) + var/original_ckey = original_ban.item[1] + var/original_address = original_ban.item[2] + var/original_computerid = original_ban.item[3] + if (original_ckey == ckey) + bad_data &= ~BAD_CKEY + if (original_address == address) + bad_data &= ~BAD_IP + if (original_computerid == computer_id) + bad_data &= ~BAD_CID + + if (bad_data) + var/DBQuery/mirrored_bans = dbcon.NewQuery("SELECT player_ckey, ban_mirror_ip, ban_mirror_computerid FROM ss13_ban_mirrors WHERE ban_id = :ban_id") + mirrored_bans.Execute(list(":ban_id" = ban_id)) + + while (mirrored_bans.NextRow()) + var/mirrored_ckey = mirrored_bans.item[1] + var/mirrored_address = mirrored_bans.item[2] + var/mirrored_computerid = mirrored_bans.item[3] + + if ((bad_data & BAD_CKEY) && mirrored_ckey == ckey) + bad_data &= ~BAD_CKEY + if ((bad_data & BAD_IP) && mirrored_address == address) + bad_data &= ~BAD_IP + if ((bad_data & BAD_CID) && mirrored_computerid == computer_id) + bad_data &= ~BAD_CID + + if (bad_data) + var/DBQuery/new_mirror = dbcon.NewQuery("INSERT INTO ss13_ban_mirrors (ban_id, player_ckey, ban_mirror_ip, ban_mirror_computerid, ban_mirror_datetime) VALUES (:ban_id, :ckey, :address, :computerid, NOW())") + new_mirror.Execute(":ban_id" = ban_id, ":ckey" = ckey, ":address" = address, ":computerid" = computer_id) + + log_misc("Mirrored ban #[ban_id] for player [ckey] from [address]-[computer_id].") + + return + + else + error("No ban retreived while attempting to handle ban mirroring. Passed ban_id: [ban_id], ckey: [ckey].") + log_misc("No ban retreived while attempting to handle ban mirroring. Passed ban_id: [ban_id], ckey: [ckey].") + return + +#undef BAD_CID +#undef BAD_IP +#undef BAD_CKEY diff --git a/code/modules/admin/DB ban/functions.dm b/code/modules/admin/DB ban/functions.dm index ebaff981c59..e36fc4ff21f 100644 --- a/code/modules/admin/DB ban/functions.dm +++ b/code/modules/admin/DB ban/functions.dm @@ -473,6 +473,19 @@ datum/admins/proc/DB_ban_unban_by_id(var/id) output += "" output += "EXPIRED at [expiration]" output += "" + if (bantype in list("PERMABAN", "TEMPBAN")) + var/mirror_count = 0 + var/DBQuery/get_mirrors = dbcon.NewQuery("SELECT ban_mirror_id FROM ss13_ban_mirrors WHERE ban_id = :ban_id") + get_mirrors.Execute(list(":ban_id" = text2num(banid))) + + while (get_mirrors.NextRow()) + mirror_count++ + + if (mirror_count) + output += "" + output += "Ban Mirrored [mirror_count] times!" + output += "" + output += "" output += " " output += "" diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm index 65bab9687c2..da4f2af534b 100644 --- a/code/modules/admin/IsBanned.dm +++ b/code/modules/admin/IsBanned.dm @@ -52,20 +52,37 @@ world/IsBanned(key,address,computer_id) failedcid = 0 cidquery = " OR computerid = '[computer_id]' " - var/DBQuery/query = dbcon.NewQuery("SELECT ckey, ip, computerid, a_ckey, reason, expiration_time, duration, bantime, bantype FROM ss13_ban WHERE (ckey = '[ckeytext]' [ipquery] [cidquery]) AND (bantype = 'PERMABAN' OR (bantype = 'TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)") + var/pulled_ban_id = null + var/DBQuery/mirror_query = dbcon.NewQuery("SELECT ban_id FROM ss13_ban_mirrors WHERE player_ckey = '[ckeytext]' [address ? "OR ban_mirror_ip = '[address]'" : ""] [computer_id ? "OR ban_mirror_computerid = '[computer_id]'" : ""]") + mirror_query.Execute() + + if (mirror_query.NextRow()) + pulled_ban_id = text2num(mirror_query.item[1]) + + 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 = '[pulled_ban_id]' AND (bantype = 'PERMABAN' OR (bantype = 'TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)" + else + query_content = "SELECT id, ckey, ip, computerid, a_ckey, reason, expiration_time, duration, bantime, bantype FROM ss13_ban WHERE (ckey = '[ckeytext]' [ipquery] [cidquery]) AND (bantype = 'PERMABAN' OR (bantype = 'TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)" + + var/DBQuery/query = dbcon.NewQuery(query_content) query.Execute() while(query.NextRow()) - var/pckey = query.item[1] - //var/pip = query.item[2] - //var/pcid = query.item[3] - var/ackey = query.item[4] - var/reason = query.item[5] - var/expiration = query.item[6] - var/duration = query.item[7] - var/bantime = query.item[8] - var/bantype = query.item[9] + var/ban_id = text2num(query.item[1]) + var/pckey = query.item[2] + var/pip = query.item[3] + var/pcid = query.item[4] + var/ackey = query.item[5] + var/reason = query.item[6] + var/expiration = query.item[7] + var/duration = query.item[8] + var/bantime = query.item[9] + var/bantype = query.item[10] + + if (pckey != ckeytext || (address && pip != address) || (computer_id && pcid != computer_id)) + handle_ban_mirroring(key, address, computer_id, ban_id) var/expires = "" if(text2num(duration) > 0) @@ -82,4 +99,3 @@ world/IsBanned(key,address,computer_id) return ..() //default pager ban stuff #endif #undef OVERRIDE_BAN_SYSTEM -