Skip to content

Commit

Permalink
Automatic TGS DMAPI Update (#3896)
Browse files Browse the repository at this point in the history
This pull request updates the TGS DMAPI to the latest version. Please
note any breaking or unimplemented changes before merging.

Co-authored-by: tgstation-server <[email protected]>
  • Loading branch information
cm13-github and tgstation-server authored Jul 18, 2023
1 parent c33e4b0 commit c65248b
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 51 deletions.
2 changes: 1 addition & 1 deletion code/__DEFINES/tgs.dm
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// tgstation-server DMAPI

#define TGS_DMAPI_VERSION "6.5.0"
#define TGS_DMAPI_VERSION "6.5.2"

// All functions and datums outside this document are subject to change with any version and should not be relied on.

Expand Down
8 changes: 8 additions & 0 deletions code/modules/tgs/core/_definitions.dm
Original file line number Diff line number Diff line change
@@ -1,2 +1,10 @@
#if DM_VERSION < 510
#error The TGS DMAPI does not support BYOND versions < 510!
#endif

#define TGS_UNIMPLEMENTED "___unimplemented"
#define TGS_VERSION_PARAMETER "server_service_version"

#ifndef TGS_DEBUG_LOG
#define TGS_DEBUG_LOG(message)
#endif
4 changes: 2 additions & 2 deletions code/modules/tgs/v3210/commands.dm
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,12 @@
user.friendly_name = sender

// Discord hack, fix the mention if it's only numbers (fuck you IRC trolls)
var/regex/discord_id_regex = regex(@"^[0-9]+$")
var/regex/discord_id_regex = regex("^\[0-9\]+$")
if(findtext(sender, discord_id_regex))
sender = "<@[sender]>"

user.mention = sender
var/datum/tgs_message_content/result = stc.Run(user, params)
result = UpgradeDeprecatedCommandResponse(result, command)

return result?.text || TRUE
return result ? result.text : TRUE
2 changes: 1 addition & 1 deletion code/modules/tgs/v4/commands.dm
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,5 @@
var/datum/tgs_message_content/result = sc.Run(u, params)
result = UpgradeDeprecatedCommandResponse(result, command)

return result?.text
return result ? result.text : TRUE
return "Unknown command: [command]!"
4 changes: 2 additions & 2 deletions code/modules/tgs/v5/_defines.dm
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
#define DMAPI5_TOPIC_DATA "tgs_data"

#define DMAPI5_BRIDGE_REQUEST_LIMIT 8198
#define DMAPI5_TOPIC_REQUEST_LIMIT 65529
#define DMAPI5_TOPIC_RESPONSE_LIMIT 65528
#define DMAPI5_TOPIC_REQUEST_LIMIT 65528
#define DMAPI5_TOPIC_RESPONSE_LIMIT 65529

#define DMAPI5_BRIDGE_COMMAND_PORT_UPDATE 0
#define DMAPI5_BRIDGE_COMMAND_STARTUP 1
Expand Down
53 changes: 35 additions & 18 deletions code/modules/tgs/v5/api.dm
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,17 @@

var/detached = FALSE

/datum/tgs_api/v5/New()
. = ..()
TGS_DEBUG_LOG("V5 API created")

/datum/tgs_api/v5/ApiVersion()
return new /datum/tgs_version(
#include "__interop_version.dm"
)

/datum/tgs_api/v5/OnWorldNew(minimum_required_security_level)
TGS_DEBUG_LOG("OnWorldNew()")
server_port = world.params[DMAPI5_PARAM_SERVER_PORT]
access_identifier = world.params[DMAPI5_PARAM_ACCESS_IDENTIFIER]

Expand Down Expand Up @@ -96,17 +101,28 @@
return TRUE

/datum/tgs_api/v5/proc/RequireInitialBridgeResponse()
TGS_DEBUG_LOG("RequireInitialBridgeResponse()")
var/logged = FALSE
while(!version)
if(!logged)
TGS_DEBUG_LOG("RequireInitialBridgeResponse: Starting sleep")
logged = TRUE

sleep(1)

TGS_DEBUG_LOG("RequireInitialBridgeResponse: Passed")

/datum/tgs_api/v5/OnInitializationComplete()
Bridge(DMAPI5_BRIDGE_COMMAND_PRIME)

/datum/tgs_api/v5/OnTopic(T)
TGS_DEBUG_LOG("OnTopic()")
RequireInitialBridgeResponse()
TGS_DEBUG_LOG("OnTopic passed bridge request gate")
var/list/params = params2list(T)
var/json = params[DMAPI5_TOPIC_DATA]
if(!json)
TGS_DEBUG_LOG("No \"[DMAPI5_TOPIC_DATA]\" entry found, ignoring...")
return FALSE // continue to /world/Topic

if(!initialized)
Expand Down Expand Up @@ -156,7 +172,7 @@
TGS_WARNING_LOG("Received legacy string when a [/datum/tgs_message_content] was expected. Please audit all calls to TgsChatBroadcast, TgsChatTargetedBroadcast, and TgsChatPrivateMessage to ensure they use the new /datum.")
return new /datum/tgs_message_content(message)

/datum/tgs_api/v5/ChatBroadcast(datum/tgs_message_content/message, list/channels)
/datum/tgs_api/v5/ChatBroadcast(datum/tgs_message_content/message2, list/channels)
if(!length(channels))
channels = ChatChannelInfo()

Expand All @@ -165,52 +181,53 @@
var/datum/tgs_chat_channel/channel = I
ids += channel.id

message = UpgradeDeprecatedChatMessage(message)
message2 = UpgradeDeprecatedChatMessage(message2)

if (!length(channels))
return

message = message._interop_serialize()
message[DMAPI5_CHAT_MESSAGE_CHANNEL_IDS] = ids
var/list/data = message2._interop_serialize()
data[DMAPI5_CHAT_MESSAGE_CHANNEL_IDS] = ids
if(intercepted_message_queue)
intercepted_message_queue += list(message)
intercepted_message_queue += list(data)
else
Bridge(DMAPI5_BRIDGE_COMMAND_CHAT_SEND, list(DMAPI5_BRIDGE_PARAMETER_CHAT_MESSAGE = message))
Bridge(DMAPI5_BRIDGE_COMMAND_CHAT_SEND, list(DMAPI5_BRIDGE_PARAMETER_CHAT_MESSAGE = data))

/datum/tgs_api/v5/ChatTargetedBroadcast(datum/tgs_message_content/message, admin_only)
/datum/tgs_api/v5/ChatTargetedBroadcast(datum/tgs_message_content/message2, admin_only)
var/list/channels = list()
for(var/I in ChatChannelInfo())
var/datum/tgs_chat_channel/channel = I
if (!channel.is_private_channel && ((channel.is_admin_channel && admin_only) || (!channel.is_admin_channel && !admin_only)))
channels += channel.id

message = UpgradeDeprecatedChatMessage(message)
message2 = UpgradeDeprecatedChatMessage(message2)

if (!length(channels))
return

message = message._interop_serialize()
message[DMAPI5_CHAT_MESSAGE_CHANNEL_IDS] = channels
var/list/data = message2._interop_serialize()
data[DMAPI5_CHAT_MESSAGE_CHANNEL_IDS] = channels
if(intercepted_message_queue)
intercepted_message_queue += list(message)
intercepted_message_queue += list(data)
else
Bridge(DMAPI5_BRIDGE_COMMAND_CHAT_SEND, list(DMAPI5_BRIDGE_PARAMETER_CHAT_MESSAGE = message))
Bridge(DMAPI5_BRIDGE_COMMAND_CHAT_SEND, list(DMAPI5_BRIDGE_PARAMETER_CHAT_MESSAGE = data))

/datum/tgs_api/v5/ChatPrivateMessage(datum/tgs_message_content/message, datum/tgs_chat_user/user)
message = UpgradeDeprecatedChatMessage(message)
message = message._interop_serialize()
message[DMAPI5_CHAT_MESSAGE_CHANNEL_IDS] = list(user.channel.id)
/datum/tgs_api/v5/ChatPrivateMessage(datum/tgs_message_content/message2, datum/tgs_chat_user/user)
message2 = UpgradeDeprecatedChatMessage(message2)
var/list/data = message2._interop_serialize()
data[DMAPI5_CHAT_MESSAGE_CHANNEL_IDS] = list(user.channel.id)
if(intercepted_message_queue)
intercepted_message_queue += list(message)
intercepted_message_queue += list(data)
else
Bridge(DMAPI5_BRIDGE_COMMAND_CHAT_SEND, list(DMAPI5_BRIDGE_PARAMETER_CHAT_MESSAGE = message))
Bridge(DMAPI5_BRIDGE_COMMAND_CHAT_SEND, list(DMAPI5_BRIDGE_PARAMETER_CHAT_MESSAGE = data))

/datum/tgs_api/v5/ChatChannelInfo()
RequireInitialBridgeResponse()
WaitForReattach(TRUE)
return chat_channels.Copy()

/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]
if(istype(chat_channels_json))
chat_channels.Cut()
Expand Down
6 changes: 3 additions & 3 deletions code/modules/tgs/v5/commands.dm
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@
if(sc)
var/datum/tgs_message_content/response = sc.Run(u, params)
response = UpgradeDeprecatedCommandResponse(response, command)

