diff --git a/auxmos.dll b/auxmos.dll index fc227f62c9..52e01b515a 100644 Binary files a/auxmos.dll and b/auxmos.dll differ diff --git a/auxmos.pdb b/auxmos.pdb index a2db349011..0f5a534a12 100644 Binary files a/auxmos.pdb and b/auxmos.pdb differ diff --git a/code/controllers/configuration/entries/connections.dm b/code/controllers/configuration/entries/connections.dm index acdf588e5a..6ec41590f2 100644 --- a/code/controllers/configuration/entries/connections.dm +++ b/code/controllers/configuration/entries/connections.dm @@ -1,6 +1,12 @@ /datum/config_entry/flag/panic_bunker // prevents people the server hasn't seen before from connecting -/datum/config_entry/number/panic_bunker_living // living time in minutes that a player needs to pass the panic bunker +/datum/config_entry/number/panic_bunker_living // living time in minutes that a player needs to pass the panic bunker. they pass **if they are above this amount** + config_entry_value = 0 // default: <= 0 meaning any playtime works. -1 to disable criteria. + integer = TRUE + +/datum/config_entry/number/panic_bunker_living_vpn + config_entry_value = 0 // default: <= 0 meaning anytime works. -1 to disable criteria. + integer = TRUE /datum/config_entry/string/panic_bunker_message config_entry_value = "Sorry but the server is currently not accepting connections from never before seen players." diff --git a/code/controllers/subsystem/fail2topic.dm b/code/controllers/subsystem/fail2topic.dm index 78c4807c3f..fc18d7dabe 100644 --- a/code/controllers/subsystem/fail2topic.dm +++ b/code/controllers/subsystem/fail2topic.dm @@ -33,7 +33,7 @@ SUBSYSTEM_DEF(fail2topic) while(i <= length(rate_limiting)) var/ip = rate_limiting[i] var/last_attempt = rate_limiting[ip] - if(world.time - last_attempt > rate_limit) + if(REALTIMEOFDAY - last_attempt > rate_limit) rate_limiting -= ip fail_counts -= ip else //if we remove that, and the next element is in its place. check that instead of incrementing. @@ -58,12 +58,12 @@ SUBSYSTEM_DEF(fail2topic) if (active_bans[ip]) return TRUE - rate_limiting[ip] = world.time + rate_limiting[ip] = REALTIMEOFDAY if (isnull(last_attempt)) return FALSE - if (world.time - last_attempt > rate_limit) + if (REALTIMEOFDAY - last_attempt > rate_limit) fail_counts -= ip return FALSE else @@ -83,7 +83,7 @@ SUBSYSTEM_DEF(fail2topic) if (!enabled) return - active_bans[ip] = world.time + active_bans[ip] = REALTIMEOFDAY fail_counts -= ip rate_limiting -= ip diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 4e57a2f717..fe1fb03426 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -540,18 +540,19 @@ if (!(. & EMP_PROTECT_CONTENTS)) for(var/obj/O in src) O.emp_act(severity) - if(secure && !broken && !(. & EMP_PROTECT_SELF)) - if(prob(50 / severity)) - locked = !locked - update_icon() - if(prob(20 / severity) && !opened) - if(!locked) - open() - else - req_access = list() - req_access += pick(get_all_accesses()) - if(!QDELETED(lockerelectronics)) - lockerelectronics.accesses = req_access + if(!secure || broken) + return + if(prob(severity/2)) + locked = !locked + update_icon() + if(prob(severity/5) && !opened) + if(!locked) + open() + else + req_access = list() + req_access += pick(get_all_accesses()) + if(!QDELETED(lockerelectronics)) + lockerelectronics.accesses = req_access /obj/structure/closet/contents_explosion(severity, target) for(var/atom/A in contents) diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index 99f24107c7..950b2b5b25 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -187,3 +187,6 @@ var/list/block_parry_hinted = list() /// moused over objects, currently capped at 7. this is awful, and should be replaced with a component to track it using signals for parrying at some point. var/list/moused_over_objects = list() + + /// AFK tracking + var/last_activity = 0 diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 571adb406b..04b643e532 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -83,6 +83,8 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( log_href("[src] (usr:[usr]\[[COORD(usr)]\]) : [hsrc ? "[hsrc] " : ""][href]") return + last_activity = world.time + //Logs all hrefs log_href("[src] (usr:[usr]\[[COORD(usr)]\]) : [hsrc ? "[hsrc] " : ""][href]") @@ -222,6 +224,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( /////////// /client/New(TopicData) + last_activity = world.time world.SetConfig("APP/admin", ckey, "role=admin") var/tdata = TopicData //save this for later use TopicData = null //Prevent calls to client.Topic from connect @@ -578,9 +581,10 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( //If we aren't an admin, and the flag is set if(CONFIG_GET(flag/panic_bunker) && !holder && !GLOB.deadmins[ckey] && !(ckey in GLOB.bunker_passthrough)) var/living_recs = CONFIG_GET(number/panic_bunker_living) + var/vpn_living_recs = CONFIG_GET(number/panic_bunker_living_vpn) //Relies on pref existing, but this proc is only called after that occurs, so we're fine. var/minutes = get_exp_living(pure_numeric = TRUE) - if(minutes <= living_recs) // && !CONFIG_GET(flag/panic_bunker_interview) + if((minutes <= living_recs) || (IsVPN() && (minutes < vpn_living_recs))) var/reject_message = "Failed Login: [key] - Account attempting to connect during panic bunker, but they do not have the required living time [minutes]/[living_recs]" log_access(reject_message) message_admins("[reject_message]") @@ -850,6 +854,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( /client/Click(atom/object, atom/location, control, params, ignore_spam = FALSE, extra_info) if(last_click > world.time - world.tick_lag) return + last_activity = world.time last_click = world.time var/ab = FALSE var/list/L = params2list(params) @@ -922,6 +927,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( //checks if a client is afk //3000 frames = 5 minutes /client/proc/is_afk(duration = CONFIG_GET(number/inactivity_period)) + var/inactivity = world.time - last_activity if(inactivity > duration) return inactivity return FALSE diff --git a/code/modules/client/client_vpn_detect.dm b/code/modules/client/client_vpn_detect.dm new file mode 100644 index 0000000000..bd35a65ef2 --- /dev/null +++ b/code/modules/client/client_vpn_detect.dm @@ -0,0 +1,3 @@ +/client/proc/IsVPN() + var/datum/ipintel/res = get_ip_intel(address) + return res.intel >= CONFIG_GET(number/ipintel_rating_bad) diff --git a/code/modules/keybindings/bindings_client.dm b/code/modules/keybindings/bindings_client.dm index 3d12f89cfe..7c0c6216a5 100644 --- a/code/modules/keybindings/bindings_client.dm +++ b/code/modules/keybindings/bindings_client.dm @@ -6,6 +6,7 @@ set hidden = TRUE client_keysend_amount += 1 + last_activity = world.time var/cache = client_keysend_amount @@ -89,6 +90,7 @@ set hidden = TRUE keys_held -= _key + last_activity = world.time var/movement = movement_keys[_key] if(!(next_move_dir_add & movement)) next_move_dir_sub |= movement diff --git a/code/modules/language/language_holder.dm b/code/modules/language/language_holder.dm index 219d8dc184..2ad1bb762b 100644 --- a/code/modules/language/language_holder.dm +++ b/code/modules/language/language_holder.dm @@ -312,12 +312,14 @@ Key procs /datum/language/machine = list(LANGUAGE_ATOM), /datum/language/draconic = list(LANGUAGE_ATOM), /datum/language/slime = list(LANGUAGE_ATOM), - /datum/language/dwarf = list(LANGUAGE_ATOM)) + /datum/language/dwarf = list(LANGUAGE_ATOM), + /datum/language/neokanji = list(LANGUAGE_ATOM)) spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM), /datum/language/machine = list(LANGUAGE_ATOM), /datum/language/draconic = list(LANGUAGE_ATOM), /datum/language/slime = list(LANGUAGE_ATOM), - /datum/language/dwarf = list(LANGUAGE_ATOM)) + /datum/language/dwarf = list(LANGUAGE_ATOM), + /datum/language/neokanji = list(LANGUAGE_ATOM)) /datum/language_holder/venus understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM), diff --git a/code/modules/language/neokanji.dm b/code/modules/language/neokanji.dm new file mode 100644 index 0000000000..bfd7face5b --- /dev/null +++ b/code/modules/language/neokanji.dm @@ -0,0 +1,25 @@ +/datum/language/neokanji + name = "Neo-Kanji" + desc = "A bastardized mixture of many old Earth asian dialects. Famously known as the official language of the spider clan." + speech_verb = "proclaims" + ask_verb = "queries" + exclaim_verb = "declares" + whisper_verb = "hushes" + key = "k" + space_chance = 40 + default_priority = 94 + flags = TONGUELESS_SPEECH + chooseable_roundstart = TRUE + syllables = list("ka", "ki", "ku", "ke", "ko", "ta", + "chi", "tsu", "te", "to", "sa", "shi", + "su", "se", "so", "na","ni","nu","ne", + "no","n","ha","hi","fu","he","ho","ma", + "mi","mu","me","mo","ya","yu","yo","ra", + "ri","ru","re","ro","wa","wo", "an", "ang", + "ao", "ba", "bai", "ban", "bang", "bao", + "bei", "beng", "chuai", "xing", "xong", "zhao", + "zhong", "xil", "ping", "dang", "guang", "guan", + "jing", "jiao", "kung", "fu", "lo", "wang", + "liu", "ling", "mang", "nong", "peng", "qiong", + "san","tiao", "wan","xiong", "men") + icon_state = "neokanji" diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 5edc52376e..8669a1458a 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1055,10 +1055,10 @@ return if(!HAS_TRAIT(src, TRAIT_IGNOREDAMAGESLOWDOWN)) //if we want to ignore slowdown from damage, but not from equipment var/scaling = maxHealth / 100 - var/health_deficiency = max(((maxHealth / scaling) - (health / scaling)), (getStaminaLoss()*0.75)) + var/health_deficiency = max(((maxHealth / scaling) - (health / scaling)), max(0, getStaminaLoss() - 39)) if(health_deficiency >= 40) - add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown, TRUE, (health_deficiency - 15) / 75) - add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying, TRUE, (health_deficiency - 15) / 25) + add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown, TRUE, health_deficiency / 75) + add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying, TRUE, health_deficiency / 25) else remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown) remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying) diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm index 3b6f37184a..d8ef440ef9 100644 --- a/code/modules/mob/say.dm +++ b/code/modules/mob/say.dm @@ -4,6 +4,7 @@ set name = "say_indicator" set hidden = TRUE set category = "IC" + client?.last_activity = world.time display_typing_indicator() var/message = input(usr, "", "say") as text|null // If they don't type anything just drop the message. @@ -21,12 +22,16 @@ to_chat(usr, "Speech is currently admin-disabled.") return clear_typing_indicator() // clear it immediately! + + client?.last_activity = world.time + say(message) /mob/verb/me_typing_indicator() set name = "me_indicator" set hidden = TRUE set category = "IC" + client?.last_activity = world.time display_typing_indicator() var/message = input(usr, "", "me") as message|null // If they don't type anything just drop the message. @@ -52,6 +57,8 @@ message = trim(copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN)) clear_typing_indicator() // clear it immediately! + client?.last_activity = world.time + usr.emote("me",1,message,TRUE) /mob/say_mod(input, message_mode) @@ -73,6 +80,7 @@ return lowertext(copytext_char(input, 1, customsayverb)) /mob/proc/whisper_keybind() + client?.last_activity = world.time var/message = input(src, "", "whisper") as text|null if(!length(message)) return @@ -89,6 +97,7 @@ whisper(message) /mob/proc/whisper(message, datum/language/language=null) + client?.last_activity = world.time say(message, language) //only living mobs actually whisper, everything else just talks /mob/proc/say_dead(var/message) @@ -132,6 +141,7 @@ message = emoji_parse(message) var/rendered = "DEAD: [name][alt_name] [emoji_parse(spanned)]" log_talk(message, LOG_SAY, tag="DEAD") + client?.last_activity = world.time deadchat_broadcast(rendered, follow_target = src, speaker_key = key) /mob/proc/check_emote(message) diff --git a/code/modules/ninja/outfit.dm b/code/modules/ninja/outfit.dm index a6faa9a3d5..ca740d9ad7 100644 --- a/code/modules/ninja/outfit.dm +++ b/code/modules/ninja/outfit.dm @@ -21,3 +21,6 @@ var/obj/item/clothing/suit/space/space_ninja/S = H.wear_suit if(istype(H.belt, belt)) S.energyKatana = H.belt + H.grant_language(/datum/language/neokanji) + var/datum/language_holder/LH = H.get_language_holder() + LH.selected_language = /datum/language/neokanji diff --git a/code/modules/surgery/organs/tongue.dm b/code/modules/surgery/organs/tongue.dm index 7cba3d358a..833fd5bc94 100644 --- a/code/modules/surgery/organs/tongue.dm +++ b/code/modules/surgery/organs/tongue.dm @@ -26,6 +26,7 @@ /datum/language/vampiric, /datum/language/dwarf, /datum/language/signlanguage, + /datum/language/neokanji, )) healing_factor = STANDARD_ORGAN_HEALING*5 //Fast!! decay_factor = STANDARD_ORGAN_DECAY/2 @@ -253,7 +254,8 @@ /datum/language/beachbum, /datum/language/aphasia, /datum/language/sylvan, - /datum/language/voltaic + /datum/language/voltaic, + /datum/language/neokanji, )) /obj/item/organ/tongue/ethereal/Initialize(mapload) diff --git a/code/modules/tgui/tgui.dm b/code/modules/tgui/tgui.dm index a0c39258b9..c739d69d0b 100644 --- a/code/modules/tgui/tgui.dm +++ b/code/modules/tgui/tgui.dm @@ -300,6 +300,7 @@ process_status() if(src_object.ui_act(act_type, payload, src, state)) SStgui.update_uis(src_object) + usr?.client?.last_activity = world.time return FALSE switch(type) if("ready") diff --git a/config/entries/connections.txt b/config/entries/connections.txt index 6351a77fcf..41df00bc40 100644 --- a/config/entries/connections.txt +++ b/config/entries/connections.txt @@ -2,9 +2,12 @@ ## Requires database #PANIC_BUNKER -## If a player connects during a bunker with less then or this amount of living time (Minutes), we deny the connection +## If a player connects during a bunker with less then or this amount of living time (Minutes), we deny the connection. Set to -1 to disable criteria. #PANIC_BUNKER_LIVING 90 +## The above but for VPN connections. Set to -1 to disable criteria. You can set the above to disabled and set this to only enforce bunker on VPNs. +#PANIC_BUNKER_LIVING_VPN 120 + ## The message the Panic Bunker gives when someone is rejected by it ## %minutes% is replaced with PANIC_BUNKER_LIVING on runtime, remove it if you don't want this #PANIC_BUNKER_MESSAGE Sorry, but the server is currently not accepting connections from players with less than %minutes% minutes of living time. diff --git a/html/changelog.html b/html/changelog.html index c51091cfe8..d85bd6b47a 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -508,22 +508,6 @@ - -

09 August 2021

-

Arturlang updated:

- -

BlueWildrose updated:

- -

Putnam3145 updated:

- GoonStation 13 Development Team diff --git a/icons/misc/language.dmi b/icons/misc/language.dmi index a33f914885..b24e9871c3 100644 Binary files a/icons/misc/language.dmi and b/icons/misc/language.dmi differ diff --git a/tgstation.dme b/tgstation.dme index f5b1121b3a..30c413815b 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1980,6 +1980,7 @@ #include "code\modules\client\client_colour.dm" #include "code\modules\client\client_defines.dm" #include "code\modules\client\client_procs.dm" +#include "code\modules\client\client_vpn_detect.dm" #include "code\modules\client\message.dm" #include "code\modules\client\player_details.dm" #include "code\modules\client\preferences.dm" @@ -2427,6 +2428,7 @@ #include "code\modules\language\monkey.dm" #include "code\modules\language\mushroom.dm" #include "code\modules\language\narsian.dm" +#include "code\modules\language\neokanji.dm" #include "code\modules\language\ratvarian.dm" #include "code\modules\language\signlanguage.dm" #include "code\modules\language\slime.dm"