diff --git a/code/modules/admin/DB ban/ban_mirroring.dm b/code/modules/admin/DB ban/ban_mirroring.dm
index d6af7bafbba..aff12952b39 100644
--- a/code/modules/admin/DB ban/ban_mirroring.dm
+++ b/code/modules/admin/DB ban/ban_mirroring.dm
@@ -13,8 +13,6 @@
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")
@@ -63,3 +61,68 @@
#undef BAD_CID
#undef BAD_IP
#undef BAD_CKEY
+
+/proc/get_active_mirror(var/ckey, var/address, var/computer_id)
+ if (!ckey || !address || !computer_id)
+ return null
+
+ establish_db_connection(dbcon)
+
+ if (!dbcon.IsConnected())
+ error("Ban database connection failure while attempting to check mirrors. Key passed for mirror checking: [ckey].")
+ 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 player_ckey = :ckey OR ban_mirror_ip = :address OR ban_mirror_computerid = :computerid")
+ initial_query.Execute(list(":ckey" = ckey, ":address" = address, ":computerid" = computer_id))
+
+ var/list/ban_ids = list()
+
+ while (initial_query.NextRow())
+ ban_ids += text2num(initial_query.item[1])
+
+ // No mirrors exist.
+ 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)")
+ search_query.Execute(":vars" = ban_ids)
+
+ var/list/active_bans = list()
+
+ while (search_query.NextRow())
+ active_bans += text2num(search_query.item[1])
+
+ if (!active_bans.len)
+ // None are active.
+ return null
+ else
+ // Return the latest entry, if multiple bans are active.
+ // Just in case.
+ return active_bans[active_bans.len]
+
+/proc/get_ban_mirrors(var/ban_id)
+ if (!ban_id)
+ return null
+
+ establish_db_connection(dbcon)
+
+ if (!dbcon.IsConnected())
+ return null
+
+ var/DBQuery/query = dbcon.NewQuery("SELECT ban_mirror_id, player_ckey, ban_mirror_ip, ban_mirror_computerid, date(ban_mirror_datetime) as datetime FROM ss13_ban_mirrors WHERE ban_id = :ban_id")
+ query.Execute(list(":ban_id" = ban_id))
+
+ testing("Ban ID: [ban_id]")
+
+ var/mirrors[] = list()
+ while (query.NextRow())
+ var/items[] = list()
+ items["ckey"] = query.item[2]
+ items["ip"] = query.item[3]
+ items["computerid"] = query.item[4]
+ items["date"] = query.item[5]
+
+ mirrors[query.item[1]] = items
+
+ return mirrors
diff --git a/code/modules/admin/DB ban/functions.dm b/code/modules/admin/DB ban/functions.dm
index a6f7141e05d..df0aa9a4818 100644
--- a/code/modules/admin/DB ban/functions.dm
+++ b/code/modules/admin/DB ban/functions.dm
@@ -488,7 +488,7 @@ datum/admins/proc/DB_ban_unban_by_id(var/id)
if (mirror_count)
output += "
"
- output += "| Ban Mirrored [mirror_count > 1 ? "[mirror_count] times" : "once"]! | "
+ output += "Ban Mirrored [mirror_count > 1 ? "[mirror_count] times" : "once"]! | "
output += "
"
output += ""
diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm
index 37eb7cc691b..29748bc6f5a 100644
--- a/code/modules/admin/IsBanned.dm
+++ b/code/modules/admin/IsBanned.dm
@@ -32,42 +32,38 @@ world/IsBanned(key,address,computer_id)
else
- var/ckeytext = ckey(key)
+ if (!address)
+ log_access("Failed Login: [key] null-[computer_id] - Denied access: No IP address broadcast.")
+ message_admins("[key] tried to connect without an IP address.")
+ return list("reason" = "Temporary ban", "desc" = "Your connection did not broadcast an IP address to check.")
+
+ if (!computer_id)
+ log_access("Failed Login: [key] [address]-null - Denied access: No computer ID broadcast.")
+ message_admins("[key] tried to connect without a computer ID.")
+ return list("reason" = "Temporary ban", "desc" = "Your connection did not broadcast an computer ID to check.")
+
+ var/ckey = ckey(key)
if(!establish_db_connection(dbcon))
- error("Ban database connection failure. Key [ckeytext] not checked")
- log_misc("Ban database connection failure. Key [ckeytext] not checked")
+ error("Ban database connection failure. Key [ckey] not checked")
+ log_misc("Ban database connection failure. Key [ckey] not checked")
return
- var/failedcid = 1
- var/failedip = 1
-
- var/ipquery = ""
- var/cidquery = ""
- if(address)
- failedip = 0
- ipquery = " OR ip = '[address]' "
-
- if(computer_id)
- failedcid = 0
- cidquery = " OR computerid = '[computer_id]' "
-
- 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/pulled_ban_id = get_active_mirror(ckey, 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 = '[pulled_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 (bantype = 'PERMABAN' OR (bantype = 'TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)"
+ 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 = '[ckeytext]' [ipquery] [cidquery]) 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 (ckey = :ckey OR computerid = :computerid OR ip = :address) AND (bantype = 'PERMABAN' OR (bantype = 'TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)"
+ params[":ckey"] = ckey
+ params[":computerid"] = computer_id
+ params[":address"] = address
var/DBQuery/query = dbcon.NewQuery(query_content)
-
- query.Execute()
+ query.Execute(params)
while(query.NextRow())
var/ban_id = text2num(query.item[1])
@@ -81,8 +77,8 @@ world/IsBanned(key,address,computer_id)
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)
+ if (pckey != ckey || (address && pip != address) || (computer_id && pcid != computer_id))
+ handle_ban_mirroring(ckey, address, computer_id, ban_id)
var/expires = ""
if(text2num(duration) > 0)
@@ -92,10 +88,6 @@ world/IsBanned(key,address,computer_id)
return list("reason"="[bantype]", "desc"="[desc]")
- if (failedcid)
- message_admins("[key] has logged in with a blank computer id in the ban check.")
- if (failedip)
- message_admins("[key] has logged in with a blank ip in the ban check.")
return ..() //default pager ban stuff
#endif
#undef OVERRIDE_BAN_SYSTEM
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index 59276e283db..cf5d002029f 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -93,6 +93,28 @@
DB_ban_record(bantype, playermob, banduration, banreason, banjob, null, banckey, banip, bancid )
+ else if(href_list["dbbanmirrors"])
+ var/ban_id = text2num(href_list["dbbanmirrors"])
+
+ var/list/mirrors = get_ban_mirrors(ban_id)
+
+ if (!mirrors)
+ usr << "Something went horribly wrong."
+ return
+
+ if (!mirrors.len)
+ usr << "No mirrors for this ban found."
+ return
+
+ var/output = "Ban mirrors for ban #[ban_id]
"
+ output += "Each line indicates a new bypass attempt.
"
+ for (var/mirror in mirrors)
+ var/list/details = mirrors[mirror]
+
+ output += "[details["date"]] - [details["ckey"]] - IP: [details["ip"]] - CID: [details["computerid"]]
"
+
+ usr << browse(output, "window=banmirrors")
+
else if(href_list["editrights"])
if(!check_rights(R_PERMISSIONS))
message_admins("[key_name_admin(usr)] attempted to edit the admin permissions without sufficient rights.")