diff --git a/aurorastation.dme b/aurorastation.dme index a407ac3bfbb..874e6fbd8c2 100644 --- a/aurorastation.dme +++ b/aurorastation.dme @@ -2208,8 +2208,8 @@ #include "code\modules\modular_computers\file_system\data.dm" #include "code\modules\modular_computers\file_system\news_article.dm" #include "code\modules\modular_computers\file_system\program.dm" -#include "code\modules\modular_computers\file_system\script.dm" #include "code\modules\modular_computers\file_system\program_events.dm" +#include "code\modules\modular_computers\file_system\script.dm" #include "code\modules\modular_computers\file_system\programs\_program.dm" #include "code\modules\modular_computers\file_system\programs\app_presets.dm" #include "code\modules\modular_computers\file_system\programs\antagonist\dos.dm" diff --git a/code/__defines/tgs.dm b/code/__defines/tgs.dm index 4015d24808d..7665982f8e6 100644 --- a/code/__defines/tgs.dm +++ b/code/__defines/tgs.dm @@ -1,6 +1,6 @@ // tgstation-server DMAPI -#define TGS_DMAPI_VERSION "5.2.2" +#define TGS_DMAPI_VERSION "6.0.2" // All functions and datums outside this document are subject to change with any version and should not be relied on. @@ -67,7 +67,7 @@ #define TGS_EVENT_REPO_CHECKOUT 1 /// When the repository performs a fetch operation. No parameters #define TGS_EVENT_REPO_FETCH 2 -/// When the repository merges a pull request. Parameters: PR Number, PR Sha, (Nullable) Comment made by TGS user +/// When the repository test merges. Parameters: PR Number, PR Sha, (Nullable) Comment made by TGS user #define TGS_EVENT_REPO_MERGE_PULL_REQUEST 3 /// Before the repository makes a sychronize operation. Parameters: Absolute repostiory path #define TGS_EVENT_REPO_PRE_SYNCHRONIZE 4 @@ -95,8 +95,13 @@ #define TGS_EVENT_WATCHDOG_SHUTDOWN 15 /// Before the watchdog detaches for a TGS update/restart. No parameters. #define TGS_EVENT_WATCHDOG_DETACH 16 -// We don't actually implement this value as the DMAPI can never receive it +// We don't actually implement these 4 events as the DMAPI can never receive them. // #define TGS_EVENT_WATCHDOG_LAUNCH 17 +// #define TGS_EVENT_WATCHDOG_CRASH 18 +// #define TGS_EVENT_WORLD_END_PROCESS 19 +// #define TGS_EVENT_WORLD_REBOOT 20 +/// Watchdog event when TgsInitializationComplete() is called. No parameters. +#define TGS_EVENT_WORLD_PRIME 21 // OTHER ENUMS @@ -145,6 +150,7 @@ /world/proc/TgsReboot() return + // DATUM DEFINITIONS // All datums defined here should be considered read-only @@ -152,6 +158,8 @@ /datum/tgs_revision_information /// Full SHA of the commit. var/commit + /// ISO 8601 timestamp of when the commit was created + var/timestamp /// Full sha of last known remote commit. This may be null if the TGS repository is not currently tracking a remote branch. var/origin_commit @@ -174,37 +182,36 @@ /// String value minus prefix var/deprefixed_parameter + /** - * Returns [TRUE]/[FALSE] based on if the [/datum/tgs_version] contains wildcards. - */ + * Returns [TRUE]/[FALSE] based on if the [/datum/tgs_version] contains wildcards. + */ /datum/tgs_version/proc/Wildcard() return /** - * Returns [TRUE]/[FALSE] based on if the [/datum/tgs_version] equals some other version. - * - * other_version - The [/datum/tgs_version] to compare against. - */ + * Returns [TRUE]/[FALSE] based on if the [/datum/tgs_version] equals some other version. + * + * other_version - The [/datum/tgs_version] to compare against. + */ /datum/tgs_version/proc/Equals(datum/tgs_version/other_version) return /// Represents a merge of a GitHub pull request. /datum/tgs_revision_information/test_merge - /// The pull request number. + /// The test merge number. var/number - /// The pull request title when it was merged. + /// The test merge source's title when it was merged. var/title - /// The pull request body when it was merged. + /// The test merge source's body when it was merged. var/body - /// The GitHub username of the pull request's author. + /// The Username of the test merge source's author. var/author - /// An http URL to the pull request. + /// An http URL to the test merge source. var/url - /// The SHA of the pull request when that was merged. - var/pull_request_commit - /// ISO 8601 timestamp of when the pull request was merged. - var/time_merged - /// (Nullable) Comment left by the TGS user who initiated the merge.. + /// The SHA of the test merge when that was merged. + var/head_commit + /// Optional comment left by the TGS user who initiated the merge. var/comment /// Represents a connected chat channel. @@ -234,10 +241,10 @@ var/datum/tgs_chat_channel/channel /** - * User definable callback for handling TGS events. - * - * event_code - One of the TGS_EVENT_ defines. Extra parameters will be documented in each - */ + * User definable callback for handling TGS events. + * + * event_code - One of the TGS_EVENT_ defines. Extra parameters will be documented in each + */ /datum/tgs_event_handler/proc/HandleEvent(event_code, ...) set waitfor = FALSE return @@ -252,67 +259,67 @@ var/admin_only = FALSE /** - * Process command activation. Should return a string to respond to the issuer with. - * - * sender - The [/datum/tgs_chat_user] who issued the command. - * params - The trimmed string following the command `/datum/tgs_chat_command/var/name]. - */ + * Process command activation. Should return a string to respond to the issuer with. + * + * sender - The [/datum/tgs_chat_user] who issued the command. + * params - The trimmed string following the command `/datum/tgs_chat_command/var/name]. + */ /datum/tgs_chat_command/proc/Run(datum/tgs_chat_user/sender, params) CRASH("[type] has no implementation for Run()") // API FUNCTIONS /// Returns the maximum supported [/datum/tgs_version] of the DMAPI. -/world/proc/TgsMaximumAPIVersion() +/world/proc/TgsMaximumApiVersion() return /// Returns the minimum supported [/datum/tgs_version] of the DMAPI. -/world/proc/TgsMinimumAPIVersion() +/world/proc/TgsMinimumApiVersion() return /** - * Returns [TRUE] if DreamDaemon was launched under TGS, the API matches, and was properly initialized. [FALSE] will be returned otherwise. - */ + * Returns [TRUE] if DreamDaemon was launched under TGS, the API matches, and was properly initialized. [FALSE] will be returned otherwise. + */ /world/proc/TgsAvailable() return // No function below this succeeds if it TgsAvailable() returns FALSE or if TgsNew() has yet to be called. /** - * Forces a hard reboot of DreamDaemon by ending the process. - * - * Unlike del(world) clients will try to reconnect. - * If TGS has not requested a [TGS_REBOOT_MODE_SHUTDOWN] DreamDaemon will be launched again - */ + * Forces a hard reboot of DreamDaemon by ending the process. + * + * Unlike del(world) clients will try to reconnect. + * If TGS has not requested a [TGS_REBOOT_MODE_SHUTDOWN] DreamDaemon will be launched again + */ /world/proc/TgsEndProcess() return /** - * Send a message to connected chats. - * - * message - The string to send. - * admin_only: If [TRUE], message will be sent to admin connected chats. Vice-versa applies. - */ + * Send a message to connected chats. + * + * message - The string to send. + * admin_only: If [TRUE], message will be sent to admin connected chats. Vice-versa applies. + */ /world/proc/TgsTargetedChatBroadcast(message, admin_only = FALSE) return /** - * Send a private message to a specific user. - * - * message - The string to send. - * user: The [/datum/tgs_chat_user] to PM. - */ + * Send a private message to a specific user. + * + * message - The string to send. + * user: The [/datum/tgs_chat_user] to PM. + */ /world/proc/TgsChatPrivateMessage(message, datum/tgs_chat_user/user) return // The following functions will sleep if a call to TgsNew() is sleeping /** - * Send a message to connected chats that are flagged as game-related in TGS. - * - * message - The string to send. - * channels - Optional list of [/datum/tgs_chat_channel]s to restrict the message to. - */ + * Send a message to connected chats that are flagged as game-related in TGS. + * + * message - The string to send. + * channels - Optional list of [/datum/tgs_chat_channel]s to restrict the message to. + */ /world/proc/TgsChatBroadcast(message, list/channels = null) return diff --git a/code/datums/helper_datums/getrev.dm b/code/datums/helper_datums/getrev.dm index 32eb4c33b40..e27e5354658 100644 --- a/code/datums/helper_datums/getrev.dm +++ b/code/datums/helper_datums/getrev.dm @@ -120,10 +120,11 @@ client/verb/showrevinfo() . += {"
"} . += {""} . += {""} - . += {""} if (config.githuburl) . += {""} . += {""} + if(tm.comment) + . += {""} . += {"
Author:[html_encode(tm.author)]
Merged:[tm.time_merged]
Link to Github
Description:[html_encode(tm.body)]
Comment:[html_encode(tm.comment)]
"} diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index 0a60fea5778..7686c0d5bb5 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -31,7 +31,7 @@ update_clothing_icon() /obj/item/storage/belt/Initialize() - ..() + . = ..() update_flip_verb() /obj/item/storage/belt/proc/update_flip_verb() @@ -52,7 +52,7 @@ flipped = !flipped icon_state = "[initial(icon_state)][flipped ? "_flip" : ""]" - item_state = icon_state + item_state = "[initial(item_state)][flipped ? "_flip" : ""]" to_chat(usr, SPAN_NOTICE("You change \the [src] to be [src.flipped ? "behind" : "in front of"] you.")) update_clothing_icon() diff --git a/code/modules/admin/admin_ranks.dm b/code/modules/admin/admin_ranks.dm index 993a706a40a..295f71fd6ca 100644 --- a/code/modules/admin/admin_ranks.dm +++ b/code/modules/admin/admin_ranks.dm @@ -213,6 +213,9 @@ var/list/forum_groupids_to_ranks = list() if(isnull(user.ckey)) log_debug("AdminRanks: [user.forum_name] does not have a ckey linked - Ignoring") return + if(user.psync_game_disabled) + log_debug("AdminRanks: [user.forum_name] has permsync-game disabled - Ignoring") + return var/rights = 0 for (var/group_id in (user.forum_secondary_groups + user.forum_primary_group)) diff --git a/code/modules/client/preference_setup/loadout/loadout_uniform.dm b/code/modules/client/preference_setup/loadout/loadout_uniform.dm index 593db51462b..0939c399d2d 100644 --- a/code/modules/client/preference_setup/loadout/loadout_uniform.dm +++ b/code/modules/client/preference_setup/loadout/loadout_uniform.dm @@ -199,7 +199,7 @@ /datum/gear/uniform/colorpants/New() ..() - var/colorpants = list() + var/list/colorpants = list() colorpants["dress pants"] = /obj/item/clothing/under/pants/dress colorpants["striped pants"] = /obj/item/clothing/under/pants/striped gear_tweaks += new/datum/gear_tweak/path(colorpants) @@ -209,14 +209,14 @@ path = /obj/item/clothing/under/syndicate/tacticool /datum/gear/uniform/dominia - display_name = "dominia clothing selection" - description = "A selection of dominian clothing." + display_name = "dominian clothing selection" + description = "A selection of Dominian clothing." path = /obj/item/clothing/under/dominia flags = GEAR_HAS_DESC_SELECTION /datum/gear/uniform/dominia/New() ..() - var/suit = list() + var/list/suit = list() suit["dominia suit, red"] = /obj/item/clothing/under/dominia suit["dominia suit, black"] = /obj/item/clothing/under/dominia/black suit["dominia sweater"] = /obj/item/clothing/under/dominia/sweater @@ -226,6 +226,19 @@ suit["dominia summer dress"] = /obj/item/clothing/under/dominia/dress/summer gear_tweaks += new/datum/gear_tweak/path(suit) +/datum/gear/uniform/dominia_dress + display_name = "dominian dress selection" + description = "A selection of fancy Dominian dresses." + path = /obj/item/clothing/under/dominia/dress + +/datum/gear/uniform/dominia_dress/New() + ..() + var/list/suit = list() + for(var/dress in subtypesof(/obj/item/clothing/under/dominia/dress/fancy)) + var/obj/item/clothing/under/dominia/dress/D = new dress //I'm not typing all this shit manually. Jesus christ. + suit["[D.name]"] = D.type + gear_tweaks += new/datum/gear_tweak/path(suit) + /datum/gear/uniform/elyra_holo display_name = "elyran holographic suit selection" description = "A marvel of Elyran technology, uses hardlight fabric and masks to transform a skin-tight, cozy suit into cultural apparel of your choosing. Has a dial for Midenean, Aemaqii and Perispolisean clothes respectively." @@ -234,7 +247,7 @@ /datum/gear/uniform/elyra_holo/New() ..() - var/suit = list() + var/list/suit = list() suit["elyran holographic suit, feminine"] = /obj/item/clothing/under/elyra_holo suit["elyran holographic suit, masculine"] = /obj/item/clothing/under/elyra_holo/masc gear_tweaks += new/datum/gear_tweak/path(suit) @@ -252,7 +265,7 @@ /datum/gear/uniform/officer/New() ..() - var/uniform = list() + var/list/uniform = list() uniform["officer uniform, standard"] = /obj/item/clothing/under/rank/security uniform["officer uniform, corporate"] = /obj/item/clothing/under/rank/security/corp uniform["officer uniform, blue"] = /obj/item/clothing/under/rank/security/blue diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index cace2eebb53..14425365548 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -936,7 +936,6 @@ var/mob/M = src.loc M.update_inv_w_uniform() - /obj/item/clothing/under/examine(mob/user) ..(user) switch(src.sensor_mode) diff --git a/code/modules/clothing/factions/dominia.dm b/code/modules/clothing/factions/dominia.dm index efe79644a14..9802762074c 100644 --- a/code/modules/clothing/factions/dominia.dm +++ b/code/modules/clothing/factions/dominia.dm @@ -325,6 +325,37 @@ overlay_state = "dominian_cape_red" contained_sprite = TRUE icon_override = null + var/rolled = FALSE + +/obj/item/clothing/accessory/poncho/dominia/red/update_clothing_icon() + if(ismob(loc)) + var/mob/M = loc + M.update_inv_wear_suit() + get_mob_overlay(TRUE) + get_inv_overlay(TRUE) + +/obj/item/clothing/accessory/poncho/dominia/red/verb/roll_up_mantle() + set name = "Roll Up Cape Mantle" + set desc = "Roll up your cape's mantle. Doesn't work with some capes." + set src in usr + + if(use_check_and_message(usr)) + return FALSE + + var/list/icon_states = icon_states(icon) + var/initial_state = initial(icon_state) + var/new_state = "[initial_state]_h" + if(!(new_state in icon_states)) + to_chat(usr, SPAN_WARNING("Your cape doesn't allow this!")) + return + + rolled = !rolled + to_chat(usr, SPAN_NOTICE("You roll your cape's mantle [rolled ? "up" : "down"].")) + icon_state = rolled ? new_state : initial_state + item_state = rolled ? new_state : initial_state + overlay_state = rolled ? new_state : initial_state + update_icon() + update_clothing_icon() /obj/item/clothing/under/dominia/initiate name = "tribunal initiate's robe" @@ -383,3 +414,84 @@ desc = "A warm fur hat with ear flaps that can be raised and tied to be out of the way. This one has a large Fisanduhian flag on the front." icon_state = "fishushanka" item_state = "fishushanka" + +/obj/item/clothing/under/dominia/dress/fancy + name = "Morozi dress" + desc = "Feminine commoner's fashion from the Empire of Dominia. This particular variant has sleeves." + desc_fluff = "Dresses such as this one are a common sight in the more developed colonies of the Empire of Dominia, and their origins can be traced back to \ + the fashion houses of Nova Luxembourg. While both sleeved and sleeveless variants exist, the sleeved one is far more common \ + due to the often frigid temperatures of Moroz." + icon = 'icons/clothing/under/uniforms/dominia_dresses.dmi' + icon_state = "morozi_dress" + item_state = "morozi_dress" + contained_sprite = TRUE + var/house + +/obj/item/clothing/under/dominia/dress/fancy/Initialize() + . = ..() + if(house) + desc = "Feminine commoner's fashion from the Empire of Dominia. This particular variant has sleeves, and a colored sash marking its wearer as \ + an affiliate of House [capitalize(house)]." + icon_state = "[house]" + item_state = "[house]" + update_clothing_icon() + +/obj/item/clothing/under/dominia/dress/fancy/sleeveless + name = "sleeveless Morozi dress" + desc = "Feminine commoner's fashion from the Empire of Dominia. This particular variant has no sleeves." + desc_fluff = "Dresses such as this one are a common sight in the more developed colonies of the Empire of Dominia, and their origins can be traced back to \ + the fashion houses of Nova Luxembourg. While both sleeved and sleeveless variants exist, the sleeved one is far more common \ + due to the often frigid temperatures of Moroz." + icon_state = "morozi_dress_rs" + item_state = "morozi_dress_rs" + +/obj/item/clothing/under/dominia/dress/fancy/sleeveless/Initialize() + . = ..() + if(house) + desc = "Feminine commoner's fashion from the Empire of Dominia. This particular variant has no sleeves, and a colored sash marking its wearer as \ + an affiliate of House [house]." + icon_state += "_rs" + item_state += "_rs" + update_clothing_icon() + +/obj/item/clothing/under/dominia/dress/fancy/zhao + name = "house zhao Morozi dress" + house = "zhao" + +/obj/item/clothing/under/dominia/dress/fancy/sleeveless/zhao + name = "sleeveless house zhao Morozi dress" + house = "zhao" + +/obj/item/clothing/under/dominia/dress/fancy/volvalaad + name = "house volvalaad Morozi dress" + house = "volvalaad" + +/obj/item/clothing/under/dominia/dress/fancy/sleeveless/volvalaad + name = "sleeveless house volvalaad Morozi dress" + house = "volvalaad" + +/obj/item/clothing/under/dominia/dress/fancy/strelitz + name = "house strelitz Morozi dress" + house = "strelitz" + +/obj/item/clothing/under/dominia/dress/fancy/sleeveless/strelitz + name = "sleeveless house strelitz Morozi dress" + house = "strelitz" + +/obj/item/clothing/under/dominia/dress/fancy/caladius + name = "house caladius Morozi dress" + house = "caladius" + +/obj/item/clothing/under/dominia/dress/fancy/sleeveless/caladius + name = "sleeveless house caladius Morozi dress" + house = "caladius" + +/obj/item/clothing/under/dominia/dress/fancy/kazhkz + name = "house kazhkz Morozi dress" + house = "kazhkz" + +/obj/item/clothing/under/dominia/dress/fancy/sleeveless/kazhkz + name = "sleeveless house kazhkz Morozi dress" + house = "kazhkz" + + diff --git a/code/modules/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm index bad23d7a30c..7042602aaee 100644 --- a/code/modules/clothing/under/accessories/accessory.dm +++ b/code/modules/clothing/under/accessories/accessory.dm @@ -28,11 +28,11 @@ cut_overlays() add_overlay(overlay_image(icon, worn_overlay, flags=RESET_COLOR)) //add the overlay w/o coloration of the original sprite -/obj/item/clothing/accessory/proc/get_inv_overlay() +/obj/item/clothing/accessory/proc/get_inv_overlay(var/force = FALSE) if(!mob_overlay) get_mob_overlay() var/I = mob_overlay.icon - if(!inv_overlay) + if(!inv_overlay || force) var/tmp_icon_state = "[overlay_state? "[overlay_state]" : "[icon_state]"]" if(icon_override) if("[tmp_icon_state]_tie" in icon_states(icon_override)) @@ -47,9 +47,9 @@ inv_overlay.add_overlay(overlay_image(I, worn_overlay, flags=RESET_COLOR)) //add the overlay w/o coloration of the original sprite return inv_overlay -/obj/item/clothing/accessory/proc/get_mob_overlay() +/obj/item/clothing/accessory/proc/get_mob_overlay(var/force = FALSE) var/I = icon_override ? icon_override : contained_sprite ? icon : INV_ACCESSORIES_DEF_ICON - if(!mob_overlay) + if(!mob_overlay || force) var/tmp_icon_state = "[overlay_state? "[overlay_state]" : "[icon_state]"]" if(icon_override) if("[tmp_icon_state]_mob" in icon_states(I)) diff --git a/code/modules/http/forumuser_api.dm b/code/modules/http/forumuser_api.dm index 20da806c8b3..d3611f354f2 100644 --- a/code/modules/http/forumuser_api.dm +++ b/code/modules/http/forumuser_api.dm @@ -7,6 +7,7 @@ var/global/forumuser_api_key = null var/list/forum_secondary_groups = list() var/discord_id var/ckey + var/psync_game_disabled = FALSE /datum/forum_user/New(data) forum_member_id = data["forum_member_id"] @@ -18,6 +19,8 @@ var/global/forumuser_api_key = null discord_id = data["discord_id"] ckey = data["ckey"] + if(data["psync_game_disalbed"] == 1) //This here is needed because the data can be null, 1 or 0 + psync_game_disabled = TRUE /datum/http_request/forumuser_api @@ -62,4 +65,3 @@ var/global/forumuser_api_key = null R.body = users return R - diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 5dfc9664abd..5fb5ecedc3d 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -969,7 +969,6 @@ There are several things that need to be remembered: if(belt.contained_sprite) belt.auto_adapt_species(src) var/t_state = "[UNDERSCORE_OR_NULL(belt.icon_species_tag)][belt.item_state][WORN_BELT]" - result_layer = image(belt.icon_override || belt.icon, t_state) else if(belt.icon_override) t_icon = belt.icon_override @@ -977,11 +976,9 @@ There are several things that need to be remembered: t_icon = belt.sprite_sheets[GET_BODY_TYPE] else if(belt.item_icons && (slot_belt_str in belt.item_icons)) t_icon = belt.item_icons[slot_belt_str] - else - t_icon = INV_BELT_DEF_ICON if(!result_layer) //Create the image - result_layer = image(t_icon, belt.icon_state) + result_layer = image(t_icon, belt.item_state) if(belt.color) result_layer.color = belt.color @@ -989,11 +986,11 @@ There are several things that need to be remembered: result_layer.appearance_flags = RESET_ALPHA var/image/worn_overlays = belt.worn_overlays(t_icon) if(worn_overlays) - result_layer.overlays.Add(worn_overlays) + result_layer.add_overlay(worn_overlays) var/list/ovr - if(belt.contents.len && istype(belt, /obj/item/storage/belt)) + if(length(belt.contents) && istype(belt, /obj/item/storage/belt)) ovr = list(result_layer) for(var/obj/item/i in belt.contents) var/c_state @@ -1005,10 +1002,9 @@ There are several things that need to be remembered: c_icon = INV_BELT_DEF_ICON c_state = i.item_state || i.icon_state var/image/belt_item_image = image(c_icon, c_state) - if(i.color) - belt_item_image.color = i.color + belt_item_image.color = i.color belt_item_image.appearance_flags = RESET_ALPHA - ovr += image(c_icon, c_state) + ovr += belt_item_image var/belt_layer = BELT_LAYER if(istype(belt, /obj/item/storage/belt)) @@ -1024,9 +1020,6 @@ There are several things that need to be remembered: if(update_icons) update_icon() - if (QDELING(src)) - return - /mob/living/carbon/human/update_inv_wear_suit(var/update_icons=1) if (QDELING(src)) return diff --git a/code/modules/tgs/core/core.dm b/code/modules/tgs/core/core.dm index f75e7837af0..41a04733945 100644 --- a/code/modules/tgs/core/core.dm +++ b/code/modules/tgs/core/core.dm @@ -40,7 +40,7 @@ if(5) api_datum = /datum/tgs_api/v5 - var/datum/tgs_version/max_api_version = TgsMaximumAPIVersion(); + 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) TGS_ERROR_LOG("Detected unknown API version! Defaulting to latest. Update the DMAPI to fix this problem.") api_datum = /datum/tgs_api/latest @@ -64,10 +64,10 @@ TGS_WRITE_GLOBAL(tgs, null) TGS_ERROR_LOG("Failed to activate API!") -/world/TgsMaximumAPIVersion() +/world/TgsMaximumApiVersion() return new /datum/tgs_version("5.x.x") -/world/TgsMinimumAPIVersion() +/world/TgsMinimumApiVersion() return new /datum/tgs_version("3.2.x") /world/TgsInitializationComplete() diff --git a/code/modules/tgs/includes.dm b/code/modules/tgs/includes.dm index c803cf7ac26..4018074f4e3 100644 --- a/code/modules/tgs/includes.dm +++ b/code/modules/tgs/includes.dm @@ -14,4 +14,4 @@ #include "v5\_defines.dm" #include "v5\api.dm" #include "v5\commands.dm" -#include "v5\undef.dm" +#include "v5\undefs.dm" diff --git a/code/modules/tgs/v3210/api.dm b/code/modules/tgs/v3210/api.dm index e0d00ad15d1..245381b93ea 100644 --- a/code/modules/tgs/v3210/api.dm +++ b/code/modules/tgs/v3210/api.dm @@ -39,7 +39,7 @@ var/warned_custom_commands = FALSE /datum/tgs_api/v3210/ApiVersion() - return new /datum/tgs_version("3.2.1.0") + return new /datum/tgs_version("3.2.1.3") /datum/tgs_api/v3210/proc/trim_left(text) for (var/i = 1 to length(text)) @@ -160,7 +160,7 @@ 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.head_commit = entry["commit"] tm.author = entry["author"] tm.title = entry["title"] . += tm @@ -180,7 +180,7 @@ ExportService(SERVICE_REQUEST_KILL_PROCESS) /datum/tgs_api/v3210/ChatChannelInfo() - return list() + return list() // :omegalul: /datum/tgs_api/v3210/ChatBroadcast(message, list/channels) if(channels) diff --git a/code/modules/tgs/v3210/commands.dm b/code/modules/tgs/v3210/commands.dm index a1949da444d..4ccfc1a8a60 100644 --- a/code/modules/tgs/v3210/commands.dm +++ b/code/modules/tgs/v3210/commands.dm @@ -42,5 +42,11 @@ var/datum/tgs_chat_command/stc = new command_type var/datum/tgs_chat_user/user = new user.friendly_name = sender + + // Discord hack, fix the mention if it's only numbers (fuck you IRC trolls) + var/regex/discord_id_regex = regex(@"^[0-9]+$") + if(findtext(sender, discord_id_regex)) + sender = "<@[sender]>" + user.mention = sender return stc.Run(user, params) || TRUE diff --git a/code/modules/tgs/v4/api.dm b/code/modules/tgs/v4/api.dm index 5e7f3c60bed..4eb8e67d928 100644 --- a/code/modules/tgs/v4/api.dm +++ b/code/modules/tgs/v4/api.dm @@ -92,7 +92,7 @@ var/list/json = cached_json["testMerges"] for(var/entry in json) var/datum/tgs_revision_information/test_merge/tm = new - tm.time_merged = text2num(entry["timeMerged"]) + tm.timestamp = text2num(entry["timeMerged"]) var/list/revInfo = entry["revision"] if(revInfo) @@ -104,7 +104,7 @@ tm.url = entry["url"] tm.author = entry["author"] tm.number = entry["number"] - tm.pull_request_commit = entry["pullRequestRevision"] + tm.head_commit = entry["pullRequestRevision"] tm.comment = entry["comment"] cached_test_merges += tm @@ -114,15 +114,6 @@ /datum/tgs_api/v4/OnInitializationComplete() Export(TGS4_COMM_SERVER_PRIMED) - 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 - else - TGS_WARNING_LOG("world.sleep_offline unexpectedly changed!") - /datum/tgs_api/v4/OnTopic(T) var/list/params = params2list(T) var/their_sCK = params[TGS4_INTEROP_ACCESS_IDENTIFIER] @@ -257,7 +248,7 @@ return instance_name /datum/tgs_api/v4/TestMerges() - return cached_test_merges + return cached_test_merges.Copy() /datum/tgs_api/v4/EndProcess() Export(TGS4_COMM_END_PROCESS) diff --git a/code/modules/tgs/v5/README.md b/code/modules/tgs/v5/README.md new file mode 100644 index 00000000000..5b48d57a1f0 --- /dev/null +++ b/code/modules/tgs/v5/README.md @@ -0,0 +1,8 @@ +# DMAPI V5 + +This DMAPI implements bridge requests using HTTP GET requests to TGS. It has no security restrictions. + +- [_defines.dm](./_defines.dm) contains constant definitions. +- [api.dm](./api.dm) contains the bulk of the API code. +- [commands.dm](./commands.dm) contains functions relating to `/datum/tgs_chat_command`s. +- [undefs.dm](./undefs.dm) Undoes the work of `_defines.dm`. diff --git a/code/modules/tgs/v5/_defines.dm b/code/modules/tgs/v5/_defines.dm index 8fd84e19fa3..10bc4cbe406 100644 --- a/code/modules/tgs/v5/_defines.dm +++ b/code/modules/tgs/v5/_defines.dm @@ -79,6 +79,7 @@ #define DMAPI5_TOPIC_RESPONSE_CHAT_RESPONSES "chatResponses" #define DMAPI5_REVISION_INFORMATION_COMMIT_SHA "commitSha" +#define DMAPI5_REVISION_INFORMATION_TIMESTAMP "timestamp" #define DMAPI5_REVISION_INFORMATION_ORIGIN_COMMIT_SHA "originCommitSha" #define DMAPI5_CHAT_USER_ID "id" diff --git a/code/modules/tgs/v5/api.dm b/code/modules/tgs/v5/api.dm index 3791cbde843..6735ed5dec5 100644 --- a/code/modules/tgs/v5/api.dm +++ b/code/modules/tgs/v5/api.dm @@ -15,8 +15,12 @@ var/datum/tgs_revision_information/revision var/list/chat_channels + var/initialized = FALSE + /datum/tgs_api/v5/ApiVersion() - return new /datum/tgs_version("5.2.2") + return new /datum/tgs_version( + #include "interop_version.dm" + ) /datum/tgs_api/v5/OnWorldNew(minimum_required_security_level) server_port = world.params[DMAPI5_PARAM_SERVER_PORT] @@ -46,6 +50,7 @@ if(istype(revisionData)) revision = new revision.commit = revisionData[DMAPI5_REVISION_INFORMATION_COMMIT_SHA] + revision.timestamp = revisionData[DMAPI5_REVISION_INFORMATION_TIMESTAMP] revision.origin_commit = revisionData[DMAPI5_REVISION_INFORMATION_ORIGIN_COMMIT_SHA] else TGS_ERROR_LOG("Failed to decode [DMAPI5_RUNTIME_INFORMATION_REVISION] from runtime information!") @@ -61,15 +66,18 @@ if(revInfo) tm.commit = revisionData[DMAPI5_REVISION_INFORMATION_COMMIT_SHA] tm.origin_commit = revisionData[DMAPI5_REVISION_INFORMATION_ORIGIN_COMMIT_SHA] + tm.timestamp = entry[DMAPI5_REVISION_INFORMATION_TIMESTAMP] else TGS_WARNING_LOG("Failed to decode [DMAPI5_TEST_MERGE_REVISION] from test merge #[tm.number]!") - tm.time_merged = text2num(entry[DMAPI5_TEST_MERGE_TIME_MERGED]) + if(!tm.timestamp) + tm.timestamp = entry[DMAPI5_TEST_MERGE_TIME_MERGED] + 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.pull_request_commit = entry[DMAPI5_TEST_MERGE_PULL_REQUEST_REVISION] + tm.head_commit = entry[DMAPI5_TEST_MERGE_PULL_REQUEST_REVISION] tm.comment = entry[DMAPI5_TEST_MERGE_COMMENT] test_merges += tm @@ -79,6 +87,7 @@ chat_channels = list() DecodeChannels(runtime_information) + initialized = TRUE return TRUE /datum/tgs_api/v5/proc/RequireInitialBridgeResponse() @@ -88,15 +97,6 @@ /datum/tgs_api/v5/OnInitializationComplete() Bridge(DMAPI5_BRIDGE_COMMAND_PRIME) - 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 - else - TGS_WARNING_LOG("world.sleep_offline unexpectedly changed!") - /datum/tgs_api/v5/proc/TopicResponse(error_message = null) var/list/response = list() response[DMAPI5_RESPONSE_ERROR_MESSAGE] = error_message @@ -107,12 +107,16 @@ var/list/params = params2list(T) var/json = params[DMAPI5_TOPIC_DATA] if(!json) - return FALSE //continue world/Topic + return FALSE // continue to /world/Topic var/list/topic_parameters = json_decode(json) if(!topic_parameters) return TopicResponse("Invalid topic parameters json!"); + if(!initialized) + TGS_WARNING_LOG("Missed topic due to not being initialized: [T]") + return TRUE // too early to handle, but it's still our responsibility + var/their_sCK = topic_parameters[DMAPI5_PARAMETER_ACCESS_IDENTIFIER] if(their_sCK != access_identifier) return TopicResponse("Failed to decode [DMAPI5_PARAMETER_ACCESS_IDENTIFIER] from: [json]!"); @@ -284,7 +288,7 @@ /datum/tgs_api/v5/TestMerges() RequireInitialBridgeResponse() - return test_merges + return test_merges.Copy() /datum/tgs_api/v5/EndProcess() Bridge(DMAPI5_BRIDGE_COMMAND_KILL) @@ -329,7 +333,7 @@ /datum/tgs_api/v5/ChatChannelInfo() RequireInitialBridgeResponse() - return chat_channels + return chat_channels.Copy() /datum/tgs_api/v5/proc/DecodeChannels(chat_update_json) var/list/chat_channels_json = chat_update_json[DMAPI5_CHAT_UPDATE_CHANNELS] diff --git a/code/modules/tgs/v5/interop_version.dm b/code/modules/tgs/v5/interop_version.dm new file mode 100644 index 00000000000..c7bf62ecae3 --- /dev/null +++ b/code/modules/tgs/v5/interop_version.dm @@ -0,0 +1 @@ +"5.3.0" diff --git a/code/modules/tgs/v5/undefs.dm b/code/modules/tgs/v5/undefs.dm new file mode 100644 index 00000000000..5885a60e75c --- /dev/null +++ b/code/modules/tgs/v5/undefs.dm @@ -0,0 +1,99 @@ +#undef DMAPI5_PARAM_SERVER_PORT +#undef DMAPI5_PARAM_ACCESS_IDENTIFIER + +#undef DMAPI5_BRIDGE_DATA +#undef DMAPI5_TOPIC_DATA + +#undef DMAPI5_BRIDGE_COMMAND_PORT_UPDATE +#undef DMAPI5_BRIDGE_COMMAND_STARTUP +#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_PARAMETER_CUSTOM_COMMANDS + +#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_BRIDGE_RESPONSE_RUNTIME_INFORMATION + +#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_CHAT_UPDATE_CHANNELS + +#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_COMMAND_CHAT_CHANNELS_UPDATE +#undef DMAPI5_TOPIC_COMMAND_SERVER_PORT_UPDATE +#undef DMAPI5_TOPIC_COMMAND_HEARTBEAT +#undef DMAPI5_TOPIC_COMMAND_WATCHDOG_REATTACH + +#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_PARAMETER_CHAT_UPDATE +#undef DMAPI5_TOPIC_PARAMETER_NEW_SERVER_VERSION + +#undef DMAPI5_TOPIC_RESPONSE_COMMAND_RESPONSE_MESSAGE +#undef DMAPI5_TOPIC_RESPONSE_CHAT_RESPONSES + +#undef DMAPI5_REVISION_INFORMATION_COMMIT_SHA +#undef DMAPI5_REVISION_INFORMATION_TIMESTAMP +#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 diff --git a/code/world.dm b/code/world.dm index cba467bd0b5..058e0a08da9 100644 --- a/code/world.dm +++ b/code/world.dm @@ -430,7 +430,7 @@ var/list/world_api_rate_limit = list() /proc/establish_db_connection(var/DBConnection/con) if (!config.sql_enabled) return FALSE - + if (!con) error("No DBConnection object passed to establish_db_connection() proc.") return FALSE diff --git a/html/changelog.html b/html/changelog.html index 5e43f69928a..87dfb8eda9f 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -35,6 +35,20 @@ -->
+

09 February 2021

+

Geeves updated:

+ + +

08 February 2021

+

MattAtlas, DasFox updated:

+ +

07 February 2021

Doxxmedearly updated: