forked from ParadiseSS13/Paradise
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
SShttp + SSdiscord | ASYNCHRONOUS STUFF IN BYOND! (ParadiseSS13#14762)
* SShttp + SSdiscord | ASYNCHRONOUS STUFF IN BYOND! * Cleanup * HTTP Callback example * Fixes rust instability * More refactors * This works * The sanitizer (Now worth £3000) * New configs + other stuff * Lets give this a shot * Farie changes * Mentor support * Farie fixes
- Loading branch information
1 parent
dbe4e00
commit 56752b0
Showing
29 changed files
with
652 additions
and
213 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
SUBSYSTEM_DEF(discord) | ||
name = "Discord" | ||
flags = SS_NO_FIRE | ||
/// Is the SS enabled | ||
var/enabled = FALSE | ||
/// Last time the administrator ping was dropped. This ensures administrators cannot be mass pinged if a large chunk of ahelps go off at once (IE: tesloose) | ||
var/last_administration_ping = 0 | ||
|
||
/datum/controller/subsystem/discord/Initialize(start_timeofday) | ||
if(config.discord_webhooks_enabled) | ||
enabled = TRUE | ||
return ..() | ||
|
||
// This is designed for ease of simplicity for sending quick messages from parts of the code | ||
/datum/controller/subsystem/discord/proc/send2discord_simple(destination, content) | ||
if(!enabled) | ||
return | ||
var/webhook_url | ||
switch(destination) | ||
if(DISCORD_WEBHOOK_ADMIN) | ||
webhook_url = config.discord_admin_webhook_url | ||
if(DISCORD_WEBHOOK_PRIMARY) | ||
webhook_url = config.discord_main_webhook_url | ||
if(DISCORD_WEBHOOK_MENTOR) | ||
webhook_url = config.discord_mentor_webhook_url | ||
|
||
var/datum/discord_webhook_payload/dwp = new() | ||
dwp.webhook_content = content | ||
SShttp.create_async_request(RUSTG_HTTP_METHOD_POST, webhook_url, dwp.serialize2json(), list("content-type" = "application/json")) | ||
|
||
// This one is designed to take in a [/datum/discord_webhook_payload] which was prepared beforehand | ||
/datum/controller/subsystem/discord/proc/send2discord_complex(destination, datum/discord_webhook_payload/dwp) | ||
if(!enabled) | ||
return | ||
var/webhook_url | ||
switch(destination) | ||
if(DISCORD_WEBHOOK_ADMIN) | ||
webhook_url = config.discord_admin_webhook_url | ||
if(DISCORD_WEBHOOK_PRIMARY) | ||
webhook_url = config.discord_main_webhook_url | ||
SShttp.create_async_request(RUSTG_HTTP_METHOD_POST, webhook_url, dwp.serialize2json(), list("content-type" = "application/json")) | ||
|
||
// This one is for sending messages to the admin channel if no admins are active, complete with a ping to the game admins role | ||
/datum/controller/subsystem/discord/proc/send2discord_simple_noadmins(content, check_send_always = FALSE) | ||
// Setup some stuff | ||
var/alerttext | ||
var/list/admincounter = staff_countup(R_BAN) | ||
var/active_admins = admincounter[1] | ||
var/inactive_admins = admincounter[3] | ||
var/add_ping = TRUE | ||
|
||
if(active_admins <= 0) | ||
if(inactive_admins > 0) | ||
alerttext = " | **ALL ADMINS AFK**" | ||
else | ||
alerttext = " | **NO ADMINS ONLINE**" | ||
else | ||
if(check_send_always && config.discord_forward_all_ahelps) | ||
// If we are here, there are admins online. We want to forward everything, but obviously dont want to add a ping, so we do this | ||
add_ping = FALSE | ||
else | ||
// We have active admins, we dont care about the rest of this proc | ||
return | ||
|
||
var/message = "[content] [alerttext] [add_ping ? handle_administrator_ping() : ""]" | ||
|
||
var/datum/discord_webhook_payload/dwp = new() | ||
dwp.webhook_content = message | ||
|
||
SShttp.create_async_request(RUSTG_HTTP_METHOD_POST, config.discord_admin_webhook_url, dwp.serialize2json(), list("content-type" = "application/json")) | ||
|
||
// Helper to make administrator ping easier | ||
/datum/controller/subsystem/discord/proc/handle_administrator_ping() | ||
// Check if a role is even set | ||
if(config.discord_admin_role_id) | ||
if(last_administration_ping > world.time) | ||
return "*(Role pinged recently)*" | ||
|
||
last_administration_ping = world.time + 60 SECONDS | ||
return "<@&[config.discord_admin_role_id]>" | ||
|
||
return "*(Role not configured)*" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
SUBSYSTEM_DEF(http) | ||
name = "HTTP" | ||
flags = SS_TICKER | SS_BACKGROUND // Measure in ticks, but also only run if we have the spare CPU. We also dont init. | ||
wait = 1 | ||
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY // All the time | ||
// Assuming for the worst, since only discord is hooked into this for now, but that may change | ||
offline_implications = "The server is no longer capable of making async HTTP requests. Shuttle call recommended." | ||
/// List of all async HTTP requests in the processing chain | ||
var/list/datum/http_request/active_async_requests | ||
/// Variable to define if logging is enabled or not. Disabled by default since we know the requests the server is making. Enable with VV if you need to debug requests | ||
var/logging_enabled = FALSE | ||
|
||
/datum/controller/subsystem/http/Initialize(start_timeofday) | ||
rustg_create_async_http_client() // Open the door | ||
active_async_requests = list() | ||
return ..() | ||
|
||
/datum/controller/subsystem/http/fire(resumed) | ||
for(var/r in active_async_requests) | ||
var/datum/http_request/req = r | ||
// Check if we are complete | ||
if(req.is_complete()) | ||
// If so, take it out the processing list | ||
active_async_requests -= req | ||
var/datum/http_response/res = req.into_response() | ||
|
||
// If the request has a callback, invoke it.Async of course to avoid choking the SS | ||
if(req.cb) | ||
req.cb.InvokeAsync(res) | ||
|
||
// And log the result | ||
if(logging_enabled) | ||
var/list/log_data = list() | ||
log_data += "BEGIN ASYNC RESPONSE (ID: [req.id])" | ||
if(res.errored) | ||
log_data += "\t ----- RESPONSE ERRROR -----" | ||
log_data += "\t [res.error]" | ||
else | ||
log_data += "\tResponse status code: [res.status_code]" | ||
log_data += "\tResponse body: [res.body]" | ||
log_data += "\tResponse headers: [json_encode(res.headers)]" | ||
log_data += "END ASYNC RESPONSE (ID: [req.id])" | ||
rustg_log_write(GLOB.http_log, log_data.Join("\n[GLOB.log_end]")) | ||
|
||
/** | ||
* Async request creator | ||
* | ||
* Generates an async request, and adds it to the subsystem's processing list | ||
* These should be used as they do not lock the entire DD process up as they execute inside their own thread pool inside RUSTG | ||
*/ | ||
/datum/controller/subsystem/http/proc/create_async_request(method, url, body = "", list/headers, datum/callback/proc_callback) | ||
var/datum/http_request/req = new() | ||
req.prepare(method, url, body, headers) | ||
if(proc_callback) | ||
req.cb = proc_callback | ||
|
||
// Begin it and add it to the SS active list | ||
req.begin_async() | ||
active_async_requests += req | ||
|
||
if(logging_enabled) | ||
// Create a log holder | ||
var/list/log_data = list() | ||
log_data += "BEGIN ASYNC REQUEST (ID: [req.id])" | ||
log_data += "\t[uppertext(req.method)] [req.url]" | ||
log_data += "\tRequest body: [req.body]" | ||
log_data += "\tRequest headers: [req.headers]" | ||
log_data += "END ASYNC REQUEST (ID: [req.id])" | ||
|
||
// Write the log data | ||
rustg_log_write(GLOB.http_log, log_data.Join("\n[GLOB.log_end]")) | ||
|
||
/** | ||
* Blocking request creator | ||
* | ||
* Generates a blocking request, executes it, logs the info then cleanly returns the response | ||
* Exists as a proof of concept, and should never be used | ||
*/ | ||
/datum/controller/subsystem/http/proc/make_blocking_request(method, url, body = "", list/headers) | ||
CRASH("Attempted use of a blocking HTTP request") | ||
/* | ||
var/datum/http_request/req = new() | ||
req.prepare(method, url, body, headers) | ||
req.execute_blocking() | ||
var/datum/http_response/res = req.into_response() | ||
// Now generate a logfile | ||
var/list/log_data = list() | ||
log_data += "NEW BLOCKING REQUEST" | ||
log_data += "\t[uppertext(req.method)] [req.url]" | ||
log_data += "\tRequest body: [req.body]" | ||
log_data += "\tRequest headers: [req.headers]" | ||
if(res.errored) | ||
log_data += "\t ----- RESPONSE ERRROR -----" | ||
log_data += "\t [res.error]" | ||
else | ||
log_data += "\tResponse status code: [res.status_code]" | ||
log_data += "\tResponse body: [res.body]" | ||
log_data += "\tResponse headers: [json_encode(res.headers)]" | ||
log_data += "END BLOCKING REQUEST" | ||
// Write the log data | ||
rustg_log_write(GLOB.http_log, log_data.Join("\n[GLOB.log_end]")) | ||
return res | ||
*/ | ||
|
||
/* | ||
Example of how to use callbacks properly | ||
/client/verb/testing() | ||
set name = "Testing" | ||
var/datum/callback/cb = CALLBACK(src, /client/.proc/response, usr) | ||
SShttp.create_async_request(RUSTG_HTTP_METHOD_GET, "http://site.domain/page.html", proc_callback=cb) | ||
/client/proc/response(mob/user, datum/http_response/response) | ||
to_chat(user, "<span class='notice'>Code: [response.status_code] | Content: [response.body]") | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.