Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatic TGS DMAPI Update #1

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 115 additions & 8 deletions 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.0.3"
#define TGS_DMAPI_VERSION "6.3.1"

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

Expand Down Expand Up @@ -102,6 +102,8 @@
// #define TGS_EVENT_WORLD_REBOOT 20
/// Watchdog event when TgsInitializationComplete() is called. No parameters.
#define TGS_EVENT_WORLD_PRIME 21
// DMAPI also doesnt implement this
// #define TGS_EVENT_DREAM_DAEMON_LAUNCH 22

// OTHER ENUMS

Expand Down Expand Up @@ -225,6 +227,8 @@
var/is_private_channel
/// Tag string associated with the channel in TGS
var/custom_tag
/// [TRUE]/[FALSE] if the channel supports embeds
var/embeds_supported

// Represents a chat user
/datum/tgs_chat_user
Expand Down Expand Up @@ -254,16 +258,119 @@
var/help_text = ""
/// If this command should be available to game administrators only
var/admin_only = FALSE
/// A subtype of [/datum/tgs_chat_command] that is ignored when enumerating available commands. Use this to create shared base /datums for commands.
var/ignore_type

/**
* Process command activation. Should return a string to respond to the issuer with.
* Process command activation. Should return a [/datum/tgs_message_content] to respond to the issuer with.
*
* sender - The [/datum/tgs_chat_user] who issued the command.
* params - The trimmed string following the command `/datum/tgs_chat_command/var/name].
*/
/datum/tgs_chat_command/proc/Run(datum/tgs_chat_user/sender, params)
CRASH("[type] has no implementation for Run()")

/// User definable chat message
/datum/tgs_message_content
/// The tring content of the message. Must be provided in New().
var/text

/// The [/datum/tgs_chat_embed] to embed in the message. Not supported on all chat providers.
var/datum/tgs_chat_embed/structure/embed

/datum/tgs_message_content/New(text)
if(!istext(text))
TGS_ERROR_LOG("[/datum/tgs_message_content] created with no text!")
text = null

src.text = text

/// User definable chat embed. Currently mirrors Discord chat embeds. See https://discord.com/developers/docs/resources/channel#embed-object-embed-structure for details.
/datum/tgs_chat_embed/structure
var/title
var/description
var/url

/// Timestamp must be encoded as: time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss"). Use the active timezone.
var/timestamp

/// Colour must be #AARRGGBB or #RRGGBB hex string
var/colour

/// See https://discord.com/developers/docs/resources/channel#embed-object-embed-image-structure for details.
var/datum/tgs_chat_embed/media/image

/// See https://discord.com/developers/docs/resources/channel#embed-object-embed-thumbnail-structure for details.
var/datum/tgs_chat_embed/media/thumbnail

/// See https://discord.com/developers/docs/resources/channel#embed-object-embed-image-structure for details.
var/datum/tgs_chat_embed/media/video

var/datum/tgs_chat_embed/footer/footer
var/datum/tgs_chat_embed/provider/provider
var/datum/tgs_chat_embed/provider/author/author

var/list/datum/tgs_chat_embed/field/fields

/// Common datum for similar discord embed medias
/datum/tgs_chat_embed/media
/// Must be set in New().
var/url
var/width
var/height
var/proxy_url

/datum/tgs_chat_embed/media/New(url)
if(!istext(url))
CRASH("[/datum/tgs_chat_embed/media] created with no url!")

src.url = url

/// See https://discord.com/developers/docs/resources/channel#embed-object-embed-footer-structure for details.
/datum/tgs_chat_embed/footer
/// Must be set in New().
var/text
var/icon_url
var/proxy_icon_url

/datum/tgs_chat_embed/footer/New(text)
if(!istext(text))
CRASH("[/datum/tgs_chat_embed/footer] created with no text!")

src.text = text

/// See https://discord.com/developers/docs/resources/channel#embed-object-embed-provider-structure for details.
/datum/tgs_chat_embed/provider
var/name
var/url

/// See https://discord.com/developers/docs/resources/channel#embed-object-embed-author-structure for details. Must have name set in New().
/datum/tgs_chat_embed/provider/author
var/icon_url
var/proxy_icon_url

