Skip to content

Commit a3960c9

Browse files
committed
Update TGS DMAPI
1 parent e6fb67f commit a3960c9

16 files changed

+417
-101
lines changed

code/__DEFINES/tgs.dm

+153-34
Large diffs are not rendered by default.

code/modules/tgs/LICENSE

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
The MIT License
22

3-
Copyright (c) 2017-2023 Jordan Brown
3+
Copyright (c) 2017-2024 Jordan Brown
44

55
Permission is hereby granted, free of charge,
66
to any person obtaining a copy of this software and

code/modules/tgs/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# DMAPI Internals
22

3-
This folder should be placed on it's own inside a codebase that wishes to use the TGS DMAPI. Warranty void if modified.
3+
This folder should be placed on its own inside a codebase that wishes to use the TGS DMAPI. Warranty void if modified.
44

55
- [includes.dm](./includes.dm) is the file that should be included by DM code, it handles including the rest.
66
- The [core](./core) folder includes all code not directly part of any API version.

code/modules/tgs/core/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
This folder contains all DMAPI code not directly involved in an API.
44

55
- [_definitions.dm](./definitions.dm) contains defines needed across DMAPI internals.
6+
- [byond_world_export.dm](./byond_world_export.dm) contains the default `/datum/tgs_http_handler` implementation which uses `world.Export()`.
67
- [core.dm](./core.dm) contains the implementations of the `/world/proc/TgsXXX()` procs. Many map directly to the `/datum/tgs_api` functions. It also contains the /datum selection and setup code.
78
- [datum.dm](./datum.dm) contains the `/datum/tgs_api` declarations that all APIs must implement.
89
- [tgs_version.dm](./tgs_version.dm) contains the `/datum/tgs_version` definition
9-
-
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/datum/tgs_http_handler/byond_world_export
2+
3+
/datum/tgs_http_handler/byond_world_export/PerformGet(url)
4+
// This is an infinite sleep until we get a response
5+
var/export_response = world.Export(url)
6+
TGS_DEBUG_LOG("byond_world_export: Export complete")
7+
8+
if(!export_response)
9+
TGS_ERROR_LOG("byond_world_export: Failed request: [url]")
10+
return new /datum/tgs_http_result(null, FALSE)
11+
12+
var/content = export_response["CONTENT"]
13+
if(!content)
14+
TGS_ERROR_LOG("byond_world_export: Failed request, missing content!")
15+
return new /datum/tgs_http_result(null, FALSE)
16+
17+
var/response_json = TGS_FILE2TEXT_NATIVE(content)
18+
if(!response_json)
19+
TGS_ERROR_LOG("byond_world_export: Failed request, failed to load content!")
20+
return new /datum/tgs_http_result(null, FALSE)
21+
22+
return new /datum/tgs_http_result(response_json, TRUE)

code/modules/tgs/core/core.dm

+28-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/world/TgsNew(datum/tgs_event_handler/event_handler, minimum_required_security_level = TGS_SECURITY_ULTRASAFE)
1+
/world/TgsNew(datum/tgs_event_handler/event_handler, minimum_required_security_level = TGS_SECURITY_ULTRASAFE, datum/tgs_http_handler/http_handler = null)
22
var/current_api = TGS_READ_GLOBAL(tgs)
33
if(current_api)
44
TGS_ERROR_LOG("API datum already set (\ref[current_api] ([current_api]))! Was TgsNew() called more than once?")
@@ -42,11 +42,11 @@
4242

4343
var/datum/tgs_version/max_api_version = TgsMaximumApiVersion();
4444
if(version.suite != null && version.minor != null && version.patch != null && version.deprecated_patch != null && version.deprefixed_parameter > max_api_version.deprefixed_parameter)
45-
TGS_ERROR_LOG("Detected unknown API version! Defaulting to latest. Update the DMAPI to fix this problem.")
45+
TGS_ERROR_LOG("Detected unknown Interop API version! Defaulting to latest. Update the DMAPI to fix this problem.")
4646
api_datum = /datum/tgs_api/latest
4747

