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" #define SHELTER_DEPLOY_ANCHORED_OBJECTS "anchored objects"
//debug printing macros //debug printing macros
#define debug_world(msg) if (GLOB.Debug2) to_chat(world, "DEBUG: [msg]") #define debug_world(msg) if (GLOB.Debug2) to_chat(world, \
#define debug_usr(msg) if (GLOB.Debug2&&usr) to_chat(usr, "DEBUG: [msg]") type = MESSAGE_TYPE_DEBUG, \
#define debug_admins(msg) if (GLOB.Debug2) to_chat(GLOB.admins, "DEBUG: [msg]") 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 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} #define INCREMENT_TALLY(L, stat) if(L[stat]){L[stat]++}else{L[stat] = 1}

View File

@@ -22,3 +22,5 @@
var/category as text var/category as text
/// Only clients/mobs with `see_invisibility` higher can use the verb. /// Only clients/mobs with `see_invisibility` higher can use the verb.
var/invisibility as num 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_PROFILER 101
#define INIT_ORDER_TITLE 100 #define INIT_ORDER_TITLE 100
#define INIT_ORDER_GARBAGE 99 #define INIT_ORDER_GARBAGE 99
#define INIT_ORDER_STATPANELS 98
#define INIT_ORDER_DBCORE 95 #define INIT_ORDER_DBCORE 95
#define INIT_ORDER_BLACKBOX 94 #define INIT_ORDER_BLACKBOX 94
#define INIT_ORDER_SERVER_MAINT 93 #define INIT_ORDER_SERVER_MAINT 93
@@ -138,13 +137,13 @@
#define INIT_ORDER_DISCORD -60 #define INIT_ORDER_DISCORD -60
#define INIT_ORDER_EXPLOSIONS -69 #define INIT_ORDER_EXPLOSIONS -69
#define INIT_ORDER_PERSISTENCE -95 #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_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. #define INIT_ORDER_CHAT -100 //Should be last to ensure chat remains smooth during init.
// Subsystem fire priority, from lowest to highest priority // 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) // 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_IDLE_NPC 10
#define FIRE_PRIORITY_SERVER_MAINT 10 #define FIRE_PRIORITY_SERVER_MAINT 10
#define FIRE_PRIORITY_RESEARCH 10 #define FIRE_PRIORITY_RESEARCH 10

View File

@@ -27,4 +27,11 @@
/// Get a window id based on the provided pool index /// Get a window id based on the provided pool index
#define TGUI_WINDOW_ID(index) "tgui-window-[index]" #define TGUI_WINDOW_ID(index) "tgui-window-[index]"
/// Get a pool index of the provided window id /// 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) /proc/log_mapping(text)
WRITE_LOG(GLOB.world_map_error_log, text) WRITE_LOG(GLOB.world_map_error_log, text)
/* ui logging */ /**
* Appends a tgui-related log entry. All arguments are optional.
/proc/log_tgui(user_or_client, text) */
/proc/log_tgui(user, message, context,
datum/tgui_window/window,
datum/src_object)
var/entry = "" var/entry = ""
if(!user_or_client) // Insert user info
entry += "no user" if(!user)
else if(istype(user_or_client, /mob)) entry += "<nobody>"
var/mob/user = user_or_client else if(istype(user, /mob))
entry += "[user.ckey] (as [user])" var/mob/mob = user
else if(istype(user_or_client, /client)) entry += "[mob.ckey] (as [mob] at [mob.x],[mob.y],[mob.z])"
var/client/client = user_or_client else if(istype(user, /client))
var/client/client = user
entry += "[client.ckey]" 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) WRITE_LOG(GLOB.tgui_log, entry)
/* For logging round startup. */ /* For logging round startup. */
/proc/start_log(log) /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")) /client/proc/browse_files(root="data/logs/", max_iterations=10, list/valid_extensions=list("txt","log","htm", "html", "json"))
if(IsAdminAdvancedProcCall()) if(IsAdminAdvancedProcCall())
log_admin_private("BROWSEFILES: Admin proc call blocked") 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. /// 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 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, * 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. * 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, "{") var/list/partial = splittext(iconData, "{")
return replacetext(copytext_char(partial[2], 3, -5), "\n", "") 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) if (!thing)
return return
@@ -1133,10 +1141,12 @@ GLOBAL_DATUM_INIT(dummySave, /savefile, new("tmp/dummySave.sav")) //Cache of ico
if (isfile(thing)) //special snowflake if (isfile(thing)) //special snowflake
var/name = sanitize_filename("[generate_asset_name(thing)].png") var/name = sanitize_filename("[generate_asset_name(thing)].png")
if (!SSassets.cache[name]) if (!SSassets.cache[name])
register_asset(name, thing) SSassets.transport.register_asset(name, thing)
for (var/thing2 in targets) for (var/thing2 in targets)
send_asset(thing2, key) SSassets.transport.send_assets(thing2, name)
return "<img class='icon icon-misc' src=\"[url_encode(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 var/atom/A = thing
if (isnull(dir)) if (isnull(dir))
dir = A.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" key = "[generate_asset_name(I)].png"
if(!SSassets.cache[key]) if(!SSassets.cache[key])
register_asset(key, I) SSassets.transport.register_asset(key, I)
for (var/thing2 in targets) for (var/thing2 in targets)
send_asset(thing2, key) SSassets.transport.send_assets(thing2, key)
if(sourceonly)
return "<img class='icon icon-[icon_state]' src=\"[url_encode(key)]\">" return SSassets.transport.get_asset_url(key)
return "<img class='icon icon-[icon_state]' src='[SSassets.transport.get_asset_url(key)]'>"
/proc/icon2base64html(thing) /proc/icon2base64html(thing)
if (!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]]'>" 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. //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) if (!thing)
return return
@@ -1206,4 +1217,4 @@ GLOBAL_DATUM_INIT(dummySave, /savefile, new("tmp/dummySave.sav")) //Cache of ico
return icon2html(thing, target) return icon2html(thing, target)
var/icon/I = getFlatIcon(thing) var/icon/I = getFlatIcon(thing)
return icon2html(I, target) return icon2html(I, target, sourceonly = sourceonly)

View File

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

View File

@@ -595,3 +595,8 @@
return "turf" return "turf"
else //regex everything else (works for /proc too) else //regex everything else (works for /proc too)
return lowertext(replacetext("[the_type]", "[type2parent(the_type)]/", "")) 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) var/turf/T = get_turf(src)
if(T && user.TurfAdjacent(T)) if(T && user.TurfAdjacent(T))
user.listed_turf = 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 // 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) /atom/proc/AltClickNoInteract(mob/user, atom/A)
var/turf/T = get_turf(A) var/turf/T = get_turf(A)
if(T && user.TurfAdjacent(T)) if(T && user.TurfAdjacent(T))
user.listed_turf = 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) /mob/proc/TurfAdjacent(turf/T)
return T.Adjacent(src) return T.Adjacent(src)

View File

@@ -49,6 +49,12 @@
loadmaplist(CONFIG_MAPS_FILE) loadmaplist(CONFIG_MAPS_FILE)
LoadMOTD() LoadMOTD()
LoadPolicy() LoadPolicy()
if (Master)
Master.OnConfigLoad()
if (Master)
Master.OnConfigLoad()
/datum/controller/configuration/proc/full_wipe() /datum/controller/configuration/proc/full_wipe()
if(IsAdminAdvancedProcCall()) if(IsAdminAdvancedProcCall())
@@ -180,10 +186,9 @@
var/list/banned_edits = list(NAMEOF(src, entries_by_type), NAMEOF(src, entries), NAMEOF(src, directory)) var/list/banned_edits = list(NAMEOF(src, entries_by_type), NAMEOF(src, entries), NAMEOF(src, directory))
return !(var_name in banned_edits) && ..() return !(var_name in banned_edits) && ..()
/datum/controller/configuration/stat_entry() /datum/controller/configuration/stat_entry(msg)
if(!statclick) msg = "Edit"
statclick = new/obj/effect/statclick/debug(null, "Edit", src) return msg
stat("[name]:", statclick)
/datum/controller/configuration/proc/Get(entry_type) /datum/controller/configuration/proc/Get(entry_type)
var/datum/config_entry/E = entry_type var/datum/config_entry/E = entry_type
@@ -395,3 +400,7 @@ Example config:
continue continue
runnable_modes[M] = probabilities[M.config_tag] runnable_modes[M] = probabilities[M.config_tag]
return runnable_modes 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/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() /datum/controller/failsafe/proc/defcon_pretty()
return defcon return defcon
/datum/controller/failsafe/stat_entry() /datum/controller/failsafe/stat_entry(msg)
if(!statclick) msg = "Defcon: [defcon_pretty()] (Interval: [Failsafe.processing_interval] | Iteration: [Failsafe.master_iteration])"
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src) return msg
stat("Failsafe Controller:", statclick.update("Defcon: [defcon_pretty()] (Interval: [Failsafe.processing_interval] | Iteration: [Failsafe.master_iteration])"))

