From 942b97a08fff42ba21d60ae529d94c30d418be2f Mon Sep 17 00:00:00 2001 From: John Willard <53777086+JohnFulpWillard@users.noreply.github.com> Date: Sun, 6 Apr 2025 15:06:58 -0400 Subject: [PATCH] Interviews now lets you see centcom bans directly (#90423) ## About The Pull Request There's now a button in Interviews that lets you directly jump to a person's centcom ban database, which also works if the client disconnects. The button is red (idk if we have any flashing color to make it REALLY stand out) and has special tooltip if they have any server permabans in the database. ## Why It's Good For The Game There's an admin request to allow servers to ban bad players from the centcom database meant for streamer servers to avoid griefers, which I wasn't the biggest fan of. Instead I thought this would be a harmless addition, letting admins see if a player joining their server is a known griefer BEFORE letting them in, directly from the interview menu- while letting them know if they have a permaban without having to even click anything. Gives admins an easier time in finding griefers before they log on without automation that may cause false positives. ## Changelog :cl: admin: Interviews now has a button to open a player's Centcom ban list, which will be in red if they have existing server permabans. /:cl: --- code/modules/admin/centcom.dm | 100 ++++++++++++++++++++ code/modules/admin/topic.dm | 61 +----------- code/modules/interview/interview.dm | 16 +++- tgstation.dme | 1 + tgui/packages/tgui/interfaces/Interview.tsx | 26 ++++- 5 files changed, 139 insertions(+), 65 deletions(-) create mode 100644 code/modules/admin/centcom.dm diff --git a/code/modules/admin/centcom.dm b/code/modules/admin/centcom.dm new file mode 100644 index 00000000000..10d14f1c456 --- /dev/null +++ b/code/modules/admin/centcom.dm @@ -0,0 +1,100 @@ +///Gets the centcom bans of the given ckey. +/datum/admins/proc/open_centcom_bans(ckey) + if(!check_rights(R_ADMIN)) + return + + if(!CONFIG_GET(string/centcom_ban_db)) + to_chat(usr, span_warning("Centcom Galactic Ban DB is disabled!")) + return + + // Make the request + var/datum/http_request/request = new() + request.prepare(RUSTG_HTTP_METHOD_GET, "[CONFIG_GET(string/centcom_ban_db)]/[ckey]", "", "") + request.begin_async() + UNTIL(request.is_complete() || !usr) + if (!usr) + return + var/datum/http_response/response = request.into_response() + + var/list/bans + + var/list/dat = list("") + + if(response.errored) + dat += "
Failed to connect to CentCom." + else if(response.status_code != 200) + dat += "
Failed to connect to CentCom. Status code: [response.status_code]" + else + if(response.body == "[]") + dat += "
0 bans detected for [ckey]
" + else + bans = json_decode(response.body) + + //Ignore bans from non-whitelisted sources, if a whitelist exists + var/list/valid_sources + if(CONFIG_GET(string/centcom_source_whitelist)) + valid_sources = splittext(CONFIG_GET(string/centcom_source_whitelist), ",") + dat += "
Bans detected for [ckey]
" + else + //Ban count is potentially inaccurate if they're using a whitelist + dat += "
[bans.len] ban\s detected for [ckey]
" + + for(var/list/ban in bans) + if(valid_sources && !(ban["sourceName"] in valid_sources)) + continue + dat += "Server: [sanitize(ban["sourceName"])]
" + dat += "RP Level: [sanitize(ban["sourceRoleplayLevel"])]
" + dat += "Type: [sanitize(ban["type"])]
" + dat += "Banned By: [sanitize(ban["bannedBy"])]
" + dat += "Reason: [sanitize(ban["reason"])]
" + dat += "Datetime: [sanitize(ban["bannedOn"])]
" + var/expiration = ban["expires"] + dat += "Expires: [expiration ? "[sanitize(expiration)]" : "Permanent"]
" + if(ban["type"] == "job") + dat += "Jobs: " + var/list/jobs = ban["jobs"] + dat += sanitize(jobs.Join(", ")) + dat += "
" + dat += "
" + + dat += "
" + var/datum/browser/popup = new(usr, "centcomlookup-[ckey]", "
Central Command Galactic Ban Database
", 700, 600) + popup.set_content(dat.Join()) + popup.open(0) + +///Returns the amount of permabans they have on centcom. +/datum/admins/proc/check_centcom_permabans(ckey) + if(!check_rights(R_ADMIN)) + return + + if(!CONFIG_GET(string/centcom_ban_db)) + to_chat(usr, span_warning("Centcom Galactic Ban DB is disabled!")) + return + + // Make the request + var/datum/http_request/request = new() + request.prepare(RUSTG_HTTP_METHOD_GET, "[CONFIG_GET(string/centcom_ban_db)]/[ckey]", "", "") + request.begin_async() + UNTIL(request.is_complete() || !usr) + if (!usr) + return + var/datum/http_response/response = request.into_response() + + var/list/bans + var/total_permabans + + if(response.body == "[]") + return + bans = json_decode(response.body) + //Ignore bans from non-whitelisted sources, if a whitelist exists + var/list/valid_sources + if(CONFIG_GET(string/centcom_source_whitelist)) + valid_sources = splittext(CONFIG_GET(string/centcom_source_whitelist), ",") + + for(var/list/ban in bans) + if(valid_sources && !(ban["sourceName"] in valid_sources)) + continue + if(!ban["expires"] && (sanitize(ban["type"]) == "Server")) //server permabans only + total_permabans++ + + return total_permabans diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 776382d4043..e394994d2aa 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1442,66 +1442,7 @@ if(!check_rights(R_ADMIN)) return - if(!CONFIG_GET(string/centcom_ban_db)) - to_chat(usr, span_warning("Centcom Galactic Ban DB is disabled!")) - return - - var/ckey = href_list["centcomlookup"] - - // Make the request - var/datum/http_request/request = new() - request.prepare(RUSTG_HTTP_METHOD_GET, "[CONFIG_GET(string/centcom_ban_db)]/[ckey]", "", "") - request.begin_async() - UNTIL(request.is_complete() || !usr) - if (!usr) - return - var/datum/http_response/response = request.into_response() - - var/list/bans - - var/list/dat = list("") - - if(response.errored) - dat += "
Failed to connect to CentCom." - else if(response.status_code != 200) - dat += "
Failed to connect to CentCom. Status code: [response.status_code]" - else - if(response.body == "[]") - dat += "
0 bans detected for [ckey]
" - else - bans = json_decode(response.body) - - //Ignore bans from non-whitelisted sources, if a whitelist exists - var/list/valid_sources - if(CONFIG_GET(string/centcom_source_whitelist)) - valid_sources = splittext(CONFIG_GET(string/centcom_source_whitelist), ",") - dat += "
Bans detected for [ckey]
" - else - //Ban count is potentially inaccurate if they're using a whitelist - dat += "
[bans.len] ban\s detected for [ckey]
" - - for(var/list/ban in bans) - if(valid_sources && !(ban["sourceName"] in valid_sources)) - continue - dat += "Server: [sanitize(ban["sourceName"])]
" - dat += "RP Level: [sanitize(ban["sourceRoleplayLevel"])]
" - dat += "Type: [sanitize(ban["type"])]
" - dat += "Banned By: [sanitize(ban["bannedBy"])]
" - dat += "Reason: [sanitize(ban["reason"])]
" - dat += "Datetime: [sanitize(ban["bannedOn"])]
" - var/expiration = ban["expires"] - dat += "Expires: [expiration ? "[sanitize(expiration)]" : "Permanent"]
" - if(ban["type"] == "job") - dat += "Jobs: " - var/list/jobs = ban["jobs"] - dat += sanitize(jobs.Join(", ")) - dat += "
" - dat += "
" - - dat += "
" - var/datum/browser/popup = new(usr, "centcomlookup-[ckey]", "
Central Command Galactic Ban Database
", 700, 600) - popup.set_content(dat.Join()) - popup.open(0) + open_centcom_bans(href_list["centcomlookup"]) else if(href_list["slowquery"]) if(!check_rights(R_ADMIN)) diff --git a/code/modules/interview/interview.dm b/code/modules/interview/interview.dm index 78490402e63..d2620274257 100644 --- a/code/modules/interview/interview.dm +++ b/code/modules/interview/interview.dm @@ -138,6 +138,9 @@ if ("adminpm") if (usr.client?.holder && owner) usr.client.cmd_admin_pm(owner, null) + if("check_centcom") + if(usr.client?.holder && owner) + usr.client?.holder.open_centcom_bans(owner_ckey) /datum/interview/ui_data(mob/user) . = list( @@ -147,7 +150,18 @@ "queue_pos" = pos_in_queue, "is_admin" = !!(user?.client && user.client.holder), "status" = status, - "connected" = !!owner) + "connected" = !!owner, + ) + if(CONFIG_GET(string/centcom_ban_db)) + . += list( + "centcom_connected" = TRUE, + "has_permabans" = user.client.holder.check_centcom_permabans(owner_ckey), + ) + else + . += list( + "centcom_connected" = FALSE, + "has_permabans" = FALSE, + ) for (var/i in 1 to questions.len) var/list/data = list( "qidx" = i, diff --git a/tgstation.dme b/tgstation.dme index da3b04cd14d..0f897881412 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -3094,6 +3094,7 @@ #include "code\modules\admin\admin_ranks.dm" #include "code\modules\admin\admin_verbs.dm" #include "code\modules\admin\antag_panel.dm" +#include "code\modules\admin\centcom.dm" #include "code\modules\admin\chat_commands.dm" #include "code\modules\admin\check_antagonists.dm" #include "code\modules\admin\create_mob.dm" diff --git a/tgui/packages/tgui/interfaces/Interview.tsx b/tgui/packages/tgui/interfaces/Interview.tsx index a02e578e007..211f11d36b8 100644 --- a/tgui/packages/tgui/interfaces/Interview.tsx +++ b/tgui/packages/tgui/interfaces/Interview.tsx @@ -7,18 +7,21 @@ import { Section, TextArea, } from 'tgui-core/components'; +import { BooleanLike } from 'tgui-core/react'; import { useBackend } from '../backend'; import { Window } from '../layouts'; type Data = { - connected: boolean; - is_admin: boolean; + connected: BooleanLike; + is_admin: BooleanLike; questions: Question[]; queue_pos: number; - read_only: boolean; + read_only: BooleanLike; status: string; welcome_message: string; + centcom_connected: BooleanLike; + has_permabans: BooleanLike; }; type Question = { @@ -63,6 +66,8 @@ export const Interview = (props) => { read_only, status, welcome_message = '', + centcom_connected, + has_permabans, } = data; const allAnswered = questions.every((q) => q.response); @@ -70,7 +75,7 @@ export const Interview = (props) => { return ( @@ -107,6 +112,19 @@ export const Interview = (props) => { + {!!centcom_connected && ( + + )} )}