4848
if(!api_datum)
49-
TGS_ERROR_LOG("Found unsupported API version: [raw_parameter]. If this is a valid version please report this, backporting is done on demand.")
49+
TGS_ERROR_LOG("Found unsupported Interop API version: [raw_parameter]. If this is a valid version please report this, backporting is done on demand.")
5050
return
5151

5252
TGS_INFO_LOG("Activating API for version [version.deprefixed_parameter]")
@@ -55,7 +55,10 @@
5555
TGS_ERROR_LOG("Invalid parameter for event_handler: [event_handler]")
5656
event_handler = null
5757

58-
var/datum/tgs_api/new_api = new api_datum(event_handler, version)
58+
if(!http_handler)
59+
http_handler = new /datum/tgs_http_handler/byond_world_export
60+
61+
var/datum/tgs_api/new_api = new api_datum(event_handler, version, http_handler)
5962

6063
TGS_WRITE_GLOBAL(tgs, new_api)
6164

@@ -107,6 +110,13 @@
107110
if(api)
108111
return api.ApiVersion()
109112

113+
/world/TgsEngine()
114+
#ifdef OPENDREAM
115+
return TGS_ENGINE_TYPE_OPENDREAM
116+
#else
117+
return TGS_ENGINE_TYPE_BYOND
118+
#endif
119+
110120
/world/TgsInstanceName()
111121
var/datum/tgs_api/api = TGS_READ_GLOBAL(tgs)
112122
if(api)
@@ -153,4 +163,17 @@
153163
/world/TgsSecurityLevel()
154164
var/datum/tgs_api/api = TGS_READ_GLOBAL(tgs)
155165
if(api)
156-
api.SecurityLevel()
166+
return api.SecurityLevel()
167+
168+
/world/TgsVisibility()
169+
var/datum/tgs_api/api = TGS_READ_GLOBAL(tgs)
170+
if(api)
171+
return api.Visibility()
172+
173+
/world/TgsTriggerEvent(event_name, list/parameters, wait_for_completion = FALSE)
174+
var/datum/tgs_api/api = TGS_READ_GLOBAL(tgs)
175+
if(api)
176+
if(!istype(parameters, /list))
177+
parameters = list()
178+
179+
return api.TriggerEvent(event_name, parameters, wait_for_completion)

code/modules/tgs/core/datum.dm

+17-2
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,20 @@ TGS_DEFINE_AND_SET_GLOBAL(tgs, null)
66

77
var/list/warned_deprecated_command_runs
88

9-
/datum/tgs_api/New(datum/tgs_event_handler/event_handler, datum/tgs_version/version)
10-
. = ..()
9+
/datum/tgs_api/New(datum/tgs_event_handler/event_handler, datum/tgs_version/version, datum/tgs_http_handler/http_handler)
10+
..()
1111
src.event_handler = event_handler
1212
src.version = version
1313

14+
/datum/tgs_api/proc/TerminateWorld()
15+
while(TRUE)
16+
TGS_DEBUG_LOG("About to terminate world. Tick: [world.time], sleep_offline: [world.sleep_offline]")
17+
world.sleep_offline = FALSE // https://www.byond.com/forum/post/2894866
18+
del(world)
19+
world.sleep_offline = FALSE // just in case, this is BYOND after all...
20+
sleep(world.tick_lag)
21+
TGS_DEBUG_LOG("BYOND DIDN'T TERMINATE THE WORLD!!! TICK IS: [world.time], sleep_offline: [world.sleep_offline]")
22+
1423
/datum/tgs_api/latest
1524
parent_type = /datum/tgs_api/v5
1625

@@ -57,3 +66,9 @@ TGS_PROTECT_DATUM(/datum/tgs_api)
5766

5867
/datum/tgs_api/proc/SecurityLevel()
5968
return TGS_UNIMPLEMENTED
69+
70+
/datum/tgs_api/proc/Visibility()
71+
return TGS_UNIMPLEMENTED
72+
73+
/datum/tgs_api/proc/TriggerEvent(event_name, list/parameters, wait_for_completion)
74+
return FALSE

code/modules/tgs/core/tgs_version.dm

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/datum/tgs_version/New(raw_parameter)
2+
..()
23
src.raw_parameter = raw_parameter
34
deprefixed_parameter = replacetext(raw_parameter, "/tg/station 13 Server v", "")
45
var/list/version_bits = splittext(deprefixed_parameter, ".")