var/list/topic_response = TopicResponse()
topic_response[DMAPI5_TOPIC_RESPONSE_COMMAND_RESPONSE_MESSAGE] = response?.text
topic_response[DMAPI5_TOPIC_RESPONSE_COMMAND_RESPONSE] = response?._interop_serialize()
topic_response[DMAPI5_TOPIC_RESPONSE_COMMAND_RESPONSE_MESSAGE] = response ? response.text : null
topic_response[DMAPI5_TOPIC_RESPONSE_COMMAND_RESPONSE] = response ? response._interop_serialize() : null
return topic_response
return TopicResponse("Unknown custom chat command: [command]!")

Expand Down
18 changes: 9 additions & 9 deletions code/modules/tgs/v5/serializers.dm
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/datum/tgs_message_content/proc/_interop_serialize()
return list("text" = text, "embed" = embed?._interop_serialize())
return list("text" = text, "embed" = embed ? embed._interop_serialize() : null)

/datum/tgs_chat_embed/proc/_interop_serialize()
CRASH("Base /proc/interop_serialize called on [type]!")

/datum/tgs_chat_embed/structure/_interop_serialize()
var/list/serialized_fields
if(islist(fields))
if(istype(fields, /list))
serialized_fields = list()
for(var/datum/tgs_chat_embed/field/field as anything in fields)
serialized_fields += list(field._interop_serialize())
Expand All @@ -16,12 +16,12 @@
"url" = url,
"timestamp" = timestamp,
"colour" = colour,
"image" = image?._interop_serialize(),
"thumbnail" = thumbnail?._interop_serialize(),
"video" = video?._interop_serialize(),
"footer" = footer?._interop_serialize(),
"provider" = provider?._interop_serialize(),
"author" = author?._interop_serialize(),
"image" = src.image ? src.image._interop_serialize() : null,
"thumbnail" = thumbnail ? thumbnail._interop_serialize() : null,
"video" = video ? video._interop_serialize() : null,
"footer" = footer ? footer._interop_serialize() : null,
"provider" = provider ? provider._interop_serialize() : null,
"author" = author ? author._interop_serialize() : null,
"fields" = serialized_fields
)