View File

@@ -25,11 +25,9 @@ GLOBAL_REAL(GLOB, /datum/controller/global_vars)
SHOULD_CALL_PARENT(FALSE) SHOULD_CALL_PARENT(FALSE)
return QDEL_HINT_IWILLGC return QDEL_HINT_IWILLGC
/datum/controller/global_vars/stat_entry() /datum/controller/global_vars/stat_entry(msg)
if(!statclick) msg = "Edit"
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src) return msg
stat("Globals:", statclick.update("Edit"))
/datum/controller/global_vars/vv_edit_var(var_name, var_value) /datum/controller/global_vars/vv_edit_var(var_name, var_value)
if(gvars_datum_protected_varlist[var_name]) if(gvars_datum_protected_varlist[var_name])

View File

@@ -603,12 +603,9 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
if (!skip_ticks) if (!skip_ticks)
skip_ticks = 1 skip_ticks = 1
/datum/controller/master/stat_entry() /datum/controller/master/stat_entry(msg)
if(!statclick) msg = "(TickRate:[Master.processing]) (Iteration:[Master.iteration]) (TickLimit: [round(Master.current_ticklimit, 0.1)])"
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src) return msg
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/StartLoadingMap() /datum/controller/master/StartLoadingMap()
//disallow more than one map to load at once, multithreading it will just cause race conditions //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) 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)) 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) 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) if(SS_SLEEPING)
state = SS_PAUSING 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 //used to initialize the subsystem AFTER the map has loaded
/datum/controller/subsystem/Initialize(start_timeofday) /datum/controller/subsystem/Initialize(start_timeofday)
@@ -166,18 +168,13 @@
log_world(msg) log_world(msg)
return time 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() /datum/controller/subsystem/stat_entry(msg)
if(can_fire && !(SS_NO_FIRE & flags))
var/title = name msg = "[round(cost,1)]ms|[round(tick_usage,1)]%([round(tick_overrun,1)]%)|[round(ticks,0.1)]\t[msg]"
if (can_fire) else
title = "\[[state_letter()]][title]" msg = "OFFLINE\t[msg]"
return msg
stat(title, statclick.update(msg))
/datum/controller/subsystem/stat_entry(msg) /datum/controller/subsystem/stat_entry(msg)
if(can_fire && !(SS_NO_FIRE & flags)) if(can_fire && !(SS_NO_FIRE & flags))

View File

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

View File

@@ -6,12 +6,13 @@ SUBSYSTEM_DEF(adjacent_air)
priority = FIRE_PRIORITY_ATMOS_ADJACENCY priority = FIRE_PRIORITY_ATMOS_ADJACENCY
var/list/queue = list() var/list/queue = list()
/datum/controller/subsystem/adjacent_air/stat_entry() /datum/controller/subsystem/adjacent_air/stat_entry(msg)
#ifdef TESTING #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 #else
return ..("P:[length(queue)]") msg = "P:[length(queue)]"
#endif #endif
return ..()
/datum/controller/subsystem/adjacent_air/Initialize() /datum/controller/subsystem/adjacent_air/Initialize()
while(length(queue)) while(length(queue))

View File

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

View File

@@ -4,6 +4,23 @@ SUBSYSTEM_DEF(assets)
flags = SS_NO_FIRE flags = SS_NO_FIRE
var/list/cache = list() var/list/cache = list()
var/list/preload = 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) /datum/controller/subsystem/assets/Initialize(timeofday)
for(var/type in typesof(/datum/asset)) for(var/type in typesof(/datum/asset))
@@ -11,8 +28,6 @@ SUBSYSTEM_DEF(assets)
if (type != initial(A._abstract)) if (type != initial(A._abstract))
get_asset_datum(type) 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() var/list/observers_given_action = list()
/datum/controller/subsystem/augury/stat_entry(msg) /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) /datum/controller/subsystem/augury/proc/register_doom(atom/A, severity)
doombringers[A] = severity doombringers[A] = severity

View File

@@ -1,3 +1,8 @@
/**
* Copyright (c) 2020 Aleksej Komarov
* SPDX-License-Identifier: MIT
*/
SUBSYSTEM_DEF(chat) SUBSYSTEM_DEF(chat)
name = "Chat" name = "Chat"
flags = SS_TICKER flags = SS_TICKER
@@ -5,62 +10,32 @@ SUBSYSTEM_DEF(chat)
priority = FIRE_PRIORITY_CHAT priority = FIRE_PRIORITY_CHAT
init_order = INIT_ORDER_CHAT init_order = INIT_ORDER_CHAT
var/list/payload = list() var/list/payload_by_client = list()
/datum/controller/subsystem/chat/fire() /datum/controller/subsystem/chat/fire()
for(var/i in payload) for(var/key in payload_by_client)
var/client/C = i var/client/client = key
C << output(payload[C], "browseroutput:output") var/payload = payload_by_client[key]
payload -= C 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) if(MC_TICK_CHECK)
return return
/datum/controller/subsystem/chat/proc/queue(target, message, confidential = FALSE)
/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>"
if(!confidential) if(!confidential)
SSdemo.write_chat(target, message) SSdemo.write_chat(target, message)
if(islist(target)) if(islist(target))
for(var/I in target) for(var/_target in target)
var/client/C = CLIENT_FROM_VAR(I) //Grab us a client if possible var/client/client = CLIENT_FROM_VAR(_target)
if(client)
if(!C?.chatOutput || C.chatOutput.broken) //A player who hasn't updated his skin file. LAZYADD(payload_by_client[client], list(message))
continue return
var/client/client = CLIENT_FROM_VAR(target)
if(!C.chatOutput.loaded) //Client still loading, put their messages in a queue if(client)
C.chatOutput.messageQueue += message LAZYADD(payload_by_client[client], list(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))

View File

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

View File

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

View File

@@ -7,8 +7,10 @@ SUBSYSTEM_DEF(fire_burning)
var/list/currentrun = list() var/list/currentrun = list()
var/list/processing = 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) /datum/controller/subsystem/fire_burning/fire(resumed = 0)
@@ -36,4 +38,3 @@ SUBSYSTEM_DEF(fire_burning)
if (MC_TICK_CHECK) if (MC_TICK_CHECK)
return return

View File

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

View File

@@ -8,10 +8,11 @@ SUBSYSTEM_DEF(idlenpcpool)
var/list/currentrun = list() var/list/currentrun = list()
var/static/list/idle_mobs_by_zlevel[][] 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/idlelist = GLOB.simple_animals[AI_IDLE]
var/list/zlist = GLOB.simple_animals[AI_Z_OFF] 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() /datum/controller/subsystem/idlenpcpool/proc/MaxZChanged()
if (!islist(idle_mobs_by_zlevel)) if (!islist(idle_mobs_by_zlevel))

View File

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

View File

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

View File

@@ -442,7 +442,7 @@ GLOBAL_LIST_EMPTY(the_station_areas)
//Manual loading of away missions. //Manual loading of away missions.
/client/proc/admin_away() /client/proc/admin_away()
set name = "Load Away Mission" set name = "Load Away Mission"
set category = "Fun" set category = "Admin.Fun"
if(!holder ||!check_rights(R_FUN)) if(!holder ||!check_rights(R_FUN))
return 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/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() var/static/list/cubemonkeys = list()
/datum/controller/subsystem/mobs/stat_entry() /datum/controller/subsystem/mobs/stat_entry(msg)
return ..("P:[GLOB.mob_living_list.len]") msg = "P:[length(GLOB.mob_living_list)]"
return ..()
/datum/controller/subsystem/mobs/proc/MaxZChanged() /datum/controller/subsystem/mobs/proc/MaxZChanged()
if (!islist(clients_by_zlevel)) if (!islist(clients_by_zlevel))

View File

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

View File