code/modules/tgs/includes.dm

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "core\_definitions.dm"
2+
#include "core\byond_world_export.dm"
23
#include "core\core.dm"
34
#include "core\datum.dm"
45
#include "core\tgs_version.dm"

code/modules/tgs/v4/api.dm

+8-8
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
if(cached_json["apiValidateOnly"])
7474
TGS_INFO_LOG("Validating API and exiting...")
7575
Export(TGS4_COMM_VALIDATE, list(TGS4_PARAMETER_DATA = "[minimum_required_security_level]"))
76-
del(world)
76+
TerminateWorld()
7777

7878
security_level = cached_json["securityLevel"]
7979
chat_channels_json_path = cached_json["chatChannelsJson"]
@@ -181,43 +181,43 @@
181181
var/json = json_encode(data)
182182

183183
while(requesting_new_port && !override_requesting_new_port)
184-
sleep(1)
184+
sleep(world.tick_lag)
185185

186186
//we need some port open at this point to facilitate return communication
187187
if(!world.port)
188188
requesting_new_port = TRUE
189189
if(!world.OpenPort(0)) //open any port
190190
TGS_ERROR_LOG("Unable to open random port to retrieve new port![TGS4_PORT_CRITFAIL_MESSAGE]")
191-
del(world)
191+
TerminateWorld()
192192

193193
//request a new port
194194
export_lock = FALSE
195195
var/list/new_port_json = Export(TGS4_COMM_NEW_PORT, list(TGS4_PARAMETER_DATA = "[world.port]"), TRUE) //stringify this on purpose
196196

197197
if(!new_port_json)
198198
TGS_ERROR_LOG("No new port response from server![TGS4_PORT_CRITFAIL_MESSAGE]")
199-
del(world)
199+
TerminateWorld()
200200

201201
var/new_port = new_port_json[TGS4_PARAMETER_DATA]
202202
if(!isnum(new_port) || new_port <= 0)
203203
TGS_ERROR_LOG("Malformed new port json ([json_encode(new_port_json)])![TGS4_PORT_CRITFAIL_MESSAGE]")
204-
del(world)
204+
TerminateWorld()
205205

206206
if(new_port != world.port && !world.OpenPort(new_port))
207207
TGS_ERROR_LOG("Unable to open port [new_port]![TGS4_PORT_CRITFAIL_MESSAGE]")
208-
del(world)
208+
TerminateWorld()
209209
requesting_new_port = FALSE
210210

211211
while(export_lock)
212-
sleep(1)
212+
sleep(world.tick_lag)
213213
export_lock = TRUE
214214

215215
last_interop_response = null
216216
fdel(server_commands_json_path)
217217
text2file(json, server_commands_json_path)
218218

219219
for(var/I = 0; I < EXPORT_TIMEOUT_DS && !last_interop_response; ++I)
220-
sleep(1)
220+
sleep(world.tick_lag)
221221

222222
if(!last_interop_response)
223223
TGS_ERROR_LOG("Failed to get export result for: [json]")
+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
"5.6.1"
1+
"5.10.0"

code/modules/tgs/v5/_defines.dm

+14-1
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,17 @@
88
#define DMAPI5_TOPIC_REQUEST_LIMIT 65528
99
#define DMAPI5_TOPIC_RESPONSE_LIMIT 65529
1010

11-
#define DMAPI5_BRIDGE_COMMAND_PORT_UPDATE 0
1211
#define DMAPI5_BRIDGE_COMMAND_STARTUP 1
1312
#define DMAPI5_BRIDGE_COMMAND_PRIME 2
1413
#define DMAPI5_BRIDGE_COMMAND_REBOOT 3
1514
#define DMAPI5_BRIDGE_COMMAND_KILL 4
1615
#define DMAPI5_BRIDGE_COMMAND_CHAT_SEND 5
1716
#define DMAPI5_BRIDGE_COMMAND_CHUNK 6
17+
#define DMAPI5_BRIDGE_COMMAND_EVENT 7
1818

