mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-26 22:50:26 +01:00
Base implementation of /datum/persistent_client (#89449)
## About The Pull Request Converts `/datum/player_details` into `/datum/persistent_client`. Persistent Clients persist across connections. The only time a mob's persistent client will change is if the ckey it's bound to logs into a different mob, or the mob is deleted (duh). Also adds PossessByPlayer() so that transfering mob control is cleaner and makes more immediate sense if you don't know byond-fu. ## Why It's Good For The Game Clients are an abstract representation of a connection that can be dropped at almost any moment so putting things that should be stable to access at any time onto an undying object is ideal. This allows for future expansions like abstracting away client.screen and managing everything cleanly.
This commit is contained in:
@@ -138,7 +138,7 @@
|
||||
var/list/credits
|
||||
|
||||
///these persist between logins/logouts during the same round.
|
||||
var/datum/player_details/player_details
|
||||
var/datum/persistent_client/persistent_client
|
||||
|
||||
///Should only be a key-value list of north/south/east/west = atom/movable/screen.
|
||||
var/list/char_render_holders
|
||||
|
||||
@@ -249,6 +249,17 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
|
||||
GLOB.clients += src
|
||||
GLOB.directory[ckey] = src
|
||||
|
||||
var/reconnecting = FALSE
|
||||
if(GLOB.persistent_clients_by_ckey[ckey])
|
||||
reconnecting = TRUE
|
||||
persistent_client = GLOB.persistent_clients_by_ckey[ckey]
|
||||
persistent_client.byond_build = byond_build
|
||||
persistent_client.byond_version = byond_version
|
||||
else
|
||||
persistent_client = new(ckey)
|
||||
persistent_client.byond_build = byond_build
|
||||
persistent_client.byond_version = byond_version
|
||||
|
||||
if(byond_version >= 516)
|
||||
winset(src, null, list("browser-options" = "find,refresh,byondstorage"))
|
||||
|
||||
@@ -328,18 +339,6 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
|
||||
else
|
||||
message_admins(span_danger("<B>[message_type]: </B></span><span class='notice'>Connecting player [key_name_admin(src)] has the same [matches] as [joined_player_ckey](no longer logged in)<b>[in_round]</b>. "))
|
||||
log_admin_private("[message_type]: Connecting player [key_name(src)] has the same [matches] as [joined_player_ckey](no longer logged in)[in_round].")
|
||||
var/reconnecting = FALSE
|
||||
if(GLOB.player_details[ckey])
|
||||
reconnecting = TRUE
|
||||
player_details = GLOB.player_details[ckey]
|
||||
player_details.byond_version = byond_version
|
||||
player_details.byond_build = byond_build
|
||||
else
|
||||
player_details = new(ckey)
|
||||
player_details.byond_version = byond_version
|
||||
player_details.byond_build = byond_build
|
||||
GLOB.player_details[ckey] = player_details
|
||||
|
||||
|
||||
. = ..() //calls mob.Login()
|
||||
|
||||
@@ -586,6 +585,8 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
|
||||
|
||||
GLOB.clients -= src
|
||||
GLOB.directory -= ckey
|
||||
persistent_client.client = null
|
||||
|
||||
log_access("Logout: [key_name(src)]")
|
||||
GLOB.ahelp_tickets.ClientLogout(src)
|
||||
GLOB.interviews.client_logout(src)
|
||||
@@ -1040,11 +1041,11 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
|
||||
|
||||
///Redirect proc that makes it easier to call the unlock achievement proc. Achievement type is the typepath to the award, user is the mob getting the award, and value is an optional variable used for leaderboard value increments
|
||||
/client/proc/give_award(achievement_type, mob/user, value = 1)
|
||||
return player_details.achievements.unlock(achievement_type, user, value)
|
||||
return persistent_client.achievements.unlock(achievement_type, user, value)
|
||||
|
||||
///Redirect proc that makes it easier to get the status of an achievement. Achievement type is the typepath to the award.
|
||||
/client/proc/get_award_status(achievement_type, mob/user, value = 1)
|
||||
return player_details.achievements.get_achievement_status(achievement_type)
|
||||
return persistent_client.achievements.get_achievement_status(achievement_type)
|
||||
|
||||
///Gives someone hearted status for OOC, from behavior commendations
|
||||
/client/proc/adjust_heart(duration = 24 HOURS)
|
||||
|
||||
@@ -1,55 +1,86 @@
|
||||
|
||||
///assoc list of ckey -> /datum/player_details
|
||||
GLOBAL_LIST_EMPTY_TYPED(player_details, /datum/player_details)
|
||||
///assoc list of ckey -> /datum/persistent_client
|
||||
GLOBAL_LIST_EMPTY_TYPED(persistent_clients_by_ckey, /datum/persistent_client)
|
||||
/// A flat list of all persistent clients, for her looping pleasure.
|
||||
GLOBAL_LIST_EMPTY_TYPED(persistent_clients, /datum/persistent_client)
|
||||
|
||||
/// Tracks information about a client between log in and log outs
|
||||
/datum/player_details
|
||||
/datum/persistent_client
|
||||
/// The true client
|
||||
var/client/client
|
||||
/// The mob this persistent client is currently bound to.
|
||||
var/mob/mob
|
||||
|
||||
/// Major version of BYOND this client is using.
|
||||
var/byond_version
|
||||
/// Build number of BYOND this client is using.
|
||||
var/byond_build
|
||||
|
||||
/// Action datums assigned to this player
|
||||
var/list/datum/action/player_actions = list()
|
||||
/// Tracks client action logging
|
||||
var/list/logging = list()
|
||||
|
||||
/// Callbacks invoked when this client logs in again
|
||||
var/list/post_login_callbacks = list()
|
||||
/// Callbacks invoked when this client logs out
|
||||
var/list/post_logout_callbacks = list()
|
||||
|
||||
/// List of names this key played under this round
|
||||
/// assoc list of name -> mob tag
|
||||
var/list/played_names = list()
|
||||
/// Lazylist of preference slots this client has joined the round under
|
||||
/// Numbers are stored as strings
|
||||
var/list/joined_as_slots
|
||||
/// Major version of BYOND this client is using.
|
||||
var/byond_version
|
||||
/// Build number of BYOND this client is using.
|
||||
var/byond_build
|
||||
|
||||
/// Tracks achievements they have earned
|
||||
var/datum/achievement_data/achievements
|
||||
|
||||
/// World.time this player last died
|
||||
var/time_of_death = 0
|
||||
|
||||
/datum/player_details/New(key)
|
||||
achievements = new(key)
|
||||
/datum/persistent_client/New(ckey, client)
|
||||
src.client = client
|
||||
achievements = new(ckey)
|
||||
GLOB.persistent_clients_by_ckey[ckey] = src
|
||||
GLOB.persistent_clients += src
|
||||
|
||||
/datum/persistent_client/Destroy(force)
|
||||
SHOULD_CALL_PARENT(FALSE)
|
||||
. = QDEL_HINT_LETMELIVE
|
||||
CRASH("Who the FUCK tried to delete a persistent client? Get your head checked you leadskull.")
|
||||
|
||||
/// Setter for the mob var, handles both references.
|
||||
/datum/persistent_client/proc/set_mob(mob/new_mob)
|
||||
if(mob == new_mob)
|
||||
return
|
||||
|
||||
mob?.persistent_client = null
|
||||
new_mob?.persistent_client?.set_mob(null)
|
||||
|
||||
mob = new_mob
|
||||
new_mob?.persistent_client = src
|
||||
|
||||
/// Writes all of the `played_names` into an HTML-escaped string.
|
||||
/datum/player_details/proc/get_played_names()
|
||||
/datum/persistent_client/proc/get_played_names()
|
||||
var/list/previous_names = list()
|
||||
for(var/previous_name in played_names)
|
||||
previous_names += html_encode("[previous_name] ([played_names[previous_name]])")
|
||||
return previous_names.Join("; ")
|
||||
|
||||
/// Returns the full version string (i.e 515.1642) of the BYOND version and build.
|
||||
/datum/player_details/proc/full_byond_version()
|
||||
/datum/persistent_client/proc/full_byond_version()
|
||||
if(!byond_version)
|
||||
return "Unknown"
|
||||
return "[byond_version].[byond_build || "xxx"]"
|
||||
|
||||
/// Adds the new names to the player's played_names list on their /datum/player_details for use of admins.
|
||||
/// Adds the new names to the player's played_names list on their /datum/persistent_client for use of admins.
|
||||
/// `ckey` should be their ckey, and `data` should be an associative list with the keys being the names they played under and the values being the unique mob ID tied to that name.
|
||||
/proc/log_played_names(ckey, data)
|
||||
if(!ckey)
|
||||
return
|
||||
|
||||
var/datum/player_details/writable = GLOB.player_details[ckey]
|
||||
var/datum/persistent_client/writable = GLOB.persistent_clients_by_ckey[ckey]
|
||||
if(isnull(writable))
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user