Skip to content

Commit 92215eb

Browse files
authored
playtime viewer (#7224)
1 parent 20b97f5 commit 92215eb

File tree

8 files changed

+99
-2
lines changed

8 files changed

+99
-2
lines changed

citadel.dme

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2672,6 +2672,7 @@
26722672
#include "code\modules\client\verbs\ooc.dm"
26732673
#include "code\modules\client\verbs\system.dm"
26742674
#include "code\modules\client\verbs\view.dm"
2675+
#include "code\modules\client\verbs\view_playtime.dm"
26752676
#include "code\modules\clothing\chameleon.dm"
26762677
#include "code\modules\clothing\clothing-inventory.dm"
26772678
#include "code\modules\clothing\clothing.dm"

code/__DEFINES/_cooldowns.dm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,3 +101,4 @@
101101

102102
//* /client *//
103103
#define TIMER_CD_INDEX_CLIENT_CHARACTER_DIRECTORY "client-verb-character_directory"
104+
#define TIMER_CD_INDEX_CLIENT_VIEW_PLAYTIME "client-verb-view_playtime"

code/controllers/subsystem/playtime.dm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ SUBSYSTEM_DEF(playtime)
4545
"minutes" = minutes,
4646
"player" = playerid
4747
)
48+
C.persistent.playtime[roleid] += minutes
4849
C.persistent.playtime_queued = list()
4950
SSdbcore.MassInsertLegacy(DB_PREFIX_TABLE_NAME("playtime"), built, duplicate_key = "ON DUPLICATE KEY UPDATE minutes = minutes + VALUES(minutes)")
5051

code/modules/client/client.dm

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@
137137
/// Our actor HUD holder
138138
var/datum/actor_hud_holder/actor_huds
139139

140+
// todo: just have a client panel, don't make this separate
141+
var/datum/client_view_playtime/legacy_playtime_viewer
142+
140143

141144
////////////////
142145
//ADMIN THINGS//

code/modules/client/data/client_data.dm

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,6 @@ GLOBAL_LIST_EMPTY(client_data)
119119

120120
/datum/client_data/proc/load_playtime_impl()
121121
PRIVATE_PROC(TRUE)
122-
ASSERT(!playtime_mutex)
123122
if(playtime_mutex)
124123
return
125124
playtime_mutex = TRUE
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//* This file is explicitly licensed under the MIT license. *//
2+
//* Copyright (c) 2025 Citadel Station Developers *//
3+
4+
// todo: DECLARE_CLIENT_VERB
5+
/client/verb/view_playtime()
6+
set name = "View Playtime"
7+
set desc = "View your own playtime."
8+
set category = VERB_CATEGORY_SYSTEM
9+
10+
if(TIMER_COOLDOWN_CHECK(src, TIMER_CD_INDEX_CLIENT_VIEW_PLAYTIME))
11+
return
12+
TIMER_COOLDOWN_START(src, TIMER_CD_INDEX_CLIENT_VIEW_PLAYTIME, 2 SECONDS)
13+
14+
log_game("[key_name(usr)] invoked view_playtime on [key_name(src)].")
15+
16+
// todo: self-panel for client maybe? instead of a different datum
17+
if(!legacy_playtime_viewer)
18+
legacy_playtime_viewer = new(src)
19+
legacy_playtime_viewer.ui_interact(mob)
20+
21+
/datum/client_view_playtime
22+
var/client/owner
23+
24+
/datum/client_view_playtime/New(client/C)
25+
src.owner = C
26+
src.owner.persistent.load_playtime()
27+
28+
/datum/client_view_playtime/Destroy()
29+
if(owner?.legacy_playtime_viewer == src)
30+
owner.legacy_playtime_viewer = null
31+
return ..()
32+
33+
/datum/client_view_playtime/ui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui)
34+
owner.persistent.block_on_playtime_loaded()
35+
ui = SStgui.try_update_ui(user, src, ui)
36+
if(!ui)
37+
ui = new(user, src, "client/ClientPlaytime")
38+
ui.open()
39+
40+
/datum/client_view_playtime/ui_static_data(mob/user, datum/tgui/ui)
41+
. = ..()
42+
// TODO: annotate playtime don't just throw raw strings
43+
.["playtime"] = owner.persistent.playtime_loaded ? owner.persistent.playtime : null
44+
45+
/datum/client_view_playtime/ui_state()
46+
return GLOB.always_state

dependencies.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export SPACEMAN_DMM_VERSION=suite-1.10
2525
export PYTHON_VERSION=3.12.0
2626

2727
# MariaDB version
28-
export MARIADB_VERSION=11.4.4
28+
export MARIADB_VERSION=11.8.2
2929

3030
# Flyway version
3131
export FLYWAY_VERSION=11.0.1
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* @file
3+
* @license MIT
4+
*/
5+
6+
import { round } from "common/math";
7+
import { useBackend } from "../../backend";
8+
import { LabeledList, NoticeBox, ProgressBar, Section } from "../../components";
9+
import { Window } from "../../layouts";
10+
11+
interface ClientPlaytimeData {
12+
playtime: Record<string, number> | null;
13+
}
14+
15+
export const ClientPlaytime = (props, context) => {
16+
const { data } = useBackend<ClientPlaytimeData>(context);
17+
18+
if (data.playtime === null) {
19+
return (
20+
<Window width={400} height={200} title="Playtime Viewer">
21+
<NoticeBox warning>Something went wrong while loading your playtime. Is the database connected?</NoticeBox>
22+
</Window>
23+
);
24+
}
25+
26+
const itIsntNullDamnit: Record<string, number> = data.playtime as any;
27+
const rawPlaytimeNumbers = Object.values(data.playtime);
28+
let highest: number = rawPlaytimeNumbers.length ? rawPlaytimeNumbers.reduce((a, b) => Math.max(a, b)) : 1;
29+
let sorted = Object.keys(data.playtime).toSorted((a, b) => itIsntNullDamnit[b] - itIsntNullDamnit[a]);
30+
31+
return (
32+
<Window width={400} height={600} title="Playtime Viewer">
33+
<Window.Content>
34+
<Section title="Tracked Playtime" fill>
35+
<LabeledList>
36+
{sorted.map((key) => (
37+
<LabeledList.Item key={key} label={key}>
38+
<ProgressBar value={itIsntNullDamnit[key]} maxValue={highest}>{`${round(itIsntNullDamnit[key] / 60, 0.1)}h`}</ProgressBar>
39+
</LabeledList.Item>
40+
))}
41+
</LabeledList>
42+
</Section>
43+
</Window.Content>
44+
</Window>
45+
);
46+
};

0 commit comments

Comments
 (0)