CDN Assets + TGChat + Statbrowser Restyle (#10211)

* asset cache cdn

* Fix cdn rsc (#52886)

I was converting this to use length so it didn't have to care if the list existed or not, and forgot to remove the .len. this broke cdn .rsc files because length(num) returns 0.

* Add warning about https to the external rsc config (#53367)

today in hostchat we discovered that most of the servers who tried to 
do cdn the .rsc, had unknown issues because they had used https:// 
urls. Byond can't into https.

like 5 servers had failed to get this to work because of that pitfall, 
so im gonna add a warning to the config.

* tchat

* tgchat compile

* fixes

* Merge pull request #53011 from stylemistake/tgui-chat-fix-asay

tgchat: Fix asay

* chat color

* logging

* webstorage

* compile TGUI

* actually like compiles on the DM side

* Update chat-dark.scss

* Update chat-light.scss

* Update resources.txt

* Update tgui-panel.bundle.css

* Colors

* compile

* s

* s

* Ports Gamers TGChat so we can edit it. - NOT LIVE TGCHAT BRANCH (#10226)

* asset cache cdn

* Fix cdn rsc (#52886)

I was converting this to use length so it didn't have to care if the list existed or not, and forgot to remove the .len. this broke cdn .rsc files because length(num) returns 0.

* Add warning about https to the external rsc config (#53367)

today in hostchat we discovered that most of the servers who tried to 
do cdn the .rsc, had unknown issues because they had used https:// 
urls. Byond can't into https.

like 5 servers had failed to get this to work because of that pitfall, 
so im gonna add a warning to the config.

* tchat

* tgchat compile

* fixes

* Merge pull request #53011 from stylemistake/tgui-chat-fix-asay

tgchat: Fix asay

* chat color

* logging

* webstorage

* compile TGUI

* actually like compiles on the DM side

* Update chat-dark.scss

* Update chat-light.scss

* Update resources.txt

* Update tgui-panel.bundle.css

* Colors

* compile

* s

* s

Co-authored-by: Kyle Spier-Swenson <kyleshome@gmail.com>
Co-authored-by: Aleksej Komarov <stylemistake@gmail.com>
Co-authored-by: TheGamerdk <5618080+TheGamerdk@users.noreply.github.com>
Co-authored-by: skoglol <33292112+kriskog@users.noreply.github.com>
Co-authored-by: TheSmallBlue <ilanmori@hotmail.com>

* Fixes Replay Chat

* Update to_chat.dm

* Update chat.dm

* Update demo.dm

* yarn berry

* yarn berry compile

* Update resources.txt

* Update config/resources.txt

* Update resources.txt

* Attempt at fixing reconnect.

* Lets try fix it again

* oops

* THROW THE SINK AT IT

* ree

* Makes Travis work again thank you jamie

* Fixes snowflake images

* Update security.dm

* Updates TGChat Test Merge (#10307)

* asset cache cdn

* Fix cdn rsc (#52886)

I was converting this to use length so it didn't have to care if the list existed or not, and forgot to remove the .len. this broke cdn .rsc files because length(num) returns 0.

* Add warning about https to the external rsc config (#53367)

today in hostchat we discovered that most of the servers who tried to 
do cdn the .rsc, had unknown issues because they had used https:// 
urls. Byond can't into https.

like 5 servers had failed to get this to work because of that pitfall, 
so im gonna add a warning to the config.

* tchat

* tgchat compile

* fixes

* Merge pull request #53011 from stylemistake/tgui-chat-fix-asay

tgchat: Fix asay

* chat color

* logging

* webstorage

* compile TGUI

* actually like compiles on the DM side

* Update chat-dark.scss

* Update chat-light.scss

* Update resources.txt

* Update tgui-panel.bundle.css

* Colors

* compile

* s

* s

* Ports Gamers TGChat so we can edit it. - NOT LIVE TGCHAT BRANCH (#10226)

* asset cache cdn

* Fix cdn rsc (#52886)

I was converting this to use length so it didn't have to care if the list existed or not, and forgot to remove the .len. this broke cdn .rsc files because length(num) returns 0.

* Add warning about https to the external rsc config (#53367)

today in hostchat we discovered that most of the servers who tried to 
do cdn the .rsc, had unknown issues because they had used https:// 
urls. Byond can't into https.

like 5 servers had failed to get this to work because of that pitfall, 
so im gonna add a warning to the config.

* tchat

* tgchat compile

* fixes

* Merge pull request #53011 from stylemistake/tgui-chat-fix-asay

tgchat: Fix asay

* chat color

* logging

* webstorage

* compile TGUI

* actually like compiles on the DM side

* Update chat-dark.scss

* Update chat-light.scss

* Update resources.txt

* Update tgui-panel.bundle.css

* Colors

* compile

* s

* s

Co-authored-by: Kyle Spier-Swenson <kyleshome@gmail.com>
Co-authored-by: Aleksej Komarov <stylemistake@gmail.com>
Co-authored-by: TheGamerdk <5618080+TheGamerdk@users.noreply.github.com>
Co-authored-by: skoglol <33292112+kriskog@users.noreply.github.com>
Co-authored-by: TheSmallBlue <ilanmori@hotmail.com>

* Fixes Replay Chat

* Update to_chat.dm

* Update chat.dm

* Update demo.dm

* yarn berry

* yarn berry compile

* Update resources.txt

* Update config/resources.txt

* Update resources.txt

* Attempt at fixing reconnect.

* Lets try fix it again

* oops

* THROW THE SINK AT IT

* ree

* Makes Travis work again thank you jamie

* Fixes snowflake images

* Update security.dm

Co-authored-by: Kyle Spier-Swenson <kyleshome@gmail.com>
Co-authored-by: Aleksej Komarov <stylemistake@gmail.com>
Co-authored-by: TheGamerdk <5618080+TheGamerdk@users.noreply.github.com>
Co-authored-by: skoglol <33292112+kriskog@users.noreply.github.com>
Co-authored-by: TheSmallBlue <ilanmori@hotmail.com>
Co-authored-by: alexkar598 <25136265+alexkar598@users.noreply.github.com>

* Fixes

* Undo Kitchen Sink

* Fucking 7 Hours.

* status panel

* stat panel fixes

* fixes

* stat panel stuff

* Stat panel finish

* Compile, oops

* Update server_maint.dm

* Update world.dm

* Update interface.dm

* tgui compile

* Update subsystems.dm

* fix statpanel deleting whole admin tab (#54211)

fix: adminhelping no longer removes entire admin tab
fix: end of round no longer removes entire admin tab

* Update skin.dmf

* verbs?

Co-authored-by: Kyle Spier-Swenson <kyleshome@gmail.com>
Co-authored-by: Aleksej Komarov <stylemistake@gmail.com>
Co-authored-by: skoglol <33292112+kriskog@users.noreply.github.com>
Co-authored-by: TheSmallBlue <ilanmori@hotmail.com>
Co-authored-by: Jamie D <993128+JamieD1@users.noreply.github.com>
Co-authored-by: alexkar598 <25136265+alexkar598@users.noreply.github.com>
Co-authored-by: Couls <coul422@gmail.com>
Co-authored-by: Tad Hardesty <tad@platymuus.com>
Co-authored-by: Bobbahbrown <bobbahbrown@gmail.com>
This commit is contained in:
TheGamerdk
2020-11-10 20:10:27 +01:00
committed by GitHub
parent 7bd21bd36b
commit 65e3fe7465
387 changed files with 19968 additions and 11514 deletions

20
code/__DEFINES/chat.dm Normal file
View File

@@ -0,0 +1,20 @@
/**
* Copyright (c) 2020 Aleksej Komarov
* SPDX-License-Identifier: MIT
*/
#define MESSAGE_TYPE_SYSTEM "system"
#define MESSAGE_TYPE_LOCALCHAT "localchat"
#define MESSAGE_TYPE_RADIO "radio"
#define MESSAGE_TYPE_INFO "info"
#define MESSAGE_TYPE_WARNING "warning"
#define MESSAGE_TYPE_DEADCHAT "deadchat"
#define MESSAGE_TYPE_OOC "ooc"
#define MESSAGE_TYPE_ADMINPM "adminpm"
#define MESSAGE_TYPE_COMBAT "combat"
#define MESSAGE_TYPE_ADMINCHAT "adminchat"
#define MESSAGE_TYPE_EVENTCHAT "eventchat"
#define MESSAGE_TYPE_ADMINLOG "adminlog"
#define MESSAGE_TYPE_ATTACKLOG "attacklog"
#define MESSAGE_TYPE_DEBUG "debug"
#define MESSAGE_TYPE_MENTORPM "mentorpm"

View File

@@ -285,9 +285,15 @@ GLOBAL_LIST_INIT(pda_styles, list(MONO, VT, ORBITRON, SHARE))
#define SHELTER_DEPLOY_ANCHORED_OBJECTS "anchored objects"
//debug printing macros
#define debug_world(msg) if (GLOB.Debug2) to_chat(world, "DEBUG: [msg]")
#define debug_usr(msg) if (GLOB.Debug2&&usr) to_chat(usr, "DEBUG: [msg]")
#define debug_admins(msg) if (GLOB.Debug2) to_chat(GLOB.admins, "DEBUG: [msg]")
#define debug_world(msg) if (GLOB.Debug2) to_chat(world, \
type = MESSAGE_TYPE_DEBUG, \
text = "DEBUG: [msg]")
#define debug_usr(msg) if (GLOB.Debug2&&usr) to_chat(usr, \
type = MESSAGE_TYPE_DEBUG, \
text = "DEBUG: [msg]")
#define debug_admins(msg) if (GLOB.Debug2) to_chat(GLOB.admins, \
type = MESSAGE_TYPE_DEBUG, \
text = "DEBUG: [msg]")
#define debug_world_log(msg) if (GLOB.Debug2) log_world("DEBUG: [msg]")
#define INCREMENT_TALLY(L, stat) if(L[stat]){L[stat]++}else{L[stat] = 1}

View File

@@ -22,3 +22,5 @@
var/category as text
/// Only clients/mobs with `see_invisibility` higher can use the verb.
var/invisibility as num
/// Whether or not the verb appears in statpanel and commandbar when you press space
var/hidden as num

View File

@@ -101,7 +101,6 @@
#define INIT_ORDER_PROFILER 101
#define INIT_ORDER_TITLE 100
#define INIT_ORDER_GARBAGE 99
#define INIT_ORDER_STATPANELS 98
#define INIT_ORDER_DBCORE 95
#define INIT_ORDER_BLACKBOX 94
#define INIT_ORDER_SERVER_MAINT 93
@@ -138,13 +137,13 @@
#define INIT_ORDER_DISCORD -60
#define INIT_ORDER_EXPLOSIONS -69
#define INIT_ORDER_PERSISTENCE -95
#define INIT_ORDER_STATPANELS -98
#define INIT_ORDER_DEMO -99 // To avoid a bunch of changes related to initialization being written, do this last
#define INIT_ORDER_CHAT -100 //Should be last to ensure chat remains smooth during init.
// Subsystem fire priority, from lowest to highest priority
// If the subsystem isn't listed here it's either DEFAULT or PROCESS (if it's a processing subsystem child)
#define FIRE_PRIORITY_PING 10
#define FIRE_PRIORITY_IDLE_NPC 10
#define FIRE_PRIORITY_SERVER_MAINT 10
#define FIRE_PRIORITY_RESEARCH 10

View File

@@ -27,4 +27,11 @@
/// Get a window id based on the provided pool index
#define TGUI_WINDOW_ID(index) "tgui-window-[index]"
/// Get a pool index of the provided window id
#define TGUI_WINDOW_INDEX(window_id) text2num(copytext(window_id, 13))
#define TGUI_WINDOW_INDEX(window_id) text2num(copytext(window_id, 13))
/// Creates a message packet for sending via output()
#define TGUI_CREATE_MESSAGE(type, payload) ( \
url_encode(json_encode(list( \
"type" = type, \
"payload" = payload, \
))))

View File

@@ -195,19 +195,36 @@
/proc/log_mapping(text)
WRITE_LOG(GLOB.world_map_error_log, text)
/* ui logging */
/proc/log_tgui(user_or_client, text)
/**
* Appends a tgui-related log entry. All arguments are optional.
*/
/proc/log_tgui(user, message, context,
datum/tgui_window/window,
datum/src_object)
var/entry = ""
if(!user_or_client)
entry += "no user"
else if(istype(user_or_client, /mob))
var/mob/user = user_or_client
entry += "[user.ckey] (as [user])"
else if(istype(user_or_client, /client))
var/client/client = user_or_client
// Insert user info
if(!user)
entry += "<nobody>"
else if(istype(user, /mob))
var/mob/mob = user
entry += "[mob.ckey] (as [mob] at [mob.x],[mob.y],[mob.z])"
else if(istype(user, /client))
var/client/client = user
entry += "[client.ckey]"
entry += ":\n[text]"
// Insert context
if(context)
entry += " in [context]"
else if(window)
entry += " in [window.id]"
// Resolve src_object
if(!src_object && window && window.locked_by)
src_object = window.locked_by.src_object
// Insert src_object info
if(src_object)
entry += "\nUsing: [src_object.type] [REF(src_object)]"
// Insert message
if(message)
entry += "\n[message]"
WRITE_LOG(GLOB.tgui_log, entry)
/* For logging round startup. */
/proc/start_log(log)

View File

@@ -1,8 +1,3 @@
//Sends resource files to client cache
/client/proc/getFiles(...)
for(var/file in args)
src << browse_rsc(file)
/client/proc/browse_files(root="data/logs/", max_iterations=10, list/valid_extensions=list("txt","log","htm", "html", "json"))
if(IsAdminAdvancedProcCall())
log_admin_private("BROWSEFILES: Admin proc call blocked")

View File

@@ -1098,6 +1098,14 @@ GLOBAL_LIST_INIT(freon_color_matrix, list("#2E5E69", "#60A2A8", "#A1AFB1", rgb(0
/// Save file used in icon2base64. Used for converting icons to base64.
GLOBAL_DATUM_INIT(dummySave, /savefile, new("tmp/dummySave.sav")) //Cache of icons for the browser output
/// Generate a filename for this asset
/// The same asset will always lead to the same asset name
/// (Generated names do not include file extention.)
/proc/generate_asset_name(file)
return "asset.[md5(fcopy_rsc(file))]"
/**
* Converts an icon to base64. Operates by putting the icon in the iconCache savefile,
* exporting it as text, and then parsing the base64 from that.
@@ -1111,7 +1119,7 @@ GLOBAL_DATUM_INIT(dummySave, /savefile, new("tmp/dummySave.sav")) //Cache of ico
var/list/partial = splittext(iconData, "{")
return replacetext(copytext_char(partial[2], 3, -5), "\n", "")
/proc/icon2html(thing, target, icon_state, dir, frame = 1, moving = FALSE)
/proc/icon2html(thing, target, icon_state, dir, frame = 1, moving = FALSE, sourceonly = FALSE)
if (!thing)
return
@@ -1133,10 +1141,12 @@ GLOBAL_DATUM_INIT(dummySave, /savefile, new("tmp/dummySave.sav")) //Cache of ico
if (isfile(thing)) //special snowflake
var/name = sanitize_filename("[generate_asset_name(thing)].png")
if (!SSassets.cache[name])
register_asset(name, thing)
SSassets.transport.register_asset(name, thing)
for (var/thing2 in targets)
send_asset(thing2, key)
return "<img class='icon icon-misc' src=\"[url_encode(name)]\">"
SSassets.transport.send_assets(thing2, name)
if(sourceonly)
return SSassets.transport.get_asset_url(name)
return "<img class='icon icon-misc' src='[SSassets.transport.get_asset_url(name)]'>"
var/atom/A = thing
if (isnull(dir))
dir = A.dir
@@ -1158,11 +1168,12 @@ GLOBAL_DATUM_INIT(dummySave, /savefile, new("tmp/dummySave.sav")) //Cache of ico
key = "[generate_asset_name(I)].png"
if(!SSassets.cache[key])
register_asset(key, I)
SSassets.transport.register_asset(key, I)
for (var/thing2 in targets)
send_asset(thing2, key)
return "<img class='icon icon-[icon_state]' src=\"[url_encode(key)]\">"
SSassets.transport.send_assets(thing2, key)
if(sourceonly)
return SSassets.transport.get_asset_url(key)
return "<img class='icon icon-[icon_state]' src='[SSassets.transport.get_asset_url(key)]'>"
/proc/icon2base64html(thing)
if (!thing)
@@ -1198,7 +1209,7 @@ GLOBAL_DATUM_INIT(dummySave, /savefile, new("tmp/dummySave.sav")) //Cache of ico
return "<img class='icon icon-[A.icon_state]' src='data:image/png;base64,[bicon_cache[key]]'>"
//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
@@ -1206,4 +1217,4 @@ 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)

View File

@@ -332,7 +332,7 @@
if(!previous)
var/list/report_parts = list(personal_report(C), GLOB.common_report)
content = report_parts.Join()
C.verbs -= /client/proc/show_previous_roundend_report
remove_verb(C, /client/proc/show_previous_roundend_report)
fdel(filename)
text2file(content, filename)
else

View File

@@ -595,3 +595,8 @@
return "turf"
else //regex everything else (works for /proc too)
return lowertext(replacetext("[the_type]", "[type2parent(the_type)]/", ""))
/// Return html to load a url.
/// for use inside of browse() calls to html assets that might be loaded on a cdn.
/proc/url2htmlloader(url)
return {"<html><head><meta http-equiv="refresh" content="0;URL='[url]'"/></head><body onLoad="parent.location='[url]'"></body></html>"}

96
code/__HELPERS/verbs.dm Normal file
View File

@@ -0,0 +1,96 @@
/**
* handles adding verbs and updating the stat panel browser
*
* pass the verb type path to this instead of adding it directly to verbs so the statpanel can update
* Arguments:
* * target - Who the verb is being added to, client or mob typepath
* * verb - typepath to a verb, or a list of verbs, supports lists of lists
*/
/proc/add_verb(client/target, verb_or_list_to_add)
if(!target)
CRASH("add_verb called without a target")
if(IsAdminAdvancedProcCall())
return
var/mob/mob_target = null
if(ismob(target))
mob_target = target
target = mob_target.client
else if(!istype(target, /client))
CRASH("add_verb called on a non-mob and non-client")
var/list/verbs_list = list()
if(!islist(verb_or_list_to_add))
verbs_list += verb_or_list_to_add
else
var/list/verb_listref = verb_or_list_to_add
var/list/elements_to_process = verb_listref.Copy()
while(length(elements_to_process))
var/element_or_list = elements_to_process[length(elements_to_process)] //Last element
elements_to_process.len--
if(islist(element_or_list))
elements_to_process += element_or_list //list/a += list/b adds the contents of b into a, not the reference to the list itself
else
verbs_list += element_or_list
if(mob_target)
mob_target.verbs += verbs_list
if(!target)
return //Our work is done.
else
target.verbs += verbs_list
var/list/output_list = list()
for(var/thing in verbs_list)
var/procpath/verb_to_add = thing
output_list[++output_list.len] = list(verb_to_add.category, verb_to_add.name)
output_list = url_encode(json_encode(output_list))
target << output("[output_list];", "statbrowser:add_verb_list")
/**
* handles removing verb and sending it to browser to update, use this for removing verbs
*
* pass the verb type path to this instead of removing it from verbs so the statpanel can update
* Arguments:
* * target - Who the verb is being removed from, client or mob typepath
* * verb - typepath to a verb, or a list of verbs, supports lists of lists
*/
/proc/remove_verb(client/target, verb_or_list_to_remove)
if(IsAdminAdvancedProcCall())
return
var/mob/mob_target = null
if(ismob(target))
mob_target = target
target = mob_target.client
else if(!istype(target, /client))
CRASH("remove_verb called on a non-mob and non-client")
var/list/verbs_list = list()
if(!islist(verb_or_list_to_remove))
verbs_list += verb_or_list_to_remove
else
var/list/verb_listref = verb_or_list_to_remove
var/list/elements_to_process = verb_listref.Copy()
while(length(elements_to_process))
var/element_or_list = elements_to_process[length(elements_to_process)] //Last element
elements_to_process.len--
if(islist(element_or_list))
elements_to_process += element_or_list //list/a += list/b adds the contents of b into a, not the reference to the list itself
else
verbs_list += element_or_list
if(mob_target)
mob_target.verbs -= verbs_list
if(!target)
return //Our work is done.
else
target.verbs -= verbs_list
var/list/output_list = list()
for(var/thing in verbs_list)
var/procpath/verb_to_remove = thing
output_list[++output_list.len] = list(verb_to_remove.category, verb_to_remove.name)
output_list = url_encode(json_encode(output_list))
target << output("[output_list];", "statbrowser:remove_verb_list")

View File

@@ -369,14 +369,14 @@
var/turf/T = get_turf(src)
if(T && user.TurfAdjacent(T))
user.listed_turf = T
user.client.statpanel = T.name
user.client << output("[url_encode(json_encode(T.name))];", "statbrowser:create_listedturf")
// Use this instead of /mob/proc/AltClickOn(atom/A) where you only want turf content listing without additional atom alt-click interaction
/atom/proc/AltClickNoInteract(mob/user, atom/A)
var/turf/T = get_turf(A)
if(T && user.TurfAdjacent(T))
user.listed_turf = T
user.client.statpanel = T.name
user.client << output("[url_encode(json_encode(T.name))];", "statbrowser:create_listedturf")
/mob/proc/TurfAdjacent(turf/T)
return T.Adjacent(src)

View File

@@ -49,6 +49,12 @@
loadmaplist(CONFIG_MAPS_FILE)
LoadMOTD()
LoadPolicy()
if (Master)
Master.OnConfigLoad()
if (Master)
Master.OnConfigLoad()
/datum/controller/configuration/proc/full_wipe()
if(IsAdminAdvancedProcCall())
@@ -180,10 +186,9 @@
var/list/banned_edits = list(NAMEOF(src, entries_by_type), NAMEOF(src, entries), NAMEOF(src, directory))
return !(var_name in banned_edits) && ..()
/datum/controller/configuration/stat_entry()
if(!statclick)
statclick = new/obj/effect/statclick/debug(null, "Edit", src)
stat("[name]:", statclick)
/datum/controller/configuration/stat_entry(msg)
msg = "Edit"
return msg
/datum/controller/configuration/proc/Get(entry_type)
var/datum/config_entry/E = entry_type
@@ -395,3 +400,7 @@ Example config:
continue
runnable_modes[M] = probabilities[M.config_tag]
return runnable_modes
//Message admins when you can.
/datum/controller/configuration/proc/DelayedMessageAdmins(text)
addtimer(CALLBACK(GLOBAL_PROC, /proc/message_admins, text), 0)

View File

@@ -0,0 +1,30 @@
/datum/config_entry/keyed_list/external_rsc_urls
key_mode = KEY_MODE_TEXT
value_mode = VALUE_MODE_FLAG
/datum/config_entry/flag/asset_simple_preload
/datum/config_entry/string/asset_transport
/datum/config_entry/string/asset_transport/ValidateAndSet(str_val)
return (lowertext(str_val) in list("simple", "webroot")) && ..(lowertext(str_val))
/datum/config_entry/string/asset_cdn_webroot
protection = CONFIG_ENTRY_LOCKED
/datum/config_entry/string/asset_cdn_webroot/ValidateAndSet(str_var)
if (!str_var || trim(str_var) == "")
return FALSE
if (str_var && str_var[length(str_var)] != "/")
str_var += "/"
return ..(str_var)
/datum/config_entry/string/asset_cdn_url
protection = CONFIG_ENTRY_LOCKED
default = null
/datum/config_entry/string/asset_cdn_url/ValidateAndSet(str_var)
if (!str_var || trim(str_var) == "")
return FALSE
if (str_var && str_var[length(str_var)] != "/")
str_var += "/"
return ..(str_var)

View File

@@ -16,4 +16,4 @@
/datum/controller/proc/Recover()
/datum/controller/proc/stat_entry()
/datum/controller/proc/stat_entry(msg)

View File

@@ -95,8 +95,6 @@ GLOBAL_REAL(Failsafe, /datum/controller/failsafe)
/datum/controller/failsafe/proc/defcon_pretty()
return defcon
/datum/controller/failsafe/stat_entry()
if(!statclick)
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
stat("Failsafe Controller:", statclick.update("Defcon: [defcon_pretty()] (Interval: [Failsafe.processing_interval] | Iteration: [Failsafe.master_iteration])"))
/datum/controller/failsafe/stat_entry(msg)
msg = "Defcon: [defcon_pretty()] (Interval: [Failsafe.processing_interval] | Iteration: [Failsafe.master_iteration])"
return msg

View File

@@ -25,11 +25,9 @@ GLOBAL_REAL(GLOB, /datum/controller/global_vars)
SHOULD_CALL_PARENT(FALSE)
return QDEL_HINT_IWILLGC
/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/stat_entry(msg)
msg = "Edit"
return msg
/datum/controller/global_vars/vv_edit_var(var_name, var_value)
if(gvars_datum_protected_varlist[var_name])

View File

@@ -603,12 +603,9 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
if (!skip_ticks)
skip_ticks = 1
/datum/controller/master/stat_entry()
if(!statclick)
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
stat("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)]%)")
stat("Master Controller:", statclick.update("(TickRate:[Master.processing]) (Iteration:[Master.iteration]) (TickLimit: [round(Master.current_ticklimit, 0.1)])"))
/datum/controller/master/stat_entry(msg)
msg = "(TickRate:[Master.processing]) (Iteration:[Master.iteration]) (TickLimit: [round(Master.current_ticklimit, 0.1)])"
return msg
/datum/controller/master/StartLoadingMap()
//disallow more than one map to load at once, multithreading it will just cause race conditions
@@ -634,3 +631,8 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
processing = CONFIG_GET(number/mc_tick_rate/base_mc_tick_rate)
else if (client_count > CONFIG_GET(number/mc_tick_rate/high_pop_mc_mode_amount))
processing = CONFIG_GET(number/mc_tick_rate/high_pop_mc_tick_rate)
/datum/controller/master/proc/OnConfigLoad()
for (var/thing in subsystems)
var/datum/controller/subsystem/SS = thing
SS.OnConfigLoad()

View File

@@ -156,6 +156,8 @@
if(SS_SLEEPING)
state = SS_PAUSING
/// Called after the config has been loaded or reloaded.
/datum/controller/subsystem/proc/OnConfigLoad()
//used to initialize the subsystem AFTER the map has loaded
/datum/controller/subsystem/Initialize(start_timeofday)
@@ -166,18 +168,13 @@
log_world(msg)
return time
//hook for printing stats to the "MC" statuspanel for admins to see performance and related stats etc.
/datum/controller/subsystem/proc/stat_entry_legacy()
if(!statclick)
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
var/msg = stat_entry()
var/title = name
if (can_fire)
title = "\[[state_letter()]][title]"
stat(title, statclick.update(msg))
/datum/controller/subsystem/stat_entry(msg)
if(can_fire && !(SS_NO_FIRE & flags))
msg = "[round(cost,1)]ms|[round(tick_usage,1)]%([round(tick_overrun,1)]%)|[round(ticks,0.1)]\t[msg]"
else
msg = "OFFLINE\t[msg]"
return msg
/datum/controller/subsystem/stat_entry(msg)
if(can_fire && !(SS_NO_FIRE & flags))

View File

@@ -7,8 +7,9 @@ SUBSYSTEM_DEF(acid)
var/list/currentrun = list()
var/list/processing = list()
/datum/controller/subsystem/acid/stat_entry()
return ..("P:[processing.len]")
/datum/controller/subsystem/acid/stat_entry(msg)
msg = "P:[length(processing)]"
return ..()
/datum/controller/subsystem/acid/fire(resumed = 0)

View File

@@ -6,12 +6,13 @@ SUBSYSTEM_DEF(adjacent_air)
priority = FIRE_PRIORITY_ATMOS_ADJACENCY
var/list/queue = list()
/datum/controller/subsystem/adjacent_air/stat_entry()
/datum/controller/subsystem/adjacent_air/stat_entry(msg)
#ifdef TESTING
return ..("P:[length(queue)], S:[GLOB.atmos_adjacent_savings[1]], T:[GLOB.atmos_adjacent_savings[2]]")
msg = "P:[length(queue)], S:[GLOB.atmos_adjacent_savings[1]], T:[GLOB.atmos_adjacent_savings[2]]"
#else
return ..("P:[length(queue)]")
msg = "P:[length(queue)]"
#endif
return ..()
/datum/controller/subsystem/adjacent_air/Initialize()
while(length(queue))

View File

@@ -59,7 +59,8 @@ SUBSYSTEM_DEF(air)
msg += "HP:[high_pressure_delta.len]|"
msg += "AS:[active_super_conductivity.len]|"
msg += "AT/MS:[round((cost ? active_turfs.len/cost : 0),0.1)]"
return ..(msg)
return ..()
/datum/controller/subsystem/air/Initialize(timeofday)
extools_update_ssair()

View File

@@ -4,6 +4,23 @@ SUBSYSTEM_DEF(assets)
flags = SS_NO_FIRE
var/list/cache = list()
var/list/preload = list()
var/datum/asset_transport/transport = new()
/datum/controller/subsystem/assets/OnConfigLoad()
var/newtransporttype = /datum/asset_transport
switch (CONFIG_GET(string/asset_transport))
if ("webroot")
newtransporttype = /datum/asset_transport/webroot
if (newtransporttype == transport.type)
return
var/datum/asset_transport/newtransport = new newtransporttype ()
if (newtransport.validate_config())
transport = newtransport
transport.Load()
/datum/controller/subsystem/assets/Initialize(timeofday)
for(var/type in typesof(/datum/asset))
@@ -11,8 +28,6 @@ SUBSYSTEM_DEF(assets)
if (type != initial(A._abstract))
get_asset_datum(type)
preload = cache.Copy() //don't preload assets generated during the round
transport.Initialize(cache)
for(var/client/C in GLOB.clients)
addtimer(CALLBACK(GLOBAL_PROC, .proc/getFilesSlow, C, preload, FALSE), 10)
..()

View File

@@ -9,7 +9,8 @@ SUBSYSTEM_DEF(augury)
var/list/observers_given_action = list()
/datum/controller/subsystem/augury/stat_entry(msg)
return ..("W:[watchers.len]|D:[doombringers.len]")
msg = "W:[watchers.len]|D:[length(doombringers)]"
return ..()
/datum/controller/subsystem/augury/proc/register_doom(atom/A, severity)
doombringers[A] = severity

View File

@@ -1,3 +1,8 @@
/**
* Copyright (c) 2020 Aleksej Komarov
* SPDX-License-Identifier: MIT
*/
SUBSYSTEM_DEF(chat)
name = "Chat"
flags = SS_TICKER
@@ -5,62 +10,32 @@ SUBSYSTEM_DEF(chat)
priority = FIRE_PRIORITY_CHAT
init_order = INIT_ORDER_CHAT
var/list/payload = list()
var/list/payload_by_client = list()
/datum/controller/subsystem/chat/fire()
for(var/i in payload)
var/client/C = i
C << output(payload[C], "browseroutput:output")
payload -= C
for(var/key in payload_by_client)
var/client/client = key
var/payload = payload_by_client[key]
payload_by_client -= key
if(client)
// Send to tgchat
client.tgui_panel?.window.send_message("chat/message", payload)
// Send to old chat
for(var/message in payload)
SEND_TEXT(client, message_to_html(message))
if(MC_TICK_CHECK)
return
/datum/controller/subsystem/chat/proc/queue(target, message, handle_whitespace = TRUE, confidential = FALSE)
if(!target || !message)
return
if(!istext(message))
stack_trace("to_chat called with invalid input type")
return
if(target == world)
target = GLOB.clients
//Some macros remain in the string even after parsing and fuck up the eventual output
message = replacetext(message, "\improper", "")
message = replacetext(message, "\proper", "")
if(handle_whitespace)
message = replacetext(message, "\n", "<br>")
message = replacetext(message, "\t", "[FOURSPACES][FOURSPACES]")
message += "<br>"
/datum/controller/subsystem/chat/proc/queue(target, message, confidential = FALSE)
if(!confidential)
SSdemo.write_chat(target, message)
if(islist(target))
for(var/I in target)
var/client/C = CLIENT_FROM_VAR(I) //Grab us a client if possible
if(!C?.chatOutput || C.chatOutput.broken) //A player who hasn't updated his skin file.
continue
if(!C.chatOutput.loaded) //Client still loading, put their messages in a queue
C.chatOutput.messageQueue += message
continue
payload[C] += url_encode(url_encode(message))
else
var/client/C = CLIENT_FROM_VAR(target) //Grab us a client if possible
if(!C?.chatOutput || C.chatOutput.broken) //A player who hasn't updated his skin file.
return
if(!C.chatOutput.loaded) //Client still loading, put their messages in a queue
C.chatOutput.messageQueue += message
return
payload[C] += url_encode(url_encode(message))
for(var/_target in target)
var/client/client = CLIENT_FROM_VAR(_target)
if(client)
LAZYADD(payload_by_client[client], list(message))
return
var/client/client = CLIENT_FROM_VAR(target)
if(client)
LAZYADD(payload_by_client[client], list(message))

View File

@@ -1,7 +1,7 @@
SUBSYSTEM_DEF(demo)
name = "Demo"
wait = 1
flags = SS_TICKER | SS_BACKGROUND
flags = SS_TICKER | SS_BACKGROUND
init_order = INIT_ORDER_DEMO
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
@@ -57,8 +57,9 @@ SUBSYSTEM_DEF(demo)
target_text = C.ckey
else
return
write_event_line("chat [target_text] [last_chat_message == text ? "=" : json_encode(text)]")
last_chat_message = text
var/json_encoded = json_encode(text)
write_event_line("chat [target_text] [last_chat_message == json_encoded ? "=" : json_encoded]")
last_chat_message = json_encoded
/datum/controller/subsystem/demo/Initialize()
WRITE_LOG_NO_FORMAT(GLOB.demo_log, "demo version 1\n") // increment this if you change the format

View File

@@ -20,7 +20,8 @@ SUBSYSTEM_DEF(disease)
return ..()
/datum/controller/subsystem/disease/stat_entry(msg)
return ..("P:[active_diseases.len]")
msg = "P:[length(active_diseases)]"
return ..()
/datum/controller/subsystem/disease/proc/get_disease_name(id)
var/datum/disease/advance/A = archive_diseases[id]

View File

@@ -100,7 +100,7 @@ SUBSYSTEM_DEF(events)
// REEEEEEEEE
/client/proc/forceEvent()
set name = "Trigger Event"
set category = "Fun"
set category = "Admin.Events"
if(!holder ||!check_rights(R_FUN))
return

View File

@@ -7,8 +7,10 @@ SUBSYSTEM_DEF(fire_burning)
var/list/currentrun = list()
var/list/processing = list()
/datum/controller/subsystem/fire_burning/stat_entry()
return ..("P:[processing.len]")
/datum/controller/subsystem/fire_burning/stat_entry(msg)
msg = "P:[length(processing)]"
return ..()
/datum/controller/subsystem/fire_burning/fire(resumed = 0)
@@ -36,4 +38,3 @@ SUBSYSTEM_DEF(fire_burning)
if (MC_TICK_CHECK)
return

View File

@@ -57,7 +57,8 @@ SUBSYSTEM_DEF(garbage)
msg += "TGR:[round((totalgcs/(totaldels+totalgcs))*100, 0.01)]%"
msg += " P:[pass_counts.Join(",")]"
msg += "|F:[fail_counts.Join(",")]"
return ..(msg)
return ..()
/datum/controller/subsystem/garbage/Shutdown()
//Adds the del() log to the qdel log file

View File

@@ -8,10 +8,11 @@ SUBSYSTEM_DEF(idlenpcpool)
var/list/currentrun = list()
var/static/list/idle_mobs_by_zlevel[][]
/datum/controller/subsystem/idlenpcpool/stat_entry()
/datum/controller/subsystem/idlenpcpool/stat_entry(msg)
var/list/idlelist = GLOB.simple_animals[AI_IDLE]
var/list/zlist = GLOB.simple_animals[AI_Z_OFF]
return ..("IdleNPCS:[idlelist.len]|Z:[zlist.len]")
msg = "IdleNPCS:[length(idlelist)]|Z:[length(zlist)]"
return ..()
/datum/controller/subsystem/idlenpcpool/proc/MaxZChanged()
if (!islist(idle_mobs_by_zlevel))

View File

@@ -8,8 +8,9 @@ SUBSYSTEM_DEF(lighting)
init_order = INIT_ORDER_LIGHTING
flags = SS_TICKER
/datum/controller/subsystem/lighting/stat_entry()
return ..("L:[GLOB.lighting_update_lights.len]|C:[GLOB.lighting_update_corners.len]|O:[GLOB.lighting_update_objects.len]")
/datum/controller/subsystem/lighting/stat_entry(msg)
msg = "L:[GLOB.lighting_update_lights.len]|C:[GLOB.lighting_update_corners.len]|O:[GLOB.lighting_update_objects.len]"
return ..()
/datum/controller/subsystem/lighting/Initialize(timeofday)

View File

@@ -22,8 +22,9 @@ SUBSYSTEM_DEF(machines)
NewPN.add_cable(PC)
propagate_network(PC,PC.powernet)
/datum/controller/subsystem/machines/stat_entry()
return ..("M:[processing.len]|PN:[powernets.len]")
/datum/controller/subsystem/machines/stat_entry(msg)
msg = "M:[length(processing)]|PN:[length(powernets)]"
return ..()
/datum/controller/subsystem/machines/fire(resumed = 0)

View File

@@ -442,7 +442,7 @@ GLOBAL_LIST_EMPTY(the_station_areas)
//Manual loading of away missions.
/client/proc/admin_away()
set name = "Load Away Mission"
set category = "Fun"
set category = "Admin.Fun"
if(!holder ||!check_rights(R_FUN))
return

View File

@@ -9,8 +9,9 @@ SUBSYSTEM_DEF(mobs)
var/static/list/dead_players_by_zlevel[][] = list(list()) // Needs to support zlevel 1 here, MaxZChanged only happens when z2 is created and new_players can login before that.
var/static/list/cubemonkeys = list()
/datum/controller/subsystem/mobs/stat_entry()
return ..("P:[GLOB.mob_living_list.len]")
/datum/controller/subsystem/mobs/stat_entry(msg)
msg = "P:[length(GLOB.mob_living_list)]"
return ..()
/datum/controller/subsystem/mobs/proc/MaxZChanged()
if (!islist(clients_by_zlevel))

View File

@@ -6,9 +6,10 @@ SUBSYSTEM_DEF(npcpool)
var/list/currentrun = list()
/datum/controller/subsystem/npcpool/stat_entry()
/datum/controller/subsystem/npcpool/stat_entry(msg)
var/list/activelist = GLOB.simple_animals[AI_ON]
return ..("NPCS:[activelist.len]")
msg = "NPCS:[length(activelist)]"
return ..()
/datum/controller/subsystem/npcpool/fire(resumed = FALSE)

View File

@@ -22,8 +22,9 @@ SUBSYSTEM_DEF(overlays)
return ..()
/datum/controller/subsystem/overlays/stat_entry()
return ..("Ov:[length(queue)]")
/datum/controller/subsystem/overlays/stat_entry(msg)
msg = "Ov:[length(queue)]"
return ..()
/datum/controller/subsystem/overlays/Shutdown()

View File

@@ -1,33 +0,0 @@
SUBSYSTEM_DEF(ping)
name = "Ping"
priority = FIRE_PRIORITY_PING
wait = 3 SECONDS
flags = SS_NO_INIT
runlevels = RUNLEVEL_LOBBY | RUNLEVEL_SETUP | RUNLEVEL_GAME | RUNLEVEL_POSTGAME
var/list/currentrun = list()
/datum/controller/subsystem/ping/stat_entry()
return ..("P:[GLOB.clients.len]")
/datum/controller/subsystem/ping/fire(resumed = 0)
if (!resumed)
src.currentrun = GLOB.clients.Copy()
//cache for sanic speed (lists are references anyways)
var/list/currentrun = src.currentrun
while (currentrun.len)
var/client/C = currentrun[currentrun.len]
currentrun.len--
if (!C || !C.chatOutput || !C.chatOutput.loaded)
if (MC_TICK_CHECK)
return
continue
// softPang isn't handled anywhere but it'll always reset the opts.lastPang.
C.chatOutput.ehjax_send(data = C.is_afk(29) ? "softPang" : "pang")
if (MC_TICK_CHECK)
return

View File

@@ -10,8 +10,9 @@ SUBSYSTEM_DEF(processing)
var/list/processing = list()
var/list/currentrun = list()
/datum/controller/subsystem/processing/stat_entry()
return ..("[stat_tag]:[processing.len]")
/datum/controller/subsystem/processing/stat_entry(msg)
msg = "[stat_tag]:[length(processing)]"
return ..()
/datum/controller/subsystem/processing/fire(resumed = 0)
if (!resumed)

View File

@@ -12,7 +12,7 @@ SUBSYSTEM_DEF(profiler)
/datum/controller/subsystem/profiler/stat_entry(msg)
msg += "F:[round(fetch_cost,1)]ms"
msg += "|W:[round(write_cost,1)]ms"
..(msg)
return msg
/datum/controller/subsystem/profiler/Initialize()
if(CONFIG_GET(flag/auto_profile))

View File

@@ -82,9 +82,7 @@ SUBSYSTEM_DEF(server_maint)
if(!thing)
continue
var/client/C = thing
var/datum/chatOutput/co = C.chatOutput
if(co)
co.ehjax_send(data = "roundrestart")
C?.tgui_panel?.send_roundrestart()
if(server) //if you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite
C << link("byond://[server]")
var/datum/tgs_version/tgsversion = world.TgsVersion()

View File

@@ -8,8 +8,9 @@ SUBSYSTEM_DEF(spacedrift)
var/list/currentrun = list()
var/list/processing = list()
/datum/controller/subsystem/spacedrift/stat_entry()
return ..("P:[processing.len]")
/datum/controller/subsystem/spacedrift/stat_entry(msg)
msg = "P:[length(processing)]"
return ..()
/datum/controller/subsystem/spacedrift/fire(resumed = 0)
@@ -57,4 +58,3 @@ SUBSYSTEM_DEF(spacedrift)
AM.inertia_last_loc = AM.loc
if (MC_TICK_CHECK)
return

View File

@@ -0,0 +1,168 @@
SUBSYSTEM_DEF(statpanels)
name = "Stat Panels"
wait = 4
init_order = INIT_ORDER_STATPANELS
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
var/list/currentrun = list()
var/encoded_global_data
var/mc_data_encoded
var/list/cached_images = list()
/datum/controller/subsystem/statpanels/fire(resumed = FALSE)
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"]",
"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()]",
"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)]%)"
)
if(SSshuttle.emergency)
var/ETA = SSshuttle.emergency.getModeStr()
if(ETA)
global_data += "[ETA] [SSshuttle.emergency.getTimerStr()]"
encoded_global_data = url_encode(json_encode(global_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--
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
if(!("MC" 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(!length(GLOB.sdql2_queries) && ("SDQL2" in target.panel_tabs))
target << output("", "statbrowser:remove_sdql2")
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
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

View File

@@ -24,13 +24,14 @@ SUBSYSTEM_DEF(tgui)
var/basehtml
/datum/controller/subsystem/tgui/PreInit()
basehtml = file2text('tgui/packages/tgui/public/tgui.html')
basehtml = file2text('tgui/public/tgui.html')
/datum/controller/subsystem/tgui/Shutdown()
close_all_uis()
/datum/controller/subsystem/tgui/stat_entry()
..("P:[open_uis.len]")
/datum/controller/subsystem/tgui/stat_entry(msg)
msg = "P:[length(open_uis)]"
return ..()
/datum/controller/subsystem/tgui/fire(resumed = 0)
if(!resumed)
@@ -81,7 +82,8 @@ SUBSYSTEM_DEF(tgui)
window_found = TRUE
break
if(!window_found)
log_tgui(user, "Error: Pool exhausted")
log_tgui(user, "Error: Pool exhausted",
context = "SStgui/request_pooled_window")
return null
return window
@@ -93,7 +95,7 @@ SUBSYSTEM_DEF(tgui)
* required user mob
*/
/datum/controller/subsystem/tgui/proc/force_close_all_windows(mob/user)
log_tgui(user, "force_close_all_windows")
log_tgui(user, context = "SStgui/force_close_all_windows")
if(user.client)
user.client.tgui_windows = list()
for(var/i in 1 to TGUI_WINDOW_HARD_LIMIT)
@@ -109,7 +111,7 @@ SUBSYSTEM_DEF(tgui)
* required window_id string
*/
/datum/controller/subsystem/tgui/proc/force_close_window(mob/user, window_id)
log_tgui(user, "force_close_window")
log_tgui(user, context = "SStgui/force_close_window")
// Close all tgui datums based on window_id.
for(var/datum/tgui/ui in user.tgui_open_uis)
if(ui.window && ui.window.id == window_id)

View File

@@ -11,8 +11,10 @@ SUBSYSTEM_DEF(throwing)
var/list/currentrun
var/list/processing = list()
/datum/controller/subsystem/throwing/stat_entry()
return ..("P:[processing.len]")
/datum/controller/subsystem/throwing/stat_entry(msg)
msg = "P:[length(processing)]"
return ..()
/datum/controller/subsystem/throwing/fire(resumed = 0)

View File

@@ -392,6 +392,7 @@ SUBSYSTEM_DEF(ticker)
if(living.client)
var/obj/screen/splash/S = new(living.client, TRUE)
S.Fade(TRUE)
living.client.init_verbs()
livings += living
if(livings.len)
addtimer(CALLBACK(src, .proc/release_characters, livings), 30, TIMER_CLIENT_TIME)

View File

@@ -34,7 +34,8 @@ SUBSYSTEM_DEF(timer)
bucket_resolution = world.tick_lag
/datum/controller/subsystem/timer/stat_entry(msg)
return ..("B:[bucket_count] P:[length(second_queue)] H:[length(hashes)] C:[length(clienttime_timers)] S:[length(timer_id_dict)]")
msg = "B:[bucket_count] P:[length(second_queue)] H:[length(hashes)] C:[length(clienttime_timers)] S:[length(timer_id_dict)]"
return ..()
/datum/controller/subsystem/timer/fire(resumed = FALSE)
var/lit = last_invoke_tick

View File

@@ -8,11 +8,11 @@
var/window_options = "can_close=1;can_minimize=1;can_maximize=0;can_resize=1;titlebar=1;" // window option is set using window_id
var/stylesheets[0]
var/scripts[0]
var/title_image
var/head_elements
var/body_elements
var/head_content = ""
var/content = ""
var/static/datum/asset/simple/namespaced/common/common_asset = get_asset_datum(/datum/asset/simple/namespaced/common)
/datum/browser/New(nuser, nwindow_id, ntitle = 0, nwidth = 0, nheight = 0, var/atom/nref = null)
@@ -27,7 +27,6 @@
height = nheight
if (nref)
ref = nref
add_stylesheet("common", 'html/browser/common.css') // this CSS sheet is common to all UIs
/datum/browser/proc/add_head_content(nhead_content)
head_content = nhead_content
@@ -35,9 +34,6 @@
/datum/browser/proc/set_window_options(nwindow_options)
window_options = nwindow_options
/datum/browser/proc/set_title_image(ntitle_image)
//title_image = ntitle_image
/datum/browser/proc/add_stylesheet(name, file)
if (istype(name, /datum/asset/spritesheet))
var/datum/asset/spritesheet/sheet = name
@@ -47,11 +43,11 @@
stylesheets[asset_name] = file
if (!SSassets.cache[asset_name])
register_asset(asset_name, file)
SSassets.transport.register_asset(asset_name, file)
/datum/browser/proc/add_script(name, file)
scripts["[ckey(name)].js"] = file
register_asset("[ckey(name)].js", file)
SSassets.transport.register_asset("[ckey(name)].js", file)
/datum/browser/proc/set_content(ncontent)
content = ncontent
@@ -61,15 +57,13 @@
/datum/browser/proc/get_header()
var/file
head_content += "<link rel='stylesheet' type='text/css' href='[common_asset.get_url_mappings()["common.css"]]'>"
for (file in stylesheets)
head_content += "<link rel='stylesheet' type='text/css' href='[file]'>"
head_content += "<link rel='stylesheet' type='text/css' href='[SSassets.transport.get_asset_url(file)]'>"
for (file in scripts)
head_content += "<script type='text/javascript' src='[file]'></script>"
var/title_attributes = "class='uiTitle'"
if (title_image)
title_attributes = "class='uiTitle icon' style='background-image: url([title_image]);'"
head_content += "<script type='text/javascript' src='[SSassets.transport.get_asset_url(file)]'></script>"
return {"<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
@@ -80,7 +74,7 @@
</head>
<body scroll=auto>
<div class='uiWrapper'>
[title ? "<div class='uiTitleWrapper'><div [title_attributes]><tt>[title]</tt></div></div>" : ""]
[title ? "<div class='uiTitleWrapper'><div class='uiTitle'><tt>[title]</tt></div></div>" : ""]
<div class='uiContent'>
"}
//" This is here because else the rest of the file looks like a string in notepad++.
@@ -106,10 +100,11 @@
var/window_size = ""
if (width && height)
window_size = "size=[width]x[height];"
common_asset.send(user)
if (stylesheets.len)
send_asset_list(user, stylesheets)
SSassets.transport.send_assets(user, stylesheets)
if (scripts.len)
send_asset_list(user, scripts)
SSassets.transport.send_assets(user, scripts)
user << browse(get_content(), "window=[window_id];[window_size][window_options]")
if (use_onclose)
setup_onclose()
@@ -416,12 +411,6 @@
if (A.selectedbutton)
return list("button" = A.selectedbutton, "settings" = A.settings)
// This will allow you to show an icon in the browse window
// This is added to mob so that it can be used without a reference to the browser object
// There is probably a better place for this...
/mob/proc/browse_rsc_icon(icon, icon_state, dir = -1)
// Registers the on-close verb for a browse window (client/verb/.windowclose)
// this will be called when the close-button of a window is pressed.
//
@@ -453,7 +442,7 @@
// otherwise, just reset the client mob's machine var.
//
/client/verb/windowclose(atomref as text)
set hidden = 1 // hide this verb from the user's panel
set hidden = TRUE // hide this verb from the user's panel
set name = ".windowclose" // no autocomplete on cmd line
if(atomref!="null") // if passed a real atomref

View File

@@ -160,7 +160,7 @@
else if(make_temporary)
base = H.mind.default_martial_art
if(help_verb)
H.verbs += help_verb
add_verb(H, help_verb)
H.mind.martial_art = src
return TRUE
@@ -197,5 +197,5 @@
*/
/datum/martial_art/proc/on_remove(mob/living/carbon/human/H)
if(help_verb)
H.verbs -= help_verb
remove_verb(H, help_verb)
return

View File

@@ -141,6 +141,8 @@
RegisterSignal(new_character, COMSIG_MOB_SAY, .proc/handle_speech)
if(active || force_key_move)
new_character.key = key //now transfer the key to link the client to our new body
if(new_character.client)
new_character.client.init_verbs() // re-initialize character specific verbs
current.update_atom_languages()
/datum/mind/proc/set_death_time()
@@ -680,6 +682,7 @@
if(istype(S, spell))
spell_list -= S
qdel(S)
current?.client << output(null, "statbrowser:check_spells")
/datum/mind/proc/RemoveAllSpells()
for(var/obj/effect/proc_holder/S in spell_list)

View File

@@ -39,7 +39,7 @@
new_ai = select_active_ai(R)
R.notify_ai(DISCONNECT)
if(new_ai && (new_ai != R.connected_ai))
R.connected_ai = new_ai
R.set_connected_ai(new_ai)
if(R.shell)
R.undeploy() //If this borg is an AI shell, disconnect the controlling AI and assign ti to a new AI
R.notify_ai(AI_SHELL)
@@ -68,7 +68,7 @@
R.notify_ai(DISCONNECT)
if(R.shell)
R.undeploy()
R.connected_ai = null
R.set_connected_ai(null)
if(WIRE_LAWSYNC) // Cut the law wire, and the borg will no longer receive law updates from its AI. Repair and it will re-sync.
if(mend)
if(!R.emagged)

View File

@@ -1174,5 +1174,25 @@
for(var/x in materials)
var/datum/material/custom_material = x
custom_material.on_applied(src, materials[custom_material] * multiplier, material_flags)
custom_materials[custom_material] += materials[x] * multiplier
///Passes Stat Browser Panel clicks to the game and calls client click on an atom
/atom/Topic(href, list/href_list)
. = ..()
if(!usr?.client)
return
var/client/usr_client = usr.client
var/list/paramslist = list()
if(href_list["statpanel_item_shiftclick"])
paramslist["shift"] = "1"
if(href_list["statpanel_item_ctrlclick"])
paramslist["ctrl"] = "1"
if(href_list["statpanel_item_altclick"])
paramslist["alt"] = "1"
if(href_list["statpanel_item_click"])
// first of all make sure we valid
var/mouseparams = list2params(paramslist)
usr_client.Click(src, loc, null, mouseparams)
return TRUE

View File

@@ -59,7 +59,7 @@
/mob/living/silicon/ai/verb/ai_camera_track(target_name in trackable_mobs())
set name = "track"
set hidden = 1 //Don't display it on the verb lists. This verb exists purely so you can type "track Oldman Robustin" and follow his ass
set hidden = TRUE //Don't display it on the verb lists. This verb exists purely so you can type "track Oldman Robustin" and follow his ass
if(!target_name)
return

View File

@@ -181,7 +181,6 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list(
dat += "</b></center>"
var/datum/browser/popup = new(user, "arcade", "Space Villain 2000")
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
popup.open()
/obj/machinery/computer/arcade/battle/Topic(href, href_list)
@@ -499,7 +498,6 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list(
dat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];close=1'>Close</a></P>"
var/datum/browser/popup = new(user, "arcade", "The Orion Trail",400,700)
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
popup.open()
return

View File

@@ -323,7 +323,6 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
dat = list("<tt>", header.Join(), body, "<hr><br></tt>")
var/datum/browser/popup = new(user, "id_com", src.name, 900, 620)
popup.set_content(dat.Join())
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
/obj/machinery/computer/card/Topic(href, href_list)

View File

@@ -315,7 +315,6 @@
var/datum/browser/popup = new(user, "cloning", "Cloning System Control")
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
popup.open()
/obj/machinery/computer/cloning/Topic(href, href_list)

View File

@@ -442,7 +442,6 @@
var/datum/browser/popup = new(user, "communications", "Communications Console", 400, 500)
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
if(issilicon(user))
var/dat2 = interact_ai(user) // give the AI a different interact proc to limit its access

View File

@@ -106,6 +106,7 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new)
.["miny"] = M.miny
.["maxx"] = M.maxx
.["maxy"] = M.maxy
.["map_filename"] = SSassets.transport.get_asset_url("minimap-1.png")
/datum/crewmonitor/proc/update_data(z)
if(data_by_z["[z]"] && last_update["[z]"] && world.time <= last_update["[z]"] + SENSORS_UPDATE_PERIOD)

View File

@@ -247,6 +247,10 @@
if(!ui)
ui = new(user, src, "DnaConsole")
ui.open()
/obj/machinery/computer/scan_consolenew/ui_assets()
. = ..() || list()
. += get_asset_datum(/datum/asset/simple/genetics)
/obj/machinery/computer/scan_consolenew/ui_data(mob/user)
var/list/data = list()

View File

@@ -188,7 +188,6 @@
dat += "<A href='?src=[REF(src)];login=1'>{Log In}</A>"
var/datum/browser/popup = new(user, "med_rec", "Medical Records Console", 600, 400)
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
/obj/machinery/computer/med_data/Topic(href, href_list)

View File

@@ -67,7 +67,6 @@
add_fingerprint(usr)
var/datum/browser/popup = new(user, "computer", title, 400, 500)
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
popup.open()
/obj/machinery/computer/pod/process()

View File

@@ -64,7 +64,6 @@
dat += "<HR><A href='?src=[REF(src)];lock=1'>Lock Console</A>"
var/datum/browser/popup = new(user, "computer", "Prisoner Management Console", 400, 500)
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
return

View File

@@ -82,10 +82,10 @@
var/md5 = md5(fcopy_rsc(picture))
if(!SSassets.cache["photo_[md5]_cropped.png"])
register_asset("photo_[md5]_cropped.png", picture)
send_asset_list(user, list("photo_[md5]_cropped.png" = picture))
SSassets.transport.register_asset("photo_[md5]_cropped.png", picture)
SSassets.transport.send_assets(user, list("photo_[md5]_cropped.png" = picture))
data["user_image"] = md5
data["user_image"] = SSassets.transport.get_asset_url("photo_[md5]_cropped.png")
data["has_access"] = check_access(user.get_idcard())
@@ -154,16 +154,19 @@
if(istype(active_general_record.fields["photo_front"], /obj/item/photo))
var/obj/item/photo/P1 = active_general_record.fields["photo_front"]
if(!SSassets.cache["photo_front_[active_general_record.fields["id"]].png"])
register_asset("photo_front_[active_general_record.fields["id"]].png", P1.picture.picture_image)
SSassets.transport.register_asset("photo_front_[active_general_record.fields["id"]].png", P1.picture.picture_image)
assets["photo_front_[active_general_record.fields["id"]].png"] = P1.picture.picture_image
if(istype(active_general_record.fields["photo_side"], /obj/item/photo))
var/obj/item/photo/P2 = active_general_record.fields["photo_side"]
if(!SSassets.cache["photo_side_[active_general_record.fields["id"]].png"])
register_asset("photo_side_[active_general_record.fields["id"]].png", P2.picture.picture_image)
SSassets.transport.register_asset("photo_side_[active_general_record.fields["id"]].png", P2.picture.picture_image)
assets["photo_side_[active_general_record.fields["id"]].png"] = P2.picture.picture_image
send_asset_list(user, assets)
SSassets.transport.send_assets(user, assets)
record["front_image"] = SSassets.transport.get_asset_url("photo_front_[active_general_record.fields["id"]].png")
record["side_image"] = SSassets.transport.get_asset_url("photo_side_[active_general_record.fields["id"]].png")
record["name"] = active_general_record.fields["name"]

View File

@@ -106,7 +106,6 @@
var/datum/browser/popup = new(user, "warrant", "Security Warrant Console", 600, 400)
popup.set_content(dat.Join())
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
/obj/machinery/computer/warrant/Topic(href, href_list)

View File

@@ -254,7 +254,6 @@
/obj/machinery/doorButtons/airlock_controller/ui_interact(mob/user)
var/datum/browser/popup = new(user, "computer", name)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.set_content(returnText())
popup.open()

View File

@@ -29,7 +29,6 @@
. = ..()
user.set_machine(src)
var/datum/browser/popup = new(user, "computer", name) // Set up the popup browser window
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.set_content(return_text())
popup.open()

View File

@@ -216,7 +216,6 @@
var/datum/browser/popup = new(user, "cloning", "Prototype Cloning System Control")
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
/obj/machinery/computer/prototype_cloning/Topic(href, href_list)

View File

@@ -491,7 +491,6 @@ GLOBAL_LIST_EMPTY(allCasters)
dat+="<A href='?src=[REF(src)];setScreen=[0]'>Return</A>"
var/datum/browser/popup = new(human_or_robot_user, "newscaster_main", "Newscaster Unit #[unit_no]", 400, 600)
popup.set_content(dat)
popup.set_title_image(human_or_robot_user.browse_rsc_icon(icon, icon_state))
popup.open()
/obj/machinery/newscaster/Topic(href, href_list)

View File

@@ -904,7 +904,6 @@
var/datum/browser/popup = new(user, "turretid", "Turret Control Panel ([get_area_name(src, TRUE)])")
popup.set_content(t)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
/obj/machinery/turretid/Topic(href, href_list)

View File

@@ -211,7 +211,6 @@ GLOBAL_LIST_EMPTY(req_console_ckey_departments)
CRASH("No UI for src. Screen var is: [screen]")
var/datum/browser/popup = new(user, "req_console", "[department] Requests Console", 450, 440)
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
return

View File

@@ -159,7 +159,6 @@
var/datum/browser/popup = new(user, "slotmachine", "Slot Machine")
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
popup.open()
/obj/machinery/computer/slot_machine/Topic(href, href_list)

View File

@@ -239,7 +239,6 @@
message = defaultmsg
var/datum/browser/popup = new(user, "hologram_console", name, 700, 700)
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
popup.open()
/obj/machinery/computer/message_monitor/proc/BruteForce(mob/user)

View File

@@ -97,7 +97,7 @@
// So he can't jump out the gate right away.
R.SetLockdown()
if(masterAI)
R.connected_ai = masterAI
R.set_connected_ai(masterAI)
R.lawsync()
R.lawupdate = 1
addtimer(CALLBACK(src, .proc/unlock_new_robot, R), 50)

View File

@@ -225,7 +225,6 @@ RLD
var/datum/browser/popup = new(user, "rcd_access", "Access Control", 900, 500)
popup.set_content(t1)
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
popup.open()
onclose(user, "rcd_access")

View File

@@ -793,9 +793,7 @@
ADD_TRAIT(G, TRAIT_HOLY, SPECIES_TRAIT)
log_game("[key_name(H)] has summoned [key_name(G)], a holoparasite, with a holy tarot deck.")
to_chat(H, "<span class='holoparasite'><font color=\"[G.namedatum.colour]\"><b>[G.real_name]</b></font> has been summoned!</span>")
H.verbs += /mob/living/proc/guardian_comm
H.verbs += /mob/living/proc/guardian_recall
H.verbs += /mob/living/proc/guardian_reset
add_verb(H, list(/mob/living/proc/guardian_comm, /mob/living/proc/guardian_recall, /mob/living/proc/guardian_reset))
force = 0
throwforce = 0
to_chat(H, "<span class='warning'>The [src]'s rigid ends become dull from summoning <font color=\"[G.namedatum.colour]\"><b>[G.real_name]</b></font>!</span>")

View File

@@ -288,12 +288,12 @@
O.custom_name = created_name
O.locked = panel_locked
if(!aisync)
lawsync = 0
O.connected_ai = null
lawsync = FALSE
O.set_connected_ai(null)
else
O.notify_ai(NEW_BORG)
if(forced_ai)
O.connected_ai = forced_ai
O.set_connected_ai(forced_ai)
if(!lawsync)
O.lawupdate = 0
if(M.laws.id == DEFAULT_AI_LAWID)
@@ -348,10 +348,10 @@
if(!aisync)
lawsync = FALSE
O.connected_ai = null
O.set_connected_ai(null)
else
if(forced_ai)
O.connected_ai = forced_ai
O.set_connected_ai(forced_ai)
O.notify_ai(AI_SHELL)
if(!lawsync)
O.lawupdate = FALSE
@@ -387,7 +387,8 @@
popup.open()
/obj/item/robot_suit/Topic(href, href_list)
if(usr.incapacitated() || !Adjacent(usr))
. = ..()
if(. || usr.incapacitated() || !Adjacent(usr)) // atom/topic only returns true if clicked
return
var/mob/living/living_user = usr

View File

@@ -97,8 +97,8 @@
/mob/proc/stop_sound_channel(chan)
SEND_SOUND(src, sound(null, repeat = 0, wait = 0, channel = chan))
if(chan == CHANNEL_LOBBYMUSIC) //yogs start
if(client && client.chatOutput)
client.chatOutput.stopLobbyMusic() //yogs end
if(client && client.tgui_panel)
client.tgui_panel?.stop_music() //yogs end
/mob/proc/set_sound_channel_volume(channel, volume)
var/sound/S = sound(null, FALSE, FALSE, channel, volume)
@@ -108,10 +108,10 @@
/client/proc/playtitlemusic(vol = 85)
set waitfor = FALSE
UNTIL(SSticker.login_music) //wait for SSticker init to set the login music
UNTIL(chatOutput.loaded)
UNTIL(tgui_panel)
if(prefs && (prefs.toggles & SOUND_LOBBY))
chatOutput.sendLobbyMusic(SSticker.login_music)
tgui_panel?.play_music(SSticker.login_music)
to_chat(src, "<span class='notice'>Currently playing: </span>[SSticker.selected_lobby_music]")
/proc/get_rand_frequency()

View File

@@ -33,8 +33,6 @@ GLOBAL_VAR(restart_counter)
log_world("World loaded at [time_stamp()]!")
SetupExternalRSC()
GLOB.config_error_log = GLOB.world_manifest_log = GLOB.world_pda_log = GLOB.world_job_debug_log = GLOB.sql_error_log = GLOB.world_href_log = GLOB.world_runtime_log = GLOB.world_attack_log = GLOB.world_game_log = "data/logs/config_error.[GUID()].log" //temporary file used to record errors with loading config, moved to log directory once logging is set bl
make_datum_references_lists() //initialises global lists for referencing frequently used datums (so that we only ever do it once)
@@ -96,16 +94,6 @@ GLOBAL_VAR(restart_counter)
#endif
SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, /proc/addtimer, cb, 10 SECONDS))
/world/proc/SetupExternalRSC()
#if (PRELOAD_RSC == 0)
GLOB.external_rsc_urls = world.file2list("[global.config.directory]/external_rsc_urls.txt","\n")
var/i=1
while(i<=GLOB.external_rsc_urls.len)
if(GLOB.external_rsc_urls[i])
i++
else
GLOB.external_rsc_urls.Cut(i,i+1)
#endif
/world/proc/SetupLogs()
var/override_dir = params[OVERRIDE_LOG_DIRECTORY_PARAMETER]
@@ -249,6 +237,7 @@ GLOBAL_VAR(restart_counter)
var/client/C = boi
if(!istype(C)) continue //yes so this is useful to prevent nulls from preventing the server from rebooting...
sync_logout_with_db(C.connection_number)
C?.tgui_panel?.send_roundrestart()
TgsReboot()

View File

@@ -2,17 +2,23 @@
////////////////////////////////
/proc/message_admins(msg)
msg = "<span class=\"admin\"><span class=\"prefix\">ADMIN LOG:</span> <span class=\"message linkify\">[msg]</span></span>"
to_chat(GLOB.admins, msg, confidential=TRUE)
to_chat(GLOB.admins,
type = MESSAGE_TYPE_ADMINLOG,
html = msg,
confidential = TRUE)
/proc/relay_msg_admins(msg)
msg = "<span class=\"admin\"><span class=\"prefix\">RELAY:</span> <span class=\"message linkify\">[msg]</span></span>"
to_chat(GLOB.admins, msg, confidential=TRUE)
to_chat(GLOB.admins,
type = MESSAGE_TYPE_ADMINLOG,
html = msg,
confidential = TRUE)
///////////////////////////////////////////////////////////////////////////////////////////////Panels
/datum/admins/proc/show_player_panel(mob/M in GLOB.mob_list)
set category = "Admin"
set category = "Admin.Game"
set name = "Show Player Panel"
set desc="Edit player (respawn, ban, heal, etc)"
@@ -210,7 +216,7 @@
/datum/admins/proc/access_news_network() //MARKER
set category = "Fun"
set category = "Admin.Fun"
set name = "Access Newscaster Network"
set desc = "Allows you to view, add and edit news feeds."
@@ -754,9 +760,9 @@
log_admin("[key_name(usr)] spawned cargo pack [chosen] at [AREACOORD(usr)]")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Spawn Cargo") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/show_traitor_panel(mob/M in GLOB.mob_list)
set category = "Admin"
set category = "Admin.Game"
set desc = "Edit mobs's memory and role"
set name = "Show Traitor Panel"

View File

@@ -6,7 +6,7 @@
/client/proc/investigate_show()
set name = "Investigate"
set category = "Admin"
set category = "Admin.Game"
if(!holder)
return

View File

@@ -19,8 +19,8 @@ GLOBAL_PROTECT(admin_verbs_default)
/client/proc/cmd_admin_pm_context, /*right-click adminPM interface*/
/client/proc/cmd_admin_pm_panel, /*admin-pm list*/
/client/proc/stop_sounds,
/client/proc/toggle_legacy_mc_tab,
/client/proc/fix_air // yogs - fix air verb
/client/proc/fix_air, // yogs - fix air verb
/client/proc/debugstatpanel
)
GLOBAL_LIST_INIT(admin_verbs_admin, world.AVerbsAdmin())
GLOBAL_PROTECT(admin_verbs_admin)
@@ -150,7 +150,8 @@ GLOBAL_PROTECT(admin_verbs_server)
/client/proc/toggle_hub,
/client/proc/mentor_memo, // YOGS - something stupid about "Mentor memos"
///client/proc/dump_memory_usage,
/client/proc/release_queue // Yogs -- Adds some queue-manipulation verbs
/client/proc/release_queue, // Yogs -- Adds some queue-manipulation verbs
/client/proc/toggle_cdn
)
GLOBAL_LIST_INIT(admin_verbs_debug, world.AVerbsDebug())
GLOBAL_PROTECT(admin_verbs_debug)
@@ -191,7 +192,8 @@ GLOBAL_PROTECT(admin_verbs_debug)
/client/proc/cmd_display_overlay_log,
/client/proc/reload_configuration,
/datum/admins/proc/create_or_modify_area,
/client/proc/debug_typeof // Yogs -- Adds a debug verb for getting the subtypes of something
/client/proc/debug_typeof, // Yogs -- Adds a debug verb for getting the subtypes of something
/client/proc/toggle_cdn
)
GLOBAL_LIST_INIT(admin_verbs_possess, list(/proc/possess, /proc/release))
GLOBAL_PROTECT(admin_verbs_possess)
@@ -275,37 +277,37 @@ GLOBAL_PROTECT(admin_verbs_hideable)
control_freak = CONTROL_FREAK_SKIN | CONTROL_FREAK_MACROS
var/rights = holder.rank.rights
verbs += GLOB.admin_verbs_default
verbs += GLOB.mentor_verbs // yogs - give admins mentor verbs
add_verb(src, GLOB.admin_verbs_default)
add_verb(src, GLOB.mentor_verbs) // yogs - give admins mentor verbs
if(rights & R_BUILDMODE)
verbs += /client/proc/togglebuildmodeself
add_verb(src, /client/proc/togglebuildmodeself)
if(rights & R_ADMIN)
verbs += GLOB.admin_verbs_admin
add_verb(src, GLOB.admin_verbs_admin)
if(rights & R_BAN)
verbs += GLOB.admin_verbs_ban
add_verb(src, GLOB.admin_verbs_ban)
if(rights & R_FUN)
verbs += GLOB.admin_verbs_fun
add_verb(src, GLOB.admin_verbs_fun)
if(rights & R_SERVER)
verbs += GLOB.admin_verbs_server
add_verb(src, GLOB.admin_verbs_server)
if(rights & R_DEBUG)
verbs += GLOB.admin_verbs_debug
add_verb(src, GLOB.admin_verbs_debug)
if(rights & R_POSSESS)
verbs += GLOB.admin_verbs_possess
add_verb(src, GLOB.admin_verbs_possess)
if(rights & R_PERMISSIONS)
verbs += GLOB.admin_verbs_permissions
add_verb(src, GLOB.admin_verbs_permissions)
if(rights & R_STEALTH)
verbs += /client/proc/stealth
add_verb(src, /client/proc/stealth)
if(rights & R_ADMIN)
verbs += GLOB.admin_verbs_poll
add_verb(src, GLOB.admin_verbs_poll)
if(rights & R_SOUNDS)
verbs += GLOB.admin_verbs_sounds
add_verb(src, GLOB.admin_verbs_sounds)
if(CONFIG_GET(string/invoke_youtubedl))
verbs += /client/proc/play_web_sound
add_verb(src, /client/proc/play_web_sound)
if(rights & R_SPAWN)
verbs += GLOB.admin_verbs_spawn
add_verb(src, GLOB.admin_verbs_spawn)
/client/proc/remove_admin_verbs()
verbs.Remove(
remove_verb(src, list(
GLOB.admin_verbs_default,
/client/proc/togglebuildmodeself,
GLOB.admin_verbs_admin,
@@ -324,14 +326,14 @@ GLOBAL_PROTECT(admin_verbs_hideable)
GLOB.admin_verbs_debug_mapping,
/client/proc/disable_debug_verbs,
/client/proc/readmin
)
))
/client/proc/hide_most_verbs()//Allows you to keep some functionality while hiding some verbs
set name = "Adminverbs - Hide Most"
set category = "Admin"
verbs.Remove(/client/proc/hide_most_verbs, GLOB.admin_verbs_hideable)
verbs += /client/proc/show_verbs
add_verb(src, /client/proc/show_verbs)
to_chat(src, "<span class='interface'>Most of your adminverbs have been hidden.</span>", confidential=TRUE)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Hide Most Adminverbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -342,7 +344,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
set category = "Admin"
remove_admin_verbs()
verbs += /client/proc/show_verbs
add_verb(src, /client/proc/show_verbs)
to_chat(src, "<span class='interface'>Almost all of your adminverbs have been hidden.</span>", confidential=TRUE)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Hide All Adminverbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -352,7 +354,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
set name = "Adminverbs - Show"
set category = "Admin"
verbs -= /client/proc/show_verbs
remove_verb(src, /client/proc/show_verbs)
add_admin_verbs()
to_chat(src, "<span class='interface'>All of your adminverbs are now visible.</span>", confidential=TRUE)
@@ -362,7 +364,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
/client/proc/admin_ghost()
set category = "Admin"
set category = "Admin.Game"
set name = "Aghost"
if(!holder)
return
@@ -387,13 +389,14 @@ GLOBAL_PROTECT(admin_verbs_hideable)
message_admins("[key_name_admin(usr)] admin ghosted.")
var/mob/body = mob
body.ghostize(1)
init_verbs()
if(body && !body.key)
body.key = "@[key]" //Haaaaaaaack. But the people have spoken. If it breaks; blame adminbus
SSblackbox.record_feedback("tally", "admin_verb", 1, "Admin Ghost") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/invisimin()
set name = "Invisimin"
set category = "Admin"
set category = "Admin.Game"
set desc = "Toggles ghost-like invisibility (Don't abuse this)"
if(holder && mob)
if(mob.invisibility == INVISIBILITY_MAXIMUM)
@@ -405,7 +408,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
/client/proc/check_antagonists()
set name = "Check Antagonists"
set category = "Admin"
set category = "Admin.Game"
if(holder)
// yogs start
log_admin("[key_name(usr)] checked antagonists.") //for tsar~
@@ -459,14 +462,14 @@ GLOBAL_PROTECT(admin_verbs_hideable)
/client/proc/game_panel()
set name = "Game Panel"
set category = "Admin"
set category = "Admin.Game"
if(holder)
holder.Game()
SSblackbox.record_feedback("tally", "admin_verb", 1, "Game Panel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/secrets()
set name = "Secrets"
set category = "Admin"
set category = "Admin.Game"
if (holder)
holder.Secrets()
SSblackbox.record_feedback("tally", "admin_verb", 1, "Secrets Panel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -518,7 +521,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Stealth Mode") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/drop_bomb()
set category = "Special Verbs"
set category = "Admin.Fun"
set name = "Drop Bomb"
set desc = "Cause an explosion of varying strength at your location."
@@ -560,7 +563,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Drop Bomb") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/drop_dynex_bomb()
set category = "Special Verbs"
set category = "Admin.Fun"
set name = "Drop DynEx Bomb"
set desc = "Cause an explosion of varying strength at your location."
@@ -607,7 +610,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
message_admins("[key_name_admin(usr)] has modified Dynamic Explosion Scale: [ex_scale]")
/client/proc/give_spell(mob/T in GLOB.mob_list)
set category = "Fun"
set category = "Admin.Fun"
set name = "Give Spell"
set desc = "Gives a spell to a mob."
@@ -631,7 +634,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
message_admins("<span class='danger'>Spells given to mindless mobs will not be transferred in mindswap or cloning!</span>")
/client/proc/remove_spell(mob/T in GLOB.mob_list)
set category = "Fun"
set category = "Admin.Fun"
set name = "Remove Spell"
set desc = "Remove a spell from the selected mob."
@@ -644,7 +647,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Remove Spell") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/give_disease(mob/living/T in GLOB.mob_living_list)
set category = "Fun"
set category = "Admin.Fun"
set name = "Give Disease"
set desc = "Gives a Disease to a mob."
if(!istype(T))
@@ -659,7 +662,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
message_admins("<span class='adminnotice'>[key_name_admin(usr)] gave [key_name_admin(T)] the disease [D].</span>")
/client/proc/object_say(obj/O in world)
set category = "Special Verbs"
set category = "Admin.Fun"
set name = "OSay"
set desc = "Makes an object say something."
var/message = input(usr, "What do you want the message to be?", "Make Sound") as text | null
@@ -671,7 +674,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Object Say") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/togglebuildmodeself()
set name = "Toggle Build Mode Self"
set category = "Special Verbs"
set category = "Admin.Fun"
if (!(holder.rank.rights & R_BUILDMODE))
return
if(src.mob)
@@ -680,7 +683,8 @@ GLOBAL_PROTECT(admin_verbs_hideable)
/client/proc/check_ai_laws()
set name = "Check AI Laws"
set category = "Admin"
set category = "Admin.Game"
if(holder)
src.holder.output_ai_laws()
@@ -703,15 +707,6 @@ GLOBAL_PROTECT(admin_verbs_hideable)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Deadmin")
/client/proc/toggle_legacy_mc_tab()
set name = "Toggle Legacy MC Tab"
set category = "Debug"
set desc = "For if the normal one breaks"
if(!holder)
return
holder.legacy_mc = !holder.legacy_mc
/client/proc/readmin()
set name = "Readmin"
@@ -774,7 +769,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
/client/proc/toggle_AI_interact()
set name = "Toggle Admin AI Interact"
set category = "Admin"
set category = "Admin.Game"
set desc = "Allows you to interact with most machines as an AI would as a ghost"
AI_Interact = !AI_Interact
@@ -810,3 +805,10 @@ GLOBAL_PROTECT(admin_verbs_hideable)
to_chat(usr, "<span class='warning'>File creation failed. Please check to see if the data/logs/memory folder actually exists.</span>")
else
to_chat(usr, "<span class='notice'>Memory dump completed.</span>")*/
/client/proc/debugstatpanel()
set name = "Debug Stat Panel"
set category = "Debug"
src << output("", "statbrowser:create_debug")

View File

@@ -5,7 +5,7 @@
/datum/verbs/menu/Admin/verb/playerpanel()
set name = "Player Panel"
set desc = "Player Panel"
set category = "Admin"
set category = "Admin.Game"
if(usr.client.holder)
usr.client.holder.player_panel_new()
SSblackbox.record_feedback("tally", "admin_verb", 1, "Player Panel New") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!

View File

@@ -28,7 +28,6 @@ GLOBAL_PROTECT(href_token)
var/deadmined
var/legacy_mc = FALSE
/datum/admins/New(datum/admin_rank/R, ckey, force_active = FALSE, protected)
if(IsAdminAdvancedProcCall())
@@ -93,7 +92,7 @@ GLOBAL_PROTECT(href_token)
var/client/C
if ((C = owner) || (C = GLOB.directory[target]))
disassociate()
C.verbs += /client/proc/readmin
add_verb(C, /client/proc/readmin)
/datum/admins/proc/associate(client/C)
if(IsAdminAdvancedProcCall())
@@ -113,7 +112,8 @@ GLOBAL_PROTECT(href_token)
owner = C
owner.holder = src
owner.add_admin_verbs() //TODO <--- todo what? the proc clearly exists and works since its the backbone to our entire admin system
owner.verbs -= /client/proc/readmin
remove_verb(owner, /client/proc/readmin)
owner.init_verbs() //re-initialize the verb list
GLOB.admins |= C
/datum/admins/proc/disassociate()
@@ -125,6 +125,7 @@ GLOBAL_PROTECT(href_token)
if(owner)
GLOB.admins -= owner
owner.remove_admin_verbs()
owner.init_verbs()
owner.holder = null
owner = null

View File

@@ -134,8 +134,3 @@
/proc/log_ipintel(text)
log_game("IPINTEL: [text]")
debug_admins("IPINTEL: [text]")

View File

@@ -9,7 +9,9 @@
/datum/admins/proc/edit_admin_permissions(action, target, operation, page)
if(!check_rights(R_PERMISSIONS))
return
var/list/output = list("<link rel='stylesheet' type='text/css' href='panels.css'><a href='?_src_=holder;[HrefToken()];editrightsbrowser=1'>\[Permissions\]</a>")
var/datum/asset/asset_cache_datum = get_asset_datum(/datum/asset/group/permissions)
asset_cache_datum.send(usr)
var/list/output = list("<link rel='stylesheet' type='text/css' href='[SSassets.transport.get_asset_url("panels.css")]'><a href='?_src_=holder;[HrefToken()];editrightsbrowser=1'>\[Permissions\]</a>")
if(action)
output += " | <a href='?_src_=holder;[HrefToken()];editrightsbrowserlog=1;editrightspage=0'>\[Log\]</a> | <a href='?_src_=holder;[HrefToken()];editrightsbrowsermanage=1'>\[Management\]</a><hr style='background:#000000; border:0; height:3px'>"
else
@@ -91,7 +93,7 @@
output += {"<head>
<meta charset='UTF-8'>
<title>Permissions Panel</title>
<script type='text/javascript' src='search.js'></script>
<script type='text/javascript' src='[SSassets.transport.get_asset_url("search.js")]'></script>
</head>
<body onload='selectTextField();updateSearch();'>
<div id='main'><table id='searchable' cellspacing='0'>
@@ -136,7 +138,7 @@
if(IsAdminAdvancedProcCall())
to_chat(usr, "<span class='admin prefix'>Admin Edit blocked: Advanced ProcCall detected.</span>", confidential=TRUE)
return
var/datum/asset/permissions_assets = get_asset_datum(/datum/asset/simple/permissions)
var/datum/asset/permissions_assets = get_asset_datum(/datum/asset/simple/namespaced/common)
permissions_assets.send(src)
var/admin_key = href_list["key"]
var/admin_ckey = ckey(admin_key)

View File

@@ -505,7 +505,7 @@
alphatext = "filter: alpha(opacity=[alpha]); opacity: [alpha/100];"
var/list/data = list("<div style='margin:0px;[alphatext]'><p class='severity'>")
if(severity)
data += "<img src='[severity]_button.png' height='24' width='24'></img> "
data += "<img src='[SSassets.transport.get_asset_url("[severity]_button.png")]' height='24' width='24'></img> "
data += "<b>[timestamp] | [server] | [admin_key][secret ? " | <i>- Secret</i>" : ""]"
if(expire_timestamp)
data += " | Expires [expire_timestamp]"

View File

@@ -35,7 +35,7 @@
M.client.show_popup_menus = TRUE
M.client.show_verb_panel = TRUE
M.notransform = FALSE
M.verbs += M.client.afreeze_stored_verbs
add_verb(M, M.client.afreeze_stored_verbs)
message = "[key_name(usr)] has unfrozen [key_name(M)]."
else
to_chat(M, "<span class='userdanger'>You have been frozen by an administrator.</span>")
@@ -44,7 +44,7 @@
M.client.show_verb_panel = FALSE
M.notransform = TRUE
M.client.afreeze_stored_verbs = M.verbs.Copy()
M.verbs.Cut()
remove_verb(M, M.verbs.Copy())
message = "[key_name(usr)] has frozen [key_name(M)]."
log_admin(message)
message_admins(message) //yogs end

View File

@@ -422,11 +422,13 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null
delete_click = new(null, "INITIALIZING", src)
if(!action_click)
action_click = new(null, "INITIALIZNG", src)
stat("[id] ", delete_click.update("DELETE QUERY | STATE : [text_state()] | ALL/ELIG/FIN \
var/list/L = list()
L[++L.len] = list("[id] ", "[delete_click.update("DELETE QUERY | STATE : [text_state()] | ALL/ELIG/FIN \
[islist(obj_count_all)? length(obj_count_all) : (isnull(obj_count_all)? "0" : obj_count_all)]/\
[islist(obj_count_eligible)? length(obj_count_eligible) : (isnull(obj_count_eligible)? "0" : obj_count_eligible)]/\
[islist(obj_count_finished)? length(obj_count_finished) : (isnull(obj_count_finished)? "0" : obj_count_finished)] - [get_query_text()]"))
stat(" ", action_click.update("[SDQL2_IS_RUNNING? "HALT" : "RUN"]"))
[islist(obj_count_finished)? length(obj_count_finished) : (isnull(obj_count_finished)? "0" : obj_count_finished)] - [get_query_text()]")]", REF(delete_click))
L[++L.len] = list(" ", "[action_click.update("[SDQL2_IS_RUNNING? "HALT" : "RUN"]")]", REF(action_click))
return L
/datum/SDQL2_query/proc/delete_click()
admin_del(usr)
@@ -1196,10 +1198,18 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null
return istype(thing, /datum) || istype(thing, /client)
/obj/effect/statclick/SDQL2_delete/Click()
if(!usr.client?.holder)
message_admins("[key_name_admin(usr)] non-holder clicked on a statclick! ([src])")
log_game("[key_name(usr)] non-holder clicked on a statclick! ([src])")
return
var/datum/SDQL2_query/Q = target
Q.delete_click()
/obj/effect/statclick/SDQL2_action/Click()
if(!usr.client?.holder)
message_admins("[key_name_admin(usr)] non-holder clicked on a statclick! ([src])")
log_game("[key_name(usr)] non-holder clicked on a statclick! ([src])")
return
var/datum/SDQL2_query/Q = target
Q.action_click()
@@ -1207,4 +1217,8 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null
name = "VIEW VARIABLES"
/obj/effect/statclick/SDQL2_VV_all/Click()
if(!usr.client?.holder)
message_admins("[key_name_admin(usr)] non-holder clicked on a statclick! ([src])")
log_game("[key_name(usr)] non-holder clicked on a statclick! ([src])")
return
usr.client.debug_variables(GLOB.sdql2_queries)

View File

@@ -90,18 +90,23 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
//Tickets statpanel
/datum/admin_help_tickets/proc/stat_entry()
SHOULD_CALL_PARENT(TRUE)
SHOULD_NOT_SLEEP(TRUE)
var/list/L = list()
var/num_disconnected = 0
stat("Active Tickets:", astatclick.update("[active_tickets.len]"))
L[++L.len] = list("Active Tickets:", "[astatclick.update("[active_tickets.len]")]", null, REF(astatclick))
astatclick.update("[active_tickets.len]")
for(var/I in active_tickets)
var/datum/admin_help/AH = I
if(AH.initiator)
stat("#[AH.id]. [AH.initiator_key_name]:", AH.statclick.update())
L[++L.len] = list("#[AH.id]. [AH.initiator_key_name]:", "[AH.statclick.update()]", REF(AH))
else
++num_disconnected
if(num_disconnected)
stat("Disconnected:", astatclick.update("[num_disconnected]"))
stat("Closed Tickets:", cstatclick.update("[closed_tickets.len]"))
stat("Resolved Tickets:", rstatclick.update("[resolved_tickets.len]"))
L[++L.len] = list("Disconnected:", "[astatclick.update("[num_disconnected]")]", null, REF(astatclick))
L[++L.len] = list("Closed Tickets:", "[cstatclick.update("[closed_tickets.len]")]", null, REF(cstatclick))
L[++L.len] = list("Resolved Tickets:", "[rstatclick.update("[resolved_tickets.len]")]", null, REF(rstatclick))
return L
//Reassociate still open ticket if one exists
/datum/admin_help_tickets/proc/ClientLogin(client/C)
@@ -138,6 +143,10 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
/obj/effect/statclick/ticket_list/Click()
GLOB.ahelp_tickets.BrowseTickets(current_state)
//called by admin topic
/obj/effect/statclick/ticket_list/proc/Action()
Click()
//
//TICKET DATUM
//
@@ -219,7 +228,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
//Removes the ahelp verb and returns it after 2 minutes
/datum/admin_help/proc/TimeoutVerb()
initiator.verbs -= /client/verb/adminhelp
remove_verb(initiator, /client/verb/adminhelp)
initiator.adminhelptimerid = addtimer(CALLBACK(initiator, /client/proc/giveadminhelpverb), 1200, TIMER_STOPPABLE) //2 minute cooldown of admin helps
//private
@@ -267,10 +276,16 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
if(X.prefs.toggles & SOUND_ADMINHELP)
SEND_SOUND(X, sound('sound/effects/adminhelp.ogg'))
window_flash(X, ignorepref = TRUE)
to_chat(X, admin_msg, confidential=TRUE)
to_chat(X,
type = MESSAGE_TYPE_ADMINPM,
html = admin_msg,
confidential = TRUE)
//show it to the person adminhelping too
to_chat(initiator, "<span class='adminnotice'>PM to-<b>Admins</b>: <span class='linkify'>[msg]</span></span>", confidential=TRUE)
to_chat(initiator,
type = MESSAGE_TYPE_ADMINPM,
html = "<span class='adminnotice'>PM to-<b>Admins</b>: <span class='linkify'>[msg]</span></span>",
confidential = TRUE)
//Reopen a closed ticket
/datum/admin_help/proc/Reopen()
@@ -473,7 +488,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
//
/client/proc/giveadminhelpverb()
src.verbs |= /client/verb/adminhelp
add_verb(src, /client/verb/adminhelp)
deltimer(adminhelptimerid)
adminhelptimerid = 0

View File

@@ -1,7 +1,7 @@
/client/proc/jumptoarea(area/A in GLOB.sortedAreas)
set name = "Jump to Area"
set desc = "Area to jump to"
set category = "Admin"
set category = "Admin.Game"
if(!src.holder)
to_chat(src, "Only administrators may use this command.", confidential=TRUE)
return
@@ -26,7 +26,7 @@
/client/proc/jumptoturf(turf/T in world)
set name = "Jump to Turf"
set category = "Admin"
set category = "Admin.Game"
if(!src.holder)
to_chat(src, "Only administrators may use this command.", confidential=TRUE)
return
@@ -38,7 +38,7 @@
return
/client/proc/jumptomob(mob/M in GLOB.mob_list)
set category = "Admin"
set category = "Admin.Game"
set name = "Jump to Mob"
if(!src.holder)
@@ -57,7 +57,7 @@
to_chat(A, "This mob is not located in the game world.")
/client/proc/jumptocoord(tx as num, ty as num, tz as num)
set category = "Admin"
set category = "Admin.Game"
set name = "Jump to Coordinate"
if (!holder)
@@ -72,7 +72,7 @@
message_admins("[key_name_admin(usr)] jumped to coordinates [tx], [ty], [tz]")
/client/proc/jumptokey()
set category = "Admin"
set category = "Admin.Game"
set name = "Jump to Key"
if(!src.holder)
@@ -95,7 +95,7 @@
SSblackbox.record_feedback("tally", "admin_verb", 1, "Jump To Key") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/Getmob(mob/M in GLOB.mob_list - GLOB.dummy_mob_list)
set category = "Admin"
set category = "Admin.Game"
set name = "Get Mob"
set desc = "Mob to teleport"
if(!src.holder)
@@ -111,7 +111,7 @@
SSblackbox.record_feedback("tally", "admin_verb", 1, "Get Mob") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/Getkey()
set category = "Admin"
set category = "Admin.Game"
set name = "Get Key"
set desc = "Key to teleport"
@@ -139,7 +139,7 @@
SSblackbox.record_feedback("tally", "admin_verb", 1, "Get Key") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/sendmob(mob/M in sortmobs())
set category = "Admin"
set category = "Admin.Game"
set name = "Send Mob"
if(!src.holder)
to_chat(src, "Only administrators may use this command.", confidential=TRUE)

View File

@@ -6,7 +6,10 @@
set category = null
set name = "Admin PM Mob"
if(!holder)
to_chat(src, "<span class='danger'>Error: Admin-PM-Context: Only administrators may use this command.</span>", confidential=TRUE)
to_chat(src,
type = MESSAGE_TYPE_ADMINPM,
html = "<span class='danger'>Error: Admin-PM-Context: Only administrators may use this command.</span>",
confidential = TRUE)
return
if(!ismob(M)) //yogs start
return
@@ -23,7 +26,10 @@
set category = "Admin"
set name = "Admin PM"
if(!holder)
to_chat(src, "<span class='danger'>Error: Admin-PM-Panel: Only administrators may use this command.</span>", confidential=TRUE)
to_chat(src,
type = MESSAGE_TYPE_ADMINPM,
html = "<span class='danger'>Error: Admin-PM-Panel: Only administrators may use this command.</span>",
confidential = TRUE)
return
var/list/client/targets[0]
for(var/client/T)
@@ -42,7 +48,10 @@
/client/proc/cmd_ahelp_reply(whom)
if(prefs.muted & MUTE_ADMINHELP)
to_chat(src, "<span class='danger'>Error: Admin-PM: You are unable to use admin PM-s (muted).</span>", confidential=TRUE)
to_chat(src,
type = MESSAGE_TYPE_ADMINPM,
html = "<span class='danger'>Error: Admin-PM: You are unable to use admin PM-s (muted).</span>",
confidential = TRUE)
return
var/client/C
if(istext(whom))
@@ -53,7 +62,10 @@
C = whom
if(!C)
if(holder)
to_chat(src, "<span class='danger'>Error: Admin-PM: Client not found.</span>", confidential=TRUE)
to_chat(src,
type = MESSAGE_TYPE_ADMINPM,
html = "<span class='danger'>Error: Admin-PM: Client not found.</span>",
confidential = TRUE)
return
var/datum/admin_help/AH = C.current_ticket
@@ -70,12 +82,25 @@
//Fetching a message if needed. src is the sender and C is the target client
/client/proc/cmd_admin_pm(whom, msg)
if(prefs.muted & MUTE_ADMINHELP)
to_chat(src, "<span class='danger'>Error: Admin-PM: You are unable to use admin PM-s (muted).</span>", confidential=TRUE)
to_chat(src,
type = MESSAGE_TYPE_ADMINPM,
html = "<span class='danger'>Error: Admin-PM: You are unable to use admin PM-s (muted).</span>",
confidential = TRUE)
return
if(!holder && !current_ticket) //no ticket? https://www.youtube.com/watch?v=iHSPf6x1Fdo
to_chat(src,
type = MESSAGE_TYPE_ADMINPM,
html = "<span class='danger'>You can no longer reply to this ticket, please open another one by using the Adminhelp verb if need be.</span>",
confidential = TRUE)
to_chat(src,
type = MESSAGE_TYPE_ADMINPM,
html = "<span class='notice'>Message: [msg]</span>",
confidential = TRUE)
return
if(!holder && !current_ticket) //no ticket? https://www.youtube.com/watch?v=iHSPf6x1Fdo
to_chat(src, "<span class='danger'>You can no longer reply to this ticket, please open another one by using the Adminhelp verb if need be.</span>", confidential=TRUE)
to_chat(src, "<span class='notice'>Message: [msg]</span>", confidential=TRUE)
return
var/client/recipient
@@ -100,7 +125,10 @@
if(!msg)
return
if(holder)
to_chat(src, "<span class='danger'>Error: Use the admin IRC channel, nerd.</span>", confidential=TRUE)
to_chat(src,
type = MESSAGE_TYPE_ADMINPM,
html = "<span class='danger'>Error: Use the admin IRC/Discord channel, nerd.</span>",
confidential = TRUE)
return
@@ -128,7 +156,10 @@
if(!recipient)
if(holder)
to_chat(src, "<span class='danger'>Error: Admin-PM: Client not found.</span>", confidential=TRUE)
to_chat(src,
type = MESSAGE_TYPE_ADMINPM,
html = "<span class='danger'>Error: Admin-PM: Client not found.</span>",
confidential = TRUE)
else
current_ticket.MessageNoRecipient(msg)
return
@@ -157,12 +188,18 @@
else
if(recipient.holder)
if(holder)
to_chat(recipient, "<span class='danger'>Admin PM from-<b>[key_name(src, recipient, 1)]</b>: <span class='linkify'>[keywordparsedmsg]</span></span>", confidential=TRUE)
to_chat(src, "<span class='notice'>Admin PM to-<b>[key_name(recipient, src, 1)]</b>: <span class='linkify'>[keywordparsedmsg]</span></span>", confidential=TRUE)
to_chat(recipient,
type = MESSAGE_TYPE_ADMINPM,
html = "<span class='danger'>Admin PM from-<b>[key_name(src, recipient, 1)]</b>: <span class='linkify'>[keywordparsedmsg]</span></span>",
confidential = TRUE)
to_chat(src,
type = MESSAGE_TYPE_ADMINPM,
html = "<span class='notice'>Admin PM to-<b>[key_name(recipient, src, 1)]</b>: <span class='linkify'>[keywordparsedmsg]</span></span>",
confidential = TRUE)
//omg this is dumb, just fill in both their tickets
// yogs start - Yog Tickets
admin_ticket_log(src, msg, FALSE)
admin_ticket_log(src, msg, FALSE)
if(recipient.current_ticket && !recipient.current_ticket.handling_admin)
recipient.current_ticket.Administer(src)
// yogs end - Yog Tickets
@@ -178,7 +215,7 @@
to_chat(recipient, "<span class='danger'>Reply PM from-<b>[key_name(src, recipient, 1)]</b>: <span class='linkify'>[keywordparsedmsg]</span></span>", confidential=TRUE)
to_chat(src, "<span class='notice'>-- [key_name(src, null, 0)] -> <b>Admins</b>: <span class='linkify'>[msg]</span></span>", confidential=TRUE)
//YOGS END
//play the receiving admin the adminhelp sound (if they have them enabled)
if(recipient.prefs.toggles & SOUND_ADMINHELP)
SEND_SOUND(recipient, sound('sound/effects/adminhelp.ogg'))
@@ -214,20 +251,29 @@
return
else //neither are admins
to_chat(src, "<span class='danger'>Error: Admin-PM: Non-admin to non-admin PM communication is forbidden.</span>", confidential=TRUE)
to_chat(src,
type = MESSAGE_TYPE_ADMINPM,
html = "<span class='danger'>Error: Admin-PM: Non-admin to non-admin PM communication is forbidden.</span>",
confidential = TRUE)
return
if(irc)
log_admin_private("PM: [key_name(src)]->IRC: [rawmsg]")
for(var/client/X in GLOB.admins)
to_chat(X, "<span class='notice'><B>PM: [key_name(src, X, 0)]-&gt;IRC:</B> [keywordparsedmsg]</span>", confidential=TRUE)
to_chat(X,
type = MESSAGE_TYPE_ADMINPM,
html = "<span class='notice'><B>PM: [key_name(src, X, 0)]-&gt;External:</B> [keywordparsedmsg]</span>",
confidential = TRUE)
else
window_flash(recipient, ignorepref = TRUE)
log_admin_private("PM: [key_name(src)]->[key_name(recipient)]: [rawmsg]")
//we don't use message_admins here because the sender/receiver might get it too
for(var/client/X in GLOB.admins)
if(X.key!=key && X.key!=recipient.key) //check client/X is an admin and isn't the sender or recipient
to_chat(X, "<span class='notice'><B>PM: [key_name(src, X, 0)]-&gt;[key_name(recipient, X, 0)]:</B> [keywordparsedmsg]</span>" , confidential=TRUE)
if(X.key!=key && X.key!=recipient.key) //check client/X is an admin and isn't the sender or recipientD
to_chat(X,
type = MESSAGE_TYPE_ADMINPM,
html = "<span class='notice'><B>PM: [key_name(src, X, 0)]-&gt;[key_name(recipient, X, 0)]:</B> [keywordparsedmsg]</span>" ,
confidential = TRUE)
@@ -309,9 +355,18 @@
log_admin_private("IRC PM: [sender] -> [key_name(C)] : [msg]")
msg = emoji_parse(msg)
to_chat(C, "<font color='red' size='4'><b>-- Administrator private message --</b></font>", confidential=TRUE)
to_chat(C, "<span class='danger'>Admin PM from-<b><a href='?priv_msg=[stealthkey]'>[adminname]</A></b>: [msg]</span>", confidential=TRUE) // yogs - Yog Tickets
to_chat(C, "<span class='danger'><i>Click on the administrator's name to reply.</i></span>", confidential=TRUE) // yogs - Yog Tickets
to_chat(C,
type = MESSAGE_TYPE_ADMINPM,
html = "<font color='red' size='4'><b>-- Administrator private message --</b></font>",
confidential = TRUE)
to_chat(C,
type = MESSAGE_TYPE_ADMINPM,
html = "<span class='adminsay'>Admin PM from-<b><a href='?priv_msg=[stealthkey]'>[adminname]</A></b>: [msg]</span>",
confidential = TRUE) // yogs - Yog Tickets
to_chat(C,
type = MESSAGE_TYPE_ADMINPM,
html = "<span class='adminsay'><i>Click on the administrator's name to reply.</i></span>",
confidential = TRUE) // yogs - Yog Tickets
admin_ticket_log(C, "<span class='notice'>PM From [irc_tagged]: [msg]</span>") // yogs - Yog Tickets

View File

@@ -2,7 +2,7 @@
/client/proc/cmd_admin_say(msg as text)
set category = "Special Verbs"
set name = "Asay" //Gave this shit a shorter name so you only have to time out "asay" rather than "admin say" to use it --NeoFite
set hidden = 1
set hidden = TRUE
if(!check_rights(0))
return
msg = to_utf8(msg, src)
@@ -15,7 +15,10 @@
msg = keywords_lookup(msg)
var/custom_asay_color = (CONFIG_GET(flag/allow_admin_asaycolor) && prefs.asaycolor) ? "<font color=[prefs.asaycolor]>" : null // Yogs -- yogs asay
msg = "<span class='adminsay'><span class='prefix'>ADMIN:</span> <EM>[key_name(usr, 1)]</EM> [ADMIN_FLW(mob)]: [custom_asay_color]<span class='message linkify'>[msg]</span></span>[custom_asay_color ? "</font>":null]"
to_chat(GLOB.admins, msg, confidential=TRUE)
to_chat(GLOB.admins,
type = MESSAGE_TYPE_ADMINCHAT,
html = msg,
confidential = TRUE)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Asay") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!

View File

@@ -61,11 +61,13 @@
return container
/datum/admins/proc/beaker_panel()
set category = "Debug"
set category = "Admin.Fun"
set name = "Spawn reagent container"
if(!check_rights())
return
var/datum/asset/asset_datum = get_asset_datum(/datum/asset/simple/namespaced/common)
asset_datum.send()
//Could somebody tell me why this isn't using the browser datum, given that it copypastes all of browser datum's html
var/dat = {"
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
@@ -73,7 +75,7 @@
<meta http-equiv="Content-Type" content="text/html">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta charset='UTF-8'>
<link rel='stylesheet' type='text/css' href='common.css'>
<link rel='stylesheet' type='text/css' href='[SSassets.transport.get_asset_url("common.css")]'>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.7/js/select2.full.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.7/css/select2.min.css">

View File

@@ -1,5 +1,5 @@
/datum/admins/proc/open_borgopanel(borgo in GLOB.silicon_mobs)
set category = "Admin"
set category = "Admin.Game"
set name = "Show Borg Panel"
set desc = "Show borg panel"
@@ -202,7 +202,7 @@
borg.notify_ai(DISCONNECT)
if(borg.shell)
borg.undeploy()
borg.connected_ai = newai
borg.set_connected_ai(newai)
borg.notify_ai(TRUE)
message_admins("[key_name_admin(user)] slaved [ADMIN_LOOKUPFLW(borg)] to the AI [ADMIN_LOOKUPFLW(newai)].")
log_admin("[key_name(user)] slaved [key_name(borg)] to the AI [key_name(newai)].")
@@ -210,7 +210,7 @@
borg.notify_ai(DISCONNECT)
if(borg.shell)
borg.undeploy()
borg.connected_ai = null
borg.set_connected_ai(null)
message_admins("[key_name_admin(user)] freed [ADMIN_LOOKUPFLW(borg)] from being slaved to an AI.")
log_admin("[key_name(user)] freed [key_name(borg)] from being slaved to an AI.")
if (borg.lawupdate)

View File

@@ -1,8 +1,8 @@
/client/proc/cinematic()
set name = "cinematic"
set category = "Fun"
set name = "Cinematic"
set category = "Admin.Fun"
set desc = "Shows a cinematic." // Intended for testing but I thought it might be nice for events on the rare occasion Feel free to comment it out if it's not wanted.
set hidden = 1
set hidden = TRUE
if(!SSticker)
return

View File

@@ -1,7 +1,7 @@
/client/proc/dsay(msg as text)
set category = "Special Verbs"
set category = "Admin.Game"
set name = "Dsay"
set hidden = 1
set hidden = TRUE
if(!holder)
to_chat(src, "Only administrators may use this command.", confidential=TRUE)
return

View File

@@ -236,7 +236,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Air Status In Location") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_robotize(mob/M in GLOB.mob_list)
set category = "Fun"
set category = "Admin.Fun"
set name = "Make Robot"
if(!SSticker.HasRoundStarted())
@@ -252,7 +252,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
alert("Invalid mob")
/client/proc/cmd_admin_blobize(mob/M in GLOB.mob_list)
set category = "Fun"
set category = "Admin.Fun"
set name = "Make Blob"
if(!SSticker.HasRoundStarted())
@@ -267,7 +267,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
/client/proc/cmd_admin_animalize(mob/M in GLOB.mob_list)
set category = "Fun"
set category = "Admin.Fun"
set name = "Make Simple Animal"
if(!SSticker.HasRoundStarted())
@@ -288,7 +288,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
/client/proc/makepAI(turf/T in GLOB.mob_list)
set category = "Fun"
set category = "Admin.Fun"
set name = "Make pAI"
set desc = "Specify a location to spawn a pAI device, then specify a key to play that pAI"
@@ -315,7 +315,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Make pAI") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_alienize(mob/M in GLOB.mob_list)
set category = "Fun"
set category = "Admin.Fun"
set name = "Make Alien"
if(!SSticker.HasRoundStarted())
@@ -330,7 +330,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
alert("Invalid mob")
/client/proc/cmd_admin_slimeize(mob/M in GLOB.mob_list)
set category = "Fun"
set category = "Admin.Fun"
set name = "Make slime"
if(!SSticker.HasRoundStarted())
@@ -495,7 +495,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has granted [M.key] full access.</span>")
/client/proc/cmd_assume_direct_control(mob/M in GLOB.mob_list)
set category = "Admin"
set category = "Admin.Game"
set name = "Assume direct control"
set desc = "Direct intervention"
@@ -729,7 +729,8 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
cmd_admin_areatest(FALSE)
/client/proc/cmd_admin_dress(mob/M in GLOB.mob_list)
set category = "Fun"
set category = "Admin.Fun"
set name = "Select equipment"
if(!(ishuman(M) || isobserver(M)))
alert("Invalid mob")

View File

@@ -111,3 +111,32 @@
load_mentors()
SSblackbox.record_feedback("tally", "admin_verb", 1, "Reload All Mentors") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
message_admins("[key_name_admin(usr)] manually reloaded mentors")
/client/proc/toggle_cdn()
set name = "Toggle CDN"
set category = "Server"
var/static/admin_disabled_cdn_transport = null
if (alert(usr, "Are you sure you want to toggle the CDN asset transport?", "Confirm", "Yes", "No") != "Yes")
return
var/current_transport = CONFIG_GET(string/asset_transport)
if (!current_transport || current_transport == "simple")
if (admin_disabled_cdn_transport)
CONFIG_SET(string/asset_transport, admin_disabled_cdn_transport)
admin_disabled_cdn_transport = null
SSassets.OnConfigLoad()
message_admins("[key_name_admin(usr)] re-enabled the CDN asset transport")
log_admin("[key_name(usr)] re-enabled the CDN asset transport")
else
to_chat(usr, "<span class='adminnotice'>The CDN is not enabled!</span>")
if (alert(usr, "The CDN asset transport is not enabled! If you having issues with assets you can also try disabling filename mutations.", "The CDN asset transport is not enabled!", "Try disabling filename mutations", "Nevermind") == "Try disabling filename mutations")
SSassets.transport.dont_mutate_filenames = !SSassets.transport.dont_mutate_filenames
message_admins("[key_name_admin(usr)] [(SSassets.transport.dont_mutate_filenames ? "disabled" : "re-enabled")] asset filename transforms")
log_admin("[key_name(usr)] [(SSassets.transport.dont_mutate_filenames ? "disabled" : "re-enabled")] asset filename transforms")
else
admin_disabled_cdn_transport = current_transport
CONFIG_SET(string/asset_transport, "simple")
SSassets.OnConfigLoad()
SSassets.transport.dont_mutate_filenames = TRUE
message_admins("[key_name_admin(usr)] disabled the CDN asset transport")
log_admin("[key_name(usr)] disabled the CDN asset transport")

View File

@@ -206,15 +206,15 @@ GLOBAL_LIST_EMPTY(dirty_vars)
set name = "Debug verbs - Enable"
if(!check_rights(R_DEBUG))
return
verbs -= /client/proc/enable_debug_verbs
verbs.Add(/client/proc/disable_debug_verbs, GLOB.admin_verbs_debug_mapping)
remove_verb(src, /client/proc/enable_debug_verbs)
add_verb(src, list(/client/proc/disable_debug_verbs, GLOB.admin_verbs_debug_mapping))
SSblackbox.record_feedback("tally", "admin_verb", 1, "Enable Debug Verbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/disable_debug_verbs()
set category = "Debug"
set name = "Debug verbs - Disable"
verbs.Remove(/client/proc/disable_debug_verbs, GLOB.admin_verbs_debug_mapping)
verbs += /client/proc/enable_debug_verbs
remove_verb(src, list(/client/proc/disable_debug_verbs, GLOB.admin_verbs_debug_mapping))
add_verb(src, /client/proc/enable_debug_verbs)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Disable Debug Verbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/count_objects_on_z_level()

View File

@@ -1,7 +1,7 @@
/client/proc/one_click_antag()
set name = "Create Antagonist"
set desc = "Auto-create an antagonist of your choice"
set category = "Admin"
set category = "Admin.Fun"
if(holder)
holder.one_click_antag()

Some files were not shown because too many files have changed in this diff Show More