removes fun

This commit is contained in:
Letter N
2020-07-08 15:10:49 +08:00
parent bfa54f7e23
commit 45a3c47608
4 changed files with 381 additions and 265 deletions
+100 -44
View File
@@ -2,18 +2,30 @@
For the main html chat area
*********************************/
//Precaching a bunch of shit
/// Should match the value set in the browser js
#define MAX_COOKIE_LENGTH 5
//Precaching a bunch of shit. Someone ship this out of here
GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of icons for the browser output
//On client, created on login
//lazy renaming to chat_output, instead renamed to old chatOutput
/**
* The chatOutput datum exists to handle the goonchat browser.
* On client, created on Client/New()
*/
/datum/chatOutput
var/client/owner //client ref
/// The client that owns us.
var/client/owner
/// How many times client data has been checked
var/total_checks = 0
var/last_check = 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
/// When to next clear the client data checks counter
var/next_time_to_clear = 0
/// 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
@@ -22,13 +34,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
@@ -43,6 +60,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)
@@ -53,6 +71,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
@@ -83,20 +102,22 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico
if("setMusicVolume")
data = setMusicVolume(arglist(params))
if("colorPresetPost") //User just swapped color presets in their goonchat preferences. Do we do anything else?
switch(href_list["preset"])
if("light")
owner.force_white_theme()
if("dark" || "normal")
owner.force_dark_theme()
// if("swaptodarkmode")
// swaptodarkmode()
// if("swaptolightmode")
// swaptolightmode()
if(data)
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
@@ -113,34 +134,75 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico
messageQueue = null
sendClientData()
syncRegex()
//do not convert to to_chat()
SEND_TEXT(owner, "<span class=\"userdanger\">Failed to load fancy chat, reverting to old chat. Certain features won't work.</span>")
/// 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
var/datum/chatOutput/Cchat = C.chatOutput
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()
if (config.ic_filter_regex)
regexes["show_filtered_ic_chat"] = list(
config.ic_filter_regex.name,
"ig",
"<span class='boldwarning'>$1</span>"
)
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")
/datum/chatOutput/proc/sendMusic(music, pitch)
/**
* 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, pitch, list/extra_data) //someone remove pitch
if(!findtext(music, GLOB.is_http_protocol))
return
var/list/music_data = list("adminMusic" = url_encode(url_encode(music)))
if(pitch)
music_data["musicRate"] = pitch
if(extra_data?.len)
music_data["musicRate"] = extra_data["pitch"] || pitch
music_data["musicSeek"] = extra_data["start"]
music_data["musicHalt"] = extra_data["end"]
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())
@@ -150,11 +212,11 @@ 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 > last_check + (3 SECONDS))
last_check = world.time
if(world.time > next_time_to_clear)
next_time_to_clear = world.time + (3 SECONDS)
total_checks = 0
total_checks += 1
@@ -172,12 +234,13 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico
if (connData && islist(connData) && connData.len > 0 && connData["connData"])
connectionHistory = connData["connData"] //lol fuck
var/list/found = new()
if(connectionHistory.len > 5)
if(connectionHistory.len > MAX_COOKIE_LENGTH)
message_admins("[key_name(src.owner)] was kicked for an invalid ban cookie)")
qdel(owner)
return
for(var/i in min(connectionHistory.len, 5) to 1 step -1)
for(var/i in connectionHistory.len to 1 step -1)
if(QDELETED(owner))
//he got cleaned up before we were done
return
@@ -191,45 +254,33 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico
//Uh oh this fucker has a history of playing on a banned account!!
if (found.len > 0)
//TODO: add a new evasion ban for the CURRENT client details, using the matched row details
message_admins("[key_name(src.owner)] has a cookie from a banned account! (Matched: [found["ckey"]], [found["ip"]], [found["compid"]])")
log_admin_private("[key_name(owner)] has a cookie from a banned account! (Matched: [found["ckey"]], [found["ip"]], [found["compid"]])")
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
/proc/to_chat_immediate(target, message, handle_whitespace=TRUE)
/// 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
//Ok so I did my best but I accept that some calls to this will be for shit like sound and images
//It stands that we PROBABLY don't want to output those to the browser output so just handle them here
if (istype(target, /savefile))
CRASH("Invalid message! [message]")
if(!istext(message))
if (istype(message, /image) || istype(message, /sound))
CRASH("Invalid message! [message]")
return
if(target == world)
target = GLOB.clients
var/original_message = message
//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 = replacetext(message, "\t", "[FOURSPACES][FOURSPACES]") //EIGHT SPACES IN TOTAL!!
if(trailing_newline)
message += "<br>"
if(islist(target))
// Do the double-encoding outside the loop to save nanoseconds
@@ -272,14 +323,19 @@ 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")
/proc/to_chat(target, message, handle_whitespace = TRUE)
/// 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)
to_chat_immediate(target, message, handle_whitespace, trailing_newline, confidential)
return
SSchat.queue(target, message, handle_whitespace)
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()
#undef MAX_COOKIE_LENGTH