diff --git a/code/__defines/dcs/signals/signals_tgui.dm b/code/__defines/dcs/signals/signals_tgui.dm new file mode 100644 index 0000000000..67b979be78 --- /dev/null +++ b/code/__defines/dcs/signals/signals_tgui.dm @@ -0,0 +1,2 @@ +/// Window is fully visible and we can make fragile calls +#define COMSIG_TGUI_WINDOW_VISIBLE "tgui_window_visible" diff --git a/code/controllers/configuration/entries/general.dm b/code/controllers/configuration/entries/general.dm index a1801eccb6..4d148f21c9 100644 --- a/code/controllers/configuration/entries/general.dm +++ b/code/controllers/configuration/entries/general.dm @@ -732,3 +732,6 @@ /datum/config_entry/string/chatlog_database_api_endpoint /datum/config_entry/flag/forbid_admin_profiling + +/datum/config_entry/flag/pixel_size_limit + default = FALSE diff --git a/code/datums/chat_message.dm b/code/datums/chat_message.dm index 8b15ba87a6..42ad0df445 100644 --- a/code/datums/chat_message.dm +++ b/code/datums/chat_message.dm @@ -452,24 +452,16 @@ var/list/runechat_image_cache = list() return (width - bound_width) * -0.5 + get_oversized_icon_offsets()["x"] /atom/movable/runechat_y_offset() - return ..() + get_oversized_icon_offsets()["y"] + return ..() + get_oversized_icon_offsets()["y"] * 1.5 // Fix to use 2 if we ever can measure sprites /* Nothing special /mob/runechat_x_offset(width, height) return (width - bound_width) * -0.5 */ -/mob/runechat_y_offset(var/consider_height) - if(consider_height) - return ..() +/mob/runechat_y_offset() return ..()*size_multiplier -/mob/living/runechat_y_offset(var/consider_height) - var/size_diff = vis_height - world.icon_size - if(size_diff > 0) - return (..(TRUE) + size_diff) * size_multiplier - return ..(FALSE) - // Allows you to specify a different attachment point for messages from yourself /atom/proc/runechat_holder(datum/chatmessage/CM) return src diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index e16c37c548..842f6f3cba 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -292,7 +292,7 @@ var/list/preferences_datums = list() to_chat(usr,span_notice("Character [player_setup?.preferences?.real_name] saved!")) save_preferences() else if(href_list["reload"]) - load_preferences() + load_preferences(TRUE) load_character() attempt_vr(client.prefs_vr,"load_vore","") sanitize_preferences() @@ -390,7 +390,7 @@ var/list/preferences_datums = list() error("Player picked [choice] slot to load, but that wasn't one we sent.") return - load_preferences() + load_preferences(TRUE) load_character(slotnum) attempt_vr(user.client?.prefs_vr,"load_vore","") sanitize_preferences() diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index a7e278fddc..9c45e44418 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -131,7 +131,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car savefile.set_entry("lastnews", lastnews) savefile.set_entry("lastlorenews", lastlorenews) -/datum/preferences/proc/load_preferences() +/datum/preferences/proc/load_preferences(skip_client) if(!savefile) stack_trace("Attempted to load the preferences of [client] without a savefile; did you forget to call load_savefile?") load_savefile() @@ -147,7 +147,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car fcopy(savefile.path, bacpath) //byond helpfully lets you use a savefile for the first arg. return FALSE - apply_all_client_preferences() + if(!skip_client) + apply_all_client_preferences() load_early_prefs() sanitize_early_prefs() diff --git a/code/modules/tgui/tgui_window.dm b/code/modules/tgui/tgui_window.dm index 3bae28e39c..06ebd09478 100644 --- a/code/modules/tgui/tgui_window.dm +++ b/code/modules/tgui/tgui_window.dm @@ -11,6 +11,7 @@ var/is_browser = FALSE var/status = TGUI_WINDOW_CLOSED var/locked = FALSE + var/visible = FALSE var/datum/tgui/locked_by var/datum/subscriber_object var/subscriber_delegate @@ -24,6 +25,8 @@ var/initial_inline_html var/initial_inline_js var/initial_inline_css + + var/list/oversized_payloads = list() var/mouse_event_macro_set = FALSE /** @@ -54,7 +57,6 @@ if(pooled) src.pool_index = TGUI_WINDOW_INDEX(id) - /** * public * @@ -116,7 +118,7 @@ html = replacetextEx(html, "\n", inline_assets_str) // Inject inline HTML if (inline_html) - html = replacetextEx(html, "", inline_html) + html = replacetextEx(html, "", isfile(inline_html) ? file2text(inline_html) : inline_html) // Inject inline JS if (inline_js) inline_js = "" @@ -230,7 +232,7 @@ * * optional can_be_suspended bool */ -/datum/tgui_window/proc/close(can_be_suspended = TRUE, logout = FALSE) +/datum/tgui_window/proc/close(can_be_suspended = TRUE) if(!client) return if(mouse_event_macro_set) @@ -241,25 +243,18 @@ #endif status = TGUI_WINDOW_READY send_message("suspend") - // You would think that BYOND would null out client or make it stop passing istypes or, y'know, ANYTHING during - // logout, but nope! It appears to be perfectly valid to call winset by every means we can measure in Logout, - // and yet it causes a bad client runtime. To avoid that happening, we just have to know if we're in Logout or - // not. - if(!logout && client) - winset(client, null, "mapwindow.map.focus=true") return #ifdef TGUI_DEBUGGING log_tgui(client, "[id]/close") #endif release_lock() + visible = FALSE status = TGUI_WINDOW_CLOSED message_queue = null // Do not close the window to give user some time // to read the error message. if(!fatally_errored) client << browse(null, "window=[id]") - if(!logout && client) - winset(client, null, "mapwindow.map.focus=true") /** * public @@ -388,6 +383,9 @@ switch(type) if("ping") send_message("ping/reply", payload) + if("visible") + visible = TRUE + // SEND_SIGNAL(src, COMSIG_TGUI_WINDOW_VISIBLE, client) // Not used yet if("suspend") close(can_be_suspended = TRUE) if("close") @@ -395,17 +393,55 @@ if("openLink") client << link(href_list["url"]) if("cacheReloaded") - // Reinitialize reinitialize() - // Resend the assets - for(var/asset in sent_assets) - send_asset(asset) if("chat/resend") SSchat.handle_resend(client, payload) + /* Does not work with tgui say, so not in use yet + if("oversizedPayloadRequest") + var/payload_id = payload["id"] + var/chunk_count = payload["chunkCount"] + var/permit_payload = chunk_count <= CONFIG_GET(number/tgui_max_chunk_count) + if(permit_payload) + create_oversized_payload(payload_id, payload["type"], chunk_count) + send_message("oversizePayloadResponse", list("allow" = permit_payload, "id" = payload_id)) + if("payloadChunk") + var/payload_id = payload["id"] + append_payload_chunk(payload_id, payload["chunk"]) + send_message("acknowlegePayloadChunk", list("id" = payload_id)) + */ /datum/tgui_window/vv_edit_var(var_name, var_value) return var_name != NAMEOF(src, id) && ..() +/datum/tgui_window/proc/create_oversized_payload(payload_id, message_type, chunk_count) + if(oversized_payloads[payload_id]) + stack_trace("Attempted to create oversized tgui payload with duplicate ID.") + return + oversized_payloads[payload_id] = list( + "type" = message_type, + "count" = chunk_count, + "chunks" = list(), + "timeout" = addtimer(CALLBACK(src, PROC_REF(remove_oversized_payload), payload_id), 1 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE|TIMER_STOPPABLE) + ) + +/datum/tgui_window/proc/append_payload_chunk(payload_id, chunk) + var/list/payload = oversized_payloads[payload_id] + if(!payload) + return + var/list/chunks = payload["chunks"] + chunks += chunk + if(length(chunks) >= payload["count"]) + deltimer(payload["timeout"]) + var/message_type = payload["type"] + var/final_payload = chunks.Join() + remove_oversized_payload(payload_id) + on_message(message_type, json_decode(final_payload), list("type" = message_type, "payload" = final_payload, "tgui" = TRUE, "window_id" = id)) + else + payload["timeout"] = addtimer(CALLBACK(src, PROC_REF(remove_oversized_payload), payload_id), 1 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE|TIMER_STOPPABLE) + +/datum/tgui_window/proc/remove_oversized_payload(payload_id) + oversized_payloads -= payload_id + /datum/tgui_window/proc/set_mouse_macro() if(mouse_event_macro_set) diff --git a/code/modules/vore/resizing/resize_vr.dm b/code/modules/vore/resizing/resize_vr.dm index 4a4ad92b97..26adacb051 100644 --- a/code/modules/vore/resizing/resize_vr.dm +++ b/code/modules/vore/resizing/resize_vr.dm @@ -86,19 +86,17 @@ * * ignore_prefs - CHANGE_ME. Default: FALSE * * aura_animation - CHANGE_ME. Default: TRUE */ -//#define USE_DIRECT_MULTIPLIERS //Uncomment to use old resize calculations. /mob/living/proc/resize(var/new_size, var/animate = TRUE, var/uncapped = FALSE, var/ignore_prefs = FALSE, var/aura_animation = TRUE) if(!uncapped) - #ifdef USE_DIRECT_MULTIPLIERS - new_size = clamp(new_size, RESIZE_MINIMUM, RESIZE_MAXIMUM) - #else - var/size_diff = ((runechat_y_offset() / size_multiplier) * new_size) // This returns 32 multiplied with the new size - var/size_cap = world.icon_size * (RESIZE_MAXIMUM+(ishuman(src)?0:0.5)) //Grace for non-humanoids so they don't get forcibly shrunk. - if(size_diff - size_cap > 0) - var/real_diff = size_cap / size_diff // Returns our diff based on the offset to world size - new_size *= real_diff // Applies our diff to the new size - new_size = clamp(new_size, RESIZE_MINIMUM, RESIZE_MAXIMUM) //If the sprite is below 32, we clamp it to only go to the resize max. - #endif + if((z in using_map.station_levels) && CONFIG_GET(flag/pixel_size_limit)) + var/size_diff = ((runechat_y_offset() / size_multiplier) * new_size) // This returns 32 multiplied with the new size + var/size_cap = world.icon_size * RESIZE_MAXIMUM //Grace for non-humanoids so they don't get forcibly shrunk. + if(size_diff - size_cap > 0) + var/real_diff = size_cap / size_diff // Returns our diff based on the offset to world size + new_size *= real_diff // Applies our diff to the new size + new_size = clamp(new_size, RESIZE_MINIMUM, RESIZE_MAXIMUM) //If the sprite is below 32, we clamp it to only go to the resize max. + else + new_size = clamp(new_size, RESIZE_MINIMUM, RESIZE_MAXIMUM) var/datum/component/resize_guard/guard = GetComponent(/datum/component/resize_guard) if(guard) qdel(guard) @@ -140,7 +138,7 @@ animate_aura(src, color = aura_color, offset = aura_offset, anim_duration = aura_anim_duration, loops = aura_loops, grow_to = aura_grow_to) else update_transform() //Lame way -//#undef USE_DIRECT_MULTIPLIERS //Uncomment to use old resize calculations. + /mob/living/carbon/human/resize(var/new_size, var/animate = TRUE, var/uncapped = FALSE, var/ignore_prefs = FALSE, var/aura_animation = TRUE) if(!resizable && !ignore_prefs) return 1 diff --git a/config/example/config.txt b/config/example/config.txt index 7ad2b539d2..9f7b48cc7b 100644 --- a/config/example/config.txt +++ b/config/example/config.txt @@ -589,3 +589,6 @@ JUKEBOX_TRACK_FILES config/jukebox.json ## Uncomment to block granting profiling privileges to users with R_DEBUG, for performance purposes #FORBID_ADMIN_PROFILING + +## Uncomment to limit resize caps depending on sprite icon height +#PIXEL_SIZE_LIMIT diff --git a/tgui/packages/tgui/backend.ts b/tgui/packages/tgui/backend.ts index 670bf2bff4..2d5bf090c3 100644 --- a/tgui/packages/tgui/backend.ts +++ b/tgui/packages/tgui/backend.ts @@ -226,6 +226,7 @@ export const backendMiddleware = (store) => { Byond.winset(Byond.windowId, { 'is-visible': true, }); + Byond.sendMessage('visible'); perf.mark('resume/finish'); if (process.env.NODE_ENV !== 'production') { logger.log( diff --git a/vorestation.dme b/vorestation.dme index 2f2b26b1e9..f19719f652 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -181,6 +181,7 @@ #include "code\__defines\dcs\signals.dm" #include "code\__defines\dcs\signals\signals_client.dm" #include "code\__defines\dcs\signals\signals_subsystem.dm" +#include "code\__defines\dcs\signals\signals_tgui.dm" #include "code\__defines\dcs\signals\signals_turf.dm" #include "code\__defines\dcs\signals\signals_mobs\signals_mob_main.dm" #include "code\__defines\traits\_traits.dm"