1919
#define DMAPI5_PARAMETER_ACCESS_IDENTIFIER "accessIdentifier"
2020
#define DMAPI5_PARAMETER_CUSTOM_COMMANDS "customCommands"
21+
#define DMAPI5_PARAMETER_TOPIC_PORT "topicPort"
2122

2223
#define DMAPI5_CHUNK "chunk"
2324
#define DMAPI5_CHUNK_PAYLOAD "payload"
@@ -34,6 +35,7 @@
3435
#define DMAPI5_BRIDGE_PARAMETER_VERSION "version"
3536
#define DMAPI5_BRIDGE_PARAMETER_CHAT_MESSAGE "chatMessage"
3637
#define DMAPI5_BRIDGE_PARAMETER_MINIMUM_SECURITY_LEVEL "minimumSecurityLevel"
38+
#define DMAPI5_BRIDGE_PARAMETER_EVENT_INVOCATION "eventInvocation"
3739

3840
#define DMAPI5_BRIDGE_RESPONSE_NEW_PORT "newPort"
3941
#define DMAPI5_BRIDGE_RESPONSE_RUNTIME_INFORMATION "runtimeInformation"
@@ -48,6 +50,7 @@
4850
#define DMAPI5_RUNTIME_INFORMATION_REVISION "revision"
4951
#define DMAPI5_RUNTIME_INFORMATION_TEST_MERGES "testMerges"
5052
#define DMAPI5_RUNTIME_INFORMATION_SECURITY_LEVEL "securityLevel"
53+
#define DMAPI5_RUNTIME_INFORMATION_VISIBILITY "visibility"
5154

5255
#define DMAPI5_CHAT_UPDATE_CHANNELS "channels"
5356

@@ -79,6 +82,8 @@
7982
#define DMAPI5_TOPIC_COMMAND_WATCHDOG_REATTACH 8
8083
#define DMAPI5_TOPIC_COMMAND_SEND_CHUNK 9
8184
#define DMAPI5_TOPIC_COMMAND_RECEIVE_CHUNK 10
85+
#define DMAPI5_TOPIC_COMMAND_RECEIVE_BROADCAST 11
86+
#define DMAPI5_TOPIC_COMMAND_COMPLETE_EVENT 12
8287

8388
#define DMAPI5_TOPIC_PARAMETER_COMMAND_TYPE "commandType"
8489
#define DMAPI5_TOPIC_PARAMETER_CHAT_COMMAND "chatCommand"
@@ -88,7 +93,9 @@
8893
#define DMAPI5_TOPIC_PARAMETER_NEW_INSTANCE_NAME "newInstanceName"
8994
#define DMAPI5_TOPIC_PARAMETER_CHAT_UPDATE "chatUpdate"
9095
#define DMAPI5_TOPIC_PARAMETER_NEW_SERVER_VERSION "newServerVersion"
96+
#define DMAPI5_TOPIC_PARAMETER_BROADCAST_MESSAGE "broadcastMessage"
9197

98+
#define DMAPI5_TOPIC_RESPONSE_CLIENT_COUNT "clientCount"
9299
#define DMAPI5_TOPIC_RESPONSE_COMMAND_RESPONSE "commandResponse"
93100
#define DMAPI5_TOPIC_RESPONSE_COMMAND_RESPONSE_MESSAGE "commandResponseMessage"
94101
#define DMAPI5_TOPIC_RESPONSE_CHAT_RESPONSES "chatResponses"
@@ -113,3 +120,9 @@
113120
#define DMAPI5_CUSTOM_CHAT_COMMAND_NAME "name"
114121
#define DMAPI5_CUSTOM_CHAT_COMMAND_HELP_TEXT "helpText"
115122
#define DMAPI5_CUSTOM_CHAT_COMMAND_ADMIN_ONLY "adminOnly"
123+
124+
#define DMAPI5_EVENT_ID "eventId"
125+
126+
#define DMAPI5_EVENT_INVOCATION_NAME "eventName"
127+
#define DMAPI5_EVENT_INVOCATION_PARAMETERS "parameters"
128+
#define DMAPI5_EVENT_INVOCATION_NOTIFY_COMPLETION "notifyCompletion"

0 commit comments

Comments
 (0)