Expand All @@ -43,7 +43,7 @@
. = ..()
.["iconUrl"] = icon_url
.["proxyIconUrl"] = proxy_icon_url

/datum/tgs_chat_embed/footer/_interop_serialize()
return list(
"text" = text,
Expand Down
39 changes: 24 additions & 15 deletions code/modules/tgs/v5/topic.dm
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
return response

/datum/tgs_api/v5/proc/ProcessTopicJson(json, check_access_identifier)
TGS_DEBUG_LOG("ProcessTopicJson(..., [check_access_identifier])")
var/list/result = ProcessRawTopic(json, check_access_identifier)
if(!result)
result = TopicResponse("Runtime error!")
Expand All @@ -25,16 +26,20 @@
return response_json

/datum/tgs_api/v5/proc/ProcessRawTopic(json, check_access_identifier)
TGS_DEBUG_LOG("ProcessRawTopic(..., [check_access_identifier])")
var/list/topic_parameters = json_decode(json)
if(!topic_parameters)
TGS_DEBUG_LOG("ProcessRawTopic: json_decode failed")
return TopicResponse("Invalid topic parameters json: [json]!");

var/their_sCK = topic_parameters[DMAPI5_PARAMETER_ACCESS_IDENTIFIER]
if(check_access_identifier && their_sCK != access_identifier)
return TopicResponse("Failed to decode [DMAPI5_PARAMETER_ACCESS_IDENTIFIER]!")
TGS_DEBUG_LOG("ProcessRawTopic: access identifier check failed")
return TopicResponse("Failed to decode [DMAPI5_PARAMETER_ACCESS_IDENTIFIER] or it does not match!")

var/command = topic_parameters[DMAPI5_TOPIC_PARAMETER_COMMAND_TYPE]
if(!isnum(command))
TGS_DEBUG_LOG("ProcessRawTopic: command type check failed")
return TopicResponse("Failed to decode [DMAPI5_TOPIC_PARAMETER_COMMAND_TYPE]!")

return ProcessTopicCommand(command, topic_parameters)
Expand All @@ -43,6 +48,7 @@
return "response[payload_id]"

/datum/tgs_api/v5/proc/ProcessTopicCommand(command, list/topic_parameters)
TGS_DEBUG_LOG("ProcessTopicCommand([command], ...)")
switch(command)

if(DMAPI5_TOPIC_COMMAND_CHAT_COMMAND)
Expand All @@ -55,7 +61,6 @@
return result

if(DMAPI5_TOPIC_COMMAND_EVENT_NOTIFICATION)
intercepted_message_queue = list()
var/list/event_notification = topic_parameters[DMAPI5_TOPIC_PARAMETER_EVENT_NOTIFICATION]
if(!istype(event_notification))
return TopicResponse("Invalid [DMAPI5_TOPIC_PARAMETER_EVENT_NOTIFICATION]!")
Expand All @@ -66,23 +71,25 @@

var/list/event_parameters = event_notification[DMAPI5_EVENT_NOTIFICATION_PARAMETERS]
if(event_parameters && !istype(event_parameters))
return TopicResponse("Invalid or missing [DMAPI5_EVENT_NOTIFICATION_PARAMETERS]!")
. = TopicResponse("Invalid or missing [DMAPI5_EVENT_NOTIFICATION_PARAMETERS]!")
else
var/list/response = TopicResponse()
. = response
if(event_handler != null)
var/list/event_call = list(event_type)
if(event_parameters)
event_call += event_parameters

intercepted_message_queue = list()
event_handler.HandleEvent(arglist(event_call))
response[DMAPI5_TOPIC_RESPONSE_CHAT_RESPONSES] = intercepted_message_queue
intercepted_message_queue = null

var/list/event_call = list(event_type)
if (event_type == TGS_EVENT_WATCHDOG_DETACH)
detached = TRUE
chat_channels.Cut() // https://github.com/tgstation/tgstation-server/issues/1490

if(event_parameters)
event_call += event_parameters

if(event_handler != null)
event_handler.HandleEvent(arglist(event_call))

var/list/response = TopicResponse()
response[DMAPI5_TOPIC_RESPONSE_CHAT_RESPONSES] = intercepted_message_queue
intercepted_message_queue = null
return response
return

if(DMAPI5_TOPIC_COMMAND_CHANGE_PORT)
var/new_port = topic_parameters[DMAPI5_TOPIC_PARAMETER_NEW_PORT]
Expand Down Expand Up @@ -122,8 +129,10 @@
return TopicResponse()

if(DMAPI5_TOPIC_COMMAND_CHAT_CHANNELS_UPDATE)
TGS_DEBUG_LOG("ProcessTopicCommand: It's a chat update")
var/list/chat_update_json = topic_parameters[DMAPI5_TOPIC_PARAMETER_CHAT_UPDATE]
if(!istype(chat_update_json))
TGS_DEBUG_LOG("ProcessTopicCommand: failed \"[DMAPI5_TOPIC_PARAMETER_CHAT_UPDATE]\" check")
return TopicResponse("Invalid or missing [DMAPI5_TOPIC_PARAMETER_CHAT_UPDATE]!")

DecodeChannels(chat_update_json)
Expand All @@ -138,7 +147,7 @@
return TopicResponse()

if(DMAPI5_TOPIC_COMMAND_HEALTHCHECK)
if(event_handler?.receive_health_checks)
if(event_handler && event_handler.receive_health_checks)
event_handler.HandleEvent(TGS_EVENT_HEALTH_CHECK)
return TopicResponse()

Expand Down

0 comments on commit c65248b

Please sign in to comment.