From ff1972c1d3149cdfa40d3b94254098df8413cf50 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 9dbac57315d..57293c0f23d 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1388,66 +1388,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 b25780c4564..374d490ec03 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -2954,6 +2954,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 && ( + + )} )}