diff --git a/code/__defines/_globals.dm b/code/__defines/_globals.dm new file mode 100644 index 0000000000..7e7aa3158f --- /dev/null +++ b/code/__defines/_globals.dm @@ -0,0 +1,38 @@ +//See controllers/globals.dm +#define GLOBAL_MANAGED(X, InitValue)\ +/datum/controller/global_vars/proc/InitGlobal##X(){\ + ##X = ##InitValue;\ + gvars_datum_init_order += #X;\ +} +#define GLOBAL_UNMANAGED(X) /datum/controller/global_vars/proc/InitGlobal##X() { return; } + +#ifndef TESTING +#define GLOBAL_PROTECT(X)\ +/datum/controller/global_vars/InitGlobal##X(){\ + ..();\ + gvars_datum_protected_varlist[#X] = TRUE;\ +} +#else +#define GLOBAL_PROTECT(X) +#endif + +#define GLOBAL_REAL_VAR(X) var/global/##X +#define GLOBAL_REAL(X, Typepath) var/global##Typepath/##X + +#define GLOBAL_RAW(X) /datum/controller/global_vars/var/global##X + +#define GLOBAL_VAR_INIT(X, InitValue) GLOBAL_RAW(/##X); GLOBAL_MANAGED(X, InitValue) + +#define GLOBAL_VAR_CONST(X, InitValue) GLOBAL_RAW(/const/##X) = InitValue; GLOBAL_UNMANAGED(X) + +#define GLOBAL_LIST_INIT(X, InitValue) GLOBAL_RAW(/list/##X); GLOBAL_MANAGED(X, InitValue) + +#define GLOBAL_LIST_EMPTY(X) GLOBAL_LIST_INIT(X, list()) + +#define GLOBAL_DATUM_INIT(X, Typepath, InitValue) GLOBAL_RAW(Typepath/##X); GLOBAL_MANAGED(X, InitValue) + +#define GLOBAL_VAR(X) GLOBAL_RAW(/##X); GLOBAL_UNMANAGED(X) + +#define GLOBAL_LIST(X) GLOBAL_RAW(/list/##X); GLOBAL_UNMANAGED(X) + +#define GLOBAL_DATUM(X, Typepath) GLOBAL_RAW(Typepath/##X); GLOBAL_UNMANAGED(X) diff --git a/code/__defines/server_tools.config.dm b/code/__defines/server_tools.config.dm new file mode 100644 index 0000000000..ef85b6503b --- /dev/null +++ b/code/__defines/server_tools.config.dm @@ -0,0 +1,8 @@ +#define SERVER_TOOLS_EXTERNAL_CONFIGURATION +#define SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(Name, Value) GLOBAL_VAR_INIT(##Name, ##Value); GLOBAL_PROTECT(##Name) +#define SERVER_TOOLS_READ_GLOBAL(Name) GLOB.##Name +#define SERVER_TOOLS_WRITE_GLOBAL(Name, Value) GLOB.##Name = ##Value +#define SERVER_TOOLS_WORLD_ANNOUNCE(message) to_chat(world, "[html_encode(##message)]") +#define SERVER_TOOLS_LOG(message) log_world("SERVICE: [##message]") +#define SERVER_TOOLS_NOTIFY_ADMINS(event) message_admins(##event) +#define SERVER_TOOLS_CLIENT_COUNT player_list.len \ No newline at end of file diff --git a/code/__defines/server_tools.dm b/code/__defines/server_tools.dm new file mode 100644 index 0000000000..5f73e2209a --- /dev/null +++ b/code/__defines/server_tools.dm @@ -0,0 +1,101 @@ +// /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 +//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. +*/ \ No newline at end of file diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm index 724f5789d8..b11cd33d32 100644 --- a/code/_helpers/unsorted.dm +++ b/code/_helpers/unsorted.dm @@ -14,6 +14,9 @@ locate(min(CENTER.x+(RADIUS),world.maxx), min(CENTER.y+(RADIUS),world.maxy), CENTER.z) \ ) +#define QDEL_NULL(item) qdel(item); item = null +#define QDEL_LIST(L) if(L) { for(var/I in L) qdel(I); L.Cut(); } + //Inverts the colour of an HTML string /proc/invertHTML(HTMLstring) @@ -1473,7 +1476,12 @@ var/mob/dview/dview_mob = new if(337.5) return "North-Northwest" - +//gives us the stack trace from CRASH() without ending the current proc. +/proc/stack_trace(msg) + CRASH(msg) + +/datum/proc/stack_trace(msg) + CRASH(msg) diff --git a/code/controllers/globals.dm b/code/controllers/globals.dm new file mode 100644 index 0000000000..af03939e54 --- /dev/null +++ b/code/controllers/globals.dm @@ -0,0 +1,69 @@ +GLOBAL_REAL(GLOB, /datum/controller/global_vars) + +/datum/controller/global_vars + name = "Global Variables" + + var/list/gvars_datum_protected_varlist + var/list/gvars_datum_in_built_vars + var/list/gvars_datum_init_order + +/datum/controller/global_vars/New() + if(GLOB) + CRASH("Multiple instances of global variable controller created") + GLOB = src + + var/datum/controller/exclude_these = new + gvars_datum_in_built_vars = exclude_these.vars + list("gvars_datum_protected_varlist", "gvars_datum_in_built_vars", "gvars_datum_init_order") + qdel(exclude_these) + + log_world("[vars.len - gvars_datum_in_built_vars.len] global variables") + + Initialize() + +/datum/controller/global_vars/Destroy(force) + stack_trace("Some fucker qdel'd the global holder!") + if(!force) + return QDEL_HINT_LETMELIVE + + QDEL_NULL(statclick) + gvars_datum_protected_varlist.Cut() + gvars_datum_in_built_vars.Cut() + + GLOB = null + + return ..() + +/datum/controller/global_vars/stat_entry() + if(!statclick) + statclick = new/obj/effect/statclick/debug(null, "Initializing...", src) + + stat("Globals:", statclick.update("Edit")) + +/datum/controller/global_vars/can_vv_get(var_name) + if(gvars_datum_protected_varlist[var_name]) + return FALSE + return ..() + +/datum/controller/global_vars/vv_edit_var(var_name, var_value) + if(gvars_datum_protected_varlist[var_name]) + return FALSE + return ..() + +/datum/controller/global_vars/Initialize() + gvars_datum_init_order = list() + gvars_datum_protected_varlist = list("gvars_datum_protected_varlist" = TRUE) + var/list/global_procs = typesof(/datum/controller/global_vars/proc) + var/expected_len = vars.len - gvars_datum_in_built_vars.len + if(global_procs.len != expected_len) + warning("Unable to detect all global initialization procs! Expected [expected_len] got [global_procs.len]!") + if(global_procs.len) + var/list/expected_global_procs = vars - gvars_datum_in_built_vars + for(var/I in global_procs) + expected_global_procs -= replacetext("[I]", "InitGlobal", "") + //log_world("Missing procs: [expected_global_procs.Join(", ")]") + for(var/I in global_procs) + var/start_tick = world.time + call(src, I)() + var/end_tick = world.time + if(end_tick - start_tick) + warning("Global [replacetext("[I]", "InitGlobal", "")] slept during initialization!") diff --git a/code/datums/datum.dm b/code/datums/datum.dm index a9fea93f9d..5b0d614672 100644 --- a/code/datums/datum.dm +++ b/code/datums/datum.dm @@ -7,6 +7,7 @@ var/gc_destroyed //Time when this object was destroyed. var/weakref/weakref // Holder of weakref instance pointing to this datum var/is_processing = FALSE // If this datum is in an MC processing list, this will be set to its name. + var/datum_flags = 0 #ifdef TESTING var/tmp/running_find_references diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm new file mode 100644 index 0000000000..c245d60894 --- /dev/null +++ b/code/datums/datumvars.dm @@ -0,0 +1,12 @@ +#define DF_VAR_EDITED 2 +#define NAMEOF(datum, X) (#X || ##datum.##X) + + +/datum/proc/can_vv_get(var_name) + return TRUE + +/datum/proc/vv_edit_var(var_name, var_value) //called whenever a var is edited + if(var_name == NAMEOF(src, vars)) + return FALSE + vars[var_name] = var_value + datum_flags |= DF_VAR_EDITED \ No newline at end of file diff --git a/code/game/world.dm b/code/game/world.dm new file mode 100644 index 0000000000..46787a6cfd --- /dev/null +++ b/code/game/world.dm @@ -0,0 +1,11 @@ +/world/New() + SERVER_TOOLS_ON_NEW + return ..() + +/world/Reboot(var/reason) + SERVER_TOOLS_ON_REBOOT + return ..(reason) + +/world/Topic(T, addr, master, key) + SERVER_TOOLS_ON_TOPIC + return ..(T, addr, master, key) \ No newline at end of file diff --git a/code/modules/DMAPI/st_commands.dm b/code/modules/DMAPI/st_commands.dm new file mode 100644 index 0000000000..dc707d8b71 --- /dev/null +++ b/code/modules/DMAPI/st_commands.dm @@ -0,0 +1,72 @@ +/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 + +//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) + 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/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] cannot 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!") + 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)) + +/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 + + var/command_type = cached_custom_server_tools_commands[command] + if(!command_type) + return FALSE + var/datum/server_tools_command/stc = new command_type + return stc.Run(sender, params) || TRUE + +/* +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. +*/ \ No newline at end of file diff --git a/code/modules/DMAPI/st_interface.dm b/code/modules/DMAPI/st_interface.dm new file mode 100644 index 0000000000..4e975b14c2 --- /dev/null +++ b/code/modules/DMAPI/st_interface.dm @@ -0,0 +1,131 @@ +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("gay")//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. +*/ \ No newline at end of file diff --git a/vorestation.dme b/vorestation.dme index 63f1a0633f..d7943c36d7 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -22,6 +22,7 @@ #include "code\stylesheet.dm" #include "code\world.dm" #include "code\__defines\_compile_options.dm" +#include "code\__defines\_globals.dm" #include "code\__defines\_planes+layers.dm" #include "code\__defines\_planes+layers_vr.dm" #include "code\__defines\_tick.dm" @@ -55,6 +56,8 @@ #include "code\__defines\qdel.dm" #include "code\__defines\research.dm" #include "code\__defines\roguemining_vr.dm" +#include "code\__defines\server_tools.config.dm" +#include "code\__defines\server_tools.dm" #include "code\__defines\species_languages.dm" #include "code\__defines\species_languages_vr.dm" #include "code\__defines\stat_tracking.dm" @@ -169,6 +172,7 @@ #include "code\controllers\controller.dm" #include "code\controllers\emergency_shuttle_controller.dm" #include "code\controllers\failsafe.dm" +#include "code\controllers\globals.dm" #include "code\controllers\hooks-defs.dm" #include "code\controllers\hooks.dm" #include "code\controllers\master.dm" @@ -220,6 +224,7 @@ #include "code\datums\computerfiles.dm" #include "code\datums\datacore.dm" #include "code\datums\datum.dm" +#include "code\datums\datumvars.dm" #include "code\datums\EPv2.dm" #include "code\datums\ghost_query.dm" #include "code\datums\hierarchy.dm" @@ -389,6 +394,7 @@ #include "code\game\sound.dm" #include "code\game\supplyshuttle.dm" #include "code\game\trader_visit.dm" +#include "code\game\world.dm" #include "code\game\antagonist\_antagonist_setup.dm" #include "code\game\antagonist\antagonist.dm" #include "code\game\antagonist\antagonist_add.dm" @@ -1600,6 +1606,8 @@ #include "code\modules\detectivework\tools\storage.dm" #include "code\modules\detectivework\tools\swabs.dm" #include "code\modules\detectivework\tools\uvlight.dm" +#include "code\modules\DMAPI\st_commands.dm" +#include "code\modules\DMAPI\st_interface.dm" #include "code\modules\economy\Accounts.dm" #include "code\modules\economy\Accounts_DB.dm" #include "code\modules\economy\ATM.dm"