mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-26 06:27:19 +01:00
Finish DMAPI v5
This commit is contained in:
@@ -30,6 +30,8 @@
|
||||
switch(version.minor)
|
||||
if(0)
|
||||
api_datum = /datum/tgs_api/v4
|
||||
if(5)
|
||||
api_datum = /datum/tgs_api/v5
|
||||
|
||||
var/datum/tgs_version/max_api_version = TgsMaximumAPIVersion();
|
||||
if(version.suite != null && version.minor != null && version.patch != null && version.deprecated_patch != null && version.deprefixed_parameter > max_api_version.deprefixed_parameter)
|
||||
@@ -51,10 +53,10 @@
|
||||
TGS_ERROR_LOG("Failed to activate API!")
|
||||
|
||||
/world/TgsMaximumAPIVersion()
|
||||
return new /datum/tgs_version("4.0.x.x")
|
||||
return new /datum/tgs_version("5.x.x")
|
||||
|
||||
/world/TgsMinimumAPIVersion()
|
||||
return new /datum/tgs_version("3.2.0.0")
|
||||
return new /datum/tgs_version("3.2.x")
|
||||
|
||||
/world/TgsInitializationComplete()
|
||||
var/datum/tgs_api/api = TGS_READ_GLOBAL(tgs)
|
||||
|
||||
@@ -8,7 +8,7 @@ TGS_DEFINE_AND_SET_GLOBAL(tgs, null)
|
||||
src.version = version
|
||||
|
||||
/datum/tgs_api/latest
|
||||
parent_type = /datum/tgs_api/v4
|
||||
parent_type = /datum/tgs_api/v5
|
||||
|
||||
TGS_PROTECT_DATUM(/datum/tgs_api)
|
||||
|
||||
|
||||
@@ -2,11 +2,42 @@
|
||||
#include "core\core.dm"
|
||||
#include "core\datum.dm"
|
||||
#include "core\tgs_version.dm"
|
||||
|
||||
#ifdef TGS_V3_API
|
||||
#include "v3210\api.dm"
|
||||
#include "v3210\commands.dm"
|
||||
#endif
|
||||
|
||||
#include "v4\api.dm"
|
||||
#include "v4\commands.dm"
|
||||
|
||||
#include "v5\api.dm"
|
||||
#include "v5\commands.dm"
|
||||
#include "v5\undef.dm"
|
||||
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2017 Jordan Brown
|
||||
|
||||
Permission is hereby granted, free of charge,
|
||||
to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to
|
||||
deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify,
|
||||
merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#define DMAPI5_PARAM_RUNTIME_INFORMATION_FILE "tgs_json"
|
||||
#define DMAPI5_TOPIC_DATA "data"
|
||||
#define DMAPI5_BRIDGE_DATA "data"
|
||||
#define DMAPI5_TOPIC_DATA "tgs_data"
|
||||
|
||||
#define DMAPI5_BRIDGE_COMMAND_PORT_UPDATE 0
|
||||
#define DMAPI5_BRIDGE_COMMAND_VALIDATE 1
|
||||
@@ -9,6 +10,7 @@
|
||||
#define DMAPI5_BRIDGE_COMMAND_CHAT_SEND 5
|
||||
|
||||
#define DMAPI5_PARAMETER_ACCESS_IDENTIFIER "accessIdentifier"
|
||||
#define DMAPI5_RESPONSE_ERROR_MESSAGE "errorMessage"
|
||||
|
||||
#define DMAPI5_BRIDGE_PARAMETER_COMMAND_TYPE "commandType"
|
||||
#define DMAPI5_BRIDGE_PARAMETER_CURRENT_PORT "currentPort"
|
||||
@@ -16,8 +18,7 @@
|
||||
#define DMAPI5_BRIDGE_PARAMETER_CHAT_MESSAGE "chatMessage"
|
||||
#define DMAPI5_BRIDGE_PARAMETER_MINIMUM_SECURITY_LEVEL "minimumSecurityLevel"
|
||||
|
||||
#define DMAPI5_BRIDGE_RESPONSE_ERROR_MESSAGE "errorMessage"
|
||||
#define DMAPI5_BRIDGE_RESPONSE_ERROR_NEW_PORT "newPort"
|
||||
#define DMAPI5_BRIDGE_RESPONSE_NEW_PORT "newPort"
|
||||
|
||||
#define DMAPI5_CHAT_MESSAGE_TEXT "text"
|
||||
#define DMAPI5_CHAT_MESSAGE_CHANNEL_IDS "channelIds"
|
||||
@@ -29,6 +30,9 @@
|
||||
#define DMAPI5_RUNTIME_INFORMATION_INSTANCE_NAME "instanceName"
|
||||
#define DMAPI5_RUNTIME_INFORMATION_REVISION "revision"
|
||||
#define DMAPI5_RUNTIME_INFORMATION_TEST_MERGES "testMerges"
|
||||
#define DMAPI5_RUNTIME_INFORMATION_SECURITY_LEVEL "securityLevel"
|
||||
#define DMAPI5_RUNTIME_INFORMATION_CHAT_COMMANDS_JSON "chatCommandsJson"
|
||||
#define DMAPI5_RUNTIME_INFORMATION_CHAT_CHANNELS_JSON "chatChannelsJson"
|
||||
|
||||
#define DMAPI5_TEST_MERGE_TIME_MERGED "timeMerged"
|
||||
#define DMAPI5_TEST_MERGE_REVISION "revision"
|
||||
@@ -36,6 +40,9 @@
|
||||
#define DMAPI5_TEST_MERGE_BODY_AT_MERGE "bodyAtMerge"
|
||||
#define DMAPI5_TEST_MERGE_URL "url"
|
||||
#define DMAPI5_TEST_MERGE_AUTHOR "author"
|
||||
#define DMAPI5_TEST_MERGE_NUMBER "number"
|
||||
#define DMAPI5_TEST_MERGE_PULL_REQUEST_REVISION "pullRequestRevision"
|
||||
#define DMAPI5_TEST_MERGE_COMMENT "comment"
|
||||
|
||||
#define DMAPI5_CHAT_COMMAND_NAME "name"
|
||||
#define DMAPI5_CHAT_COMMAND_PARAMS "params"
|
||||
@@ -57,7 +64,6 @@
|
||||
#define DMAPI5_TOPIC_PARAMETER_NEW_REBOOT_STATE "newRebootState"
|
||||
#define DMAPI5_TOPIC_PARAMETER_NEW_INSTANCE_NAME "newInstanceName"
|
||||
|
||||
#define DMAPI5_TOPIC_RESPONSE_ERROR_MESSAGE "errorMessage"
|
||||
#define DMAPI5_TOPIC_RESPONSE_COMMAND_RESPONSE_MESSAGE "commandResponseMessage"
|
||||
#define DMAPI5_TOPIC_RESPONSE_CHAT_RESPONSES "chatResponses"
|
||||
|
||||
@@ -74,5 +80,35 @@
|
||||
#define DMAPI5_CHAT_CHANNEL_CONNECTION_NAME "connectionName"
|
||||
#define DMAPI5_CHAT_CHANNEL_IS_ADMIN_CHANNEL "isAdminChannel"
|
||||
#define DMAPI5_CHAT_CHANNEL_IS_PRIVATE_CHANNEL "isPrivateChannel"
|
||||
#define DMAPI5_CHAT_CHANNEL_IS_WATCHDOG_CHANNEL "isWatchdogChannel"
|
||||
#define DMAPI5_CHAT_CHANNEL_TAG "tag"
|
||||
|
||||
#define DMAPI5_CUSTOM_CHAT_COMMAND_NAME "name"
|
||||
#define DMAPI5_CUSTOM_CHAT_COMMAND_HELP_TEXT "helpText"
|
||||
#define DMAPI5_CUSTOM_CHAT_COMMAND_ADMIN_ONLY "adminOnly"
|
||||
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2020 Jordan Brown
|
||||
|
||||
Permission is hereby granted, free of charge,
|
||||
to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to
|
||||
deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify,
|
||||
merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
+131
-164
@@ -1,30 +1,3 @@
|
||||
#define TGS4_PARAM_DEPLOYMENT_INFORMATION_FILE "tgs_json"
|
||||
#define TGS4_TOPIC_DATA "data"
|
||||
|
||||
#define TGS4_INTEROP_ACCESS_IDENTIFIER "tgs_tok"
|
||||
|
||||
#define TGS4_RESPONSE_SUCCESS "tgs_succ"
|
||||
|
||||
#define TGS4_TOPIC_CHANGE_PORT "tgs_port"
|
||||
#define TGS4_TOPIC_CHANGE_REBOOT_MODE "tgs_rmode"
|
||||
#define TGS4_TOPIC_CHAT_COMMAND "tgs_chat_comm"
|
||||
#define TGS4_TOPIC_EVENT "tgs_event"
|
||||
#define TGS4_TOPIC_INTEROP_RESPONSE "tgs_interop"
|
||||
|
||||
#define TGS4_COMM_NEW_PORT "tgs_new_port"
|
||||
#define TGS4_COMM_VALIDATE "tgs_validate"
|
||||
#define TGS4_COMM_SERVER_PRIMED "tgs_prime"
|
||||
#define TGS4_COMM_WORLD_REBOOT "tgs_reboot"
|
||||
#define TGS4_COMM_END_PROCESS "tgs_kill"
|
||||
#define TGS4_COMM_CHAT "tgs_chat_send"
|
||||
|
||||
#define TGS4_PARAMETER_COMMAND "tgs_com"
|
||||
#define TGS4_PARAMETER_DATA "tgs_data"
|
||||
|
||||
#define TGS4_PORT_CRITFAIL_MESSAGE " Must exit to let watchdog reboot..."
|
||||
|
||||
#define EXPORT_TIMEOUT_DS 200
|
||||
|
||||
/datum/tgs_api/v5
|
||||
var/access_identifier
|
||||
var/instance_name
|
||||
@@ -33,8 +6,7 @@
|
||||
var/chat_commands_json_path
|
||||
var/reboot_mode = TGS_REBOOT_MODE_NORMAL
|
||||
var/security_level
|
||||
|
||||
var/requesting_new_port = FALSE
|
||||
var/server_port
|
||||
|
||||
var/list/intercepted_message_queue
|
||||
|
||||
@@ -47,13 +19,13 @@
|
||||
|
||||
var/export_lock = FALSE
|
||||
|
||||
/datum/tgs_api/v4/ApiVersion()
|
||||
/datum/tgs_api/v5/ApiVersion()
|
||||
return "5.0.0"
|
||||
|
||||
/datum/tgs_api/v4/OnWorldNew(datum/tgs_event_handler/event_handler, minimum_required_security_level)
|
||||
json_path = world.params[TGS4_PARAM_INFO_JSON]
|
||||
/datum/tgs_api/v5/OnWorldNew(datum/tgs_event_handler/event_handler, minimum_required_security_level)
|
||||
json_path = world.params[DMAPI5_PARAM_RUNTIME_INFORMATION_FILE]
|
||||
if(!json_path)
|
||||
TGS_ERROR_LOG("Missing [TGS4_PARAM_INFO_JSON] world parameter!")
|
||||
TGS_ERROR_LOG("Missing [DMAPI5_PARAM_RUNTIME_INFORMATION_FILE] world parameter!")
|
||||
return
|
||||
var/json_file = file2text(json_path)
|
||||
if(!json_file)
|
||||
@@ -64,181 +36,176 @@
|
||||
TGS_ERROR_LOG("Failed to decode info json: [json_file]")
|
||||
return
|
||||
|
||||
access_identifier = cached_json["accessIdentifier"]
|
||||
server_commands_json_path = cached_json["serverCommandsJson"]
|
||||
access_identifier = cached_json[DMAPI5_RUNTIME_INFORMATION_ACCESS_IDENTIFIER]
|
||||
server_port = cached_json[DMAPI5_RUNTIME_INFORMATION_SERVER_PORT]
|
||||
|
||||
if(cached_json["apiValidateOnly"])
|
||||
TGS_INFO_LOG("Validating API and exiting...")
|
||||
Export(TGS4_COMM_VALIDATE, list(TGS4_PARAMETER_DATA = "[minimum_required_security_level]"))
|
||||
if(cached_json[DMAPI5_RUNTIME_INFORMATION_API_VALIDATE_ONLY])
|
||||
TGS_INFO_LOG("Validating DMAPI and exiting...")
|
||||
Bridge(DMAPI5_BRIDGE_COMMAND_VALIDATE, list(DMAPI5_BRIDGE_PARAMETER_MINIMUM_SECURITY_LEVEL = minimum_required_security_level, DMAPI5_BRIDGE_PARAMETER_VERSION = Version()))
|
||||
del(world)
|
||||
|
||||
security_level = cached_json["securityLevel"]
|
||||
chat_channels_json_path = cached_json["chatChannelsJson"]
|
||||
chat_commands_json_path = cached_json["chatCommandsJson"]
|
||||
security_level = cached_json[DMAPI5_RUNTIME_INFORMATION_SECURITY_LEVEL]
|
||||
chat_channels_json_path = cached_json[DMAPI5_RUNTIME_INFORMATION_CHAT_CHANNELS_JSON]
|
||||
chat_commands_json_path = cached_json[DMAPI5_RUNTIME_INFORMATION_CHAT_COMMANDS_JSON]
|
||||
src.event_handler = event_handler
|
||||
instance_name = cached_json["instanceName"]
|
||||
instance_name = cached_json[DMAPI5_RUNTIME_INFORMATION_INSTANCE_NAME]
|
||||
|
||||
ListCustomCommands()
|
||||
|
||||
var/list/revisionData = cached_json["revision"]
|
||||
var/list/revisionData = cached_json[DMAPI5_RUNTIME_INFORMATION_REVISION]
|
||||
if(revisionData)
|
||||
cached_revision = new
|
||||
cached_revision.commit = revisionData["commitSha"]
|
||||
cached_revision.origin_commit = revisionData["originCommitSha"]
|
||||
cached_revision.commit = revisionData[DMAPI5_REVISION_INFORMATION_COMMIT_SHA]
|
||||
cached_revision.origin_commit = revisionData[DMAPI5_REVISION_INFORMATION_ORIGIN_COMMIT_SHA]
|
||||
|
||||
cached_test_merges = list()
|
||||
var/list/json = cached_json["testMerges"]
|
||||
var/list/json = cached_json[DMAPI5_RUNTIME_INFORMATION_TEST_MERGES]
|
||||
for(var/entry in json)
|
||||
var/datum/tgs_revision_information/test_merge/tm = new
|
||||
tm.time_merged = text2num(entry["timeMerged"])
|
||||
tm.time_merged = text2num(entry[DMAPI5_TEST_MERGE_TIME_MERGED])
|
||||
|
||||
var/list/revInfo = entry["revision"]
|
||||
var/list/revInfo = entry[DMAPI5_TEST_MERGE_REVISION]
|
||||
if(revInfo)
|
||||
tm.commit = revInfo["commitSha"]
|
||||
tm.origin_commit = revInfo["originCommitSha"]
|
||||
tm.commit = revisionData[DMAPI5_REVISION_INFORMATION_COMMIT_SHA]
|
||||
tm.origin_commit = revisionData[DMAPI5_REVISION_INFORMATION_ORIGIN_COMMIT_SHA]
|
||||
|
||||
tm.title = entry["titleAtMerge"]
|
||||
tm.body = entry["bodyAtMerge"]
|
||||
tm.url = entry["url"]
|
||||
tm.author = entry["author"]
|
||||
tm.number = entry["number"]
|
||||
tm.pull_request_commit = entry["pullRequestRevision"]
|
||||
tm.comment = entry["comment"]
|
||||
tm.title = entry[DMAPI5_TEST_MERGE_TITLE_AT_MERGE]
|
||||
tm.body = entry[DMAPI5_TEST_MERGE_BODY_AT_MERGE]
|
||||
tm.url = entry[DMAPI5_TEST_MERGE_URL]
|
||||
tm.author = entry[DMAPI5_TEST_MERGE_AUTHOR]
|
||||
tm.number = entry[DMAPI5_TEST_MERGE_NUMBER]
|
||||
tm.pull_request_commit = entry[DMAPI5_TEST_MERGE_PULL_REQUEST_REVISION]
|
||||
tm.comment = entry[DMAPI5_TEST_MERGE_COMMENT]
|
||||
|
||||
cached_test_merges += tm
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/tgs_api/v4/OnInitializationComplete()
|
||||
Export(TGS4_COMM_SERVER_PRIMED)
|
||||
/datum/tgs_api/v5/OnInitializationComplete()
|
||||
Bridge(TGS4_COMM_SERVER_PRIMED)
|
||||
|
||||
var/tgs4_secret_sleep_offline_sauce = 24051994
|
||||
var/tgs4_secret_sleep_offline_sauce = 29051994
|
||||
var/old_sleep_offline = world.sleep_offline
|
||||
world.sleep_offline = tgs4_secret_sleep_offline_sauce
|
||||
sleep(1)
|
||||
if(world.sleep_offline == tgs4_secret_sleep_offline_sauce) //if not someone changed it
|
||||
world.sleep_offline = old_sleep_offline
|
||||
|
||||
/datum/tgs_api/v4/OnTopic(T)
|
||||
/datum/tgs_api/v5/TopicError(message)
|
||||
return json_encode(list(DMAPI5_RESPONSE_ERROR_MESSAGE = message))
|
||||
|
||||
/datum/tgs_api/v5/OnTopic(T)
|
||||
var/list/params = params2list(T)
|
||||
var/their_sCK = params[TGS4_INTEROP_ACCESS_IDENTIFIER]
|
||||
if(!their_sCK)
|
||||
var/json = params[DMAPI5_TOPIC_DATA]
|
||||
if(!json)
|
||||
return FALSE //continue world/Topic
|
||||
|
||||
var/list/topic_parameters = json_decode(json)
|
||||
if(!topic_parameters)
|
||||
return TopicError("Invalid topic parameters json!");
|
||||
|
||||
var/their_sCK = topic_parameters[DMAPI5_PARAMETER_ACCESS_IDENTIFIER]
|
||||
if(their_sCK != access_identifier)
|
||||
return "Invalid comms key!";
|
||||
return TopicError("Invalid access identifier!");
|
||||
|
||||
var/command = params[TGS4_PARAMETER_COMMAND]
|
||||
if(!command)
|
||||
return "No command!"
|
||||
|
||||
. = TGS4_RESPONSE_SUCCESS
|
||||
var/command = topic_parameters[DMAPI5_TOPIC_PARAMETER_COMMAND_TYPE]
|
||||
if(command == null)
|
||||
return TopicError("No command type!")
|
||||
|
||||
switch(command)
|
||||
if(TGS4_TOPIC_CHAT_COMMAND)
|
||||
var/result = HandleCustomCommand(params[TGS4_PARAMETER_DATA])
|
||||
if(result == null)
|
||||
result = "Error running chat command!"
|
||||
if(DMAPI5_TOPIC_COMMAND_CHAT_COMMAND)
|
||||
var/result = HandleCustomCommand(topic_parameters[DMAPI5_TOPIC_PARAMETER_CHAT_COMMAND])
|
||||
if(!result)
|
||||
result = TopicError("Error running chat command!")
|
||||
return result
|
||||
if(TGS4_TOPIC_EVENT)
|
||||
if(DMAPI5_TOPIC_COMMAND_EVENT_NOTIFICATION)
|
||||
intercepted_message_queue = list()
|
||||
var/list/event_notification = json_decode(params[TGS4_PARAMETER_DATA])
|
||||
var/list/event_parameters = event_notification["Parameters"]
|
||||
|
||||
var/list/event_call = list(event_notification["Type"])
|
||||
var/list/event_notification = topic_parameters[DMAPI5_TOPIC_PARAMETER_EVENT_NOTIFICATION]
|
||||
var/list/event_parameters = event_notification[DMAPI5_EVENT_NOTIFICATION_PARAMETERS]
|
||||
var/list/event_call = list(event_notification[DMAPI5_EVENT_NOTIFICATION_TYPE])
|
||||
if(event_parameters)
|
||||
event_call += event_parameters
|
||||
|
||||
if(event_handler != null)
|
||||
event_handler.HandleEvent(arglist(event_call))
|
||||
|
||||
. = json_encode(intercepted_message_queue)
|
||||
var/list/response = list()
|
||||
if(intercepted_message_queue.len)
|
||||
response[DMAPI5_TOPIC_RESPONSE_CHAT_RESPONSES] = intercepted_message_queue
|
||||
intercepted_message_queue = null
|
||||
return
|
||||
if(TGS4_TOPIC_INTEROP_RESPONSE)
|
||||
last_interop_response = json_decode(params[TGS4_PARAMETER_DATA])
|
||||
return
|
||||
if(TGS4_TOPIC_CHANGE_PORT)
|
||||
var/new_port = text2num(params[TGS4_PARAMETER_DATA])
|
||||
return json_encode(response)
|
||||
if(DMAPI5_TOPIC_COMMAND_CHANGE_PORT)
|
||||
var/new_port = text2num(topic_parameters[DMAPI5_TOPIC_PARAMETER_NEW_PORT])
|
||||
if (!(new_port > 0))
|
||||
return "Invalid port: [new_port]"
|
||||
return TopicError("Invalid port: [new_port]")
|
||||
|
||||
//the topic still completes, miraculously
|
||||
//I honestly didn't believe byond could do it
|
||||
if(event_handler != null)
|
||||
event_handler.HandleEvent(TGS_EVENT_PORT_SWAP, new_port)
|
||||
if(!world.OpenPort(new_port))
|
||||
return "Port change failed!"
|
||||
return
|
||||
if(TGS4_TOPIC_CHANGE_REBOOT_MODE)
|
||||
var/new_reboot_mode = text2num(params[TGS4_PARAMETER_DATA])
|
||||
return TopicError("Port change failed!")
|
||||
return json_encode(list())
|
||||
if(DMAPI5_TOPIC_COMMAND_CHANGE_REBOOT_STATE)
|
||||
var/new_reboot_mode = text2num(topic_parameters[DMAPI5_TOPIC_PARAMETER_NEW_REBOOT_STATE])
|
||||
if(event_handler != null)
|
||||
event_handler.HandleEvent(TGS_EVENT_REBOOT_MODE_CHANGE, reboot_mode, new_reboot_mode)
|
||||
reboot_mode = new_reboot_mode
|
||||
return
|
||||
return json_encode(list())
|
||||
if(DMAPI5_TOPIC_COMMAND_INSTANCE_RENAMED)
|
||||
var/new_instance_name = topic_parameters[DMAPI5_TOPIC_PARAMETER_NEW_INSTANCE_NAME]
|
||||
if(!new_instance_name)
|
||||
return TopicError("Missing new instance name!")
|
||||
instance_name = new_instance_name
|
||||
return json_encode(list())
|
||||
|
||||
return "Unknown command: [command]"
|
||||
return TopicError("Unknown command: [command]")
|
||||
|
||||
/datum/tgs_api/v5/proc/Bridge(command, list/data)
|
||||
if(command == null)
|
||||
TGS_ERROR_LOG("Attempted to bridge with no command!")
|
||||
return
|
||||
|
||||
/datum/tgs_api/v4/proc/Export(command, list/data, override_requesting_new_port = FALSE)
|
||||
if(!data)
|
||||
data = list()
|
||||
data[TGS4_PARAMETER_COMMAND] = command
|
||||
|
||||
data[DMAPI5_BRIDGE_PARAMETER_COMMAND_TYPE] = command
|
||||
data[DMAPI5_PARAMETER_ACCESS_IDENTIFIER] = access_identifier
|
||||
|
||||
var/json = json_encode(data)
|
||||
var/encoded_json = url_encode(json)
|
||||
|
||||
// This is an infinite sleep until we get a response
|
||||
var/export_response = world.Export("http://127.0.0.1:[server_port]/Bridge?[DMAPI5_BRIDGE_DATA]=[encoded_json]")
|
||||
if(!export_response)
|
||||
TGS_ERROR_LOG("Failed export request: [json]")
|
||||
return
|
||||
|
||||
var/response_json = file2text(export_result["CONTENT"])
|
||||
if(!response_json)
|
||||
TGS_ERROR_LOG("Failed export request, missing content!")
|
||||
return
|
||||
|
||||
var/list/bridge_response = json_decode(response_json)
|
||||
if(!bridge_response)
|
||||
TGS_ERROR_LOG("Failed export request, bad json: [response_json]")
|
||||
return
|
||||
|
||||
while(requesting_new_port && !override_requesting_new_port)
|
||||
sleep(1)
|
||||
var/error = bridge_response[DMAPI5_RESPONSE_ERROR_MESSAGE]
|
||||
if(error)
|
||||
TGS_ERROR_LOG("Failed export request, bad request: [error]")
|
||||
return
|
||||
|
||||
return bridge_response
|
||||
|
||||
//we need some port open at this point to facilitate return communication
|
||||
if(!world.port)
|
||||
requesting_new_port = TRUE
|
||||
if(!world.OpenPort(0)) //open any port
|
||||
TGS_ERROR_LOG("Unable to open random port to retrieve new port![TGS4_PORT_CRITFAIL_MESSAGE]")
|
||||
del(world)
|
||||
|
||||
//request a new port
|
||||
export_lock = FALSE
|
||||
var/list/new_port_json = Export(TGS4_COMM_NEW_PORT, list(TGS4_PARAMETER_DATA = "[world.port]"), TRUE) //stringify this on purpose
|
||||
|
||||
if(!new_port_json)
|
||||
TGS_ERROR_LOG("No new port response from server![TGS4_PORT_CRITFAIL_MESSAGE]")
|
||||
del(world)
|
||||
|
||||
var/new_port = new_port_json[TGS4_PARAMETER_DATA]
|
||||
if(!isnum(new_port) || new_port <= 0)
|
||||
TGS_ERROR_LOG("Malformed new port json ([json_encode(new_port_json)])![TGS4_PORT_CRITFAIL_MESSAGE]")
|
||||
del(world)
|
||||
|
||||
if(new_port != world.port && !world.OpenPort(new_port))
|
||||
TGS_ERROR_LOG("Unable to open port [new_port]![TGS4_PORT_CRITFAIL_MESSAGE]")
|
||||
del(world)
|
||||
requesting_new_port = FALSE
|
||||
|
||||
while(export_lock)
|
||||
sleep(1)
|
||||
export_lock = TRUE
|
||||
|
||||
last_interop_response = null
|
||||
fdel(server_commands_json_path)
|
||||
text2file(json, server_commands_json_path)
|
||||
|
||||
for(var/I = 0; I < EXPORT_TIMEOUT_DS && !last_interop_response; ++I)
|
||||
sleep(1)
|
||||
|
||||
if(!last_interop_response)
|
||||
TGS_ERROR_LOG("Failed to get export result for: [json]")
|
||||
else
|
||||
. = last_interop_response
|
||||
|
||||
export_lock = FALSE
|
||||
|
||||
/datum/tgs_api/v4/OnReboot()
|
||||
var/list/result = Export(TGS4_COMM_WORLD_REBOOT)
|
||||
/datum/tgs_api/v5/OnReboot()
|
||||
var/list/result = Bridge(DMAPI5_BRIDGE_COMMAND_REBOOT)
|
||||
if(!result)
|
||||
return
|
||||
|
||||
//okay so the standard TGS4 proceedure is: right before rebooting change the port to whatever was sent to us in the above json's data parameter
|
||||
|
||||
var/port = result[TGS4_PARAMETER_DATA]
|
||||
var/port = result[DMAPI5_BRIDGE_RESPONSE_NEW_PORT]
|
||||
if(!isnum(port))
|
||||
return //this is valid, server may just want use to reboot
|
||||
|
||||
@@ -249,74 +216,74 @@
|
||||
if(!world.OpenPort(port))
|
||||
TGS_ERROR_LOG("Unable to set port to [port]!")
|
||||
|
||||
/datum/tgs_api/v4/InstanceName()
|
||||
/datum/tgs_api/v5/InstanceName()
|
||||
return instance_name
|
||||
|
||||
/datum/tgs_api/v4/TestMerges()
|
||||
/datum/tgs_api/v5/TestMerges()
|
||||
return cached_test_merges
|
||||
|
||||
/datum/tgs_api/v4/EndProcess()
|
||||
Export(TGS4_COMM_END_PROCESS)
|
||||
/datum/tgs_api/v5/EndProcess()
|
||||
Bridge(DMAPI5_BRIDGE_COMMAND_KILL)
|
||||
|
||||
/datum/tgs_api/v4/Revision()
|
||||
/datum/tgs_api/v5/Revision()
|
||||
return cached_revision
|
||||
|
||||
/datum/tgs_api/v4/ChatBroadcast(message, list/channels)
|
||||
/datum/tgs_api/v5/ChatBroadcast(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 = list(DMAPI5_CHAT_MESSAGE_TEXT = message, DMAPI5_CHAT_MESSAGE_CHANNEL_IDS = ids)
|
||||
if(intercepted_message_queue)
|
||||
intercepted_message_queue += list(message)
|
||||
else
|
||||
Export(TGS4_COMM_CHAT, message)
|
||||
Bridge(DMAPI5_BRIDGE_PARAMETER_CHAT_MESSAGE, message)
|
||||
|
||||
/datum/tgs_api/v4/ChatTargetedBroadcast(message, admin_only)
|
||||
/datum/tgs_api/v5/ChatTargetedBroadcast(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 = list(DMAPI5_CHAT_MESSAGE_TEXT = message, DMAPI5_CHAT_MESSAGE_CHANNEL_IDS = 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/v5/ChatPrivateMessage(message, datum/tgs_chat_user/user)
|
||||
message = list(DMAPI5_CHAT_MESSAGE_TEXT = message, DMAPI5_CHAT_MESSAGE_CHANNEL_IDS = list(user.channel.id))
|
||||
if(intercepted_message_queue)
|
||||
intercepted_message_queue += list(message)
|
||||
else
|
||||
Export(TGS4_COMM_CHAT, message)
|
||||
|
||||
/datum/tgs_api/v4/ChatChannelInfo()
|
||||
/datum/tgs_api/v5/ChatChannelInfo()
|
||||
. = list()
|
||||
//no caching cause tgs may change this
|
||||
var/list/json = json_decode(file2text(chat_channels_json_path))
|
||||
for(var/I in json)
|
||||
. += DecodeChannel(I)
|
||||
|
||||
/datum/tgs_api/v4/proc/DecodeChannel(channel_json)
|
||||
/datum/tgs_api/v5/proc/DecodeChannel(channel_json)
|
||||
var/datum/tgs_chat_channel/channel = new
|
||||
channel.id = channel_json["id"]
|
||||
channel.friendly_name = channel_json["friendlyName"]
|
||||
channel.connection_name = channel_json["connectionName"]
|
||||
channel.is_admin_channel = channel_json["isAdminChannel"]
|
||||
channel.is_private_channel = channel_json["isPrivateChannel"]
|
||||
channel.custom_tag = channel_json["tag"]
|
||||
channel.id = channel_json[DMAPI5_CHAT_CHANNEL_ID]
|
||||
channel.friendly_name = channel_json[DMAPI5_CHAT_CHANNEL_FRIENDLY_NAME]
|
||||
channel.connection_name = channel_json[DMAPI5_CHAT_CHANNEL_CONNECTION_NAME]
|
||||
channel.is_admin_channel = channel_json[DMAPI5_CHAT_CHANNEL_IS_ADMIN_CHANNEL]
|
||||
channel.is_private_channel = channel_json[DMAPI5_CHAT_CHANNEL_IS_PRIVATE_CHANNEL]
|
||||
channel.custom_tag = channel_json[DMAPI5_CHAT_CHANNEL_TAG]
|
||||
return channel
|
||||
|
||||
/datum/tgs_api/v4/SecurityLevel()
|
||||
/datum/tgs_api/v5/SecurityLevel()
|
||||
return security_level
|
||||
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2017 Jordan Brown
|
||||
Copyright (c) 2020 Jordan Brown
|
||||
|
||||
Permission is hereby granted, free of charge,
|
||||
to any person obtaining a copy of this software and
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/datum/tgs_api/v4/proc/ListCustomCommands()
|
||||
/datum/tgs_api/v5/proc/ListCustomCommands()
|
||||
var/results = list()
|
||||
custom_commands = list()
|
||||
for(var/I in typesof(/datum/tgs_chat_command) - /datum/tgs_chat_command)
|
||||
@@ -12,7 +12,7 @@
|
||||
var/datum/other = custom_commands[command_name]
|
||||
TGS_ERROR_LOG("Custom commands [other.type] and [I] have the same name (\"[command_name]\"), only [other.type] will be available!")
|
||||
continue
|
||||
results += list(list("name" = command_name, "help_text" = stc.help_text, "admin_only" = stc.admin_only))
|
||||
results += list(list(DMAPI5_CUSTOM_CHAT_COMMAND_NAME = command_name, DMAPI5_CUSTOM_CHAT_COMMAND_HELP_TEXT = stc.help_text, DMAPI5_CUSTOM_CHAT_COMMAND_ADMIN_ONLY = stc.admin_only))
|
||||
custom_commands[command_name] = stc
|
||||
|
||||
var/commands_file = chat_commands_json_path
|
||||
@@ -20,31 +20,31 @@
|
||||
return
|
||||
text2file(json_encode(results), commands_file)
|
||||
|
||||
/datum/tgs_api/v4/proc/HandleCustomCommand(command_json)
|
||||
var/list/data = json_decode(command_json)
|
||||
var/command = data["command"]
|
||||
var/user = data["user"]
|
||||
var/params = data["params"]
|
||||
/datum/tgs_api/v5/proc/HandleCustomCommand(list/command_json)
|
||||
var/command = data[DMAPI5_CHAT_COMMAND_NAME]
|
||||
var/user = data[DMAPI5_CHAT_COMMAND_USER]
|
||||
var/params = data[DMAPI5_CHAT_COMMAND_PARAMS]
|
||||
|
||||
var/datum/tgs_chat_user/u = new
|
||||
u.id = user["id"]
|
||||
u.friendly_name = user["friendlyName"]
|
||||
u.mention = user["mention"]
|
||||
u.channel = DecodeChannel(user["channel"])
|
||||
u.id = user[DMAPI5_CHAT_USER_ID]
|
||||
u.friendly_name = user[DMAPI5_CHAT_USER_FRIENDLY_NAME]
|
||||
u.mention = user[DMAPI5_CHAT_USER_MENTION]
|
||||
u.channel = DecodeChannel(user[DMAPI5_CHAT_USER_CHANNEL])
|
||||
|
||||
var/datum/tgs_chat_command/sc = custom_commands[command]
|
||||
if(sc)
|
||||
var/result = sc.Run(u, params)
|
||||
if(result == null)
|
||||
result = ""
|
||||
return result
|
||||
return "Unknown command: [command]!"
|
||||
var/textResponse = sc.Run(u, params)
|
||||
var/list/topic_response = list()
|
||||
if(textResponse != null)
|
||||
topic_response(DMAPI5_TOPIC_RESPONSE_COMMAND_RESPONSE_MESSAGE = textResponse)
|
||||
return topic_response
|
||||
return TopicError("Unknown custom chat command: [command]!")
|
||||
|
||||
/*
|
||||
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2017 Jordan Brown
|
||||
Copyright (c) 2020 Jordan Brown
|
||||
|
||||
Permission is hereby granted, free of charge,
|
||||
to any person obtaining a copy of this software and
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
#undef DMAPI5_PARAM_RUNTIME_INFORMATION_FILE
|
||||
#undef DMAPI5_BRIDGE_DATA
|
||||
#undef DMAPI5_TOPIC_DATA
|
||||
|
||||
#undef DMAPI5_BRIDGE_COMMAND_PORT_UPDATE
|
||||
#undef DMAPI5_BRIDGE_COMMAND_VALIDATE
|
||||
#undef DMAPI5_BRIDGE_COMMAND_PRIME
|
||||
#undef DMAPI5_BRIDGE_COMMAND_REBOOT
|
||||
#undef DMAPI5_BRIDGE_COMMAND_KILL
|
||||
#undef DMAPI5_BRIDGE_COMMAND_CHAT_SEND
|
||||
|
||||
#undef DMAPI5_PARAMETER_ACCESS_IDENTIFIER
|
||||
#undef DMAPI5_RESPONSE_ERROR_MESSAGE
|
||||
|
||||
#undef DMAPI5_BRIDGE_PARAMETER_COMMAND_TYPE
|
||||
#undef DMAPI5_BRIDGE_PARAMETER_CURRENT_PORT
|
||||
#undef DMAPI5_BRIDGE_PARAMETER_VERSION
|
||||
#undef DMAPI5_BRIDGE_PARAMETER_CHAT_MESSAGE
|
||||
#undef DMAPI5_BRIDGE_PARAMETER_MINIMUM_SECURITY_LEVEL
|
||||
|
||||
#undef DMAPI5_BRIDGE_RESPONSE_NEW_PORT
|
||||
|
||||
#undef DMAPI5_CHAT_MESSAGE_TEXT
|
||||
#undef DMAPI5_CHAT_MESSAGE_CHANNEL_IDS
|
||||
|
||||
#undef DMAPI5_RUNTIME_INFORMATION_ACCESS_IDENTIFIER
|
||||
#undef DMAPI5_RUNTIME_INFORMATION_SERVER_VERSION
|
||||
#undef DMAPI5_RUNTIME_INFORMATION_SERVER_PORT
|
||||
#undef DMAPI5_RUNTIME_INFORMATION_API_VALIDATE_ONLY
|
||||
#undef DMAPI5_RUNTIME_INFORMATION_INSTANCE_NAME
|
||||
#undef DMAPI5_RUNTIME_INFORMATION_REVISION
|
||||
#undef DMAPI5_RUNTIME_INFORMATION_TEST_MERGES
|
||||
#undef DMAPI5_RUNTIME_INFORMATION_SECURITY_LEVEL
|
||||
#undef DMAPI5_RUNTIME_INFORMATION_CHAT_COMMANDS_JSON
|
||||
#undef DMAPI5_RUNTIME_INFORMATION_CHAT_CHANNELS_JSON
|
||||
|
||||
#undef DMAPI5_TEST_MERGE_TIME_MERGED
|
||||
#undef DMAPI5_TEST_MERGE_REVISION
|
||||
#undef DMAPI5_TEST_MERGE_TITLE_AT_MERGE
|
||||
#undef DMAPI5_TEST_MERGE_BODY_AT_MERGE
|
||||
#undef DMAPI5_TEST_MERGE_URL
|
||||
#undef DMAPI5_TEST_MERGE_AUTHOR
|
||||
#undef DMAPI5_TEST_MERGE_NUMBER
|
||||
#undef DMAPI5_TEST_MERGE_PULL_REQUEST_REVISION
|
||||
#undef DMAPI5_TEST_MERGE_COMMENT
|
||||
|
||||
#undef DMAPI5_CHAT_COMMAND_NAME
|
||||
#undef DMAPI5_CHAT_COMMAND_PARAMS
|
||||
#undef DMAPI5_CHAT_COMMAND_USER
|
||||
|
||||
#undef DMAPI5_EVENT_NOTIFICATION_TYPE
|
||||
#undef DMAPI5_EVENT_NOTIFICATION_PARAMETERS
|
||||
|
||||
#undef DMAPI5_TOPIC_COMMAND_CHAT_COMMAND
|
||||
#undef DMAPI5_TOPIC_COMMAND_EVENT_NOTIFICATION
|
||||
#undef DMAPI5_TOPIC_COMMAND_CHANGE_PORT
|
||||
#undef DMAPI5_TOPIC_COMMAND_CHANGE_REBOOT_STATE
|
||||
#undef DMAPI5_TOPIC_COMMAND_INSTANCE_RENAMED
|
||||
|
||||
#undef DMAPI5_TOPIC_PARAMETER_COMMAND_TYPE
|
||||
#undef DMAPI5_TOPIC_PARAMETER_CHAT_COMMAND
|
||||
#undef DMAPI5_TOPIC_PARAMETER_EVENT_NOTIFICATION
|
||||
#undef DMAPI5_TOPIC_PARAMETER_NEW_PORT
|
||||
#undef DMAPI5_TOPIC_PARAMETER_NEW_REBOOT_STATE
|
||||
#undef DMAPI5_TOPIC_PARAMETER_NEW_INSTANCE_NAME
|
||||
|
||||
#undef DMAPI5_TOPIC_RESPONSE_COMMAND_RESPONSE_MESSAGE
|
||||
#undef DMAPI5_TOPIC_RESPONSE_CHAT_RESPONSES
|
||||
|
||||
#undef DMAPI5_REVISION_INFORMATION_COMMIT_SHA
|
||||
#undef DMAPI5_REVISION_INFORMATION_ORIGIN_COMMIT_SHA
|
||||
|
||||
#undef DMAPI5_CHAT_USER_ID
|
||||
#undef DMAPI5_CHAT_USER_FRIENDLY_NAME
|
||||
#undef DMAPI5_CHAT_USER_MENTION
|
||||
#undef DMAPI5_CHAT_USER_CHANNEL
|
||||
|
||||
#undef DMAPI5_CHAT_CHANNEL_ID
|
||||
#undef DMAPI5_CHAT_CHANNEL_FRIENDLY_NAME
|
||||
#undef DMAPI5_CHAT_CHANNEL_CONNECTION_NAME
|
||||
#undef DMAPI5_CHAT_CHANNEL_IS_ADMIN_CHANNEL
|
||||
#undef DMAPI5_CHAT_CHANNEL_IS_PRIVATE_CHANNEL
|
||||
#undef DMAPI5_CHAT_CHANNEL_TAG
|
||||
|
||||
#undef DMAPI5_CUSTOM_CHAT_COMMAND_NAME
|
||||
#undef DMAPI5_CUSTOM_CHAT_COMMAND_HELP_TEXT
|
||||
#undef DMAPI5_CUSTOM_CHAT_COMMAND_ADMIN_ONLY
|
||||
|
||||
/*
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2020 Jordan Brown
|
||||
|
||||
Permission is hereby granted, free of charge,
|
||||
to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to
|
||||
deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify,
|
||||
merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom
|
||||
the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
@@ -6,7 +6,7 @@
|
||||
public sealed class BridgeResponse : DMApiResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// The new port for <see cref="BridgeCommandType.PortUpdate"/> requests.
|
||||
/// The new port for <see cref="BridgeCommandType.Reboot"/> requests.
|
||||
/// </summary>
|
||||
public ushort? NewPort { get; set; }
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace Tgstation.Server.Host.Components.Interop
|
||||
/// <summary>
|
||||
/// Parameter json is encoded in for topic requests.
|
||||
/// </summary>
|
||||
public const string TopicData = "data";
|
||||
public const string TopicData = "tgs_data";
|
||||
|
||||
/// <summary>
|
||||
/// The DMAPI <see cref="Version"/> being used.
|
||||
|
||||
@@ -22,3 +22,10 @@ var/list/clients = list()
|
||||
/client/Del()
|
||||
clients -= src
|
||||
return ..()
|
||||
|
||||
/datum/tgs_chat_command/echo
|
||||
name = "echo"
|
||||
help_text = "echos input parameters"
|
||||
|
||||
/datum/tgs_chat_command/echo/Run(datum/tgs_chat_user/sender, params)
|
||||
return "[sender.channel.connection_name]|[sender.channel.friendly_name]|[sender.friendly_name]: [params]"
|
||||
|
||||
Reference in New Issue
Block a user