@@ -22,8 +22,9 @@ SUBSYSTEM_DEF(overlays)
return ..() return ..()
/datum/controller/subsystem/overlays/stat_entry() /datum/controller/subsystem/overlays/stat_entry(msg)
return ..("Ov:[length(queue)]") msg = "Ov:[length(queue)]"
return ..()
/datum/controller/subsystem/overlays/Shutdown() /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/processing = list()
var/list/currentrun = list() var/list/currentrun = list()
/datum/controller/subsystem/processing/stat_entry() /datum/controller/subsystem/processing/stat_entry(msg)
return ..("[stat_tag]:[processing.len]") msg = "[stat_tag]:[length(processing)]"
return ..()
/datum/controller/subsystem/processing/fire(resumed = 0) /datum/controller/subsystem/processing/fire(resumed = 0)
if (!resumed) if (!resumed)

View File

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

View File

@@ -82,9 +82,7 @@ SUBSYSTEM_DEF(server_maint)
if(!thing) if(!thing)
continue continue
var/client/C = thing var/client/C = thing
var/datum/chatOutput/co = C.chatOutput C?.tgui_panel?.send_roundrestart()
if(co)
co.ehjax_send(data = "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 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]") C << link("byond://[server]")
var/datum/tgs_version/tgsversion = world.TgsVersion() var/datum/tgs_version/tgsversion = world.TgsVersion()

View File

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

View File

@@ -11,8 +11,10 @@ SUBSYSTEM_DEF(throwing)
var/list/currentrun var/list/currentrun
var/list/processing = list() 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) /datum/controller/subsystem/throwing/fire(resumed = 0)

View File

@@ -392,6 +392,7 @@ SUBSYSTEM_DEF(ticker)
if(living.client) if(living.client)
var/obj/screen/splash/S = new(living.client, TRUE) var/obj/screen/splash/S = new(living.client, TRUE)
S.Fade(TRUE) S.Fade(TRUE)
living.client.init_verbs()
livings += living livings += living
if(livings.len) if(livings.len)
addtimer(CALLBACK(src, .proc/release_characters, livings), 30, TIMER_CLIENT_TIME) 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 bucket_resolution = world.tick_lag
/datum/controller/subsystem/timer/stat_entry(msg) /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) /datum/controller/subsystem/timer/fire(resumed = FALSE)
var/lit = last_invoke_tick 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/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/stylesheets[0]
var/scripts[0] var/scripts[0]
var/title_image
var/head_elements var/head_elements
var/body_elements var/body_elements
var/head_content = "" var/head_content = ""
var/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) /datum/browser/New(nuser, nwindow_id, ntitle = 0, nwidth = 0, nheight = 0, var/atom/nref = null)
@@ -27,7 +27,6 @@
height = nheight height = nheight
if (nref) if (nref)
ref = 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) /datum/browser/proc/add_head_content(nhead_content)
head_content = nhead_content head_content = nhead_content
@@ -35,9 +34,6 @@
/datum/browser/proc/set_window_options(nwindow_options) /datum/browser/proc/set_window_options(nwindow_options)
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) /datum/browser/proc/add_stylesheet(name, file)
if (istype(name, /datum/asset/spritesheet)) if (istype(name, /datum/asset/spritesheet))
var/datum/asset/spritesheet/sheet = name var/datum/asset/spritesheet/sheet = name
@@ -47,11 +43,11 @@
stylesheets[asset_name] = file stylesheets[asset_name] = file
if (!SSassets.cache[asset_name]) if (!SSassets.cache[asset_name])
register_asset(asset_name, file) SSassets.transport.register_asset(asset_name, file)
/datum/browser/proc/add_script(name, file) /datum/browser/proc/add_script(name, file)
scripts["[ckey(name)].js"] = 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) /datum/browser/proc/set_content(ncontent)
content = ncontent content = ncontent
@@ -61,15 +57,13 @@
/datum/browser/proc/get_header() /datum/browser/proc/get_header()
var/file var/file
head_content += "<link rel='stylesheet' type='text/css' href='[common_asset.get_url_mappings()["common.css"]]'>"
for (file in stylesheets) 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) for (file in scripts)
head_content += "<script type='text/javascript' src='[file]'></script>" head_content += "<script type='text/javascript' src='[SSassets.transport.get_asset_url(file)]'></script>"
var/title_attributes = "class='uiTitle'"
if (title_image)
title_attributes = "class='uiTitle icon' style='background-image: url([title_image]);'"
return {"<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> return {"<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html> <html>
@@ -80,7 +74,7 @@
</head> </head>
<body scroll=auto> <body scroll=auto>
<div class='uiWrapper'> <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'> <div class='uiContent'>
"} "}
//" This is here because else the rest of the file looks like a string in notepad++. //" This is here because else the rest of the file looks like a string in notepad++.
@@ -106,10 +100,11 @@
var/window_size = "" var/window_size = ""
if (width && height) if (width && height)
window_size = "size=[width]x[height];" window_size = "size=[width]x[height];"
common_asset.send(user)
if (stylesheets.len) if (stylesheets.len)
send_asset_list(user, stylesheets) SSassets.transport.send_assets(user, stylesheets)
if (scripts.len) 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]") user << browse(get_content(), "window=[window_id];[window_size][window_options]")
if (use_onclose) if (use_onclose)
setup_onclose() setup_onclose()
@@ -416,12 +411,6 @@
if (A.selectedbutton) if (A.selectedbutton)
return list("button" = A.selectedbutton, "settings" = A.settings) 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) // 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. // 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. // otherwise, just reset the client mob's machine var.
// //
/client/verb/windowclose(atomref as text) /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 set name = ".windowclose" // no autocomplete on cmd line
if(atomref!="null") // if passed a real atomref if(atomref!="null") // if passed a real atomref

View File

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

View File

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

View File

@@ -39,7 +39,7 @@
new_ai = select_active_ai(R) new_ai = select_active_ai(R)
R.notify_ai(DISCONNECT) R.notify_ai(DISCONNECT)
if(new_ai && (new_ai != R.connected_ai)) if(new_ai && (new_ai != R.connected_ai))
R.connected_ai = new_ai R.set_connected_ai(new_ai)
if(R.shell) if(R.shell)
R.undeploy() //If this borg is an AI shell, disconnect the controlling AI and assign ti to a new AI 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) R.notify_ai(AI_SHELL)
@@ -68,7 +68,7 @@
R.notify_ai(DISCONNECT) R.notify_ai(DISCONNECT)
if(R.shell) if(R.shell)
R.undeploy() 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(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(mend)
if(!R.emagged) if(!R.emagged)

View File

@@ -1174,5 +1174,25 @@
for(var/x in materials) for(var/x in materials)
var/datum/material/custom_material = x var/datum/material/custom_material = x
custom_material.on_applied(src, materials[custom_material] * multiplier, material_flags) custom_material.on_applied(src, materials[custom_material] * multiplier, material_flags)
custom_materials[custom_material] += materials[x] * multiplier 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()) /mob/living/silicon/ai/verb/ai_camera_track(target_name in trackable_mobs())
set name = "track" 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) if(!target_name)
return return

View File

@@ -181,7 +181,6 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list(
dat += "</b></center>" dat += "</b></center>"
var/datum/browser/popup = new(user, "arcade", "Space Villain 2000") var/datum/browser/popup = new(user, "arcade", "Space Villain 2000")
popup.set_content(dat) popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
popup.open() popup.open()
/obj/machinery/computer/arcade/battle/Topic(href, href_list) /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>" 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) var/datum/browser/popup = new(user, "arcade", "The Orion Trail",400,700)
popup.set_content(dat) popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
popup.open() popup.open()
return return

View File

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

View File

@@ -315,7 +315,6 @@
var/datum/browser/popup = new(user, "cloning", "Cloning System Control") var/datum/browser/popup = new(user, "cloning", "Cloning System Control")
popup.set_content(dat) popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
popup.open() popup.open()
/obj/machinery/computer/cloning/Topic(href, href_list) /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) 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)) if(issilicon(user))
var/dat2 = interact_ai(user) // give the AI a different interact proc to limit its access 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 .["miny"] = M.miny
.["maxx"] = M.maxx .["maxx"] = M.maxx
.["maxy"] = M.maxy .["maxy"] = M.maxy
.["map_filename"] = SSassets.transport.get_asset_url("minimap-1.png")
/datum/crewmonitor/proc/update_data(z) /datum/crewmonitor/proc/update_data(z)
if(data_by_z["[z]"] && last_update["[z]"] && world.time <= last_update["[z]"] + SENSORS_UPDATE_PERIOD) if(data_by_z["[z]"] && last_update["[z]"] && world.time <= last_update["[z]"] + SENSORS_UPDATE_PERIOD)

View File

