diff --git a/backend/src/main/java/com/alttd/altitudeweb/mappers/StaffPtToStaffPlaytimeMapper.java b/backend/src/main/java/com/alttd/altitudeweb/mappers/StaffPtToStaffPlaytimeMapper.java index 257f1e5..76efebb 100644 --- a/backend/src/main/java/com/alttd/altitudeweb/mappers/StaffPtToStaffPlaytimeMapper.java +++ b/backend/src/main/java/com/alttd/altitudeweb/mappers/StaffPtToStaffPlaytimeMapper.java @@ -1,6 +1,6 @@ package com.alttd.altitudeweb.mappers; -import com.alttd.altitudeweb.database.luckperms.Player; +import com.alttd.altitudeweb.database.luckperms.PlayerWithGroup; import com.alttd.altitudeweb.database.proxyplaytime.StaffPt; import com.alttd.altitudeweb.model.StaffPlaytimeDto; import org.springframework.stereotype.Service; @@ -15,10 +15,10 @@ import java.util.concurrent.TimeUnit; public final class StaffPtToStaffPlaytimeMapper { private record PlaytimeInfo(long totalPlaytime, long lastPlayed) {} - public List map(List sessions, List staffMembers, long from, long to) { + public List map(List sessions, List staffMembers, long from, long to, HashMap staffGroupsMap) { Map playtimeData = getUuidPlaytimeInfoMap(sessions, from, to); - for (Player staffMember : staffMembers) { + for (PlayerWithGroup staffMember : staffMembers) { if (!playtimeData.containsKey(staffMember.uuid())) { playtimeData.put(staffMember.uuid(), new PlaytimeInfo(0L, Long.MIN_VALUE)); } @@ -28,14 +28,22 @@ public final class StaffPtToStaffPlaytimeMapper { for (Map.Entry entry : playtimeData.entrySet()) { long lastPlayedMillis = entry.getValue().lastPlayed() == Long.MIN_VALUE ? 0L : entry.getValue().lastPlayed(); StaffPlaytimeDto dto = new StaffPlaytimeDto(); + Optional first = staffMembers.stream() + .filter(player -> player.uuid().equals(entry.getKey())).findFirst(); + dto.setStaffMember(first.isPresent() ? first.get().username() : entry.getKey().toString()); dto.setStaffMember(staffMembers.stream() .filter(player -> player.uuid().equals(entry.getKey())) - .map(Player::username) + .map(PlayerWithGroup::username) .findFirst() .orElse(entry.getKey().toString()) ); dto.setLastPlayed(OffsetDateTime.ofInstant(Instant.ofEpochMilli(lastPlayedMillis), ZoneOffset.UTC)); dto.setPlaytime((int) TimeUnit.MILLISECONDS.toMinutes(entry.getValue().totalPlaytime())); + if (first.isPresent()) { + dto.setRole(staffGroupsMap.getOrDefault(first.get().group(), "Unknown")); + } else { + dto.setRole("Unknown"); + } results.add(dto); } return results; diff --git a/backend/src/main/java/com/alttd/altitudeweb/services/site/StaffPtService.java b/backend/src/main/java/com/alttd/altitudeweb/services/site/StaffPtService.java index 2fe4d61..f297716 100644 --- a/backend/src/main/java/com/alttd/altitudeweb/services/site/StaffPtService.java +++ b/backend/src/main/java/com/alttd/altitudeweb/services/site/StaffPtService.java @@ -2,6 +2,7 @@ package com.alttd.altitudeweb.services.site; import com.alttd.altitudeweb.database.Databases; import com.alttd.altitudeweb.database.luckperms.Player; +import com.alttd.altitudeweb.database.luckperms.PlayerWithGroup; import com.alttd.altitudeweb.database.luckperms.TeamMemberMapper; import com.alttd.altitudeweb.database.proxyplaytime.StaffPlaytimeMapper; import com.alttd.altitudeweb.database.proxyplaytime.StaffPt; @@ -14,6 +15,7 @@ import org.springframework.stereotype.Service; import java.time.Instant; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Optional; import java.util.concurrent.CompletableFuture; @@ -23,17 +25,30 @@ import java.util.stream.Collectors; @Service @RequiredArgsConstructor public class StaffPtService { - private final static String STAFF_GROUPS = "'group.admin', 'group.developer', 'group.headmod', 'group.manager', 'group.moderator', 'group.owner', 'group.trainee'"; + private final static HashMap STAFF_GROUPS_MAP = new HashMap<>(); + private final static String STAFF_GROUPS; + static { + STAFF_GROUPS_MAP.put("group.owner", "Owner"); + STAFF_GROUPS_MAP.put("group.manager", "Manager"); + STAFF_GROUPS_MAP.put("group.admin", "Admin"); + STAFF_GROUPS_MAP.put("group.headmod", "Head Mod"); + STAFF_GROUPS_MAP.put("group.moderator", "Moderator"); + STAFF_GROUPS_MAP.put("group.trainee", "Trainee"); + STAFF_GROUPS_MAP.put("group.developer", "Developer"); + STAFF_GROUPS = STAFF_GROUPS_MAP.keySet().stream() + .map(group -> "'" + group + "'") + .collect(Collectors.joining(", ")); + } private final StaffPtToStaffPlaytimeMapper staffPtToStaffPlaytimeMapper; public Optional> getStaffPlaytime(Instant from, Instant to) { - CompletableFuture> staffMembersFuture = new CompletableFuture<>(); + CompletableFuture> staffMembersFuture = new CompletableFuture<>(); CompletableFuture> staffPlaytimeFuture = new CompletableFuture<>(); Connection.getConnection(Databases.LUCK_PERMS) .runQuery(sqlSession -> { log.debug("Loading staff members"); try { - List staffMemberList = sqlSession.getMapper(TeamMemberMapper.class) + List staffMemberList = sqlSession.getMapper(TeamMemberMapper.class) .getTeamMembersOfGroupList(STAFF_GROUPS); staffMembersFuture.complete(staffMemberList); } catch (Exception e) { @@ -41,14 +56,14 @@ public class StaffPtService { staffMembersFuture.completeExceptionally(e); } }); - List staffMembers = staffMembersFuture.join().stream() + List staffMembers = staffMembersFuture.join().stream() .collect(Collectors.collectingAndThen( - Collectors.toMap(Player::uuid, player -> player, (player1, player2) -> player1), + Collectors.toMap(PlayerWithGroup::uuid, player -> player, (player1, player2) -> player1), m -> new ArrayList<>(m.values()))); Connection.getConnection(Databases.PROXY_PLAYTIME) .runQuery(sqlSession -> { String staffUUIDs = staffMembers.stream() - .map(Player::uuid) + .map(PlayerWithGroup::uuid) .map(uuid -> "'" + uuid + "'") .collect(Collectors.joining(",")); log.debug("Loading staff playtime for group"); @@ -62,7 +77,7 @@ public class StaffPtService { } }); List join = staffPlaytimeFuture.join(); - - return Optional.of(staffPtToStaffPlaytimeMapper.map(join, staffMembers, from.toEpochMilli(), to.toEpochMilli())); + HashMap staffGroupsMap = new HashMap<>(STAFF_GROUPS_MAP); + return Optional.of(staffPtToStaffPlaytimeMapper.map(join, staffMembers, from.toEpochMilli(), to.toEpochMilli(), staffGroupsMap)); } } diff --git a/database/src/main/java/com/alttd/altitudeweb/database/luckperms/PlayerWithGroup.java b/database/src/main/java/com/alttd/altitudeweb/database/luckperms/PlayerWithGroup.java new file mode 100644 index 0000000..3c94565 --- /dev/null +++ b/database/src/main/java/com/alttd/altitudeweb/database/luckperms/PlayerWithGroup.java @@ -0,0 +1,6 @@ +package com.alttd.altitudeweb.database.luckperms; + +import java.util.UUID; + +public record PlayerWithGroup(UUID uuid, String username, String group) { +} diff --git a/database/src/main/java/com/alttd/altitudeweb/database/luckperms/TeamMemberMapper.java b/database/src/main/java/com/alttd/altitudeweb/database/luckperms/TeamMemberMapper.java index 8df0e1e..ec4a92c 100644 --- a/database/src/main/java/com/alttd/altitudeweb/database/luckperms/TeamMemberMapper.java +++ b/database/src/main/java/com/alttd/altitudeweb/database/luckperms/TeamMemberMapper.java @@ -25,13 +25,13 @@ public interface TeamMemberMapper { @Arg(column = "uuid", javaType = UUID.class, typeHandler = UUIDTypeHandler.class) }) @Select(""" - SELECT players.username, players.uuid + SELECT players.username, players.uuid, players.primary_group AS 'group' FROM luckperms_user_permissions AS permissions INNER JOIN luckperms_players AS players ON players.uuid = permissions.uuid WHERE permission IN (${groupPermissions}) AND server = 'global' AND world = 'global' """) - List getTeamMembersOfGroupList(@Param("groupPermissions") String groupPermissions); + List getTeamMembersOfGroupList(@Param("groupPermissions") String groupPermissions); } diff --git a/frontend/src/app/pages/head-mod/staff-pt/staff-pt.component.html b/frontend/src/app/pages/head-mod/staff-pt/staff-pt.component.html index e50fee4..26439f3 100644 --- a/frontend/src/app/pages/head-mod/staff-pt/staff-pt.component.html +++ b/frontend/src/app/pages/head-mod/staff-pt/staff-pt.component.html @@ -20,17 +20,22 @@ - + - + + + + + + diff --git a/frontend/src/app/pages/head-mod/staff-pt/staff-pt.component.ts b/frontend/src/app/pages/head-mod/staff-pt/staff-pt.component.ts index 30cbb3e..427d20a 100644 --- a/frontend/src/app/pages/head-mod/staff-pt/staff-pt.component.ts +++ b/frontend/src/app/pages/head-mod/staff-pt/staff-pt.component.ts @@ -78,7 +78,7 @@ export class StaffPtComponent implements OnInit { parts.push(`${d}d`); } if (h > 0 || d > 0) { - parts.push(`${h}h`); + parts.push(`${h}hr`); } if (m > 0 || (h === 0 && d === 0)) { parts.push(`${m}m`); diff --git a/open_api/src/main/resources/schemas/site/staff_pt.yml b/open_api/src/main/resources/schemas/site/staff_pt.yml index 95e00de..5aba20f 100644 --- a/open_api/src/main/resources/schemas/site/staff_pt.yml +++ b/open_api/src/main/resources/schemas/site/staff_pt.yml @@ -40,6 +40,11 @@ components: $ref: '#/components/schemas/StaffPlaytime' StaffPlaytime: type: object + required: + - staff_member + - playtime + - last_played + - role properties: staff_member: type: string @@ -51,3 +56,6 @@ components: type: string format: date-time description: Last played timestamp + role: + type: string + description: The role of the staff member
Staff MemberStaff Member {{ row.staff_member }} PlaytimePlaytime {{ minutesToHm(row.playtime) }} Rank {{ row.role }}