diff --git a/code/__HELPERS/stacktrace.dm b/code/__HELPERS/stacktrace.dm new file mode 100644 index 00000000000..66cd8ba75d0 --- /dev/null +++ b/code/__HELPERS/stacktrace.dm @@ -0,0 +1,14 @@ +// This file should contain only these two procs in order to make logging filtering easier +// DO NOT ADD ANYTHING ELSE TO THIS FILE FOR THE LOVE OF GOD +// DONT EVEN EXPAN THIS COMMENT, KEEP THE LINE NUMBERS THE SAME +// (The whitespace after this is for line consistency) + + + + + +/proc/stack_trace(msg) + CRASH(msg) + +/datum/proc/stack_trace(msg) + CRASH(msg) diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index 7ce8d987722..8d304d8729f 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -411,7 +411,7 @@ var/index = findtext(text, char) var/keylength = length(char) while(index) - log_runtime(EXCEPTION("Bad string given to dmm encoder! [text]")) + stack_trace("Bad string given to dmm encoder! [text]") // Replace w/ underscore to prevent "{4;" from cheesing the radar // Should probably also use canon text replacing procs text = copytext(text, 1, index) + "_" + copytext(text, index+keylength) diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm index a4b6f7cebfe..410cbf6ba25 100644 --- a/code/__HELPERS/type2type.dm +++ b/code/__HELPERS/type2type.dm @@ -100,7 +100,7 @@ if(4.0) return EAST if(8.0) return WEST else - log_runtime(EXCEPTION("UNKNOWN DIRECTION: [direction]")) + stack_trace("UNKNOWN DIRECTION: [direction]") /proc/dir2text(direction) switch(direction) diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 954f9a4ec1a..a84489de1af 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1923,13 +1923,6 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) continue . += A -//gives us the stack trace from CRASH() without ending the current proc. -/proc/stack_trace(msg) - CRASH(msg) - -/datum/proc/stack_trace(msg) - CRASH(msg) - /proc/pass() return diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index a7000f0c760..a06f28c0db3 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -544,7 +544,7 @@ else if(isclient(D)) var/client/C = D href_list[paramname] = C.UID() - log_runtime(EXCEPTION("Found \\ref-based '[paramname]' param in VV topic for [datuminfo], should be UID: [href]")) + stack_trace("Found \\ref-based '[paramname]' param in VV topic for [datuminfo], should be UID: [href]") if(href_list["Vars"]) debug_variables(locateUID(href_list["Vars"])) diff --git a/code/datums/helper_datums/map_template.dm b/code/datums/helper_datums/map_template.dm index 3b942850108..01d01dd1423 100644 --- a/code/datums/helper_datums/map_template.dm +++ b/code/datums/helper_datums/map_template.dm @@ -55,10 +55,10 @@ if(!bounds) return 0 if(bot_left == null || top_right == null) - log_runtime(EXCEPTION("One of the late setup corners is bust"), src) + stack_trace("One of the late setup corners is bust") if(ST_bot_left == null || ST_top_right == null) - log_runtime(EXCEPTION("One of the smoothing corners is bust"), src) + stack_trace("One of the smoothing corners is bust") GLOB.space_manager.remove_dirt(placement.z) late_setup_level( @@ -75,7 +75,7 @@ . = file(mappath) if(!.) - log_runtime(EXCEPTION(" The file of [src] appears to be empty/non-existent."), src) + stack_trace(" The file of [src] appears to be empty/non-existent.") /datum/map_template/proc/get_affected_turfs(turf/T, centered = 0) var/turf/placement = T diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 0d71c8d0e13..f31428fa802 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -120,7 +120,7 @@ var/datum/atom_hud/antag/hud_to_transfer = antag_hud //we need this because leave_hud() will clear this list var/mob/living/old_current = current if(!istype(new_character)) - log_runtime(EXCEPTION("transfer_to(): Some idiot has tried to transfer_to() a non mob/living mob."), src) + stack_trace("transfer_to(): Some idiot has tried to transfer_to() a non mob/living mob.") if(current) //remove ourself from our old body's mind variable current.mind = null leave_all_huds() //leave all the huds in the old body, so it won't get huds if somebody else enters it @@ -725,8 +725,7 @@ return var/datum/mind/targ = new_target if(!istype(targ)) - log_runtime(EXCEPTION("Invalid target for identity theft objective, cancelling"), src) - return + CRASH("Invalid target for identity theft objective, cancelling") new_objective = new /datum/objective/escape/escape_with_identity new_objective.owner = src new_objective.target = new_target diff --git a/code/datums/spawners_menu.dm b/code/datums/spawners_menu.dm index 0a69855638c..5383d20d1b0 100644 --- a/code/datums/spawners_menu.dm +++ b/code/datums/spawners_menu.dm @@ -44,8 +44,7 @@ var/list/possible_spawners = params2list(spawners) var/obj/effect/mob_spawn/MS = locate(pick(possible_spawners)) if(!MS || !istype(MS)) - log_runtime(EXCEPTION("A ghost tried to interact with an invalid spawner, or the spawner didn't exist.")) - return + CRASH("A ghost tried to interact with an invalid spawner, or the spawner didn't exist.") switch(action) if("jump") owner.forceMove(get_turf(MS)) diff --git a/code/defines/procs/admin.dm b/code/defines/procs/admin.dm index a3291d61f77..882c3ffce94 100644 --- a/code/defines/procs/admin.dm +++ b/code/defines/procs/admin.dm @@ -7,7 +7,7 @@ /proc/key_name_helper(whom, include_name, include_link = FALSE, type = null) if(include_link != FALSE && include_link != TRUE) - log_runtime(EXCEPTION("Key_name was called with an incorrect include_link [include_link]")) + stack_trace("Key_name was called with an incorrect include_link [include_link]") var/mob/M var/client/C diff --git a/code/game/dna/dna2_helpers.dm b/code/game/dna/dna2_helpers.dm index 5d6616d196c..464a230085f 100644 --- a/code/game/dna/dna2_helpers.dm +++ b/code/game/dna/dna2_helpers.dm @@ -241,8 +241,7 @@ /datum/dna/proc/head_traits_to_dna(mob/living/carbon/human/character, obj/item/organ/external/head/head_organ) if(!head_organ) - log_runtime(EXCEPTION("Attempting to reset DNA from a missing head!"), src) - return + CRASH("Attempting to reset DNA from a missing head!") if(!head_organ.h_style) head_organ.h_style = "Skinhead" var/hair = GLOB.hair_styles_full_list.Find(head_organ.h_style) diff --git a/code/game/gamemodes/setupgame.dm b/code/game/gamemodes/setupgame.dm index 7315b52b062..7e70e907ab2 100644 --- a/code/game/gamemodes/setupgame.dm +++ b/code/game/gamemodes/setupgame.dm @@ -148,6 +148,6 @@ picked_cult = new random_cult() if(!picked_cult) - log_runtime(EXCEPTION("Cult datum creation failed")) + stack_trace("Cult datum creation failed") //todo:add adminonly datum var, check for said var here... return picked_cult diff --git a/code/game/gamemodes/wizard/raginmages.dm b/code/game/gamemodes/wizard/raginmages.dm index bf7312c25f1..1a845d39e8d 100644 --- a/code/game/gamemodes/wizard/raginmages.dm +++ b/code/game/gamemodes/wizard/raginmages.dm @@ -137,8 +137,8 @@ mages_made++ return TRUE else - log_runtime(EXCEPTION("The candidates list for ragin' mages contained non-observer entries!"), src) - return FALSE + . = FALSE + CRASH("The candidates list for ragin' mages contained non-observer entries!") // ripped from -tg-'s wizcode, because whee lets make a very general proc for a very specific gamemode // This probably wouldn't do half bad as a proc in __HELPERS diff --git a/code/game/machinery/navbeacon.dm b/code/game/machinery/navbeacon.dm index 70256099b9e..4ddb356d2fc 100644 --- a/code/game/machinery/navbeacon.dm +++ b/code/game/machinery/navbeacon.dm @@ -29,8 +29,8 @@ var/turf/T = loc if(!T.transparent_floor) hide(T.intact) - if(!codes || !codes.len) - log_runtime(EXCEPTION("Empty codes datum at ([x],[y],[z])"), src, list("codes_txt: '[codes_txt]'")) + if(!length(codes)) + stack_trace("Empty codes datum at ([x],[y],[z]) (codes_txt: [codes_txt])") if("patrol" in codes) if(!GLOB.navbeacons["[z]"]) GLOB.navbeacons["[z]"] = list() diff --git a/code/game/objects/effects/spawners/random_barrier.dm b/code/game/objects/effects/spawners/random_barrier.dm index 6de7e48b60f..40897a60bcd 100644 --- a/code/game/objects/effects/spawners/random_barrier.dm +++ b/code/game/objects/effects/spawners/random_barrier.dm @@ -17,14 +17,13 @@ . = ..() var/turf/T = get_turf(src) if(!T) - log_runtime(EXCEPTION("Barrier spawner placed in nullspace!"), src) - return + CRASH("Barrier spawner placed in nullspace!") var/thing_to_place = pickweight(result) if(ispath(thing_to_place, /turf)) T.ChangeTurf(thing_to_place) else new thing_to_place(T) - qdel(src) + return INITIALIZE_HINT_QDEL /obj/effect/spawner/random_barrier/wall_probably name = "probably a wall" diff --git a/code/game/objects/effects/spawners/random_spawners.dm b/code/game/objects/effects/spawners/random_spawners.dm index 69831545397..2dbe235c6cb 100644 --- a/code/game/objects/effects/spawners/random_spawners.dm +++ b/code/game/objects/effects/spawners/random_spawners.dm @@ -10,11 +10,12 @@ var/spawn_inside = null // This needs to use New() instead of Initialize() because the thing it creates might need to be initialized too +// AA 2022-08-11: The above comment doesnt even make sense. If extra atoms are loaded during SSatoms.Initialize(), they still get initialised! /obj/effect/spawner/random_spawners/New() . = ..() var/turf/T = get_turf(src) if(!T) - log_runtime(EXCEPTION("Spawner placed in nullspace!"), src) + stack_trace("Spawner placed in nullspace!") return randspawn(T) diff --git a/code/game/objects/effects/spawners/windowspawner.dm b/code/game/objects/effects/spawners/windowspawner.dm index ed4e7dcb48e..8d8654957cc 100644 --- a/code/game/objects/effects/spawners/windowspawner.dm +++ b/code/game/objects/effects/spawners/windowspawner.dm @@ -13,7 +13,7 @@ var/obj/structure/window/WI for(var/obj/structure/grille/G in get_turf(src)) // Complain noisily - log_runtime(EXCEPTION("Extra grille on turf: ([T.x],[T.y],[T.z])"), src) + stack_trace("Extra grille on turf: ([T.x],[T.y],[T.z])") qdel(G) //just in case mappers don't know what they are doing if(!useFull) diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 629bae3407d..d282899d0ea 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -322,7 +322,7 @@ GLOBAL_LIST_INIT(default_medbay_channels, list( return ..() /mob/living/automatedannouncer/proc/autocleanup() - log_runtime(EXCEPTION("An announcer somehow managed to outlive the radio! Deleting!"), src, list("Message: '[message]'")) + stack_trace("An announcer somehow managed to outlive the radio! Deleting! (Message: [message])") qdel(src) // Interprets the message mode when talking into a radio, possibly returning a connection datum diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm index 3d0930b1dc0..5ee94588ffd 100644 --- a/code/game/objects/items/weapons/defib.dm +++ b/code/game/objects/items/weapons/defib.dm @@ -65,7 +65,7 @@ . += "[icon_state]-emagged" if(powered) . += "[icon_state]-powered" - if(powered && cell) + if(powered && cell) var/ratio = cell.charge / cell.maxcharge ratio = CEILING(ratio*4, 1) * 25 . += "[icon_state]-charge[ratio]" @@ -562,7 +562,7 @@ if(ghost && !ghost.client) // In case the ghost's not getting deleted for some reason H.key = ghost.key - log_runtime(EXCEPTION("Ghost of name [ghost.name] is bound to [H.real_name], but lacks a client. Deleting ghost."), H) + stack_trace("Ghost of name [ghost.name] is bound to [H.real_name], but lacks a client. Deleting ghost.") QDEL_NULL(ghost) var/tplus = world.time - H.timeofdeath diff --git a/code/game/objects/items/weapons/dna_injector.dm b/code/game/objects/items/weapons/dna_injector.dm index bfd45d88da8..a0409084346 100644 --- a/code/game/objects/items/weapons/dna_injector.dm +++ b/code/game/objects/items/weapons/dna_injector.dm @@ -77,7 +77,7 @@ H = M if(!buf) - log_runtime(EXCEPTION("[src] used by [user] on [M] failed to initialize properly."), src) + stack_trace("[src] used by [user] on [M] failed to initialize properly.") return spawn(0) //Some mutations have sleeps in them, like monkey diff --git a/code/game/objects/items/weapons/rpd.dm b/code/game/objects/items/weapons/rpd.dm index d1edf8560cc..7ef650799dd 100644 --- a/code/game/objects/items/weapons/rpd.dm +++ b/code/game/objects/items/weapons/rpd.dm @@ -95,8 +95,7 @@ /obj/item/rpd/proc/create_atmos_pipe(mob/user, turf/T) //Make an atmos pipe, meter, or gas sensor if(!can_dispense_pipe(whatpipe, RPD_ATMOS_MODE)) - log_runtime(EXCEPTION("Failed to spawn [get_pipe_name(whatpipe, PIPETYPE_ATMOS)] - possible tampering detected")) //Damn dirty apes -- I mean hackers - return + CRASH("Failed to spawn [get_pipe_name(whatpipe, PIPETYPE_ATMOS)] - possible tampering detected") //Damn dirty apes -- I mean hackers var/obj/item/pipe/P if(whatpipe == PIPE_GAS_SENSOR) P = new /obj/item/pipe_gsensor(T) @@ -117,8 +116,7 @@ /obj/item/rpd/proc/create_disposals_pipe(mob/user, turf/T) //Make a disposals pipe / construct if(!can_dispense_pipe(whatdpipe, RPD_DISPOSALS_MODE)) - log_runtime(EXCEPTION("Failed to spawn [get_pipe_name(whatdpipe, PIPETYPE_DISPOSAL)] - possible tampering detected")) - return + CRASH("Failed to spawn [get_pipe_name(whatdpipe, PIPETYPE_DISPOSAL)] - possible tampering detected") var/obj/structure/disposalconstruct/P = new(T, whatdpipe, iconrotation) if(!iconrotation) //Automatic rotation P.dir = user.dir @@ -287,7 +285,7 @@ playsound(src, 'sound/machines/synth_no.ogg', 15, TRUE) to_chat(user, "ERROR: \The [T] is out of [src]'s range!") return - + T.rpd_act(user, src) #undef RPD_COOLDOWN_TIME diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm index 2fa5a0180c0..caaf888573c 100644 --- a/code/game/objects/items/weapons/storage/storage.dm +++ b/code/game/objects/items/weapons/storage/storage.dm @@ -708,9 +708,9 @@ if(islist(thing)) list_to_object(thing, src) else if(thing == null) - log_runtime(EXCEPTION("Null entry found in storage/deserialize."), src) + stack_trace("Null entry found in storage/deserialize.") else - log_runtime(EXCEPTION("Non-list thing found in storage/deserialize."), src, list("Thing: [thing]")) + stack_trace("Non-list thing found in storage/deserialize (Thing: [thing])") ..() /obj/item/storage/AllowDrop() diff --git a/code/modules/antagonists/vampire/vampire_powers/dantalion_powers.dm b/code/modules/antagonists/vampire/vampire_powers/dantalion_powers.dm index c46ee037fdf..0949add5841 100644 --- a/code/modules/antagonists/vampire/vampire_powers/dantalion_powers.dm +++ b/code/modules/antagonists/vampire/vampire_powers/dantalion_powers.dm @@ -39,28 +39,28 @@ to_chat(user, "You or your target moved.") /obj/effect/proc_holder/spell/vampire/enthrall/proc/can_enthrall(mob/living/user, mob/living/carbon/C) + . = FALSE if(!C) - log_runtime(EXCEPTION("target was null while trying to vampire enthrall, attacker is [user] [user.key] \ref[user]"), user) - return FALSE + CRASH("target was null while trying to vampire enthrall, attacker is [user] [user.key] \ref[user]") if(!user.mind.som) CRASH("Dantalion Thrall datum ended up null.") if(!ishuman(C)) to_chat(user, "You can only enthrall sentient humanoids!") - return FALSE + return if(!C.mind) to_chat(user, "[C.name]'s mind is not there for you to enthrall.") - return FALSE + return var/datum/antagonist/vampire/V = user.mind.has_antag_datum(/datum/antagonist/vampire) if(V.subclass.thrall_cap <= length(user.mind.som.serv)) to_chat(user, "You don't have enough power to enthrall any more people!") - return FALSE + return if(ismindshielded(C) || C.mind.has_antag_datum(/datum/antagonist/vampire) || C.mind.has_antag_datum(/datum/antagonist/mindslave)) C.visible_message("[C] seems to resist the takeover!", "You feel a familiar sensation in your skull that quickly dissipates.") - return FALSE + return if(C.mind.isholy) C.visible_message("[C] seems to resist the takeover!", "Your faith in [SSticker.Bible_deity_name] has kept your mind clear of all evil.") - return FALSE + return return TRUE /obj/effect/proc_holder/spell/vampire/enthrall/proc/handle_enthrall(mob/living/user, mob/living/carbon/human/H) diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm index c9441c8d274..41e77fdc8d1 100644 --- a/code/modules/atmospherics/machinery/airalarm.dm +++ b/code/modules/atmospherics/machinery/airalarm.dm @@ -267,8 +267,8 @@ if(!alarm_area) alarm_area = get_area(src) if(!alarm_area) - log_runtime(EXCEPTION("Air alarm /obj/machinery/alarm lacks alarm_area vars during proc/master_is_operating()"), src) - return FALSE + . = FALSE + CRASH("Air alarm /obj/machinery/alarm lacks alarm_area vars during proc/master_is_operating()") return alarm_area.master_air_alarm && !(alarm_area.master_air_alarm.stat & (NOPOWER|BROKEN)) diff --git a/code/modules/atmospherics/machinery/datum_pipeline.dm b/code/modules/atmospherics/machinery/datum_pipeline.dm index ff9fb9a4ab1..1f4529c9e43 100644 --- a/code/modules/atmospherics/machinery/datum_pipeline.dm +++ b/code/modules/atmospherics/machinery/datum_pipeline.dm @@ -57,7 +57,7 @@ GLOBAL_VAR_INIT(pipenetwarnings, 10) if(!members.Find(item)) if(item.parent) - log_runtime(EXCEPTION("[item.type] \[\ref[item]] added to a pipenet while still having one ([item.parent]) (pipes leading to the same spot stacking in one turf). Nearby: [item.x], [item.y], [item.z].")) + stack_trace("[item.type] \[\ref[item]] added to a pipenet while still having one ([item.parent]) (pipes leading to the same spot stacking in one turf). Nearby: [item.x], [item.y], [item.z].") members += item possible_expansions += item diff --git a/code/modules/awaymissions/maploader/reader.dm b/code/modules/awaymissions/maploader/reader.dm index 2f807cb1db2..336c84b9655 100644 --- a/code/modules/awaymissions/maploader/reader.dm +++ b/code/modules/awaymissions/maploader/reader.dm @@ -156,14 +156,7 @@ GLOBAL_DATUM_INIT(_preloader, /datum/dmm_suite/preloader, new()) log_debug("Loaded map in [stop_watch(watch)]s.") qdel(LM) if(bounds[MAP_MINX] == 1.#INF) // Shouldn't need to check every item - log_runtime(EXCEPTION("Bad Map bounds in [fname]"), src, list( - "Min x: [bounds[MAP_MINX]]", - "Min y: [bounds[MAP_MINY]]", - "Min z: [bounds[MAP_MINZ]]", - "Max x: [bounds[MAP_MAXX]]", - "Max y: [bounds[MAP_MAXY]]", - "Max z: [bounds[MAP_MAXZ]]")) - return null + CRASH("Bad Map bounds in [fname], Min x: [bounds[MAP_MINX]], Min y: [bounds[MAP_MINY]], Min z: [bounds[MAP_MINZ]], Max x: [bounds[MAP_MAXX]], Max y: [bounds[MAP_MAXY]], Max z: [bounds[MAP_MAXZ]]") else if(!measureOnly) for(var/t in block(locate(bounds[MAP_MINX], bounds[MAP_MINY], bounds[MAP_MINZ]), locate(bounds[MAP_MAXX], bounds[MAP_MAXY], bounds[MAP_MAXZ]))) @@ -227,7 +220,7 @@ GLOBAL_DATUM_INIT(_preloader, /datum/dmm_suite/preloader, new()) old_position = dpos + 1 if(!atom_def) // Skip the item if the path does not exist. Fix your crap, mappers! - log_runtime(EXCEPTION("Bad path: [atom_text]"), src, list("Source String: [model]", "dpos: [dpos]")) + stack_trace("Bad path: [atom_text] | Source String: [model] | dpos: [dpos]") continue members.Add(atom_def) @@ -453,7 +446,7 @@ GLOBAL_DATUM_INIT(_preloader, /datum/dmm_suite/preloader, new()) try A.deserialize(json_decode(json_data)) catch(var/exception/E) - log_runtime(EXCEPTION("Bad json data: '[json_data]'"), src) + stack_trace("Bad json data: '[json_data]'") throw E for(var/attribute in attributes) var/value = attributes[attribute] diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 117d3feb044..81583716b9a 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -47,14 +47,10 @@ 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]")) + stack_trace("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["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 @@ -64,17 +60,19 @@ // Rate limiting var/mtl = 100 // 100 topics per minute - if (!holder) // Admins are allowed to spam click, deal with it. + if(!holder) // Admins are allowed to spam click, deal with it. var/minute = round(world.time, 600) - if (!topiclimiter) + if(!topiclimiter) topiclimiter = new(LIMITER_SIZE) - if (minute != topiclimiter[CURRENT_MINUTE]) + + if(minute != topiclimiter[CURRENT_MINUTE]) topiclimiter[CURRENT_MINUTE] = minute topiclimiter[MINUTE_COUNT] = 0 + topiclimiter[MINUTE_COUNT] += 1 - if (topiclimiter[MINUTE_COUNT] > mtl) + if(topiclimiter[MINUTE_COUNT] > mtl) var/msg = "Your previous action was ignored because you've done too many in a minute." - if (minute != topiclimiter[ADMINSWARNED_AT]) //only one admin message per-minute. (if they spam the admins can just boot/ban them) + if(minute != topiclimiter[ADMINSWARNED_AT]) //only one admin message per-minute. (if they spam the admins can just boot/ban them) topiclimiter[ADMINSWARNED_AT] = minute msg += " Administrators have been informed." log_game("[key_name(src)] Has hit the per-minute topic limit of [mtl] topic calls in a given game minute") @@ -83,22 +81,24 @@ return var/stl = 10 // 10 topics a second - if (!holder) // Admins are allowed to spam click, deal with it. + if(!holder) // Admins are allowed to spam click, deal with it. var/second = round(world.time, 10) - if (!topiclimiter) + if(!topiclimiter) topiclimiter = new(LIMITER_SIZE) - if (second != topiclimiter[CURRENT_SECOND]) + + if(second != topiclimiter[CURRENT_SECOND]) topiclimiter[CURRENT_SECOND] = second topiclimiter[SECOND_COUNT] = 0 + topiclimiter[SECOND_COUNT] += 1 - if (topiclimiter[SECOND_COUNT] > stl) + if(topiclimiter[SECOND_COUNT] > stl) to_chat(src, "Your previous action was ignored because you've done too many in a second") return //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 +/client/proc/is_afk(duration = 5 MINUTES) + if(inactivity > duration) + return inactivity return 0 //Send resources to the client. @@ -839,13 +884,16 @@ // Change the way they should download resources. if(length(GLOB.configuration.url.rsc_urls)) preload_rsc = pick(GLOB.configuration.url.rsc_urls) + else preload_rsc = 1 // If config.resource_urls is not set, preload like normal. + // Most assets are now handled through global_cache.dm getFiles( 'html/search.js', // Used in various non-TGUI HTML windows for search functionality 'html/panels.css' // Used for styling certain panels, such as in the new player panel ) + spawn (10) //removing this spawn causes all clients to not get verbs. //Precache the client with all other assets slowly, so as to not block other browse() calls getFilesSlow(src, SSassets.preload, register_asset = FALSE) @@ -855,8 +903,10 @@ for(var/L in GLOB.all_languages) var/datum/language/lang = GLOB.all_languages[L] var/message = "[lang.name] : [lang.type]" + if(lang.flags & RESTRICTED) message += " (RESTRICTED)" + to_chat(world, "[message]") /client/proc/colour_transition(list/colour_to = null, time = 10) //Call this with no parameters to reset to default. @@ -950,10 +1000,13 @@ /client/proc/send_ssd_warning(mob/M) if(!GLOB.configuration.general.ssd_warning) return FALSE + if(ssd_warning_acknowledged) return FALSE - if(M && M.player_logged < SSD_WARNING_TIMER) + + if(M?.player_logged < SSD_WARNING_TIMER) return FALSE + to_chat(src, "Are you taking this person to cryo or giving them medical treatment? If you are, confirm that and proceed. Interacting with SSD players in other ways is against server rules unless you've ahelped first for permission.") return TRUE @@ -1009,13 +1062,16 @@ var/list/lines = splittext(http["CONTENT"], "\n") var/list/initial_data = list() var/current_index = "" + for(var/L in lines) if(L == "") continue + if(!findtext(L, "\t")) current_index = L initial_data[current_index] = list() continue + initial_data[current_index] += replacetext(replacetext(L, "\t", ""), "\"", "") var/list/parsed_data = list() @@ -1032,12 +1088,15 @@ // Main return is here return parsed_data + catch log_debug("Error parsing byond.com data for [ckey]. Please inform maintainers.") return null + else log_debug("Error retrieving data from byond.com for [ckey]. Invalid status code (Expected: 200 | Got: [status]).") return null + else log_debug("Failed to retrieve data from byond.com for [ckey]. Connection failed.") return null @@ -1056,6 +1115,7 @@ var/datum/db_query/query_date = SSdbcore.NewQuery("SELECT byond_date, DATEDIFF(Now(), byond_date) FROM player WHERE ckey=:ckey", list( "ckey" = ckey )) + if(!query_date.warn_execute()) qdel(query_date) return @@ -1083,21 +1143,25 @@ "date" = byondacc_date, "ckey" = ckey )) + if(!query_update.warn_execute()) qdel(query_update) return + qdel(query_update) // Now retrieve the age again because BYOND doesnt have native methods for this var/datum/db_query/query_age = SSdbcore.NewQuery("SELECT DATEDIFF(Now(), byond_date) FROM player WHERE ckey=:ckey", list( "ckey" = ckey )) + if(!query_age.warn_execute()) qdel(query_age) return while(query_age.NextRow()) byondacc_age = max(text2num(query_age.item[1]), 0) // Ensure account isnt negative days old + qdel(query_age) // Notify admins on new clients connecting, if the byond account age is less than a config value @@ -1111,7 +1175,9 @@ if(prefs.sound & SOUND_AMBIENCE) if(SSambience.ambience_listening_clients[src] > world.time) return // If already properly set we don't want to reset the timer. + SSambience.ambience_listening_clients[src] = world.time + 10 SECONDS //Just wait 10 seconds before the next one aight mate? cheers. + else SSambience.ambience_listening_clients -= src @@ -1124,12 +1190,11 @@ var/output = GLOB.join_tos output += "
By withdrawing your consent, you acknowledge that you will be instantaneously kicked from the server and will have to re-accept the Terms of Service. If you do not wish to withdraw your consent at this moment, feel free to close this window.
" output += "" - src << browse(output,"window=privacy_consent;size=600x500") + var/datum/browser/popup = new(src, "privacy_consent", "