@@ -247,6 +247,10 @@
if(!ui) if(!ui)
ui = new(user, src, "DnaConsole") ui = new(user, src, "DnaConsole")
ui.open() 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) /obj/machinery/computer/scan_consolenew/ui_data(mob/user)
var/list/data = list() var/list/data = list()

View File

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

View File

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

View File

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

View File

@@ -82,10 +82,10 @@
var/md5 = md5(fcopy_rsc(picture)) var/md5 = md5(fcopy_rsc(picture))
if(!SSassets.cache["photo_[md5]_cropped.png"]) if(!SSassets.cache["photo_[md5]_cropped.png"])
register_asset("photo_[md5]_cropped.png", picture) SSassets.transport.register_asset("photo_[md5]_cropped.png", picture)
send_asset_list(user, list("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()) data["has_access"] = check_access(user.get_idcard())
@@ -154,16 +154,19 @@
if(istype(active_general_record.fields["photo_front"], /obj/item/photo)) if(istype(active_general_record.fields["photo_front"], /obj/item/photo))
var/obj/item/photo/P1 = active_general_record.fields["photo_front"] var/obj/item/photo/P1 = active_general_record.fields["photo_front"]
if(!SSassets.cache["photo_front_[active_general_record.fields["id"]].png"]) 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 assets["photo_front_[active_general_record.fields["id"]].png"] = P1.picture.picture_image
if(istype(active_general_record.fields["photo_side"], /obj/item/photo)) if(istype(active_general_record.fields["photo_side"], /obj/item/photo))
var/obj/item/photo/P2 = active_general_record.fields["photo_side"] var/obj/item/photo/P2 = active_general_record.fields["photo_side"]
if(!SSassets.cache["photo_side_[active_general_record.fields["id"]].png"]) 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 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"] 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) var/datum/browser/popup = new(user, "warrant", "Security Warrant Console", 600, 400)
popup.set_content(dat.Join()) popup.set_content(dat.Join())
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open() popup.open()
/obj/machinery/computer/warrant/Topic(href, href_list) /obj/machinery/computer/warrant/Topic(href, href_list)

View File

@@ -254,7 +254,6 @@
/obj/machinery/doorButtons/airlock_controller/ui_interact(mob/user) /obj/machinery/doorButtons/airlock_controller/ui_interact(mob/user)
var/datum/browser/popup = new(user, "computer", name) 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.set_content(returnText())
popup.open() popup.open()

View File

@@ -29,7 +29,6 @@
. = ..() . = ..()
user.set_machine(src) user.set_machine(src)
var/datum/browser/popup = new(user, "computer", name) // Set up the popup browser window 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.set_content(return_text())
popup.open() popup.open()

View File

@@ -216,7 +216,6 @@
var/datum/browser/popup = new(user, "cloning", "Prototype Cloning System Control") var/datum/browser/popup = new(user, "cloning", "Prototype Cloning System Control")
popup.set_content(dat) popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open() popup.open()
/obj/machinery/computer/prototype_cloning/Topic(href, href_list) /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>" 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) var/datum/browser/popup = new(human_or_robot_user, "newscaster_main", "Newscaster Unit #[unit_no]", 400, 600)
popup.set_content(dat) popup.set_content(dat)
popup.set_title_image(human_or_robot_user.browse_rsc_icon(icon, icon_state))
popup.open() popup.open()
/obj/machinery/newscaster/Topic(href, href_list) /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)])") var/datum/browser/popup = new(user, "turretid", "Turret Control Panel ([get_area_name(src, TRUE)])")
popup.set_content(t) popup.set_content(t)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open() popup.open()
/obj/machinery/turretid/Topic(href, href_list) /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]") CRASH("No UI for src. Screen var is: [screen]")
var/datum/browser/popup = new(user, "req_console", "[department] Requests Console", 450, 440) var/datum/browser/popup = new(user, "req_console", "[department] Requests Console", 450, 440)
popup.set_content(dat) popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open() popup.open()
return return

View File

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

View File

@@ -239,7 +239,6 @@
message = defaultmsg message = defaultmsg
var/datum/browser/popup = new(user, "hologram_console", name, 700, 700) var/datum/browser/popup = new(user, "hologram_console", name, 700, 700)
popup.set_content(dat) popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
popup.open() popup.open()
/obj/machinery/computer/message_monitor/proc/BruteForce(mob/user) /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. // So he can't jump out the gate right away.
R.SetLockdown() R.SetLockdown()
if(masterAI) if(masterAI)
R.connected_ai = masterAI R.set_connected_ai(masterAI)
R.lawsync() R.lawsync()
R.lawupdate = 1 R.lawupdate = 1
addtimer(CALLBACK(src, .proc/unlock_new_robot, R), 50) 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) var/datum/browser/popup = new(user, "rcd_access", "Access Control", 900, 500)
popup.set_content(t1) popup.set_content(t1)
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
popup.open() popup.open()
onclose(user, "rcd_access") onclose(user, "rcd_access")

View File

@@ -793,9 +793,7 @@
ADD_TRAIT(G, TRAIT_HOLY, SPECIES_TRAIT) ADD_TRAIT(G, TRAIT_HOLY, SPECIES_TRAIT)
log_game("[key_name(H)] has summoned [key_name(G)], a holoparasite, with a holy tarot deck.") 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>") 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 add_verb(H, list(/mob/living/proc/guardian_comm, /mob/living/proc/guardian_recall, /mob/living/proc/guardian_reset))
H.verbs += /mob/living/proc/guardian_recall
H.verbs += /mob/living/proc/guardian_reset
force = 0 force = 0
throwforce = 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>") 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.custom_name = created_name
O.locked = panel_locked O.locked = panel_locked
if(!aisync) if(!aisync)
lawsync = 0 lawsync = FALSE
O.connected_ai = null O.set_connected_ai(null)
else else
O.notify_ai(NEW_BORG) O.notify_ai(NEW_BORG)
if(forced_ai) if(forced_ai)
O.connected_ai = forced_ai O.set_connected_ai(forced_ai)
if(!lawsync) if(!lawsync)
O.lawupdate = 0 O.lawupdate = 0
if(M.laws.id == DEFAULT_AI_LAWID) if(M.laws.id == DEFAULT_AI_LAWID)
@@ -348,10 +348,10 @@
if(!aisync) if(!aisync)
lawsync = FALSE lawsync = FALSE
O.connected_ai = null O.set_connected_ai(null)
else else
if(forced_ai) if(forced_ai)
O.connected_ai = forced_ai O.set_connected_ai(forced_ai)
O.notify_ai(AI_SHELL) O.notify_ai(AI_SHELL)
if(!lawsync) if(!lawsync)
O.lawupdate = FALSE O.lawupdate = FALSE
@@ -387,7 +387,8 @@
popup.open() popup.open()
/obj/item/robot_suit/Topic(href, href_list) /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 return
var/mob/living/living_user = usr var/mob/living/living_user = usr

View File

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

View File

@@ -33,8 +33,6 @@ GLOBAL_VAR(restart_counter)
log_world("World loaded at [time_stamp()]!") 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 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) 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 #endif
SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, /proc/addtimer, cb, 10 SECONDS)) 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() /world/proc/SetupLogs()
var/override_dir = params[OVERRIDE_LOG_DIRECTORY_PARAMETER] var/override_dir = params[OVERRIDE_LOG_DIRECTORY_PARAMETER]
@@ -249,6 +237,7 @@ GLOBAL_VAR(restart_counter)
var/client/C = boi var/client/C = boi
if(!istype(C)) continue //yes so this is useful to prevent nulls from preventing the server from rebooting... 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) sync_logout_with_db(C.connection_number)
C?.tgui_panel?.send_roundrestart()
TgsReboot() TgsReboot()

View File

@@ -2,17 +2,23 @@
//////////////////////////////// ////////////////////////////////
/proc/message_admins(msg) /proc/message_admins(msg)
msg = "<span class=\"admin\"><span class=\"prefix\">ADMIN LOG:</span> <span class=\"message linkify\">[msg]</span></span>" 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) /proc/relay_msg_admins(msg)
msg = "<span class=\"admin\"><span class=\"prefix\">RELAY:</span> <span class=\"message linkify\">[msg]</span></span>" 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 ///////////////////////////////////////////////////////////////////////////////////////////////Panels
/datum/admins/proc/show_player_panel(mob/M in GLOB.mob_list) /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 name = "Show Player Panel"
set desc="Edit player (respawn, ban, heal, etc)" set desc="Edit player (respawn, ban, heal, etc)"
@@ -210,7 +216,7 @@
/datum/admins/proc/access_news_network() //MARKER /datum/admins/proc/access_news_network() //MARKER
set category = "Fun" set category = "Admin.Fun"
set name = "Access Newscaster Network" set name = "Access Newscaster Network"
set desc = "Allows you to view, add and edit news feeds." 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)]") 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! 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) /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 desc = "Edit mobs's memory and role"
set name = "Show Traitor Panel" set name = "Show Traitor Panel"

