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 -