[MIRROR] Automatic TGS DMAPI Update (#26689)

* Automatic TGS DMAPI Update (#81655)

This pull request updates the TGS DMAPI to the latest version. Please
note any changes that may be breaking or unimplemented in your codebase
by checking what changes are in the definitions file:
code/__DEFINES/tgs.dm before merging.

Co-authored-by: tgstation-server <tgstation-server@ users.noreply.github.com>

* Automatic TGS DMAPI Update

---------

Co-authored-by: orange man <61334995+comfyorange@users.noreply.github.com>
Co-authored-by: tgstation-server <tgstation-server@ users.noreply.github.com>
This commit is contained in:
SkyratBot
2024-02-29 22:58:02 +01:00
committed by GitHub
co-authored by tgstation-server orange man
parent 3a0029d61a
commit b0eda383de
10 changed files with 111 additions and 9 deletions
+18 -1
View File
@@ -1,6 +1,6 @@
// tgstation-server DMAPI
#define TGS_DMAPI_VERSION "7.0.2"
#define TGS_DMAPI_VERSION "7.1.1"
// All functions and datums outside this document are subject to change with any version and should not be relied on.
@@ -50,6 +50,13 @@
#endif
#ifndef TGS_FILE2TEXT_NATIVE
#ifdef file2text
#error Your codebase is re-defining the BYOND proc file2text. The DMAPI requires the native version to read the result of world.Export(). You can fix this by adding "#define TGS_FILE2TEXT_NATIVE file2text" before your override of file2text to allow the DMAPI to use the native version. This will only be used for world.Export(), not regular file accesses
#endif
#define TGS_FILE2TEXT_NATIVE file2text
#endif
// EVENT CODES
/// Before a reboot mode change, extras parameters are the current and new reboot mode enums.
@@ -490,6 +497,16 @@
/world/proc/TgsChatChannelInfo()
return
/**
* Trigger an event in TGS. Requires TGS version >= 6.3.0. Returns [TRUE] if the event was triggered successfully, [FALSE] otherwise. This function may sleep!
*
* event_name - The name of the event to trigger
* parameters - Optional list of string parameters to pass as arguments to the event script. The first parameter passed to a script will always be the running game's directory followed by these parameters.
* wait_for_completion - If set, this function will not return until the event has run to completion.
*/
/world/proc/TgsTriggerEvent(event_name, list/parameters, wait_for_completion = FALSE)
return
/*
The MIT License
+8
View File
@@ -166,3 +166,11 @@
var/datum/tgs_api/api = TGS_READ_GLOBAL(tgs)
if(api)
return api.Visibility()
/world/TgsTriggerEvent(event_name, list/parameters, wait_for_completion = FALSE)
var/datum/tgs_api/api = TGS_READ_GLOBAL(tgs)
if(api)
if(!istype(parameters, /list))
parameters = list()
return api.TriggerEvent(event_name, parameters, wait_for_completion)
+4 -1
View File
@@ -17,7 +17,7 @@ TGS_DEFINE_AND_SET_GLOBAL(tgs, null)
world.sleep_offline = FALSE // https://www.byond.com/forum/post/2894866
del(world)
world.sleep_offline = FALSE // just in case, this is BYOND after all...
sleep(1)
sleep(world.tick_lag)
TGS_DEBUG_LOG("BYOND DIDN'T TERMINATE THE WORLD!!! TICK IS: [world.time], sleep_offline: [world.sleep_offline]")
/datum/tgs_api/latest
@@ -69,3 +69,6 @@ TGS_PROTECT_DATUM(/datum/tgs_api)
/datum/tgs_api/proc/Visibility()
return TGS_UNIMPLEMENTED
/datum/tgs_api/proc/TriggerEvent(event_name, list/parameters, wait_for_completion)
return FALSE
+3 -3
View File
@@ -181,7 +181,7 @@
var/json = json_encode(data)
while(requesting_new_port && !override_requesting_new_port)
sleep(1)
sleep(world.tick_lag)
//we need some port open at this point to facilitate return communication
if(!world.port)
@@ -209,7 +209,7 @@
requesting_new_port = FALSE
while(export_lock)
sleep(1)
sleep(world.tick_lag)
export_lock = TRUE
last_interop_response = null
@@ -217,7 +217,7 @@
text2file(json, server_commands_json_path)
for(var/I = 0; I < EXPORT_TIMEOUT_DS && !last_interop_response; ++I)
sleep(1)
sleep(world.tick_lag)
if(!last_interop_response)
TGS_ERROR_LOG("Failed to get export result for: [json]")
+1 -1
View File
@@ -1 +1 @@
"5.8.0"
"5.9.0"
+9
View File
@@ -14,6 +14,7 @@
#define DMAPI5_BRIDGE_COMMAND_KILL 4
#define DMAPI5_BRIDGE_COMMAND_CHAT_SEND 5
#define DMAPI5_BRIDGE_COMMAND_CHUNK 6
#define DMAPI5_BRIDGE_COMMAND_EVENT 7
#define DMAPI5_PARAMETER_ACCESS_IDENTIFIER "accessIdentifier"
#define DMAPI5_PARAMETER_CUSTOM_COMMANDS "customCommands"
@@ -34,6 +35,7 @@
#define DMAPI5_BRIDGE_PARAMETER_VERSION "version"
#define DMAPI5_BRIDGE_PARAMETER_CHAT_MESSAGE "chatMessage"
#define DMAPI5_BRIDGE_PARAMETER_MINIMUM_SECURITY_LEVEL "minimumSecurityLevel"
#define DMAPI5_BRIDGE_PARAMETER_EVENT_INVOCATION "eventInvocation"
#define DMAPI5_BRIDGE_RESPONSE_NEW_PORT "newPort"
#define DMAPI5_BRIDGE_RESPONSE_RUNTIME_INFORMATION "runtimeInformation"
@@ -81,6 +83,7 @@
#define DMAPI5_TOPIC_COMMAND_SEND_CHUNK 9
#define DMAPI5_TOPIC_COMMAND_RECEIVE_CHUNK 10
#define DMAPI5_TOPIC_COMMAND_RECEIVE_BROADCAST 11
#define DMAPI5_TOPIC_COMMAND_COMPLETE_EVENT 12
#define DMAPI5_TOPIC_PARAMETER_COMMAND_TYPE "commandType"
#define DMAPI5_TOPIC_PARAMETER_CHAT_COMMAND "chatCommand"
@@ -116,3 +119,9 @@
#define DMAPI5_CUSTOM_CHAT_COMMAND_NAME "name"
#define DMAPI5_CUSTOM_CHAT_COMMAND_HELP_TEXT "helpText"
#define DMAPI5_CUSTOM_CHAT_COMMAND_ADMIN_ONLY "adminOnly"
#define DMAPI5_EVENT_ID "eventId"
#define DMAPI5_EVENT_INVOCATION_NAME "eventName"
#define DMAPI5_EVENT_INVOCATION_PARAMETERS "parameters"
#define DMAPI5_EVENT_INVOCATION_NOTIFY_COMPLETION "notifyCompletion"
+41 -1
View File
@@ -27,6 +27,8 @@
var/chunked_requests = 0
var/list/chunked_topics = list()
var/list/pending_events = list()
var/detached = FALSE
/datum/tgs_api/v5/New()
@@ -46,6 +48,10 @@
var/datum/tgs_version/api_version = ApiVersion()
version = null // we want this to be the TGS version, not the interop version
// sleep once to prevent an issue where world.Export on the first tick can hang indefinitely
sleep(world.tick_lag)
var/list/bridge_response = Bridge(DMAPI5_BRIDGE_COMMAND_STARTUP, list(DMAPI5_BRIDGE_PARAMETER_MINIMUM_SECURITY_LEVEL = minimum_required_security_level, DMAPI5_BRIDGE_PARAMETER_VERSION = api_version.raw_parameter, DMAPI5_PARAMETER_CUSTOM_COMMANDS = ListCustomCommands(), DMAPI5_PARAMETER_TOPIC_PORT = GetTopicPort()))
if(!istype(bridge_response))
TGS_ERROR_LOG("Failed initial bridge request!")
@@ -125,7 +131,7 @@
TGS_DEBUG_LOG("RequireInitialBridgeResponse: Starting sleep")
logged = TRUE
sleep(1)
sleep(world.tick_lag)
TGS_DEBUG_LOG("RequireInitialBridgeResponse: Passed")
@@ -249,6 +255,40 @@
WaitForReattach(TRUE)
return chat_channels.Copy()
/datum/tgs_api/v5/TriggerEvent(event_name, list/parameters, wait_for_completion)
RequireInitialBridgeResponse()
WaitForReattach(TRUE)
if(interop_version.minor < 9)
TGS_WARNING_LOG("Interop version too low for custom events!")
return FALSE
var/str_parameters = list()
for(var/i in parameters)
str_parameters += "[i]"
var/list/response = Bridge(DMAPI5_BRIDGE_COMMAND_EVENT, list(DMAPI5_BRIDGE_PARAMETER_EVENT_INVOCATION = list(DMAPI5_EVENT_INVOCATION_NAME = event_name, DMAPI5_EVENT_INVOCATION_PARAMETERS = str_parameters, DMAPI5_EVENT_INVOCATION_NOTIFY_COMPLETION = wait_for_completion)))
if(!response)
return FALSE
var/event_id = response[DMAPI5_EVENT_ID]
if(!event_id)
return FALSE
TGS_DEBUG_LOG("Created event ID: [event_id]")
if(!wait_for_completion)
return TRUE
TGS_DEBUG_LOG("Waiting for completion of event ID: [event_id]")
while(!pending_events[event_id])
sleep(world.tick_lag)
TGS_DEBUG_LOG("Completed wait on event ID: [event_id]")
pending_events -= event_id
return TRUE
/datum/tgs_api/v5/proc/DecodeChannels(chat_update_json)
TGS_DEBUG_LOG("DecodeChannels()")
var/list/chat_channels_json = chat_update_json[DMAPI5_CHAT_UPDATE_CHANNELS]
+5 -2
View File
@@ -65,7 +65,7 @@
if(detached)
// Wait up to one minute
for(var/i in 1 to 600)
sleep(1)
sleep(world.tick_lag)
if(!detached && (!require_channels || length(chat_channels)))
break
@@ -77,8 +77,11 @@
/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
@@ -88,7 +91,7 @@
TGS_ERROR_LOG("Failed bridge request, missing content!")
return
var/response_json = file2text(content)
var/response_json = TGS_FILE2TEXT_NATIVE(content)
if(!response_json)
TGS_ERROR_LOG("Failed bridge request, failed to load content!")
return
+13
View File
@@ -176,6 +176,10 @@
var/list/reattach_response = TopicResponse(error_message)
reattach_response[DMAPI5_PARAMETER_CUSTOM_COMMANDS] = ListCustomCommands()
reattach_response[DMAPI5_PARAMETER_TOPIC_PORT] = GetTopicPort()
for(var/eventId in pending_events)
pending_events[eventId] = TRUE
return reattach_response
if(DMAPI5_TOPIC_COMMAND_SEND_CHUNK)
@@ -276,6 +280,15 @@
TGS_WORLD_ANNOUNCE(message)
return TopicResponse()
if(DMAPI5_TOPIC_COMMAND_COMPLETE_EVENT)
var/event_id = topic_parameters[DMAPI5_EVENT_ID]
if (!istext(event_id))
return TopicResponse("Invalid or missing [DMAPI5_EVENT_ID]")
TGS_DEBUG_LOG("Completing event ID [event_id]...")
pending_events[event_id] = TRUE
return TopicResponse()
return TopicResponse("Unknown command: [command]")
/datum/tgs_api/v5/proc/WorldBroadcast(message)
+9
View File
@@ -14,6 +14,7 @@
#undef DMAPI5_BRIDGE_COMMAND_KILL
#undef DMAPI5_BRIDGE_COMMAND_CHAT_SEND
#undef DMAPI5_BRIDGE_COMMAND_CHUNK
#undef DMAPI5_BRIDGE_COMMAND_EVENT
#undef DMAPI5_PARAMETER_ACCESS_IDENTIFIER
#undef DMAPI5_PARAMETER_CUSTOM_COMMANDS
@@ -34,6 +35,7 @@
#undef DMAPI5_BRIDGE_PARAMETER_VERSION
#undef DMAPI5_BRIDGE_PARAMETER_CHAT_MESSAGE
#undef DMAPI5_BRIDGE_PARAMETER_MINIMUM_SECURITY_LEVEL
#undef DMAPI5_BRIDGE_PARAMETER_EVENT_INVOCATION
#undef DMAPI5_BRIDGE_RESPONSE_NEW_PORT
#undef DMAPI5_BRIDGE_RESPONSE_RUNTIME_INFORMATION
@@ -81,6 +83,7 @@
#undef DMAPI5_TOPIC_COMMAND_SEND_CHUNK
#undef DMAPI5_TOPIC_COMMAND_RECEIVE_CHUNK
#undef DMAPI5_TOPIC_COMMAND_RECEIVE_BROADCAST
#undef DMAPI5_TOPIC_COMMAND_COMPLETE_EVENT
#undef DMAPI5_TOPIC_PARAMETER_COMMAND_TYPE
#undef DMAPI5_TOPIC_PARAMETER_CHAT_COMMAND
@@ -116,3 +119,9 @@
#undef DMAPI5_CUSTOM_CHAT_COMMAND_NAME
#undef DMAPI5_CUSTOM_CHAT_COMMAND_HELP_TEXT
#undef DMAPI5_CUSTOM_CHAT_COMMAND_ADMIN_ONLY
#undef DMAPI5_EVENT_ID
#undef DMAPI5_EVENT_INVOCATION_NAME
#undef DMAPI5_EVENT_INVOCATION_PARAMETERS
#undef DMAPI5_EVENT_INVOCATION_NOTIFY_COMPLETION