From 6a51b4585a665ab49d2e795ffd80d5f9d50b7d59 Mon Sep 17 00:00:00 2001 From: Lucy Date: Thu, 28 Nov 2024 22:42:28 -0500 Subject: [PATCH] Refactor patreon+twitch data to be linked to `/datum/player_details` rather than `/client` --- code/controllers/subsystem/vote.dm | 10 +++-- code/datums/mocking/client.dm | 12 +++++ code/modules/client/player_details.dm | 20 ++++----- code/modules/client/verbs/ooc.dm | 4 +- monkestation/code/datums/meta_tokens.dm | 9 ++-- monkestation/code/datums/patreon_data.dm | 44 +++++-------------- monkestation/code/datums/twitch_data.dm | 37 +++++----------- .../code/modules/client/player_details.dm | 32 ++++++++++++++ .../modules/client/preferences/inventory.dm | 6 +-- .../modules/ghost_critters/client_addons.dm | 6 +-- .../modules/loadouts/loadout_middleware.dm | 8 ++-- monkestation/code/modules/mob/login.dm | 6 --- .../code/modules/store/store_items/__store.dm | 2 +- tgstation.dme | 1 + 14 files changed, 100 insertions(+), 97 deletions(-) create mode 100644 monkestation/code/modules/client/player_details.dm diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 8698fcdbdc65..809b817fe45a 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -106,13 +106,14 @@ SUBSYSTEM_DEF(vote) // monkestation start if(!current_vote.can_vote(voter)) return + var/patreon_rank = get_player_details(voter)?.patreon?.access_rank // monkestation end // If user has already voted, remove their specific vote if(voter.ckey in current_vote.choices_by_ckey) var/their_old_vote = current_vote.choices_by_ckey[voter.ckey] //monkestation edit start - if(current_vote.donator_multiplier && voter?.client?.patreon?.access_rank >= 3) + if(current_vote.donator_multiplier && patreon_rank >= 3) current_vote.choices[their_old_vote] -= current_vote.donator_multiplier else current_vote.choices[their_old_vote]-- @@ -122,7 +123,7 @@ SUBSYSTEM_DEF(vote) current_vote.choices_by_ckey[voter.ckey] = their_vote //monkestation edit start - if(current_vote.donator_multiplier && voter?.client?.patreon?.access_rank >= 3) + if(current_vote.donator_multiplier && patreon_rank >= 3) current_vote.choices[their_vote] += current_vote.donator_multiplier else current_vote.choices[their_vote]++ @@ -140,6 +141,7 @@ SUBSYSTEM_DEF(vote) // monkestation start if(!current_vote.can_vote(voter)) return + var/patreon_rank = get_player_details(voter)?.patreon?.access_rank // monkestation end if(CONFIG_GET(flag/no_dead_vote) && voter.stat == DEAD && !voter.client?.holder) return @@ -149,7 +151,7 @@ SUBSYSTEM_DEF(vote) if(current_vote.choices_by_ckey[voter.ckey + their_vote] == 1) current_vote.choices_by_ckey[voter.ckey + their_vote] = 0 //monkestation edit start - if(current_vote.donator_multiplier && voter?.client?.patreon?.access_rank >= 3) + if(current_vote.donator_multiplier && patreon_rank >= 3) current_vote.choices[their_vote] -= current_vote.donator_multiplier else current_vote.choices[their_vote]-- @@ -158,7 +160,7 @@ SUBSYSTEM_DEF(vote) else current_vote.choices_by_ckey[voter.ckey + their_vote] = 1 //monkestation edit start - if(current_vote.donator_multiplier && voter?.client?.patreon?.access_rank >= 3) + if(current_vote.donator_multiplier && patreon_rank >= 3) current_vote.choices[their_vote] += current_vote.donator_multiplier else current_vote.choices[their_vote]++ diff --git a/code/datums/mocking/client.dm b/code/datums/mocking/client.dm index d3a3ff461632..22f249a6fbf1 100644 --- a/code/datums/mocking/client.dm +++ b/code/datums/mocking/client.dm @@ -29,6 +29,10 @@ var/datum/interaction_mode/imode var/context_menu_requires_shift = FALSE + ///these persist between logins/logouts during the same round. + var/datum/player_details/player_details + var/reconnecting = FALSE + /datum/client_interface/proc/IsByondMember() return FALSE @@ -37,6 +41,14 @@ if(key) src.key = key ckey = ckey(key) + if(GLOB.player_details[ckey]) + reconnecting = TRUE + player_details = GLOB.player_details[ckey] + else + player_details = new(ckey) + player_details.byond_version = world.byond_version + player_details.byond_build = world.byond_build + GLOB.player_details[ckey] = player_details /datum/client_interface/proc/set_macros() return diff --git a/code/modules/client/player_details.dm b/code/modules/client/player_details.dm index d83ef344aae3..658d6f578887 100644 --- a/code/modules/client/player_details.dm +++ b/code/modules/client/player_details.dm @@ -3,6 +3,8 @@ GLOBAL_LIST_EMPTY_TYPED(player_details, /datum/player_details) /datum/player_details + /// The ckey of the player this is tied to. + var/ckey /// Action datums assigned to this player var/list/datum/action/player_actions = list() /// Tracks client action logging @@ -21,8 +23,9 @@ GLOBAL_LIST_EMPTY_TYPED(player_details, /datum/player_details) /// Tracks achievements they have earned var/datum/achievement_data/achievements -/datum/player_details/New(key) - achievements = new(key) +/datum/player_details/New(player_key) + src.ckey = ckey(player_key) + achievements = new(src.ckey) /// Returns the full version string (i.e 515.1642) of the BYOND version and build. /datum/player_details/proc/full_byond_version() @@ -31,13 +34,10 @@ GLOBAL_LIST_EMPTY_TYPED(player_details, /datum/player_details) return "[byond_version].[byond_build || "xxx"]" /proc/log_played_names(ckey, ...) - if(!ckey) - return - if(args.len < 2) + if(!ckey || length(args) < 2) return var/list/names = args.Copy(2) - var/datum/player_details/P = GLOB.player_details[ckey] - if(P) - for(var/name in names) - if(name) - P.played_names |= name + var/datum/player_details/details = GLOB.player_details[ckey] + for(var/name in names) + if(name) + details.played_names |= name diff --git a/code/modules/client/verbs/ooc.dm b/code/modules/client/verbs/ooc.dm index bc2b683882f2..a431c21ef227 100644 --- a/code/modules/client/verbs/ooc.dm +++ b/code/modules/client/verbs/ooc.dm @@ -81,11 +81,11 @@ GLOBAL_VAR_INIT(normal_ooc_colour, "#002eb8") var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/chat) keyname = "[sheet.icon_tag("emoji-heart")][keyname]" - if(patreon.access_rank > 0) + if(player_details.patreon.access_rank > 0) var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/chat) keyname = "[sheet.icon_tag("patreon")][keyname]" - if(twitch.access_rank > 0) + if(player_details.twitch.access_rank > 0) var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/chat) keyname = "[sheet.icon_tag("twitch")][keyname]" diff --git a/monkestation/code/datums/meta_tokens.dm b/monkestation/code/datums/meta_tokens.dm index c6ce6bae780e..b1ff622e8870 100644 --- a/monkestation/code/datums/meta_tokens.dm +++ b/monkestation/code/datums/meta_tokens.dm @@ -88,15 +88,14 @@ GLOBAL_LIST_INIT(patreon_etoken_values, list( owner.prefs.save_preferences() /datum/meta_token_holder/proc/check_for_donator_token() - if(!owner.patreon) + var/datum/patreon_data/patreon = owner?.player_details?.patreon + if(!patreon?.has_access(ACCESS_COMMAND_RANK)) return FALSE - if(!owner.patreon.has_access(ACCESS_COMMAND_RANK)) - return var/month_number = text2num(time2text(world.time, "MM")) owner.prefs.token_month = month_number if(owner.prefs.token_month != month_number) owner.prefs.adjust_metacoins(owner?.ckey, 10000, "Monthly Monkecoin rations.", TRUE, FALSE, FALSE) - if(!owner.patreon.has_access(ACCESS_TRAITOR_RANK)) + if(!patreon.has_access(ACCESS_TRAITOR_RANK)) owner.prefs.save_preferences() return FALSE if(owner.prefs.token_month == month_number) @@ -193,7 +192,7 @@ GLOBAL_LIST_INIT(patreon_etoken_values, list( var/month_number = text2num(time2text(world.time, "MM")) if(event_token_month != month_number) event_token_month = month_number - event_tokens = GLOB.patreon_etoken_values[checked_client.patreon.owned_rank] + event_tokens = GLOB.patreon_etoken_values[checked_client.player_details.patreon.owned_rank] convert_tokens_to_list() /datum/meta_token_holder/proc/approve_token_event() diff --git a/monkestation/code/datums/patreon_data.dm b/monkestation/code/datums/patreon_data.dm index c1ee4bc83ed4..f4f55a7a702f 100644 --- a/monkestation/code/datums/patreon_data.dm +++ b/monkestation/code/datums/patreon_data.dm @@ -1,9 +1,6 @@ -/client - var/datum/patreon_data/patreon - /datum/patreon_data - ///the client that owns this data - var/client/owner + /// The details of the linked player. + var/datum/player_details/owner ///the stored patreon client key for the information var/client_key ///the stored patreon rank collected from the server @@ -12,42 +9,27 @@ var/access_rank = 0 -/datum/patreon_data/New(client/created_client) +/datum/patreon_data/New(datum/player_details/owner) . = ..() - if(!created_client) + if(!owner) return - + src.owner = owner if(!SSdbcore.IsConnected()) owned_rank = NUKIE_RANK ///this is a testing variable return - owner = created_client - - fetch_key(owner.ckey) - fetch_rank(owner.ckey) - + fetch_key_and_rank() assign_access_rank() - -/datum/patreon_data/proc/fetch_key(ckey) - var/datum/db_query/query_get_key = SSdbcore.NewQuery("SELECT patreon_key FROM [format_table_name("player")] WHERE ckey = '[ckey]'") +/datum/patreon_data/proc/fetch_key_and_rank() + var/datum/db_query/query_get_key = SSdbcore.NewQuery("SELECT patreon_key, patreon_rank FROM [format_table_name("player")] WHERE ckey = :ckey", list("ckey" = owner.ckey)) if(query_get_key.warn_execute()) if(query_get_key.NextRow()) client_key = query_get_key.item[1] - qdel(query_get_key) - -/datum/patreon_data/proc/fetch_rank(ckey) - var/datum/db_query/query_get_rank = SSdbcore.NewQuery("SELECT patreon_rank FROM [format_table_name("player")] WHERE ckey = '[ckey]'") - if(query_get_rank.warn_execute()) - if(query_get_rank.NextRow()) - if(query_get_rank.item[1]) - owned_rank = query_get_rank.item[1] - if(owned_rank == "UNSUBBED2") - owned_rank = NO_RANK - else + owned_rank = query_get_key.item[2] + if(owned_rank == "UNSUBBED2") owned_rank = NO_RANK - qdel(query_get_rank) - + qdel(query_get_key) /datum/patreon_data/proc/assign_access_rank() switch(owned_rank) @@ -70,6 +52,4 @@ return FALSE /datum/patreon_data/proc/is_donator() - if((owned_rank == NO_RANK) || !owned_rank || (owned_rank == UNSUBBED)) - return FALSE - return TRUE + return owned_rank && owned_rank != NO_RANK && owned_rank != UNSUBBED diff --git a/monkestation/code/datums/twitch_data.dm b/monkestation/code/datums/twitch_data.dm index 7197a30e2681..4d52f9dd6fb9 100644 --- a/monkestation/code/datums/twitch_data.dm +++ b/monkestation/code/datums/twitch_data.dm @@ -1,9 +1,6 @@ -/client - var/datum/twitch_data/twitch - /datum/twitch_data - ///the client that owns this data - var/client/owner + /// The details of the linked player. + var/datum/player_details/owner ///the stored twitch client key for the information var/client_key ///the stored twitch rank collected from the server @@ -11,35 +8,23 @@ ///access rank in numbers var/access_rank = 0 - - - -/datum/twitch_data/New(client/created_client) +/datum/twitch_data/New(datum/player_details/owner) . = ..() - if(!created_client) + if(!owner) return - + src.owner = owner if(!SSdbcore.IsConnected()) owned_rank = ACCESS_TWITCH_SUB_TIER_3 ///this is a testing variable return - owner = created_client - - fetch_rank(owner.ckey) - + fetch_rank() assign_twitch_rank() - -/datum/twitch_data/proc/fetch_rank(ckey) - var/datum/db_query/query_get_rank = SSdbcore.NewQuery("SELECT twitch_rank FROM [format_table_name("player")] WHERE ckey = '[ckey]'") +/datum/twitch_data/proc/fetch_rank() + var/datum/db_query/query_get_rank = SSdbcore.NewQuery("SELECT twitch_rank FROM [format_table_name("player")] WHERE ckey = :ckey", list("ckey" = owner.ckey)) if(query_get_rank.warn_execute()) if(query_get_rank.NextRow()) - if(query_get_rank.item[1]) - owned_rank = query_get_rank.item[1] - if(owned_rank == "") - owned_rank = NO_TWITCH_SUB - else - owned_rank = NO_TWITCH_SUB + owned_rank = query_get_rank.item[1] || NO_TWITCH_SUB qdel(query_get_rank) @@ -60,6 +45,4 @@ return FALSE /datum/twitch_data/proc/is_donator() - if(owned_rank != NO_TWITCH_SUB) - return TRUE - return FALSE + return owned_rank != NO_TWITCH_SUB diff --git a/monkestation/code/modules/client/player_details.dm b/monkestation/code/modules/client/player_details.dm new file mode 100644 index 000000000000..5e24cc9bde28 --- /dev/null +++ b/monkestation/code/modules/client/player_details.dm @@ -0,0 +1,32 @@ +/datum/player_details + /// Patreon data for this player. + var/datum/patreon_data/patreon + /// Twitch subscription data for this player. + var/datum/twitch_data/twitch + +/datum/player_details/New(player_key) + . = ..() + patreon = new(src) + twitch = new(src) + +/** + * Gets a player details instance from a variable, whether it be a mob, a client, or a ckey. + */ +/proc/get_player_details(target) as /datum/player_details + RETURN_TYPE(/datum/player_details) + if(istext(target)) + return GLOB.player_details[ckey(target)] + else if(ismob(target)) + var/mob/mob_target = target + // Check to see if there's a client first. + . = mob_target.client?.player_details + if(!. && mob_target.ckey) + // Do they have a ckey? Let's try that. + var/mob_ckey = replacetext(mob_target.ckey, "@", "") + return GLOB.player_details[mob_ckey] + else if(IS_CLIENT_OR_MOCK(target)) + var/datum/client_interface/client_target = target + return client_target.player_details + else if(istype(target, /datum/player_details)) + return target // well, that was easy + diff --git a/monkestation/code/modules/client/preferences/inventory.dm b/monkestation/code/modules/client/preferences/inventory.dm index b6f328a4f2d3..dee691acd938 100644 --- a/monkestation/code/modules/client/preferences/inventory.dm +++ b/monkestation/code/modules/client/preferences/inventory.dm @@ -44,16 +44,16 @@ max_round_coins -= amount //Patreon Flat Roundend Bonus - if((parent.patreon?.has_access(2)) && donator_multipler) + if((parent.player_details.patreon?.has_access(2)) && donator_multipler) amount += DONATOR_ROUNDEND_BONUS //Twitch Flat Roundend Bonus - if((parent.twitch?.has_access(1)) && donator_multipler) + if((parent.player_details.twitch?.has_access(1)) && donator_multipler) amount += DONATOR_ROUNDEND_BONUS //Donator Multiplier if(amount > 0 && donator_multipler) - switch(parent.patreon.access_rank) + switch(parent.player_details.patreon.access_rank) if(ACCESS_COMMAND_RANK) amount *= 1.5 if(ACCESS_TRAITOR_RANK) diff --git a/monkestation/code/modules/ghost_critters/client_addons.dm b/monkestation/code/modules/ghost_critters/client_addons.dm index e0fe4cd10bca..60c1ce163d32 100644 --- a/monkestation/code/modules/ghost_critters/client_addons.dm +++ b/monkestation/code/modules/ghost_critters/client_addons.dm @@ -15,7 +15,7 @@ mobs_to_pick += return_donator_mobs() - if(!patreon.has_access(ACCESS_ASSISTANT_RANK) && !is_admin(src) && !length(mobs_to_pick)) + if(!player_details.patreon.has_access(ACCESS_ASSISTANT_RANK) && !is_admin(src) && !length(mobs_to_pick)) return pick(basic_list) mobs_to_pick += basic_list @@ -47,7 +47,7 @@ var/cooldown_time = get_critter_cooldown() ghost_critter_cooldown = cooldown_time - if(patreon.has_access(ACCESS_NUKIE_RANK) || is_admin(src)) + if(player_details.patreon.has_access(ACCESS_NUKIE_RANK) || is_admin(src)) created_mob.AddComponent(/datum/component/basic_inhands, y_offset = -6) created_mob.AddComponent(/datum/component/max_held_weight, WEIGHT_CLASS_SMALL) created_mob.AddElement(/datum/element/dextrous) @@ -64,7 +64,7 @@ /client/proc/get_critter_cooldown() var/base_time = 25 MINUTES - switch(patreon.access_rank) + switch(player_details.patreon.access_rank) if(0, 1) return base_time if(2) diff --git a/monkestation/code/modules/loadouts/loadout_middleware.dm b/monkestation/code/modules/loadouts/loadout_middleware.dm index 10816e827232..8b2b698d29b2 100644 --- a/monkestation/code/modules/loadouts/loadout_middleware.dm +++ b/monkestation/code/modules/loadouts/loadout_middleware.dm @@ -58,7 +58,7 @@ data["selected_loadout"] = all_selected_paths data["selected_unusuals"] = all_selected_unusuals - data["user_is_donator"] = !!(preferences.parent.patreon?.is_donator() || preferences.parent.twitch?.is_donator() || is_admin(preferences.parent)) + data["user_is_donator"] = !!(preferences.parent.player_details.patreon?.is_donator() || preferences.parent.player_details.twitch?.is_donator() || is_admin(preferences.parent)) data["mob_name"] = preferences.read_preference(/datum/preference/name/real_name) data["ismoth"] = istype(preferences.parent.prefs.read_preference(/datum/preference/choiced/species), /datum/species/moth) // Moth's humanflaticcon isn't the same dimensions for some reason data["total_coins"] = preferences.metacoins @@ -74,7 +74,7 @@ return null //Here we will perform basic checks to ensure there are no exploits happening - if(interacted_item.donator_only && !preferences.parent.patreon?.is_donator() && !preferences.parent.twitch?.is_donator() && !is_admin(preferences.parent)) + if(interacted_item.donator_only && !preferences.parent.player_details.patreon?.is_donator() && !preferences.parent.player_details.twitch?.is_donator() && !is_admin(preferences.parent)) message_admins("LOADOUT SYSTEM: Possible exploit detected, non-donator [preferences.parent.ckey] tried loading [interacted_item.item_path], but this is donator only.") return null @@ -156,7 +156,7 @@ formatted_list.len-- continue if(item.donator_only) //These checks are also performed in the backend. - if((!preferences.parent.patreon?.is_donator() && !preferences.parent.twitch?.is_donator()) && !is_admin(preferences.parent)) + if((!preferences.parent.player_details.patreon?.is_donator() && !preferences.parent.player_details.twitch?.is_donator()) && !is_admin(preferences.parent)) formatted_list.len-- continue @@ -315,7 +315,7 @@ to_chat(preferences.parent, examine_block(span_green("This item is restricted to your ckey only. Thank you!"))) /datum/preference_middleware/loadout/proc/donator_explain(list/params, mob/user) - if(preferences.parent.patreon?.is_donator() || preferences.parent.twitch?.is_donator()) + if(preferences.parent.player_details.patreon?.is_donator() || preferences.parent.player_details.twitch?.is_donator()) to_chat(preferences.parent, examine_block("Thank you for donating, this item is for you <3!")) else to_chat(preferences.parent, examine_block(span_boldnotice("This item is restricted to donators only, for more information, please check the discord(#server-info) for more information!"))) diff --git a/monkestation/code/modules/mob/login.dm b/monkestation/code/modules/mob/login.dm index 0c20722e48d1..79792e93dddd 100644 --- a/monkestation/code/modules/mob/login.dm +++ b/monkestation/code/modules/mob/login.dm @@ -3,12 +3,6 @@ if(!. || QDELETED(client)) return FALSE - if(QDELETED(client?.patreon)) - client?.patreon = new(client) - - if(QDELETED(client?.twitch)) - client?.twitch = new(client) - if(QDELETED(client?.client_token_holder)) if(!client?.prefs.loaded) CRASH("Tried to load client_token's on a logging in mob but prefs haven't loaded.") diff --git a/monkestation/code/modules/store/store_items/__store.dm b/monkestation/code/modules/store/store_items/__store.dm index 2cbf4b60d8e8..6f25c340f6b9 100644 --- a/monkestation/code/modules/store/store_items/__store.dm +++ b/monkestation/code/modules/store/store_items/__store.dm @@ -127,7 +127,7 @@ GLOBAL_LIST_EMPTY(all_store_datums) var/list/all_selected_paths = list() for(var/path in owner?.prefs?.loadout_list) all_selected_paths += path - data["user_is_donator"] = !!(owner.patreon?.is_donator() || owner.twitch?.is_donator() || is_admin(owner)) + data["user_is_donator"] = !!(owner.player_details.patreon.is_donator() || owner.player_details.twitch.is_donator() || is_admin(owner)) data["owned_items"] = user.client.prefs.inventory data["total_coins"] = user.client.prefs.metacoins diff --git a/tgstation.dme b/tgstation.dme index ecb1e4c86e75..1bd5c348af23 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -7020,6 +7020,7 @@ #include "monkestation\code\modules\cassettes\machines\media\subsystem\media_track_manager.dm" #include "monkestation\code\modules\cassettes\walkman\_walkmen.dm" #include "monkestation\code\modules\client\client_colour.dm" +#include "monkestation\code\modules\client\player_details.dm" #include "monkestation\code\modules\client\preference_savefile.dm" #include "monkestation\code\modules\client\preferences.dm" #include "monkestation\code\modules\client\verbs.dm"