From 3daec39efac9ee8f890ccc943df4a38a00288afa Mon Sep 17 00:00:00 2001 From: Werner <1331699+Arrow768@users.noreply.github.com> Date: Tue, 19 Dec 2023 23:54:57 +0100 Subject: [PATCH] Changes the discord bot into a subsystem and adds quite a bit of additional logging (#17996) * Changes the discord bot into a subsystem and adds quite a bit of additional logging * Removes a forgotten todo * replaces call with RUSTG_CALL (to make it compile) and adds a comment * Re-Add log prefix --------- Co-authored-by: Werner --- aurorastation.dme | 3 +- code/__defines/rust_g.dm | 2 +- code/_helpers/logging/subsystems/discord.dm | 3 + code/controllers/configuration.dm | 12 +- .../subsystems/discord.dm} | 220 ++++++++++-------- code/controllers/subsystems/documents.dm | 4 +- .../subsystems/initialization/misc_early.dm | 4 +- code/game/gamemodes/game_mode.dm | 6 +- code/game/objects/items/devices/uplink.dm | 2 +- code/game/verbs/who.dm | 2 +- code/modules/admin/admin.dm | 2 +- code/modules/admin/ticket.dm | 4 +- code/modules/admin/verbs/SDQL_2.dm | 2 +- code/modules/admin/verbs/adminhelp.dm | 2 +- code/modules/admin/verbs/adminpm.dm | 4 +- code/modules/admin/verbs/modifyvariables.dm | 4 +- code/modules/admin/verbs/pray.dm | 4 +- .../admin/view_variables/view_variables.dm | 4 +- .../client/preferences_notification.dm | 4 +- .../mob/living/carbon/human/human_powers.dm | 4 +- code/modules/mob/logout.dm | 4 +- code/modules/paperwork/faxmachine.dm | 2 +- .../world_api/commands/server_management.dm | 6 +- config/example/logging.json | 4 +- config/example/logging_files.json | 1 + html/changelogs/arrow768-discord.yml | 41 ++++ interface/interface.dm | 4 +- 27 files changed, 219 insertions(+), 135 deletions(-) create mode 100644 code/_helpers/logging/subsystems/discord.dm rename code/{datums/discord/bot.dm => controllers/subsystems/discord.dm} (68%) create mode 100644 html/changelogs/arrow768-discord.yml diff --git a/aurorastation.dme b/aurorastation.dme index 665caf39b9d..b678ece412a 100644 --- a/aurorastation.dme +++ b/aurorastation.dme @@ -184,6 +184,7 @@ #include "code\_helpers\logging\subsystems\atlas.dm" #include "code\_helpers\logging\subsystems\cargo.dm" #include "code\_helpers\logging\subsystems\chemistry.dm" +#include "code\_helpers\logging\subsystems\discord.dm" #include "code\_helpers\logging\subsystems\documents.dm" #include "code\_helpers\logging\subsystems\fail2topic.dm" #include "code\_helpers\logging\subsystems\garbage.dm" @@ -248,6 +249,7 @@ #include "code\controllers\subsystems\chat.dm" #include "code\controllers\subsystems\chemistry.dm" #include "code\controllers\subsystems\cult.dm" +#include "code\controllers\subsystems\discord.dm" #include "code\controllers\subsystems\documents.dm" #include "code\controllers\subsystems\economy.dm" #include "code\controllers\subsystems\effects.dm" @@ -365,7 +367,6 @@ #include "code\datums\components\multitool\multitool.dm" #include "code\datums\components\multitool\circuitboards\circuitboards.dm" #include "code\datums\components\turf_click\turf_hand.dm" -#include "code\datums\discord\bot.dm" #include "code\datums\discord\webhook.dm" #include "code\datums\elements\_element.dm" #include "code\datums\elements\empprotection.dm" diff --git a/code/__defines/rust_g.dm b/code/__defines/rust_g.dm index a56d77b3e5b..e718682e67f 100644 --- a/code/__defines/rust_g.dm +++ b/code/__defines/rust_g.dm @@ -213,7 +213,7 @@ else CRASH(output["content"]) -#define rustg_udp_send(addr, text) call(RUST_G, "udp_send")(addr, text) +#define rustg_udp_send(addr, text) RUSTG_CALL(RUST_G, "udp_send")(addr, text) #define rustg_url_encode(text) RUSTG_CALL(RUST_G, "url_encode")("[text]") #define rustg_url_decode(text) RUSTG_CALL(RUST_G, "url_decode")(text) diff --git a/code/_helpers/logging/subsystems/discord.dm b/code/_helpers/logging/subsystems/discord.dm new file mode 100644 index 00000000000..18722214922 --- /dev/null +++ b/code/_helpers/logging/subsystems/discord.dm @@ -0,0 +1,3 @@ +/proc/log_subsystem_discord(text) + if (config?.logsettings["log_subsystems_discord"]) + WRITE_LOG(config.logfiles["world_subsystems_discord_log"], "SSdiscord: [text]") diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index d4b103c1e87..fd27cb0876a 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -1165,21 +1165,19 @@ var/list/gamemode_cache = list() else if (type == "discord") // Ideally, this would never happen. But just in case. - if (!discord_bot) + if (!SSdiscord) LOG_DEBUG("BOREALIS: Attempted to read config/discord.txt before initializing the bot.") return switch (name) if ("token") - discord_bot.auth_token = value + SSdiscord.auth_token = value if ("active") - discord_bot.active = 1 - if ("robust_debug") - discord_bot.robust_debug = 1 + SSdiscord.active = TRUE if ("subscriber") - discord_bot.subscriber_role = value + SSdiscord.subscriber_role = value if ("alert_visibility") - discord_bot.alert_visibility = 1 + SSdiscord.alert_visibility = TRUE else log_config("Unknown setting in discord configuration: '[name]'") load_logging_config() diff --git a/code/datums/discord/bot.dm b/code/controllers/subsystems/discord.dm similarity index 68% rename from code/datums/discord/bot.dm rename to code/controllers/subsystems/discord.dm index 92592af5604..9c8451ad433 100644 --- a/code/datums/discord/bot.dm +++ b/code/controllers/subsystems/discord.dm @@ -3,54 +3,29 @@ #define CHAN_ANNOUNCE "channel_announce" #define CHAN_INVITE "channel_invite" -#define SEND_OK 0 -#define SEND_TIMEOUT 1 -#define ERROR_PROC 2 -#define ERROR_HTTP 4 +#define SEND_OK 1 +#define SEND_TIMEOUT 2 +#define ERROR_PROC 4 +#define ERROR_HTTP 8 -var/datum/discord_bot/discord_bot = null +//ToDos: +// At some point the subsystem processing should be used instead of the addtimer´s +// But that requires a larger overhaul of this subsystem (and ideally a http subsystem to delegate the queueing/processing of the http requests to) -/hook/startup/proc/initialize_discord_bot() - if (discord_bot) - // This shouldn't be possible, but sure! - return 0 +SUBSYSTEM_DEF(discord) + name = "Discord" + init_order = SS_INIT_MISC_FIRST + flags = SS_NO_FIRE | SS_NO_DISPLAY - discord_bot = new() - - config.load("config/discord.txt", "discord") - - discord_bot.update_channels() - - return 1 - -/hook/roundstart/proc/alert_no_admins() - var/admins_number = 0 - - for (var/C in clients) - var/client/cc = C - if (cc.holder && (cc.holder.rights & (R_MOD|R_ADMIN))) - admins_number++ - - post_webhook_event(WEBHOOK_ROUNDSTART, list("playercount"=clients.len)) - if (!admins_number) - post_webhook_event(WEBHOOK_ALERT_NO_ADMINS, list()) - if (!discord_bot) - return 1 - discord_bot.send_to_admins("@here Round has started with no admins or mods online.") - - return 1 - -/datum/discord_bot var/list/channels_to_group = list() // Group flag -> list of channel datums map. var/list/channels = list() // Channel ID -> channel datum map. Will ensure that only one datum per channel ID exists. - var/datum/discord_channel/invite = null // The channel datum where the ingame Join Channel button will link to. + var/datum/discord_channel/invite_channel = null // The channel datum where the ingame Join Channel button will link to. - var/active = 0 + var/active = FALSE var/auth_token = "" var/subscriber_role = "" - var/robust_debug = 0 // Lazy man's rate limiting vars var/list/queue = list() @@ -59,6 +34,15 @@ var/datum/discord_bot/discord_bot = null // with world.visibility == 0. var/alert_visibility = 0 + +/datum/controller/subsystem/discord/Initialize() + config.load("config/discord.txt", "discord") + update_channels() + +/datum/controller/subsystem/discord/stat_entry(msg) + msg = "A: [active] C: [length(channels)] G: [length(channels_to_group)]" + return ..() + /* * Proc update_channels * Used to load channels from the database and construct them with the discord API. @@ -66,12 +50,14 @@ var/datum/discord_bot/discord_bot = null * * @return num - Error code. 0 upon success. */ -/datum/discord_bot/proc/update_channels() +/datum/controller/subsystem/discord/proc/update_channels() + log_subsystem_discord("UpdateChannels - Attempted") if (!active) + log_subsystem_discord("UpdateChannels - Failed - Discord bot is not active") return 1 if (!establish_db_connection(dbcon)) - LOG_DEBUG("BOREALIS: Failed to update channels due to missing database.") + log_subsystem_discord("UpdateChannels - Failed - Unable to connect to database") return 2 // Reset the channel lists. @@ -93,7 +79,7 @@ var/datum/discord_bot/discord_bot = null B = new(channel_query.item[2], channel_query.item[4], text2num(channel_query.item[3])) if (!B) - LOG_DEBUG("BOREALIS: Bad channel data during update channels. [jointext(channel_query.item, ", ")].") + log_subsystem_discord("UpdateChannels - Error - Bad channel data during update channels - [jointext(channel_query.item, ", ")]") continue channels[channel_query.item[2]] = B @@ -105,11 +91,11 @@ var/datum/discord_bot/discord_bot = null channels_to_group[channel_query.item[1]] += B if (!isnull(channels_to_group[CHAN_INVITE])) - invite = channels_to_group[CHAN_INVITE][1] - else if (robust_debug) - LOG_DEBUG("BOREALIS: No invite channel designated.") + invite_channel = channels_to_group[CHAN_INVITE][1] + else + log_subsystem_discord("UpdateChannels - No Invite Channel Designated") - LOG_DEBUG("BOREALIS: Channels updated successfully.") + log_subsystem_discord("UpdateChannels - Completed") return 0 /* @@ -119,17 +105,34 @@ var/datum/discord_bot/discord_bot = null * @param text channel_group - The name of the channel group which to target. * @param text message - The message to send. */ -/datum/discord_bot/proc/send_message(var/channel_group, var/message) - if (!active || !auth_token) +/datum/controller/subsystem/discord/proc/send_message(var/channel_group, var/message) + log_subsystem_discord("SendMessage - Attempted") + if (!active) + log_subsystem_discord("SendMessage - Failed - Bot not Active") return - if (!channel_group || !channels.len || isnull(channels_to_group[channel_group])) + if (!auth_token) + log_subsystem_discord("SendMessage - Failed - No Auth Token set") + return + + if (!channel_group) + log_subsystem_discord("SendMessage - Failed - No ChannelGroup specified") + return + + if (!channels.len) + log_subsystem_discord("SendMessage - Failed - No Channels Loaded from DB") + return + + if (isnull(channels_to_group[channel_group])) + log_subsystem_discord("SendMessage - Failed - No Channels found for group '[channel_group]'") return if (!message) + log_subsystem_discord("SendMessage - Failed - No message specified") return if (length(message) > 2000) + log_subsystem_discord("SendMessage - Message Cropped - Message too long") message = copytext(message, 1, 2001) // Let's run it through the proper JSON encoder, just in case of special characters. @@ -139,7 +142,9 @@ var/datum/discord_bot/discord_bot = null var/list/sent = list() for (var/B in A) var/datum/discord_channel/channel = B + log_subsystem_discord("SendMessage - Sending - Attempting to send to send to '[channel.id]'") if (channel.send_message_to(auth_token, message) == SEND_TIMEOUT) + log_subsystem_discord("SendMessage - Sending - Attempt has been rate-limited - Queuing") // Whoopsies, rate limited. // Set up the queue. queue.Add(list(list(message, A - sent))) @@ -152,8 +157,7 @@ var/datum/discord_bot/discord_bot = null else sent += channel - if (robust_debug) - LOG_DEBUG("BOREALIS: Message sent to [channel_group]. JSON body: '[message]'") + log_subsystem_discord("SendMessage - Sent to [channel_group]. JSON body: '[message]'") /* * Proc retreive_pins @@ -163,20 +167,26 @@ var/datum/discord_bot/discord_bot = null * list("pin_flag" = list(list("author" = author name, "content" = content), * list("author" = author name, "content" = content))) */ -/datum/discord_bot/proc/retreive_pins() - if (!active || !auth_token) +/datum/controller/subsystem/discord/proc/retreive_pins() + log_subsystem_discord("RetrievePins - Attempted") + if (!active) + log_subsystem_discord("RetrievePins - Failed - Bot not Active") return list() - if (!channels.len || isnull(channels_to_group["channel_pins"])) - if (robust_debug) - LOG_DEBUG("BOREALIS: No pins channel group.") + if (!auth_token) + log_subsystem_discord("RetrievePins - Failed - No Auth Token set") + return list() + + if (!channels.len) + log_subsystem_discord("RetrievePins - Failed - No Channels Loaded from DB") + return + + if (isnull(channels_to_group["channel_pins"])) + log_subsystem_discord("RetrievePins - Failed - No Channels found for group 'channel_pins'") return list() var/list/output = list() - if (robust_debug) - LOG_DEBUG("BOREALIS: Acquiring pins.") - for (var/A in channels_to_group["channel_pins"]) var/datum/discord_channel/channel = A if (isnull(output["[channel.pin_flag]"])) @@ -186,8 +196,7 @@ var/datum/discord_bot/discord_bot = null if (length(ch_pins)) output["[channel.pin_flag]"] += ch_pins - if (robust_debug) - LOG_DEBUG("BOREALIS: Finished acquiring pins.") + log_subsystem_discord("RetrievePins - Finished - Pins Acquired") return output @@ -198,22 +207,28 @@ var/datum/discord_bot/discord_bot = null * * @return text - The invite URL to the designated invite channel. */ -/datum/discord_bot/proc/retreive_invite() +/datum/controller/subsystem/discord/proc/retreive_invite() set background = 1 - if (!active || !auth_token) + if (!active) + log_subsystem_discord("RetrieveInvite - Failed - Bot not Active") return "" - if (!invite) + if (!auth_token) + log_subsystem_discord("RetrieveInvite - Failed - No Auth Token set") return "" - var/res = invite.get_invite(auth_token) + if (!invite_channel) + log_subsystem_discord("RetrieveInvite - Failed - No Invite Channel") + return "" + + var/res = invite_channel.get_invite(auth_token) return isnum(res) ? "" : res /* * Proc send_to_admin * Forwards a message to the admin channels. */ -/datum/discord_bot/proc/send_to_admins(message) +/datum/controller/subsystem/discord/proc/send_to_admins(message) set background = 1 send_message(CHAN_ADMIN, message) @@ -221,7 +236,7 @@ var/datum/discord_bot/discord_bot = null * Proc send_to_cciaa * Forwards a message to the CCIAA channels. */ -/datum/discord_bot/proc/send_to_cciaa(message) +/datum/controller/subsystem/discord/proc/send_to_cciaa(message) set background = 1 send_message(CHAN_CCIAA, message) @@ -229,7 +244,7 @@ var/datum/discord_bot/discord_bot = null * Proc send_to_announce * Forwards a message to the announcements channels. */ -/datum/discord_bot/proc/send_to_announce(message, prepend_role = 0) +/datum/controller/subsystem/discord/proc/send_to_announce(message, prepend_role = 0) set background = 1 if (prepend_role && subscriber_role) message = "<@&[subscriber_role]> " + message @@ -240,11 +255,11 @@ var/datum/discord_bot/discord_bot = null * Handles the queue pushing for the bot. If there is no need to reschedule (all messages get successfully * pushed), then it deletes push_task and sets it back to null. Otherwise, it simply reschedules it. */ -/datum/discord_bot/proc/push_queue() +/datum/controller/subsystem/discord/proc/push_queue() + log_subsystem_discord("PushQueue - Attempt") // What facking queue. if (!queue || !queue.len) - if (robust_debug) - LOG_DEBUG("BOREALIS: Attempted to push a null length queue.") + log_subsystem_discord("PushQueue - Failed - Attempted to push a null length queue.") return // A[1] - message body. @@ -266,11 +281,28 @@ var/datum/discord_bot/discord_bot = null queue.Remove(A) + +/datum/controller/subsystem/discord/proc/discord_escape(var/input, var/remove_everyone = TRUE, var/remove_mentions = FALSE) + . = replace_characters(input, list("`" = "\\`", "*" = "\\*", "_" = "\\_", "~" = "\\~")) + + if (remove_everyone) + var/regex/evReg = regex("@everyone", "gi") + . = evReg.Replace(., "@ everyone") + var/regex/hereReg = regex("@here", "gi") + . = hereReg.Replace(., "@ here") + + if (remove_mentions) + var/regex/menReg = regex("<@\[\\d]+>", "g") + . = menReg.Replace(., "\[mention]") + var/regex/roleReg = regex("<@&\[\\d]+>", "g") + . = roleReg.Replace(., "\[role mention]") + + /** * Will alert the staff on Discord if the server is initialized in invisible mode. * Can be toggled via config. */ -/datum/discord_bot/proc/alert_server_visibility() +/datum/controller/subsystem/discord/proc/alert_server_visibility() set background = 1 if (alert_visibility && !world.visibility) send_to_admins("Server started as invisible!") @@ -303,7 +335,7 @@ var/datum/discord_bot/discord_bot = null * * @param text token - the authorization token to be used for the requests. * @param text message - the sanitized message content to be sent. - * @return num - a specific return code for the discord_bot to handle. + * @return num - a specific return code for the SSdiscord to handle. */ /datum/discord_channel/proc/send_message_to(var/token, var/message) if (!token || !message) @@ -317,18 +349,20 @@ var/datum/discord_bot/discord_bot = null var/datum/http_response/res = req.into_response() if (res.errored) - LOG_DEBUG("BOREALIS: library error during HTTP query. [res.error]") + log_subsystem_discord("SendMessageTo - library error during HTTP query. [res.error]") return ERROR_PROC switch (res.status_code) if (200) + log_subsystem_discord("SendMessageTo - Success") return SEND_OK if (429) + log_subsystem_discord("SendMessageTo - RateLimited") return SEND_TIMEOUT else - LOG_DEBUG("BOREALIS: HTTP error while forwarding message to Discord API: [res]. Channel: [id]. Message body: [message].") + log_subsystem_discord("SendMessageTo - HTTP error while forwarding message to Discord API: [res]. Channel: [id]. Message body: [message].") return ERROR_HTTP /* @@ -348,10 +382,10 @@ var/datum/discord_bot/discord_bot = null var/datum/http_response/res = req.into_response() if (res.errored) - LOG_DEBUG("BOREALIS: Proc error while fetching pins: [res.error]") + log_subsystem_discord("GetPins - Proc error while fetching pins: [res.error]") return else if (res.status_code != 200) - LOG_DEBUG("BOREALIS: HTTP error while fetching pins: [res.status_code].") + log_subsystem_discord("GetPins - HTTP error while fetching pins: [res.status_code].") return else var/list/A = json_decode(res.body) @@ -398,10 +432,10 @@ var/datum/discord_bot/discord_bot = null var/datum/http_response/res = req.into_response() if (res.errored) - LOG_DEBUG("BOREALIS: Proc error while fetching invite: [res.error]") + log_subsystem_discord("GetInvite - Proc error while fetching invite: [res.error]") return else if (res.status_code != 200) - LOG_DEBUG("BOREALIS: HTTP error while fetching invite: [res.status_code].") + log_subsystem_discord("GetInvite - HTTP error while fetching invite: [res.status_code].") return else var/list/A = json_decode(res.body) @@ -428,7 +462,7 @@ var/datum/discord_bot/discord_bot = null // Sanity check for debug I guess. if (!code) - LOG_DEBUG("BOREALIS: Retreived an empty invite. This should not happen. Response object: [json_encode(A)]") + log_subsystem_discord("GetInvite - Retreived an empty invite. This should not happen. Response object: [json_encode(A)]") return // Save the URL for later retreival. @@ -460,20 +494,24 @@ var/datum/discord_bot/discord_bot = null invite_url = "https://discord.gg/[r_data["code"]]" return invite_url -/proc/discord_escape(var/input, var/remove_everyone = TRUE, var/remove_mentions = FALSE) - . = replace_characters(input, list("`" = "\\`", "*" = "\\*", "_" = "\\_", "~" = "\\~")) - if(remove_everyone) - var/regex/evReg = regex("@everyone", "gi") - . = evReg.Replace(., "@ everyone") - var/regex/hereReg = regex("@here", "gi") - . = hereReg.Replace(., "@ here") +/hook/roundstart/proc/alert_no_admins() + var/admins_number = 0 + + for (var/C in clients) + var/client/cc = C + if (cc.holder && (cc.holder.rights & (R_MOD|R_ADMIN))) + admins_number++ + + post_webhook_event(WEBHOOK_ROUNDSTART, list("playercount"=clients.len)) + if (!admins_number) + post_webhook_event(WEBHOOK_ALERT_NO_ADMINS, list()) + if (!SSdiscord) + return 1 + SSdiscord.send_to_admins("@here Round has started with no admins or mods online.") + + return 1 - if(remove_mentions) - var/regex/menReg = regex("<@\[\\d]+>", "g") - . = menReg.Replace(., "\[mention]") - var/regex/roleReg = regex("<@&\[\\d]+>", "g") - . = roleReg.Replace(., "\[role mention]") #undef CHAN_ADMIN #undef CHAN_CCIAA diff --git a/code/controllers/subsystems/documents.dm b/code/controllers/subsystems/documents.dm index 11cca54edbb..9654c407098 100644 --- a/code/controllers/subsystems/documents.dm +++ b/code/controllers/subsystems/documents.dm @@ -16,10 +16,10 @@ SUBSYSTEM_DEF(docs) /datum/controller/subsystem/docs/Initialize(timeofday) //Load in the docs config if(config.docs_load_docs_from == "sql") - log_subsystem_documents("SSdocs: Attempting to Load from SQL") + log_subsystem_documents("Attempting to Load from SQL") load_from_sql() else if(config.docs_load_docs_from == "json") - log_subsystem_documents("SSdocs: Attempting to Load from JSON") + log_subsystem_documents("Attempting to Load from JSON") load_from_json() else log_config("SSdocs: invalid load option specified in config") diff --git a/code/controllers/subsystems/initialization/misc_early.dm b/code/controllers/subsystems/initialization/misc_early.dm index e656af280cc..3bc284bc8e6 100644 --- a/code/controllers/subsystems/initialization/misc_early.dm +++ b/code/controllers/subsystems/initialization/misc_early.dm @@ -32,8 +32,8 @@ SUBSYSTEM_DEF(misc_early) // Get BOREALIS to warn staff about a lazy admin forgetting visibility to 0 // before anyone has a chance to change it! - if (discord_bot) - discord_bot.alert_server_visibility() + if (SSdiscord) + SSdiscord.alert_server_visibility() global_initialize_webhooks() diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 20b3fc33a2e..1aad3cf7786 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -357,14 +357,14 @@ var/global/list/additional_antag_types = list() antag.check_victory() antag.print_player_summary() // Avoid the longest loop if we aren't actively using the bot. - if (discord_bot.active) + if (SSdiscord.active) antag_text += antag.print_player_summary_discord() sleep(10) print_ownerless_uplinks() discord_text += antag_text - discord_bot.send_to_announce(discord_text, 1) + SSdiscord.send_to_announce(discord_text, 1) discord_text = "" var/clients = 0 @@ -406,7 +406,7 @@ var/global/list/additional_antag_types = list() discord_text += "There were **no survivors** ([ghosts] ghosts)." to_world(text) - discord_bot.send_to_announce(discord_text) + SSdiscord.send_to_announce(discord_text) post_webhook_event(WEBHOOK_ROUNDEND, list("survivours"=surviving_total, "escaped"=escaped_total, "ghosts"=ghosts, "gamemode"=name, "gameid"=game_id, "antags"=antag_text)) if(clients > 0) diff --git a/code/game/objects/items/devices/uplink.dm b/code/game/objects/items/devices/uplink.dm index 7c318c179fe..0d437d056a2 100644 --- a/code/game/objects/items/devices/uplink.dm +++ b/code/game/objects/items/devices/uplink.dm @@ -409,7 +409,7 @@ Then check if it's true, if true return. This will stop the normal menu appearin return command_announcement.Announce("[message]", title, new_sound = 'sound/AI/commandreport.ogg', msg_sanitized = 1); - discord_bot.send_to_cciaa("Announcer - Fake announcement:`[title]` - `[message]`, sent by [user]!") + SSdiscord.send_to_cciaa("Announcer - Fake announcement:`[title]` - `[message]`, sent by [user]!") qdel(src) /obj/item/device/special_uplink diff --git a/code/game/verbs/who.dm b/code/game/verbs/who.dm index 08c54ce85f3..71c6ee79b44 100644 --- a/code/game/verbs/who.dm +++ b/code/game/verbs/who.dm @@ -170,7 +170,7 @@ cciaamsg += "\t[C.key] is a [C.holder.rank]
" num_cciaa_online++ - if(discord_bot && discord_bot.active) + if(SSdiscord && SSdiscord.active) to_chat(src, "Adminhelps are also sent to Discord. If no admins are available in game try anyway and an admin on Discord may see it and respond.") msg = "Current Admins ([num_admins_online]):
" + msg diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index a97ca81d7ce..37388bda5b2 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -790,7 +790,7 @@ var/global/enabled_spooking = 0 var/long_message = " toggled hub visibility. The server is now [world.visibility ? "visible" : "invisible"] ([world.visibility])." post_webhook_event(WEBHOOK_ADMIN, list("title"="Hub visibility has been toggled", "message"="**[key_name(src)]**" + long_message)) - discord_bot.send_to_admins("[key_name(src)]" + long_message) + SSdiscord.send_to_admins("[key_name(src)]" + long_message) message_admins("[key_name_admin(usr)]" + long_message, 1) log_admin("[key_name(usr)] toggled hub visibility.") feedback_add_details("admin_verb","THUB") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc diff --git a/code/modules/admin/ticket.dm b/code/modules/admin/ticket.dm index ba7e68f4bee..a821492e81b 100644 --- a/code/modules/admin/ticket.dm +++ b/code/modules/admin/ticket.dm @@ -30,7 +30,7 @@ var/global/list/ticket_panels = list() /datum/ticket/proc/broadcast_closure(closing_user) var/client/owner_client = client_by_ckey(owner) if(owner_client && owner_client.adminhelped == ADMINHELPED_DISCORD) - discord_bot.send_to_admins("[key_name(owner_client)]'s request for help has been closed/deemed unnecessary by [closing_user].") + SSdiscord.send_to_admins("[key_name(owner_client)]'s request for help has been closed/deemed unnecessary by [closing_user].") owner_client.adminhelped = ADMINHELPED /datum/ticket/proc/set_to_closed(closing_key) @@ -101,7 +101,7 @@ var/global/list/ticket_panels = list() var/client/owner_client = client_by_ckey(src.owner) if(owner_client && owner_client.adminhelped == ADMINHELPED_DISCORD) - discord_bot.send_to_admins("[key_name(owner_client)]'s request for help has been taken by [key_name(assigned_admin)].") + SSdiscord.send_to_admins("[key_name(owner_client)]'s request for help has been taken by [key_name(assigned_admin)].") owner_client.adminhelped = ADMINHELPED message_admins("[key_name(assigned_admin)] has assigned themself to [src.owner]'s ticket.") diff --git a/code/modules/admin/verbs/SDQL_2.dm b/code/modules/admin/verbs/SDQL_2.dm index 06568b45ab1..571129ced6a 100644 --- a/code/modules/admin/verbs/SDQL_2.dm +++ b/code/modules/admin/verbs/SDQL_2.dm @@ -58,7 +58,7 @@ objs += d //to_chat(usr, "Query: [query_text]") - var/static/list/blacklist = list(/datum/configuration) + var/static/list/blacklist = list(/datum/configuration, /datum/controller/subsystem/discord) for(var/datum/D in objs) if(blacklist[D.type]) objs -= D diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index d1702a9f13d..bd34cb9982f 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -134,7 +134,7 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey"," log_admin("HELP: [key_name(src)]: [original_msg] - heard by [admin_number_present] non-AFK admins.",admin_key=key_name(src)) if(admin_number_active <= 0) post_webhook_event(WEBHOOK_ADMIN_PM_IMPORTANT, list("title"="Help is requested", "message"="Request for Help from **[key_name(src)]**: ```[html_decode(original_msg)]```\n[admin_number_afk ? "All admins AFK ([admin_number_afk])" : "No admins online"]!!")) - discord_bot.send_to_admins("@here Request for Help from [key_name(src)]: [html_decode(original_msg)] - !![admin_number_afk ? "All admins AFK ([admin_number_afk])" : "No admins online"]!!") + SSdiscord.send_to_admins("@here Request for Help from [key_name(src)]: [html_decode(original_msg)] - !![admin_number_afk ? "All admins AFK ([admin_number_afk])" : "No admins online"]!!") adminhelped = ADMINHELPED_DISCORD feedback_add_details("admin_verb","AH") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! return diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm index a6159b3d1b2..439d0c5ffe6 100644 --- a/code/modules/admin/verbs/adminpm.dm +++ b/code/modules/admin/verbs/adminpm.dm @@ -175,8 +175,8 @@ msg = sanitize(msg) sender = sanitize(sender, encode=0) - post_webhook_event(WEBHOOK_ADMIN_PM, list("title"="Help is requested", "message"="PlayerPM to **[discord_escape(sender)]** from **[discord_escape(key_name(src))]**: ```[discord_escape(html_decode(msg))]```")) - discord_bot.send_to_admins("PlayerPM to [discord_escape(sender)] from [discord_escape(key_name(src))]: [discord_escape(html_decode(msg))]") + post_webhook_event(WEBHOOK_ADMIN_PM, list("title"="Help is requested", "message"="PlayerPM to **[SSdiscord.discord_escape(sender)]** from **[SSdiscord.discord_escape(key_name(src))]**: ```[SSdiscord.discord_escape(html_decode(msg))]```")) + SSdiscord.send_to_admins("PlayerPM to [SSdiscord.discord_escape(sender)] from [SSdiscord.discord_escape(key_name(src))]: [SSdiscord.discord_escape(html_decode(msg))]") to_chat(src, "" + create_text_tag("PM <-", src) + " to Discord-[sender]: [msg]") diff --git a/code/modules/admin/verbs/modifyvariables.dm b/code/modules/admin/verbs/modifyvariables.dm index ea7255a1e27..153820d42a6 100644 --- a/code/modules/admin/verbs/modifyvariables.dm +++ b/code/modules/admin/verbs/modifyvariables.dm @@ -1,8 +1,8 @@ var/list/forbidden_varedit_object_types = list( /datum/admins, //Admins editing their own admin-power object? Yup, sounds like a good idea. /datum/controller/subsystem/statistics, //Prevents people messing with feedback gathering - /datum/feedback_variable, //Prevents people messing with feedback gathering - /datum/discord_bot //Nope.jpg. Stop it. + /datum/controller/subsystem/discord, //Nope.jpg + /datum/feedback_variable //Prevents people messing with feedback gathering ) var/list/VVlocked = list("vars", "holder", "client", "virus", "viruses", "cuffed", "last_eaten", "unlock_content", "bound_x", "bound_y", "step_x", "step_y", "force_ending") diff --git a/code/modules/admin/verbs/pray.dm b/code/modules/admin/verbs/pray.dm index 203a5c3f33e..1eb4d4bf321 100644 --- a/code/modules/admin/verbs/pray.dm +++ b/code/modules/admin/verbs/pray.dm @@ -43,7 +43,7 @@ to_chat(C, msg_cciaa) - discord_bot.send_to_cciaa("Emergency message from the station: `[msg]`, sent by [Sender]! Gamemode: [SSticker.mode]") + SSdiscord.send_to_cciaa("Emergency message from the station: `[msg]`, sent by [Sender]! Gamemode: [SSticker.mode]") var/discord_msg = "[cciaa_present] agents online." if (cciaa_present) @@ -52,7 +52,7 @@ else discord_msg += " [cciaa_afk] AFK." - discord_bot.send_to_cciaa(discord_msg) + SSdiscord.send_to_cciaa(discord_msg) post_webhook_event(WEBHOOK_CCIAA_EMERGENCY_MESSAGE, list("message"=msg, "sender"="[Sender]", "cciaa_present"=cciaa_present, "cciaa_afk"=cciaa_afk)) /proc/Syndicate_announce(var/msg, var/mob/Sender) diff --git a/code/modules/admin/view_variables/view_variables.dm b/code/modules/admin/view_variables/view_variables.dm index 49569cfd97e..5fd3f114e75 100644 --- a/code/modules/admin/view_variables/view_variables.dm +++ b/code/modules/admin/view_variables/view_variables.dm @@ -21,8 +21,8 @@ if(!D) return - var/static/list/blacklist = list(/datum/configuration) - if(blacklist[D.type]) + var/static/list/blacklist = list(/datum/configuration, /datum/controller/subsystem/discord) + if(is_type_in_list(D,blacklist)) return var/icon/sprite diff --git a/code/modules/client/preferences_notification.dm b/code/modules/client/preferences_notification.dm index ae8ac7280e6..4243431b35b 100644 --- a/code/modules/client/preferences_notification.dm +++ b/code/modules/client/preferences_notification.dm @@ -187,12 +187,12 @@ panel_notification=1 notification_count++ if("admin") - discord_bot.send_to_admins("Server Notification for [user.ckey]: [query.item[1]]") + SSdiscord.send_to_admins("Server Notification for [user.ckey]: [query.item[1]]") post_webhook_event(WEBHOOK_ADMIN, list("title"="Server Notification for: [user.ckey]", "message"="Server Notification Triggered for [user.ckey]: [query.item[1]]")) //Immediately ack the notification autoack=1 if("ccia") - discord_bot.send_to_cciaa("Server Notification for [user.ckey]: [query.item[1]]") + SSdiscord.send_to_cciaa("Server Notification for [user.ckey]: [query.item[1]]") post_webhook_event(WEBHOOK_CCIAA_EMERGENCY_MESSAGE, list("title"="Server Notification for: [user.ckey]", "message"="Server Notification Triggered for [user.ckey]: [query.item[1]]")) //Immeidately ack the notification autoack=1 diff --git a/code/modules/mob/living/carbon/human/human_powers.dm b/code/modules/mob/living/carbon/human/human_powers.dm index 0201f11eb4e..c25063ec7ba 100644 --- a/code/modules/mob/living/carbon/human/human_powers.dm +++ b/code/modules/mob/living/carbon/human/human_powers.dm @@ -1381,7 +1381,7 @@ to_chat(C, ccia_msg) - discord_bot.send_to_cciaa("Emergency message from the station: `[msg]`, sent by [src]! Gamemode: [SSticker.mode]") + SSdiscord.send_to_cciaa("Emergency message from the station: `[msg]`, sent by [src]! Gamemode: [SSticker.mode]") var/discord_msg = "[cciaa_present] agents online." if (cciaa_present) @@ -1390,7 +1390,7 @@ else discord_msg += " [cciaa_afk] AFK." - discord_bot.send_to_cciaa(discord_msg) + SSdiscord.send_to_cciaa(discord_msg) post_webhook_event(WEBHOOK_CCIAA_EMERGENCY_MESSAGE, list("message"=msg, "sender"="[src]", "cciaa_present"=cciaa_present, "cciaa_afk"=cciaa_afk)) /mob/living/carbon/human/proc/hiveban() //Removes Hivenet completely from a Vaurca diff --git a/code/modules/mob/logout.dm b/code/modules/mob/logout.dm index 42df0a1636d..73128a3edb2 100644 --- a/code/modules/mob/logout.dm +++ b/code/modules/mob/logout.dm @@ -25,10 +25,10 @@ if (admins_number == 0) //Apparently the admin logging out is no longer an admin at this point, so we have to check this towards 0 and not towards 1. Awell. post_webhook_event(WEBHOOK_ADMIN_IMPORTANT, list("title"="Admin has logged out", "message"="**[key_name(src)]** logged out - no more admins online.")) - discord_bot.send_to_admins("@here [key_name(src)] logged out - no more admins online.") + SSdiscord.send_to_admins("@here [key_name(src)] logged out - no more admins online.") else if ((admins_number - admins_number_afk) <= 0) post_webhook_event(WEBHOOK_ADMIN, list("title"="Admin has logged out", "message"="**[key_name(src)]** logged out - only AFK admins _([admins_number_afk])_ are online.")) - discord_bot.send_to_admins("[key_name(src)] logged out - only AFK admins ([admins_number_afk]) are online.") + SSdiscord.send_to_admins("[key_name(src)] logged out - only AFK admins ([admins_number_afk]) are online.") if (mob_thinks) MOB_START_THINKING(src) diff --git a/code/modules/paperwork/faxmachine.dm b/code/modules/paperwork/faxmachine.dm index 3364d542f60..df0d9cde64d 100644 --- a/code/modules/paperwork/faxmachine.dm +++ b/code/modules/paperwork/faxmachine.dm @@ -314,7 +314,7 @@ var/list/admin_departments discord_msg += " Gamemode: [SSticker.mode]" - discord_bot.send_to_cciaa(discord_msg) + SSdiscord.send_to_cciaa(discord_msg) /obj/machinery/photocopier/faxmachine/proc/do_pda_alerts() for(var/obj/item/modular_computer/pda in alert_pdas) diff --git a/code/modules/world_api/commands/server_management.dm b/code/modules/world_api/commands/server_management.dm index 636d5120f03..944a2bbecb4 100644 --- a/code/modules/world_api/commands/server_management.dm +++ b/code/modules/world_api/commands/server_management.dm @@ -24,7 +24,7 @@ response = "Orders have been placed. Use force parameter to overwrite." return TRUE -// Update discord_bot's channels. +// Update SSdiscord's channels. /datum/topic_command/update_bot_channels name = "update_bot_channels" description = "Tells the ingame instance of the Discord bot to update its cached channels list." @@ -32,12 +32,12 @@ /datum/topic_command/update_bot_channels/run_command() data = null - if (!discord_bot) + if (!SSdiscord) statuscode = 404 response = "Ingame Discord bot not initialized." return 1 - switch (discord_bot.update_channels()) + switch (SSdiscord.update_channels()) if (1) statuscode = 404 response = "Ingame Discord bot is not active." diff --git a/config/example/logging.json b/config/example/logging.json index aa147bfb9a4..f21fab777b1 100644 --- a/config/example/logging.json +++ b/config/example/logging.json @@ -29,7 +29,9 @@ "log_subsystems_chemistry":1, "log_subsystems_atlas":1, "log_subsystems_ghostroles":1, - "log_subsystems_law":1,"log_subsystems_cargo":1, + "log_subsystems_law":1, + "log_subsystems_cargo":1, + "log_subsystems_discord":0, "log_subsystems_documents":1, "log_subsystems_fail2topic":1, "log_subsystems_mapfinalization":1, diff --git a/config/example/logging_files.json b/config/example/logging_files.json index 10819a1cb9f..d6bd0146062 100644 --- a/config/example/logging_files.json +++ b/config/example/logging_files.json @@ -31,6 +31,7 @@ "world_subsystems_ghostroles_log":"subsystems/ghostroles.log", "world_subsystems_law_log":"subsystems/law.log", "world_subsystems_cargo_log":"subsystems/cargo.log", + "world_subsystems_discord_log":"subsystems/discord.log", "world_subsystems_documents_log":"subsystems/documents.log", "world_subsystems_fail2topic_log":"subsystems/fail2topic.log", "world_subsystems_mapfinalization_log":"subsystems/mapfinalization.log", diff --git a/html/changelogs/arrow768-discord.yml b/html/changelogs/arrow768-discord.yml new file mode 100644 index 00000000000..9e862893b2a --- /dev/null +++ b/html/changelogs/arrow768-discord.yml @@ -0,0 +1,41 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +# balance +# admin +# backend +# security +# refactor +################################# + +# Your name. +author: arrow768 + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - backend: "Overhauls logging of the discord notifications." diff --git a/interface/interface.dm b/interface/interface.dm index 45e0f97872b..a57a57c2904 100644 --- a/interface/interface.dm +++ b/interface/interface.dm @@ -191,9 +191,9 @@ Any-Mode: (hotkey doesn't need to be on) set desc = "Get a link to the Discord server." set hidden = 1 - if (discord_bot && discord_bot.active) + if (SSdiscord && SSdiscord.active) if(alert("This will open Discord in your browser or directly. Are you sure?",, "Yes", "No") == "Yes") - var/url_link = discord_bot.retreive_invite() + var/url_link = SSdiscord.retreive_invite() if (url_link) send_link(src, url_link) else