View File

@@ -6,7 +6,7 @@
/client/proc/investigate_show() /client/proc/investigate_show()
set name = "Investigate" set name = "Investigate"
set category = "Admin" set category = "Admin.Game"
if(!holder) if(!holder)
return 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_context, /*right-click adminPM interface*/
/client/proc/cmd_admin_pm_panel, /*admin-pm list*/ /client/proc/cmd_admin_pm_panel, /*admin-pm list*/
/client/proc/stop_sounds, /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_LIST_INIT(admin_verbs_admin, world.AVerbsAdmin())
GLOBAL_PROTECT(admin_verbs_admin) GLOBAL_PROTECT(admin_verbs_admin)
@@ -150,7 +150,8 @@ GLOBAL_PROTECT(admin_verbs_server)
/client/proc/toggle_hub, /client/proc/toggle_hub,
/client/proc/mentor_memo, // YOGS - something stupid about "Mentor memos" /client/proc/mentor_memo, // YOGS - something stupid about "Mentor memos"
///client/proc/dump_memory_usage, ///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_LIST_INIT(admin_verbs_debug, world.AVerbsDebug())
GLOBAL_PROTECT(admin_verbs_debug) GLOBAL_PROTECT(admin_verbs_debug)
@@ -191,7 +192,8 @@ GLOBAL_PROTECT(admin_verbs_debug)
/client/proc/cmd_display_overlay_log, /client/proc/cmd_display_overlay_log,
/client/proc/reload_configuration, /client/proc/reload_configuration,
/datum/admins/proc/create_or_modify_area, /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_LIST_INIT(admin_verbs_possess, list(/proc/possess, /proc/release))
GLOBAL_PROTECT(admin_verbs_possess) GLOBAL_PROTECT(admin_verbs_possess)
@@ -275,37 +277,37 @@ GLOBAL_PROTECT(admin_verbs_hideable)
control_freak = CONTROL_FREAK_SKIN | CONTROL_FREAK_MACROS control_freak = CONTROL_FREAK_SKIN | CONTROL_FREAK_MACROS
var/rights = holder.rank.rights var/rights = holder.rank.rights
verbs += GLOB.admin_verbs_default add_verb(src, GLOB.admin_verbs_default)
verbs += GLOB.mentor_verbs // yogs - give admins mentor verbs add_verb(src, GLOB.mentor_verbs) // yogs - give admins mentor verbs
if(rights & R_BUILDMODE) if(rights & R_BUILDMODE)
verbs += /client/proc/togglebuildmodeself add_verb(src, /client/proc/togglebuildmodeself)
if(rights & R_ADMIN) if(rights & R_ADMIN)
verbs += GLOB.admin_verbs_admin add_verb(src, GLOB.admin_verbs_admin)
if(rights & R_BAN) if(rights & R_BAN)
verbs += GLOB.admin_verbs_ban add_verb(src, GLOB.admin_verbs_ban)
if(rights & R_FUN) if(rights & R_FUN)
verbs += GLOB.admin_verbs_fun add_verb(src, GLOB.admin_verbs_fun)
if(rights & R_SERVER) if(rights & R_SERVER)
verbs += GLOB.admin_verbs_server add_verb(src, GLOB.admin_verbs_server)
if(rights & R_DEBUG) if(rights & R_DEBUG)
verbs += GLOB.admin_verbs_debug add_verb(src, GLOB.admin_verbs_debug)
if(rights & R_POSSESS) if(rights & R_POSSESS)
verbs += GLOB.admin_verbs_possess add_verb(src, GLOB.admin_verbs_possess)
if(rights & R_PERMISSIONS) if(rights & R_PERMISSIONS)
verbs += GLOB.admin_verbs_permissions add_verb(src, GLOB.admin_verbs_permissions)
if(rights & R_STEALTH) if(rights & R_STEALTH)
verbs += /client/proc/stealth add_verb(src, /client/proc/stealth)
if(rights & R_ADMIN) if(rights & R_ADMIN)
verbs += GLOB.admin_verbs_poll add_verb(src, GLOB.admin_verbs_poll)
if(rights & R_SOUNDS) if(rights & R_SOUNDS)
verbs += GLOB.admin_verbs_sounds add_verb(src, GLOB.admin_verbs_sounds)
if(CONFIG_GET(string/invoke_youtubedl)) if(CONFIG_GET(string/invoke_youtubedl))
verbs += /client/proc/play_web_sound add_verb(src, /client/proc/play_web_sound)
if(rights & R_SPAWN) if(rights & R_SPAWN)
verbs += GLOB.admin_verbs_spawn add_verb(src, GLOB.admin_verbs_spawn)
/client/proc/remove_admin_verbs() /client/proc/remove_admin_verbs()
verbs.Remove( remove_verb(src, list(
GLOB.admin_verbs_default, GLOB.admin_verbs_default,
/client/proc/togglebuildmodeself, /client/proc/togglebuildmodeself,
GLOB.admin_verbs_admin, GLOB.admin_verbs_admin,
@@ -324,14 +326,14 @@ GLOBAL_PROTECT(admin_verbs_hideable)
GLOB.admin_verbs_debug_mapping, GLOB.admin_verbs_debug_mapping,
/client/proc/disable_debug_verbs, /client/proc/disable_debug_verbs,
/client/proc/readmin /client/proc/readmin
) ))
/client/proc/hide_most_verbs()//Allows you to keep some functionality while hiding some verbs /client/proc/hide_most_verbs()//Allows you to keep some functionality while hiding some verbs
set name = "Adminverbs - Hide Most" set name = "Adminverbs - Hide Most"
set category = "Admin" set category = "Admin"
verbs.Remove(/client/proc/hide_most_verbs, GLOB.admin_verbs_hideable) 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) 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! 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" set category = "Admin"
remove_admin_verbs() 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) 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! 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 name = "Adminverbs - Show"
set category = "Admin" set category = "Admin"
verbs -= /client/proc/show_verbs remove_verb(src, /client/proc/show_verbs)
add_admin_verbs() add_admin_verbs()
to_chat(src, "<span class='interface'>All of your adminverbs are now visible.</span>", confidential=TRUE) 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() /client/proc/admin_ghost()
set category = "Admin" set category = "Admin.Game"
set name = "Aghost" set name = "Aghost"
if(!holder) if(!holder)
return return
@@ -387,13 +389,14 @@ GLOBAL_PROTECT(admin_verbs_hideable)
message_admins("[key_name_admin(usr)] admin ghosted.") message_admins("[key_name_admin(usr)] admin ghosted.")
var/mob/body = mob var/mob/body = mob
body.ghostize(1) body.ghostize(1)
init_verbs()
if(body && !body.key) if(body && !body.key)
body.key = "@[key]" //Haaaaaaaack. But the people have spoken. If it breaks; blame adminbus 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! 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() /client/proc/invisimin()
set name = "Invisimin" set name = "Invisimin"
set category = "Admin" set category = "Admin.Game"
set desc = "Toggles ghost-like invisibility (Don't abuse this)" set desc = "Toggles ghost-like invisibility (Don't abuse this)"
if(holder && mob) if(holder && mob)
if(mob.invisibility == INVISIBILITY_MAXIMUM) if(mob.invisibility == INVISIBILITY_MAXIMUM)
@@ -405,7 +408,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
/client/proc/check_antagonists() /client/proc/check_antagonists()
set name = "Check Antagonists" set name = "Check Antagonists"
set category = "Admin" set category = "Admin.Game"
if(holder) if(holder)
// yogs start // yogs start
log_admin("[key_name(usr)] checked antagonists.") //for tsar~ log_admin("[key_name(usr)] checked antagonists.") //for tsar~
@@ -459,14 +462,14 @@ GLOBAL_PROTECT(admin_verbs_hideable)
/client/proc/game_panel() /client/proc/game_panel()
set name = "Game Panel" set name = "Game Panel"
set category = "Admin" set category = "Admin.Game"
if(holder) if(holder)
holder.Game() 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! 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() /client/proc/secrets()
set name = "Secrets" set name = "Secrets"
set category = "Admin" set category = "Admin.Game"
if (holder) if (holder)
holder.Secrets() 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! 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! 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() /client/proc/drop_bomb()
set category = "Special Verbs" set category = "Admin.Fun"
set name = "Drop Bomb" set name = "Drop Bomb"
set desc = "Cause an explosion of varying strength at your location." 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! 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() /client/proc/drop_dynex_bomb()
set category = "Special Verbs" set category = "Admin.Fun"
set name = "Drop DynEx Bomb" set name = "Drop DynEx Bomb"
set desc = "Cause an explosion of varying strength at your location." 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]") message_admins("[key_name_admin(usr)] has modified Dynamic Explosion Scale: [ex_scale]")
/client/proc/give_spell(mob/T in GLOB.mob_list) /client/proc/give_spell(mob/T in GLOB.mob_list)
set category = "Fun" set category = "Admin.Fun"
set name = "Give Spell" set name = "Give Spell"
set desc = "Gives a spell to a mob." 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>") 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) /client/proc/remove_spell(mob/T in GLOB.mob_list)
set category = "Fun" set category = "Admin.Fun"
set name = "Remove Spell" set name = "Remove Spell"
set desc = "Remove a spell from the selected mob." 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! 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) /client/proc/give_disease(mob/living/T in GLOB.mob_living_list)
set category = "Fun" set category = "Admin.Fun"
set name = "Give Disease" set name = "Give Disease"
set desc = "Gives a Disease to a mob." set desc = "Gives a Disease to a mob."
if(!istype(T)) 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>") 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) /client/proc/object_say(obj/O in world)
set category = "Special Verbs" set category = "Admin.Fun"
set name = "OSay" set name = "OSay"
set desc = "Makes an object say something." set desc = "Makes an object say something."
var/message = input(usr, "What do you want the message to be?", "Make Sound") as text | null 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! 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() /client/proc/togglebuildmodeself()
set name = "Toggle Build Mode Self" set name = "Toggle Build Mode Self"
set category = "Special Verbs" set category = "Admin.Fun"
if (!(holder.rank.rights & R_BUILDMODE)) if (!(holder.rank.rights & R_BUILDMODE))
return return
if(src.mob) if(src.mob)
@@ -680,7 +683,8 @@ GLOBAL_PROTECT(admin_verbs_hideable)
/client/proc/check_ai_laws() /client/proc/check_ai_laws()
set name = "Check AI Laws" set name = "Check AI Laws"
set category = "Admin" set category = "Admin.Game"
if(holder) if(holder)
src.holder.output_ai_laws() src.holder.output_ai_laws()
@@ -703,15 +707,6 @@ GLOBAL_PROTECT(admin_verbs_hideable)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Deadmin") 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() /client/proc/readmin()
set name = "Readmin" set name = "Readmin"
@@ -774,7 +769,7 @@ GLOBAL_PROTECT(admin_verbs_hideable)
/client/proc/toggle_AI_interact() /client/proc/toggle_AI_interact()
set name = "Toggle Admin 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" set desc = "Allows you to interact with most machines as an AI would as a ghost"
AI_Interact = !AI_Interact 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>") to_chat(usr, "<span class='warning'>File creation failed. Please check to see if the data/logs/memory folder actually exists.</span>")
else else
to_chat(usr, "<span class='notice'>Memory dump completed.</span>")*/ 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() /datum/verbs/menu/Admin/verb/playerpanel()
set name = "Player Panel" set name = "Player Panel"
set desc = "Player Panel" set desc = "Player Panel"
set category = "Admin" set category = "Admin.Game"
if(usr.client.holder) if(usr.client.holder)
usr.client.holder.player_panel_new() 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! 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/deadmined
var/legacy_mc = FALSE
/datum/admins/New(datum/admin_rank/R, ckey, force_active = FALSE, protected) /datum/admins/New(datum/admin_rank/R, ckey, force_active = FALSE, protected)
if(IsAdminAdvancedProcCall()) if(IsAdminAdvancedProcCall())
@@ -93,7 +92,7 @@ GLOBAL_PROTECT(href_token)
var/client/C var/client/C
if ((C = owner) || (C = GLOB.directory[target])) if ((C = owner) || (C = GLOB.directory[target]))
disassociate() disassociate()
C.verbs += /client/proc/readmin add_verb(C, /client/proc/readmin)
/datum/admins/proc/associate(client/C) /datum/admins/proc/associate(client/C)
if(IsAdminAdvancedProcCall()) if(IsAdminAdvancedProcCall())
@@ -113,7 +112,8 @@ GLOBAL_PROTECT(href_token)
owner = C owner = C
owner.holder = src 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.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 GLOB.admins |= C
/datum/admins/proc/disassociate() /datum/admins/proc/disassociate()
@@ -125,6 +125,7 @@ GLOBAL_PROTECT(href_token)
if(owner) if(owner)
GLOB.admins -= owner GLOB.admins -= owner
owner.remove_admin_verbs() owner.remove_admin_verbs()
owner.init_verbs()
owner.holder = null owner.holder = null
owner = null owner = null

