From 382a15a916364c3fa412c93c2ac211fe94701680 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Wed, 25 Apr 2018 12:14:46 -0400 Subject: [PATCH] Add DMAPI compatibility layer --- .travis.yml | 2 +- DMAPI/server_tools.dm | 129 ---------- DMAPI/st_interface.dm | 135 ---------- DMAPI/tgs.dm | 202 +++++++++++++++ DMAPI/tgs/core/_definitions.dm | 2 + DMAPI/tgs/core/core.dm | 139 ++++++++++ DMAPI/tgs/core/datum.dm | 74 ++++++ DMAPI/tgs/core/default_event_handler.dm | 30 +++ DMAPI/tgs/includes.dm | 6 + DMAPI/tgs/v3210/api.dm | 242 ++++++++++++++++++ .../{st_commands.dm => tgs/v3210/commands.dm} | 53 ++-- TGS.Tests/TGS.Tests.csproj | 10 +- TGStationServer3.sln | 29 ++- Tools/Config.dm | 18 +- Tools/Test.dm | 28 +- ...DMAPITravisTester.dme => travistester.dme} | 5 +- 16 files changed, 768 insertions(+), 336 deletions(-) delete mode 100644 DMAPI/server_tools.dm delete mode 100644 DMAPI/st_interface.dm create mode 100644 DMAPI/tgs.dm create mode 100644 DMAPI/tgs/core/_definitions.dm create mode 100644 DMAPI/tgs/core/core.dm create mode 100644 DMAPI/tgs/core/datum.dm create mode 100644 DMAPI/tgs/core/default_event_handler.dm create mode 100644 DMAPI/tgs/includes.dm create mode 100644 DMAPI/tgs/v3210/api.dm rename DMAPI/{st_commands.dm => tgs/v3210/commands.dm} (51%) rename Tools/{DMAPITravisTester.dme => travistester.dme} (71%) diff --git a/.travis.yml b/.travis.yml index df970b29e7..b54966f76b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ env: global: - BYOND_MAJOR="511" - BYOND_MINOR="1385" - - DMEName="Tools/DMAPITravisTester.dme" + - DMEName="Tools/travistester.dme" matrix: - BUILD_CLIENT=true - BUILD_CLIENT=false diff --git a/DMAPI/server_tools.dm b/DMAPI/server_tools.dm deleted file mode 100644 index 2540dac4ba..0000000000 --- a/DMAPI/server_tools.dm +++ /dev/null @@ -1,129 +0,0 @@ -// /tg/station 13 server tools API -#define SERVICE_API_VERSION_STRING "3.2.0.3" - -//CONFIGURATION -//use this define if you want to do configuration outside of this file -#ifndef SERVER_TOOLS_EXTERNAL_CONFIGURATION -//Comment this out once you've filled in the below -#error /tg/station server tools interface unconfigured - -//Required interfaces (fill in with your codebase equivalent): - -//create a global variable named `Name` and set it to `Value` -//These globals must not be modifiable from anywhere outside of the server tools -#define SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(Name, Value) -//Read the value in the global variable `Name` -#define SERVER_TOOLS_READ_GLOBAL(Name) -//Set the value in the global variable `Name` to `Value` -#define SERVER_TOOLS_WRITE_GLOBAL(Name, Value) -//display an announcement `message` from the server to all players -#define SERVER_TOOLS_WORLD_ANNOUNCE(message) -//Write a string `message` to a server log -#define SERVER_TOOLS_LOG(message) -//Notify current in-game administrators of a string `event` -#define SERVER_TOOLS_NOTIFY_ADMINS(event) -//The current amount of connected clients -#define SERVER_TOOLS_CLIENT_COUNT -#endif - -//Required hooks: - -//Put this somewhere in /world/New() that is always run -#define SERVER_TOOLS_ON_NEW ServiceInit() -//Put this somewhere in /world/Topic(T, Addr, Master, Keys) that is always run before T is modified -#define SERVER_TOOLS_ON_TOPIC var/service_topic_return = ServiceCommand(params2list(T)); if(service_topic_return) return service_topic_return -//Put at the beginning of world/Reboot(reason) -#define SERVER_TOOLS_ON_REBOOT ServiceReboot() - -//Optional callable functions: - -//Returns the string version of the API -#define SERVER_TOOLS_API_VERSION ServiceAPIVersion() -//Returns TRUE if the world was launched under the server tools and the API matches, FALSE otherwise -//No function below this succeed if this is FALSE -#define SERVER_TOOLS_PRESENT RunningService() -//Gets the current version of the service running the server -#define SERVER_TOOLS_VERSION ServiceVersion() -//Forces a hard reboot of BYOND by ending the process -//unlike del(world) clients will try to reconnect -//If the service has not requested a shutdown, the world will reboot shortly after -#define SERVER_TOOLS_REBOOT_BYOND(silent) world.ServiceEndProcess(silent) -/* - Gets the list of any testmerged github pull requests - - "[PR Number]" => list( - "title" -> PR title - "commit" -> Full hash of commit merged - "author" -> Github username of the author of the PR - ) -*/ -#define SERVER_TOOLS_PR_LIST GetTestMerges() -//Sends a message to connected game chats -#define SERVER_TOOLS_CHAT_BROADCAST(message) world.ChatBroadcast(message) -//Sends a message to connected admin chats -#define SERVER_TOOLS_RELAY_BROADCAST(message) world.AdminBroadcast(message) - -//IMPLEMENTATION - -#define REBOOT_MODE_NORMAL 0 -#define REBOOT_MODE_HARD 1 -#define REBOOT_MODE_SHUTDOWN 2 - -#define SERVICE_WORLD_PARAM "server_service" -#define SERVICE_VERSION_PARAM "server_service_version" -#define SERVICE_INSTANCE_PARAM "server_instance" -#define SERVICE_PR_TEST_JSON "prtestjob.json" -#define SERVICE_INTERFACE_DLL "TGDreamDaemonBridge.dll" -#define SERVICE_INTERFACE_FUNCTION "DDEntryPoint" - -#define SERVICE_CMD_HARD_REBOOT "hard_reboot" -#define SERVICE_CMD_GRACEFUL_SHUTDOWN "graceful_shutdown" -#define SERVICE_CMD_WORLD_ANNOUNCE "world_announce" -#define SERVICE_CMD_LIST_CUSTOM "list_custom_commands" -#define SERVICE_CMD_API_COMPATIBLE "api_compat" -#define SERVICE_CMD_PLAYER_COUNT "client_count" - -#define SERVICE_CMD_PARAM_KEY "serviceCommsKey" -#define SERVICE_CMD_PARAM_COMMAND "command" -#define SERVICE_CMD_PARAM_SENDER "sender" -#define SERVICE_CMD_PARAM_CUSTOM "custom" - -#define SERVICE_JSON_PARAM_HELPTEXT "help_text" -#define SERVICE_JSON_PARAM_ADMINONLY "admin_only" -#define SERVICE_JSON_PARAM_REQUIREDPARAMETERS "required_parameters" - -#define SERVICE_REQUEST_KILL_PROCESS "killme" -#define SERVICE_REQUEST_KILL_PROCESS_SILENT "killmesilent" -#define SERVICE_REQUEST_IRC_BROADCAST "irc" -#define SERVICE_REQUEST_IRC_ADMIN_CHANNEL_MESSAGE "send2irc" -#define SERVICE_REQUEST_WORLD_REBOOT "worldreboot" -#define SERVICE_REQUEST_API_VERSION "api_ver" - -#define SERVICE_RETURN_SUCCESS "SUCCESS" - -/* -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. -*/ diff --git a/DMAPI/st_interface.dm b/DMAPI/st_interface.dm deleted file mode 100644 index 931ab10ff3..0000000000 --- a/DMAPI/st_interface.dm +++ /dev/null @@ -1,135 +0,0 @@ -SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(reboot_mode, REBOOT_MODE_NORMAL) -SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(server_tools_api_compatible, FALSE) - -/proc/GetTestMerges() - if(RunningService(TRUE) && fexists(SERVICE_PR_TEST_JSON)) - . = json_decode(file2text(SERVICE_PR_TEST_JSON)) - if(.) - return - return list() - -/world/proc/ServiceInit() - if(!RunningService(TRUE)) - return - ListServiceCustomCommands(TRUE) - ExportService("[SERVICE_REQUEST_API_VERSION] [SERVER_TOOLS_API_VERSION]", TRUE) - -/proc/RunningService(skip_compat_check = FALSE) - if(!skip_compat_check && !SERVER_TOOLS_READ_GLOBAL(server_tools_api_compatible)) - return FALSE - . = world.params[SERVICE_WORLD_PARAM] != null - if(. && world.system_type != MS_WINDOWS) - SERVER_TOOLS_LOG("Warning: Server tools world parameter detected but not running on Windows. Aborting initialization!") - return FALSE - -/proc/ServiceVersion() - if(RunningService(TRUE)) - return world.params[SERVICE_VERSION_PARAM] - -/proc/ServiceAPIVersion() - return SERVICE_API_VERSION_STRING - -/world/proc/ExportService(command, skip_compat_check = FALSE) - . = FALSE - if(!RunningService(skip_compat_check)) - return - if(skip_compat_check && !fexists(SERVICE_INTERFACE_DLL)) - CRASH("Service parameter present but no interface DLL detected. This is symptomatic of running a service less than version 3.1! Please upgrade.") - var/instance = params[SERVICE_INSTANCE_PARAM] - if(!instance) - instance = "TG Station Server" //maybe just upgraded - call(SERVICE_INTERFACE_DLL, SERVICE_INTERFACE_FUNCTION)(instance, command) //trust no retval - return TRUE - -/world/proc/ChatBroadcast(message) - ExportService("[SERVICE_REQUEST_IRC_BROADCAST] [message]") - -/world/proc/AdminBroadcast(message) - ExportService("[SERVICE_REQUEST_IRC_ADMIN_CHANNEL_MESSAGE] [message]") - -/world/proc/ServiceEndProcess(silent = FALSE) - SERVER_TOOLS_LOG("Sending shutdown request!"); - sleep(world.tick_lag) //flush the buffers - ExportService(silent ? SERVICE_REQUEST_KILL_PROCESS_SILENT : SERVICE_REQUEST_KILL_PROCESS) - -//called at the exact moment the world is supposed to reboot -/world/proc/ServiceReboot() - switch(SERVER_TOOLS_READ_GLOBAL(reboot_mode)) - if(REBOOT_MODE_HARD) - SERVER_TOOLS_WORLD_ANNOUNCE("Hard reboot triggered, you will automatically reconnect...") - ServiceEndProcess() - if(REBOOT_MODE_SHUTDOWN) - SERVER_TOOLS_WORLD_ANNOUNCE("The server is shutting down...") - ServiceEndProcess() - else - ExportService(SERVICE_REQUEST_WORLD_REBOOT) //just let em know - -/world/proc/ServiceCommand(list/params) - var/their_sCK = params[SERVICE_CMD_PARAM_KEY] - if(!their_sCK || !RunningService(TRUE)) - return FALSE //continue world/Topic - - var/sCK = world.params[SERVICE_WORLD_PARAM] - if(their_sCK != sCK) - return "Invalid comms key!"; - - var/command = params[SERVICE_CMD_PARAM_COMMAND] - if(!command) - return "No command!" - - switch(command) - if(SERVICE_CMD_API_COMPATIBLE) - SERVER_TOOLS_WRITE_GLOBAL(server_tools_api_compatible, TRUE) - return SERVICE_RETURN_SUCCESS - if(SERVICE_CMD_HARD_REBOOT) - if(SERVER_TOOLS_READ_GLOBAL(reboot_mode) != REBOOT_MODE_HARD) - SERVER_TOOLS_WRITE_GLOBAL(reboot_mode, REBOOT_MODE_HARD) - SERVER_TOOLS_LOG("Hard reboot requested by service") - SERVER_TOOLS_NOTIFY_ADMINS("The world will hard reboot at the end of the game. Requested by service.") - if(SERVICE_CMD_GRACEFUL_SHUTDOWN) - if(SERVER_TOOLS_READ_GLOBAL(reboot_mode) != REBOOT_MODE_SHUTDOWN) - SERVER_TOOLS_WRITE_GLOBAL(reboot_mode, REBOOT_MODE_SHUTDOWN) - SERVER_TOOLS_LOG("Shutdown requested by service") - message_admins("The world will shutdown at the end of the game. Requested by service.") - if(SERVICE_CMD_WORLD_ANNOUNCE) - var/msg = params["message"] - if(!istext(msg) || !msg) - return "No message set!" - SERVER_TOOLS_WORLD_ANNOUNCE(msg) - return SERVICE_RETURN_SUCCESS - if(SERVICE_CMD_PLAYER_COUNT) - return "[SERVER_TOOLS_CLIENT_COUNT]" - if(SERVICE_CMD_LIST_CUSTOM) - return json_encode(ListServiceCustomCommands(FALSE)) - else - var/custom_command_result = HandleServiceCustomCommand(lowertext(command), params[SERVICE_CMD_PARAM_SENDER], params[SERVICE_CMD_PARAM_CUSTOM]) - if(custom_command_result) - return istext(custom_command_result) ? custom_command_result : SERVICE_RETURN_SUCCESS - return "Unknown command: [command]" - -/* -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. -*/ diff --git a/DMAPI/tgs.dm b/DMAPI/tgs.dm new file mode 100644 index 0000000000..e885b06397 --- /dev/null +++ b/DMAPI/tgs.dm @@ -0,0 +1,202 @@ +//tgstation-server DMAPI + +//All functions and datums outside this document are subject to change with any version and should not be relied on + +//CONFIGURATION + +//create this define if you want to do configuration outside of this file +#ifndef TGS_EXTERNAL_CONFIGURATION + +//Comment this out once you've filled in the below +#error TGS API unconfigured + +//Required interfaces (fill in with your codebase equivalent): + +//create a global variable named `Name` and set it to `Value` +//These globals must not be modifiable from anywhere outside of the server tools +#define TGS_DEFINE_AND_SET_GLOBAL(Name, Value) + +//Read the value in the global variable `Name` +#define TGS_READ_GLOBAL(Name) + +//Set the value in the global variable `Name` to `Value` +#define TGS_WRITE_GLOBAL(Name, Value) + +//Disallow ANYONE from reflecting a given `path`, security measure to prevent in-game priveledge escalation +#define TGS_PROTECT_DATUM(Path) + +//display an announcement `message` from the server to all players +#define TGS_WORLD_ANNOUNCE(message) + +//Notify current in-game administrators of a string `event` +#define TGS_NOTIFY_ADMINS(event) + +//Write an info `message` to a server log +#define TGS_INFO_LOG(message) + +//Write an error `message` to a server log +#define TGS_ERROR_LOG(message) + +//Get the number of connected /clients +#define TGS_CLIENT_COUNT + +#endif + +//EVENT CODES + +//TODO + +//REQUIRED HOOKS + +//Call this somewhere in /world/New() that is always run +//event_handler: optional user defined event handler. The default behaviour is to broadcast the event in english to all connected admin channels +/world/proc/TgsNew(datum/tgs_event_handler/event_handler) + return + +//Call this when your initializations are complete and your game is ready to play before any player interactions happen +//This may use world.sleep_offline to make this happen so ensure no changes are made to it while this call is running +/world/proc/TgsInitializationComplete() + return + +//Put this somewhere in /world/Topic(T, Addr, Master, Keys) that is always run before T is modified +#define TGS_TOPIC var/tgs_topic_return = TgsTopic(T); if(tgs_topic_return) return tgs_topic_return + +//Call this at the beginning of world/Reboot(reason) +/world/proc/TgsReboot() + return + +//DATUM DEFINITIONS +//unless otherwise specified all datums defined here should be considered read-only, warranty void if written + +//represents git revision information about the current world build +/datum/tgs_revision_information + var/commit //full sha of compiled commit + var/origin_commit //full sha of last known remote commit. This may be null if the TGS repository is not currently tracking a remote branch + +//represents a merge of a GitHub pull request +/datum/tgs_revision_information/test_merge + var/number //pull request number + var/title //pull request title + var/body //pull request body + var/author //pull request github author + var/url //link to pull request html + var/pull_request_commit //commit of the pull request when it was merged + var/time_merged //timestamp of when the merge commit for the pull request was created + var/comment //optional comment left by the one who initiated the test merge + +//represents a connected chat channel +/datum/tgs_chat_channel + var/id //internal channel representation + var/friendly_name //user friendly channel name + var/server_name //server name the channel resides on + var/provider_name //chat provider for the channel + var/is_admin_channel //if the server operator has marked this channel for game admins only + var/is_private_channel //if this is a private chat channel + +//represents a chat user +/datum/tgs_chat_user + var/id //Internal user representation + var/friendly_name //The user's public name + var/mention //The text to use to ping this user in a message + var/datum/tgs_chat_channel/channel //The /datum/tgs_chat_channel this user was from + +//user definable callback for handling events +/datum/tgs_event_handler/proc/HandleEvent(event_code) + return + +//user definable chat command +/datum/tgs_chat_command + var/name = "" //the string to trigger this command on a chat bot. e.g. TGS3_BOT: do_this_command + var/help_text = "" //help text for this command + var/admin_only = FALSE //set to TRUE if this command should only be usable by registered chat admins + +//override to implement command +//sender: The tgs_chat_user who send to command +//params: The trimmed string following the command name +//The return value will be stringified and sent to the appropriate chat +/datum/tgs_chat_command/proc/Run(datum/tgs_chat_user/sender, params) + CRASH("[type] has no implementation for Run()") + +//FUNCTIONS + +//Returns the respective string version of the API +/world/proc/TgsMaximumAPIVersion() + return + +/world/proc/TgsMinimumAPIVersion() + return + +//Gets the current version of the server tools running the server +/world/proc/TgsVersion() + return + +//Returns TRUE if the world was launched under the server tools and the API matches, FALSE otherwise +//No function below this succeeds if it returns FALSE +/world/proc/TgsAvailable() + return + +/world/proc/TgsInstanceName() + return + +//Get the current `/datum/tgs_revision_information` +/world/proc/TgsRevision() + return + +//Gets a list of active `/datum/tgs_revision_information/test_merge`s +/world/proc/TgsTestMerges() + return + +//Forces a hard reboot of BYOND by ending the process +//unlike del(world) clients will try to reconnect +//If the service has not requested a shutdown, the next server will take over +/world/proc/TgsEndProcess() + return + +//Gets a list of connected tgs_chat_channel +/world/proc/TgsChatChannelInfo() + return + +//Sends a message to connected game chats +//message: The message to send +//channels: optional channels to limit the broadcast to +/world/proc/TgsChatBroadcast(message, list/channels) + return + +//Send a message to non-admin connected chats +//message: The message to send +//admin_only: If TRUE, message will instead be sent to only admin connected chats +/world/proc/TgsTargetedChatBroadcast(message, admin_only) + return + +//Send a private message to a specific user +//message: The message to send +//user: The /datum/tgs_chat_user to send to +/world/proc/TgsChatPrivateMessage(message, datum/tgs_chat_user/user) + return + +/* +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. +*/ diff --git a/DMAPI/tgs/core/_definitions.dm b/DMAPI/tgs/core/_definitions.dm new file mode 100644 index 0000000000..ebf6d17c2a --- /dev/null +++ b/DMAPI/tgs/core/_definitions.dm @@ -0,0 +1,2 @@ +#define TGS_UNIMPLEMENTED "___unimplemented" +#define TGS_VERSION_PARAMETER "server_service_version" diff --git a/DMAPI/tgs/core/core.dm b/DMAPI/tgs/core/core.dm new file mode 100644 index 0000000000..ffeab4289b --- /dev/null +++ b/DMAPI/tgs/core/core.dm @@ -0,0 +1,139 @@ +/world/TgsNew(datum/tgs_event_handler/event_handler) + var/tgs_version = world.params[TGS_VERSION_PARAMETER] + if(!tgs_version) + return + + var/path = SelectTgsApi(tgs_version) + if(!path) + TGS_ERROR_LOG("Found unsupported API version: [tgs_version]. If this is a valid version please report this, backporting is done on demand.") + + var/datum/tgs_api/new_api = new path + TGS_INFO_LOG("Activated tgstation-server API for version [tgs_version]") + + var/result = new_api.OnWorldNew(event_handler ? event_handler : new /datum/tgs_event_handler/tgs_default) + if(result && result != TGS_UNIMPLEMENTED) + TGS_WRITE_GLOBAL(tgs, new_api) + +/world/proc/SelectTgsApi(tgs_version) + var/list/version_bits = splittext(tgs_version, ".") + + var/super = text2num(version_bits[0]) + var/major = text2num(version_bits[1]) + var/minor = text2num(version_bits[2]) + var/patch = text2num(version_bits[3]) + + switch(super) + if(3) + switch(major) + if(2) + return /datum/tgs_api/v3210 + + if(super != null && major != null && minor != null && patch != null && tgs_version > TgsMaximumAPIVersion()) + TGS_ERROR_LOG("Detected unknown API version! Defaulting to latest. Update the DMAPI to fix this problem.") + return /datum/tgs_api/latest + +/world/TgsMaximumAPIVersion() + return "4.0.0.0" + +/world/TgsMinimumAPIVersion() + return "3.2.0.0" + +/world/TgsInitializationComplete() + var/datum/tgs_api/api = TGS_READ_GLOBAL(tgs) + if(api) + api.OnInitializationComplete() + +/world/proc/TgsTopic(T) + var/datum/tgs_api/api = TGS_READ_GLOBAL(tgs) + if(api) + var/result = api.OnTopic(T) + if(result != TGS_UNIMPLEMENTED) + return result + +/world/TgsRevision() + var/datum/tgs_api/api = TGS_READ_GLOBAL(tgs) + if(api) + var/result = api.Revision() + if(result != TGS_UNIMPLEMENTED) + return result + +/world/TgsReboot() + var/datum/tgs_api/api = TGS_READ_GLOBAL(tgs) + if(api) + api.OnReboot() + +/world/TgsAvailable() + return TGS_READ_GLOBAL(tgs) != null + +/world/TgsVersion() + return world.params[TGS_VERSION_PARAMETER] + +/world/TgsInstanceName() + var/datum/tgs_api/api = TGS_READ_GLOBAL(tgs) + if(api) + var/result = api.InstanceName() + if(result != TGS_UNIMPLEMENTED) + return result + +/world/TgsTestMerges() + var/datum/tgs_api/api = TGS_READ_GLOBAL(tgs) + if(api) + var/result = api.TestMerges() + if(result != TGS_UNIMPLEMENTED) + return result + return list() + +/world/TgsEndProcess() + var/datum/tgs_api/api = TGS_READ_GLOBAL(tgs) + if(api) + api.EndProcess() + +/world/TgsChatChannelInfo() + var/datum/tgs_api/api = TGS_READ_GLOBAL(tgs) + if(api) + var/result = api.ChatChannelInfo() + if(result != TGS_UNIMPLEMENTED) + return result + return list() + +/world/TgsChatBroadcast(message, list/channels) + var/datum/tgs_api/api = TGS_READ_GLOBAL(tgs) + if(api) + api.ChatBroadcast(message, channels) + +/world/TgsTargetedChatBroadcast(message, admin_only) + var/datum/tgs_api/api = TGS_READ_GLOBAL(tgs) + if(api) + api.ChatTargetedBroadcast(message, admin_only) + +/world/TgsChatPrivateMessage(message, datum/tgs_chat_user/user) + var/datum/tgs_api/api = TGS_READ_GLOBAL(tgs) + if(api) + api.ChatPrivateMessage(message, user) + +/* +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. +*/ diff --git a/DMAPI/tgs/core/datum.dm b/DMAPI/tgs/core/datum.dm new file mode 100644 index 0000000000..0a8782529e --- /dev/null +++ b/DMAPI/tgs/core/datum.dm @@ -0,0 +1,74 @@ +TGS_DEFINE_AND_SET_GLOBAL(datum/tgs_api/tgs, null) + +/datum/tgs_api + +/datum/tgs_api/latest + parent_type = /datum/tgs_api/v3210 + +TGS_PROTECT_DATUM(/datum/tgs_api) + +/datum/tgs_api/proc/ApiVersion() + return TGS_UNIMPLEMENTED + +/datum/tgs_api/proc/OnWorldNew(datum/tgs_event_handler/event_handler) + return TGS_UNIMPLEMENTED + +/datum/tgs_api/proc/OnInitializationComplete() + return TGS_UNIMPLEMENTED + +/datum/tgs_api/proc/OnTopic(T) + return TGS_UNIMPLEMENTED + +/datum/tgs_api/proc/OnReboot() + return TGS_UNIMPLEMENTED + +/datum/tgs_api/proc/InstanceName() + return TGS_UNIMPLEMENTED + +/datum/tgs_api/proc/TestMerges() + return TGS_UNIMPLEMENTED + +/datum/tgs_api/proc/EndProcess() + return TGS_UNIMPLEMENTED + +/datum/tgs_api/proc/Revision() + return TGS_UNIMPLEMENTED + +/datum/tgs_api/proc/ChatChannelInfo() + return TGS_UNIMPLEMENTED + +/datum/tgs_api/proc/ChatBroadcast(message, list/channels) + return TGS_UNIMPLEMENTED + +/datum/tgs_api/proc/ChatTargetedBroadcast(message, admin_only) + return TGS_UNIMPLEMENTED + +/datum/tgs_api/proc/ChatPrivateMessage(message, admin_only) + return TGS_UNIMPLEMENTED + +/* +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. +*/ diff --git a/DMAPI/tgs/core/default_event_handler.dm b/DMAPI/tgs/core/default_event_handler.dm new file mode 100644 index 0000000000..716715bb26 --- /dev/null +++ b/DMAPI/tgs/core/default_event_handler.dm @@ -0,0 +1,30 @@ +/datum/tgs_event_handler/tgs_default/HandleEvent(event_code) + //TODO + return + +/* +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. +*/ diff --git a/DMAPI/tgs/includes.dm b/DMAPI/tgs/includes.dm new file mode 100644 index 0000000000..7ca906c840 --- /dev/null +++ b/DMAPI/tgs/includes.dm @@ -0,0 +1,6 @@ +#include "core\_definitions.dm" +#include "core\core.dm" +#include "core\datum.dm" +#include "core\default_event_handler.dm" +#include "v3210\api.dm" +#include "v3210\commands.dm" diff --git a/DMAPI/tgs/v3210/api.dm b/DMAPI/tgs/v3210/api.dm new file mode 100644 index 0000000000..7de257f9b4 --- /dev/null +++ b/DMAPI/tgs/v3210/api.dm @@ -0,0 +1,242 @@ +#define REBOOT_MODE_NORMAL 0 +#define REBOOT_MODE_HARD 1 +#define REBOOT_MODE_SHUTDOWN 2 + +#define SERVICE_WORLD_PARAM "server_service" +#define SERVICE_INSTANCE_PARAM "server_instance" +#define SERVICE_PR_TEST_JSON "prtestjob.json" +#define SERVICE_INTERFACE_DLL "TGDreamDaemonBridge.dll" +#define SERVICE_INTERFACE_FUNCTION "DDEntryPoint" + +#define SERVICE_CMD_HARD_REBOOT "hard_reboot" +#define SERVICE_CMD_GRACEFUL_SHUTDOWN "graceful_shutdown" +#define SERVICE_CMD_WORLD_ANNOUNCE "world_announce" +#define SERVICE_CMD_LIST_CUSTOM "list_custom_commands" +#define SERVICE_CMD_API_COMPATIBLE "api_compat" +#define SERVICE_CMD_PLAYER_COUNT "client_count" + +#define SERVICE_CMD_PARAM_KEY "serviceCommsKey" +#define SERVICE_CMD_PARAM_COMMAND "command" +#define SERVICE_CMD_PARAM_SENDER "sender" +#define SERVICE_CMD_PARAM_CUSTOM "custom" + +#define SERVICE_REQUEST_KILL_PROCESS "killme" +#define SERVICE_REQUEST_IRC_BROADCAST "irc" +#define SERVICE_REQUEST_IRC_ADMIN_CHANNEL_MESSAGE "send2irc" +#define SERVICE_REQUEST_WORLD_REBOOT "worldreboot" +#define SERVICE_REQUEST_API_VERSION "api_ver" + +#define SERVICE_RETURN_SUCCESS "SUCCESS" + +/datum/tgs_api/v3210 + var/reboot_mode = REBOOT_MODE_NORMAL + var/comms_key + var/instance_name + var/originmastercommit + var/commit + var/list/cached_custom_tgs_chat_commands + var/warned_revison = FALSE + var/warned_custom_commands = FALSE + +/datum/tgs_api/v3210/ApiVersion() + return "3.2.1.0" + +/datum/tgs_api/v3210/proc/trim_left(text) + for (var/i = 1 to length(text)) + if (text2ascii(text, i) > 32) + return copytext(text, i) + return "" + +/datum/tgs_api/v3210/proc/trim_right(text) + for (var/i = length(text), i > 0, i--) + if (text2ascii(text, i) > 32) + return copytext(text, 1, i + 1) + return "" + +/datum/tgs_api/v3210/OnWorldNew(datum/tgs_event_handler/event_handler) //don't use event handling in this version + comms_key = world.params[SERVICE_WORLD_PARAM] + instance_name = world.params[SERVICE_INSTANCE_PARAM] + if(!instance_name) + instance_name = "TG Station Server" //maybe just upgraded + + var/list/logs = splittext(trim_left(trim_right(file2text(".git/logs/HEAD"))), "\n") + if(logs.len) + logs = splittext(logs[logs.len - 1], " ") + commit = logs[2] + logs = world.file2list(".git/logs/refs/remotes/origin/master") + if(logs.len) + originmastercommit = splittext(logs[logs.len - 1], " ")[2] + + if(world.system_type != MS_WINDOWS) + TGS_ERROR_LOG("This API version is only supported on Windows. Not running on Windows. Aborting initialization!") + return FALSE + ListServiceCustomCommands(TRUE) + ExportService("[SERVICE_REQUEST_API_VERSION] [ApiVersion()]", TRUE) + +/world/proc/file2list(filename, seperator="\n", trim = TRUE) + +//nothing to do for v3 +/datum/tgs_api/v3210/OnInitializationComplete() + return + +/datum/tgs_api/v3210/InstanceName() + return world.params[SERVICE_INSTANCE_PARAM] + +/datum/tgs_api/v3210/proc/ExportService(command, skip_compat_check = FALSE) + . = FALSE + 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 + call(SERVICE_INTERFACE_DLL, SERVICE_INTERFACE_FUNCTION)(instance_name, command) //trust no retval + return TRUE + +/datum/tgs_api/v3210/OnTopic(T) + var/list/params = params2list(T) + var/their_sCK = params[SERVICE_CMD_PARAM_KEY] + if(!their_sCK) + return FALSE //continue world/Topic + + if(their_sCK != comms_key) + return "Invalid comms key!"; + + var/command = params[SERVICE_CMD_PARAM_COMMAND] + if(!command) + return "No command!" + + switch(command) + if(SERVICE_CMD_API_COMPATIBLE) + return SERVICE_RETURN_SUCCESS + if(SERVICE_CMD_HARD_REBOOT) + if(reboot_mode != REBOOT_MODE_HARD) + reboot_mode = REBOOT_MODE_HARD + TGS_INFO_LOG("Hard reboot requested by service") + TGS_NOTIFY_ADMINS("The world will hard reboot at the end of the game. Requested by TGS.") + if(SERVICE_CMD_GRACEFUL_SHUTDOWN) + if(reboot_mode != REBOOT_MODE_SHUTDOWN) + reboot_mode = REBOOT_MODE_SHUTDOWN + TGS_INFO_LOG("Shutdown requested by service") + TGS_NOTIFY_ADMINS("The world will shutdown at the end of the game. Requested by TGS.") + if(SERVICE_CMD_WORLD_ANNOUNCE) + var/msg = params["message"] + if(!istext(msg) || !msg) + return "No message set!" + TGS_WORLD_ANNOUNCE(msg) + return SERVICE_RETURN_SUCCESS + if(SERVICE_CMD_PLAYER_COUNT) + return "[TGS_CLIENT_COUNT]" + if(SERVICE_CMD_LIST_CUSTOM) + return json_encode(ListServiceCustomCommands(FALSE)) + else + var/custom_command_result = HandleServiceCustomCommand(lowertext(command), params[SERVICE_CMD_PARAM_SENDER], params[SERVICE_CMD_PARAM_CUSTOM]) + if(custom_command_result) + return istext(custom_command_result) ? custom_command_result : SERVICE_RETURN_SUCCESS + return "Unknown command: [command]" + +/datum/tgs_api/v3210/OnReboot() + switch(reboot_mode) + if(REBOOT_MODE_HARD) + TGS_WORLD_ANNOUNCE("Hard reboot triggered, you will automatically reconnect...") + EndProcess() + if(REBOOT_MODE_SHUTDOWN) + TGS_WORLD_ANNOUNCE("The server is shutting down...") + EndProcess() + else + ExportService(SERVICE_REQUEST_WORLD_REBOOT) //just let em know + +/datum/tgs_api/v3210/TestMerges() + //do the best we can here as the datum can't be completed using the v3 api + . = list() + if(!fexists(SERVICE_PR_TEST_JSON)) + return + var/list/json = json_decode(file2text(SERVICE_PR_TEST_JSON)) + if(!json) + return + for(var/I in json) + var/datum/tgs_revision_information/test_merge/tm = new + tm.number = text2num(I) + var/list/entry = json[I] + tm.pull_request_commit = entry["commit"] + tm.author = entry["author"] + tm.title = entry["title"] + . += tm + +/datum/tgs_api/v3210/Revision() + if(!warned_revison) + TGS_ERROR_LOG("Use of TgsRevision on [ApiVersion()] origin_commit only points to master!") + warned_revison = TRUE + var/datum/tgs_revision_information/ri = new + ri.commit = commit + ri.origin_commit = originmastercommit + +/datum/tgs_api/v3210/EndProcess() + sleep(world.tick_lag) //flush the buffers + ExportService(SERVICE_REQUEST_KILL_PROCESS) + +/datum/tgs_api/v3210/ChatChannelInfo() + return list() + +/datum/tgs_api/v3210/ChatBroadcast(message, list/channels) + return TGS_UNIMPLEMENTED + +/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/ChatPrivateMessage(message, admin_only) + return TGS_UNIMPLEMENTED + +#undef REBOOT_MODE_NORMAL +#undef REBOOT_MODE_HARD +#undef REBOOT_MODE_SHUTDOWN + +#undef SERVICE_WORLD_PARAM +#undef SERVICE_INSTANCE_PARAM +#undef SERVICE_PR_TEST_JSON +#undef SERVICE_INTERFACE_DLL +#undef SERVICE_INTERFACE_FUNCTION + +#undef SERVICE_CMD_HARD_REBOOT +#undef SERVICE_CMD_GRACEFUL_SHUTDOWN +#undef SERVICE_CMD_WORLD_ANNOUNCE +#undef SERVICE_CMD_LIST_CUSTOM +#undef SERVICE_CMD_API_COMPATIBLE +#undef SERVICE_CMD_PLAYER_COUNT + +#undef SERVICE_CMD_PARAM_KEY +#undef SERVICE_CMD_PARAM_COMMAND +#undef SERVICE_CMD_PARAM_SENDER +#undef SERVICE_CMD_PARAM_CUSTOM + +#undef SERVICE_REQUEST_KILL_PROCESS +#undef SERVICE_REQUEST_IRC_BROADCAST +#undef SERVICE_REQUEST_IRC_ADMIN_CHANNEL_MESSAGE +#undef SERVICE_REQUEST_WORLD_REBOOT +#undef SERVICE_REQUEST_API_VERSION + +#undef SERVICE_RETURN_SUCCESS + +/* +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. +*/ diff --git a/DMAPI/st_commands.dm b/DMAPI/tgs/v3210/commands.dm similarity index 51% rename from DMAPI/st_commands.dm rename to DMAPI/tgs/v3210/commands.dm index ce3fb1bb75..e823c16d26 100644 --- a/DMAPI/st_commands.dm +++ b/DMAPI/tgs/v3210/commands.dm @@ -1,54 +1,53 @@ -/datum/server_tools_command - var/name = "" //the string to trigger this command on a chat bot. e.g. TGS3_BOT: do_this_command - var/help_text = "" //help text for this command - var/required_parameters = 0 //number of parameters required for this command - var/admin_only = FALSE //set to TRUE if this command should only be usable by registered chat admins +#define SERVICE_JSON_PARAM_HELPTEXT "help_text" +#define SERVICE_JSON_PARAM_ADMINONLY "admin_only" +#define SERVICE_JSON_PARAM_REQUIREDPARAMETERS "required_parameters" -//override to implement command -//sender is the display name of who sent the command -//params is the trimmed string following the command name -/datum/server_tools_command/proc/Run(sender, params) - CRASH("[type] has no implementation for Run()") - -/world/proc/ListServiceCustomCommands(warnings_only) +/datum/tgs_api/v3210/proc/ListServiceCustomCommands(warnings_only) if(!warnings_only) . = list() var/list/command_name_types = list() var/list/warned_command_names = warnings_only ? list() : null - for(var/I in typesof(/datum/server_tools_command) - /datum/server_tools_command) - var/datum/server_tools_command/stc = I + 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!") + warned_about_the_dangers_of_robutussin = TRUE + var/datum/tgs_chat_command/stc = I var/command_name = initial(stc.name) - var/static/list/warned_server_tools_names = list() if(!command_name || findtext(command_name, " ") || findtext(command_name, "'") || findtext(command_name, "\"")) if(warnings_only && !warned_command_names[command_name]) - SERVER_TOOLS_LOG("WARNING: Custom command [command_name] can't be used as it is empty or contains illegal characters!") + TGS_ERROR_LOG("Custom command [command_name] can't be used as it is empty or contains illegal characters!") warned_command_names[command_name] = TRUE continue if(command_name_types[command_name]) if(warnings_only) - SERVER_TOOLS_LOG("WARNING: Custom commands [command_name_types[command_name]] and [stc] have the same name, only [command_name_types[command_name]] will be available!") + TGS_ERROR_LOG("Custom commands [command_name_types[command_name]] and [stc] have the same name, only [command_name_types[command_name]] will be available!") continue command_name_types[stc] = command_name if(!warnings_only) - .[command_name] = list(SERVICE_JSON_PARAM_HELPTEXT = initial(stc.help_text), SERVICE_JSON_PARAM_ADMINONLY = initial(stc.admin_only), SERVICE_JSON_PARAM_REQUIREDPARAMETERS = initial(stc.required_parameters)) + .[command_name] = list(SERVICE_JSON_PARAM_HELPTEXT = initial(stc.help_text), SERVICE_JSON_PARAM_ADMINONLY = initial(stc.admin_only), SERVICE_JSON_PARAM_REQUIREDPARAMETERS = 0) -/world/proc/HandleServiceCustomCommand(command, sender, params) - var/static/list/cached_custom_server_tools_commands - if(!cached_custom_server_tools_commands) - cached_custom_server_tools_commands = list() - for(var/I in typesof(/datum/server_tools_command) - /datum/server_tools_command) - var/datum/server_tools_command/stc = I - cached_custom_server_tools_commands[lowertext(initial(stc.name))] = stc +/datum/tgs_api/v3210/proc/HandleServiceCustomCommand(command, sender, params) + if(!cached_custom_tgs_chat_commands) + cached_custom_tgs_chat_commands = list() + for(var/I in typesof(/datum/tgs_chat_command) - /datum/tgs_chat_command) + var/datum/tgs_chat_command/stc = I + cached_custom_tgs_chat_commands[lowertext(initial(stc.name))] = stc - var/command_type = cached_custom_server_tools_commands[command] + var/command_type = cached_custom_tgs_chat_commands[command] if(!command_type) return FALSE - var/datum/server_tools_command/stc = new command_type + var/datum/tgs_chat_command/stc = new command_type return stc.Run(sender, params) || TRUE /* + +#undef SERVICE_JSON_PARAM_HELPTEXT +#undef SERVICE_JSON_PARAM_ADMINONLY +#undef SERVICE_JSON_PARAM_REQUIREDPARAMETERS + The MIT License Copyright (c) 2017 Jordan Brown diff --git a/TGS.Tests/TGS.Tests.csproj b/TGS.Tests/TGS.Tests.csproj index df98e93aeb..c0cc4f3a84 100644 --- a/TGS.Tests/TGS.Tests.csproj +++ b/TGS.Tests/TGS.Tests.csproj @@ -79,23 +79,23 @@ {89191f69-b18e-4b59-b72e-e12f9b6811a0} - TGCommandLine + TGS.CommandLine {394e7643-6b8c-416f-ab18-95ac12648cdc} - TGControlPanel + TGS.ControlPanel {8956d4c3-bfb9-448e-bf5f-ee7e6f9996f9} - TGInstallerWrapper + TGS.Installer.UI {f32eda25-0855-411c-af5e-f0d042917e2d} - TGServerService + TGS.Server {ac4e7e8b-f83a-481c-a8b0-8fa4e8ae59ab} - TGServiceInterface + TGS.Interface diff --git a/TGStationServer3.sln b/TGStationServer3.sln index 8b72b2546b..c31cc7e5ac 100644 --- a/TGStationServer3.sln +++ b/TGStationServer3.sln @@ -65,10 +65,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "bin", "bin", "{3BB3DA66-970 EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DMAPI", "DMAPI", "{9032B448-5E2B-4E71-8ECB-D5FB828E049C}" ProjectSection(SolutionItems) = preProject - DMAPI\server_tools.dm = DMAPI\server_tools.dm - DMAPI\st_commands.dm = DMAPI\st_commands.dm - DMAPI\st_interface.dm = DMAPI\st_interface.dm - TGS3.json = TGS3.json + DMAPI\tgs.dm = DMAPI\tgs.dm EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{081BB0BB-2E84-47D4-9419-A2AB8E814ABF}" @@ -77,7 +74,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{081BB0BB Tools\BuildDox.ps1 = Tools\BuildDox.ps1 Tools\Config.dm = Tools\Config.dm Tools\CoverageExclusions.runsettings = Tools\CoverageExclusions.runsettings - Tools\DMAPITravisTester.dme = Tools\DMAPITravisTester.dme Tools\Doxyfile = Tools\Doxyfile Tools\install_byond.sh = Tools\install_byond.sh Tools\PostCIBuild.ps1 = Tools\PostCIBuild.ps1 @@ -85,6 +81,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{081BB0BB Tools\SignMSI.ps1 = Tools\SignMSI.ps1 Tools\Test.dm = Tools\Test.dm Tools\tgstation13.org.pfx = Tools\tgstation13.org.pfx + Tools\travistester.dme = Tools\travistester.dme Tools\UploadCoverage.ps1 = Tools\UploadCoverage.ps1 EndProjectSection EndProject @@ -101,6 +98,25 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TGS.Server.Service", "TGS.S EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TGS.Server.Console", "TGS.Server.Console\TGS.Server.Console.csproj", "{509433F6-AEFB-44CA-BFE3-C782166D2CC3}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tgs", "tgs", "{E7103B1A-8097-4BD4-B642-E7A2FAB1B0F3}" + ProjectSection(SolutionItems) = preProject + DMAPI\tgs\includes.dm = DMAPI\tgs\includes.dm + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "core", "core", "{D30454E2-ABAF-4698-B5EC-D2E7C9641F43}" + ProjectSection(SolutionItems) = preProject + DMAPI\tgs\core\_definitions.dm = DMAPI\tgs\core\_definitions.dm + DMAPI\tgs\core\core.dm = DMAPI\tgs\core\core.dm + DMAPI\tgs\core\datum.dm = DMAPI\tgs\core\datum.dm + DMAPI\tgs\core\default_event_handler.dm = DMAPI\tgs\core\default_event_handler.dm + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "v3210", "v3210", "{FFECCA21-8B4A-4A70-B524-33DDDCA04850}" + ProjectSection(SolutionItems) = preProject + DMAPI\tgs\v3210\api.dm = DMAPI\tgs\v3210\api.dm + DMAPI\tgs\v3210\commands.dm = DMAPI\tgs\v3210\commands.dm + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -181,6 +197,9 @@ Global EndGlobalSection GlobalSection(NestedProjects) = preSolution {3BB3DA66-970C-4AAE-A77C-9E40F5E7E56A} = {0DDF886A-7ABB-4DCA-96A3-349B2DA00016} + {E7103B1A-8097-4BD4-B642-E7A2FAB1B0F3} = {9032B448-5E2B-4E71-8ECB-D5FB828E049C} + {D30454E2-ABAF-4698-B5EC-D2E7C9641F43} = {E7103B1A-8097-4BD4-B642-E7A2FAB1B0F3} + {FFECCA21-8B4A-4A70-B524-33DDDCA04850} = {E7103B1A-8097-4BD4-B642-E7A2FAB1B0F3} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {1B511D10-AB55-43E0-B363-7F8838E9E977} diff --git a/Tools/Config.dm b/Tools/Config.dm index 2a65e3b036..6c7a2564ef 100644 --- a/Tools/Config.dm +++ b/Tools/Config.dm @@ -1,8 +1,10 @@ -#define SERVER_TOOLS_EXTERNAL_CONFIGURATION -#define SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(Name, Value) var/##Name = ##Value -#define SERVER_TOOLS_READ_GLOBAL(Name) global.##Name -#define SERVER_TOOLS_WRITE_GLOBAL(Name, Value) global.##Name = ##Value -#define SERVER_TOOLS_WORLD_ANNOUNCE(message) world << ##message -#define SERVER_TOOLS_LOG(message) world.log << ##message -#define SERVER_TOOLS_NOTIFY_ADMINS(event) message_admins(event) -#define SERVER_TOOLS_CLIENT_COUNT clients.len \ No newline at end of file +#define TGS_EXTERNAL_CONFIGURATION +#define TGS_DEFINE_AND_SET_GLOBAL(Name, Value) var/##Name = ##Value +#define TGS_READ_GLOBAL(Name) global.##Name +#define TGS_WRITE_GLOBAL(Name, Value) global.##Name = ##Value +#define TGS_PROTECT_DATUM(Path) +#define TGS_WORLD_ANNOUNCE(message) world << ##message +#define TGS_INFO_LOG(message) world.log << "Info: [##message]" +#define TGS_ERROR_LOG(message) world.log << "Error: [##message]" +#define TGS_NOTIFY_ADMINS(event) message_admins(event) +#define TGS_CLIENT_COUNT clients.len diff --git a/Tools/Test.dm b/Tools/Test.dm index 91c97a26d6..addf8c7603 100644 --- a/Tools/Test.dm +++ b/Tools/Test.dm @@ -1,36 +1,18 @@ /world/New() - SERVER_TOOLS_ON_NEW - world.log << "Service API Version: [SERVER_TOOLS_API_VERSION]" - WaitForAPICompatResponse() + TgsNew() + TgsInitializationComplete() /world/Topic(T, Addr, Master, Keys) - SERVER_TOOLS_ON_TOPIC + TGS_TOPIC /world/Reboot(reason) - SERVER_TOOLS_ON_REBOOT - SERVER_TOOLS_REBOOT_BYOND(FALSE) + TgsReboot() /proc/message_admins(event) + event = "Admins: [event]" world << event world.log << event -/proc/WaitForAPICompatResponse() - set waitfor = FALSE - sleep(50) - if(!SERVER_TOOLS_PRESENT) - world.log << "No running service detected" - del(world) - return - world.log << "Running service version: [SERVER_TOOLS_VERSION]" - var/list/prs = SERVER_TOOLS_PR_LIST - for(var/I in prs) - var/data = prs[I] - world.log << "Testmerge: #[I]: [data["title"]] by [data["author"]] at commit [data["commit"]]" - var/checks_complete = "Server tools API checks complete! Rebooting..." - SERVER_TOOLS_CHAT_BROADCAST(checks_complete) - SERVER_TOOLS_RELAY_BROADCAST(checks_complete) - world.Reboot() - var/list/clients = list() /client/New() diff --git a/Tools/DMAPITravisTester.dme b/Tools/travistester.dme similarity index 71% rename from Tools/DMAPITravisTester.dme rename to Tools/travistester.dme index dd468a6dfe..94a15e4bc6 100644 --- a/Tools/DMAPITravisTester.dme +++ b/Tools/travistester.dme @@ -12,8 +12,7 @@ // BEGIN_INCLUDE #include "Config.dm" -#include "..\DMAPI\server_tools.dm" -#include "..\DMAPI\st_commands.dm" -#include "..\DMAPI\st_interface.dm" +#include "..\DMAPI\tgs.dm" +#include "..\DMAPI\tgs\includes.dm" #include "Test.dm" // END_INCLUDE