/datum/tgs_chat_embed/provider/author/New(name)
if(!istext(name))
CRASH("[/datum/tgs_chat_embed/provider/author] created with no name!")

src.name = name

/// See https://discord.com/developers/docs/resources/channel#embed-object-embed-field-structure for details. Must have name and value set in New().
/datum/tgs_chat_embed/field
var/name
var/value
var/is_inline

/datum/tgs_chat_embed/field/New(name, value)
if(!istext(name))
CRASH("[/datum/tgs_chat_embed/field] created with no name!")

if(!istext(value))
CRASH("[/datum/tgs_chat_embed/field] created with no value!")

src.name = name
src.value = value

// API FUNCTIONS

/// Returns the maximum supported [/datum/tgs_version] of the DMAPI.
Expand Down Expand Up @@ -294,30 +401,30 @@
/**
* Send a message to connected chats.
*
* message - The string to send.
* message - The [/datum/tgs_message_content] to send.
* admin_only: If [TRUE], message will be sent to admin connected chats. Vice-versa applies.
*/
/world/proc/TgsTargetedChatBroadcast(message, admin_only = FALSE)
/world/proc/TgsTargetedChatBroadcast(datum/tgs_message_content/message, admin_only = FALSE)
return

/**
* Send a private message to a specific user.
*
* message - The string to send.
* message - The [/datum/tgs_message_content] to send.
* user: The [/datum/tgs_chat_user] to PM.
*/
/world/proc/TgsChatPrivateMessage(message, datum/tgs_chat_user/user)
/world/proc/TgsChatPrivateMessage(datum/tgs_message_content/message, datum/tgs_chat_user/user)
return

// The following functions will sleep if a call to TgsNew() is sleeping

/**
* Send a message to connected chats that are flagged as game-related in TGS.
*
* message - The string to send.
* message - The [/datum/tgs_message_content] to send.
* channels - Optional list of [/datum/tgs_chat_channel]s to restrict the message to.
*/
/world/proc/TgsChatBroadcast(message, list/channels = null)
/world/proc/TgsChatBroadcast(datum/tgs_message_content/message, list/channels = null)
return

/// Returns the current [/datum/tgs_version] of TGS if it is running the server, null otherwise.
Expand Down
2 changes: 1 addition & 1 deletion code/modules/tgs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ This folder should be placed on it's own inside a codebase that wishes to use th
- The other versioned folders contain code for the different DMAPI versions.
- [v3210](./v3210) contains the final TGS3 API.
- [v4](./v4) is the legacy DMAPI 4 (Used in TGS 4.0.X versions).
- [v5](./v5) is the current DMAPI version used by TGS4 >=4.1.
- [v5](./v5) is the current DMAPI version used by TGS >=4.1.
- [LICENSE](./LICENSE) is the MIT license for the DMAPI.

