////////////
//SECURITY//
////////////
//debugging, uncomment for viewing topic calls
//#define TOPIC_DEBUGGING 1
#define TOPIC_SPAM_DELAY 2 //2 ticks is about 2/10ths of a second; it was 4 ticks, but that caused too many clicks to be lost due to lag
#define UPLOAD_LIMIT 10485760 //Restricts client uploads to the server to 10MB //Boosted this thing. What's the worst that can happen?
#define MIN_CLIENT_VERSION 0 //Just an ambiguously low version for now, I don't want to suddenly stop people playing.
//I would just like the code ready should it ever need to be used.
#define SUGGESTED_CLIENT_VERSION 510 // only integers (e.g: 510, 511) useful here. Does not properly handle minor versions (e.g: 510.58, 511.848)
/*
When somebody clicks a link in game, this Topic is called first.
It does the stuff in this proc and then is redirected to the Topic() proc for the src=[0xWhatever]
(if specified in the link). ie locate(hsrc).Topic()
Such links can be spoofed.
Because of this certain things MUST be considered whenever adding a Topic() for something:
- Can it be fed harmful values which could cause runtimes?
- Is the Topic call an admin-only thing?
- If so, does it have checks to see if the person who called it (usr.client) is an admin?
- Are the processes being called by Topic() particularly laggy?
- If so, is there any protection against somebody spam-clicking a link?
If you have any questions about this stuff feel free to ask. ~Carn
*/
/client/Topic(href, href_list, hsrc)
if(!usr || usr != mob) //stops us calling Topic for somebody else's client. Also helps prevent usr=null
return
// src should always be a UID; if it isn't, warn instead of failing entirely
if(href_list["src"])
hsrc = locateUID(href_list["src"])
// If there's a ]_ in the src, it's a UID, so don't try to locate it
if(!hsrc && !findtext(href_list["src"], "]_"))
hsrc = locate(href_list["src"])
if(hsrc)
var/hsrc_info = datum_info_line(hsrc) || "[hsrc]"
log_runtime(EXCEPTION("Got \\ref-based src in topic from [src] for [hsrc_info], should be UID: [href]"))
#if defined(TOPIC_DEBUGGING)
to_chat(world, "[src]'s Topic: [href] destined for [hsrc].")
#endif
if(href_list["nano_err"]) //nano throwing errors
if(topic_debugging)
to_chat(src, "## NanoUI: " + html_decode(href_list["nano_err"]))//NANO DEBUG HOOK
if(href_list["asset_cache_confirm_arrival"])
// to_chat(src, "ASSET JOB [href_list["asset_cache_confirm_arrival"]] ARRIVED.")
var/job = text2num(href_list["asset_cache_confirm_arrival"])
completed_asset_jobs += job
return
if(href_list["_src_"] == "chat")
return chatOutput.Topic(href, href_list)
//Reduces spamming of links by dropping calls that happen during the delay period
if(next_allowed_topic_time > world.time)
return
next_allowed_topic_time = world.time + TOPIC_SPAM_DELAY
//search the href for script injection
if( findtext(href,"",
"border=0;titlebar=0;size=1x1")
to_chat(src, "You will be automatically taken to the game, if not, click here to be taken manually. Except you can't, since the chat window doesn't exist yet.")
//checks if a client is afk
//3000 frames = 5 minutes
/client/proc/is_afk(duration=3000)
if(inactivity > duration) return inactivity
return 0
//Send resources to the client.
/client/proc/send_resources()
// Most assets are now handled through global_cache.dm
getFiles(
'html/search.js', // Used in various non-NanoUI HTML windows for search functionality
'html/panels.css' // Used for styling certain panels, such as in the new player panel
)
spawn (10)
//Precache the client with all other assets slowly, so as to not block other browse() calls
getFilesSlow(src, asset_cache, register_asset = FALSE)
//For debugging purposes
/client/proc/list_all_languages()
for(var/L in all_languages)
var/datum/language/lang = all_languages[L]
var/message = "[lang.name] : [lang.type]"
if(lang.flags & RESTRICTED)
message += " (RESTRICTED)"
to_chat(world, "[message]")
/client/proc/colour_transition(var/list/colour_to = null, var/time = 10) //Call this with no parameters to reset to default.
animate(src, color=colour_to, time=time, easing=SINE_EASING)
/client/proc/on_varedit()
var_edited = TRUE