diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm
index 7c54ef79a06..e58f5619837 100644
--- a/code/controllers/configuration.dm
+++ b/code/controllers/configuration.dm
@@ -265,6 +265,9 @@
/// (This does not mean all ahelps are pinged, only ahelps sent when staff are offline get the ping, regardless of this setting)
var/discord_forward_all_ahelps = FALSE
+ /// URL for the CentCom Ban DB API
+ var/centcom_ban_db_url = null
+
/datum/configuration/New()
for(var/T in subtypesof(/datum/game_mode))
var/datum/game_mode/M = T
@@ -754,6 +757,8 @@
if("discord_forward_all_ahelps")
discord_forward_all_ahelps = TRUE
// End discord stuff
+ if("centcom_ban_db_url")
+ centcom_ban_db_url = value
else
log_config("Unknown setting in configuration: '[name]'")
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index ab9e215fbba..2d338825f22 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -91,7 +91,10 @@ GLOBAL_VAR_INIT(nologevent, 0)
else
body += "\[[M.client.holder ? M.client.holder.rank : "Player"]\] "
body += "\[" + M.client.get_exp_type(EXP_TYPE_CREW) + " as [EXP_TYPE_CREW]\]"
- body += "
BYOND account registration date: [M.client.byondacc_date || "ERROR"] [M.client.byondacc_age <= config.byond_account_age_threshold ? "" : ""]([M.client.byondacc_age] days old)[M.client.byondacc_age <= config.byond_account_age_threshold ? "" : ""]
"
+ body += "
BYOND account registration date: [M.client.byondacc_date || "ERROR"] [M.client.byondacc_age <= config.byond_account_age_threshold ? "" : ""]([M.client.byondacc_age] days old)[M.client.byondacc_age <= config.byond_account_age_threshold ? "" : ""]"
+ body += "
Global Ban DB Lookup: [config.centcom_ban_db_url ? "Lookup" : "Disabled"]"
+
+ body += "
"
if(isnewplayer(M))
body += " Hasn't Entered Game "
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index 5f05df4b6f5..02154b4bdb4 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -69,7 +69,8 @@ GLOBAL_LIST_INIT(admin_verbs_admin, list(
/client/proc/reset_all_tcs, /*resets all telecomms scripts*/
/client/proc/toggle_mentor_chat,
/client/proc/toggle_advanced_interaction, /*toggle admin ability to interact with not only machines, but also atoms such as buttons and doors*/
- /client/proc/list_ssds_afks
+ /client/proc/list_ssds_afks,
+ /client/proc/ccbdb_lookup_ckey
))
GLOBAL_LIST_INIT(admin_verbs_ban, list(
/client/proc/ban_panel,
diff --git a/code/modules/admin/centcom_ban_db.dm b/code/modules/admin/centcom_ban_db.dm
new file mode 100644
index 00000000000..6416a1a935b
--- /dev/null
+++ b/code/modules/admin/centcom_ban_db.dm
@@ -0,0 +1,117 @@
+// CCBDB = CentCom Ban DB
+// This file contains procs for handling all requests to the CCBDB API, hosted by Bobbahbrown
+// API Documentation: https://centcom.melonmesa.com/swagger/index.html
+// Please refer to said documentation before editing any of the stuff in here, otherwise it will likely break
+
+
+/**
+ * CCBDB Lookup Initiator
+ *
+ * Checks the configuration before invoking the request to the CCBDB server.
+ *
+ * Arguments:
+ * * ckey - ckey to be looked up
+ */
+/datum/admins/proc/create_ccbdb_lookup(ckey)
+ // Bail if disabled
+ if(!config.centcom_ban_db_url)
+ to_chat(usr, "The CentCom Ban DB lookup is disabled. Please inform a maintainer or server host.")
+ return
+ // Bail if no ckey is supplied
+ if(!ckey)
+ return
+
+ var/datum/callback/cb = CALLBACK(src, /datum/admins/.proc/ccbdb_lookup_callback, usr, ckey)
+ SShttp.create_async_request(RUSTG_HTTP_METHOD_GET, "[config.centcom_ban_db_url][ckey]", proc_callback=cb)
+
+/**
+ * CCBDB Lookup Callback
+ *
+ * Callback assigned in [/datum/admins/proc/create_ccbdb_lookup] for async operations without a sleep()
+ *
+ * Arguments:
+ * * user - Mob calling the lookup so the UI can be opened
+ * * ckey - Ckey being looked up
+ * * response - [/datum/http_response] passed through from [SShttp]
+ */
+/datum/admins/proc/ccbdb_lookup_callback(mob/user, ckey, datum/http_response/response)
+ // If the admin DC'd during the lookup, dont try and do things
+ if(!user)
+ return
+
+ // Bail if it errored
+ if(response.errored)
+ to_chat(user, "Error connecting to CentCom Ban DB. Please inform a maintainer or server host.")
+ return
+
+ // Bail if the code isnt 200
+ if(response.status_code != 200)
+ to_chat(user, "Error performing CentCom Ban DB lookup (Code: [response.status_code])")
+ return
+
+ var/list/popup_data = list()
+
+ // A body of "[]" means there were no bans on record for the user
+ if(response.body == "\[]")
+ popup_data += "
0 bans detected for [ckey]
"
+ else
+ var/list/bans = list()
+ // Wrap this in try/catch because JSON is a finnicky bastard
+ try
+ bans = json_decode(response.body)
+ // Yes I threw a ternary in because I am that obsessed over OCD
+ popup_data += "[length(bans)] ban[length(bans) == 1 ? "" : "s"] detected for [ckey]
"
+ // These vars are also just for OCD (Adding a
between each ban but the last)
+ var/total_bans = length(bans)
+ var/index = 0
+ for(var/list/ban in bans)
+ index++
+ // For anyone else who edits this. SANITIZE ALL THE DATA. OTHER SERVERS MAY HAVE BAD ACTORS WHO TRY AND XSS PEOPLE.
+ popup_data += "Server: [sanitize(ban["sourceName"])] ([sanitize(ban["sourceRoleplayLevel"])] RP)
"
+
+ var/ban_status
+ // If the ban is active, its, well, active
+ if(ban["active"] == TRUE) // The == TRUE is intentional here. Dont remove it.
+ ban_status = "Ban Active"
+ // If they have an entry of being unbanned by someone, its been appealed
+ else if(ban["unbannedBy"])
+ ban_status = "Ban Appealed"
+ else
+ ban_status = "Ban Expired"
+ popup_data += "Status: [ban_status]
"
+
+ // All the other stats
+ popup_data += "Ban Type: [sanitize(ban["type"])]
"
+ popup_data += "Banning Admin: [sanitize(ban["bannedBy"])]
"
+ popup_data += "Ban Date: [sanitize(ban["bannedOn"])]
"
+ var/expiration = ban["expires"]
+ popup_data += "Expires: [expiration ? "[sanitize(expiration)]" : "Permanent"]
"
+ popup_data += "Ban Reason: [sanitize(ban["reason"])]
"
+
+ // If its a job ban, tell the admin the job list
+ if(ban["type"] == "Job")
+ var/list/jobs = ban["jobs"]
+ popup_data += "Jobs: [sanitize(english_list(jobs))]
"
+
+ // Add a newline between bans if its not the last one
+ if(index != total_bans)
+ popup_data += "
"
+
+ catch
+ to_chat(user, "Error parsing JSON data from CentCom Ban DB lookup. Please inform a maintainer.")
+ return
+
+ var/datum/browser/popup = new(user, "ccbdblookup-[ckey]", "CC Ban DB Lookup - [ckey]
", 700, 600)
+ popup.set_content(popup_data.Join())
+ popup.open(FALSE)
+
+// Just a simple verb so admins can do manual lookups
+/client/proc/ccbdb_lookup_ckey()
+ set name = "Global Ban DB Lookup"
+ set category = "Admin"
+
+ if(!check_rights(R_ADMIN))
+ return
+
+ var/input_ckey = input(usr, "Please enter a ckey to lookup", "Global Ban DB Lookup")
+ holder.create_ccbdb_lookup(input_ckey)
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index ed961e83337..cae09b224d2 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -3349,21 +3349,6 @@
// Refresh the page
src.view_flagged_books()
- // Force unlink a discord key
- // TODO: Delete this
- else if(href_list["force_discord_unlink"])
- if(!check_rights(R_ADMIN))
- return
- var/target_ckey = href_list["force_discord_unlink"]
- var/DBQuery/admin_unlink_discord_id = GLOB.dbcon.NewQuery("DELETE FROM [format_table_name("discord")] WHERE ckey = '[target_ckey]'")
- if(!admin_unlink_discord_id.Execute())
- var/err = admin_unlink_discord_id.ErrorMsg()
- log_game("SQL ERROR while admin-unlinking discord account. Error : \[[err]\]\n")
- return
- to_chat(src, "Successfully forcefully unlinked discord account from [target_ckey]")
- message_admins("[key_name_admin(usr)] forcefully unlinked the discord account belonging to [target_ckey]")
- log_admin("[key_name_admin(usr)] forcefully unlinked the discord account belonging to [target_ckey]")
-
else if(href_list["create_outfit_finalize"])
if(!check_rights(R_EVENT))
return
@@ -3386,6 +3371,11 @@
return
var/datum/outfit/O = locate(href_list["chosen_outfit"]) in GLOB.custom_outfits
save_outfit(usr,O)
+ else if(href_list["open_ccbdb"])
+ if(!check_rights(R_ADMIN))
+ return
+ create_ccbdb_lookup(href_list["open_ccbdb"])
+
/client/proc/create_eventmob_for(var/mob/living/carbon/human/H, var/killthem = 0)
if(!check_rights(R_EVENT))
diff --git a/config/example/config.txt b/config/example/config.txt
index 54622806507..e36472ed2b6 100644
--- a/config/example/config.txt
+++ b/config/example/config.txt
@@ -465,3 +465,9 @@ BYOND_ACCOUNT_AGE_THRESHOLD 7
#DISCORD_FORWARD_ALL_AHELPS
##### END DISCORD STUFF #####
+
+## URL For CentCom global ban DB
+## This is a config option should you want to disable this system, or if the primary URL changes
+## THE TRAILING SLASH ON THE END IS IMPORTANT SINCE IT JUST APPENDS THE CKEY TO THE END IN RAW
+## Add a hash before the line below to disable the system
+CENTCOM_BAN_DB_URL https://centcom.melonmesa.com/ban/search/
diff --git a/paradise.dme b/paradise.dme
index 5034f1fc089..1f4ae631087 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -1198,6 +1198,7 @@
#include "code\modules\admin\admin_verbs.dm"
#include "code\modules\admin\banappearance.dm"
#include "code\modules\admin\banjob.dm"
+#include "code\modules\admin\centcom_ban_db.dm"
#include "code\modules\admin\create_mob.dm"
#include "code\modules\admin\create_object.dm"
#include "code\modules\admin\create_poll.dm"