diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index 3a74ae4e3bb..c0efebaa459 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -1100,14 +1100,19 @@ GLOBAL_LIST_INIT(freon_color_matrix, list("#2E5E69", "#60A2A8", "#A1AFB1", rgb(0 obj_flags &= ~FROZEN -//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. -// (This relies on byond automatically storing icons in savefiles as base64) -/proc/icon2base64(icon/icon, iconKey = "misc") +/// 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 + +/** + * 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. + * (This relies on byond automatically storing icons in savefiles as base64) + */ +/proc/icon2base64(icon/icon) if (!isicon(icon)) return FALSE - WRITE_FILE(GLOB.iconCache[iconKey], icon) - var/iconData = GLOB.iconCache.ExportText(iconKey) + WRITE_FILE(GLOB.dummySave["dummy"], icon) + var/iconData = GLOB.dummySave.ExportText("dummy") var/list/partial = splittext(iconData, "{") return replacetext(copytext_char(partial[2], 3, -5), "\n", "") @@ -1193,7 +1198,7 @@ GLOBAL_LIST_INIT(freon_color_matrix, list("#2E5E69", "#60A2A8", "#A1AFB1", rgb(0 I = icon() I.Insert(temp, dir = SOUTH) - bicon_cache[key] = icon2base64(I, key) + bicon_cache[key] = icon2base64(I) return "" diff --git a/code/modules/goonchat/browserOutput.dm b/code/modules/goonchat/browserOutput.dm index de3456cbdea..e9194f1b553 100644 --- a/code/modules/goonchat/browserOutput.dm +++ b/code/modules/goonchat/browserOutput.dm @@ -2,23 +2,26 @@ For the main html chat area *********************************/ -//Precaching a bunch of shit -GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of icons for the browser output - -//Should match the value set in the browser js +/// Should match the value set in the browser js #define MAX_COOKIE_LENGTH 5 -//On client, created on login +/** + * The chatOutput datum exists to handle the goonchat browser. + * On client, created on Client/New() + */ /datum/chatOutput - var/client/owner //client ref - // How many times client data has been checked + /// The client that owns us. + var/client/owner + /// How many times client data has been checked var/total_checks = 0 - // When to next clear the client data checks counter + /// When to next clear the client data checks counter var/next_time_to_clear = 0 - var/loaded = FALSE // Has the client loaded the browser output area? - var/list/messageQueue //If they haven't loaded chat, this is where messages will go until they do - var/cookieSent = FALSE // Has the client sent a cookie for analysis - var/broken = FALSE + /// Has the client loaded the browser output area? + var/loaded = FALSE + /// If they haven't loaded chat, this is where messages will go until they do + var/list/messageQueue + var/cookieSent = FALSE // Has the client sent a cookie for analysis + var/broken = FALSE var/list/connectionHistory //Contains the connection history passed from chat cookie var/adminMusicVolume = 25 //This is for the Play Global Sound verb @@ -27,13 +30,18 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico messageQueue = list() connectionHistory = list() +/** + * start: Tries to load the chat browser + * Aborts if a problem is encountered. + * Async because this is called from Client/New. + */ /datum/chatOutput/proc/start() + set waitfor = FALSE //Check for existing chat if(!owner) return FALSE if(!winexists(owner, "browseroutput")) // Oh goddamnit. - set waitfor = FALSE broken = TRUE message_admins("Couldn't start chat for [key_name_admin(owner)]!") . = FALSE @@ -48,6 +56,7 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico return TRUE +/// Loads goonchat and sends assets. /datum/chatOutput/proc/load() set waitfor = FALSE if(!owner) @@ -58,6 +67,7 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico owner << browse(file('code/modules/goonchat/browserassets/html/browserOutput.html'), "window=browseroutput") +/// Interprets input from the client. Will send data back if required. /datum/chatOutput/Topic(href, list/href_list) if(usr.client != owner) return TRUE @@ -97,7 +107,7 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico ehjax_send(data = data) -//Called on chat output done-loading by JS. +/// Called on chat output done-loading by JS. /datum/chatOutput/proc/doneLoading() if(loaded) return @@ -119,10 +129,12 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico //do not convert to to_chat() SEND_TEXT(owner, "Failed to load fancy chat, reverting to old chat. Certain features won't work.") +/// Hides the standard output and makes the browser visible. /datum/chatOutput/proc/showChat() winset(owner, "output", "is-visible=false") winset(owner, "browseroutput", "is-disabled=false;is-visible=true") +/// Calls syncRegex on all currently owned chatOutput datums /proc/syncChatRegexes() for (var/user in GLOB.clients) var/client/C = user @@ -130,6 +142,7 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico if (Cchat && !Cchat.broken && Cchat.loaded) Cchat.syncRegex() +/// Used to dynamically add regexes to the browser output. Currently only used by the IC filter. /datum/chatOutput/proc/syncRegex() var/list/regexes = list() @@ -143,11 +156,21 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico if (regexes.len) ehjax_send(data = list("syncRegex" = regexes)) +/// Sends json encoded data to the browser. /datum/chatOutput/proc/ehjax_send(client/C = owner, window = "browseroutput", data) if(islist(data)) data = json_encode(data) C << output("[data]", "[window]:ehjaxCallback") +/** + * Sends music data to the browser. If enabled by the browser, it will start playing. + * Arguments: + * music must be a https adress. + * extra_data is a list. The keys "pitch", "start" and "end" are used. + ** "pitch" determines the playback rate + ** "start" determines the start time of the sound + ** "end" determines when the musics stops playing + */ /datum/chatOutput/proc/sendMusic(music, list/extra_data) if(!findtext(music, GLOB.is_http_protocol)) return @@ -160,14 +183,16 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico ehjax_send(data = music_data) +/// Stops music playing throw the browser. /datum/chatOutput/proc/stopMusic() ehjax_send(data = "stopMusic") +/// Setter for adminMusicVolume. Sanitizes the value to between 0 and 100. /datum/chatOutput/proc/setMusicVolume(volume = "") if(volume) adminMusicVolume = clamp(text2num(volume), 0, 100) -//Sends client connection details to the chat to handle and save +/// Sends client connection details to the chat to handle and save /datum/chatOutput/proc/sendClientData() //Get dem deets var/list/deets = list("clientData" = list()) @@ -177,7 +202,7 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico var/data = json_encode(deets) ehjax_send(data = data) -//Called by client, sent data to investigate (cookie history so far) +/// Called by client, sent data to investigate (cookie history so far) /datum/chatOutput/proc/analyzeClientData(cookie = "") //Spam check if(world.time > next_time_to_clear) @@ -224,15 +249,15 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico cookieSent = TRUE -//Called by js client every 60 seconds +/// Called by js client every 60 seconds /datum/chatOutput/proc/ping() return "pong" -//Called by js client on js error +/// Called by js client on js error /datum/chatOutput/proc/debug(error) log_world("\[[time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")]\] Client: [(src.owner.key ? src.owner.key : src.owner)] triggered JS error: [error]") -//Global chat procs +/// Global chat proc. to_chat_immediate will circumvent SSchat and send data as soon as possible. /proc/to_chat_immediate(target, message, handle_whitespace = TRUE, trailing_newline = TRUE, confidential = FALSE) if(!target || !message) return @@ -288,15 +313,18 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico // url_encode it TWICE, this way any UTF-8 characters are able to be decoded by the Javascript. C << output(url_encode(url_encode(message)), "browseroutput:output") +/// Sends a text message to the target. /proc/to_chat(target, message, handle_whitespace = TRUE, trailing_newline = TRUE, confidential = FALSE) if(Master.current_runlevel == RUNLEVEL_INIT || !SSchat?.initialized) to_chat_immediate(target, message, handle_whitespace, trailing_newline, confidential) return SSchat.queue(target, message, handle_whitespace, trailing_newline, confidential) -/datum/chatOutput/proc/swaptolightmode() //Dark mode light mode stuff. Yell at KMC if this breaks! (See darkmode.dm for documentation) +/// Dark mode light mode stuff. Yell at KMC if this breaks! (See darkmode.dm for documentation) +/datum/chatOutput/proc/swaptolightmode() owner.force_white_theme() +/// Light mode stuff. (See darkmode.dm for documentation) /datum/chatOutput/proc/swaptodarkmode() owner.force_dark_theme()