From d493886875d0e4f803b32254e0a3fe6017a5936d Mon Sep 17 00:00:00 2001 From: Artur Date: Wed, 23 Sep 2020 19:14:50 +0300 Subject: [PATCH 1/2] Speedmerge fix --- code/__DEFINES/subsystems.dm | 1 + code/__HELPERS/icons.dm | 5 +- code/controllers/subsystem/statpanel.dm | 240 ++++++++++++++++-------- 3 files changed, 162 insertions(+), 84 deletions(-) diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index a3fdf762c2..9deddd4b46 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -122,6 +122,7 @@ #define FIRE_PRIORITY_PROJECTILES 200 #define FIRE_PRIORITY_TICKER 200 #define FIRE_PRIORITY_ATMOS_ADJACENCY 300 +#define FIRE_PRIORITY_STATPANEL 390 #define FIRE_PRIORITY_CHAT 400 #define FIRE_PRIORITY_OVERLAYS 500 #define FIRE_PRIORITY_INPUT 1000 // This must always always be the max highest priority. Player input must never be lost. diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index 2bd477d98c..4723577fad 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -1223,7 +1223,7 @@ GLOBAL_DATUM_INIT(dummySave, /savefile, new("tmp/dummySave.sav")) //Cache of ico return "" //Costlier version of icon2html() that uses getFlatIcon() to account for overlays, underlays, etc. Use with extreme moderation, ESPECIALLY on mobs. -/proc/costly_icon2html(thing, target) +/proc/costly_icon2html(thing, target, sourceonly = FALSE) if (!thing) return @@ -1231,4 +1231,5 @@ GLOBAL_DATUM_INIT(dummySave, /savefile, new("tmp/dummySave.sav")) //Cache of ico return icon2html(thing, target) var/icon/I = getFlatIcon(thing) - return icon2html(I, target) + return icon2html(I, target, sourceonly = sourceonly) + diff --git a/code/controllers/subsystem/statpanel.dm b/code/controllers/subsystem/statpanel.dm index 4731940f41..cf7d4ba533 100644 --- a/code/controllers/subsystem/statpanel.dm +++ b/code/controllers/subsystem/statpanel.dm @@ -1,7 +1,8 @@ SUBSYSTEM_DEF(statpanels) name = "Stat Panels" wait = 4 - init_order = INIT_ORDER_STATPANELS //Really early so we can debug MC roundstart + init_order = INIT_ORDER_STATPANELS + priority = FIRE_PRIORITY_STATPANEL runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY var/list/currentrun = list() var/encoded_global_data @@ -9,13 +10,15 @@ SUBSYSTEM_DEF(statpanels) var/list/cached_images = list() /datum/controller/subsystem/statpanels/fire(resumed = FALSE) - if(!resumed) + if (!resumed) var/datum/map_config/cached = SSmapping.next_map_config + var/round_time = world.time - SSticker.round_start_time var/list/global_data = list( "Map: [SSmapping.config?.map_name || "Loading..."]", cached ? "Next Map: [cached.map_name]" : null, "Round ID: [GLOB.round_id ? GLOB.round_id : "NULL"]", - "[SStime_track.stat_time_text]", + "Server Time: [time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]", + "Round Time: [round_time > MIDNIGHT_ROLLOVER ? "[round(round_time/MIDNIGHT_ROLLOVER)]:[worldtime2text()]" : worldtime2text()]", "Station Time: [STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)]", "Time Dilation: [round(SStime_track.time_dilation_current,1)]% AVG:([round(SStime_track.time_dilation_avg_fast,1)]%, [round(SStime_track.time_dilation_avg,1)]%, [round(SStime_track.time_dilation_avg_slow,1)]%)" ) @@ -24,96 +27,169 @@ SUBSYSTEM_DEF(statpanels) var/ETA = SSshuttle.emergency.getModeStr() if(ETA) global_data += "[ETA] [SSshuttle.emergency.getTimerStr()]" +/* Please fix + if(SSvote.mode) + var/static/list/supported = list(PLURALITY_VOTING, APPROVAL_VOTING) + global_data += "Vote active!, There is currently a vote running. Question: [SSvote.question]" + if(!(SSvote.vote_system in supported)) + global_data += ", The current vote system is not supported by statpanel rendering. Please vote manually by opening the vote popup using the action button or chat link." + return + global_data += "Time Left:, [round(SSvote.end_time - world.time)] seconds" + + global_data += "Choices:" + for(var/i in 1 to SSvote.choice_statclicks.len) + var/choice = SSvote.choice_statclicks[i] + var/ivotedforthis = FALSE + if(usr.ckey) + switch(SSvote.vote_system) + if(APPROVAL_VOTING) + ivotedforthis = SSvote.voted[usr.ckey] && (i in SSvote.voted[usr.ckey]) + if(PLURALITY_VOTING) + ivotedforthis = SSvote.voted[usr.ckey] == i + + global_data += (ivotedforthis? "\[X\]" : "\[ \]", SSvote.choice_statclicks[choice]) +*/ + encoded_global_data = url_encode(json_encode(global_data)) - - var/list/mc_data = list( - list("CPU:", world.cpu), - list("Instances:", "[num2text(world.contents.len, 10)]"), - list("World Time:", "[world.time]"), - list("Globals:", GLOB.stat_entry(), "\ref[GLOB]"), - list("[config]:", config.stat_entry(), "\ref[config]"), - list("Byond:", "(FPS:[world.fps]) (TickCount:[world.time/world.tick_lag]) (TickDrift:[round(Master.tickdrift,1)]([round((Master.tickdrift/(world.time/world.tick_lag))*100,0.1)]%)) (Internal Tick Usage: [round(MAPTICK_LAST_INTERNAL_TICK_USAGE,0.1)]%)"), - list("Master Controller:", Master.stat_entry(), "\ref[Master]"), - list("Failsafe Controller:", Failsafe.stat_entry(), "\ref[Failsafe]"), - list("","") - ) - for(var/ss in Master.subsystems) - var/datum/controller/subsystem/sub_system = ss - mc_data[++mc_data.len] = list("\[[sub_system.state_letter()]][sub_system.name]", sub_system.stat_entry(), "\ref[sub_system]") - mc_data[++mc_data.len] = list("Camera Net", "Cameras: [GLOB.cameranet.cameras.len] | Chunks: [GLOB.cameranet.chunks.len]", "\ref[GLOB.cameranet]") - mc_data_encoded = url_encode(json_encode(mc_data)) src.currentrun = GLOB.clients.Copy() - + mc_data_encoded = null var/list/currentrun = src.currentrun while(length(currentrun)) var/client/target = currentrun[length(currentrun)] currentrun.len-- - var/ping_str = url_encode("Ping: [round(target.lastping, 1)]ms (Average: [round(target.avgping, 1)]ms)") - var/other_str = url_encode(json_encode(target.mob.get_status_tab_items())) - target << output("[encoded_global_data];[ping_str];[other_str]", "statbrowser:update") + if(!target.statbrowser_ready) + continue + if(target.stat_tab == "Status") + var/ping_str = url_encode("Ping: [round(target.lastping, 1)]ms (Average: [round(target.avgping, 1)]ms)") + var/other_str = url_encode(json_encode(target.mob.get_status_tab_items())) + target << output("[encoded_global_data];[ping_str];[other_str]", "statbrowser:update") if(!target.holder) target << output("", "statbrowser:remove_admin_tabs") else - var/turf/eye_turf = get_turf(target.eye) - var/coord_entry = url_encode(COORD(eye_turf)) - target << output("[mc_data_encoded];[coord_entry];[url_encode(target.holder.href_token)]", "statbrowser:update_mc") - var/list/ahelp_tickets = GLOB.ahelp_tickets.stat_entry() - target << output("[url_encode(json_encode(ahelp_tickets))];", "statbrowser:update_tickets") - if(!length(GLOB.sdql2_queries)) + if(!("MC" in target.panel_tabs) || !("Tickets" in target.panel_tabs)) + target << output("[url_encode(target.holder.href_token)]", "statbrowser:add_admin_tabs") + if(target.stat_tab == "MC") + var/turf/eye_turf = get_turf(target.eye) + var/coord_entry = url_encode(COORD(eye_turf)) + if(!mc_data_encoded) + generate_mc_data() + target << output("[mc_data_encoded];[coord_entry]", "statbrowser:update_mc") + if(target.stat_tab == "Tickets") + var/list/ahelp_tickets = GLOB.ahelp_tickets.stat_entry() + target << output("[url_encode(json_encode(ahelp_tickets))];", "statbrowser:update_tickets") + if(!length(GLOB.sdql2_queries) && ("SDQL2" in target.panel_tabs)) target << output("", "statbrowser:remove_sdql2") - else - var/list/sqdl2A = list() - sqdl2A[++sqdl2A.len] = list("", "Access Global SDQL2 List", REF(GLOB.sdql2_vv_statobj)) - var/list/sqdl2B = list() + else if(length(GLOB.sdql2_queries) && (target.stat_tab == "SDQL2" || !("SDQL2" in target.panel_tabs))) + var/list/sdql2A = list() + sdql2A[++sdql2A.len] = list("", "Access Global SDQL2 List", REF(GLOB.sdql2_vv_statobj)) + var/list/sdql2B = list() for(var/i in GLOB.sdql2_queries) var/datum/SDQL2_query/Q = i - sqdl2B = Q.generate_stat() - sqdl2A += sqdl2B - target << output(url_encode(json_encode(sqdl2A)), "statbrowser:update_sdql2") - var/list/proc_holders = target.mob.get_proc_holders() - target.spell_tabs.Cut() - for(var/phl in proc_holders) - var/list/proc_holder_list = phl - target.spell_tabs |= proc_holder_list[1] - var/proc_holders_encoded = "" - if(length(proc_holders)) - proc_holders_encoded = url_encode(json_encode(proc_holders)) - target << output("[url_encode(json_encode(target.spell_tabs))];[proc_holders_encoded]", "statbrowser:update_spells") - if(target.mob?.listed_turf) - var/mob/target_mob = target.mob - if(!target_mob.TurfAdjacent(target_mob.listed_turf)) - target << output("", "statbrowser:remove_listedturf") - target_mob.listed_turf = null - else - var/list/overrides = list() - var/list/turfitems = list() - for(var/img in target.images) - var/image/target_image = img - if(!target_image.loc || target_image.loc.loc != target_mob.listed_turf || !target_image.override) - continue - overrides += target_image.loc - if(!(REF(target_mob.listed_turf) in cached_images)) - target << browse_rsc(getFlatIcon(target_mob.listed_turf, no_anim = TRUE), "[REF(target_mob.listed_turf)].png") - cached_images += REF(target_mob.listed_turf) - turfitems[++turfitems.len] = list("[target_mob.listed_turf]", REF(target_mob.listed_turf), "[REF(target_mob.listed_turf)].png") - for(var/tc in target_mob.listed_turf) - var/atom/movable/turf_content = tc - if(turf_content.mouse_opacity == MOUSE_OPACITY_TRANSPARENT) - continue - if(turf_content.invisibility > target_mob.see_invisible) - continue - if(turf_content in overrides) - continue - if(turf_content.IsObscured()) - continue - if(length(turfitems) < 30) // only create images for the first 30 items on the turf, for performance reasons - if(!(REF(turf_content) in cached_images)) - target << browse_rsc(getFlatIcon(turf_content, no_anim = TRUE), "[REF(turf_content)].png") - cached_images += REF(turf_content) - turfitems[++turfitems.len] = list("[turf_content.name]", REF(turf_content), "[REF(turf_content)].png") - else - turfitems[++turfitems.len] = list("[turf_content.name]", REF(turf_content)) - turfitems = url_encode(json_encode(turfitems)) - target << output("[turfitems];", "statbrowser:update_listedturf") + sdql2B = Q.generate_stat() + sdql2A += sdql2B + target << output(url_encode(json_encode(sdql2A)), "statbrowser:update_sdql2") + if(target.mob) + var/mob/M = target.mob + if((target.stat_tab in target.spell_tabs) || !length(target.spell_tabs) && (length(M.mob_spell_list) || length(M.mind?.spell_list))) + var/list/proc_holders = M.get_proc_holders() + target.spell_tabs.Cut() + for(var/phl in proc_holders) + var/list/proc_holder_list = phl + target.spell_tabs |= proc_holder_list[1] + var/proc_holders_encoded = "" + if(length(proc_holders)) + proc_holders_encoded = url_encode(json_encode(proc_holders)) + target << output("[url_encode(json_encode(target.spell_tabs))];[proc_holders_encoded]", "statbrowser:update_spells") + if(M?.listed_turf) + var/mob/target_mob = M + if(!target_mob.TurfAdjacent(target_mob.listed_turf)) + target << output("", "statbrowser:remove_listedturf") + target_mob.listed_turf = null + else if(target.stat_tab == M?.listed_turf.name || !(M?.listed_turf.name in target.panel_tabs)) + var/list/overrides = list() + var/list/turfitems = list() + for(var/img in target.images) + var/image/target_image = img + if(!target_image.loc || target_image.loc.loc != target_mob.listed_turf || !target_image.override) + continue + overrides += target_image.loc + turfitems[++turfitems.len] = list("[target_mob.listed_turf]", REF(target_mob.listed_turf), icon2html(target_mob.listed_turf, target, sourceonly=TRUE)) + for(var/tc in target_mob.listed_turf) + var/atom/movable/turf_content = tc + if(turf_content.mouse_opacity == MOUSE_OPACITY_TRANSPARENT) + continue + if(turf_content.invisibility > target_mob.see_invisible) + continue + if(turf_content in overrides) + continue + if(turf_content.IsObscured()) + continue + if(length(turfitems) < 30) // only create images for the first 30 items on the turf, for performance reasons + if(!(REF(turf_content) in cached_images)) + cached_images += REF(turf_content) + turf_content.RegisterSignal(turf_content, COMSIG_PARENT_QDELETING, /atom/.proc/remove_from_cache) // we reset cache if anything in it gets deleted + if(ismob(turf_content) || length(turf_content.overlays) > 2) + turfitems[++turfitems.len] = list("[turf_content.name]", REF(turf_content), costly_icon2html(turf_content, target, sourceonly=TRUE)) + else + turfitems[++turfitems.len] = list("[turf_content.name]", REF(turf_content), icon2html(turf_content, target, sourceonly=TRUE)) + else + turfitems[++turfitems.len] = list("[turf_content.name]", REF(turf_content)) + else + turfitems[++turfitems.len] = list("[turf_content.name]", REF(turf_content)) + turfitems = url_encode(json_encode(turfitems)) + target << output("[turfitems];", "statbrowser:update_listedturf") if(MC_TICK_CHECK) return + + +/datum/controller/subsystem/statpanels/proc/generate_mc_data() + var/list/mc_data = list( + list("CPU:", world.cpu), + list("Instances:", "[num2text(world.contents.len, 10)]"), + list("World Time:", "[world.time]"), + list("Globals:", GLOB.stat_entry(), "\ref[GLOB]"), + list("[config]:", config.stat_entry(), "\ref[config]"), + list("Byond:", "(FPS:[world.fps]) (TickCount:[world.time/world.tick_lag]) (TickDrift:[round(Master.tickdrift,1)]([round((Master.tickdrift/(world.time/world.tick_lag))*100,0.1)]%)) (Internal Tick Usage: [round(MAPTICK_LAST_INTERNAL_TICK_USAGE,0.1)]%)"), + list("Master Controller:", Master.stat_entry(), "\ref[Master]"), + list("Failsafe Controller:", Failsafe.stat_entry(), "\ref[Failsafe]"), + list("","") + ) + for(var/ss in Master.subsystems) + var/datum/controller/subsystem/sub_system = ss + mc_data[++mc_data.len] = list("\[[sub_system.state_letter()]][sub_system.name]", sub_system.stat_entry(), "\ref[sub_system]") + mc_data[++mc_data.len] = list("Camera Net", "Cameras: [GLOB.cameranet.cameras.len] | Chunks: [GLOB.cameranet.chunks.len]", "\ref[GLOB.cameranet]") + mc_data_encoded = url_encode(json_encode(mc_data)) + +/atom/proc/remove_from_cache() + SSstatpanels.cached_images -= REF(src) + +/// verbs that send information from the browser UI +/client/verb/set_tab(tab as text|null) + set name = "Set Tab" + set hidden = TRUE + + stat_tab = tab + +/client/verb/send_tabs(tabs as text|null) + set name = "Send Tabs" + set hidden = TRUE + + panel_tabs |= tabs + +/client/verb/remove_tabs(tabs as text|null) + set name = "Remove Tabs" + set hidden = TRUE + + panel_tabs -= tabs + +/client/verb/reset_tabs() + set name = "Reset Tabs" + set hidden = TRUE + + panel_tabs = list() + +/client/verb/panel_ready() + set name = "Panel Ready" + set hidden = TRUE + + statbrowser_ready = TRUE From e483cf06b3690bb5fe53d0f2d49666f695b5166e Mon Sep 17 00:00:00 2001 From: Artur Date: Wed, 23 Sep 2020 19:54:30 +0300 Subject: [PATCH 2/2] fIXD --- code/modules/client/client_defines.dm | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index d4f8547c34..755665583a 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -130,6 +130,15 @@ /// datum wrapper for client view var/datum/view_data/view_size + /// our current tab + var/stat_tab + + /// whether our browser is ready or not yet + var/statbrowser_ready = FALSE + + /// list of all tabs + var/list/panel_tabs = list() + /// list of tabs containing spells and abilities var/list/spell_tabs = list() /// list of tabs containing verbs