View File

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

View File

@@ -9,7 +9,9 @@
/datum/admins/proc/edit_admin_permissions(action, target, operation, page) /datum/admins/proc/edit_admin_permissions(action, target, operation, page)
if(!check_rights(R_PERMISSIONS)) if(!check_rights(R_PERMISSIONS))
return 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) 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'>" 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 else
@@ -91,7 +93,7 @@
output += {"<head> output += {"<head>
<meta charset='UTF-8'> <meta charset='UTF-8'>
<title>Permissions Panel</title> <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> </head>
<body onload='selectTextField();updateSearch();'> <body onload='selectTextField();updateSearch();'>
<div id='main'><table id='searchable' cellspacing='0'> <div id='main'><table id='searchable' cellspacing='0'>
@@ -136,7 +138,7 @@
if(IsAdminAdvancedProcCall()) if(IsAdminAdvancedProcCall())
to_chat(usr, "<span class='admin prefix'>Admin Edit blocked: Advanced ProcCall detected.</span>", confidential=TRUE) to_chat(usr, "<span class='admin prefix'>Admin Edit blocked: Advanced ProcCall detected.</span>", confidential=TRUE)
return 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) permissions_assets.send(src)
var/admin_key = href_list["key"] var/admin_key = href_list["key"]
var/admin_ckey = ckey(admin_key) var/admin_ckey = ckey(admin_key)

View File