APIs communicate with TGS in two ways. All versions implement TGS -> DM communication using /world/Topic. DM -> TGS communication, called the bridge method, is different for each version.
3 changes: 2 additions & 1 deletion code/modules/tgs/core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ This folder contains all DMAPI code not directly involved in an API.
- [_definitions.dm](./definitions.dm) contains defines needed across DMAPI internals.
- [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.
- [datum.dm](./datum.dm) contains the `/datum/tgs_api` declarations that all APIs must implement.
- [tgs_version.dm](./tgs_version.dm) contains the `/datum/tgs_version` definition
- [tgs_version.dm](./tgs_version.dm) contains the `/datum/tgs_version` definition
-
2 changes: 2 additions & 0 deletions code/modules/tgs/core/datum.dm
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ TGS_DEFINE_AND_SET_GLOBAL(tgs, null)
var/datum/tgs_version/version
var/datum/tgs_event_handler/event_handler

var/list/warned_deprecated_command_runs

/datum/tgs_api/New(datum/tgs_event_handler/event_handler, datum/tgs_version/version)
. = ..()
src.event_handler = event_handler
Expand Down
1 change: 1 addition & 0 deletions code/modules/tgs/includes.dm
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@
#include "v5\_defines.dm"
#include "v5\api.dm"
#include "v5\commands.dm"
#include "v5\serializers.dm"
#include "v5\undefs.dm"
38 changes: 27 additions & 11 deletions code/modules/tgs/v3210/api.dm
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@

#define SERVICE_RETURN_SUCCESS "SUCCESS"

#define TGS_FILE2LIST(filename) (splittext(trim_left(trim_right(file2text(filename))), "\n"))

/datum/tgs_api/v3210
var/reboot_mode = REBOOT_MODE_NORMAL
var/comms_key
Expand All @@ -53,9 +55,6 @@
return copytext(text, 1, i + 1)
return ""

/datum/tgs_api/v3210/proc/file2list(filename)
return splittext(trim_left(trim_right(file2text(filename))), "\n")

/datum/tgs_api/v3210/OnWorldNew(minimum_required_security_level)
. = FALSE

Expand All @@ -64,13 +63,21 @@
if(!instance_name)
instance_name = "TG Station Server" //maybe just upgraded

var/list/logs = file2list(".git/logs/HEAD")
var/list/logs = TGS_FILE2LIST(".git/logs/HEAD")
if(logs.len)
logs = splittext(logs[logs.len - 1], " ")
commit = logs[2]
logs = file2list(".git/logs/refs/remotes/origin/master")
logs = splittext(logs[logs.len], " ")
if (logs.len >= 2)
commit = logs[2]
else
TGS_ERROR_LOG("Error parsing commit logs")

logs = TGS_FILE2LIST(".git/logs/refs/remotes/origin/master")
if(logs.len)
originmastercommit = splittext(logs[logs.len - 1], " ")[2]
logs = splittext(logs[logs.len], " ")
if (logs.len >= 2)
originmastercommit = logs[2]
else
TGS_ERROR_LOG("Error parsing origin commmit logs")

if(world.system_type != MS_WINDOWS)
TGS_ERROR_LOG("This API version is only supported on Windows. Not running on Windows. Aborting initialization!")
Expand All @@ -92,7 +99,11 @@
if(skip_compat_check && !fexists(SERVICE_INTERFACE_DLL))
TGS_ERROR_LOG("Service parameter present but no interface DLL detected. This is symptomatic of running a service less than version 3.1! Please upgrade.")
return
#if DM_VERSION >= 515
call_ext(SERVICE_INTERFACE_DLL, SERVICE_INTERFACE_FUNCTION)(instance_name, command) //trust no retval
#else
call(SERVICE_INTERFACE_DLL, SERVICE_INTERFACE_FUNCTION)(instance_name, command) //trust no retval
#endif
return TRUE

/datum/tgs_api/v3210/OnTopic(T)
Expand Down Expand Up @@ -182,16 +193,19 @@
/datum/tgs_api/v3210/ChatChannelInfo()
return list() // :omegalul:

/datum/tgs_api/v3210/ChatBroadcast(message, list/channels)
/datum/tgs_api/v3210/ChatBroadcast(datum/tgs_message_content/message, list/channels)
if(channels)
return TGS_UNIMPLEMENTED
message = UpgradeDeprecatedChatMessage(message)
ChatTargetedBroadcast(message, TRUE)
ChatTargetedBroadcast(message, FALSE)

/datum/tgs_api/v3210/ChatTargetedBroadcast(message, admin_only)
ExportService("[admin_only ? SERVICE_REQUEST_IRC_ADMIN_CHANNEL_MESSAGE : SERVICE_REQUEST_IRC_BROADCAST] [message]")
/datum/tgs_api/v3210/ChatTargetedBroadcast(datum/tgs_message_content/message, admin_only)
message = UpgradeDeprecatedChatMessage(message)
ExportService("[admin_only ? SERVICE_REQUEST_IRC_ADMIN_CHANNEL_MESSAGE : SERVICE_REQUEST_IRC_BROADCAST] [message.text]")

/datum/tgs_api/v3210/ChatPrivateMessage(message, datum/tgs_chat_user/user)
UpgradeDeprecatedChatMessage(message)
return TGS_UNIMPLEMENTED

/datum/tgs_api/v3210/SecurityLevel()
Expand Down Expand Up @@ -226,3 +240,5 @@
#undef SERVICE_REQUEST_API_VERSION

#undef SERVICE_RETURN_SUCCESS

#undef TGS_FILE2LIST
10 changes: 8 additions & 2 deletions code/modules/tgs/v3210/commands.dm
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@
var/warned_about_the_dangers_of_robutussin = !warnings_only
for(var/I in typesof(/datum/tgs_chat_command) - /datum/tgs_chat_command)
if(!warned_about_the_dangers_of_robutussin)
TGS_ERROR_LOG("Custom chat commands in [ApiVersion()] lacks the /datum/tgs_chat_user/sender.channel field!")
TGS_WARNING_LOG("Custom chat commands in [ApiVersion()] lacks the /datum/tgs_chat_user/sender.channel field!")
warned_about_the_dangers_of_robutussin = TRUE
var/datum/tgs_chat_command/stc = I
if(stc.ignore_type == I)
continue

var/command_name = initial(stc.name)
if(!command_name || findtext(command_name, " ") || findtext(command_name, "'") || findtext(command_name, "\""))
if(warnings_only && !warned_command_names[command_name])
Expand Down Expand Up @@ -49,4 +52,7 @@
sender = "<@[sender]>"

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

return result?.text || TRUE
15 changes: 9 additions & 6 deletions code/modules/tgs/v4/api.dm
Original file line number Diff line number Diff line change
Expand Up @@ -256,33 +256,36 @@
/datum/tgs_api/v4/Revision()
return cached_revision

/datum/tgs_api/v4/ChatBroadcast(message, list/channels)
/datum/tgs_api/v4/ChatBroadcast(datum/tgs_message_content/message, list/channels)
var/list/ids
if(length(channels))
ids = list()
for(var/I in channels)
var/datum/tgs_chat_channel/channel = I
ids += channel.id
message = list("message" = message, "channelIds" = ids)
message = UpgradeDeprecatedChatMessage(message)
message = list("message" = message.text, "channelIds" = ids)
if(intercepted_message_queue)
intercepted_message_queue += list(message)
else
Export(TGS4_COMM_CHAT, message)

/datum/tgs_api/v4/ChatTargetedBroadcast(message, admin_only)
/datum/tgs_api/v4/ChatTargetedBroadcast(datum/tgs_message_content/message, 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 = list("message" = message, "channelIds" = channels)
message = UpgradeDeprecatedChatMessage(message)
message = list("message" = message.text, "channelIds" = channels)
if(intercepted_message_queue)
intercepted_message_queue += list(message)
else
Export(TGS4_COMM_CHAT, message)

/datum/tgs_api/v4/ChatPrivateMessage(message, datum/tgs_chat_user/user)
message = list("message" = message, "channelIds" = list(user.channel.id))
/datum/tgs_api/v4/ChatPrivateMessage(datum/tgs_message_content/message, datum/tgs_chat_user/user)
message = UpgradeDeprecatedChatMessage(message)
message = list("message" = message.text, "channelIds" = list(user.channel.id))
if(intercepted_message_queue)
intercepted_message_queue += list(message)
else
Expand Down
11 changes: 7 additions & 4 deletions code/modules/tgs/v4/commands.dm
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
custom_commands = list()
for(var/I in typesof(/datum/tgs_chat_command) - /datum/tgs_chat_command)
var/datum/tgs_chat_command/stc = new I
if(stc.ignore_type == I)
continue

var/command_name = stc.name
if(!command_name || findtext(command_name, " ") || findtext(command_name, "'") || findtext(command_name, "\""))
TGS_ERROR_LOG("Custom command [command_name] ([I]) can't be used as it is empty or contains illegal characters!")
Expand Down Expand Up @@ -34,8 +37,8 @@

var/datum/tgs_chat_command/sc = custom_commands[command]
if(sc)
var/result = sc.Run(u, params)
if(result == null)
result = ""
return result
var/datum/tgs_message_content/result = sc.Run(u, params)
result = UpgradeDeprecatedCommandResponse(result, command)

return result?.text
return "Unknown command: [command]!"
Loading