Skip to content

Commit

Permalink
adds player panel metadata (first join and account age) (#5873)
Browse files Browse the repository at this point in the history
![CleanShot 2024-03-03 at 20 01
40@2x](https://github.com/cmss13-devs/cmss13/assets/55142896/5d4b0c61-9214-4021-b6ce-91eabbdd10c3)


:cl:
admin: byond account age and first time connected to server can now be
seen in the player panel
/:cl:
  • Loading branch information
harryob authored Mar 5, 2024
1 parent 2f2633c commit 17ad642
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 1 deletion.
36 changes: 36 additions & 0 deletions code/datums/entities/player.dm
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@

var/stickyban_whitelisted = FALSE

var/byond_account_age
var/first_join_date


// UNTRACKED FIELDS
var/name // Used for NanoUI statistics menu
Expand Down Expand Up @@ -78,6 +81,8 @@ BSQL_PROTECT_DATUM(/datum/entity/player)
"migrated_bans" = DB_FIELDTYPE_INT,
"migrated_jobbans" = DB_FIELDTYPE_INT,
"stickyban_whitelisted" = DB_FIELDTYPE_INT,
"byond_account_age" = DB_FIELDTYPE_STRING_MEDIUM,
"first_join_date" = DB_FIELDTYPE_STRING_MEDIUM,
)

// NOTE: good example of database operations using NDatabase, so it is well commented
Expand Down Expand Up @@ -449,6 +454,31 @@ BSQL_PROTECT_DATUM(/datum/entity/player)
for(var/datum/entity/player_stat/S as anything in _stat)
LAZYSET(stats, S.stat_id, S)

/datum/entity/player/proc/load_byond_account_age()
var/datum/http_request/request = new()
request.prepare(RUSTG_HTTP_METHOD_GET, "https://www.byond.com/members/[ckey]?format=text")
request.execute_blocking()
var/datum/http_response/response = request.into_response()
if(response.errored)
return

var/static/regex/regex = regex("joined = \"(\\d{4}-\\d{2}-\\d{2})\"")
if(!regex.Find(response.body))
return

byond_account_age = regex.group[1]

/datum/entity/player/proc/find_first_join_date()
var/list/triplets = search_login_triplet_by_ckey(ckey)

if(!length(triplets))
first_join_date = "UNKNOWN"
return

var/datum/view_record/login_triplet/first_triplet = triplets[1]
first_join_date = first_triplet.login_date


/proc/get_player_from_key(key)
var/safe_key = ckey(key)
if(!safe_key)
Expand All @@ -470,9 +500,15 @@ BSQL_PROTECT_DATUM(/datum/entity/player)
error("ALARM: MISMATCH. Loaded player data for client [ckey], player data ckey is [player.ckey], id: [player.id]")
player_data = player
player_data.owning_client = src
if(!player_data.last_login)
player_data.first_join_date = "[time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")]"
if(!player_data.first_join_date)
player_data.find_first_join_date()
player_data.last_login = "[time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")]"
player_data.last_known_ip = address
player_data.last_known_cid = computer_id
if(!player_data.byond_account_age)
player_data.load_byond_account_age()
player_data.save()
record_login_triplet(player.ckey, address, computer_id)
player_data.sync()
Expand Down
2 changes: 2 additions & 0 deletions code/modules/admin/player_panel/player_panel.dm
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,8 @@
.["client_ckey"] = targetClient.ckey

.["client_muted"] = targetClient.prefs.muted
.["client_age"] = targetClient.player_data.byond_account_age
.["first_join"] = targetClient.player_data.first_join_date
.["client_rank"] = targetClient.admin_holder ? targetClient.admin_holder.rank : "Player"
.["client_muted"] = targetClient.prefs.muted

Expand Down
32 changes: 31 additions & 1 deletion tgui/packages/tgui/interfaces/PlayerPanel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,15 @@ export const PlayerPanel = (props) => {
const [pageIndex, setPageIndex] = useLocalState('pageIndex', 0);
const [canModifyCkey, setModifyCkey] = useLocalState('canModifyCkey', false);
const PageComponent = PAGES[pageIndex].component();
const { mob_name, mob_type, client_key, client_ckey, client_rank } = data;
const {
mob_name,
mob_type,
client_key,
client_ckey,
client_rank,
client_age,
first_join,
} = data;

return (
<Window title={`${mob_name} Player Panel`} width={600} height={500}>
Expand Down Expand Up @@ -176,6 +184,28 @@ export const PlayerPanel = (props) => {
</Stack.Item>
</Stack>
)}
{client_age && (
<Stack mt={1}>
<Stack.Item width="80px" color="label">
Account age:
</Stack.Item>
<Stack.Item grow={1} align="right">
{client_age}
</Stack.Item>
</Stack>
)}
{first_join && (
<Stack mt={1}>
<Stack.Item width="80px" color="label">
<Tooltip content="This is estimated, and depending on database integrity, may not be accurate to a user's first join date.">
<Box position="relative">First join:</Box>
</Tooltip>
</Stack.Item>
<Stack.Item grow={1} align="right">
{first_join}
</Stack.Item>
</Stack>
)}
</Section>
<Stack grow>
<Stack.Item>
Expand Down

0 comments on commit 17ad642

Please sign in to comment.