@@ -505,7 +505,7 @@
alphatext = "filter: alpha(opacity=[alpha]); opacity: [alpha/100];" alphatext = "filter: alpha(opacity=[alpha]); opacity: [alpha/100];"
var/list/data = list("<div style='margin:0px;[alphatext]'><p class='severity'>") var/list/data = list("<div style='margin:0px;[alphatext]'><p class='severity'>")
if(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>" : ""]" data += "<b>[timestamp] | [server] | [admin_key][secret ? " | <i>- Secret</i>" : ""]"
if(expire_timestamp) if(expire_timestamp)
data += " | Expires [expire_timestamp]" data += " | Expires [expire_timestamp]"

View File

@@ -35,7 +35,7 @@
M.client.show_popup_menus = TRUE M.client.show_popup_menus = TRUE
M.client.show_verb_panel = TRUE M.client.show_verb_panel = TRUE
M.notransform = FALSE 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)]." message = "[key_name(usr)] has unfrozen [key_name(M)]."
else else
to_chat(M, "<span class='userdanger'>You have been frozen by an administrator.</span>") 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.client.show_verb_panel = FALSE
M.notransform = TRUE M.notransform = TRUE
M.client.afreeze_stored_verbs = M.verbs.Copy() 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)]." message = "[key_name(usr)] has frozen [key_name(M)]."
log_admin(message) log_admin(message)
message_admins(message) //yogs end 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) delete_click = new(null, "INITIALIZING", src)
if(!action_click) if(!action_click)
action_click = new(null, "INITIALIZNG", src) 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_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_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()]")) [islist(obj_count_finished)? length(obj_count_finished) : (isnull(obj_count_finished)? "0" : obj_count_finished)] - [get_query_text()]")]", REF(delete_click))
stat(" ", action_click.update("[SDQL2_IS_RUNNING? "HALT" : "RUN"]")) L[++L.len] = list(" ", "[action_click.update("[SDQL2_IS_RUNNING? "HALT" : "RUN"]")]", REF(action_click))
return L
/datum/SDQL2_query/proc/delete_click() /datum/SDQL2_query/proc/delete_click()
admin_del(usr) 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) return istype(thing, /datum) || istype(thing, /client)
/obj/effect/statclick/SDQL2_delete/Click() /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 var/datum/SDQL2_query/Q = target
Q.delete_click() Q.delete_click()
/obj/effect/statclick/SDQL2_action/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 var/datum/SDQL2_query/Q = target
Q.action_click() Q.action_click()
@@ -1207,4 +1217,8 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null
name = "VIEW VARIABLES" name = "VIEW VARIABLES"
/obj/effect/statclick/SDQL2_VV_all/Click() /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) 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 //Tickets statpanel
/datum/admin_help_tickets/proc/stat_entry() /datum/admin_help_tickets/proc/stat_entry()
SHOULD_CALL_PARENT(TRUE)
SHOULD_NOT_SLEEP(TRUE)
var/list/L = list()
var/num_disconnected = 0 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) for(var/I in active_tickets)
var/datum/admin_help/AH = I var/datum/admin_help/AH = I
if(AH.initiator) 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 else
++num_disconnected ++num_disconnected
if(num_disconnected) if(num_disconnected)
stat("Disconnected:", astatclick.update("[num_disconnected]")) L[++L.len] = list("Disconnected:", "[astatclick.update("[num_disconnected]")]", null, REF(astatclick))
stat("Closed Tickets:", cstatclick.update("[closed_tickets.len]")) L[++L.len] = list("Closed Tickets:", "[cstatclick.update("[closed_tickets.len]")]", null, REF(cstatclick))
stat("Resolved Tickets:", rstatclick.update("[resolved_tickets.len]")) L[++L.len] = list("Resolved Tickets:", "[rstatclick.update("[resolved_tickets.len]")]", null, REF(rstatclick))
return L
//Reassociate still open ticket if one exists //Reassociate still open ticket if one exists
/datum/admin_help_tickets/proc/ClientLogin(client/C) /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() /obj/effect/statclick/ticket_list/Click()
GLOB.ahelp_tickets.BrowseTickets(current_state) GLOB.ahelp_tickets.BrowseTickets(current_state)
//called by admin topic
/obj/effect/statclick/ticket_list/proc/Action()
Click()
// //
//TICKET DATUM //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 //Removes the ahelp verb and returns it after 2 minutes
/datum/admin_help/proc/TimeoutVerb() /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 initiator.adminhelptimerid = addtimer(CALLBACK(initiator, /client/proc/giveadminhelpverb), 1200, TIMER_STOPPABLE) //2 minute cooldown of admin helps
//private //private
@@ -267,10 +276,16 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
if(X.prefs.toggles & SOUND_ADMINHELP) if(X.prefs.toggles & SOUND_ADMINHELP)
SEND_SOUND(X, sound('sound/effects/adminhelp.ogg')) SEND_SOUND(X, sound('sound/effects/adminhelp.ogg'))
window_flash(X, ignorepref = TRUE) 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 //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 //Reopen a closed ticket
/datum/admin_help/proc/Reopen() /datum/admin_help/proc/Reopen()
@@ -473,7 +488,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
// //
/client/proc/giveadminhelpverb() /client/proc/giveadminhelpverb()
src.verbs |= /client/verb/adminhelp add_verb(src, /client/verb/adminhelp)
deltimer(adminhelptimerid) deltimer(adminhelptimerid)
adminhelptimerid = 0 adminhelptimerid = 0

View File

@@ -1,7 +1,7 @@
/client/proc/jumptoarea(area/A in GLOB.sortedAreas) /client/proc/jumptoarea(area/A in GLOB.sortedAreas)
set name = "Jump to Area" set name = "Jump to Area"
set desc = "Area to jump to" set desc = "Area to jump to"
set category = "Admin" set category = "Admin.Game"
if(!src.holder) if(!src.holder)
to_chat(src, "Only administrators may use this command.", confidential=TRUE) to_chat(src, "Only administrators may use this command.", confidential=TRUE)
return return
@@ -26,7 +26,7 @@
/client/proc/jumptoturf(turf/T in world) /client/proc/jumptoturf(turf/T in world)
set name = "Jump to Turf" set name = "Jump to Turf"
set category = "Admin" set category = "Admin.Game"
if(!src.holder) if(!src.holder)
to_chat(src, "Only administrators may use this command.", confidential=TRUE) to_chat(src, "Only administrators may use this command.", confidential=TRUE)
return return
@@ -38,7 +38,7 @@
return return
/client/proc/jumptomob(mob/M in GLOB.mob_list) /client/proc/jumptomob(mob/M in GLOB.mob_list)
set category = "Admin" set category = "Admin.Game"
set name = "Jump to Mob" set name = "Jump to Mob"
if(!src.holder) if(!src.holder)
@@ -57,7 +57,7 @@
to_chat(A, "This mob is not located in the game world.") to_chat(A, "This mob is not located in the game world.")
/client/proc/jumptocoord(tx as num, ty as num, tz as num) /client/proc/jumptocoord(tx as num, ty as num, tz as num)
set category = "Admin" set category = "Admin.Game"
set name = "Jump to Coordinate" set name = "Jump to Coordinate"
if (!holder) if (!holder)
@@ -72,7 +72,7 @@
message_admins("[key_name_admin(usr)] jumped to coordinates [tx], [ty], [tz]") message_admins("[key_name_admin(usr)] jumped to coordinates [tx], [ty], [tz]")
/client/proc/jumptokey() /client/proc/jumptokey()
set category = "Admin" set category = "Admin.Game"
set name = "Jump to Key" set name = "Jump to Key"
if(!src.holder) 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! 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) /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 name = "Get Mob"
set desc = "Mob to teleport" set desc = "Mob to teleport"
if(!src.holder) 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! 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() /client/proc/Getkey()
set category = "Admin" set category = "Admin.Game"
set name = "Get Key" set name = "Get Key"
set desc = "Key to teleport" 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! 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()) /client/proc/sendmob(mob/M in sortmobs())
set category = "Admin" set category = "Admin.Game"
set name = "Send Mob" set name = "Send Mob"
if(!src.holder) if(!src.holder)
to_chat(src, "Only administrators may use this command.", confidential=TRUE) to_chat(src, "Only administrators may use this command.", confidential=TRUE)

View File

