From 92425819ee9c3c657041705907b99ae739747d72 Mon Sep 17 00:00:00 2001 From: LetterN <24603524+LetterN@users.noreply.github.com> Date: Mon, 11 Nov 2024 11:56:57 +0800 Subject: [PATCH 1/9] boink --- citadel.dme | 4 +- code/__DEFINES/admin/admin.dm | 35 +- code/__HELPERS/admin.dm | 9 + code/__HELPERS/chat.dm | 38 +- code/__HELPERS/game.dm | 11 +- code/__HELPERS/text.dm | 6 + code/__HELPERS/unsorted.dm | 2 +- .../configuration/entries/general.dm | 13 + code/controllers/subsystem/ticker.dm | 114 +-- code/datums/http.dm | 82 ++ code/game/antagonist/antagonist_panel.dm | 2 +- code/game/gamemodes/game_mode.dm | 2 +- code/modules/admin/admin.dm | 397 ++++---- code/modules/admin/admin_verbs.dm | 53 +- code/modules/admin/chat_commands.dm | 181 ++-- code/modules/admin/holder2.dm | 100 +- code/modules/admin/player_panel.dm | 179 ++-- code/modules/admin/topic.dm | 46 +- code/modules/admin/verbs/adminhelp.dm | 606 ++++++++---- code/modules/admin/verbs/adminhelp_vr.dm | 16 - code/modules/admin/verbs/adminjump.dm | 202 ++-- code/modules/admin/verbs/adminpm.dm | 896 +++++++++++++----- code/modules/admin/verbs/adminsay.dm | 42 +- code/modules/admin/verbs/panicbunker.dm | 4 +- code/modules/admin/verbs/randomverbs.dm | 67 +- code/modules/client/client_procs.dm | 59 +- code/modules/client/spam_prevention.dm | 2 +- code/modules/discord/discord_embed.dm | 80 ++ code/modules/mob/logout.dm | 7 +- code/modules/mob/mob_helpers.dm | 3 - config/entries/general.txt | 20 + sound/misc/asay_ping.ogg | Bin 0 -> 6964 bytes 32 files changed, 2137 insertions(+), 1141 deletions(-) create mode 100644 code/__HELPERS/admin.dm create mode 100644 code/datums/http.dm delete mode 100644 code/modules/admin/verbs/adminhelp_vr.dm create mode 100644 code/modules/discord/discord_embed.dm create mode 100644 sound/misc/asay_ping.ogg diff --git a/citadel.dme b/citadel.dme index 6bf3846e787a..b5e820c6b990 100644 --- a/citadel.dme +++ b/citadel.dme @@ -361,6 +361,7 @@ #include "code\__HELPERS\_global_objects.dm" #include "code\__HELPERS\_lists_tg.dm" #include "code\__HELPERS\_logging.dm" +#include "code\__HELPERS\admin.dm" #include "code\__HELPERS\animations.dm" #include "code\__HELPERS\areas.dm" #include "code\__HELPERS\atom_movables.dm" @@ -693,6 +694,7 @@ #include "code\datums\EPv2.dm" #include "code\datums\ghost_query.dm" #include "code\datums\hierarchy.dm" +#include "code\datums\http.dm" #include "code\datums\is_abstract.dm" #include "code\datums\material_container.dm" #include "code\datums\mind.dm" @@ -2182,7 +2184,6 @@ #include "code\modules\admin\secrets\random_events\trigger_xenomorph_infestation.dm" #include "code\modules\admin\verbs\admin_set_headshot.dm" #include "code\modules\admin\verbs\adminhelp.dm" -#include "code\modules\admin\verbs\adminhelp_vr.dm" #include "code\modules\admin\verbs\adminjump.dm" #include "code\modules\admin\verbs\adminpm.dm" #include "code\modules\admin\verbs\adminsay.dm" @@ -2668,6 +2669,7 @@ #include "code\modules\detectivework\tools\storage.dm" #include "code\modules\detectivework\tools\swabs.dm" #include "code\modules\detectivework\tools\uvlight.dm" +#include "code\modules\discord\discord_embed.dm" #include "code\modules\donatorreskins\donatoraccessory.dm" #include "code\modules\donatorreskins\donatorarmor.dm" #include "code\modules\donatorreskins\donatorclothing.dm" diff --git a/code/__DEFINES/admin/admin.dm b/code/__DEFINES/admin/admin.dm index 96d7f09ed2de..3b9f57a97f04 100644 --- a/code/__DEFINES/admin/admin.dm +++ b/code/__DEFINES/admin/admin.dm @@ -84,19 +84,19 @@ #define ADMIN_FULLMONTY(user) ("[key_name_admin(user)] [ADMIN_FULLMONTY_NONAME(user)]") /atom/proc/Admin_Coordinates_Readable(area_name, admin_jump_ref) - var/turf/T = Safe_COORD_Location() - return T ? "[area_name ? "[get_area_name(T, TRUE)] " : " "]([T.x],[T.y],[T.z])[admin_jump_ref ? " [ADMIN_JMP(T)]" : ""]" : "nonexistent location" + var/turf/turf_at_coords = Safe_COORD_Location() + return turf_at_coords ? "[area_name ? "[get_area_name(turf_at_coords, TRUE)] " : " "]([turf_at_coords.x],[turf_at_coords.y],[turf_at_coords.z])[admin_jump_ref ? " [ADMIN_JMP(turf_at_coords)]" : ""]" : "nonexistent location" /atom/proc/Safe_COORD_Location() - var/atom/A = drop_location() - if(!A) - return // Not a valid atom. - var/turf/T = get_step(A, 0) // Resolve where the thing is. - if(!T) // Incase it's inside a valid drop container, inside another container. ie if a mech picked up a closet and has it inside it's internal storage. - var/atom/last_try = A.loc?.drop_location() // One last try, otherwise fuck it. + var/atom/drop_atom = drop_location() + if(!drop_atom) + return //not a valid atom. + var/turf/drop_turf = get_step(drop_atom, 0) //resolve where the thing is. + if(!drop_turf) //incase it's inside a valid drop container, inside another container. ie if a mech picked up a closet and has it inside its internal storage. + var/atom/last_try = drop_atom.loc?.drop_location() //one last try, otherwise fuck it. if(last_try) - T = get_step(last_try, 0) - return T + drop_turf = get_step(last_try, 0) + return drop_turf /turf/Safe_COORD_Location() return src @@ -104,11 +104,11 @@ /** *! AHELP Commands. */ -#define ADMIN_AHELP_REJECT(user) ("([SPAN_TOOLTIP("Reject and close this ticket.","REJT")])") -#define ADMIN_AHELP_IC(user) ("([SPAN_TOOLTIP("Close this ticket and mark it IC.","IC")])") -#define ADMIN_AHELP_CLOSE(user) ("([SPAN_TOOLTIP("Close this ticket.","CLOSE")])") -#define ADMIN_AHELP_RESOLVE(user) ("([SPAN_TOOLTIP("Close this ticket and mark it as Resolved.","RSLVE")])") -#define ADMIN_AHELP_HANDLE(user) ("([SPAN_TOOLTIP("Alert other Administrators that you're handling this ticket.","HANDLE")])") +#define ADMIN_AHELP_REJECT(user) ("([SPAN_TOOLTIP("Reject and close this ticket.","REJT")])") +#define ADMIN_AHELP_IC(user) ("([SPAN_TOOLTIP("Close this ticket and mark it IC.","IC")])") +#define ADMIN_AHELP_CLOSE(user) ("([SPAN_TOOLTIP("Close this ticket.","CLOSE")])") +#define ADMIN_AHELP_RESOLVE(user) ("([SPAN_TOOLTIP("Close this ticket and mark it as Resolved.","RSLVE")])") +#define ADMIN_AHELP_HANDLE(user) ("([SPAN_TOOLTIP("Alert other Administrators that you're handling this ticket.","HANDLE")])") #define ADMIN_AHELP_FULLMONTY(user) ("[ADMIN_AHELP_REJECT(user)] [ADMIN_AHELP_IC(user)] [ADMIN_AHELP_CLOSE(user)] [ADMIN_AHELP_RESOLVE(user)] [ADMIN_AHELP_HANDLE(user)]") #define AHELP_ACTIVE 1 @@ -118,3 +118,8 @@ // LOG BROWSE TYPES #define BROWSE_ROOT_ALL_LOGS 1 #define BROWSE_ROOT_CURRENT_LOGS 2 + +/// for [/proc/check_asay_links], if there are any actionable refs in the asay message, this index in the return list contains the new message text to be printed +#define ASAY_LINK_NEW_MESSAGE_INDEX "!asay_new_message" +/// for [/proc/check_asay_links], if there are any admin pings in the asay message, this index in the return list contains a list of admins to ping +#define ASAY_LINK_PINGED_ADMINS_INDEX "!pinged_admins" diff --git a/code/__HELPERS/admin.dm b/code/__HELPERS/admin.dm new file mode 100644 index 000000000000..88c2d1ecb0d6 --- /dev/null +++ b/code/__HELPERS/admin.dm @@ -0,0 +1,9 @@ + +/proc/is_admin(mob/user) + return check_rights(R_ADMIN, 0, user) != 0 + +/// Sends a message in the event that someone attempts to elevate their permissions through invoking a certain proc. +/proc/alert_to_permissions_elevation_attempt(mob/user) + var/message = " has tried to elevate permissions!" + message_admins(key_name_admin(user) + message) + log_admin(key_name(user) + message) diff --git a/code/__HELPERS/chat.dm b/code/__HELPERS/chat.dm index 94982ca90fbf..3927135c7e22 100644 --- a/code/__HELPERS/chat.dm +++ b/code/__HELPERS/chat.dm @@ -1,13 +1,17 @@ -/** +/* + * + * Here's how to use the TGS chat system with configs * - * Here's how to use the chat system with configs + * send2adminchat is a simple function that broadcasts to all admin channels that are designated in TGS * - *? send2adminchat is a simple function that broadcasts to admin channels + * send2chat is a bit verbose but can be very specific * - *? send2chat is a bit verbose but can be very specific + * In TGS3 it will always be sent to all connected designated game chats. + * + * In TGS4+ they use the new tagging system * * The second parameter is a string, this string should be read from a config. - * What this does is dictacte which TGS4 channels can be sent to. + * What this does is dictate which TGS channels can be sent to. * * For example if you have the following channels in tgs4 set up * - Channel 1, Tag: asdf @@ -18,7 +22,7 @@ * * and you make the call: * - * send2chat("I sniff butts", CONFIG_GET(string/where_to_send_sniff_butts)) + * send2chat(new /datum/tgs_message_content("I sniff butts"), CONFIG_GET(string/where_to_send_sniff_butts)) * * and the config option is set like: * @@ -31,47 +35,49 @@ * WHERE_TO_SEND_SNIFF_BUTTS * * it will be sent to all connected chats. - * - * In TGS3 it will always be sent to all connected designated game chats. -*/ + */ /** - * Sends a message to TGS chat channels. + * Asynchronously sends a message to TGS chat channels. * - * message - The message to send. + * message - The [/datum/tgs_message_content] to send. * channel_tag - Required. If "", the message with be sent to all connected (Game-type for TGS3) channels. Otherwise, it will be sent to TGS4 channels with that tag (Delimited by ','s). + * admin_only - Determines if this communication can only be sent to admin only channels. */ -/proc/send2chat(message, channel_tag) +/proc/send2chat(datum/tgs_message_content/message, channel_tag, admin_only = FALSE) + set waitfor = FALSE if(channel_tag == null || !world.TgsAvailable()) return var/datum/tgs_version/version = world.TgsVersion() if(channel_tag == "" || version.suite == 3) - world.TgsTargetedChatBroadcast(message, FALSE) + world.TgsTargetedChatBroadcast(message, admin_only) return var/list/channels_to_use = list() for(var/I in world.TgsChatChannelInfo()) var/datum/tgs_chat_channel/channel = I var/list/applicable_tags = splittext(channel.custom_tag, ",") - if(channel_tag in applicable_tags) + if((!admin_only || channel.is_admin_channel) && (channel_tag in applicable_tags)) channels_to_use += channel if(channels_to_use.len) world.TgsChatBroadcast(message, channels_to_use) /** - * Sends a message to TGS admin chat channels. + * Asynchronously sends a message to TGS admin chat channels. * * category - The category of the mssage. * message - The message to send. */ /proc/send2adminchat(category, message, embed_links = FALSE) + set waitfor = FALSE + category = replacetext(replacetext(category, "\proper", ""), "\improper", "") message = replacetext(replacetext(message, "\proper", ""), "\improper", "") if(!embed_links) message = GLOB.has_discord_embeddable_links.Replace(replacetext(message, "`", ""), " ```$1``` ") - world.TgsTargetedChatBroadcast("[category] | [message]", TRUE) + world.TgsTargetedChatBroadcast(new /datum/tgs_message_content("[category] | [message]"), TRUE) /// Handles text formatting for item use hints in examine text #define EXAMINE_HINT(text) ("" + text + "") diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 4e9ca9fe3625..9172f024a486 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -512,10 +512,15 @@ /proc/SecondsToTicks(seconds) return seconds * 10 -/proc/window_flash(client_or_usr) - if (!client_or_usr) +/// Flash the window of a player +/proc/window_flash(client/flashed_client) + if(ismob(flashed_client)) + var/mob/player_mob = flashed_client + if(player_mob.client) + flashed_client = player_mob.client + if(!flashed_client) return - winset(client_or_usr, "mainwindow", "flash=5") + winset(flashed_client, "mainwindow", "flash=5") /** * Used for the multiz camera console stolen from virgo. diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index 7fcdc575e3a9..ecbe20b0512a 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -622,3 +622,9 @@ GLOBAL_LIST_INIT(binary, list("0","1")) /proc/sanitize_css_class_name(name) var/static/regex/regex = new(@"[^a-zA-Z0-9]","g") return replacetext(name, regex, "") + +// return input text if it is a text, else returns default +/proc/sanitize_text(text, default="") + if(istext(text)) + return text + return default diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 33a67bc10f00..6dc612128f3e 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1426,7 +1426,7 @@ var/list/WALLITEMS = list( /proc/admin_chat_message(message = "Debug Message", color = "#FFFFFF", sender) // Adds TGS3 integration to those fancy verbose round event messages. if(message) - send2irc("Event", message) + send2adminchat("Event", message) if (!config_legacy.chat_webhook_url || !message) return spawn(0) diff --git a/code/controllers/configuration/entries/general.dm b/code/controllers/configuration/entries/general.dm index d9882912bae2..23d2ebc70bde 100644 --- a/code/controllers/configuration/entries/general.dm +++ b/code/controllers/configuration/entries/general.dm @@ -4,6 +4,8 @@ /datum/config_entry/string/invoke_youtubedl protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN +/datum/config_entry/flag/show_irc_name + /datum/config_entry/number/client_warn_version default = null min_val = 500 @@ -41,3 +43,14 @@ /// Enable or disable the toast notification when the the instance finishes initializing. /datum/config_entry/flag/toast_notification_on_init + +/datum/config_entry/string/channel_announce_new_game + default = null + +/datum/config_entry/string/channel_announce_end_game + default = null + +/datum/config_entry/string/chat_new_game_notifications + default = null + +/datum/config_entry/flag/debug_admin_hrefs diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 85c11386e172..31a4194736d3 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -81,15 +81,23 @@ SUBSYSTEM_DEF(ticker) /datum/controller/subsystem/ticker/fire() switch(current_state) if(GAME_STATE_INIT) - // We fire after init finishes - on_mc_init_finish() + if(Master.initializations_finished_with_no_players_logged_in) + start_at = world.time + (CONFIG_GET(number/lobby_countdown) * 10) + for(var/client/C in GLOB.clients) + window_flash(C) //let them know lobby has opened up. + SEND_SOUND(world, sound('sound/misc/server-ready.ogg', volume = 100)) + send2chat(new /datum/tgs_message_content("New round starting on [LEGACY_MAP_DATUM.station_name]!"), CONFIG_GET(string/channel_announce_new_game)) + to_chat(world, SPAN_NOTICE("Welcome to [LEGACY_MAP_DATUM.station_name]!")) + to_chat(world, SPAN_NOTICE("Please set up your character and select ready. The round will start in [CONFIG_GET(number/lobby_countdown)] seconds.")) + current_state = GAME_STATE_PREGAME + + fire() if(GAME_STATE_PREGAME) process_pregame() if(GAME_STATE_SETTING_UP) setup() - setup_done = TRUE if(GAME_STATE_PLAYING) round_process() @@ -111,29 +119,19 @@ SUBSYSTEM_DEF(ticker) if(blackbox) blackbox.save_all_data_to_sql() - send2irc("Server", "A round of [mode.name] just ended.") + send2chat(new /datum/tgs_message_content("[GLOB.round_id ? "Round [GLOB.round_id]" : "The round has"] just ended."), CONFIG_GET(string/channel_announce_end_game)) + send2adminchat("Server", "Round just ended.") if(CONFIG_GET(string/chat_roundend_notice_tag)) - var/broadcastmessage = "The round has ended." + var/broadcastmessage = "[GLOB.round_id ? "Round [GLOB.round_id]" : "The round has"] just ended." if(CONFIG_GET(string/chat_reboot_role)) broadcastmessage += "\n\n<@&[CONFIG_GET(string/chat_reboot_role)]>, the server will reboot shortly!" - send2chat(broadcastmessage, CONFIG_GET(string/chat_roundend_notice_tag)) + send2chat(new /datum/tgs_message_content(broadcastmessage), CONFIG_GET(string/chat_roundend_notice_tag)) SSdbcore.SetRoundEnd() SSpersistence.SavePersistence() if(!SSpersistence.world_saved_count && CONFIG_GET(flag/persistence) && !SSpersistence.world_non_canon) SSpersistence.save_the_world() - -/datum/controller/subsystem/ticker/proc/on_mc_init_finish() - send2irc("Server lobby is loaded and open at byond://[config_legacy.serverurl ? config_legacy.serverurl : (config_legacy.server ? config_legacy.server : "[world.address]:[world.port]")]") - to_chat(world, "Welcome to the pregame lobby!") - to_chat(world, "Please set up your character and select ready. The round will start in [CONFIG_GET(number/lobby_countdown)] seconds.") - SEND_SOUND(world, sound('sound/misc/server-ready.ogg', volume = 100)) - current_state = GAME_STATE_PREGAME - if(Master.initializations_finished_with_no_players_logged_in) - start_at = world.time + (CONFIG_GET(number/lobby_countdown) * 10) - fire() - /datum/controller/subsystem/ticker/proc/process_pregame() var/citest = FALSE #ifdef CITESTING @@ -232,9 +230,11 @@ SUBSYSTEM_DEF(ticker) timeLeft = newtime /datum/controller/subsystem/ticker/proc/setup() - to_chat(world, "Starting game...") + to_chat(world, SPAN_BOLDANNOUNCE("Starting game...")) var/init_start = world.timeofday + CHECK_TICK + //Create and announce mode if(master_mode=="secret") src.hide_mode = 1 @@ -262,11 +262,15 @@ SUBSYSTEM_DEF(ticker) to_chat(world, "Serious error in mode setup! Reverting to pregame lobby.") //Uses setup instead of set up due to computational context. return 0 + CHECK_TICK + SSjob.reset_occupations() src.mode.create_antagonists() src.mode.pre_setup() SSjob.DivideOccupations() // Apparently important for new antagonist system to register specific job antags properly. + CHECK_TICK + if(!src.mode.can_start()) to_chat(world, "Unable to start [mode.name]. Not enough players readied, [config_legacy.player_requirements[mode.config_tag]] players needed. Reverting to pregame lobby.") current_state = GAME_STATE_PREGAME @@ -289,7 +293,6 @@ SUBSYSTEM_DEF(ticker) src.mode.announce() setup_economy() - current_state = GAME_STATE_PLAYING create_characters() //Create player characters and transfer them. collect_minds() equip_characters() @@ -301,54 +304,55 @@ SUBSYSTEM_DEF(ticker) cb.InvokeAsync() LAZYCLEARLIST(round_start_events) - for(var/obj/landmark/L in GLOB.landmarks_list) - // type filtered, we cannot risk runtimes - L.OnRoundstart() + for(var/i in GLOB.landmarks_list) + var/obj/landmark/L = i + if(istype(L)) //we can not runtime here. not in this important of a proc. + L.OnRoundstart() + else + stack_trace("[L] [L.type] found in landmarks list, which isn't a landmark!") - log_world("Game start took [(world.timeofday - init_start)/10]s") round_start_time = world.time + + log_world("Game start took [(world.timeofday - init_start)/10]s") INVOKE_ASYNC(SSdbcore, TYPE_PROC_REF(/datum/controller/subsystem/dbcore, SetRoundStart)) - // TODO Dear God Fix This. Fix all of this. Not just this line, this entire proc. This entire file! - spawn(0)//Forking here so we dont have to wait for this to finish - mode.post_setup() - //Cleanup some stuff - to_chat(world, "Enjoy the game!") - var/startupsound = rand(1,4) - switch(startupsound) - if(1) - SEND_SOUND(world, sound('sound/roundStart/start_up_1.ogg')) - if(2) - SEND_SOUND(world, sound('sound/roundStart/start_up_2.ogg')) - if(3) - SEND_SOUND(world, sound('sound/roundStart/start_up_3.ogg')) - if(4) - SEND_SOUND(world, sound('sound/roundStart/start_up_4.ogg'))//the original sound - //Holiday Round-start stuff ~Carn - Holiday_Game_Start() - - //start_events() //handles random events and space dust. - //new random event system is handled from the MC. - - var/admins_number = 0 - for(var/client/C) - if(C.holder) - admins_number++ - if(admins_number == 0) - send2irc("A round has started with no admins online.") - -/* SSsupply.process() //Start the supply shuttle regenerating points -- TLE // handled in scheduler - master_controller.process() //Start master_controller.process() - lighting_controller.process() //Start processing DynamicAreaLighting updates - */ + to_chat(world, SPAN_NOTICE(SPAN_BOLD("Welcome to [LEGACY_MAP_DATUM.station_name], enjoy your stay!"))) + // fine to leave this not spawn() + switch(rand(1,4)) + if(1) + SEND_SOUND(world, sound('sound/roundStart/start_up_[rand(1,4)].ogg')) + if(2) + SEND_SOUND(world, sound('sound/roundStart/start_up_2.ogg')) + if(3) + SEND_SOUND(world, sound('sound/roundStart/start_up_3.ogg')) + if(4) + SEND_SOUND(world, sound('sound/roundStart/start_up_4.ogg'))//the original sound + current_state = GAME_STATE_PLAYING Master.SetRunLevel(RUNLEVEL_GAME) + // this is horrible and should be moved to ssblackbox if(CONFIG_GET(flag/sql_enabled)) ASYNC // THIS REQUIRES THE ASYNC! statistic_cycle() // Polls population totals regularly and stores them in an SQL DB -- TLE + + Holiday_Game_Start() // before post setup + + PostSetup() + return TRUE +/datum/controller/subsystem/ticker/proc/PostSetup() + set waitfor = FALSE + + // old stuff + mode.post_setup() + + var/list/adm = get_admin_counts() + var/list/allmins = adm["present"] + send2adminchat("Server", "Round [GLOB.round_id ? "#[GLOB.round_id]" : ""] has started[allmins.len ? ".":" with no active admins online!"]") + setup_done = TRUE + //These callbacks will fire after roundstart key transfer /datum/controller/subsystem/ticker/proc/OnRoundstart(datum/callback/cb) if(!HasRoundStarted()) diff --git a/code/datums/http.dm b/code/datums/http.dm new file mode 100644 index 000000000000..49b183fde6c6 --- /dev/null +++ b/code/datums/http.dm @@ -0,0 +1,82 @@ +/datum/http_request + var/id + var/in_progress = FALSE + + var/method + var/body + var/headers + var/url + /// If present response body will be saved to this file. + var/output_file + + var/_raw_response + +/datum/http_request/proc/prepare(method, url, body = "", list/headers, output_file) + if (!length(headers)) + headers = "" + else + headers = json_encode(headers) + + src.method = method + src.url = url + src.body = body + src.headers = headers + src.output_file = output_file + +/datum/http_request/proc/execute_blocking() + _raw_response = rustg_http_request_blocking(method, url, body, headers, build_options()) + +/datum/http_request/proc/begin_async() + if (in_progress) + CRASH("Attempted to re-use a request object.") + + id = rustg_http_request_async(method, url, body, headers, build_options()) + + if (isnull(text2num(id))) + stack_trace("Proc error: [id]") + _raw_response = "Proc error: [id]" + else + in_progress = TRUE + +/datum/http_request/proc/build_options() + if(output_file) + return json_encode(list("output_filename"=output_file,"body_filename"=null)) + return null + +/datum/http_request/proc/is_complete() + if (isnull(id)) + return TRUE + + if (!in_progress) + return TRUE + + var/r = rustg_http_check_request(id) + + if (r == RUSTG_JOB_NO_RESULTS_YET) + return FALSE + else + _raw_response = r + in_progress = FALSE + return TRUE + +/datum/http_request/proc/into_response() + var/datum/http_response/R = new() + + try + var/list/L = json_decode(_raw_response) + R.status_code = L["status_code"] + R.headers = L["headers"] + R.body = L["body"] + catch + R.errored = TRUE + R.error = _raw_response + + return R + +/datum/http_response + var/status_code + var/body + var/list/headers + + var/errored = FALSE + var/error diff --git a/code/game/antagonist/antagonist_panel.dm b/code/game/antagonist/antagonist_panel.dm index 3f397d29c38d..2d676cf2ba44 100644 --- a/code/game/antagonist/antagonist_panel.dm +++ b/code/game/antagonist/antagonist_panel.dm @@ -31,7 +31,7 @@ if(!M.client) dat += " (logged out)" if(M.stat == DEAD) dat += " (DEAD)" dat += "" - dat += "
1 | 2 | 3 | 4 | 5 | " var/bname @@ -139,9 +149,9 @@ var/global/floorIsLava = 0 bname = assigned_blocks[block] body += "" if(bname) - var/bstate=M.dna.GetSEState(block) + var/bstate=player.dna.GetSEState(block) var/bcolor="[(bstate)?"#006600":"#ff0000"]" - body += "[bname][block]" + body += "[bname][block]" else body += "[block]" body+=" | " @@ -149,46 +159,44 @@ var/global/floorIsLava = 0 body += {"|
---|---|---|---|---|---|---|
[t] | ||||||
[t] |