Files
Yogstation/code/modules/tgs/v5/bridge.dm
2024-03-16 15:35:58 -04:00

110 lines
3.2 KiB
Plaintext

/datum/tgs_api/v5/proc/Bridge(command, list/data)
if(!data)
data = list()
var/single_bridge_request = CreateBridgeRequest(command, data)
if(length(single_bridge_request) <= DMAPI5_BRIDGE_REQUEST_LIMIT)
return PerformBridgeRequest(single_bridge_request)
// chunking required
var/payload_id = ++chunked_requests
var/raw_data = CreateBridgeData(command, data, FALSE)
var/list/chunk_requests = GenerateChunks(raw_data, TRUE)
var/list/response
for(var/bridge_request in chunk_requests)
response = PerformBridgeRequest(bridge_request)
if(!response)
// Abort
return
var/list/missing_sequence_ids = response[DMAPI5_MISSING_CHUNKS]
if(length(missing_sequence_ids))
do
TGS_WARNING_LOG("Server is still missing some chunks of bridge P[payload_id]! Sending missing chunks...")
if(!istype(missing_sequence_ids))
TGS_ERROR_LOG("Did not receive a list() for [DMAPI5_MISSING_CHUNKS]!")
return
for(var/missing_sequence_id in missing_sequence_ids)
if(!isnum(missing_sequence_id))
TGS_ERROR_LOG("Did not receive a num in [DMAPI5_MISSING_CHUNKS]!")
return
var/missing_chunk_request = chunk_requests[missing_sequence_id + 1]
response = PerformBridgeRequest(missing_chunk_request)
if(!response)
// Abort
return
missing_sequence_ids = response[DMAPI5_MISSING_CHUNKS]
while(length(missing_sequence_ids))
return response
/datum/tgs_api/v5/proc/CreateBridgeRequest(command, list/data)
var/json = CreateBridgeData(command, data, TRUE)
var/encoded_json = url_encode(json)
var/api_prefix = interop_version.minor >= 8 ? "api/" : ""
var/url = "http://127.0.0.1:[server_port]/[api_prefix]Bridge?[DMAPI5_BRIDGE_DATA]=[encoded_json]"
return url
/datum/tgs_api/v5/proc/CreateBridgeData(command, list/data, needs_auth)
data[DMAPI5_BRIDGE_PARAMETER_COMMAND_TYPE] = command
if(needs_auth)
data[DMAPI5_PARAMETER_ACCESS_IDENTIFIER] = access_identifier
var/json = json_encode(data)
return json
/datum/tgs_api/v5/proc/WaitForReattach(require_channels = FALSE)
if(detached)
// Wait up to one minute
for(var/i in 1 to 600)
sleep(world.tick_lag)
if(!detached && (!require_channels || length(chat_channels)))
break
// dad went out for milk and cigarettes 20 years ago...
// yes, this affects all other waiters, intentional
if(i == 600)
detached = FALSE
/datum/tgs_api/v5/proc/PerformBridgeRequest(bridge_request)
WaitForReattach(FALSE)
TGS_DEBUG_LOG("Bridge request start")
// This is an infinite sleep until we get a response
var/export_response = world.Export(bridge_request)
TGS_DEBUG_LOG("Bridge request complete")
if(!export_response)
TGS_ERROR_LOG("Failed bridge request: [bridge_request]")
return
var/content = export_response["CONTENT"]
if(!content)
TGS_ERROR_LOG("Failed bridge request, missing content!")
return
var/response_json = TGS_FILE2TEXT_NATIVE(content)
if(!response_json)
TGS_ERROR_LOG("Failed bridge request, failed to load content!")
return
var/list/bridge_response = json_decode(response_json)
if(!bridge_response)
TGS_ERROR_LOG("Failed bridge request, bad json: [response_json]")
return
var/error = bridge_response[DMAPI5_RESPONSE_ERROR_MESSAGE]
if(error)
TGS_ERROR_LOG("Failed bridge request, bad request: [error]")
return
return bridge_response