@@ -6,7 +6,10 @@
set category = null set category = null
set name = "Admin PM Mob" set name = "Admin PM Mob"
if(!holder) 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 return
if(!ismob(M)) //yogs start if(!ismob(M)) //yogs start
return return
@@ -23,7 +26,10 @@
set category = "Admin" set category = "Admin"
set name = "Admin PM" set name = "Admin PM"
if(!holder) 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 return
var/list/client/targets[0] var/list/client/targets[0]
for(var/client/T) for(var/client/T)
@@ -42,7 +48,10 @@
/client/proc/cmd_ahelp_reply(whom) /client/proc/cmd_ahelp_reply(whom)
if(prefs.muted & MUTE_ADMINHELP) 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 return
var/client/C var/client/C
if(istext(whom)) if(istext(whom))
@@ -53,7 +62,10 @@
C = whom C = whom
if(!C) if(!C)
if(holder) 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 return
var/datum/admin_help/AH = C.current_ticket 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 //Fetching a message if needed. src is the sender and C is the target client
/client/proc/cmd_admin_pm(whom, msg) /client/proc/cmd_admin_pm(whom, msg)
if(prefs.muted & MUTE_ADMINHELP) 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 return
if(!holder && !current_ticket) //no ticket? https://www.youtube.com/watch?v=iHSPf6x1Fdo 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 return
var/client/recipient var/client/recipient
@@ -100,7 +125,10 @@
if(!msg) if(!msg)
return return
if(holder) 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 return
@@ -128,7 +156,10 @@
if(!recipient) if(!recipient)
if(holder) 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 else
current_ticket.MessageNoRecipient(msg) current_ticket.MessageNoRecipient(msg)
return return
@@ -157,12 +188,18 @@
else else
if(recipient.holder) if(recipient.holder)
if(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(recipient,
to_chat(src, "<span class='notice'>Admin PM to-<b>[key_name(recipient, src, 1)]</b>: <span class='linkify'>[keywordparsedmsg]</span></span>", confidential=TRUE) 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 //omg this is dumb, just fill in both their tickets
// yogs start - Yog 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) if(recipient.current_ticket && !recipient.current_ticket.handling_admin)
recipient.current_ticket.Administer(src) recipient.current_ticket.Administer(src)
// yogs end - Yog Tickets // 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(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) to_chat(src, "<span class='notice'>-- [key_name(src, null, 0)] -> <b>Admins</b>: <span class='linkify'>[msg]</span></span>", confidential=TRUE)
//YOGS END //YOGS END
//play the receiving admin the adminhelp sound (if they have them enabled) //play the receiving admin the adminhelp sound (if they have them enabled)
if(recipient.prefs.toggles & SOUND_ADMINHELP) if(recipient.prefs.toggles & SOUND_ADMINHELP)
SEND_SOUND(recipient, sound('sound/effects/adminhelp.ogg')) SEND_SOUND(recipient, sound('sound/effects/adminhelp.ogg'))
@@ -214,20 +251,29 @@
return return
else //neither are admins 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 return
if(irc) if(irc)
log_admin_private("PM: [key_name(src)]->IRC: [rawmsg]") log_admin_private("PM: [key_name(src)]->IRC: [rawmsg]")
for(var/client/X in GLOB.admins) 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 else
window_flash(recipient, ignorepref = TRUE) window_flash(recipient, ignorepref = TRUE)
log_admin_private("PM: [key_name(src)]->[key_name(recipient)]: [rawmsg]") 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 //we don't use message_admins here because the sender/receiver might get it too
for(var/client/X in GLOB.admins) 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 if(X.key!=key && X.key!=recipient.key) //check client/X is an admin and isn't the sender or recipientD
to_chat(X, "<span class='notice'><B>PM: [key_name(src, X, 0)]-&gt;[key_name(recipient, X, 0)]:</B> [keywordparsedmsg]</span>" , confidential=TRUE) 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]") log_admin_private("IRC PM: [sender] -> [key_name(C)] : [msg]")
msg = emoji_parse(msg) msg = emoji_parse(msg)
to_chat(C, "<font color='red' size='4'><b>-- Administrator private message --</b></font>", confidential=TRUE) to_chat(C,
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 type = MESSAGE_TYPE_ADMINPM,
to_chat(C, "<span class='danger'><i>Click on the administrator's name to reply.</i></span>", confidential=TRUE) // yogs - Yog Tickets 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 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) /client/proc/cmd_admin_say(msg as text)
set category = "Special Verbs" 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 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)) if(!check_rights(0))
return return
msg = to_utf8(msg, src) msg = to_utf8(msg, src)
@@ -15,7 +15,10 @@
msg = keywords_lookup(msg) msg = keywords_lookup(msg)
var/custom_asay_color = (CONFIG_GET(flag/allow_admin_asaycolor) && prefs.asaycolor) ? "<font color=[prefs.asaycolor]>" : null // Yogs -- yogs asay 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]" 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! 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 return container
/datum/admins/proc/beaker_panel() /datum/admins/proc/beaker_panel()
set category = "Debug" set category = "Admin.Fun"
set name = "Spawn reagent container" set name = "Spawn reagent container"
if(!check_rights()) if(!check_rights())
return 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 = {" var/dat = {"
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html> <html>
@@ -73,7 +75,7 @@
<meta http-equiv="Content-Type" content="text/html"> <meta http-equiv="Content-Type" content="text/html">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta charset='UTF-8'> <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/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> <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"> <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) /datum/admins/proc/open_borgopanel(borgo in GLOB.silicon_mobs)
set category = "Admin" set category = "Admin.Game"
set name = "Show Borg Panel" set name = "Show Borg Panel"
set desc = "Show borg panel" set desc = "Show borg panel"
@@ -202,7 +202,7 @@
borg.notify_ai(DISCONNECT) borg.notify_ai(DISCONNECT)
if(borg.shell) if(borg.shell)
borg.undeploy() borg.undeploy()
borg.connected_ai = newai borg.set_connected_ai(newai)
borg.notify_ai(TRUE) borg.notify_ai(TRUE)
message_admins("[key_name_admin(user)] slaved [ADMIN_LOOKUPFLW(borg)] to the AI [ADMIN_LOOKUPFLW(newai)].") 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)].") log_admin("[key_name(user)] slaved [key_name(borg)] to the AI [key_name(newai)].")
@@ -210,7 +210,7 @@
borg.notify_ai(DISCONNECT) borg.notify_ai(DISCONNECT)
if(borg.shell) if(borg.shell)
borg.undeploy() 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.") 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.") log_admin("[key_name(user)] freed [key_name(borg)] from being slaved to an AI.")
if (borg.lawupdate) if (borg.lawupdate)

View File

@@ -1,8 +1,8 @@
/client/proc/cinematic() /client/proc/cinematic()
set name = "cinematic" set name = "Cinematic"
set category = "Fun" 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 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) if(!SSticker)
return return

View File

@@ -1,7 +1,7 @@
/client/proc/dsay(msg as text) /client/proc/dsay(msg as text)
set category = "Special Verbs" set category = "Admin.Game"
set name = "Dsay" set name = "Dsay"
set hidden = 1 set hidden = TRUE
if(!holder) if(!holder)
to_chat(src, "Only administrators may use this command.", confidential=TRUE) to_chat(src, "Only administrators may use this command.", confidential=TRUE)
return 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! 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) /client/proc/cmd_admin_robotize(mob/M in GLOB.mob_list)
set category = "Fun" set category = "Admin.Fun"
set name = "Make Robot" set name = "Make Robot"
if(!SSticker.HasRoundStarted()) if(!SSticker.HasRoundStarted())
@@ -252,7 +252,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
alert("Invalid mob") alert("Invalid mob")
/client/proc/cmd_admin_blobize(mob/M in GLOB.mob_list) /client/proc/cmd_admin_blobize(mob/M in GLOB.mob_list)
set category = "Fun" set category = "Admin.Fun"
set name = "Make Blob" set name = "Make Blob"
if(!SSticker.HasRoundStarted()) if(!SSticker.HasRoundStarted())
@@ -267,7 +267,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
/client/proc/cmd_admin_animalize(mob/M in GLOB.mob_list) /client/proc/cmd_admin_animalize(mob/M in GLOB.mob_list)
set category = "Fun" set category = "Admin.Fun"
set name = "Make Simple Animal" set name = "Make Simple Animal"
if(!SSticker.HasRoundStarted()) if(!SSticker.HasRoundStarted())
@@ -288,7 +288,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
/client/proc/makepAI(turf/T in GLOB.mob_list) /client/proc/makepAI(turf/T in GLOB.mob_list)
set category = "Fun" set category = "Admin.Fun"
set name = "Make pAI" set name = "Make pAI"
set desc = "Specify a location to spawn a pAI device, then specify a key to play that 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! 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) /client/proc/cmd_admin_alienize(mob/M in GLOB.mob_list)
set category = "Fun" set category = "Admin.Fun"
set name = "Make Alien" set name = "Make Alien"
if(!SSticker.HasRoundStarted()) if(!SSticker.HasRoundStarted())
@@ -330,7 +330,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
alert("Invalid mob") alert("Invalid mob")
/client/proc/cmd_admin_slimeize(mob/M in GLOB.mob_list) /client/proc/cmd_admin_slimeize(mob/M in GLOB.mob_list)
set category = "Fun" set category = "Admin.Fun"
set name = "Make slime" set name = "Make slime"
if(!SSticker.HasRoundStarted()) 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>") 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) /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 name = "Assume direct control"
set desc = "Direct intervention" set desc = "Direct intervention"
@@ -729,7 +729,8 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
cmd_admin_areatest(FALSE) cmd_admin_areatest(FALSE)
/client/proc/cmd_admin_dress(mob/M in GLOB.mob_list) /client/proc/cmd_admin_dress(mob/M in GLOB.mob_list)
set category = "Fun" set category = "Admin.Fun"
set name = "Select equipment" set name = "Select equipment"
if(!(ishuman(M) || isobserver(M))) if(!(ishuman(M) || isobserver(M)))
alert("Invalid mob") alert("Invalid mob")

View File

@@ -111,3 +111,32 @@
load_mentors() 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! 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") 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" set name = "Debug verbs - Enable"
if(!check_rights(R_DEBUG)) if(!check_rights(R_DEBUG))
return return
verbs -= /client/proc/enable_debug_verbs remove_verb(src, /client/proc/enable_debug_verbs)
verbs.Add(/client/proc/disable_debug_verbs, GLOB.admin_verbs_debug_mapping) 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! 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() /client/proc/disable_debug_verbs()
set category = "Debug" set category = "Debug"
set name = "Debug verbs - Disable" set name = "Debug verbs - Disable"
verbs.Remove(/client/proc/disable_debug_verbs, GLOB.admin_verbs_debug_mapping) remove_verb(src, list(/client/proc/disable_debug_verbs, GLOB.admin_verbs_debug_mapping))
verbs += /client/proc/enable_debug_verbs 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! 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() /client/proc/count_objects_on_z_level()

View File

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

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