mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-23 12:07:27 +01:00
Merge pull request #11732 from farie82/AFK-subsystem
Adds the AFK auto cryo removal system (preference setting for players)
This commit is contained in:
@@ -268,6 +268,7 @@ CREATE TABLE `player` (
|
||||
`atklog` smallint(4) DEFAULT '0',
|
||||
`fuid` BIGINT(20) NULL DEFAULT NULL,
|
||||
`fupdate` SMALLINT(4) NULL DEFAULT 0,
|
||||
`afk_watch` tinyint(1) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `ckey` (`ckey`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=32446 DEFAULT CHARSET=latin1;
|
||||
|
||||
@@ -267,6 +267,7 @@ CREATE TABLE `SS13_player` (
|
||||
`atklog` smallint(4) DEFAULT '0',
|
||||
`fuid` BIGINT(20) NULL DEFAULT NULL,
|
||||
`fupdate` SMALLINT(4) NULL DEFAULT 0,
|
||||
`afk_watch` tinyint(1) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `ckey` (`ckey`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=32446 DEFAULT CHARSET=latin1;
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
# Add afk_watch which gives users the option to make use of the AFK watcher subsystem
|
||||
ALTER TABLE `player` ADD `afk_watch` tinyint(1) NOT NULL DEFAULT '0';
|
||||
@@ -315,7 +315,7 @@
|
||||
#define INVESTIGATE_BOMB "bombs"
|
||||
|
||||
// The SQL version required by this version of the code
|
||||
#define SQL_VERSION 7
|
||||
#define SQL_VERSION 8
|
||||
|
||||
// Vending machine stuff
|
||||
#define CAT_NORMAL 1
|
||||
|
||||
@@ -72,6 +72,11 @@
|
||||
var/assistantlimit = 0 //enables assistant limiting
|
||||
var/assistantratio = 2 //how many assistants to security members
|
||||
|
||||
// The AFK subsystem will not be activated if any of the below config values are equal or less than 0
|
||||
var/warn_afk_minimum = 0 // How long till you get a warning while being AFK
|
||||
var/auto_cryo_afk = 0 // How long till you get put into cryo when you're AFK
|
||||
var/auto_despawn_afk = 0 // How long till you actually despawn in cryo when you're AFK (Not ssd so not automatic)
|
||||
|
||||
var/auto_cryo_ssd_mins = 0
|
||||
var/ssd_warning = 0
|
||||
|
||||
@@ -314,6 +319,13 @@
|
||||
if("shadowling_max_age")
|
||||
config.shadowling_max_age = text2num(value)
|
||||
|
||||
if("warn_afk_minimum")
|
||||
config.warn_afk_minimum = text2num(value)
|
||||
if("auto_cryo_afk")
|
||||
config.auto_cryo_afk = text2num(value)
|
||||
if("auto_despawn_afk")
|
||||
config.auto_despawn_afk = text2num(value)
|
||||
|
||||
if("auto_cryo_ssd_mins")
|
||||
config.auto_cryo_ssd_mins = text2num(value)
|
||||
if("ssd_warning")
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
#define AFK_WARNED 1
|
||||
#define AFK_CRYOD 2
|
||||
|
||||
SUBSYSTEM_DEF(afk)
|
||||
name = "AFK Watcher"
|
||||
wait = 300
|
||||
flags = SS_BACKGROUND
|
||||
var/list/afk_players = list() // Associative list. ckey as key and AFK state as value
|
||||
|
||||
|
||||
/datum/controller/subsystem/afk/Initialize()
|
||||
if(config.warn_afk_minimum <= 0 || config.auto_cryo_afk <= 0 || config.auto_despawn_afk <= 0)
|
||||
flags |= SS_NO_FIRE
|
||||
|
||||
/datum/controller/subsystem/afk/fire()
|
||||
var/list/toRemove = list()
|
||||
for(var/mob/living/carbon/human/H in GLOB.living_mob_list)
|
||||
if(!H.ckey) // Useless non ckey creatures
|
||||
continue
|
||||
|
||||
var/turf/T
|
||||
// Only players and players with the AFK watch enabled
|
||||
// No dead, unconcious, restrained, people without jobs, people on other Z levels than the station or antags
|
||||
if(!H.client || !H.client.prefs.afk_watch || !H.mind || \
|
||||
H.stat || H.restrained() || !H.job || H.mind.special_role || \
|
||||
!is_station_level((T = get_turf(H)).z)) // Assign the turf as last. Small optimization
|
||||
if(afk_players[H.ckey])
|
||||
toRemove += H.ckey
|
||||
continue
|
||||
|
||||
var/mins_afk = round(H.client.inactivity / 600)
|
||||
if(mins_afk < config.warn_afk_minimum)
|
||||
if(afk_players[H.ckey])
|
||||
toRemove += H.ckey
|
||||
continue
|
||||
|
||||
if(!afk_players[H.ckey])
|
||||
afk_players[H.ckey] = AFK_WARNED
|
||||
warn(H, "<span class='danger'>You are AFK for [mins_afk] minutes. You will be cryod after [config.auto_cryo_afk] total minutes and fully despawned after [config.auto_despawn_afk] total minutes. Please move or click in game if you want to avoid being despawned.</span>")
|
||||
else
|
||||
var/area/A = T.loc // Turfs loc is the area
|
||||
if(afk_players[H.ckey] == AFK_WARNED)
|
||||
if(mins_afk >= config.auto_cryo_afk && A.can_get_auto_cryod)
|
||||
if(A.fast_despawn)
|
||||
toRemove += H.ckey
|
||||
warn(H, "<span class='danger'>You are have been despawned after being AFK for [mins_afk] minutes. You have been despawned instantly due to you being in a secure area.</span>")
|
||||
msg_admins(H, mins_afk, T, "forcefully despawned", "AFK in a fast despawn area")
|
||||
force_cryo_human(H)
|
||||
else if(cryo_ssd(H))
|
||||
afk_players[H.ckey] = AFK_CRYOD
|
||||
msg_admins(H, mins_afk, T, "put into cryostorage")
|
||||
warn(H, "<span class='danger'>You are AFK for [mins_afk] minutes and have been moved to cryostorage. After being AFK for [config.auto_despawn_afk] total minutes you will be fully despawned. Please eject yourself (right click, eject) out of the cryostorage if you want to avoid being despawned.</span>")
|
||||
|
||||
else if(mins_afk >= config.auto_despawn_afk)
|
||||
var/obj/machinery/cryopod/P = H.loc
|
||||
msg_admins(H, mins_afk, T, "forcefully despawned")
|
||||
warn(H, "<span class='danger'>You are have been despawned after being AFK for [mins_afk] minutes.</span>")
|
||||
toRemove += H.ckey
|
||||
P.despawn_occupant()
|
||||
|
||||
removeFromWatchList(toRemove)
|
||||
|
||||
/datum/controller/subsystem/afk/proc/warn(mob/living/carbon/human/H, text)
|
||||
to_chat(H, text)
|
||||
SEND_SOUND(H, 'sound/effects/adminhelp.ogg')
|
||||
if(H.client)
|
||||
window_flash(H.client)
|
||||
|
||||
/datum/controller/subsystem/afk/proc/msg_admins(mob/living/carbon/human/H, mins_afk, turf/location, action, info)
|
||||
log_admin("[key_name(H)] has been [action] by the AFK Watcher subsystem after being AFK for [mins_afk] minutes.[info ? " Extra info:" + info : ""]")
|
||||
message_admins("[key_name_admin(H)] at ([get_area(location).name] [ADMIN_JMP(location)]) has been [action] by the AFK Watcher subsystem after being AFK for [mins_afk] minutes.[info ? " Extra info:" + info : ""]")
|
||||
|
||||
/datum/controller/subsystem/afk/proc/removeFromWatchList(list/toRemove)
|
||||
for(var/C in toRemove)
|
||||
for(var/i in 1 to afk_players.len)
|
||||
if(afk_players[i] == C)
|
||||
afk_players.Cut(i, i + 1)
|
||||
break
|
||||
|
||||
#undef AFK_WARNED
|
||||
#undef AFK_CRYOD
|
||||
@@ -1400,10 +1400,12 @@ var/list/ghostteleportlocs = list()
|
||||
name = "\improper Prison Wing"
|
||||
icon_state = "sec_prison_perma"
|
||||
fast_despawn = TRUE
|
||||
can_get_auto_cryod = FALSE
|
||||
|
||||
/area/security/prison
|
||||
name = "\improper Prison Wing"
|
||||
icon_state = "sec_prison"
|
||||
can_get_auto_cryod = FALSE
|
||||
|
||||
/area/security/prison/prison_break()
|
||||
for(var/obj/structure/closet/secure_closet/brig/temp_closet in src)
|
||||
@@ -1432,14 +1434,17 @@ var/list/ghostteleportlocs = list()
|
||||
/area/security/execution
|
||||
name = "\improper Execution"
|
||||
icon_state = "execution"
|
||||
can_get_auto_cryod = FALSE
|
||||
|
||||
/area/security/processing
|
||||
name = "\improper Prisoner Processing"
|
||||
icon_state = "prisonerprocessing"
|
||||
can_get_auto_cryod = FALSE
|
||||
|
||||
/area/security/interrogation
|
||||
name = "\improper Interrogation"
|
||||
icon_state = "interrogation"
|
||||
can_get_auto_cryod = FALSE
|
||||
|
||||
/area/security/seceqstorage
|
||||
name = "\improper Security Equipment Storage"
|
||||
@@ -1456,6 +1461,7 @@ var/list/ghostteleportlocs = list()
|
||||
/area/security/interrogationobs
|
||||
name = "\improper Interrogation Observation"
|
||||
icon_state = "security"
|
||||
can_get_auto_cryod = FALSE
|
||||
|
||||
/area/security/evidence
|
||||
name = "\improper Evidence Room"
|
||||
@@ -1464,6 +1470,7 @@ var/list/ghostteleportlocs = list()
|
||||
/area/security/prisonlockers
|
||||
name = "\improper Prisoner Lockers"
|
||||
icon_state = "sec_prison_lockers"
|
||||
can_get_auto_cryod = FALSE
|
||||
|
||||
/area/security/medbay
|
||||
name = "\improper Security Medbay"
|
||||
@@ -1472,6 +1479,7 @@ var/list/ghostteleportlocs = list()
|
||||
/area/security/prisonershuttle
|
||||
name = "\improper Security Prisoner Shuttle"
|
||||
icon_state = "security"
|
||||
can_get_auto_cryod = FALSE
|
||||
|
||||
/area/security/warden
|
||||
name = "\improper Warden's Office"
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
'sound/ambience/ambigen12.ogg','sound/ambience/ambigen14.ogg')
|
||||
|
||||
var/fast_despawn = FALSE
|
||||
var/can_get_auto_cryod = TRUE
|
||||
|
||||
/area/Initialize(mapload)
|
||||
GLOB.all_areas += src
|
||||
|
||||
@@ -93,6 +93,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
var/clientfps = 0
|
||||
var/atklog = ATKLOG_ALL
|
||||
var/fuid // forum userid
|
||||
var/afk_watch = FALSE // If the player wants to be kept track of by the AFK system
|
||||
|
||||
//ghostly preferences
|
||||
var/ghost_anonsay = 0
|
||||
@@ -439,6 +440,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
dat += "<h2>General Settings</h2>"
|
||||
if(user.client.holder)
|
||||
dat += "<b>Adminhelp sound:</b> <a href='?_src_=prefs;preference=hear_adminhelps'><b>[(sound & SOUND_ADMINHELP)?"On":"Off"]</b></a><br>"
|
||||
dat += "<b>AFK Cryoing:</b> <a href='?_src_=prefs;preference=afk_watch'>[(afk_watch) ? "Yes" : "No"]</a><br>"
|
||||
dat += "<b>Ambient Occlusion:</b> <a href='?_src_=prefs;preference=ambientocclusion'><b>[toggles & AMBIENT_OCCLUSION ? "Enabled" : "Disabled"]</b></a><br>"
|
||||
dat += "<b>Attack Animations:</b> <a href='?_src_=prefs;preference=ghost_att_anim'>[(show_ghostitem_attack) ? "Yes" : "No"]</a><br>"
|
||||
if(unlock_content)
|
||||
@@ -1977,6 +1979,9 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
if("winflash")
|
||||
windowflashing = !windowflashing
|
||||
|
||||
if("afk_watch")
|
||||
afk_watch = !afk_watch
|
||||
|
||||
if("UIcolor")
|
||||
var/UI_style_color_new = input(user, "Choose your UI color, dark colors are not recommended!", UI_style_color) as color|null
|
||||
if(!UI_style_color_new) return
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
exp,
|
||||
clientfps,
|
||||
atklog,
|
||||
fuid
|
||||
fuid,
|
||||
afk_watch
|
||||
FROM [format_table_name("player")]
|
||||
WHERE ckey='[C.ckey]'"}
|
||||
)
|
||||
@@ -52,6 +53,7 @@
|
||||
clientfps = text2num(query.item[17])
|
||||
atklog = text2num(query.item[18])
|
||||
fuid = text2num(query.item[19])
|
||||
afk_watch = text2num(query.item[20])
|
||||
|
||||
//Sanitize
|
||||
ooccolor = sanitize_hexcolor(ooccolor, initial(ooccolor))
|
||||
@@ -72,6 +74,7 @@
|
||||
clientfps = sanitize_integer(clientfps, 0, 1000, initial(clientfps))
|
||||
atklog = sanitize_integer(atklog, 0, 100, initial(atklog))
|
||||
fuid = sanitize_integer(fuid, 0, 10000000, initial(fuid))
|
||||
afk_watch = sanitize_integer(afk_watch, 0, 1, initial(afk_watch))
|
||||
return 1
|
||||
|
||||
/datum/preferences/proc/save_preferences(client/C)
|
||||
@@ -101,7 +104,8 @@
|
||||
windowflashing='[windowflashing]',
|
||||
ghost_anonsay='[ghost_anonsay]',
|
||||
clientfps='[clientfps]',
|
||||
atklog='[atklog]'
|
||||
atklog='[atklog]',
|
||||
afk_watch='[afk_watch]'
|
||||
WHERE ckey='[C.ckey]'"}
|
||||
)
|
||||
|
||||
|
||||
@@ -85,6 +85,16 @@ LOG_WORLD_OUTPUT
|
||||
## log admin warning messages
|
||||
LOG_ADMINWARN
|
||||
|
||||
|
||||
## Amount of minutes that a person has to be AFK before he will be warned by the AFK subsystem. Leave this 0 to prevent the subsystem from activating
|
||||
WARN_AFK_MINIMUM 0
|
||||
|
||||
## Amount of minutes that a person has to be AFK before he will be cryod by the AFK subsystem. Leave this 0 to prevent the subsystem from activating
|
||||
AUTO_CRYO_AFK 0
|
||||
|
||||
## Amount of minutes that a person has to be AFK before he will be despawned by the AFK subsystem. Leave this 0 to prevent the subsystem from activating
|
||||
AUTO_DESPAWN_AFK 0
|
||||
|
||||
## probablities for game modes chosen in "secret" and "random" modes
|
||||
##
|
||||
## default probablity is 1, increase to make that mode more likely to be picked
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
## This value must be set to the version of the paradise schema in use.
|
||||
## If this value does not match, the SQL database will not be loaded and an error will be generated.
|
||||
## Roundstart will be delayed.
|
||||
DB_VERSION 7
|
||||
DB_VERSION 8
|
||||
|
||||
## Server the MySQL database can be found at.
|
||||
# Examples: localhost, 200.135.5.43, www.mysqldb.com, etc.
|
||||
|
||||
@@ -198,6 +198,7 @@
|
||||
#include "code\controllers\master.dm"
|
||||
#include "code\controllers\subsystem.dm"
|
||||
#include "code\controllers\verbs.dm"
|
||||
#include "code\controllers\subsystem\afk.dm"
|
||||
#include "code\controllers\subsystem\air.dm"
|
||||
#include "code\controllers\subsystem\alarm.dm"
|
||||
#include "code\controllers\subsystem\assets.dm"
|
||||
|
||||
Reference in New Issue
Block a user